[lxc-devel] [lxd/master] lvm: reuse existing volume group
brauner on Github
lxc-bot at linuxcontainers.org
Tue Feb 21 14:30:03 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170221/11cdc76b/attachment.bin>
-------------- next part --------------
From 195b63bf4e97d68ef3852bbeb1ede2827fc45d21 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 21 Feb 2017 00:26:08 +0100
Subject: [PATCH 1/3] lvm: remove volume.lvm.thinpool_name
Will be replaced by storage pool config key lvm.thinpool_name.
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_pools_config.go | 6 +++---
lxd/storage_volumes_config.go | 7 -------
2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index 75f34c1..a57e594 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -34,7 +34,7 @@ var storagePoolConfigKeys = map[string]func(value string) error{
},
"volume.zfs.use_refquota": shared.IsBool,
"volume.zfs.remove_snapshots": shared.IsBool,
- "volume.lvm.thinpool_name": shared.IsAny,
+ "lvm.thinpool_name": shared.IsAny,
"zfs.pool_name": shared.IsAny,
}
@@ -148,8 +148,8 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
}
if driver == "lvm" {
- if config["volume.lvm.thinpool_name"] == "" {
- config["volume.lvm.thinpool_name"] = "LXDThinpool"
+ if config["lvm.thinpool_name"] == "" {
+ config["lvm.thinpool_name"] = "LXDThinpool"
}
if config["volume.block.filesystem"] == "" {
diff --git a/lxd/storage_volumes_config.go b/lxd/storage_volumes_config.go
index 435457e..e20e6cf 100644
--- a/lxd/storage_volumes_config.go
+++ b/lxd/storage_volumes_config.go
@@ -121,13 +121,6 @@ func storageVolumeFillDefault(name string, config map[string]string, parentPool
if config["block.mount_options"] == "" && config["block.filesystem"] == "ext4" {
config["block.mount_options"] = "discard"
}
-
- if config["lvm.thinpool_name"] == "" {
- config["lvm.thinpool_name"] = parentPool.Config["volume.lvm.thinpool_name"]
- if config["lvm.thinpool_name"] == "" {
- config["lvm.thinpool_name"] = "LXDThinPool"
- }
- }
}
return nil
From ee7972f01fd5bf7f5a276ebcc556bcc0ddfa0579 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 21 Feb 2017 00:34:18 +0100
Subject: [PATCH 2/3] lvm: add lvm.thinpool_name + lvm.vg_name
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_lvm.go | 16 ++++++++++------
lxd/storage_pools_config.go | 5 +++++
lxd/storage_zfs.go | 8 ++++++--
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index e3c1f7b..d93fb20 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -86,7 +86,7 @@ func storageLVMValidateThinPoolName(d *Daemon, vgName string, value string) erro
if value != "" {
if vgName == "" {
- return fmt.Errorf("Can not set lvm_thinpool_name without lvm_vg_name set.")
+ return fmt.Errorf("Can not set lvm.thinpool_name without lvm.vg_name set.")
}
poolExists, err := storageLVMThinpoolExists(vgName, value)
@@ -311,7 +311,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
tryUndo := true
vgName := s.pool.Name
- thinPoolName := s.volume.Config["lvm.thinpool_name"]
+ thinPoolName := s.pool.Config["lvm.thinpool_name"]
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
@@ -467,8 +467,12 @@ func (s *storageLvm) StoragePoolUpdate(changedConfig []string) error {
// noop
}
- if shared.StringInSlice("volume.lvm.thinpool_name", changedConfig) {
- return fmt.Errorf("The \"volume.lvm.thinpool_name\" property cannot be changed.")
+ if shared.StringInSlice("lvm.thinpool_name", changedConfig) {
+ return fmt.Errorf("The \"lvm.thinpool_name\" property cannot be changed.")
+ }
+
+ if shared.StringInSlice("lvm.vg_name", changedConfig) {
+ return fmt.Errorf("The \"lvm.vg_name\" property cannot be changed.")
}
return nil
@@ -489,7 +493,7 @@ func (s *storageLvm) ContainerCreate(container container) error {
containerName := container.Name()
containerLvmName := containerNameToLVName(containerName)
- thinPoolName := s.volume.Config["lvm.thinpool_name"]
+ thinPoolName := s.pool.Config["lvm.thinpool_name"]
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
@@ -1124,7 +1128,7 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
tryUndo := true
vgName := s.pool.Name
- thinPoolName := s.volume.Config["lvm.thinpool_name"]
+ thinPoolName := s.pool.Config["lvm.thinpool_name"]
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index a57e594..b1d12e5 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -35,6 +35,7 @@ var storagePoolConfigKeys = map[string]func(value string) error{
"volume.zfs.use_refquota": shared.IsBool,
"volume.zfs.remove_snapshots": shared.IsBool,
"lvm.thinpool_name": shared.IsAny,
+ "lvm.vg_name": shared.IsAny,
"zfs.pool_name": shared.IsAny,
}
@@ -148,6 +149,10 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
}
if driver == "lvm" {
+ if config["lvm.vg_name"] == "" {
+ config["lvm.vg_name"] == "LXDVGroup"
+ }
+
if config["lvm.thinpool_name"] == "" {
config["lvm.thinpool_name"] = "LXDThinpool"
}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index b615298..951381e 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -307,8 +307,12 @@ func (s *storageZfs) StoragePoolUpdate(changedConfig []string) error {
return fmt.Errorf("The \"volume.block.filesystem\" property cannot be changed.")
}
- if shared.StringInSlice("volume.lvm.thinpool_name", changedConfig) {
- return fmt.Errorf("The \"volume.lvm.thinpool_name\" property cannot be changed.")
+ if shared.StringInSlice("lvm.thinpool_name", changedConfig) {
+ return fmt.Errorf("The \"lvm.thinpool_name\" property cannot be changed.")
+ }
+
+ if shared.StringInSlice("lvm.vg_name", changedConfig) {
+ return fmt.Errorf("The \"lvm.vg_name\" property cannot be changed.")
}
if shared.StringInSlice("volume.zfs.use_refquota", changedConfig) {
From 621b290a972b49bb245eda020f8a983e25105780 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 21 Feb 2017 15:22:51 +0100
Subject: [PATCH 3/3] lvm: allow to reuse existing volume groups
Reuse an already existing LVM volume group:
- lxc storage create <pool_name> lvm lvm.vg_name=LXDvg lvm.thinpool_name=LXDthin
Create a new LVM volume group or reuse an existing one:
- lxc storage create <pool_name> lvm source=/dev/sdb lvm.vg_name=LXDvg lvm.thinpool_name=LXDthin
- lxc storage create <pool_name> lvm source=/dev/sdb
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
lxd/storage_lvm.go | 192 +++++++++++++++++++++++++++++++++-----------
lxd/storage_pools_config.go | 5 +-
test/suites/storage.sh | 3 +
3 files changed, 153 insertions(+), 47 deletions(-)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index d93fb20..2792166 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -17,6 +17,38 @@ import (
log "gopkg.in/inconshreveable/log15.v2"
)
+func storageVGExists(vgName string) (bool, error) {
+ err := exec.Command("vgs", "--noheadings", "-o", "lv_attr", vgName).Run()
+ if err != nil {
+ if exitError, ok := err.(*exec.ExitError); ok {
+ waitStatus := exitError.Sys().(syscall.WaitStatus)
+ if waitStatus.ExitStatus() == 5 {
+ // pool LV was not found
+ return false, nil
+ }
+ }
+ return false, fmt.Errorf("Error checking for volume group '%s'", vgName)
+ }
+
+ return true, nil
+}
+
+func storagePVExists(pvName string) (bool, error) {
+ err := exec.Command("pvs", "--noheadings", "-o", "lv_attr", pvName).Run()
+ if err != nil {
+ if exitError, ok := err.(*exec.ExitError); ok {
+ waitStatus := exitError.Sys().(syscall.WaitStatus)
+ if waitStatus.ExitStatus() == 5 {
+ // pool LV was not found
+ return false, nil
+ }
+ }
+ return false, fmt.Errorf("Error checking for volume group '%s'", pvName)
+ }
+
+ return true, nil
+}
+
func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) {
output, err := exec.Command("vgs", "--noheadings", "-o", "lv_attr", fmt.Sprintf("%s/%s", vgName, poolName)).Output()
if err != nil {
@@ -120,9 +152,19 @@ func containerNameToLVName(containerName string) string {
}
type storageLvm struct {
+ vgName string
+ thinPoolName string
storageShared
}
+func (s *storageLvm) getOnDiskPoolName() string {
+ if s.vgName != "" {
+ return s.vgName
+ }
+
+ return s.pool.Name
+}
+
func getLvmDevPath(lvmPool string, volumeType string, lvmVolume string) string {
return fmt.Sprintf("/dev/%s/%s_%s", lvmPool, volumeType, lvmVolume)
}
@@ -179,6 +221,26 @@ func (s *storageLvm) StoragePoolInit(config map[string]interface{}) (storage, er
return s, err
}
+ source := s.pool.Config["source"]
+ s.vgName = s.pool.Config["lvm.vg_name"]
+ s.thinPoolName = s.pool.Config["lvm.thinpool_name"]
+ if source == "" {
+ // Source property is empty, so the user wants us to reuse an
+ // already existing volume group.
+ s.log.Debug(fmt.Sprintf("Source property of this lvm storage pool empty: Checking that volume group \"lvm.vg_name=%s\" already exists.", s.vgName))
+ ok, err := storageVGExists(s.vgName)
+ if err != nil {
+ // Internal error.
+ return s, err
+ } else if !ok {
+ // Volume group does not exist.
+ return s, fmt.Errorf("The \"source\" property of the storage pool is empty and the \"lvm.vg_name=%s\" volume group does not exist.", s.vgName)
+ }
+ s.log.Debug(fmt.Sprintf("Source property of this lvm storage pool empty: Detected that volume group \"lvm.vg_name=%s\" already exists.", s.vgName))
+ } else if filepath.IsAbs(source) && !shared.IsBlockdevPath(source) {
+ return s, fmt.Errorf("Loop backed lvm storage volumes are currently not supported.")
+ }
+
return s, nil
}
@@ -232,9 +294,6 @@ func (s *storageLvm) StoragePoolCreate() error {
tryUndo := true
source := s.pool.Config["source"]
- if source == "" {
- return fmt.Errorf("No \"source\" property found for the storage pool.")
- }
// Create the mountpoint for the storage pool.
poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
@@ -248,28 +307,56 @@ func (s *storageLvm) StoragePoolCreate() error {
}
}()
- if !shared.IsBlockdevPath(source) {
- return fmt.Errorf("Loop backed lvm storage volumes are currently not supported.")
- }
+ poolName := s.getOnDiskPoolName()
+ if filepath.IsAbs(source) {
+ // Check whether we have been given a block device.
+ if !shared.IsBlockdevPath(source) {
+ return fmt.Errorf("Loop backed lvm storage volumes are currently not supported.")
+ }
- // Create a lvm physical volume.
- output, err := exec.Command("pvcreate", source).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", source).Run()
+ ok, err := storagePVExists(source)
+ if err == nil && !ok {
+ // Create a new lvm physical volume.
+ output, err := exec.Command("pvcreate", source).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", source).Run()
+ }
+ }()
}
- }()
- // Create a volume group on the physical volume.
- output, err = exec.Command("vgcreate", s.pool.Name, source).CombinedOutput()
- if err != nil {
- return fmt.Errorf("Failed to create the volume group for the lvm storage pool: %s.", output)
- }
+ ok, err = storageVGExists(poolName)
+ if err == nil && !ok {
+ // Create a volume group on the physical volume.
+ output, err := exec.Command("vgcreate", poolName, source).CombinedOutput()
+ if err != nil {
+ return fmt.Errorf("Failed to create the volume group for the lvm storage pool: %s.", output)
+ }
+ }
- s.pool.Config["source"] = s.pool.Name
+ s.pool.Config["source"] = s.pool.Name
+ } else {
+ if source == "" || source == s.vgName && s.vgName != "" && s.thinPoolName != "" {
+ // Source property is empty, so the user wants us to
+ // reuse an already existing volume group.
+ ok, err := storageVGExists(s.vgName)
+ if err != nil {
+ // Internal error.
+ return err
+ } else if !ok {
+ // Volume group does not exist.
+ return fmt.Errorf("The \"source\" property of the storage pool is empty and the \"lvm.vg_name=%s\" volume group does not exist.", s.vgName)
+ }
+ } else if source != "" {
+ return fmt.Errorf("Inconsistent LVM request. The \"source\" property can only be a non absolute path when it matches the \"lvm.vg_name\" property.")
+ }
+ // Set source to the volume group name since we can't
+ // rely on the existence of the block device.
+ s.pool.Config["source"] = s.vgName
+ }
// Deregister cleanup.
tryUndo = false
@@ -283,8 +370,9 @@ func (s *storageLvm) StoragePoolDelete() error {
return fmt.Errorf("No \"source\" property found for the storage pool.")
}
+ poolName := s.getOnDiskPoolName()
// Remove the volume group.
- output, err := exec.Command("vgremove", "-f", s.pool.Name).CombinedOutput()
+ output, err := exec.Command("vgremove", "-f", poolName).CombinedOutput()
if err != nil {
return fmt.Errorf("Failed to destroy the volume group for the lvm storage pool: %s.", output)
}
@@ -310,7 +398,7 @@ func (s *storageLvm) StoragePoolUmount() (bool, error) {
func (s *storageLvm) StoragePoolVolumeCreate() error {
tryUndo := true
- vgName := s.pool.Name
+ poolName := s.getOnDiskPoolName()
thinPoolName := s.pool.Config["lvm.thinpool_name"]
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
@@ -320,7 +408,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
return err
}
- err = s.createThinLV(vgName, thinPoolName, s.volume.Name, lvFsType, lvSize, volumeType)
+ err = s.createThinLV(poolName, thinPoolName, s.volume.Name, lvFsType, lvSize, volumeType)
if err != nil {
s.log.Error("LVMCreateThinLV", log.Ctx{"err": err})
return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
@@ -359,7 +447,8 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
return err
}
- err = s.removeLV(s.pool.Name, volumeType, s.volume.Name)
+ poolName := s.getOnDiskPoolName()
+ err = s.removeLV(poolName, volumeType, s.volume.Name)
if err != nil {
return err
}
@@ -386,7 +475,8 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
return false, err
}
- lvmVolumePath := getLvmDevPath(s.pool.Name, volumeType, s.volume.Name)
+ poolName := s.getOnDiskPoolName()
+ lvmVolumePath := getLvmDevPath(poolName, volumeType, s.volume.Name)
mountOptions := s.volume.Config["block.mount_options"]
err = tryMount(lvmVolumePath, customPoolVolumeMntPoint, lvFsType, 0, mountOptions)
if err != nil {
@@ -497,7 +587,8 @@ func (s *storageLvm) ContainerCreate(container container) error {
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
- err := s.createThinLV(s.pool.Name, thinPoolName, containerLvmName, lvFsType, lvSize, storagePoolVolumeApiEndpointContainers)
+ poolName := s.getOnDiskPoolName()
+ err := s.createThinLV(poolName, thinPoolName, containerLvmName, lvFsType, lvSize, storagePoolVolumeApiEndpointContainers)
if err != nil {
return err
}
@@ -542,11 +633,13 @@ func (s *storageLvm) ContainerCreate(container container) error {
func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint string) error {
tryUndo := true
+ poolName := s.getOnDiskPoolName()
+
// Check if the image already exists.
- imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
- imageLvmDevPath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointImages, fingerprint)
+ imageMntPoint := getImageMountPoint(poolName, fingerprint)
+ imageLvmDevPath := getLvmDevPath(poolName, storagePoolVolumeApiEndpointImages, fingerprint)
- imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
+ imageStoragePoolLockID := getImageCreateLockID(poolName, fingerprint)
lxdStorageMapLock.Lock()
if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
lxdStorageMapLock.Unlock()
@@ -576,7 +669,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
containerName := container.Name()
containerLvmName := containerNameToLVName(containerName)
- containerLvSnapshotPath, err := s.createSnapshotLV(s.pool.Name, fingerprint, storagePoolVolumeApiEndpointImages, containerLvmName, storagePoolVolumeApiEndpointContainers, false)
+ containerLvSnapshotPath, err := s.createSnapshotLV(poolName, fingerprint, storagePoolVolumeApiEndpointImages, containerLvmName, storagePoolVolumeApiEndpointContainers, false)
if err != nil {
return err
}
@@ -665,7 +758,8 @@ func (s *storageLvm) ContainerDelete(container container) error {
}
}
- err := s.removeLV(s.pool.Name, storagePoolVolumeApiEndpointContainers, containerLvmName)
+ poolName := s.getOnDiskPoolName()
+ err := s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, containerLvmName)
if err != nil {
return err
}
@@ -762,7 +856,8 @@ func (s *storageLvm) ContainerCopy(container container, sourceContainer containe
func (s *storageLvm) ContainerMount(name string, path string) (bool, error) {
containerLvmName := containerNameToLVName(name)
lvFsType := s.volume.Config["block.filesystem"]
- containerLvmPath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointContainers, containerLvmName)
+ poolName := s.getOnDiskPoolName()
+ containerLvmPath := getLvmDevPath(poolName, storagePoolVolumeApiEndpointContainers, containerLvmName)
mountOptions := s.volume.Config["block.mount_options"]
containerMntPoint := getContainerMountPoint(s.pool.Name, name)
@@ -945,12 +1040,13 @@ func (s *storageLvm) ContainerRestore(container container, sourceContainer conta
return err
}
- err = s.removeLV(s.pool.Name, storagePoolVolumeApiEndpointContainers, destName)
+ poolName := s.getOnDiskPoolName()
+ err = s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, destName)
if err != nil {
s.log.Error(fmt.Sprintf("Failed to remove \"%s\": %s.", destName, err))
}
- _, err = s.createSnapshotLV(s.pool.Name, srcLvName, storagePoolVolumeApiEndpointContainers, destLvName, storagePoolVolumeApiEndpointContainers, false)
+ _, err = s.createSnapshotLV(poolName, srcLvName, storagePoolVolumeApiEndpointContainers, destLvName, storagePoolVolumeApiEndpointContainers, false)
if err != nil {
return fmt.Errorf("Error creating snapshot LV: %v", err)
}
@@ -979,7 +1075,8 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
targetContainerLvmName := containerNameToLVName(targetContainerName)
s.log.Debug("Creating snapshot", log.Ctx{"srcName": sourceContainerName, "destName": targetContainerName})
- _, err := s.createSnapshotLV(s.pool.Name, sourceContainerLvmName, storagePoolVolumeApiEndpointContainers, targetContainerLvmName, storagePoolVolumeApiEndpointContainers, readonly)
+ poolName := s.getOnDiskPoolName()
+ _, err := s.createSnapshotLV(poolName, sourceContainerLvmName, storagePoolVolumeApiEndpointContainers, targetContainerLvmName, storagePoolVolumeApiEndpointContainers, readonly)
if err != nil {
return fmt.Errorf("Error creating snapshot LV: %s", err)
}
@@ -1064,18 +1161,19 @@ func (s *storageLvm) ContainerSnapshotStart(container container) error {
s.log.Debug("Creating snapshot", log.Ctx{"srcName": sourceLvmName, "destName": targetLvmName})
- lvpath, err := s.createSnapshotLV(s.pool.Name, sourceLvmName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName, storagePoolVolumeApiEndpointContainers, false)
+ poolName := s.getOnDiskPoolName()
+ lvpath, err := s.createSnapshotLV(poolName, sourceLvmName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName, storagePoolVolumeApiEndpointContainers, false)
if err != nil {
return fmt.Errorf("Error creating snapshot LV: %s", err)
}
defer func() {
if tryUndo {
- s.removeLV(s.pool.Name, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName)
+ s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName)
}
}()
lvFsType := s.volume.Config["block.filesystem"]
- containerLvmPath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName)
+ containerLvmPath := getLvmDevPath(poolName, storagePoolVolumeApiEndpointContainers, tmpTargetLvmName)
mountOptions := s.volume.Config["block.mount_options"]
containerMntPoint := getSnapshotMountPoint(s.pool.Name, sourceName)
@@ -1112,7 +1210,8 @@ func (s *storageLvm) ContainerSnapshotStop(container container) error {
lvName := containerNameToLVName(name)
tmpLvName := getTmpSnapshotName(lvName)
- err := s.removeLV(s.pool.Name, storagePoolVolumeApiEndpointContainers, tmpLvName)
+ poolName := s.getOnDiskPoolName()
+ err := s.removeLV(poolName, storagePoolVolumeApiEndpointContainers, tmpLvName)
if err != nil {
return err
}
@@ -1127,7 +1226,7 @@ func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer container) e
func (s *storageLvm) ImageCreate(fingerprint string) error {
tryUndo := true
- vgName := s.pool.Name
+ poolName := s.getOnDiskPoolName()
thinPoolName := s.pool.Config["lvm.thinpool_name"]
lvFsType := s.volume.Config["block.filesystem"]
lvSize := s.volume.Config["size"]
@@ -1137,7 +1236,7 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
return err
}
- err = s.createThinLV(vgName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeApiEndpointImages)
+ err = s.createThinLV(poolName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeApiEndpointImages)
if err != nil {
s.log.Error("LVMCreateThinLV", log.Ctx{"err": err})
return fmt.Errorf("Error Creating LVM LV for new image: %v", err)
@@ -1181,7 +1280,8 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
return err
}
- err = s.removeLV(s.pool.Name, storagePoolVolumeApiEndpointImages, fingerprint)
+ poolName := s.getOnDiskPoolName()
+ err = s.removeLV(poolName, storagePoolVolumeApiEndpointImages, fingerprint)
if err != nil {
return err
}
@@ -1214,7 +1314,8 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
return false, fmt.Errorf("No filesystem type specified.")
}
- lvmVolumePath := getLvmDevPath(s.pool.Name, storagePoolVolumeApiEndpointImages, fingerprint)
+ poolName := s.getOnDiskPoolName()
+ lvmVolumePath := getLvmDevPath(poolName, storagePoolVolumeApiEndpointImages, fingerprint)
lvmMountOptions := s.volume.Config["block.mount_options"]
// Shouldn't be necessary since it should be validated in the config
// checks.
@@ -1393,7 +1494,8 @@ func (s *storageLvm) createSnapshotLV(vgName string, origLvName string, origVolu
func (s *storageLvm) renameLV(oldName string, newName string, volumeType string) (string, error) {
oldLvmName := getPrefixedLvName(volumeType, oldName)
newLvmName := getPrefixedLvName(volumeType, newName)
- output, err := tryExec("lvrename", s.pool.Name, oldLvmName, newLvmName)
+ poolName := s.getOnDiskPoolName()
+ output, err := tryExec("lvrename", poolName, oldLvmName, newLvmName)
return string(output), err
}
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index b1d12e5..840ff89 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -50,7 +50,7 @@ func storagePoolValidateConfig(name string, driver string, config map[string]str
if config["source"] == "" {
if driver == "dir" {
config["source"] = filepath.Join(shared.VarPath("storage-pools"), name)
- } else {
+ } else if driver != "lvm" {
config["source"] = filepath.Join(shared.VarPath("disks"), name)
}
}
@@ -150,7 +150,8 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
if driver == "lvm" {
if config["lvm.vg_name"] == "" {
- config["lvm.vg_name"] == "LXDVGroup"
+ // Default is to set this to the pool name if empty.
+ config["lvm.vg_name"] = name
}
if config["lvm.thinpool_name"] == "" {
diff --git a/test/suites/storage.sh b/test/suites/storage.sh
index b32ddf9..2eb2ffa 100644
--- a/test/suites/storage.sh
+++ b/test/suites/storage.sh
@@ -53,6 +53,9 @@ test_storage() {
configure_lvm_loop_device loop_file_3 loop_device_3
# shellcheck disable=SC2154
lxc storage create "lxdtest-$(basename "${LXD_DIR}")-pool6" lvm source="${loop_device_3}" volume.size=10MB
+
+ configure_lvm_loop_device loop_file_3 loop_device_3
+ lxc storage create "lxdtest-$(basename "${LXD_DIR}")-pool7" lvm source="${loop_device_3}" volume.size=10MB
fi
# Set default storage pool for image import.
More information about the lxc-devel
mailing list