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

Reply via email to