[lxc-devel] [lxd/master] Storage Utils moved to storage package

tomponline on Github lxc-bot at linuxcontainers.org
Tue Oct 22 11:42:36 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 529 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191022/09e51d69/attachment-0001.bin>
-------------- next part --------------
From e3dcaa696308ba975246ad9f898ddad8981aca0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sun, 6 Oct 2019 20:56:17 -0400
Subject: [PATCH 1/3] lxd/storage/utils: Add common helpers to utils
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/utils.go | 274 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 274 insertions(+)

diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index d23d4f4171..e370a7efd9 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -3,17 +3,41 @@ package storage
 import (
 	"fmt"
 	"os"
+	"path/filepath"
 	"strings"
 	"time"
 
 	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/lxd/db"
+	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
+var baseDirectories = []string{
+	"containers",
+	"containers-snapshots",
+	"custom",
+	"custom-snapshots",
+	"images",
+	"virtual-machines",
+	"virtual-machines-snapshots",
+}
+
+func createStorageStructure(path string) error {
+	for _, name := range baseDirectories {
+		err := os.MkdirAll(filepath.Join(path, name), 0711)
+		if err != nil && !os.IsExist(err) {
+			return err
+		}
+	}
+
+	return nil
+}
+
 // MkfsOptions represents options for filesystem creation.
 type MkfsOptions struct {
 	Label string
@@ -360,3 +384,253 @@ func GetStorageResource(path string) (*api.ResourcesStoragePool, error) {
 
 	return &res, nil
 }
+
+// VolumeTypeNameToType converts a volume type string to internal code.
+func VolumeTypeNameToType(volumeTypeName string) (int, error) {
+	switch volumeTypeName {
+	case db.StoragePoolVolumeTypeNameContainer:
+		return db.StoragePoolVolumeTypeContainer, nil
+	case db.StoragePoolVolumeTypeNameImage:
+		return db.StoragePoolVolumeTypeImage, nil
+	case db.StoragePoolVolumeTypeNameCustom:
+		return db.StoragePoolVolumeTypeCustom, nil
+	}
+
+	return -1, fmt.Errorf("invalid storage volume type name")
+}
+
+// VolumeDBCreate creates a volume in the database.
+func VolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, snapshot bool, volumeConfig map[string]string) error {
+	// Convert the volume type name to our internal integer representation.
+	volumeType, err := VolumeTypeNameToType(volumeTypeName)
+	if err != nil {
+		return err
+	}
+
+	// Load storage pool the volume will be attached to.
+	poolID, poolStruct, err := s.Cluster.StoragePoolGet(poolName)
+	if err != nil {
+		return err
+	}
+
+	// Check that a storage volume of the same storage volume type does not
+	// already exist.
+	volumeID, _ := s.Cluster.StoragePoolNodeVolumeGetTypeID(volumeName, volumeType, poolID)
+	if volumeID > 0 {
+		return fmt.Errorf("a storage volume of type %s does already exist", volumeTypeName)
+	}
+
+	// Make sure that we don't pass a nil to the next function.
+	if volumeConfig == nil {
+		volumeConfig = map[string]string{}
+	}
+
+	// Validate the requested storage volume configuration.
+	err = VolumeValidateConfig(poolName, volumeConfig, poolStruct)
+	if err != nil {
+		return err
+	}
+
+	err = VolumeFillDefault(poolName, volumeConfig, poolStruct)
+	if err != nil {
+		return err
+	}
+
+	// Create the database entry for the storage volume.
+	_, err = s.Cluster.StoragePoolVolumeCreate("default", volumeName, volumeDescription, volumeType, snapshot, poolID, volumeConfig)
+	if err != nil {
+		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
+	}
+
+	return nil
+}
+
+// SupportedPoolTypes the types of pools supported.
+var SupportedPoolTypes = []string{"btrfs", "ceph", "cephfs", "dir", "lvm", "zfs"}
+
+// StorageVolumeConfigKeys config validation for btrfs, ceph, cephfs, dir, lvm, zfs types.
+var StorageVolumeConfigKeys = map[string]func(value string) ([]string, error){
+	"block.filesystem": func(value string) ([]string, error) {
+		err := shared.IsOneOf(value, []string{"btrfs", "ext4", "xfs"})
+		if err != nil {
+			return nil, err
+		}
+
+		return []string{"ceph", "lvm"}, nil
+	},
+	"block.mount_options": func(value string) ([]string, error) {
+		return []string{"ceph", "lvm"}, shared.IsAny(value)
+	},
+	"security.shifted": func(value string) ([]string, error) {
+		return SupportedPoolTypes, shared.IsBool(value)
+	},
+	"security.unmapped": func(value string) ([]string, error) {
+		return SupportedPoolTypes, shared.IsBool(value)
+	},
+	"size": func(value string) ([]string, error) {
+		if value == "" {
+			return []string{"btrfs", "ceph", "cephfs", "lvm", "zfs"}, nil
+		}
+
+		_, err := units.ParseByteSizeString(value)
+		if err != nil {
+			return nil, err
+		}
+
+		return []string{"btrfs", "ceph", "cephfs", "lvm", "zfs"}, nil
+	},
+	"volatile.idmap.last": func(value string) ([]string, error) {
+		return SupportedPoolTypes, shared.IsAny(value)
+	},
+	"volatile.idmap.next": func(value string) ([]string, error) {
+		return SupportedPoolTypes, shared.IsAny(value)
+	},
+	"zfs.remove_snapshots": func(value string) ([]string, error) {
+		err := shared.IsBool(value)
+		if err != nil {
+			return nil, err
+		}
+
+		return []string{"zfs"}, nil
+	},
+	"zfs.use_refquota": func(value string) ([]string, error) {
+		err := shared.IsBool(value)
+		if err != nil {
+			return nil, err
+		}
+
+		return []string{"zfs"}, nil
+	},
+}
+
+// VolumeValidateConfig validations volume config.
+func VolumeValidateConfig(name string, config map[string]string, parentPool *api.StoragePool) error {
+	for key, val := range config {
+		// User keys are not validated.
+		if strings.HasPrefix(key, "user.") {
+			continue
+		}
+
+		// Validate storage volume config keys.
+		validator, ok := StorageVolumeConfigKeys[key]
+		if !ok {
+			return fmt.Errorf("Invalid storage volume configuration key: %s", key)
+		}
+
+		_, err := validator(val)
+		if err != nil {
+			return err
+		}
+
+		if parentPool.Driver != "zfs" || parentPool.Driver == "dir" {
+			if config["zfs.use_refquota"] != "" {
+				return fmt.Errorf("the key volume.zfs.use_refquota cannot be used with non zfs storage volumes")
+			}
+
+			if config["zfs.remove_snapshots"] != "" {
+				return fmt.Errorf("the key volume.zfs.remove_snapshots cannot be used with non zfs storage volumes")
+			}
+		}
+
+		if parentPool.Driver == "dir" {
+			if config["block.mount_options"] != "" {
+				return fmt.Errorf("the key block.mount_options cannot be used with dir storage volumes")
+			}
+
+			if config["block.filesystem"] != "" {
+				return fmt.Errorf("the key block.filesystem cannot be used with dir storage volumes")
+			}
+		}
+	}
+
+	return nil
+}
+
+// VolumeFillDefault fills default settings into a volume config.
+func VolumeFillDefault(name string, config map[string]string, parentPool *api.StoragePool) error {
+	if parentPool.Driver == "dir" {
+		config["size"] = ""
+	} else if parentPool.Driver == "lvm" || parentPool.Driver == "ceph" {
+		if config["block.filesystem"] == "" {
+			config["block.filesystem"] = parentPool.Config["volume.block.filesystem"]
+		}
+		if config["block.filesystem"] == "" {
+			// Unchangeable volume property: Set unconditionally.
+			config["block.filesystem"] = "ext4"
+		}
+
+		if config["block.mount_options"] == "" {
+			config["block.mount_options"] = parentPool.Config["volume.block.mount_options"]
+		}
+		if config["block.mount_options"] == "" {
+			// Unchangeable volume property: Set unconditionally.
+			config["block.mount_options"] = "discard"
+		}
+
+		// Does the pool request a default size for new storage volumes?
+		if config["size"] == "0" || config["size"] == "" {
+			config["size"] = parentPool.Config["volume.size"]
+		}
+		// Does the user explicitly request a default size for new
+		// storage volumes?
+		if config["size"] == "0" || config["size"] == "" {
+			config["size"] = "10GB"
+		}
+	} else {
+		if config["size"] != "" {
+			_, err := units.ParseByteSizeString(config["size"])
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+// VolumeSnapshotsGet returns a list of snapshots of the form <volume>/<snapshot-name>.
+func VolumeSnapshotsGet(s *state.State, pool string, volume string, volType int) ([]string, error) {
+	poolID, err := s.Cluster.StoragePoolGetID(pool)
+	if err != nil {
+		return nil, err
+	}
+
+	snapshots, err := s.Cluster.StoragePoolVolumeSnapshotsGetType(volume, volType, poolID)
+	if err != nil {
+		return nil, err
+	}
+
+	return snapshots, nil
+}
+
+// VolumePropertiesTranslate validates the supplied volume config and removes any keys that are not
+// suitable for the volume's driver type.
+func VolumePropertiesTranslate(targetConfig map[string]string, targetParentPoolDriver string) (map[string]string, error) {
+	newConfig := make(map[string]string, len(targetConfig))
+	for key, val := range targetConfig {
+		// User keys are not validated.
+		if strings.HasPrefix(key, "user.") {
+			continue
+		}
+
+		// Validate storage volume config keys.
+		validator, ok := StorageVolumeConfigKeys[key]
+		if !ok {
+			return nil, fmt.Errorf("Invalid storage volume configuration key: %s", key)
+		}
+
+		validStorageDrivers, err := validator(val)
+		if err != nil {
+			return nil, err
+		}
+
+		// Drop invalid keys.
+		if !shared.StringInSlice(targetParentPoolDriver, validStorageDrivers) {
+			continue
+		}
+
+		newConfig[key] = val
+	}
+
+	return newConfig, nil
+}

From 79bcc4aa2cc1095abb97f10fe6c2e09826d7de21 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 9 Oct 2019 11:31:26 +0100
Subject: [PATCH 2/3] lxd/storage/volumes/config: Removes functions moved to
 storage package

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage_volumes_config.go | 173 ----------------------------------
 lxd/storage_volumes_utils.go  |  73 --------------
 2 files changed, 246 deletions(-)

diff --git a/lxd/storage_volumes_config.go b/lxd/storage_volumes_config.go
index 76dca2b558..fff20d0496 100644
--- a/lxd/storage_volumes_config.go
+++ b/lxd/storage_volumes_config.go
@@ -2,43 +2,8 @@ package main
 
 import (
 	"fmt"
-	"strings"
-
-	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/units"
 )
 
-func storageVolumePropertiesTranslate(targetConfig map[string]string, targetParentPoolDriver string) (map[string]string, error) {
-	newConfig := make(map[string]string, len(targetConfig))
-	for key, val := range targetConfig {
-		// User keys are not validated.
-		if strings.HasPrefix(key, "user.") {
-			continue
-		}
-
-		// Validate storage volume config keys.
-		validator, ok := storageVolumeConfigKeys[key]
-		if !ok {
-			return nil, fmt.Errorf("Invalid storage volume configuration key: %s", key)
-		}
-
-		validStorageDrivers, err := validator(val)
-		if err != nil {
-			return nil, err
-		}
-
-		// Drop invalid keys.
-		if !shared.StringInSlice(targetParentPoolDriver, validStorageDrivers) {
-			continue
-		}
-
-		newConfig[key] = val
-	}
-
-	return newConfig, nil
-}
-
 func updateStoragePoolVolumeError(unchangeable []string, driverName string) error {
 	return fmt.Errorf(`The %v properties cannot be changed for "%s" `+
 		`storage volumes`, unchangeable, driverName)
@@ -89,141 +54,3 @@ var changeableStoragePoolVolumeProperties = map[string][]string{
 		"zfs.use_refquota",
 	},
 }
-
-// btrfs, ceph, cephfs, dir, lvm, zfs
-var storageVolumeConfigKeys = map[string]func(value string) ([]string, error){
-	"block.filesystem": func(value string) ([]string, error) {
-		err := shared.IsOneOf(value, []string{"btrfs", "ext4", "xfs"})
-		if err != nil {
-			return nil, err
-		}
-
-		return []string{"ceph", "lvm"}, nil
-	},
-	"block.mount_options": func(value string) ([]string, error) {
-		return []string{"ceph", "lvm"}, shared.IsAny(value)
-	},
-	"security.shifted": func(value string) ([]string, error) {
-		return supportedPoolTypes, shared.IsBool(value)
-	},
-	"security.unmapped": func(value string) ([]string, error) {
-		return supportedPoolTypes, shared.IsBool(value)
-	},
-	"size": func(value string) ([]string, error) {
-		if value == "" {
-			return []string{"btrfs", "ceph", "cephfs", "lvm", "zfs"}, nil
-		}
-
-		_, err := units.ParseByteSizeString(value)
-		if err != nil {
-			return nil, err
-		}
-
-		return []string{"btrfs", "ceph", "cephfs", "lvm", "zfs"}, nil
-	},
-	"volatile.idmap.last": func(value string) ([]string, error) {
-		return supportedPoolTypes, shared.IsAny(value)
-	},
-	"volatile.idmap.next": func(value string) ([]string, error) {
-		return supportedPoolTypes, shared.IsAny(value)
-	},
-	"zfs.remove_snapshots": func(value string) ([]string, error) {
-		err := shared.IsBool(value)
-		if err != nil {
-			return nil, err
-		}
-
-		return []string{"zfs"}, nil
-	},
-	"zfs.use_refquota": func(value string) ([]string, error) {
-		err := shared.IsBool(value)
-		if err != nil {
-			return nil, err
-		}
-
-		return []string{"zfs"}, nil
-	},
-}
-
-func storageVolumeValidateConfig(name string, config map[string]string, parentPool *api.StoragePool) error {
-	for key, val := range config {
-		// User keys are not validated.
-		if strings.HasPrefix(key, "user.") {
-			continue
-		}
-
-		// Validate storage volume config keys.
-		validator, ok := storageVolumeConfigKeys[key]
-		if !ok {
-			return fmt.Errorf("Invalid storage volume configuration key: %s", key)
-		}
-
-		_, err := validator(val)
-		if err != nil {
-			return err
-		}
-
-		if parentPool.Driver != "zfs" || parentPool.Driver == "dir" {
-			if config["zfs.use_refquota"] != "" {
-				return fmt.Errorf("the key volume.zfs.use_refquota cannot be used with non zfs storage volumes")
-			}
-
-			if config["zfs.remove_snapshots"] != "" {
-				return fmt.Errorf("the key volume.zfs.remove_snapshots cannot be used with non zfs storage volumes")
-			}
-		}
-
-		if parentPool.Driver == "dir" {
-			if config["block.mount_options"] != "" {
-				return fmt.Errorf("the key block.mount_options cannot be used with dir storage volumes")
-			}
-
-			if config["block.filesystem"] != "" {
-				return fmt.Errorf("the key block.filesystem cannot be used with dir storage volumes")
-			}
-		}
-	}
-
-	return nil
-}
-
-func storageVolumeFillDefault(name string, config map[string]string, parentPool *api.StoragePool) error {
-	if parentPool.Driver == "dir" {
-		config["size"] = ""
-	} else if parentPool.Driver == "lvm" || parentPool.Driver == "ceph" {
-		if config["block.filesystem"] == "" {
-			config["block.filesystem"] = parentPool.Config["volume.block.filesystem"]
-		}
-		if config["block.filesystem"] == "" {
-			// Unchangeable volume property: Set unconditionally.
-			config["block.filesystem"] = "ext4"
-		}
-
-		if config["block.mount_options"] == "" {
-			config["block.mount_options"] = parentPool.Config["volume.block.mount_options"]
-		}
-		if config["block.mount_options"] == "" {
-			// Unchangeable volume property: Set unconditionally.
-			config["block.mount_options"] = "discard"
-		}
-
-		// Does the pool request a default size for new storage volumes?
-		if config["size"] == "0" || config["size"] == "" {
-			config["size"] = parentPool.Config["volume.size"]
-		}
-		// Does the user explicitly request a default size for new
-		// storage volumes?
-		if config["size"] == "0" || config["size"] == "" {
-			config["size"] = "10GB"
-		}
-	} else {
-		if config["size"] != "" {
-			_, err := units.ParseByteSizeString(config["size"])
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index aa02763399..45da213876 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -38,19 +38,6 @@ const (
 var supportedVolumeTypesExceptImages = []int{storagePoolVolumeTypeContainer, storagePoolVolumeTypeCustom}
 var supportedVolumeTypes = append(supportedVolumeTypesExceptImages, storagePoolVolumeTypeImage)
 
-func storagePoolVolumeTypeNameToType(volumeTypeName string) (int, error) {
-	switch volumeTypeName {
-	case storagePoolVolumeTypeNameContainer:
-		return storagePoolVolumeTypeContainer, nil
-	case storagePoolVolumeTypeNameImage:
-		return storagePoolVolumeTypeImage, nil
-	case storagePoolVolumeTypeNameCustom:
-		return storagePoolVolumeTypeCustom, nil
-	}
-
-	return -1, fmt.Errorf("invalid storage volume type name")
-}
-
 func storagePoolVolumeTypeNameToAPIEndpoint(volumeTypeName string) (string, error) {
 	switch volumeTypeName {
 	case storagePoolVolumeTypeNameContainer:
@@ -524,51 +511,6 @@ func profilesUsingPoolVolumeGetNames(db *db.Cluster, volumeName string, volumeTy
 	return usedBy, nil
 }
 
-func storagePoolVolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, snapshot bool, volumeConfig map[string]string) error {
-	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
-	if err != nil {
-		return err
-	}
-
-	// Load storage pool the volume will be attached to.
-	poolID, poolStruct, err := s.Cluster.StoragePoolGet(poolName)
-	if err != nil {
-		return err
-	}
-
-	// Check that a storage volume of the same storage volume type does not
-	// already exist.
-	volumeID, _ := s.Cluster.StoragePoolNodeVolumeGetTypeID(volumeName, volumeType, poolID)
-	if volumeID > 0 {
-		return fmt.Errorf("a storage volume of type %s does already exist", volumeTypeName)
-	}
-
-	// Make sure that we don't pass a nil to the next function.
-	if volumeConfig == nil {
-		volumeConfig = map[string]string{}
-	}
-
-	// Validate the requested storage volume configuration.
-	err = storageVolumeValidateConfig(poolName, volumeConfig, poolStruct)
-	if err != nil {
-		return err
-	}
-
-	err = storageVolumeFillDefault(poolName, volumeConfig, poolStruct)
-	if err != nil {
-		return err
-	}
-
-	// Create the database entry for the storage volume.
-	_, err = s.Cluster.StoragePoolVolumeCreate("default", volumeName, volumeDescription, volumeType, snapshot, poolID, volumeConfig)
-	if err != nil {
-		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
-	}
-
-	return nil
-}
-
 func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol *api.StorageVolumesPost) (storage, error) {
 	volumeName := vol.Name
 	volumeDescription := vol.Description
@@ -729,18 +671,3 @@ func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.St
 
 	return s, nil
 }
-
-// storagePoolVolumeSnapshotsGet returns a list of snapshots of the form <volume>/<snapshot-name>.
-func storagePoolVolumeSnapshotsGet(s *state.State, pool string, volume string, volType int) ([]string, error) {
-	poolID, err := s.Cluster.StoragePoolGetID(pool)
-	if err != nil {
-		return nil, err
-	}
-
-	snapshots, err := s.Cluster.StoragePoolVolumeSnapshotsGetType(volume, volType, poolID)
-	if err != nil {
-		return nil, err
-	}
-
-	return snapshots, nil
-}

From 37c28ba47441219ef472d7c5c53580d8db1c643f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 9 Oct 2019 11:34:21 +0100
Subject: [PATCH 3/3] lxd: Updates use of funcs/vars moved to storage pkg

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/container_lxc.go            |  2 +-
 lxd/migrate_storage_volumes.go  |  3 ++-
 lxd/patches.go                  | 34 ++++++++++++++++-----------------
 lxd/storage.go                  |  2 +-
 lxd/storage_btrfs.go            |  2 +-
 lxd/storage_ceph.go             |  2 +-
 lxd/storage_ceph_utils.go       |  2 +-
 lxd/storage_cephfs.go           |  2 +-
 lxd/storage_dir.go              |  2 +-
 lxd/storage_lvm.go              |  2 +-
 lxd/storage_migration.go        |  2 +-
 lxd/storage_pools_utils.go      |  2 --
 lxd/storage_shared.go           |  3 ++-
 lxd/storage_volumes.go          | 20 +++++++++----------
 lxd/storage_volumes_snapshot.go | 12 ++++++------
 lxd/storage_volumes_utils.go    | 17 +++++++++--------
 lxd/storage_zfs.go              |  2 +-
 17 files changed, 56 insertions(+), 55 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index f3282cdde6..7355f554d8 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -324,7 +324,7 @@ func containerLXCCreate(s *state.State, args db.InstanceArgs) (container, error)
 
 	// Fill in any default volume config
 	volumeConfig := map[string]string{}
-	err = storageVolumeFillDefault(storagePool, volumeConfig, pool)
+	err = driver.VolumeFillDefault(storagePool, volumeConfig, pool)
 	if err != nil {
 		c.Delete()
 		return nil, err
diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 1c492dedb2..4067d9e3a7 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/operations"
+	storagePools "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -58,7 +59,7 @@ func (s *migrationSourceWs) DoStorage(migrateOp *operations.Operation) error {
 
 		var err error
 
-		snaps, err := storagePoolVolumeSnapshotsGet(state, pool.Name, volume.Name, storagePoolVolumeTypeCustom)
+		snaps, err := storagePools.VolumeSnapshotsGet(state, pool.Name, volume.Name, storagePoolVolumeTypeCustom)
 		if err == nil {
 			poolID, err := state.Cluster.StoragePoolGetID(pool.Name)
 			if err == nil {
diff --git a/lxd/patches.go b/lxd/patches.go
index 1193bbd927..e3e8e7fd35 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -470,7 +470,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		// Initialize empty storage volume configuration for the
 		// container.
 		containerPoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -558,7 +558,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// Initialize empty storage volume configuration for the
 			// container.
 			snapshotPoolVolumeConfig := map[string]string{}
-			err = storageVolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
+			err = driver.VolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
 			if err != nil {
 				return err
 			}
@@ -639,7 +639,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 	images := append(imgPublic, imgPrivate...)
 	for _, img := range images {
 		imagePoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -757,7 +757,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 		// Initialize empty storage volume configuration for the
 		// container.
 		containerPoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -874,7 +874,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 		// Initialize empty storage volume configuration for the
 		// container.
 		snapshotPoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -904,7 +904,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 	images := append(imgPublic, imgPrivate...)
 	for _, img := range images {
 		imagePoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -1066,7 +1066,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		// Initialize empty storage volume configuration for the
 		// container.
 		containerPoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -1221,7 +1221,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// Initialize empty storage volume configuration for the
 			// container.
 			snapshotPoolVolumeConfig := map[string]string{}
-			err = storageVolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
+			err = driver.VolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
 			if err != nil {
 				return err
 			}
@@ -1392,7 +1392,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 	for _, img := range images {
 		imagePoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -1584,7 +1584,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		// Initialize empty storage volume configuration for the
 		// container.
 		containerPoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(ct, containerPoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -1670,7 +1670,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			// Initialize empty storage volume configuration for the
 			// container.
 			snapshotPoolVolumeConfig := map[string]string{}
-			err = storageVolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
+			err = driver.VolumeFillDefault(cs, snapshotPoolVolumeConfig, defaultPool)
 			if err != nil {
 				return err
 			}
@@ -1726,7 +1726,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 	images := append(imgPublic, imgPrivate...)
 	for _, img := range images {
 		imagePoolVolumeConfig := map[string]string{}
-		err = storageVolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
+		err = driver.VolumeFillDefault(img, imagePoolVolumeConfig, defaultPool)
 		if err != nil {
 			return err
 		}
@@ -2248,7 +2248,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 			}
 
 			// Insert default values.
-			err := storageVolumeFillDefault(volume.Name, volume.Config, pool)
+			err := driver.VolumeFillDefault(volume.Name, volume.Config, pool)
 			if err != nil {
 				return err
 			}
@@ -2286,7 +2286,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 
 			// It shouldn't be possible that false volume types
 			// exist in the db, so it's safe to ignore the error.
-			volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type)
+			volumeType, _ := driver.VolumeTypeNameToType(volume.Type)
 			// Update the volume config.
 			err = d.cluster.StoragePoolVolumeUpdate(volume.Name, volumeType, poolID, volume.Description, volume.Config)
 			if err != nil {
@@ -2409,7 +2409,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 				volume.Config = map[string]string{}
 
 				// Insert default values.
-				err := storageVolumeFillDefault(volume.Name, volume.Config, pool)
+				err := driver.VolumeFillDefault(volume.Name, volume.Config, pool)
 				if err != nil {
 					return err
 				}
@@ -2434,7 +2434,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 
 			// It shouldn't be possible that false volume types
 			// exist in the db, so it's safe to ignore the error.
-			volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type)
+			volumeType, _ := driver.VolumeTypeNameToType(volume.Type)
 			// Update the volume config.
 			err = d.cluster.StoragePoolVolumeUpdate(volume.Name, volumeType, poolID, volume.Description, volume.Config)
 			if err != nil {
@@ -2564,7 +2564,7 @@ func patchStorageZFSVolumeSize(name string, d *Daemon) error {
 
 			// It shouldn't be possible that false volume types
 			// exist in the db, so it's safe to ignore the error.
-			volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type)
+			volumeType, _ := driver.VolumeTypeNameToType(volume.Type)
 			// Update the volume config.
 			err = d.cluster.StoragePoolVolumeUpdate(volume.Name,
 				volumeType, poolID, volume.Description,
diff --git a/lxd/storage.go b/lxd/storage.go
index 4f5a1d6289..64bce90a1c 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -902,7 +902,7 @@ func storageVolumeMount(state *state.State, poolName string, volumeName string,
 		return fmt.Errorf("Received non-LXC container instance")
 	}
 
-	volumeType, _ := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, _ := driver.VolumeTypeNameToType(volumeTypeName)
 	s, err := storagePoolVolumeAttachInit(state, poolName, volumeName, volumeType, c)
 	if err != nil {
 		return err
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 8690f2a8ae..4619e0abd3 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2897,7 +2897,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
 
 	if !volumeOnly {
 		// Handle snapshots
-		snapshots, err := storagePoolVolumeSnapshotsGet(s.s, sourcePool, sourceName, storagePoolVolumeTypeCustom)
+		snapshots, err := driver.VolumeSnapshotsGet(s.s, sourcePool, sourceName, storagePoolVolumeTypeCustom)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index b6c4d5e29d..ec7d78d848 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -422,7 +422,7 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
 		s.volume.Name, s.pool.Name)
 
 	// Delete all snapshots
-	snapshots, err := storagePoolVolumeSnapshotsGet(s.s, s.pool.Name, s.volume.Name, storagePoolVolumeTypeCustom)
+	snapshots, err := driver.VolumeSnapshotsGet(s.s, s.pool.Name, s.volume.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 2b3d9bed36..c5fedc0898 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -1925,7 +1925,7 @@ func (s *storageCeph) doCrossPoolVolumeCopy(source *api.StorageVolumeSource) err
 		defer srcStorage.StoragePoolUmount()
 	}
 
-	snapshots, err := storagePoolVolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+	snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 120a6100b1..6793e2bbf3 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -799,7 +799,7 @@ func (s *storageCephFs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) e
 
 	// Copy the snapshots
 	if !source.VolumeOnly {
-		snapshots, err := storagePoolVolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+		snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index da290132c5..128f9b90f2 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -1397,7 +1397,7 @@ func (s *storageDir) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 		return nil
 	}
 
-	snapshots, err := storagePoolVolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+	snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index a3d408f6d2..3671f8055b 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -2221,7 +2221,7 @@ func (s *storageLvm) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 		return nil
 	}
 
-	snapshots, err := storagePoolVolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+	snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 7bb005266d..525298614f 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -62,7 +62,7 @@ func (s rsyncStorageSourceDriver) SendStorageVolume(conn *websocket.Conn, op *op
 	volume := storage.GetStoragePoolVolume()
 
 	if !volumeOnly {
-		snapshots, err := storagePoolVolumeSnapshotsGet(state, pool.Name, volume.Name, storagePoolVolumeTypeCustom)
+		snapshots, err := driver.VolumeSnapshotsGet(state, pool.Name, volume.Name, storagePoolVolumeTypeCustom)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index e122cdcf87..3da2e8d30e 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -12,8 +12,6 @@ import (
 	"github.com/lxc/lxd/shared/version"
 )
 
-var supportedPoolTypes = []string{"btrfs", "ceph", "cephfs", "dir", "lvm", "zfs"}
-
 func storagePoolUpdate(state *state.State, name, newDescription string, newConfig map[string]string, withDB bool) error {
 	s, err := storagePoolInit(state, name)
 	if err != nil {
diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
index 11875f06ec..cf7c974840 100644
--- a/lxd/storage_shared.go
+++ b/lxd/storage_shared.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	"github.com/lxc/lxd/lxd/state"
+	storagePools "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared/api"
 )
 
@@ -61,7 +62,7 @@ func (s *storageShared) SetStoragePoolVolumeWritable(writable *api.StorageVolume
 func (s *storageShared) createImageDbPoolVolume(fingerprint string) error {
 	// Fill in any default volume config.
 	volumeConfig := map[string]string{}
-	err := storageVolumeFillDefault(fingerprint, volumeConfig, s.pool)
+	err := storagePools.VolumeFillDefault(fingerprint, volumeConfig, s.pool)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index b3ab72ec23..c49186033a 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -14,13 +14,13 @@ import (
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/operations"
 	"github.com/lxc/lxd/lxd/response"
+	storagePools "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	log "github.com/lxc/lxd/shared/log15"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
-
-	log "github.com/lxc/lxd/shared/log15"
 )
 
 var storagePoolVolumesCmd = APIEndpoint{
@@ -166,7 +166,7 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) response.Response {
 	recursion := util.IsRecursionRequest(r)
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -505,7 +505,7 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string
 	}
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -676,7 +676,7 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request, volumeTypeName string)
 	poolName := mux.Vars(r)["pool"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -754,7 +754,7 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string)
 	poolName := mux.Vars(r)["pool"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -813,7 +813,7 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string)
 		}
 	} else {
 		// Validate the configuration
-		err = storageVolumeValidateConfig(volumeName, req.Config, pool)
+		err = storagePools.VolumeValidateConfig(volumeName, req.Config, pool)
 		if err != nil {
 			return response.BadRequest(err)
 		}
@@ -862,7 +862,7 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName strin
 	poolName := mux.Vars(r)["pool"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -919,7 +919,7 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request, volumeTypeName strin
 	}
 
 	// Validate the configuration
-	err = storageVolumeValidateConfig(volumeName, req.Config, pool)
+	err = storagePools.VolumeValidateConfig(volumeName, req.Config, pool)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -960,7 +960,7 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
 	poolName := mux.Vars(r)["pool"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index bd77b92bb6..53ddc97e45 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -52,7 +52,7 @@ func storagePoolVolumeSnapshotsTypePost(d *Daemon, r *http.Request) response.Res
 	}
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -176,7 +176,7 @@ func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) response.Resp
 	volumeName := mux.Vars(r)["name"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -269,7 +269,7 @@ func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) response.Resp
 	}
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -335,7 +335,7 @@ func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) response.Respo
 	snapshotName := mux.Vars(r)["snapshotName"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -391,7 +391,7 @@ func storagePoolVolumeSnapshotTypePut(d *Daemon, r *http.Request) response.Respo
 	snapshotName := mux.Vars(r)["snapshotName"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
@@ -473,7 +473,7 @@ func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) response.Re
 	snapshotName := mux.Vars(r)["snapshotName"]
 
 	// Convert the volume type name to our internal integer representation.
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := driver.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		return response.BadRequest(err)
 	}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 45da213876..d58da7e98b 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/state"
+	storagePools "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/version"
@@ -526,7 +527,7 @@ func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol
 		}
 
 		driver := s.GetStorageTypeName()
-		newConfig, err := storageVolumePropertiesTranslate(vol.Config, driver)
+		newConfig, err := storagePools.VolumePropertiesTranslate(vol.Config, driver)
 		if err != nil {
 			return nil, err
 		}
@@ -536,7 +537,7 @@ func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol
 	}
 
 	// Create database entry for new storage volume.
-	err := storagePoolVolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, false, volumeConfig)
+	err := storagePools.VolumeDBCreate(state, poolName, volumeName, volumeDescription, volumeTypeName, false, volumeConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -547,7 +548,7 @@ func storagePoolVolumeDBCreateInternal(state *state.State, poolName string, vol
 		return nil, err
 	}
 
-	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
 	if err != nil {
 		state.Cluster.StoragePoolVolumeDelete("default", volumeName, volumeType, poolID)
 		return nil, err
@@ -569,7 +570,7 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
 		return err
 	}
 
-	volumeType, err1 := storagePoolVolumeTypeNameToType(vol.Type)
+	volumeType, err1 := storagePools.VolumeTypeNameToType(vol.Type)
 	poolID, _, _ := s.GetContainerPoolInfo()
 	revert := true
 
@@ -583,7 +584,7 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
 		err = s.StoragePoolVolumeCreate()
 	} else {
 		if !vol.Source.VolumeOnly {
-			snapshots, err := storagePoolVolumeSnapshotsGet(state, vol.Source.Pool, vol.Source.Name, volumeType)
+			snapshots, err := storagePools.VolumeSnapshotsGet(state, vol.Source.Pool, vol.Source.Name, volumeType)
 			if err != nil {
 				return err
 			}
@@ -609,7 +610,7 @@ func storagePoolVolumeCreateInternal(state *state.State, poolName string, vol *a
 }
 
 func storagePoolVolumeSnapshotCopyInternal(state *state.State, poolName string, vol *api.StorageVolumesPost, snapshotName string) (storage, error) {
-	volumeType, err := storagePoolVolumeTypeNameToType(vol.Type)
+	volumeType, err := storagePools.VolumeTypeNameToType(vol.Type)
 	if err != nil {
 		return nil, err
 	}
@@ -645,7 +646,7 @@ func storagePoolVolumeSnapshotCopyInternal(state *state.State, poolName string,
 
 func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.StorageVolumeArgs) (storage, error) {
 	// Create database entry for new storage volume.
-	err := storagePoolVolumeDBCreate(state, dbArgs.PoolName, dbArgs.Name, dbArgs.Description, dbArgs.TypeName, true, dbArgs.Config)
+	err := storagePools.VolumeDBCreate(state, dbArgs.PoolName, dbArgs.Name, dbArgs.Description, dbArgs.TypeName, true, dbArgs.Config)
 	if err != nil {
 		return nil, err
 	}
@@ -656,7 +657,7 @@ func storagePoolVolumeSnapshotDBCreateInternal(state *state.State, dbArgs *db.St
 		return nil, err
 	}
 
-	volumeType, err := storagePoolVolumeTypeNameToType(dbArgs.TypeName)
+	volumeType, err := storagePools.VolumeTypeNameToType(dbArgs.TypeName)
 	if err != nil {
 		state.Cluster.StoragePoolVolumeDelete("default", dbArgs.Name, volumeType, poolID)
 		return nil, err
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index a124173704..7ef9ca9a09 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2827,7 +2827,7 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
 	dstMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 
-	snapshots, err := storagePoolVolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
+	snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, source.Name, storagePoolVolumeTypeCustom)
 	if err != nil {
 		return err
 	}


More information about the lxc-devel mailing list