[lxc-devel] [lxd/master] Storage containerLXC linking
tomponline on Github
lxc-bot at linuxcontainers.org
Thu Dec 5 17:14:34 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 602 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191205/051dbc8e/attachment-0001.bin>
-------------- next part --------------
From 3e7bad04011c95f7c92f2b60ae72a27c2367cae4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 5 Dec 2019 15:41:39 +0000
Subject: [PATCH 1/4] lxd/container/lxc: Unexport storageStartSensitive
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_lxc.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 09120cfca4..3dc126200f 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -2572,7 +2572,7 @@ func (c *containerLXC) OnStart() error {
c.fromHook = true
// Start the storage for this container
- ourStart, err := c.StorageStartSensitive()
+ ourStart, err := c.storageStartSensitive()
if err != nil {
return err
}
@@ -6216,7 +6216,7 @@ func (c *containerLXC) StorageStart() (bool, error) {
return false, err
}
- isOurOperation, err := c.StorageStartSensitive()
+ isOurOperation, err := c.storageStartSensitive()
// Remove this as soon as zfs is fixed
if c.storage.GetStorageType() == storageTypeZfs && err == unix.EBUSY {
return isOurOperation, nil
@@ -6226,7 +6226,7 @@ func (c *containerLXC) StorageStart() (bool, error) {
}
// Kill this function as soon as zfs is fixed.
-func (c *containerLXC) StorageStartSensitive() (bool, error) {
+func (c *containerLXC) storageStartSensitive() (bool, error) {
// Initialize storage interface for the container.
err := c.initStorage()
if err != nil {
From 57aa879f7a965db338a6da0e11e4cd0a580af3ef Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 5 Dec 2019 17:08:54 +0000
Subject: [PATCH 2/4] lxd/vm/qemu: Makes mount and unmount functions behave the
same as containerLXC's
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/vm_qemu.go | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go
index 284ef6df37..c362f6355b 100644
--- a/lxd/vm_qemu.go
+++ b/lxd/vm_qemu.go
@@ -345,7 +345,7 @@ func (vm *vmQemu) getMonitorEventHandler() func(event string, data map[string]in
}
}
-// mount mounts the instance's config volume if needed.
+// mount the instance's config volume if needed.
func (vm *vmQemu) mount() (ourMount bool, err error) {
var pool storagePools.Pool
pool, err = vm.getStoragePool()
@@ -361,19 +361,20 @@ func (vm *vmQemu) mount() (ourMount bool, err error) {
return
}
-// unmount unmounts the instance's config volume if needed.
-func (vm *vmQemu) unmount() error {
- pool, err := vm.getStoragePool()
+// unmount the instance's config volume if needed.
+func (vm *vmQemu) unmount() (unmounted bool, err error) {
+ var pool storagePools.Pool
+ pool, err = vm.getStoragePool()
if err != nil {
- return err
+ return
}
- _, err = pool.UnmountInstance(vm, nil)
+ unmounted, err = pool.UnmountInstance(vm, nil)
if err != nil {
- return err
+ return
}
- return nil
+ return
}
// generateAgentCert creates the necessary server key and certificate if needed.
From 4ae3f43d52f35c1350c2014972f20557e90c3205 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 5 Dec 2019 17:09:26 +0000
Subject: [PATCH 3/4] lxd/storage/backend/lxd: Fixes
MountInstanceSnapshot/UnmountInstanceSnapshot functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/backend_lxd.go | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index c6f40d6345..fadbd99ded 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -1461,11 +1461,11 @@ func (b *lxdBackend) MountInstanceSnapshot(inst instance.Instance, op *operation
return false, err
}
- // Get the volume name on storage.
- volStorageName := project.Prefix(inst.Project(), inst.Name())
+ // Get the parent and snapshot name.
+ parentName, snapName, _ := shared.InstanceGetParentAndSnapshotName(inst.Name())
- // Get the snapshot name.
- _, snapName, _ := shared.InstanceGetParentAndSnapshotName(inst.Name())
+ // Get the volume name on storage.
+ volStorageName := project.Prefix(inst.Project(), parentName)
return b.driver.MountVolumeSnapshot(volType, volStorageName, snapName, op)
}
@@ -1486,11 +1486,11 @@ func (b *lxdBackend) UnmountInstanceSnapshot(inst instance.Instance, op *operati
return false, err
}
- // Get the volume name on storage.
- volStorageName := project.Prefix(inst.Project(), inst.Name())
+ // Get the parent and snapshot name.
+ parentName, snapName, _ := shared.InstanceGetParentAndSnapshotName(inst.Name())
- // Get the snapshot name.
- _, snapName, _ := shared.InstanceGetParentAndSnapshotName(inst.Name())
+ // Get the volume name on storage.
+ volStorageName := project.Prefix(inst.Project(), parentName)
return b.driver.UnmountVolumeSnapshot(volType, volStorageName, snapName, op)
}
From 2087c449e1c9aba80eba1c89b113bd7d5990e2f4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 5 Dec 2019 17:10:16 +0000
Subject: [PATCH 4/4] lxd/container/lxc: Links to new storage pkg
- Creates unexported mount/unmount functions the same as vmQemu (that are new storage pkg aware).
- Links StorageStart/StorageStop functions to them and marks functions as deprecated.
- Removes internal use of StorageStart/StorageStop (plan to eventually remove these once external uses are changed).
- Adds new storage pool loader and cache.
- Adds storage pool type function (that is new storage pkg aware), and updates usage.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_lxc.go | 193 +++++++++++++++++++++++++++++++++----------
1 file changed, 151 insertions(+), 42 deletions(-)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 3dc126200f..1185fd506e 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -541,7 +541,10 @@ type containerLXC struct {
idmapset *idmap.IdmapSet
// Storage
- storage storage
+ // Do not use these variables directly, instead use their associated get functions so they
+ // will be initialised on demand.
+ storage storage
+ storagePool storagePools.Pool
// Clustering
node string
@@ -2083,38 +2086,43 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
logger.Debugf("Container idmap changed, remapping")
c.updateProgress("Remapping container filesystem")
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return "", postStartHooks, errors.Wrap(err, "Storage start")
}
+ storageType, err := c.getStorageType()
+ if err != nil {
+ return "", postStartHooks, errors.Wrap(err, "Storage type")
+ }
+
if diskIdmap != nil {
- if c.Storage().GetStorageType() == storageTypeZfs {
+ if storageType == "zfs" {
err = diskIdmap.UnshiftRootfs(c.RootfsPath(), zfsIdmapSetSkipper)
- } else if c.Storage().GetStorageType() == storageTypeBtrfs {
+ } else if storageType == "btrfs" {
err = UnshiftBtrfsRootfs(c.RootfsPath(), diskIdmap)
} else {
err = diskIdmap.UnshiftRootfs(c.RootfsPath(), nil)
}
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
}
if nextIdmap != nil && !c.state.OS.Shiftfs {
- if c.Storage().GetStorageType() == storageTypeZfs {
+ if storageType == "zfs" {
err = nextIdmap.ShiftRootfs(c.RootfsPath(), zfsIdmapSetSkipper)
- } else if c.Storage().GetStorageType() == storageTypeBtrfs {
+ } else if storageType == "btrfs" {
err = ShiftBtrfsRootfs(c.RootfsPath(), nextIdmap)
} else {
err = nextIdmap.ShiftRootfs(c.RootfsPath(), nil)
}
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
@@ -2327,7 +2335,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
}
// Storage is guaranteed to be mountable now (must be called after devices setup).
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return "", postStartHooks, err
}
@@ -2344,7 +2352,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
currentIdmapset, err := c.CurrentIdmap()
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
@@ -2357,7 +2365,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
err = os.Chown(c.Path(), int(uid), 0)
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
@@ -2366,7 +2374,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
err = os.Chmod(c.Path(), 0100)
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
@@ -2375,7 +2383,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
err = writeBackupFile(c)
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return "", postStartHooks, err
}
@@ -2437,7 +2445,7 @@ func (c *containerLXC) Start(stateful bool) error {
}
// Ensure that the container storage volume is mounted.
- _, err = c.StorageStart()
+ _, err = c.mount()
if err != nil {
return errors.Wrap(err, "Storage start")
}
@@ -2581,7 +2589,7 @@ func (c *containerLXC) OnStart() error {
err = apparmor.LoadProfile(c)
if err != nil {
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return err
}
@@ -2594,7 +2602,7 @@ func (c *containerLXC) OnStart() error {
if err != nil {
apparmor.Destroy(c)
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return err
}
@@ -2604,7 +2612,7 @@ func (c *containerLXC) OnStart() error {
if err != nil {
apparmor.Destroy(c)
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return err
}
@@ -2614,7 +2622,7 @@ func (c *containerLXC) OnStart() error {
if err != nil {
apparmor.Destroy(c)
if ourStart {
- c.StorageStop()
+ c.unmount()
}
return err
}
@@ -2905,7 +2913,7 @@ func (c *containerLXC) OnStop(target string) error {
}
// Stop the storage for this container
- _, err = c.StorageStop()
+ _, err = c.unmount()
if err != nil {
if op != nil {
op.Done(err)
@@ -3342,12 +3350,12 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
return err
}
- ourStart, err := c.StorageStart()
+ ourStart, err := c.mount()
if err != nil {
return err
}
if ourStart {
- defer c.StorageStop()
+ defer c.unmount()
}
}
@@ -3407,12 +3415,12 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
defer pool.UnmountInstance(c, nil)
}
} else {
- ourStart, err := c.StorageStart()
+ ourStart, err := c.mount()
if err != nil {
return err
}
if ourStart {
- defer c.StorageStop()
+ defer c.unmount()
}
}
}
@@ -4885,13 +4893,13 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
logger.Info("Exporting container", ctxMap)
// Start the storage
- ourStart, err := c.StorageStart()
+ ourStart, err := c.mount()
if err != nil {
logger.Error("Failed exporting container", ctxMap)
return err
}
if ourStart {
- defer c.StorageStop()
+ defer c.unmount()
}
// Unshift the container
@@ -5231,20 +5239,25 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error {
}
if idmapset != nil {
- ourStart, err := c.StorageStart()
+ ourStart, err := c.mount()
if err != nil {
return err
}
- if c.Storage().GetStorageType() == storageTypeZfs {
+ storageType, err := c.getStorageType()
+ if err != nil {
+ return errors.Wrap(err, "Storage type")
+ }
+
+ if storageType == "zfs" {
err = idmapset.ShiftRootfs(args.stateDir, zfsIdmapSetSkipper)
- } else if c.Storage().GetStorageType() == storageTypeBtrfs {
+ } else if storageType == "btrfs" {
err = ShiftBtrfsRootfs(args.stateDir, idmapset)
} else {
err = idmapset.ShiftRootfs(args.stateDir, nil)
}
if ourStart {
- _, err2 := c.StorageStop()
+ _, err2 := c.unmount()
if err != nil {
return err
}
@@ -5514,7 +5527,7 @@ func (c *containerLXC) FileExists(path string) error {
var ourStart bool
var err error
if !c.IsRunning() {
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return err
}
@@ -5533,7 +5546,7 @@ func (c *containerLXC) FileExists(path string) error {
// Tear down container storage if needed
if !c.IsRunning() && ourStart {
- _, err := c.StorageStop()
+ _, err := c.unmount()
if err != nil {
return err
}
@@ -5562,7 +5575,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o
var err error
// Setup container storage if needed
if !c.IsRunning() {
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return -1, -1, 0, "", nil, err
}
@@ -5582,7 +5595,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o
// Tear down container storage if needed
if !c.IsRunning() && ourStart {
- _, err := c.StorageStop()
+ _, err := c.unmount()
if err != nil {
return -1, -1, 0, "", nil, err
}
@@ -5702,7 +5715,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, ui
var err error
// Setup container storage if needed
if !c.IsRunning() {
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return err
}
@@ -5735,7 +5748,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, ui
// Tear down container storage if needed
if !c.IsRunning() && ourStart {
- _, err := c.StorageStop()
+ _, err := c.unmount()
if err != nil {
return err
}
@@ -5777,7 +5790,7 @@ func (c *containerLXC) FileRemove(path string) error {
// Setup container storage if needed
if !c.IsRunning() {
- ourStart, err = c.StorageStart()
+ ourStart, err = c.mount()
if err != nil {
return err
}
@@ -5796,7 +5809,7 @@ func (c *containerLXC) FileRemove(path string) error {
// Tear down container storage if needed
if !c.IsRunning() && ourStart {
- _, err := c.StorageStop()
+ _, err := c.unmount()
if err != nil {
return err
}
@@ -6200,8 +6213,13 @@ func (c *containerLXC) processesState() int64 {
return int64(len(pids))
}
-// Storage functions
+// Storage gets instance's legacy storage pool. Deprecated.
func (c *containerLXC) Storage() storage {
+ return c.legacyStorage()
+}
+
+// legacyStorage returns the instance's legacy storage pool. Deprecated.
+func (c *containerLXC) legacyStorage() storage {
if c.storage == nil {
c.initStorage()
}
@@ -6209,9 +6227,70 @@ func (c *containerLXC) Storage() storage {
return c.storage
}
+// getStoragePool returns the current storage pool handle. To avoid a DB lookup each time this
+// function is called, the handle is cached internally in the vmQemu struct.
+func (c *containerLXC) getStoragePool() (storagePools.Pool, error) {
+ if c.storagePool != nil {
+ return c.storagePool, nil
+ }
+
+ pool, err := storagePools.GetPoolByInstance(c.state, c)
+ if err != nil {
+ return nil, err
+ }
+ c.storagePool = pool
+
+ return c.storagePool, nil
+}
+
+// getStorageType returns the storage type of the instance's storage pool.
+func (c *containerLXC) getStorageType() (string, error) {
+ // Check if we can load new storage layer for pool driver type.
+ pool, err := c.getStoragePool()
+ if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented {
+ if err != nil {
+ return "", err
+ }
+
+ return pool.Driver().Info().Name, nil
+ }
+
+ return storageTypeToString(c.legacyStorage().GetStorageType())
+}
+
+// StorageStart mounts the instance's rootfs volume. Deprecated.
func (c *containerLXC) StorageStart() (bool, error) {
- // Initialize storage interface for the container.
- err := c.initStorage()
+ return c.mount()
+}
+
+// mount the instance's rootfs volume if needed.
+func (c *containerLXC) mount() (bool, error) {
+ // Check if we can load new storage layer for pool driver type.
+ pool, err := c.getStoragePool()
+ if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented {
+ if err != nil {
+ return false, err
+ }
+
+ if c.IsSnapshot() {
+ ourMount, err := pool.MountInstanceSnapshot(c, nil)
+ if err != nil {
+ return false, err
+ }
+
+ return ourMount, nil
+ }
+
+ ourMount, err := pool.MountInstance(c, nil)
+ if err != nil {
+ return false, err
+ }
+
+ return ourMount, nil
+ }
+
+ // Initialize legacy storage interface for the container.
+ err = c.initStorage()
if err != nil {
return false, err
}
@@ -6243,9 +6322,39 @@ func (c *containerLXC) storageStartSensitive() (bool, error) {
return isOurOperation, err
}
+// StorageStop unmounts the instance's rootfs volume. Deprecated.
func (c *containerLXC) StorageStop() (bool, error) {
- // Initialize storage interface for the container.
- err := c.initStorage()
+ return c.unmount()
+}
+
+// unmount the instance's rootfs volume if needed.
+func (c *containerLXC) unmount() (bool, error) {
+ // Check if we can load new storage layer for pool driver type.
+ pool, err := c.getStoragePool()
+ if err != storageDrivers.ErrUnknownDriver && err != storageDrivers.ErrNotImplemented {
+ if err != nil {
+ return false, err
+ }
+
+ if c.IsSnapshot() {
+ unmounted, err := pool.UnmountInstanceSnapshot(c, nil)
+ if err != nil {
+ return false, err
+ }
+
+ return unmounted, nil
+ }
+
+ unmounted, err := pool.UnmountInstance(c, nil)
+ if err != nil {
+ return false, err
+ }
+
+ return unmounted, nil
+ }
+
+ // Initialize legacy storage interface for the container.
+ err = c.initStorage()
if err != nil {
return false, err
}
More information about the lxc-devel
mailing list