[lxc-devel] [lxd/master] Storage: BTRFS subvolume migration tweaks

tomponline on Github lxc-bot at linuxcontainers.org
Tue May 12 09:49:24 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200512/4924c30e/attachment.bin>
-------------- next part --------------
From cbefe0cc283a4ec3b0fe04424922b0eb94b2dd85 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 12 May 2020 10:08:19 +0100
Subject: [PATCH 1/4] lxd/storage/drivers/driver/btrfs/utils: Renames
 metadatHeader to restorationHeader

And updates comments clarifying the role of this function.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_btrfs_utils.go | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lxd/storage/drivers/driver_btrfs_utils.go b/lxd/storage/drivers/driver_btrfs_utils.go
index 6ce0fbac91..0586da3cd6 100644
--- a/lxd/storage/drivers/driver_btrfs_utils.go
+++ b/lxd/storage/drivers/driver_btrfs_utils.go
@@ -461,8 +461,13 @@ type BTRFSMetaDataHeader struct {
 	Subvolumes []BTRFSSubVolume // Sub volumes inside the volume (including the top level ones).
 }
 
-// metadataHeader scans the volume and any specified snapshots, returning a header containing subvolume meta data.
-func (d *btrfs) metadataHeader(vol Volume, snapshots []string) (*BTRFSMetaDataHeader, error) {
+// restorationHeader scans the volume and any specified snapshots, returning a header containing subvolume metadata
+// for use in restoring a volume and its snapshots onto another system. The metadata returned represents how the
+// subvolumes should be restored, not necessarily how they are on disk now. Most of the time this is the same,
+// however in circumstances where the volume being scanned is itself a snapshot, the returned metadata will
+// not report the volume as readonly or as being a snapshot, as the expectation is that this volume will be
+// restored on the target system as a normal volume and not a snapshot.
+func (d *btrfs) restorationHeader(vol Volume, snapshots []string) (*BTRFSMetaDataHeader, error) {
 	var migrationHeader BTRFSMetaDataHeader
 
 	// Add snapshots to volumes list.
@@ -484,7 +489,9 @@ func (d *btrfs) metadataHeader(vol Volume, snapshots []string) (*BTRFSMetaDataHe
 		return nil, err
 	}
 
-	// If vol is a snapshot itself, we need to fixup the metadata.
+	// If vol is a snapshot itself, we force the volume as writable (even if it isn't on disk) and remove the
+	// snapshot name indicator as the expectation is that this volume is going to be restored on the target
+	// system as a normal (non-snapshot) writable volume.
 	if vol.IsSnapshot() {
 		subVols[0].Readonly = false
 		for i := range subVols {

From 8620268a8a882377a93d6b18a7f356dfc7b4fe52 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 12 May 2020 10:08:53 +0100
Subject: [PATCH 2/4] lxd/storage/drivers/driver/btrfs/volumes:
 d.restorationHeader usage

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_btrfs_volumes.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go
index bdac8afacc..b6b3ca1264 100644
--- a/lxd/storage/drivers/driver_btrfs_volumes.go
+++ b/lxd/storage/drivers/driver_btrfs_volumes.go
@@ -689,8 +689,8 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 		return nil
 	}
 
-	// Generate migration header, containing subvolume info.
-	migrationHeader, err := d.metadataHeader(vol, volSrcArgs.Snapshots)
+	// Generate restoration header, containing info on the subvolumes and how they should be restored.
+	migrationHeader, err := d.restorationHeader(vol, volSrcArgs.Snapshots)
 	if err != nil {
 		return err
 	}

From 919f4754e631d4d1ab40236cb6af3e71b16ac5da Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 12 May 2020 10:25:12 +0100
Subject: [PATCH 3/4] lxd/storage/drivers/driver/btrfs/volumes: Clarifies
 comments in MigrateVolume

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_btrfs_volumes.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go
index b6b3ca1264..6a7cdaac23 100644
--- a/lxd/storage/drivers/driver_btrfs_volumes.go
+++ b/lxd/storage/drivers/driver_btrfs_volumes.go
@@ -727,11 +727,11 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 
 	// sendVolume sends a volume and its subvolumes (if negotiated subvolumes feature) to recipient.
 	sendVolume := func(v Volume, sourcePrefix string, parentPrefix string) error {
-		snapName := "" // Default to empty if volume isn't a snapshot and is main volume.
+		snapName := "" // Default to empty (sending main volume) from migrationHeader.Subvolumes.
 
-		// Detect snapshot by comparing to main volume.
-		// We can't use IsSnapshot() as the main vol may itself be a snapshot.
-		if v.name != vol.name {
+		// Detect if we are sending a snapshot by comparing to main volume name.
+		// We can't only use IsSnapshot() as the main vol may itself be a snapshot.
+		if v.IsSnapshot() && v.name != vol.name {
 			_, snapName, _ = shared.InstanceGetParentAndSnapshotName(v.name)
 		}
 

From a09f194d9827fc5fef747786fb8a69b4039d54a4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 12 May 2020 10:30:35 +0100
Subject: [PATCH 4/4] lxd/storage/drivers/driver/btrfs/volumes: Adds safety net
 against failed matching of subvolumes

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_btrfs_volumes.go | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go
index 6a7cdaac23..4e08660345 100644
--- a/lxd/storage/drivers/driver_btrfs_volumes.go
+++ b/lxd/storage/drivers/driver_btrfs_volumes.go
@@ -741,6 +741,8 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 			wrapper = migration.ProgressTracker(op, "fs_progress", v.name)
 		}
 
+		sentVols := 0
+
 		// Send volume (and any subvolumes if supported) to target.
 		for _, subVolume := range migrationHeader.Subvolumes {
 			if subVolume.Snapshot != snapName {
@@ -781,6 +783,12 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 			if err != nil {
 				return errors.Wrapf(err, "Failed sending volume %v:%s", v.name, subVolume.Path)
 			}
+			sentVols++
+		}
+
+		// Ensure we found and sent at least root subvolume of the volume requested.
+		if sentVols < 1 {
+			return fmt.Errorf("No matching subvolume(s) for %q found in subvolumes list", v.name)
 		}
 
 		return nil


More information about the lxc-devel mailing list