The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6634
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === This batch fixes some mount/unmount issues with btrfs and moves more logic to common to reduce the size of the upcoming btrfs driver.
From 48ef89c0006d9fedde5550841d64c021d69a3daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Mon, 16 Dec 2019 16:00:27 -0500 Subject: [PATCH 1/4] lxd/storage/cephfs: Simplify Delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage/drivers/driver_cephfs.go | 31 +++++++--------------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/lxd/storage/drivers/driver_cephfs.go b/lxd/storage/drivers/driver_cephfs.go index 6c63190390..5966a0d564 100644 --- a/lxd/storage/drivers/driver_cephfs.go +++ b/lxd/storage/drivers/driver_cephfs.go @@ -190,25 +190,14 @@ func (d *cephfs) Delete(op *operations.Operation) error { } defer forceUnmount(mountPoint) - if shared.PathExists(filepath.Join(mountPoint, fsPath)) { - // Delete the usual directories. - for _, volType := range d.Info().VolumeTypes { - for _, dir := range BaseDirectories[volType] { - if shared.PathExists(filepath.Join(mountPoint, fsPath, dir)) { - err = os.Remove(filepath.Join(mountPoint, fsPath, dir)) - if err != nil { - return err - } - } - } - } - - // Confirm that the path is now empty. - ok, _ := shared.PathIsEmpty(filepath.Join(mountPoint, fsPath)) - if !ok { - return fmt.Errorf("Only empty CEPHFS paths can be used as a LXD storage pool") - } + // On delete, wipe everything in the directory. + err = wipeDirectory(GetPoolMountPath(d.name)) + if err != nil { + return err + } + // Delete the pool from the parent. + if shared.PathExists(filepath.Join(mountPoint, fsPath)) { // Delete the path itself. if fsPath != "" && fsPath != "/" { err = os.Remove(filepath.Join(mountPoint, fsPath)) @@ -218,12 +207,6 @@ func (d *cephfs) Delete(op *operations.Operation) error { } } - // On delete, wipe everything in the directory. - err = wipeDirectory(GetPoolMountPath(d.name)) - if err != nil { - return err - } - // Make sure the existing pool is unmounted. _, err = d.Unmount() if err != nil { From dfbdc1c0b2fe6361d15feacec513bcd1932e2e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Mon, 16 Dec 2019 18:54:04 -0500 Subject: [PATCH 2/4] shared: Handle btrfs in IsMountPoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- shared/fs_32bit.go | 7 +++++++ shared/fs_64bit.go | 7 +++++++ shared/util_linux.go | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 shared/fs_32bit.go create mode 100644 shared/fs_64bit.go diff --git a/shared/fs_32bit.go b/shared/fs_32bit.go new file mode 100644 index 0000000000..703bf82cd4 --- /dev/null +++ b/shared/fs_32bit.go @@ -0,0 +1,7 @@ +// +build 386 arm ppc s390 + +package shared + +const ( + filesystemSuperMagicBtrfs = -1859950530 +) diff --git a/shared/fs_64bit.go b/shared/fs_64bit.go new file mode 100644 index 0000000000..7c04ad13ad --- /dev/null +++ b/shared/fs_64bit.go @@ -0,0 +1,7 @@ +// +build amd64 ppc64 ppc64le arm64 s390x + +package shared + +const ( + filesystemSuperMagicBtrfs = 0x9123683E +) diff --git a/shared/util_linux.go b/shared/util_linux.go index f2b8827416..ded0dac39e 100644 --- a/shared/util_linux.go +++ b/shared/util_linux.go @@ -79,11 +79,13 @@ func parseMountinfo(name string) int { } func IsMountPoint(name string) bool { + // If we find a mount entry, it is obviously a mount point. ret := parseMountinfo(name) if ret == 1 { return true } + // Get the stat details. stat, err := os.Stat(name) if err != nil { return false @@ -93,8 +95,21 @@ func IsMountPoint(name string) bool { if err != nil { return false } + // If the directory has the same device as parent, then it's not a mountpoint. - return stat.Sys().(*syscall.Stat_t).Dev != rootStat.Sys().(*syscall.Stat_t).Dev + if stat.Sys().(*syscall.Stat_t).Dev == rootStat.Sys().(*syscall.Stat_t).Dev { + return false + } + + // Btrfs annoyingly uses a different Dev id for different subvolumes on the same mount. + // So for btrfs, we require a matching mount entry in mountinfo. + fs := unix.Statfs_t{} + err = unix.Statfs(name, &fs) + if err == nil && fs.Type == filesystemSuperMagicBtrfs { + return false + } + + return true } func SetSize(fd int, width int, height int) (err error) { From 887d4a5fcec4ae0c3d534232be20f29215db1d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Mon, 16 Dec 2019 19:10:07 -0500 Subject: [PATCH 3/4] lxd/storage: Allow deletion of missing pools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage/backend_lxd.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index d3ba43a29a..0c89abdaa2 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -177,6 +177,11 @@ func (b *lxdBackend) Delete(localOnly bool, op *operations.Operation) error { logger.Debug("Delete started") defer logger.Debug("Delete finished") + // If completely gone, just return + if !shared.PathExists(shared.VarPath("storage-pools", b.name)) { + return nil + } + // Delete the low-level storage. if !localOnly || !b.driver.Info().Remote { err := b.driver.Delete(op) From e2f1bc34c14d31691e53a1902de9c49b8d159d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Mon, 16 Dec 2019 22:04:56 -0500 Subject: [PATCH 4/4] lxd/storage/dir: Move MigrateVolume to common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage/drivers/driver_common.go | 39 +++++++++++++++++++++++ lxd/storage/drivers/driver_dir_volumes.go | 34 +------------------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go index 591577f5dd..c843b5b341 100644 --- a/lxd/storage/drivers/driver_common.go +++ b/lxd/storage/drivers/driver_common.go @@ -2,6 +2,7 @@ package drivers import ( "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -9,9 +10,11 @@ import ( "github.com/lxc/lxd/lxd/migration" "github.com/lxc/lxd/lxd/operations" + "github.com/lxc/lxd/lxd/rsync" "github.com/lxc/lxd/lxd/state" "github.com/lxc/lxd/shared" "github.com/lxc/lxd/shared/api" + "github.com/lxc/lxd/shared/ioprogress" "github.com/lxc/lxd/shared/logger" ) @@ -217,3 +220,39 @@ func (d *common) vfsRenameVolumeSnapshot(snapVol Volume, newSnapshotName string, return nil } + +func (d *common) vfsMigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs migration.VolumeSourceArgs, op *operations.Operation) error { + bwlimit := d.config["rsync.bwlimit"] + + for _, snapName := range volSrcArgs.Snapshots { + snapshot, err := vol.NewSnapshot(snapName) + if err != nil { + return err + } + + // Send snapshot to recipient (ensure local snapshot volume is mounted if needed). + err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error { + var wrapper *ioprogress.ProgressTracker + if volSrcArgs.TrackProgress { + wrapper = migration.ProgressTracker(op, "fs_progress", snapshot.name) + } + + path := shared.AddSlash(mountPath) + return rsync.Send(snapshot.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath) + }, op) + if err != nil { + return err + } + } + + // Send volume to recipient (ensure local volume is mounted if needed). + return vol.MountTask(func(mountPath string, op *operations.Operation) error { + var wrapper *ioprogress.ProgressTracker + if volSrcArgs.TrackProgress { + wrapper = migration.ProgressTracker(op, "fs_progress", vol.name) + } + + path := shared.AddSlash(mountPath) + return rsync.Send(vol.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath) + }, op) +} diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go index 53d6b53ae6..d36a0d8bef 100644 --- a/lxd/storage/drivers/driver_dir_volumes.go +++ b/lxd/storage/drivers/driver_dir_volumes.go @@ -488,39 +488,7 @@ func (d *dir) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs migr return fmt.Errorf("Migration type not supported") } - bwlimit := d.config["rsync.bwlimit"] - - for _, snapName := range volSrcArgs.Snapshots { - snapshot, err := vol.NewSnapshot(snapName) - if err != nil { - return err - } - - // Send snapshot to recipient (ensure local snapshot volume is mounted if needed). - err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error { - var wrapper *ioprogress.ProgressTracker - if volSrcArgs.TrackProgress { - wrapper = migration.ProgressTracker(op, "fs_progress", snapshot.name) - } - - path := shared.AddSlash(mountPath) - return rsync.Send(snapshot.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath) - }, op) - if err != nil { - return err - } - } - - // Send volume to recipient (ensure local volume is mounted if needed). - return vol.MountTask(func(mountPath string, op *operations.Operation) error { - var wrapper *ioprogress.ProgressTracker - if volSrcArgs.TrackProgress { - wrapper = migration.ProgressTracker(op, "fs_progress", vol.name) - } - - path := shared.AddSlash(mountPath) - return rsync.Send(vol.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath) - }, op) + return d.vfsMigrateVolume(vol, conn, volSrcArgs, op) } // BackupVolume copies a volume (and optionally its snapshots) to a specified target path.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel