Merge pull request #6650 from henry118/xfs

Two xfs file systems with same UUID can not be mounted on the same sy…
This commit is contained in:
Phil Estes 2022-03-11 09:43:10 -05:00 committed by GitHub
commit e771443845
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 26 deletions

View File

@ -504,6 +504,8 @@ func (s *Snapshotter) buildMounts(ctx context.Context, snap storage.Snapshot, fi
if fileSystemType == "" {
log.G(ctx).Error("File system type cannot be empty")
return nil
} else if fileSystemType == fsTypeXFS {
options = append(options, "nouuid")
}
if snap.Kind != snapshots.KindActive {
options = append(options, "ro")

View File

@ -46,38 +46,13 @@ func TestSnapshotterSuite(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
snapshotterFn := func(ctx context.Context, root string) (snapshots.Snapshotter, func() error, error) {
// Create loopback devices for each test case
_, loopDataDevice := createLoopbackDevice(t, root)
_, loopMetaDevice := createLoopbackDevice(t, root)
poolName := fmt.Sprintf("containerd-snapshotter-suite-pool-%d", time.Now().Nanosecond())
err := dmsetup.CreatePool(poolName, loopDataDevice, loopMetaDevice, 64*1024/dmsetup.SectorSize)
assert.NilError(t, err, "failed to create pool %q", poolName)
config := &Config{
RootPath: root,
PoolName: poolName,
BaseImageSize: "16Mb",
}
snap, err := NewSnapshotter(context.Background(), config)
if err != nil {
return nil, nil, err
}
// Remove device mapper pool and detach loop devices after test completes
removePool := func() error {
result := multierror.Append(
snap.pool.RemovePool(ctx),
mount.DetachLoopDevice(loopDataDevice, loopMetaDevice))
return result.ErrorOrNil()
}
// Pool cleanup should be called before closing metadata store (as we need to retrieve device names)
snap.cleanupFn = append([]closeFunc{removePool}, snap.cleanupFn...)
return snap, snap.Close, nil
return createSnapshotter(ctx, t, config)
}
testsuite.SnapshotterSuite(t, "devmapper", snapshotterFn)
@ -165,3 +140,85 @@ func TestMkfsXfsNonDefault(t *testing.T) {
err := mkfs(ctx, "xfs", "noquota", "")
assert.ErrorContains(t, err, `mkfs.xfs couldn't initialize ""`)
}
func TestMultipleXfsMounts(t *testing.T) {
testutil.RequiresRoot(t)
logrus.SetLevel(logrus.DebugLevel)
ctx := context.Background()
ctx = namespaces.WithNamespace(ctx, "testsuite")
tempDir, err := os.MkdirTemp("", "snapshot-suite-usage")
assert.NilError(t, err)
defer os.RemoveAll(tempDir)
poolName := fmt.Sprintf("containerd-snapshotter-suite-pool-%d", time.Now().Nanosecond())
config := &Config{
RootPath: tempDir,
PoolName: poolName,
BaseImageSize: "16Mb",
FileSystemType: "xfs",
}
snapshotter, closer, err := createSnapshotter(ctx, t, config)
assert.NilError(t, err)
defer closer()
var (
sizeBytes int64 = 1048576 // 1MB
baseApplier = fstest.Apply(fstest.CreateRandomFile("/a", 12345679, sizeBytes, 0777))
)
// Create base layer
mounts, err := snapshotter.Prepare(ctx, "prepare-1", "")
assert.NilError(t, err)
root1, _ := os.MkdirTemp(os.TempDir(), "containerd-mount")
defer func() {
mount.UnmountAll(root1, 0)
os.Remove(root1)
}()
err = mount.All(mounts, root1)
assert.NilError(t, err)
baseApplier.Apply(root1)
snapshotter.Commit(ctx, "layer-1", "prepare-1")
// Create one child layer
mounts, err = snapshotter.Prepare(ctx, "prepare-2", "layer-1")
assert.NilError(t, err)
root2, _ := os.MkdirTemp(os.TempDir(), "containerd-mount")
defer func() {
mount.UnmountAll(root2, 0)
os.Remove(root2)
}()
err = mount.All(mounts, root2)
assert.NilError(t, err)
}
func createSnapshotter(ctx context.Context, t *testing.T, config *Config) (snapshots.Snapshotter, func() error, error) {
// Create loopback devices for each test case
_, loopDataDevice := createLoopbackDevice(t, config.RootPath)
_, loopMetaDevice := createLoopbackDevice(t, config.RootPath)
err := dmsetup.CreatePool(config.PoolName, loopDataDevice, loopMetaDevice, 64*1024/dmsetup.SectorSize)
assert.NilError(t, err, "failed to create pool %q", config.PoolName)
snap, err := NewSnapshotter(ctx, config)
if err != nil {
return nil, nil, err
}
// Remove device mapper pool and detach loop devices after test completes
removePool := func() error {
result := multierror.Append(
snap.pool.RemovePool(ctx),
mount.DetachLoopDevice(loopDataDevice, loopMetaDevice))
return result.ErrorOrNil()
}
// Pool cleanup should be called before closing metadata store (as we need to retrieve device names)
snap.cleanupFn = append([]closeFunc{removePool}, snap.cleanupFn...)
return snap, snap.Close, nil
}