[lxc-devel] [lxd/master] lvm: allow loop-backed storage pools
brauner on Github
lxc-bot at linuxcontainers.org
Wed Mar 1 14:19:45 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 398 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170301/035732fa/attachment.bin>
-------------- next part --------------
From 36ced25d40ead29924bd28e74dc8150c4dfb9bc9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 1 Mar 2017 15:06:10 +0100
Subject: [PATCH 1/2] storage_cgo: add set_autoclear_loop_device()
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_cgo.go | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index d7a6ba3..c5922e6 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -28,6 +28,9 @@ package main
#define LXD_MAX_LOOP_PATHLEN (2 * sizeof("loop/")) + LXD_NUMSTRLEN64 + sizeof("backing_file") + 1
// If a loop file is already associated with a loop device, find it.
+// This looks at "/sys/block" to avoid having to parse all of "/dev". Also, this
+// allows to retrieve the full name of the backing file even if
+// strlen(backing file) > LO_NAME_SIZE.
static int find_associated_loop_device(const char *loop_file,
char *loop_dev_name)
{
@@ -98,6 +101,7 @@ static int find_associated_loop_device(const char *loop_file,
continue;
}
+ // Create path to loop device.
ret = snprintf(loop_dev_name, LO_NAME_SIZE, "/dev/%s",
dp->d_name);
if (ret < 0 || ret >= LO_NAME_SIZE) {
@@ -105,7 +109,14 @@ static int find_associated_loop_device(const char *loop_file,
fd = -1;
continue;
}
+ close(fd);
+ // Open fd to loop device.
+ fd = open(loop_dev_name, O_RDWR);
+ if (fd < 0) {
+ close(fd);
+ fd = -1;
+ }
break;
}
@@ -239,6 +250,20 @@ on_error:
return fd_loop;
}
+
+// Note that this does not guarantee to clear the loop device in time so that
+// find_associated_loop_device() will not report that there still is a
+// configured device (udev and so on...). So don't call
+// find_associated_loop_device() after having called
+// set_autoclear_loop_device().
+int set_autoclear_loop_device(int fd_loop)
+{
+ struct loop_info64 lo64;
+
+ memset(&lo64, 0, sizeof(lo64));
+ lo64.lo_flags = LO_FLAGS_AUTOCLEAR;
+ return ioctl(fd_loop, LOOP_SET_STATUS64, &lo64);
+}
*/
import "C"
@@ -277,3 +302,8 @@ func prepareLoopDev(source string, flags int) (*os.File, error) {
return os.NewFile(uintptr(loopFd), C.GoString((*C.char)(cLoopDev))), nil
}
+
+func setAutoclearOnLoopDev(loopFd int) error {
+ _, err := C.set_autoclear_loop_device(C.int(loopFd))
+ return err
+}
From 6d9dd00e2b225e8734b36b303f4b4afbeb48575c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 1 Mar 2017 15:06:27 +0100
Subject: [PATCH 2/2] lvm: allow loop-backed lvm storage pools
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_lvm.go | 248 +++++++++++++++++++++++++++++++++++++++-----
lxd/storage_pools_config.go | 2 +-
test/suites/storage.sh | 31 ++++++
3 files changed, 252 insertions(+), 29 deletions(-)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index a9697f9..6bcf02d 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -211,6 +211,7 @@ func containerNameToLVName(containerName string) string {
type storageLvm struct {
vgName string
thinPoolName string
+ loopInfo *os.File
storageShared
}
@@ -333,22 +334,14 @@ func (s *storageLvm) StoragePoolInit() error {
s.vgName = s.pool.Config["lvm.vg_name"]
}
- if source == "" {
- return fmt.Errorf("Loop backed lvm storage pools are not supported.")
- } else {
- if filepath.IsAbs(source) {
- if !shared.IsBlockdevPath(source) {
- return fmt.Errorf("Loop backed lvm storage pools are not supported.")
- }
- } else {
- ok, err := storageVGExists(source)
- if err != nil {
- // Internal error.
- return err
- } else if !ok {
- // Volume group does not exist.
- return fmt.Errorf("The requested volume group \"%s\" does not exist.", source)
- }
+ if source != "" && !filepath.IsAbs(source) {
+ ok, err := storageVGExists(source)
+ if err != nil {
+ // Internal error.
+ return err
+ } else if !ok {
+ // Volume group does not exist.
+ return fmt.Errorf("The requested volume group \"%s\" does not exist.", source)
}
}
@@ -358,8 +351,16 @@ func (s *storageLvm) StoragePoolInit() error {
func (s *storageLvm) StoragePoolCheck() error {
shared.LogDebugf("Checking LVM storage pool \"%s\".", s.pool.Name)
+ _, err := s.StoragePoolMount()
+ if err != nil {
+ return err
+ }
+ if s.loopInfo != nil {
+ defer s.loopInfo.Close()
+ }
+
poolName := s.getOnDiskPoolName()
- err := storageVGActivate(poolName)
+ err = storageVGActivate(poolName)
if err != nil {
return err
}
@@ -426,16 +427,77 @@ func (s *storageLvm) StoragePoolCreate() error {
}
}()
- // Clear size as we're currently not using it for LVM.
- s.pool.Config["size"] = ""
poolName := s.getOnDiskPoolName()
source := s.pool.Config["source"]
if source == "" {
- return fmt.Errorf("Loop backed lvm storage pools are not supported.")
+ source = filepath.Join(shared.VarPath("disks"), fmt.Sprintf("%s.img", s.pool.Name))
+ s.pool.Config["source"] = source
+
+ if s.pool.Config["lvm.vg_name"] == "" {
+ s.pool.Config["lvm.vg_name"] = poolName
+ }
+
+ f, err := os.Create(source)
+ if err != nil {
+ return fmt.Errorf("Failed to open %s: %s", source, err)
+ }
+ defer f.Close()
+
+ err = f.Chmod(0600)
+ if err != nil {
+ return fmt.Errorf("Failed to chmod %s: %s", source, err)
+ }
+
+ size, err := shared.ParseByteSizeString(s.pool.Config["size"])
+ if err != nil {
+ return err
+ }
+ err = f.Truncate(size)
+ if err != nil {
+ return fmt.Errorf("Failed to create sparse file %s: %s", source, err)
+ }
+
+ _, err = s.StoragePoolMount()
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if tryUndo {
+ os.Remove(source)
+ }
+ }()
+
+ // Check if the physical volume already exists.
+ loopDevicePath := s.loopInfo.Name()
+ defer s.loopInfo.Close()
+ ok, err := storagePVExists(loopDevicePath)
+ if err == nil && !ok {
+ // Create a new lvm physical volume.
+ output, err := exec.Command("pvcreate", loopDevicePath).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("Failed to create the physical volume for the lvm storage pool: %s.", output)
+ }
+ defer func() {
+ if tryUndo {
+ exec.Command("pvremove", loopDevicePath).Run()
+ }
+ }()
+ }
+
+ // Check if the volume group already exists.
+ ok, err = storageVGExists(poolName)
+ if err == nil && !ok {
+ // Create a volume group on the physical volume.
+ output, err := exec.Command("vgcreate", poolName, loopDevicePath).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("Failed to create the volume group for the lvm storage pool: %s.", output)
+ }
+ }
} else {
+ s.pool.Config["size"] = ""
if filepath.IsAbs(source) {
if !shared.IsBlockdevPath(source) {
- return fmt.Errorf("Loop backed lvm storage pools are not supported.")
+ return fmt.Errorf("Custom loop file locations are not supported.")
}
if s.pool.Config["lvm.vg_name"] == "" {
@@ -503,6 +565,18 @@ func (s *storageLvm) StoragePoolCreate() error {
func (s *storageLvm) StoragePoolDelete() error {
shared.LogInfof("Deleting LVM storage pool \"%s\".", s.pool.Name)
+ _, err := s.StoragePoolMount()
+ if err != nil {
+ return err
+ }
+ if s.loopInfo != nil {
+ err := setAutoclearOnLoopDev(int(s.loopInfo.Fd()))
+ if err != nil {
+ shared.LogWarnf("Failed to set LO_FLAGS_AUTOCLEAR on loop device: %s. Manual cleanup needed.", err)
+ }
+ defer s.loopInfo.Close()
+ }
+
source := s.pool.Config["source"]
if source == "" {
return fmt.Errorf("No \"source\" property found for the storage pool.")
@@ -515,6 +589,15 @@ func (s *storageLvm) StoragePoolDelete() error {
return fmt.Errorf("Failed to destroy the volume group for the lvm storage pool: %s.", output)
}
+ if filepath.IsAbs(source) {
+ // This is a loop file so deconfigure the associated loop
+ // device.
+ err = os.Remove(source)
+ if err != nil {
+ return err
+ }
+ }
+
// Delete the mountpoint for the storage pool.
poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
err = os.RemoveAll(poolMntPoint)
@@ -526,7 +609,66 @@ func (s *storageLvm) StoragePoolDelete() error {
return nil
}
+// Currently only used for loop-backed LVM storage pools. Can be called without
+// overhead since it is essentially a noop for non-loop-backed LVM storage
+// pools.
func (s *storageLvm) StoragePoolMount() (bool, error) {
+ source := s.pool.Config["source"]
+ if source == "" {
+ return false, fmt.Errorf("No \"source\" property found for the storage pool.")
+ }
+
+ if !filepath.IsAbs(source) {
+ return true, nil
+ }
+
+ poolMountLockID := getPoolMountLockID(s.pool.Name)
+ lxdStorageMapLock.Lock()
+ if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
+ lxdStorageMapLock.Unlock()
+ if _, ok := <-waitChannel; ok {
+ shared.LogWarnf("Received value over semaphore. This should not have happened.")
+ }
+ // Give the benefit of the doubt and assume that the other
+ // thread actually succeeded in mounting the storage pool.
+ return false, nil
+ }
+
+ lxdStorageOngoingOperationMap[poolMountLockID] = make(chan bool)
+ lxdStorageMapLock.Unlock()
+
+ removeLockFromMap := func() {
+ lxdStorageMapLock.Lock()
+ if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; ok {
+ close(waitChannel)
+ delete(lxdStorageOngoingOperationMap, poolMountLockID)
+ }
+ lxdStorageMapLock.Unlock()
+ }
+
+ defer removeLockFromMap()
+
+ if filepath.IsAbs(source) && !shared.IsBlockdevPath(source) {
+ loopF, err := prepareLoopDev(source, 0)
+ if err != nil {
+ return false, fmt.Errorf("Could not prepare loop device: %s", err)
+ }
+ s.loopInfo = loopF
+
+ // Force rescan, since LVM is not working nicely with loop
+ // devices.
+ output, err := tryExec("pvscan")
+ if err != nil {
+ shared.LogWarnf("pvscan failed: %s.", string(output))
+ }
+
+ // See comment above.
+ output, err = tryExec("vgscan")
+ if err != nil {
+ shared.LogWarnf("vgscan failed: %s.", string(output))
+ }
+ }
+
return true, nil
}
@@ -588,8 +730,13 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
func (s *storageLvm) StoragePoolVolumeDelete() error {
shared.LogInfof("Deleting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return err
+ }
+
customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
- _, err := s.StoragePoolVolumeUmount()
+ _, err = s.StoragePoolVolumeUmount()
if err != nil {
return err
}
@@ -619,6 +766,11 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
shared.LogDebugf("Mounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return false, err
+ }
+
customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
poolName := s.getOnDiskPoolName()
mountOptions := s.getLvmBlockMountOptions()
@@ -672,6 +824,11 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
shared.LogDebugf("Unmounting LVM storage volume \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return false, err
+ }
+
customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
customUmountLockID := getCustomUmountLockID(s.pool.Name, s.volume.Name)
@@ -1049,6 +1206,11 @@ func (s *storageLvm) ContainerCanRestore(container container, sourceContainer co
func (s *storageLvm) ContainerDelete(container container) error {
shared.LogDebugf("Deleting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return err
+ }
+
containerName := container.Name()
containerLvmName := containerNameToLVName(containerName)
containerMntPoint := ""
@@ -1069,7 +1231,7 @@ func (s *storageLvm) ContainerDelete(container container) error {
}
poolName := s.getOnDiskPoolName()
- err := s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, containerLvmName)
+ err = s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, containerLvmName)
if err != nil {
return err
}
@@ -1227,6 +1389,11 @@ func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
func (s *storageLvm) ContainerUmount(name string, path string) (bool, error) {
shared.LogDebugf("Unmounting LVM storage volume for container \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return false, err
+ }
+
containerMntPoint := getContainerMountPoint(s.pool.Name, name)
containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
@@ -1355,7 +1522,12 @@ func (s *storageLvm) ContainerRename(container container, newContainerName strin
func (s *storageLvm) ContainerRestore(container container, sourceContainer container) error {
shared.LogDebugf("Restoring LVM storage volume for container \"%s\" from %s -> %s.", s.volume.Name, sourceContainer.Name(), container.Name())
- err := sourceContainer.StorageStart()
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return err
+ }
+
+ err = sourceContainer.StorageStart()
if err != nil {
return err
}
@@ -1406,7 +1578,12 @@ func (s *storageLvm) ContainerGetUsage(container container) (int64, error) {
func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
shared.LogDebugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
- err := s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return err
+ }
+
+ err = s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
if err != nil {
return err
}
@@ -1467,7 +1644,12 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer container) error {
shared.LogDebugf("Deleting LVM storage volume for snapshot \"%s\" on storage pool \"%s\".", s.volume.Name, s.pool.Name)
- err := s.ContainerDelete(snapshotContainer)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return err
+ }
+
+ err = s.ContainerDelete(snapshotContainer)
if err != nil {
return fmt.Errorf("Error deleting snapshot %s: %s", snapshotContainer.Name(), err)
}
@@ -1713,6 +1895,11 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
shared.LogDebugf("Mounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return false, err
+ }
+
imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
if shared.IsMountPoint(imageMntPoint) {
return false, nil
@@ -1727,7 +1914,7 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
poolName := s.getOnDiskPoolName()
lvmVolumePath := getLvmDevPath(poolName, storagePoolVolumeApiEndpointImages, fingerprint)
lvmMountOptions := s.getLvmBlockMountOptions()
- err := tryMount(lvmVolumePath, imageMntPoint, lvmFstype, 0, lvmMountOptions)
+ err = tryMount(lvmVolumePath, imageMntPoint, lvmFstype, 0, lvmMountOptions)
if err != nil {
shared.LogErrorf(fmt.Sprintf("Error mounting image LV for unpacking: %s", err))
return false, fmt.Errorf("Error mounting image LV: %v", err)
@@ -1740,12 +1927,17 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
shared.LogDebugf("Unmounting LVM storage volume for image \"%s\" on storage pool \"%s\".", fingerprint, s.pool.Name)
+ err := s.StoragePoolCheck()
+ if err != nil {
+ return false, err
+ }
+
imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
if !shared.IsMountPoint(imageMntPoint) {
return false, nil
}
- err := tryUnmount(imageMntPoint, 0)
+ err = tryUnmount(imageMntPoint, 0)
if err != nil {
return false, err
}
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index 9d88738..4be75a4 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -101,7 +101,7 @@ func storagePoolValidateConfig(name string, driver string, config map[string]str
func storagePoolFillDefault(name string, driver string, config map[string]string) error {
if driver != "dir" {
- if driver != "lvm" && config["size"] == "" {
+ if config["size"] == "" {
st := syscall.Statfs_t{}
err := syscall.Statfs(shared.VarPath(), &st)
if err != nil {
diff --git a/test/suites/storage.sh b/test/suites/storage.sh
index 50d86e2..f01362e 100644
--- a/test/suites/storage.sh
+++ b/test/suites/storage.sh
@@ -84,6 +84,8 @@ test_storage() {
pvcreate "${loop_device_8}"
# Create new volume group "dummy_vg_4" on existing physical volume.
lxc storage create "lxdtest-$(basename "${LXD_DIR}")-pool13" lvm source="${loop_device_8}" lvm.vg_name="lxdtest-$(basename "${LXD_DIR}")-pool13-dummy_vg_4" volume.size=25MB
+
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-pool14" lvm
fi
# Set default storage pool for image import.
@@ -235,6 +237,12 @@ test_storage() {
lxc launch testimage c12pool13 -s "lxdtest-$(basename "${LXD_DIR}")-pool13"
lxc list -c b c12pool13 | grep "lxdtest-$(basename "${LXD_DIR}")-pool13"
+ lxc init testimage c10pool14 -s "lxdtest-$(basename "${LXD_DIR}")-pool14"
+ lxc list -c b c10pool14 | grep "lxdtest-$(basename "${LXD_DIR}")-pool14"
+
+ lxc launch testimage c12pool14 -s "lxdtest-$(basename "${LXD_DIR}")-pool14"
+ lxc list -c b c12pool14 | grep "lxdtest-$(basename "${LXD_DIR}")-pool14"
+
lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-pool6" c10pool6
lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool6" c10pool6 c10pool6 testDevice /opt
! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool6" c10pool6 c10pool6 testDevice2 /opt
@@ -298,6 +306,22 @@ test_storage() {
lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool13" custom/c12pool13 c12pool13 testDevice /opt
! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool13" custom/c12pool13 c12pool13 testDevice2 /opt
lxc storage volume detach "lxdtest-$(basename "${LXD_DIR}")-pool13" c12pool13 c12pool13 testDevice
+
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14
+ lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14 c10pool14 testDevice /opt
+ ! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14 c10pool14 testDevice2 /opt
+ lxc storage volume detach "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14 c10pool14 testDevice
+ lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" custom/c10pool14 c10pool14 testDevice /opt
+ ! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" custom/c10pool14 c10pool14 testDevice2 /opt
+ lxc storage volume detach "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14 c10pool14 testDevice
+
+ lxc storage volume create "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14
+ lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14 c12pool14 testDevice /opt
+ ! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14 c12pool14 testDevice2 /opt
+ lxc storage volume detach "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14 c12pool14 testDevice
+ lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" custom/c12pool14 c12pool14 testDevice /opt
+ ! lxc storage volume attach "lxdtest-$(basename "${LXD_DIR}")-pool14" custom/c12pool14 c12pool14 testDevice2 /opt
+ lxc storage volume detach "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14 c12pool14 testDevice
fi
if which zfs >/dev/null 2>&1; then
@@ -404,6 +428,9 @@ test_storage() {
lxc delete -f c10pool13
lxc delete -f c12pool13
+ lxc delete -f c10pool14
+ lxc delete -f c12pool14
+
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool6" c10pool6
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool6" c12pool6
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool11" c10pool11
@@ -412,6 +439,8 @@ test_storage() {
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool12" c12pool12
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool13" c10pool13
lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool13" c12pool13
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool14" c10pool14
+ lxc storage volume delete "lxdtest-$(basename "${LXD_DIR}")-pool14" c12pool14
fi
if which zfs >/dev/null 2>&1; then
@@ -473,6 +502,8 @@ test_storage() {
lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-pool13"
# shellcheck disable=SC2154
deconfigure_lvm_loop_device "${loop_file_8}" "${loop_device_8}"
+
+ lxc storage delete "lxdtest-$(basename "${LXD_DIR}")-pool14"
fi
)
More information about the lxc-devel
mailing list