[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