[lxc-devel] [lxd/master] Storage: More removal of legacy driver usage.

tomponline on Github lxc-bot at linuxcontainers.org
Thu Feb 27 11:50:53 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/20200227/8e278433/attachment-0001.bin>
-------------- next part --------------
From 5f7dd11bb4a8d59ec3601992f6db2cb78f756170 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 10:07:37 +0000
Subject: [PATCH 1/9] lxd/main/init: Removes legacy storage drivers from
 availableStorageDrivers

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/main_init.go | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/lxd/main_init.go b/lxd/main_init.go
index 00a4a574a5..d757277926 100644
--- a/lxd/main_init.go
+++ b/lxd/main_init.go
@@ -198,18 +198,11 @@ func (c *cmdInit) availableStorageDrivers(poolType string) []string {
 			continue
 		}
 
-		// Check if available as a new style driver.
+		// Check if available as a driver.
 		if shared.StringInSlice(driver, availableDrivers) {
 			drivers = append(drivers, driver)
 			continue
 		}
-
-		// Check if available as an old style driver.
-		_, err := storageCoreInit(driver)
-		if err == nil {
-			drivers = append(drivers, driver)
-			continue
-		}
 	}
 
 	return drivers

From 8c3059aa6e3d7e97e6aba265d9dc265e33224900 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 10:08:25 +0000
Subject: [PATCH 2/9] lxd/patches: Updates patchStorageApiPermissions to use
 new storage drivers

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/patches.go | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/lxd/patches.go b/lxd/patches.go
index 3c2c44c73a..ec51b9f995 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -3023,22 +3023,31 @@ func patchStorageApiPermissions(name string, d *Daemon) error {
 		}
 
 		for _, vol := range volumes {
-			volStruct, err := storagePoolVolumeInit(d.State(), "default", poolName, vol, storagePoolVolumeTypeCustom)
+			pool, err := storagePools.GetPoolByName(d.State(), poolName)
 			if err != nil {
 				return err
 			}
 
-			ourMount, err := volStruct.StoragePoolVolumeMount()
-			if err != nil {
-				return err
-			}
-			if ourMount {
-				defer volStruct.StoragePoolVolumeUmount()
-			}
+			// Run task in anonymous function so as not to stack up defers.
+			err = func() error {
+				ourMount, err := pool.MountCustomVolume(vol, nil)
+				if err != nil {
+					return err
+				}
 
-			cuMntPoint := driver.GetStoragePoolVolumeMountPoint(poolName, vol)
-			err = os.Chmod(cuMntPoint, 0711)
-			if err != nil && !os.IsNotExist(err) {
+				if ourMount {
+					defer pool.UnmountCustomVolume(vol, nil)
+				}
+
+				cuMntPoint := driver.GetStoragePoolVolumeMountPoint(poolName, vol)
+				err = os.Chmod(cuMntPoint, 0711)
+				if err != nil && !os.IsNotExist(err) {
+					return err
+				}
+
+				return nil
+			}()
+			if err != nil {
 				return err
 			}
 		}

From beca714e331b8d73c5703a7bd31a647e1ff2f546 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 10:08:57 +0000
Subject: [PATCH 3/9] lxd/storage: Removes storageCoreInit function

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage.go | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index 223064ed1e..c28012c155 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -223,32 +223,6 @@ type storage interface {
 	StorageMigrationSink(conn *websocket.Conn, op *operations.Operation, args MigrationSinkArgs) error
 }
 
-func storageCoreInit(driver string) (storage, error) {
-	sType, err := storageStringToType(driver)
-	if err != nil {
-		return nil, err
-	}
-
-	switch sType {
-	case storageTypeCeph:
-		ceph := storageCeph{}
-		err = ceph.StorageCoreInit()
-		if err != nil {
-			return nil, err
-		}
-		return &ceph, nil
-	case storageTypeMock:
-		mock := storageMock{}
-		err = mock.StorageCoreInit()
-		if err != nil {
-			return nil, err
-		}
-		return &mock, nil
-	}
-
-	return nil, fmt.Errorf("invalid storage type")
-}
-
 func storageInit(s *state.State, project, poolName, volumeName string, volumeType int) (storage, error) {
 	// Load the storage pool.
 	poolID, pool, err := s.Cluster.StoragePoolGet(poolName)

From 571ec26c841764de76b821c9a5e2bcb413dec78d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 10:09:14 +0000
Subject: [PATCH 4/9] lxd/storage: Removes legacy drivers from
 storagePoolDriversCacheUpdate

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage.go | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/lxd/storage.go b/lxd/storage.go
index c28012c155..03397c3931 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -644,18 +644,6 @@ func storagePoolDriversCacheUpdate(s *state.State) {
 		}
 	}
 
-	// Handle legacy backends.
-	for _, driver := range drivers {
-		// Initialize a core storage interface for the given driver.
-		sCore, err := storageCoreInit(driver)
-		if err != nil {
-			continue
-		}
-
-		// Grab the version.
-		data[driver] = sCore.GetStorageTypeVersion()
-	}
-
 	// Prepare the cache entries.
 	backends := []string{}
 	for k, v := range data {

From 1f5ebdc51ffc4058e522e03b8c142afca528a109 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 10:39:51 +0000
Subject: [PATCH 5/9] lxd/patches: Removes old storage layer from
 upgradeFromStorageTypeLvm

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/patches.go | 48 +++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/lxd/patches.go b/lxd/patches.go
index ec51b9f995..c69503407d 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -1210,44 +1210,50 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				// means that this was a mixed-storage LXD
 				// instance.
 
-				// Initialize storage interface for the new
-				// container.
-				ctStorage, err := storagePoolVolumeContainerLoadInit(d.State(), "default", ct)
+				// Load the container from the database.
+				ctStruct, err := instance.LoadByProjectAndName(d.State(), "default", ct)
 				if err != nil {
-					logger.Errorf("Failed to initialize new storage interface for LVM container %s: %s", ct, err)
+					logger.Errorf("Failed to load LVM container %s: %s", ct, err)
 					return err
 				}
 
-				// Load the container from the database.
-				ctStruct, err := instance.LoadByProjectAndName(d.State(), "default", ct)
+				pool, err := storagePools.GetPoolByInstance(d.State(), ctStruct)
 				if err != nil {
-					logger.Errorf("Failed to load LVM container %s: %s", ct, err)
 					return err
 				}
 
-				// Create an empty LVM logical volume for the
-				// container.
-				err = ctStorage.ContainerCreate(ctStruct)
+				// Create an empty LVM logical volume for the container.
+				err = pool.CreateInstance(ctStruct, nil)
 				if err != nil {
 					logger.Errorf("Failed to create empty LVM logical volume for container %s: %s", ct, err)
 					return err
 				}
 
-				// In case the new LVM logical volume for the
-				// container is not mounted mount it.
-				if !shared.IsMountPoint(newContainerMntPoint) {
-					_, err = ctStorage.ContainerMount(ctStruct)
+				err = func() error {
+					// In case the new LVM logical volume for the container is not mounted mount it.
+					if !shared.IsMountPoint(newContainerMntPoint) {
+						ourMount, err := pool.MountInstance(ctStruct, nil)
+						if err != nil {
+							logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s", ct, err)
+							return err
+						}
+
+						if ourMount {
+							defer pool.UnmountInstance(ctStruct, nil)
+						}
+					}
+
+					// Use rsync to fill the empty volume.
+					output, err := rsync.LocalCopy(oldContainerMntPoint, newContainerMntPoint, "", true)
 					if err != nil {
-						logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s", ct, err)
-						return err
+						pool.DeleteInstance(ctStruct, nil)
+						return fmt.Errorf("rsync failed: %s", string(output))
 					}
-				}
 
-				// Use rsync to fill the empty volume.
-				output, err := rsync.LocalCopy(oldContainerMntPoint, newContainerMntPoint, "", true)
+					return nil
+				}()
 				if err != nil {
-					ctStorage.ContainerDelete(ctStruct)
-					return fmt.Errorf("rsync failed: %s", string(output))
+					return err
 				}
 
 				// Remove the old container.

From fba757123b4c94d49f1cc5443ee2bf95e892eeab Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 11:47:30 +0000
Subject: [PATCH 6/9] lxd/container/lxc: Removes some calls to the old storage
 layer

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/container_lxc.go | 48 +++++++++-----------------------------------
 1 file changed, 9 insertions(+), 39 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index e2827b564e..d538adf7cc 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3272,22 +3272,12 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
 		}
 
 		// Ensure that storage is mounted for state path checks and for backup.yaml updates.
-		if pool != nil {
-			ourStart, err := pool.MountInstance(c, nil)
-			if err != nil {
-				return err
-			}
-			if ourStart {
-				defer pool.UnmountInstance(c, nil)
-			}
-		} else {
-			ourStart, err := c.mount()
-			if err != nil {
-				return err
-			}
-			if ourStart {
-				defer c.unmount()
-			}
+		ourStart, err := pool.MountInstance(c, nil)
+		if err != nil {
+			return err
+		}
+		if ourStart {
+			defer pool.UnmountInstance(c, nil)
 		}
 	}
 
@@ -3302,17 +3292,9 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
 	logger.Info("Restoring container", ctxMap)
 
 	// Restore the rootfs.
-	if pool != nil {
-		err = pool.RestoreInstanceSnapshot(c, sourceContainer, nil)
-		if err != nil {
-			return err
-		}
-	} else {
-		err = c.storage.ContainerRestore(c, sourceContainer)
-		if err != nil {
-			logger.Error("Failed restoring container filesystem", ctxMap)
-			return err
-		}
+	err = pool.RestoreInstanceSnapshot(c, sourceContainer, nil)
+	if err != nil {
+		return err
 	}
 
 	// Restore the configuration.
@@ -4803,12 +4785,6 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error {
 
 	logger.Info("Migrating container", ctxMap)
 
-	// Initialize storage interface for the container.
-	err = c.initStorage()
-	if err != nil {
-		return err
-	}
-
 	prettyCmd := ""
 	switch args.cmd {
 	case lxc.MIGRATE_PRE_DUMP:
@@ -5667,12 +5643,6 @@ func (c *containerLXC) cpuState() api.InstanceStateCPU {
 func (c *containerLXC) diskState() map[string]api.InstanceStateDisk {
 	disk := map[string]api.InstanceStateDisk{}
 
-	// Initialize storage interface for the container.
-	err := c.initStorage()
-	if err != nil {
-		return disk
-	}
-
 	for _, dev := range c.expandedDevices.Sorted() {
 		if dev.Config["type"] != "disk" {
 			continue

From 8f4795bef87e0de5b32c8d83299c83feb9942750 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 11:47:54 +0000
Subject: [PATCH 7/9] lxd/migrate/container: Removes calls to old storage layer

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/migrate_container.go | 114 +++++++++------------------------------
 1 file changed, 25 insertions(+), 89 deletions(-)

diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index f242b42eb5..70751a70a7 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -432,8 +432,6 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
 		return err
 	}
 
-	var legacyDriver MigrationStorageSourceDriver
-	var legacyCleanup func()            // Called after migration, to remove any temporary snapshots, etc.
 	var migrationTypes []migration.Type // Negotiated migration types.
 	var rsyncBwlimit string             // Used for CRIU state and legacy storage rsync transfers.
 
@@ -454,10 +452,6 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
 	// the purpose of using defer. An abort function reduces the odds of mishandling errors
 	// without introducing the fragility of closing on err.
 	abort := func(err error) error {
-		if legacyCleanup != nil {
-			legacyCleanup()
-		}
-
 		go s.sendControl(err)
 		return err
 	}
@@ -469,71 +463,27 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
 	// Indicate this info to the storage driver so that it can alter its behaviour if needed.
 	volSourceArgs.MultiSync = s.live || (respHeader.Criu != nil && *respHeader.Criu == migration.CRIUType_NONE)
 
-	if pool != nil {
-		rsyncBwlimit = pool.Driver().Config()["rsync.bwlimit"]
-		migrationTypes, err = migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
-		if err != nil {
-			logger.Errorf("Failed to negotiate migration type: %v", err)
-			return abort(err)
-		}
-
-		sendSnapshotNames := snapshotNames
-
-		// If we are in refresh mode, only send the snapshots the target has asked for.
-		if respHeader.GetRefresh() {
-			sendSnapshotNames = respHeader.GetSnapshotNames()
-		}
-
-		volSourceArgs.Name = s.instance.Name()
-		volSourceArgs.MigrationType = migrationTypes[0]
-		volSourceArgs.Snapshots = sendSnapshotNames
-		volSourceArgs.TrackProgress = true
-		err = pool.MigrateInstance(s.instance, &shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
-		if err != nil {
-			return abort(err)
-		}
-	} else {
-		// Handle zfs options.
-		zfsFeatures := respHeader.GetZfsFeaturesSlice()
-
-		// Set source args.
-		sourceArgs := MigrationSourceArgs{
-			Instance:      s.instance,
-			InstanceOnly:  s.instanceOnly,
-			RsyncFeatures: rsyncFeatures,
-			ZfsFeatures:   zfsFeatures,
-		}
-
-		// Initialize storage driver.
-		legacyDriver, err = ct.Storage().MigrationSource(sourceArgs)
-		if err != nil {
-			return abort(err)
-		}
-		legacyCleanup = legacyDriver.Cleanup
+	rsyncBwlimit = pool.Driver().Config()["rsync.bwlimit"]
+	migrationTypes, err = migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
+	if err != nil {
+		logger.Errorf("Failed to negotiate migration type: %v", err)
+		return abort(err)
+	}
 
-		if respHeader.GetRefresh() || *offerHeader.Fs != *respHeader.Fs {
-			myType := migration.MigrationFSType_RSYNC
-			respHeader.Fs = &myType
+	sendSnapshotNames := snapshotNames
 
-			if respHeader.GetRefresh() {
-				legacyDriver, _ = rsyncRefreshSource(respHeader.GetSnapshotNames(), sourceArgs)
-			} else {
-				legacyDriver, _ = rsyncMigrationSource(sourceArgs)
-			}
-
-			// Check if this storage pool has a rate limit set for rsync.
-			poolwritable := ct.Storage().GetStoragePoolWritable()
-			if poolwritable.Config != nil {
-				rsyncBwlimit = poolwritable.Config["rsync.bwlimit"]
-			}
-		}
+	// If we are in refresh mode, only send the snapshots the target has asked for.
+	if respHeader.GetRefresh() {
+		sendSnapshotNames = respHeader.GetSnapshotNames()
+	}
 
-		logger.Debugf("SendWhileRunning starting")
-		err = legacyDriver.SendWhileRunning(s.fsConn, migrateOp, rsyncBwlimit, s.instanceOnly)
-		if err != nil {
-			return abort(err)
-		}
-		logger.Debugf("SendWhileRunning finished")
+	volSourceArgs.Name = s.instance.Name()
+	volSourceArgs.MigrationType = migrationTypes[0]
+	volSourceArgs.Snapshots = sendSnapshotNames
+	volSourceArgs.TrackProgress = true
+	err = pool.MigrateInstance(s.instance, &shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
+	if err != nil {
+		return abort(err)
 	}
 
 	restoreSuccess := make(chan bool, 1)
@@ -716,31 +666,17 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
 
 	// Perform final sync if in multi sync mode.
 	if volSourceArgs.MultiSync {
-		if pool != nil {
-			// Indicate to the storage driver we are doing final sync and because of this don't send
-			// snapshots as they don't need to have a final sync as not being modified.
-			volSourceArgs.FinalSync = true
-			volSourceArgs.Snapshots = nil
+		// Indicate to the storage driver we are doing final sync and because of this don't send
+		// snapshots as they don't need to have a final sync as not being modified.
+		volSourceArgs.FinalSync = true
+		volSourceArgs.Snapshots = nil
 
-			err = pool.MigrateInstance(s.instance, &shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
-			if err != nil {
-				return abort(err)
-			}
-		} else {
-			logger.Debugf("SendAfterCheckpoint starting")
-			err = legacyDriver.SendAfterCheckpoint(s.fsConn, rsyncBwlimit)
-			if err != nil {
-				return abort(err)
-			}
-			logger.Debugf("SendAfterCheckpoint finished")
+		err = pool.MigrateInstance(s.instance, &shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
+		if err != nil {
+			return abort(err)
 		}
 	}
 
-	// Perform any storage level cleanup, such as removing any temporary snapshots.
-	if legacyCleanup != nil {
-		legacyCleanup()
-	}
-
 	msg := migration.MigrationControl{}
 	err = s.recv(&msg)
 	if err != nil {

From 0bffb5e91b3a5bb7ee01adc239b517c737ed4e89 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 11:48:12 +0000
Subject: [PATCH 8/9] lxd/migrate/storage/volumes: Removes calls to old storage
 layer

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/migrate_storage_volumes.go | 85 +++++++---------------------------
 1 file changed, 16 insertions(+), 69 deletions(-)

diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index fdf17d7f1b..66a959dd85 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -108,77 +108,24 @@ func (s *migrationSourceWs) DoStorage(state *state.State, poolName string, volNa
 	}
 
 	// Use new storage layer for migration if supported.
-	if pool != nil {
-		migrationTypes, err := migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
-		if err != nil {
-			logger.Errorf("Failed to negotiate migration type: %v", err)
-			s.sendControl(err)
-			return err
-		}
-
-		volSourceArgs := &migration.VolumeSourceArgs{
-			Name:          volName,
-			MigrationType: migrationTypes[0],
-			Snapshots:     snapshotNames,
-			TrackProgress: true,
-		}
-
-		err = pool.MigrateCustomVolume(&shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
-		if err != nil {
-			go s.sendControl(err)
-			return err
-		}
-	} else {
-		// Use legacy storage layer for migration.
-
-		// Get target's rsync options.
-		rsyncFeatures := respHeader.GetRsyncFeaturesSlice()
-		if !shared.StringInSlice("bidirectional", rsyncFeatures) {
-			// If no bi-directional support, assume LXD 3.7 level
-			// NOTE: Do NOT extend this list of arguments
-			rsyncFeatures = []string{"xattrs", "delete", "compress"}
-		}
-
-		// Get target's zfs options.
-		zfsFeatures := respHeader.GetZfsFeaturesSlice()
-
-		// Set source args
-		sourceArgs := MigrationSourceArgs{
-			RsyncFeatures: rsyncFeatures,
-			ZfsFeatures:   zfsFeatures,
-			VolumeOnly:    s.volumeOnly,
-		}
-
-		driver, fsErr := s.storage.StorageMigrationSource(sourceArgs)
-		if fsErr != nil {
-			logger.Errorf("Failed to initialize new storage volume migration driver")
-			s.sendControl(fsErr)
-			return fsErr
-		}
-
-		bwlimit := ""
-
-		if *offerHeader.Fs != *respHeader.Fs {
-			driver, _ = rsyncStorageMigrationSource(sourceArgs)
-
-			// Check if this storage pool has a rate limit set for rsync.
-			poolwritable := s.storage.GetStoragePoolWritable()
-			if poolwritable.Config != nil {
-				bwlimit = poolwritable.Config["rsync.bwlimit"]
-			}
-		}
+	migrationTypes, err := migration.MatchTypes(respHeader, migration.MigrationFSType_RSYNC, poolMigrationTypes)
+	if err != nil {
+		logger.Errorf("Failed to negotiate migration type: %v", err)
+		s.sendControl(err)
+		return err
+	}
 
-		abort := func(err error) error {
-			driver.Cleanup()
-			go s.sendControl(err)
-			return err
-		}
+	volSourceArgs := &migration.VolumeSourceArgs{
+		Name:          volName,
+		MigrationType: migrationTypes[0],
+		Snapshots:     snapshotNames,
+		TrackProgress: true,
+	}
 
-		err = driver.SendStorageVolume(s.fsConn, migrateOp, bwlimit, s.storage, s.volumeOnly)
-		if err != nil {
-			logger.Errorf("Failed to send storage volume")
-			return abort(err)
-		}
+	err = pool.MigrateCustomVolume(&shared.WebsocketIO{Conn: s.fsConn}, volSourceArgs, migrateOp)
+	if err != nil {
+		go s.sendControl(err)
+		return err
 	}
 
 	msg := migration.MigrationControl{}

From 55f2b700c9a4692407d5b4d4955a5a130e6e663f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 11:48:39 +0000
Subject: [PATCH 9/9] lxd/patches: Switches upgradeFromStorageTypeLvm to use
 new storage layer

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/patches.go | 68 +++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/lxd/patches.go b/lxd/patches.go
index c69503407d..bd13a029eb 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -1369,14 +1369,6 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 					// and it means that this was a
 					// mixed-storage LXD instance.
 
-					// Initialize storage interface for the new
-					// snapshot.
-					csStorage, err := storagePoolVolumeContainerLoadInit(d.State(), "default", cs)
-					if err != nil {
-						logger.Errorf("Failed to initialize new storage interface for LVM container %s: %s", cs, err)
-						return err
-					}
-
 					// Load the snapshot from the database.
 					csStruct, err := instance.LoadByProjectAndName(d.State(), "default", cs)
 					if err != nil {
@@ -1384,36 +1376,56 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 						return err
 					}
 
-					// Create an empty LVM logical volume
-					// for the snapshot.
-					err = csStorage.ContainerSnapshotCreateEmpty(csStruct)
+					pool, err := storagePools.GetPoolByInstance(d.State(), csStruct)
 					if err != nil {
-						logger.Errorf("Failed to create empty LVM logical volume for container %s: %s", cs, err)
 						return err
 					}
 
-					// In case the new LVM logical volume
-					// for the snapshot is not mounted mount
-					// it.
-					if !shared.IsMountPoint(newSnapshotMntPoint) {
-						_, err = csStorage.ContainerMount(csStruct)
-						if err != nil {
-							logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s", cs, err)
-							return err
-						}
+					parent, _, _ := shared.InstanceGetParentAndSnapshotName(csStruct.Name())
+					parentInst, err := instance.LoadByProjectAndName(d.State(), csStruct.Project(), parent)
+					if err != nil {
+						logger.Errorf("Failed to load parent LVM container %s: %s", cs, err)
+						return err
 					}
 
-					// Use rsync to fill the empty volume.
-					output, err := rsync.LocalCopy(oldSnapshotMntPoint, newSnapshotMntPoint, "", true)
+					// Create an empty LVM logical volume for the snapshot.
+					err = pool.CreateInstanceSnapshot(csStruct, parentInst, nil)
 					if err != nil {
-						csStorage.ContainerDelete(csStruct)
-						return fmt.Errorf("rsync failed: %s", string(output))
+						logger.Errorf("Failed to create LVM logical volume snapshot for container %s: %s", cs, err)
+						return err
 					}
 
-					// Remove the old snapshot.
-					err = os.RemoveAll(oldSnapshotMntPoint)
+					err = func() error {
+						// In case the new LVM logical volume for the snapshot is not mounted mount it.
+						if !shared.IsMountPoint(newSnapshotMntPoint) {
+							ourMount, err := pool.MountInstanceSnapshot(csStruct, nil)
+							if err != nil {
+								logger.Errorf("Failed to mount new empty LVM logical volume for container %s: %s", cs, err)
+								return err
+							}
+
+							if ourMount {
+								defer pool.UnmountInstanceSnapshot(csStruct, nil)
+							}
+						}
+
+						// Use rsync to fill the snapshot volume.
+						output, err := rsync.LocalCopy(oldSnapshotMntPoint, newSnapshotMntPoint, "", true)
+						if err != nil {
+							pool.DeleteInstanceSnapshot(csStruct, nil)
+							return fmt.Errorf("rsync failed: %s", string(output))
+						}
+
+						// Remove the old snapshot.
+						err = os.RemoveAll(oldSnapshotMntPoint)
+						if err != nil {
+							logger.Errorf("Failed to remove old container %s: %s", oldSnapshotMntPoint, err)
+							return err
+						}
+
+						return nil
+					}()
 					if err != nil {
-						logger.Errorf("Failed to remove old container %s: %s", oldSnapshotMntPoint, err)
 						return err
 					}
 				}


More information about the lxc-devel mailing list