The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6636
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Moves LVM utils functions needed for pool creation to storage package ready for the LVM driver implementation.
From d8097a52c38000d7ec4d2b65889fb5b04926997c Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 11:40:08 +0000 Subject: [PATCH 01/18] lxd/storage/drivers/interface: Comments on pool mount/unmount definitions Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/interface.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lxd/storage/drivers/interface.go b/lxd/storage/drivers/interface.go index c5f7d063ec..1ecc052068 100644 --- a/lxd/storage/drivers/interface.go +++ b/lxd/storage/drivers/interface.go @@ -28,7 +28,12 @@ type Driver interface { // Pool. Create() error Delete(op *operations.Operation) error + // Mount mounts a storage pool if needed, returns true if we caused a new mount, false if + // already mounted. Mount() (bool, error) + + // Unmount unmounts a storage pool if needed, returns true if unmounted, false if was not + // mounted. Unmount() (bool, error) GetResources() (*api.ResourcesStoragePool, error) Validate(config map[string]string) error From e2f4052dcf7242716f61dc7dfbc54229fc4ee886 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 14:13:29 +0000 Subject: [PATCH 02/18] shared/util: Adds comment to TryRunCommand Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- shared/util.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/util.go b/shared/util.go index e307f985fe..0a80f5dd7e 100644 --- a/shared/util.go +++ b/shared/util.go @@ -861,6 +861,8 @@ func RunCommandWithFds(stdin io.Reader, stdout io.Writer, name string, arg ...st return nil } +// TryRunCommand runs the specified command up to 20 times with a 500ms delay between each call +// until it runs without an error. If after 20 times it is still failing then returns the error. func TryRunCommand(name string, arg ...string) (string, error) { var err error var output string From c399ff35a6d226088a3e4ef7b1d0b66b845afab7 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:22:34 +0000 Subject: [PATCH 03/18] lxd/storage/drivers/utils/lvm: Adds LVM util functions for creating pools Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/drivers/utils_lvm.go | 262 +++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 lxd/storage/drivers/utils_lvm.go diff --git a/lxd/storage/drivers/utils_lvm.go b/lxd/storage/drivers/utils_lvm.go new file mode 100644 index 0000000000..e9f1088e72 --- /dev/null +++ b/lxd/storage/drivers/utils_lvm.go @@ -0,0 +1,262 @@ +package drivers + +import ( + "fmt" + "os/exec" + "strconv" + "strings" + "syscall" + + "github.com/lxc/lxd/lxd/project" + "github.com/lxc/lxd/shared" + "github.com/lxc/lxd/shared/units" + "github.com/lxc/lxd/shared/version" +) + +// LVMPysicalVolumeExists checks if an LVM Physical Volume exists. +func LVMPysicalVolumeExists(pvName string) (bool, error) { + _, err := shared.RunCommand("pvs", "--noheadings", "-o", "lv_attr", pvName) + if err != nil { + runErr, ok := err.(shared.RunError) + if ok { + exitError, ok := runErr.Err.(*exec.ExitError) + if ok { + waitStatus := exitError.Sys().(syscall.WaitStatus) + if waitStatus.ExitStatus() == 5 { + // physical volume not found + return false, nil + } + } + } + return false, fmt.Errorf("error checking for physical volume \"%s\"", pvName) + } + + return true, nil +} + +// LVMVolumeGroupExists checks if an LVM Volume Group exists. +func LVMVolumeGroupExists(vgName string) (bool, error) { + _, err := shared.RunCommand("vgs", "--noheadings", "-o", "lv_attr", vgName) + if err != nil { + runErr, ok := err.(shared.RunError) + if ok { + exitError, ok := runErr.Err.(*exec.ExitError) + if ok { + waitStatus := exitError.Sys().(syscall.WaitStatus) + if waitStatus.ExitStatus() == 5 { + // volume group not found + return false, nil + } + } + } + + return false, fmt.Errorf("error checking for volume group \"%s\"", vgName) + } + + return true, nil +} + +// LVMGetLVCount gets the count of volumes in a volume group. +func LVMGetLVCount(vgName string) (int, error) { + output, err := shared.TryRunCommand("vgs", "--noheadings", "-o", "lv_count", vgName) + if err != nil { + return -1, err + } + + output = strings.TrimSpace(output) + return strconv.Atoi(output) +} + +// LVMThinpoolExists checks whether the specified thinpool exists in a volume group. +func LVMThinpoolExists(vgName string, poolName string) (bool, error) { + output, err := shared.RunCommand("vgs", "--noheadings", "-o", "lv_attr", fmt.Sprintf("%s/%s", vgName, poolName)) + if err != nil { + runErr, ok := err.(shared.RunError) + if ok { + exitError, ok := runErr.Err.(*exec.ExitError) + if 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 pool \"%s\"", poolName) + } + // Found LV named poolname, check type: + attrs := strings.TrimSpace(string(output[:])) + if strings.HasPrefix(attrs, "t") { + return true, nil + } + + return false, fmt.Errorf("pool named \"%s\" exists but is not a thin pool", poolName) +} + +// LVMDevPath returns the path to the LVM volume device. +func LVMDevPath(projectName, lvmPool string, volumeDBTypeName string, lvmVolume string) string { + lvmVolume = project.Prefix(projectName, lvmVolume) + if volumeDBTypeName == "" { + return fmt.Sprintf("/dev/%s/%s", lvmPool, lvmVolume) + } + + return fmt.Sprintf("/dev/%s/%s_%s", lvmPool, volumeDBTypeName, lvmVolume) +} + +// LVMVolumeExists checks whether the specified logical volume exists. +func LVMVolumeExists(lvDevPath string) (bool, error) { + _, err := shared.RunCommand("lvs", "--noheadings", "-o", "lv_attr", lvDevPath) + if err != nil { + runErr, ok := err.(shared.RunError) + if ok { + exitError, ok := runErr.Err.(*exec.ExitError) + if ok { + waitStatus := exitError.Sys().(syscall.WaitStatus) + if waitStatus.ExitStatus() == 5 { + // logical volume not found. + return false, nil + } + } + } + + return false, fmt.Errorf("error checking for logical volume \"%s\"", lvDevPath) + } + + return true, nil +} + +// LVMCreateThinpool creates a thin pool logical volume. +func LVMCreateThinpool(lvmVersion string, vgName string, thinPoolName string) error { + exists, err := LVMThinpoolExists(vgName, thinPoolName) + if err != nil { + return err + } + + if exists { + return nil + } + + err = lvmCreateDefaultThinPool(lvmVersion, vgName, thinPoolName) + if err != nil { + return err + } + + poolExists, err := LVMThinpoolExists(vgName, thinPoolName) + if err != nil { + return fmt.Errorf("Error checking for thin pool \"%s\" in \"%s\": %v", thinPoolName, vgName, err) + } + + if !poolExists { + return fmt.Errorf("Thin pool \"'%s\" does not exist in Volume Group \"%s\"", thinPoolName, vgName) + } + + return nil +} + +func lvmCreateDefaultThinPool(lvmVersion string, vgName string, thinPoolName string) error { + isRecent, err := LVMVersionIsAtLeast(lvmVersion, "2.02.99") + if err != nil { + return fmt.Errorf("Error checking LVM version: %s", err) + } + + // Create the thin pool + lvmThinPool := fmt.Sprintf("%s/%s", vgName, thinPoolName) + if isRecent { + _, err = shared.TryRunCommand( + "lvcreate", + "-Wy", "--yes", + "--poolmetadatasize", "1G", + "-l", "100%FREE", + "--thinpool", lvmThinPool) + } else { + _, err = shared.TryRunCommand( + "lvcreate", + "-Wy", "--yes", + "--poolmetadatasize", "1G", + "-L", "1G", + "--thinpool", lvmThinPool) + } + + if err != nil { + return fmt.Errorf("Could not create LVM thin pool named %s: %v", thinPoolName, err) + } + + if !isRecent { + // Grow it to the maximum VG size (two step process required by old LVM) + _, err = shared.TryRunCommand("lvextend", "--alloc", "anywhere", "-l", "100%FREE", lvmThinPool) + + if err != nil { + return fmt.Errorf("Could not grow LVM thin pool named %s: %v", thinPoolName, err) + } + } + + return nil +} + +// LVMVersionIsAtLeast checks whether the installed version of LVM is at least the specific version. +func LVMVersionIsAtLeast(sTypeVersion string, versionString string) (bool, error) { + lvmVersionString := strings.Split(sTypeVersion, "/")[0] + + lvmVersion, err := version.Parse(lvmVersionString) + if err != nil { + return false, err + } + + inVersion, err := version.Parse(versionString) + if err != nil { + return false, err + } + + if lvmVersion.Compare(inVersion) < 0 { + return false, nil + } + + return true, nil +} + +// LVMCreateLogicalVolume creates a logical volume. +func LVMCreateLogicalVolume(projectName, vgName string, thinPoolName string, lvName string, lvFsType string, lvSize string, volumeType string, makeThinLv bool) error { + var output string + var err error + + // Round the size to closest 512 bytes + lvSizeInt, err := units.ParseByteSizeString(lvSize) + if err != nil { + return err + } + + lvSizeInt = int64(lvSizeInt/512) * 512 + lvSizeString := units.GetByteSizeString(lvSizeInt, 0) + + lvmPoolVolumeName := lvmFullVolumeName(projectName, volumeType, lvName) + if makeThinLv { + targetVg := fmt.Sprintf("%s/%s", vgName, thinPoolName) + _, err = shared.TryRunCommand("lvcreate", "-Wy", "--yes", "--thin", "-n", lvmPoolVolumeName, "--virtualsize", lvSizeString, targetVg) + } else { + _, err = shared.TryRunCommand("lvcreate", "-Wy", "--yes", "-n", lvmPoolVolumeName, "--size", lvSizeString, vgName) + } + if err != nil { + return fmt.Errorf("Could not create thin LV named %s: %v", lvmPoolVolumeName, err) + } + + fsPath := LVMDevPath(projectName, vgName, volumeType, lvName) + + output, err = MakeFSType(fsPath, lvFsType, nil) + if err != nil { + return fmt.Errorf("Error making filesystem on image LV: %v (%s)", err, output) + } + + return nil +} + +// lvmFullVolumeName returns the logical volume's full name with project and volume type prefix. +func lvmFullVolumeName(projectName, volumeType string, lvmVolume string) string { + storageName := project.Prefix(projectName, lvmVolume) + + if volumeType != "" { + storageName = fmt.Sprintf("%s_%s", volumeType, storageName) + } + + return storageName +} From a9a5f082446224da11f2ddace9486403ba7cf057 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:23:02 +0000 Subject: [PATCH 04/18] lxd/api/internal: LVMVolumeExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/api_internal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/api_internal.go b/lxd/api_internal.go index 4a5e8e6d3f..949f0a5e89 100644 --- a/lxd/api_internal.go +++ b/lxd/api_internal.go @@ -752,7 +752,7 @@ func internalImport(d *Daemon, r *http.Request) response.Response { ctLvName := getLVName(poolName, storagePoolVolumeAPIEndpointContainers, ctLvmName) - exists, err := storageLVExists(ctLvName) + exists, err := storageDrivers.LVMVolumeExists(ctLvName) if err != nil { return response.InternalError(err) } From 03439cd6a3921a83f4942205805f2e64682f2e33 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:23:36 +0000 Subject: [PATCH 05/18] lxd/patches: LVMVolumeExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/patches.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lxd/patches.go b/lxd/patches.go index 3049b08896..81826071f2 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -20,6 +20,7 @@ import ( "github.com/lxc/lxd/lxd/instance" "github.com/lxc/lxd/lxd/rsync" driver "github.com/lxc/lxd/lxd/storage" + storageDrivers "github.com/lxc/lxd/lxd/storage/drivers" "github.com/lxc/lxd/shared" log "github.com/lxc/lxd/shared/log15" "github.com/lxc/lxd/shared/logger" @@ -162,7 +163,7 @@ func patchRenameCustomVolumeLVs(name string, d *Daemon) error { oldName := fmt.Sprintf("%s/custom_%s", vgName, volume) newName := fmt.Sprintf("%s/custom_%s", vgName, containerNameToLVName(volume)) - exists, err := storageLVExists(newName) + exists, err := storageDrivers.LVMVolumeExists(newName) if err != nil { return err } From 6c59543e1ccf81759b7582d1caeb4958bac55b65 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:23:50 +0000 Subject: [PATCH 06/18] lxd/patches: LVMDevPath usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/patches.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/patches.go b/lxd/patches.go index 81826071f2..c9bde13539 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -1109,7 +1109,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d newContainerMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, ct) ctLvName := containerNameToLVName(ct) newContainerLvName := fmt.Sprintf("%s_%s", storagePoolVolumeAPIEndpointContainers, ctLvName) - containerLvDevPath := getLvmDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointContainers, ctLvName) + containerLvDevPath := storageDrivers.LVMDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointContainers, ctLvName) if !shared.PathExists(containerLvDevPath) { oldLvDevPath := fmt.Sprintf("/dev/%s/%s", defaultPoolName, ctLvName) // If the old LVM device path for the logical volume @@ -1265,7 +1265,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d // Make sure we use a valid lv name. csLvName := containerNameToLVName(cs) newSnapshotLvName := fmt.Sprintf("%s_%s", storagePoolVolumeAPIEndpointContainers, csLvName) - snapshotLvDevPath := getLvmDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointContainers, csLvName) + snapshotLvDevPath := storageDrivers.LVMDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointContainers, csLvName) if !shared.PathExists(snapshotLvDevPath) { oldLvDevPath := fmt.Sprintf("/dev/%s/%s", defaultPoolName, csLvName) if shared.PathExists(oldLvDevPath) { @@ -1445,7 +1445,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d // Rename the logical volume device. newImageLvName := fmt.Sprintf("%s_%s", storagePoolVolumeAPIEndpointImages, img) - imageLvDevPath := getLvmDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointImages, img) + imageLvDevPath := storageDrivers.LVMDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointImages, img) oldLvDevPath := fmt.Sprintf("/dev/%s/%s", defaultPoolName, img) // Only create logical volumes for images that have a logical // volume on the pre-storage-api LXD instance. If not, we don't @@ -2422,7 +2422,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error { // exist in the db, so it's safe to ignore the error. volumeTypeApiEndpoint, _ := storagePoolVolumeTypeNameToAPIEndpoint(volume.Type) lvmName := containerNameToLVName(volume.Name) - lvmLvDevPath := getLvmDevPath("default", poolName, volumeTypeApiEndpoint, lvmName) + lvmLvDevPath := storageDrivers.LVMDevPath("default", poolName, volumeTypeApiEndpoint, lvmName) size, err := lvmGetLVSize(lvmLvDevPath) if err != nil { logger.Errorf("Failed to detect size of logical volume: %s", err) From e0ba747e5de9fedbad78e1da1a4c755c94430f41 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:25:57 +0000 Subject: [PATCH 07/18] lxd/storage/lvm: LVMVolumeGroupExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index e4cab25c5e..0224323299 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -95,7 +95,7 @@ func (s *storageLvm) StoragePoolInit() error { } if source != "" && !filepath.IsAbs(source) { - ok, err := storageVGExists(source) + ok, err := drivers.LVMVolumeGroupExists(source) if err != nil { // Internal error. return err @@ -210,7 +210,7 @@ func (s *storageLvm) StoragePoolCreate() error { } // Check if the volume group already exists. - vgExisted, globalErr = storageVGExists(poolName) + vgExisted, globalErr = drivers.LVMVolumeGroupExists(poolName) if globalErr != nil { return globalErr } @@ -236,7 +236,7 @@ func (s *storageLvm) StoragePoolCreate() error { } // Check if the volume group already exists. - vgExisted, globalErr = storageVGExists(poolName) + vgExisted, globalErr = drivers.LVMVolumeGroupExists(poolName) if globalErr != nil { return globalErr } @@ -252,7 +252,7 @@ func (s *storageLvm) StoragePoolCreate() error { s.pool.Config["lvm.vg_name"] = vgName s.vgName = vgName - vgExisted, globalErr = storageVGExists(vgName) + vgExisted, globalErr = drivers.LVMVolumeGroupExists(vgName) if globalErr != nil { return globalErr } @@ -359,15 +359,15 @@ func (s *storageLvm) StoragePoolDelete() error { } poolName := s.getOnDiskPoolName() - poolExists, _ := storageVGExists(poolName) + poolExists, _ := drivers.LVMVolumeGroupExists(poolName) // Delete the thinpool. if s.useThinpool && poolExists { // Check that the thinpool actually exists. For example, it // won't when the user has never created a storage volume in the // storage pool. - devPath := getLvmDevPath("default", poolName, "", s.thinPoolName) - ok, _ := storageLVExists(devPath) + devPath := drivers.LVMDevPath("default", poolName, "", s.thinPoolName) + ok, _ := drivers.LVMVolumeExists(devPath) if ok { msg, err := shared.TryRunCommand("lvremove", "-f", devPath) if err != nil { From e9b7a66bc9614f7a811b29e58cb902e431c3e2e1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:26:36 +0000 Subject: [PATCH 08/18] lxd/storage/lvm: LVMPysicalVolumeExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 0224323299..c629987a6c 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -204,7 +204,7 @@ func (s *storageLvm) StoragePoolCreate() error { // Check if the physical volume already exists. pvName = s.loopInfo.Name() - pvExisted, globalErr = storagePVExists(pvName) + pvExisted, globalErr = drivers.LVMPysicalVolumeExists(pvName) if globalErr != nil { return globalErr } @@ -230,7 +230,7 @@ func (s *storageLvm) StoragePoolCreate() error { s.pool.Config["source"] = poolName // Check if the physical volume already exists. - pvExisted, globalErr = storagePVExists(pvName) + pvExisted, globalErr = drivers.LVMPysicalVolumeExists(pvName) if globalErr != nil { return globalErr } From e624ff5450fecea8aa807e779a04bd95b18d6a45 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:27:13 +0000 Subject: [PATCH 09/18] lxd/storage/lvm: LVMGetLVCount usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index c629987a6c..044f77d98a 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -285,7 +285,7 @@ func (s *storageLvm) StoragePoolCreate() error { if vgExisted { // Check that the volume group is empty. // Otherwise we will refuse to use it. - count, err := lvmGetLVCount(poolName) + count, err := drivers.LVMGetLVCount(poolName) if err != nil { logger.Errorf("Failed to determine whether the volume group \"%s\" is empty", poolName) return err @@ -381,7 +381,7 @@ func (s *storageLvm) StoragePoolDelete() error { // assume that other users are using the volume group, so don't remove // it. This actually goes against policy since we explicitly state: our // pool, and nothing but our pool but still, let's not hurt users. - count, err := lvmGetLVCount(poolName) + count, err := drivers.LVMGetLVCount(poolName) if err != nil { return err } From 7aff5a90fa0904e2da23255c09cb31d7ebd0407b Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:28:00 +0000 Subject: [PATCH 10/18] lxd/storage/lvm: LVMThinpoolExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 044f77d98a..f3a169c4e8 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -297,7 +297,7 @@ func (s *storageLvm) StoragePoolCreate() error { } if count > 0 && s.useThinpool { - ok, err := storageLVMThinpoolExists(poolName, s.thinPoolName) + ok, err := drivers.LVMThinpoolExists(poolName, s.thinPoolName) if err != nil { logger.Errorf("Failed to determine whether thinpool \"%s\" exists in volume group \"%s\": %s", poolName, s.thinPoolName, err) return err From 8b6704a10826479c52f131e22b097d4f817bc1ef Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:28:44 +0000 Subject: [PATCH 11/18] lxd/storage/lvm: LVMCreateThinpool usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index f3a169c4e8..122e2689fd 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -508,7 +508,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error { } if s.useThinpool { - err = lvmCreateThinpool(s.s, s.sTypeVersion, poolName, thinPoolName, lvFsType) + err = drivers.LVMCreateThinpool(s.sTypeVersion, poolName, thinPoolName) if err != nil { return err } @@ -1833,7 +1833,7 @@ func (s *storageLvm) doContainerBackupLoad(projectName, containerName string, pr poolName := s.getOnDiskPoolName() if s.useThinpool { - err = lvmCreateThinpool(s.s, s.sTypeVersion, poolName, thinPoolName, lvFsType) + err = drivers.LVMCreateThinpool(s.sTypeVersion, poolName, thinPoolName) if err != nil { return "", err } @@ -1921,7 +1921,7 @@ func (s *storageLvm) ImageCreate(fingerprint string, tracker *ioprogress.Progres }() if s.useThinpool { - err = lvmCreateThinpool(s.s, s.sTypeVersion, poolName, thinPoolName, lvFsType) + err = drivers.LVMCreateThinpool(s.sTypeVersion, poolName, thinPoolName) if err != nil { return err } From 5844672725204ad398d2ecb656a7a19ba4ea69d0 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:29:22 +0000 Subject: [PATCH 12/18] lxd/storage/lvm: LVMCreateLogicalVolume usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 122e2689fd..19c53c67e9 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -514,7 +514,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error { } } - err = lvmCreateLv("default", poolName, thinPoolName, volumeLvmName, lvFsType, lvSize, volumeType, s.useThinpool) + err = drivers.LVMCreateLogicalVolume("default", poolName, thinPoolName, volumeLvmName, lvFsType, lvSize, volumeType, s.useThinpool) if err != nil { return fmt.Errorf("Error Creating LVM LV for new image: %v", err) } @@ -950,13 +950,13 @@ func (s *storageLvm) ContainerCreate(container instance.Instance) error { poolName := s.getOnDiskPoolName() if s.useThinpool { - err = lvmCreateThinpool(s.s, s.sTypeVersion, poolName, thinPoolName, lvFsType) + err = drivers.LVMCreateThinpool(s.sTypeVersion, poolName, thinPoolName) if err != nil { return err } } - err = lvmCreateLv(container.Project(), poolName, thinPoolName, containerLvmName, lvFsType, lvSize, storagePoolVolumeAPIEndpointContainers, s.useThinpool) + err = drivers.LVMCreateLogicalVolume(container.Project(), poolName, thinPoolName, containerLvmName, lvFsType, lvSize, storagePoolVolumeAPIEndpointContainers, s.useThinpool) if err != nil { return err } @@ -1840,7 +1840,7 @@ func (s *storageLvm) doContainerBackupLoad(projectName, containerName string, pr } if !snapshot { - err = lvmCreateLv(projectName, poolName, thinPoolName, containerLvmName, lvFsType, lvSize, + err = drivers.LVMCreateLogicalVolume(projectName, poolName, thinPoolName, containerLvmName, lvFsType, lvSize, storagePoolVolumeAPIEndpointContainers, s.useThinpool) } else { cname, _, _ := shared.InstanceGetParentAndSnapshotName(containerName) @@ -1926,7 +1926,7 @@ func (s *storageLvm) ImageCreate(fingerprint string, tracker *ioprogress.Progres return err } - err = lvmCreateLv("default", poolName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeAPIEndpointImages, true) + err = drivers.LVMCreateLogicalVolume("default", poolName, thinPoolName, fingerprint, lvFsType, lvSize, storagePoolVolumeAPIEndpointImages, true) if err != nil { return fmt.Errorf("Error Creating LVM LV for new image: %v", err) } From 7162baf9b0e1a31abd809405c7c3ed900266e9aa Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:30:06 +0000 Subject: [PATCH 13/18] lxd/storage/lvm: LVMDevPath usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 19c53c67e9..7f24cd04b5 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -554,7 +554,7 @@ func (s *storageLvm) StoragePoolVolumeDelete() error { volumeLvmName := containerNameToLVName(s.volume.Name) poolName := s.getOnDiskPoolName() - customLvmDevPath := getLvmDevPath("default", poolName, + customLvmDevPath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, volumeLvmName) lvExists, _ := storageLVExists(customLvmDevPath) @@ -609,7 +609,7 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) { if err != nil { return false, err } - lvmVolumePath := getLvmDevPath("default", poolName, volumeType, volumeLvmName) + lvmVolumePath := drivers.LVMDevPath("default", poolName, volumeType, volumeLvmName) customMountLockID := getCustomMountLockID(s.pool.Name, s.volume.Name) lxdStorageMapLock.Lock() @@ -929,8 +929,8 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error { func (s *storageLvm) ContainerStorageReady(container instance.Instance) bool { containerLvmName := containerNameToLVName(container.Name()) poolName := s.getOnDiskPoolName() - containerLvmPath := getLvmDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) - ok, _ := storageLVExists(containerLvmPath) + containerLvmPath := drivers.LVMDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) + ok, _ := drivers.LVMVolumeExists(containerLvmPath) return ok } @@ -1035,7 +1035,7 @@ func (s *storageLvm) ContainerCreateFromImage(container instance.Instance, finge } poolName := s.getOnDiskPoolName() - containerLvDevPath := getLvmDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) + containerLvDevPath := drivers.LVMDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) // Generate a new xfs's UUID lvFsType := s.getLvmFilesystem() msg, err := driver.FSGenerateNewUUID(lvFsType, containerLvDevPath) @@ -1086,7 +1086,7 @@ func lvmContainerDeleteInternal(projectName, poolName string, ctName string, isS } } - containerLvmDevPath := getLvmDevPath(projectName, vgName, + containerLvmDevPath := drivers.LVMDevPath(projectName, vgName, storagePoolVolumeAPIEndpointContainers, containerLvmName) lvExists, _ := storageLVExists(containerLvmDevPath) @@ -1247,7 +1247,7 @@ func (s *storageLvm) doContainerMount(project, name string, snap bool) (bool, er containerLvmName := containerNameToLVName(name) lvFsType := s.getLvmFilesystem() poolName := s.getOnDiskPoolName() - containerLvmPath := getLvmDevPath(project, poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) + containerLvmPath := drivers.LVMDevPath(project, poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) containerMntPoint := driver.GetContainerMountPoint(project, s.pool.Name, name) if shared.IsSnapshot(name) { containerMntPoint = driver.GetSnapshotMountPoint(project, s.pool.Name, name) @@ -1583,7 +1583,7 @@ func (s *storageLvm) ContainerSnapshotStart(container instance.Instance) (bool, poolName := s.getOnDiskPoolName() containerName := container.Name() containerLvmName := containerNameToLVName(containerName) - containerLvmPath := getLvmDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) + containerLvmPath := drivers.LVMDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) wasWritableAtCheck, err := lvmLvIsWritable(containerLvmPath) if err != nil { @@ -1642,7 +1642,7 @@ func (s *storageLvm) ContainerSnapshotStop(container instance.Instance) (bool, e } } - containerLvmPath := getLvmDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerNameToLVName(containerName)) + containerLvmPath := drivers.LVMDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerNameToLVName(containerName)) wasWritableAtCheck, err := lvmLvIsWritable(containerLvmPath) if err != nil { return false, err @@ -1973,7 +1973,7 @@ func (s *storageLvm) ImageDelete(fingerprint string) error { if s.useThinpool { poolName := s.getOnDiskPoolName() - imageLvmDevPath := getLvmDevPath("default", poolName, + imageLvmDevPath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fingerprint) lvExists, _ := storageLVExists(imageLvmDevPath) @@ -2022,7 +2022,7 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) { } poolName := s.getOnDiskPoolName() - lvmVolumePath := getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fingerprint) + lvmVolumePath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fingerprint) mountFlags, mountOptions := drivers.ResolveMountOptions(s.getLvmMountOptions()) err := driver.TryMount(lvmVolumePath, imageMntPoint, lvmFstype, mountFlags, mountOptions) if err != nil { @@ -2092,11 +2092,11 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte } ctLvmName := containerNameToLVName(ctName) - lvDevPath = getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointContainers, ctLvmName) + lvDevPath = drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointContainers, ctLvmName) mountpoint = driver.GetContainerMountPoint(c.Project(), s.pool.Name, ctName) default: customLvmName := containerNameToLVName(s.volume.Name) - lvDevPath = getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, customLvmName) + lvDevPath = drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, customLvmName) mountpoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name) } @@ -2306,8 +2306,8 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error { } poolName := s.getOnDiskPoolName() - snapshotLVDevPath := getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, snapshotLVName) - lvExists, _ := storageLVExists(snapshotLVDevPath) + snapshotLVDevPath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, snapshotLVName) + lvExists, _ := drivers.LVMVolumeExists(snapshotLVDevPath) if lvExists { err := removeLV("default", poolName, storagePoolVolumeAPIEndpointCustom, snapshotLVName) if err != nil { From f8d6eade0ecd52b9bf5807b86a2818534797ce10 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:30:23 +0000 Subject: [PATCH 14/18] lxd/storage/lvm: LVMVolumeExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 7f24cd04b5..36f21f52c6 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -556,7 +556,7 @@ func (s *storageLvm) StoragePoolVolumeDelete() error { poolName := s.getOnDiskPoolName() customLvmDevPath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, volumeLvmName) - lvExists, _ := storageLVExists(customLvmDevPath) + lvExists, _ := drivers.LVMVolumeExists(customLvmDevPath) if lvExists { _, err := s.StoragePoolVolumeUmount() @@ -1089,7 +1089,7 @@ func lvmContainerDeleteInternal(projectName, poolName string, ctName string, isS containerLvmDevPath := drivers.LVMDevPath(projectName, vgName, storagePoolVolumeAPIEndpointContainers, containerLvmName) - lvExists, _ := storageLVExists(containerLvmDevPath) + lvExists, _ := drivers.LVMVolumeExists(containerLvmDevPath) if lvExists { err := removeLV(projectName, vgName, storagePoolVolumeAPIEndpointContainers, containerLvmName) if err != nil { @@ -1975,7 +1975,7 @@ func (s *storageLvm) ImageDelete(fingerprint string) error { poolName := s.getOnDiskPoolName() imageLvmDevPath := drivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fingerprint) - lvExists, _ := storageLVExists(imageLvmDevPath) + lvExists, _ := drivers.LVMVolumeExists(imageLvmDevPath) if lvExists { _, err := s.ImageUmount(fingerprint) From a76b5e515c266a76bd60d08e201903a4417da22e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:31:37 +0000 Subject: [PATCH 15/18] lxd/storage/lvm/utils: Removes LVM utils moved to storage pkg Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm_utils.go | 232 --------------------------------------- 1 file changed, 232 deletions(-) diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go index ae3085f8e6..ca71f7df5b 100644 --- a/lxd/storage_lvm_utils.go +++ b/lxd/storage_lvm_utils.go @@ -3,10 +3,8 @@ package main import ( "fmt" "os" - "os/exec" "strconv" "strings" - "syscall" "github.com/pkg/errors" @@ -22,7 +20,6 @@ import ( "github.com/lxc/lxd/shared/api" "github.com/lxc/lxd/shared/logger" "github.com/lxc/lxd/shared/units" - "github.com/lxc/lxd/shared/version" ) func (s *storageLvm) lvExtend(lvPath string, lvSize int64, fsType string, fsMntPoint string, volumeType int, data interface{}) error { @@ -577,16 +574,6 @@ func (s *storageLvm) containerCreateFromImageThinLv(c instance.Instance, fp stri return nil } -func lvmGetLVCount(vgName string) (int, error) { - output, err := shared.TryRunCommand("vgs", "--noheadings", "-o", "lv_count", vgName) - if err != nil { - return -1, err - } - - output = strings.TrimSpace(output) - return strconv.Atoi(output) -} - func lvmLvIsWritable(lvName string) (bool, error) { output, err := shared.TryRunCommand("lvs", "--noheadings", "-o", "lv_attr", lvName) if err != nil { @@ -615,68 +602,6 @@ func storageLVActivate(lvmVolumePath string) error { return nil } -func storagePVExists(pvName string) (bool, error) { - _, err := shared.RunCommand("pvs", "--noheadings", "-o", "lv_attr", pvName) - if err != nil { - runErr, ok := err.(shared.RunError) - if ok { - exitError, ok := runErr.Err.(*exec.ExitError) - if ok { - waitStatus := exitError.Sys().(syscall.WaitStatus) - if waitStatus.ExitStatus() == 5 { - // physical volume not found - return false, nil - } - } - } - return false, fmt.Errorf("error checking for physical volume \"%s\"", pvName) - } - - return true, nil -} - -func storageVGExists(vgName string) (bool, error) { - _, err := shared.RunCommand("vgs", "--noheadings", "-o", "lv_attr", vgName) - if err != nil { - runErr, ok := err.(shared.RunError) - if ok { - exitError, ok := runErr.Err.(*exec.ExitError) - if ok { - waitStatus := exitError.Sys().(syscall.WaitStatus) - if waitStatus.ExitStatus() == 5 { - // volume group not found - return false, nil - } - } - } - - return false, fmt.Errorf("error checking for volume group \"%s\"", vgName) - } - - return true, nil -} - -func storageLVExists(lvName string) (bool, error) { - _, err := shared.RunCommand("lvs", "--noheadings", "-o", "lv_attr", lvName) - if err != nil { - runErr, ok := err.(shared.RunError) - if ok { - exitError, ok := runErr.Err.(*exec.ExitError) - if ok { - waitStatus := exitError.Sys().(syscall.WaitStatus) - if waitStatus.ExitStatus() == 5 { - // logical volume not found - return false, nil - } - } - } - - return false, fmt.Errorf("error checking for logical volume \"%s\"", lvName) - } - - return true, nil -} - func lvmGetLVSize(lvPath string) (string, error) { msg, err := shared.TryRunCommand("lvs", "--noheadings", "-o", "size", "--nosuffix", "--units", "b", lvPath) if err != nil { @@ -695,32 +620,6 @@ func lvmGetLVSize(lvPath string) (string, error) { return detectedSize, nil } -func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) { - output, err := shared.RunCommand("vgs", "--noheadings", "-o", "lv_attr", fmt.Sprintf("%s/%s", vgName, poolName)) - if err != nil { - runErr, ok := err.(shared.RunError) - if ok { - exitError, ok := runErr.Err.(*exec.ExitError) - if 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 pool \"%s\"", poolName) - } - // Found LV named poolname, check type: - attrs := strings.TrimSpace(string(output[:])) - if strings.HasPrefix(attrs, "t") { - return true, nil - } - - return false, fmt.Errorf("pool named \"%s\" exists but is not a thin pool", poolName) -} - func storageLVMGetThinPoolUsers(s *state.State) ([]string, error) { results := []string{} @@ -808,15 +707,6 @@ func containerNameToLVName(containerName string) string { return strings.Replace(lvName, shared.SnapshotDelimiter, "-", -1) } -func getLvmDevPath(projectName, lvmPool string, volumeType string, lvmVolume string) string { - lvmVolume = project.Prefix(projectName, lvmVolume) - if volumeType == "" { - return fmt.Sprintf("/dev/%s/%s", lvmPool, lvmVolume) - } - - return fmt.Sprintf("/dev/%s/%s_%s", lvmPool, volumeType, lvmVolume) -} - func getLVName(lvmPool string, volumeType string, lvmVolume string) string { if volumeType == "" { return fmt.Sprintf("%s/%s", lvmPool, lvmVolume) @@ -830,128 +720,6 @@ func getPrefixedLvName(projectName, volumeType string, lvmVolume string) string return fmt.Sprintf("%s_%s", volumeType, lvmVolume) } -func lvmCreateLv(projectName, vgName string, thinPoolName string, lvName string, lvFsType string, lvSize string, volumeType string, makeThinLv bool) error { - var output string - var err error - - // Round the size to closest 512 bytes - lvSizeInt, err := units.ParseByteSizeString(lvSize) - if err != nil { - return err - } - - lvSizeInt = int64(lvSizeInt/512) * 512 - lvSizeString := units.GetByteSizeString(lvSizeInt, 0) - - lvmPoolVolumeName := getPrefixedLvName(projectName, volumeType, lvName) - if makeThinLv { - targetVg := fmt.Sprintf("%s/%s", vgName, thinPoolName) - _, err = shared.TryRunCommand("lvcreate", "-Wy", "--yes", "--thin", "-n", lvmPoolVolumeName, "--virtualsize", lvSizeString, targetVg) - } else { - _, err = shared.TryRunCommand("lvcreate", "-Wy", "--yes", "-n", lvmPoolVolumeName, "--size", lvSizeString, vgName) - } - if err != nil { - logger.Errorf("Could not create LV \"%s\": %v", lvmPoolVolumeName, err) - return fmt.Errorf("Could not create thin LV named %s: %v", lvmPoolVolumeName, err) - } - - fsPath := getLvmDevPath(projectName, vgName, volumeType, lvName) - - output, err = storageDrivers.MakeFSType(fsPath, lvFsType, nil) - if err != nil { - logger.Errorf("Filesystem creation failed: %v (%s)", err, output) - return fmt.Errorf("Error making filesystem on image LV: %v (%s)", err, output) - } - - return nil -} - -func lvmCreateThinpool(s *state.State, sTypeVersion string, vgName string, thinPoolName string, lvFsType string) error { - exists, err := storageLVMThinpoolExists(vgName, thinPoolName) - if err != nil { - return err - } - - if exists { - return nil - } - - err = createDefaultThinPool(sTypeVersion, vgName, thinPoolName, lvFsType) - if err != nil { - return err - } - - err = storageLVMValidateThinPoolName(s, vgName, thinPoolName) - if err != nil { - logger.Errorf("Setting thin pool name: %s", err) - return fmt.Errorf("Error setting LVM thin pool config: %v", err) - } - - return nil -} - -func createDefaultThinPool(sTypeVersion string, vgName string, thinPoolName string, lvFsType string) error { - isRecent, err := lvmVersionIsAtLeast(sTypeVersion, "2.02.99") - if err != nil { - return fmt.Errorf("Error checking LVM version: %s", err) - } - - // Create the thin pool - lvmThinPool := fmt.Sprintf("%s/%s", vgName, thinPoolName) - if isRecent { - _, err = shared.TryRunCommand( - "lvcreate", - "-Wy", "--yes", - "--poolmetadatasize", "1G", - "-l", "100%FREE", - "--thinpool", lvmThinPool) - } else { - _, err = shared.TryRunCommand( - "lvcreate", - "-Wy", "--yes", - "--poolmetadatasize", "1G", - "-L", "1G", - "--thinpool", lvmThinPool) - } - - if err != nil { - logger.Errorf("Could not create thin pool \"%s\": %v", thinPoolName, err) - return fmt.Errorf("Could not create LVM thin pool named %s: %v", thinPoolName, err) - } - - if !isRecent { - // Grow it to the maximum VG size (two step process required by old LVM) - _, err = shared.TryRunCommand("lvextend", "--alloc", "anywhere", "-l", "100%FREE", lvmThinPool) - - if err != nil { - logger.Errorf("Could not grow thin pool: \"%s\": %v", thinPoolName, err) - return fmt.Errorf("Could not grow LVM thin pool named %s: %v", thinPoolName, err) - } - } - - return nil -} - -func lvmVersionIsAtLeast(sTypeVersion string, versionString string) (bool, error) { - lvmVersionString := strings.Split(sTypeVersion, "/")[0] - - lvmVersion, err := version.Parse(lvmVersionString) - if err != nil { - return false, err - } - - inVersion, err := version.Parse(versionString) - if err != nil { - return false, err - } - - if lvmVersion.Compare(inVersion) < 0 { - return false, nil - } - - return true, nil -} - // Copy an LVM custom volume. func (s *storageLvm) copyVolume(sourcePool string, source string) error { targetMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name) From b766478db727e3378766fb285e679984330db118 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:32:14 +0000 Subject: [PATCH 16/18] lxd/storage/lvm/utils: LVMDevPath usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm_utils.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go index ca71f7df5b..dba9888a6a 100644 --- a/lxd/storage_lvm_utils.go +++ b/lxd/storage_lvm_utils.go @@ -177,7 +177,7 @@ func (s *storageLvm) renameLVByPath(project, oldName string, newName string, vol } func removeLV(project, vgName string, volumeType string, lvName string) error { - lvmVolumePath := getLvmDevPath(project, vgName, volumeType, lvName) + lvmVolumePath := storageDrivers.LVMDevPath(project, vgName, volumeType, lvName) _, err := shared.TryRunCommand("lvremove", "-f", lvmVolumePath) if err != nil { @@ -195,8 +195,8 @@ func (s *storageLvm) createSnapshotLV(project, vgName string, origLvName string, sourceProject = "default" } - sourceLvmVolumePath := getLvmDevPath(sourceProject, vgName, origVolumeType, origLvName) - isRecent, err := lvmVersionIsAtLeast(s.sTypeVersion, "2.02.99") + sourceLvmVolumePath := storageDrivers.LVMDevPath(sourceProject, vgName, origVolumeType, origLvName) + isRecent, err := storageDrivers.LVMVersionIsAtLeast(s.sTypeVersion, "2.02.99") if err != nil { return "", fmt.Errorf("Error checking LVM version: %v", err) } @@ -241,7 +241,7 @@ func (s *storageLvm) createSnapshotLV(project, vgName string, origLvName string, return "", fmt.Errorf("Could not create snapshot LV named %s: %v", lvName, err) } - targetLvmVolumePath := getLvmDevPath(project, vgName, volumeType, lvName) + targetLvmVolumePath := storageDrivers.LVMDevPath(project, vgName, volumeType, lvName) if makeThinLv { // Snapshots of thin logical volumes can be directly activated. // Normal snapshots will complain about changing the origin @@ -315,7 +315,7 @@ func (s *storageLvm) copyContainerThinpool(target instance.Instance, source inst poolName := s.getOnDiskPoolName() containerName := target.Name() containerLvmName := containerNameToLVName(containerName) - containerLvDevPath := getLvmDevPath(target.Project(), poolName, + containerLvDevPath := storageDrivers.LVMDevPath(target.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName) // If btrfstune sees two btrfs filesystems with the same UUID it @@ -518,7 +518,7 @@ func (s *storageLvm) containerCreateFromImageLv(c instance.Instance, fp string) func (s *storageLvm) containerCreateFromImageThinLv(c instance.Instance, fp string) error { poolName := s.getOnDiskPoolName() // Check if the image already exists. - imageLvmDevPath := getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fp) + imageLvmDevPath := storageDrivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fp) imageStoragePoolLockID := getImageCreateLockID(poolName, fp) lxdStorageMapLock.Lock() @@ -847,7 +847,7 @@ func (s *storageLvm) copyVolumeThinpool(source string, target string, readOnly b return err } - lvDevPath := getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, targetLvmName) + lvDevPath := storageDrivers.LVMDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, targetLvmName) msg, err := driver.FSGenerateNewUUID(lvFsType, lvDevPath) if err != nil { From 695324fe7d32e87e05eb449488efba6d0054526a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:32:33 +0000 Subject: [PATCH 17/18] lxd/storage/lvm/utils: LVMVolumeExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm_utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go index dba9888a6a..e0ae2c3329 100644 --- a/lxd/storage_lvm_utils.go +++ b/lxd/storage_lvm_utils.go @@ -371,7 +371,7 @@ func (s *storageLvm) copySnapshot(target instance.Instance, source instance.Inst // Copy a container on a storage pool that does not use a thinpool. func (s *storageLvm) copyContainerLv(target instance.Instance, source instance.Instance, readonly bool, refresh bool) error { - exists, err := storageLVExists(getLvmDevPath(target.Project(), s.getOnDiskPoolName(), + exists, err := storageDrivers.LVMVolumeExists(storageDrivers.LVMDevPath(target.Project(), s.getOnDiskPoolName(), storagePoolVolumeAPIEndpointContainers, containerNameToLVName(target.Name()))) if err != nil { return err @@ -532,7 +532,7 @@ func (s *storageLvm) containerCreateFromImageThinLv(c instance.Instance, fp stri lxdStorageMapLock.Unlock() var imgerr error - ok, _ := storageLVExists(imageLvmDevPath) + ok, _ := storageDrivers.LVMVolumeExists(imageLvmDevPath) if ok { _, volume, err := s.s.Cluster.StoragePoolNodeVolumeGetType(fp, db.StoragePoolVolumeTypeImage, s.poolID) if err != nil { From 998e2a7846647fe9dca7a6783221e2473ba6712a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 17 Dec 2019 11:32:54 +0000 Subject: [PATCH 18/18] lxd/storage/lvm/utils: LVMThinpoolExists usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_lvm_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go index e0ae2c3329..a7d52ad7eb 100644 --- a/lxd/storage_lvm_utils.go +++ b/lxd/storage_lvm_utils.go @@ -671,7 +671,7 @@ func storageLVMValidateThinPoolName(s *state.State, vgName string, value string) return fmt.Errorf("can not set lvm.thinpool_name without lvm.vg_name set") } - poolExists, err := storageLVMThinpoolExists(vgName, value) + poolExists, err := storageDrivers.LVMThinpoolExists(vgName, value) if err != nil { return fmt.Errorf("error checking for thin pool \"%s\" in \"%s\": %v", value, vgName, err) }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel