[lxc-devel] [lxd/master] lxd: More storage cleanup preparation

monstermunchkin on Github lxc-bot at linuxcontainers.org
Fri Aug 16 07:00:44 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190816/9ed7d0da/attachment-0001.bin>
-------------- next part --------------
From 5b2f25c5a8cc4fdcde3dc4af8be0f28d873d977a Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Fri, 16 Aug 2019 07:44:11 +0200
Subject: [PATCH 1/2] lxd: Move get*MountPoint() to storage package

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/api_cluster.go            |   6 +-
 lxd/api_internal.go           |  12 +-
 lxd/container_lxc.go          |   2 +-
 lxd/container_post.go         |   5 +-
 lxd/patches.go                |  52 ++++-----
 lxd/storage.go                |  34 +-----
 lxd/storage/storage.go        |  41 ++++++-
 lxd/storage_btrfs.go          | 210 +++++++++++++++++-----------------
 lxd/storage_ceph.go           |  90 +++++++--------
 lxd/storage_ceph_migration.go |   8 +-
 lxd/storage_ceph_utils.go     |  24 ++--
 lxd/storage_cephfs.go         |  50 ++++----
 lxd/storage_dir.go            | 106 ++++++++---------
 lxd/storage_lvm.go            |  90 +++++++--------
 lxd/storage_lvm_utils.go      |  30 ++---
 lxd/storage_migration.go      |   9 +-
 lxd/storage_pools.go          |   4 +-
 lxd/storage_pools_utils.go    |   2 +-
 lxd/storage_zfs.go            |  98 ++++++++--------
 lxd/storage_zfs_utils.go      |  10 +-
 20 files changed, 449 insertions(+), 434 deletions(-)

diff --git a/lxd/api_cluster.go b/lxd/api_cluster.go
index 21c133c40a..2b16ebfe6a 100644
--- a/lxd/api_cluster.go
+++ b/lxd/api_cluster.go
@@ -14,16 +14,18 @@ import (
 
 	"github.com/canonical/go-dqlite"
 	"github.com/gorilla/mux"
+	"github.com/pkg/errors"
+
 	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/node"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
-	"github.com/pkg/errors"
 )
 
 var clusterCmd = APIEndpoint{
@@ -493,7 +495,7 @@ func clusterPutJoin(d *Daemon, req api.ClusterPut) Response {
 			if err != nil {
 				return errors.Wrap(err, "failed to init ceph pool for joining node")
 			}
-			volumeMntPoint := getStoragePoolVolumeMountPoint(
+			volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(
 				name, storage.(*storageCeph).volume.Name)
 			err = os.MkdirAll(volumeMntPoint, 0711)
 			if err != nil {
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index babac2c8d6..91333e3044 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -425,7 +425,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	containerMntPoints := []string{}
 	containerPoolName := ""
 	for _, poolName := range storagePoolNames {
-		containerMntPoint := getContainerMountPoint(projectName, poolName, req.Name)
+		containerMntPoint := driver.GetContainerMountPoint(projectName, poolName, req.Name)
 		if shared.PathExists(containerMntPoint) {
 			containerMntPoints = append(containerMntPoints, containerMntPoint)
 			containerPoolName = poolName
@@ -544,7 +544,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	if len(backup.Snapshots) > 0 {
 		switch backup.Pool.Driver {
 		case "btrfs":
-			snapshotsDirPath := getSnapshotMountPoint(projectName, poolName, req.Name)
+			snapshotsDirPath := driver.GetSnapshotMountPoint(projectName, poolName, req.Name)
 			snapshotsDir, err := os.Open(snapshotsDirPath)
 			if err != nil {
 				return InternalError(err)
@@ -556,7 +556,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 			}
 			snapshotsDir.Close()
 		case "dir":
-			snapshotsDirPath := getSnapshotMountPoint(projectName, poolName, req.Name)
+			snapshotsDirPath := driver.GetSnapshotMountPoint(projectName, poolName, req.Name)
 			snapshotsDir, err := os.Open(snapshotsDirPath)
 			if err != nil {
 				return InternalError(err)
@@ -716,7 +716,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	for _, snap := range backup.Snapshots {
 		switch backup.Pool.Driver {
 		case "btrfs":
-			snpMntPt := getSnapshotMountPoint(projectName, backup.Pool.Name, snap.Name)
+			snpMntPt := driver.GetSnapshotMountPoint(projectName, backup.Pool.Name, snap.Name)
 			if !shared.PathExists(snpMntPt) || !isBtrfsSubVolume(snpMntPt) {
 				if req.Force {
 					continue
@@ -724,7 +724,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 				return BadRequest(needForce)
 			}
 		case "dir":
-			snpMntPt := getSnapshotMountPoint(projectName, backup.Pool.Name, snap.Name)
+			snpMntPt := driver.GetSnapshotMountPoint(projectName, backup.Pool.Name, snap.Name)
 			if !shared.PathExists(snpMntPt) {
 				if req.Force {
 					continue
@@ -965,7 +965,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		}
 
 		// Recreate missing mountpoints and symlinks.
-		snapshotMountPoint := getSnapshotMountPoint(projectName, backup.Pool.Name,
+		snapshotMountPoint := driver.GetSnapshotMountPoint(projectName, backup.Pool.Name,
 			snap.Name)
 		sourceName, _, _ := containerGetParentAndSnapshotName(snap.Name)
 		sourceName = project.Prefix(projectName, sourceName)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 5462dce848..aa4bcb7ff9 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3931,7 +3931,7 @@ func (c *containerLXC) Delete() error {
 		// Delete the container from disk
 		if c.storage != nil && !isImport {
 			_, poolName, _ := c.storage.GetContainerPoolInfo()
-			containerMountPoint := getContainerMountPoint(c.Project(), poolName, c.Name())
+			containerMountPoint := driver.GetContainerMountPoint(c.Project(), poolName, c.Name())
 			if shared.PathExists(c.Path()) ||
 				shared.PathExists(containerMountPoint) {
 				err := c.storage.ContainerDelete(c)
diff --git a/lxd/container_post.go b/lxd/container_post.go
index f9a3b57619..ab7438e0be 100644
--- a/lxd/container_post.go
+++ b/lxd/container_post.go
@@ -14,6 +14,7 @@ import (
 	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -528,14 +529,14 @@ func containerPostCreateContainerMountPoint(d *Daemon, project, containerName st
 		return errors.Wrap(err, "Failed to create container snapshot names")
 	}
 
-	containerMntPoint := getContainerMountPoint(c.Project(), poolName, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(c.Project(), poolName, containerName)
 	err = createContainerMountpoint(containerMntPoint, c.Path(), c.IsPrivileged())
 	if err != nil {
 		return errors.Wrap(err, "Failed to create container mount point on target node")
 	}
 
 	for _, snapshotName := range snapshotNames {
-		mntPoint := getSnapshotMountPoint(project, poolName, snapshotName)
+		mntPoint := driver.GetSnapshotMountPoint(project, poolName, snapshotName)
 		snapshotsSymlinkTarget := shared.VarPath("storage-pools",
 			poolName, "containers-snapshots", containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", containerName)
diff --git a/lxd/patches.go b/lxd/patches.go
index b876b590de..6b2ab6438d 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -385,7 +385,7 @@ func patchStorageApi(name string, d *Daemon) error {
 
 func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, defaultStorageTypeName string, cRegular []string, cSnapshots []string, imgPublic []string, imgPrivate []string) error {
 	poolConfig := map[string]string{}
-	poolSubvolumePath := getStoragePoolMountPoint(defaultPoolName)
+	poolSubvolumePath := driver.GetStoragePoolMountPoint(defaultPoolName)
 	poolConfig["source"] = poolSubvolumePath
 
 	err := storagePoolValidateConfig(defaultPoolName, defaultStorageTypeName, poolConfig, nil)
@@ -448,7 +448,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 	if len(cRegular) > 0 {
 		// ${LXD_DIR}/storage-pools/<name>
-		containersSubvolumePath := getContainerMountPoint("default", defaultPoolName, "")
+		containersSubvolumePath := driver.GetContainerMountPoint("default", defaultPoolName, "")
 		if !shared.PathExists(containersSubvolumePath) {
 			err := os.MkdirAll(containersSubvolumePath, 0711)
 			if err != nil {
@@ -495,7 +495,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		// subvolume of the subvolume of the storage pool:
 		// mv ${LXD_DIR}/containers/<container_name> ${LXD_DIR}/storage-pools/<pool>/<container_name>
 		oldContainerMntPoint := shared.VarPath("containers", ct)
-		newContainerMntPoint := getContainerMountPoint("default", defaultPoolName, ct)
+		newContainerMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, ct)
 		if shared.PathExists(oldContainerMntPoint) && !shared.PathExists(newContainerMntPoint) {
 			err = os.Rename(oldContainerMntPoint, newContainerMntPoint)
 			if err != nil {
@@ -539,7 +539,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// Create the snapshots directory in
 			// the new storage pool:
 			// ${LXD_DIR}/storage-pools/<pool>/snapshots
-			newSnapshotsMntPoint := getSnapshotMountPoint("default", defaultPoolName, ct)
+			newSnapshotsMntPoint := driver.GetSnapshotMountPoint("default", defaultPoolName, ct)
 			if !shared.PathExists(newSnapshotsMntPoint) {
 				err := os.MkdirAll(newSnapshotsMntPoint, 0700)
 				if err != nil {
@@ -582,7 +582,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// We need to create a new snapshot since we can't move
 			// readonly snapshots.
 			oldSnapshotMntPoint := shared.VarPath("snapshots", cs)
-			newSnapshotMntPoint := getSnapshotMountPoint("default", defaultPoolName, cs)
+			newSnapshotMntPoint := driver.GetSnapshotMountPoint("default", defaultPoolName, cs)
 			if shared.PathExists(oldSnapshotMntPoint) && !shared.PathExists(newSnapshotMntPoint) {
 				err = btrfsSnapshot(d.State(), oldSnapshotMntPoint, newSnapshotMntPoint, true)
 				if err != nil {
@@ -620,7 +620,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			// storage pool:
 			// ${LXD_DIR}/snapshots/<container_name> to ${LXD_DIR}/storage-pools/<pool>/snapshots/<container_name>
 			snapshotsPath := shared.VarPath("snapshots", ct)
-			newSnapshotMntPoint := getSnapshotMountPoint("default", defaultPoolName, ct)
+			newSnapshotMntPoint := driver.GetSnapshotMountPoint("default", defaultPoolName, ct)
 			os.Remove(snapshotsPath)
 			if !shared.PathExists(snapshotsPath) {
 				err := os.Symlink(newSnapshotMntPoint, snapshotsPath)
@@ -660,7 +660,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			return err
 		}
 
-		imagesMntPoint := getImageMountPoint(defaultPoolName, "")
+		imagesMntPoint := driver.GetImageMountPoint(defaultPoolName, "")
 		if !shared.PathExists(imagesMntPoint) {
 			err := os.MkdirAll(imagesMntPoint, 0700)
 			if err != nil {
@@ -669,7 +669,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		}
 
 		oldImageMntPoint := shared.VarPath("images", img+".btrfs")
-		newImageMntPoint := getImageMountPoint(defaultPoolName, img)
+		newImageMntPoint := driver.GetImageMountPoint(defaultPoolName, img)
 		if shared.PathExists(oldImageMntPoint) && !shared.PathExists(newImageMntPoint) {
 			err := os.Rename(oldImageMntPoint, newImageMntPoint)
 			if err != nil {
@@ -780,7 +780,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		// Create the new path where containers will be located on the
 		// new storage api.
-		containersMntPoint := getContainerMountPoint("default", defaultPoolName, "")
+		containersMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, "")
 		if !shared.PathExists(containersMntPoint) {
 			err := os.MkdirAll(containersMntPoint, 0711)
 			if err != nil {
@@ -790,7 +790,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		// Simply rename the container when they are directories.
 		oldContainerMntPoint := shared.VarPath("containers", ct)
-		newContainerMntPoint := getContainerMountPoint("default", defaultPoolName, ct)
+		newContainerMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, ct)
 		if shared.PathExists(oldContainerMntPoint) && !shared.PathExists(newContainerMntPoint) {
 			// First try to rename.
 			err := os.Rename(oldContainerMntPoint, newContainerMntPoint)
@@ -838,7 +838,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 		}
 
 		// Now simply rename the snapshots directory as well.
-		newSnapshotMntPoint := getSnapshotMountPoint("default", defaultPoolName, ct)
+		newSnapshotMntPoint := driver.GetSnapshotMountPoint("default", defaultPoolName, ct)
 		if shared.PathExists(oldSnapshotMntPoint) && !shared.PathExists(newSnapshotMntPoint) {
 			err := os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 			if err != nil {
@@ -1033,7 +1033,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	// Create pool mountpoint if it doesn't already exist.
-	poolMntPoint := getStoragePoolMountPoint(defaultPoolName)
+	poolMntPoint := driver.GetStoragePoolMountPoint(defaultPoolName)
 	if !shared.PathExists(poolMntPoint) {
 		err = os.MkdirAll(poolMntPoint, 0711)
 		if err != nil {
@@ -1043,7 +1043,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 	if len(cRegular) > 0 {
 		// Create generic containers folder on the storage pool.
-		newContainersMntPoint := getContainerMountPoint("default", defaultPoolName, "")
+		newContainersMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, "")
 		if !shared.PathExists(newContainersMntPoint) {
 			err = os.MkdirAll(newContainersMntPoint, 0711)
 			if err != nil {
@@ -1100,7 +1100,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		// Create the new path where containers will be located on the
 		// new storage api. We do os.Rename() here to preserve
 		// permissions and ownership.
-		newContainerMntPoint := getContainerMountPoint("default", defaultPoolName, ct)
+		newContainerMntPoint := driver.GetContainerMountPoint("default", defaultPoolName, ct)
 		ctLvName := containerNameToLVName(ct)
 		newContainerLvName := fmt.Sprintf("%s_%s", storagePoolVolumeAPIEndpointContainers, ctLvName)
 		containerLvDevPath := getLvmDevPath("default", defaultPoolName, storagePoolVolumeAPIEndpointContainers, ctLvName)
@@ -1245,7 +1245,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// Create the snapshots directory in the new storage
 			// pool:
 			// ${LXD_DIR}/storage-pools/<pool>/snapshots
-			newSnapshotMntPoint := getSnapshotMountPoint("default", defaultPoolName, cs)
+			newSnapshotMntPoint := driver.GetSnapshotMountPoint("default", defaultPoolName, cs)
 			if !shared.PathExists(newSnapshotMntPoint) {
 				err := os.MkdirAll(newSnapshotMntPoint, 0700)
 				if err != nil {
@@ -1350,7 +1350,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// storage pool:
 			// ${LXD_DIR}/snapshots/<container_name> to ${LXD_DIR}/storage-pools/<pool>/snapshots/<container_name>
 			snapshotsPath := shared.VarPath("snapshots", ct)
-			newSnapshotsPath := getSnapshotMountPoint("default", defaultPoolName, ct)
+			newSnapshotsPath := driver.GetSnapshotMountPoint("default", defaultPoolName, ct)
 			if shared.PathExists(snapshotsPath) {
 				// On a broken update snapshotsPath will contain
 				// empty directories that need to be removed.
@@ -1378,7 +1378,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 	images := append(imgPublic, imgPrivate...)
 	if len(images) > 0 {
-		imagesMntPoint := getImageMountPoint(defaultPoolName, "")
+		imagesMntPoint := driver.GetImageMountPoint(defaultPoolName, "")
 		if !shared.PathExists(imagesMntPoint) {
 			err := os.MkdirAll(imagesMntPoint, 0700)
 			if err != nil {
@@ -1429,7 +1429,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			}
 		}
 
-		newImageMntPoint := getImageMountPoint(defaultPoolName, img)
+		newImageMntPoint := driver.GetImageMountPoint(defaultPoolName, img)
 		if !shared.PathExists(newImageMntPoint) {
 			err := os.MkdirAll(newImageMntPoint, 0700)
 			if err != nil {
@@ -1567,7 +1567,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	if len(cRegular) > 0 {
-		containersSubvolumePath := getContainerMountPoint("default", poolName, "")
+		containersSubvolumePath := driver.GetContainerMountPoint("default", poolName, "")
 		if !shared.PathExists(containersSubvolumePath) {
 			err := os.MkdirAll(containersSubvolumePath, 0711)
 			if err != nil {
@@ -1631,7 +1631,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		// Changing the mountpoint property should have actually created
 		// the path but in case it somehow didn't let's do it ourselves.
 		doesntMatter := false
-		newContainerMntPoint := getContainerMountPoint("default", poolName, ct)
+		newContainerMntPoint := driver.GetContainerMountPoint("default", poolName, ct)
 		err = createContainerMountpoint(newContainerMntPoint, oldContainerMntPoint, doesntMatter)
 		if err != nil {
 			logger.Warnf("Failed to create mountpoint for the container: %s", newContainerMntPoint)
@@ -1693,7 +1693,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 			// Create the new mountpoint for snapshots in the new
 			// storage api.
-			newSnapshotMntPoint := getSnapshotMountPoint("default", poolName, cs)
+			newSnapshotMntPoint := driver.GetSnapshotMountPoint("default", poolName, cs)
 			if !shared.PathExists(newSnapshotMntPoint) {
 				err = os.MkdirAll(newSnapshotMntPoint, 0711)
 				if err != nil {
@@ -1708,7 +1708,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 		// Create a symlink for this container's snapshots.
 		if len(ctSnapshots) != 0 {
-			newSnapshotsMntPoint := getSnapshotMountPoint("default", poolName, ct)
+			newSnapshotsMntPoint := driver.GetSnapshotMountPoint("default", poolName, ct)
 			if !shared.PathExists(newSnapshotsMntPoint) {
 				err := os.Symlink(newSnapshotsMntPoint, snapshotsPath)
 				if err != nil {
@@ -1747,7 +1747,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		imageMntPoint := getImageMountPoint(poolName, img)
+		imageMntPoint := driver.GetImageMountPoint(poolName, img)
 		if !shared.PathExists(imageMntPoint) {
 			err := os.MkdirAll(imageMntPoint, 0700)
 			if err != nil {
@@ -2342,7 +2342,7 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
 			continue
 		}
 
-		pool.Config["source"] = getStoragePoolMountPoint(poolName)
+		pool.Config["source"] = driver.GetStoragePoolMountPoint(poolName)
 
 		// Update the storage pool config.
 		err = d.cluster.StoragePoolUpdate(poolName, pool.Description, pool.Config)
@@ -2632,7 +2632,7 @@ func patchStorageApiDirBindMount(name string, d *Daemon) error {
 			return fmt.Errorf(msg)
 		}
 		cleanSource := filepath.Clean(source)
-		poolMntPoint := getStoragePoolMountPoint(poolName)
+		poolMntPoint := driver.GetStoragePoolMountPoint(poolName)
 
 		if cleanSource == poolMntPoint {
 			continue
@@ -2972,7 +2972,7 @@ func patchStorageApiPermissions(name string, d *Daemon) error {
 				defer volStruct.StoragePoolVolumeUmount()
 			}
 
-			cuMntPoint := getStoragePoolVolumeMountPoint(poolName, vol)
+			cuMntPoint := driver.GetStoragePoolVolumeMountPoint(poolName, vol)
 			err = os.Chmod(cuMntPoint, 0711)
 			if err != nil && !os.IsNotExist(err) {
 				return err
diff --git a/lxd/storage.go b/lxd/storage.go
index 56ef5c11ea..5ee427f4e8 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -13,8 +13,8 @@ import (
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/migration"
-	"github.com/lxc/lxd/lxd/project"
 	"github.com/lxc/lxd/lxd/state"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/idmap"
@@ -467,7 +467,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str
 	poolVolumePut.Config["volatile.idmap.next"] = nextJsonMap
 
 	// get mountpoint of storage volume
-	remapPath := getStoragePoolVolumeMountPoint(poolName, volumeName)
+	remapPath := driver.GetStoragePoolVolumeMountPoint(poolName, volumeName)
 
 	if !nextIdmap.Equals(lastIdmap) {
 		logger.Debugf("Shifting storage volume")
@@ -607,36 +607,6 @@ func storagePoolVolumeContainerLoadInit(s *state.State, project, containerName s
 	return storagePoolVolumeInit(s, project, poolName, containerName, storagePoolVolumeTypeContainer)
 }
 
-// {LXD_DIR}/storage-pools/<pool>
-func getStoragePoolMountPoint(poolName string) string {
-	return shared.VarPath("storage-pools", poolName)
-}
-
-// ${LXD_DIR}/storage-pools/<pool>/containers/[<project_name>_]<container_name>
-func getContainerMountPoint(projectName string, poolName string, containerName string) string {
-	return shared.VarPath("storage-pools", poolName, "containers", project.Prefix(projectName, containerName))
-}
-
-// ${LXD_DIR}/storage-pools/<pool>/containers-snapshots/<snapshot_name>
-func getSnapshotMountPoint(projectName, poolName string, snapshotName string) string {
-	return shared.VarPath("storage-pools", poolName, "containers-snapshots", project.Prefix(projectName, snapshotName))
-}
-
-// ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>
-func getImageMountPoint(poolName string, fingerprint string) string {
-	return shared.VarPath("storage-pools", poolName, "images", fingerprint)
-}
-
-// ${LXD_DIR}/storage-pools/<pool>/custom/<storage_volume>
-func getStoragePoolVolumeMountPoint(poolName string, volumeName string) string {
-	return shared.VarPath("storage-pools", poolName, "custom", volumeName)
-}
-
-// ${LXD_DIR}/storage-pools/<pool>/custom-snapshots/<custom volume name>/<snapshot name>
-func getStoragePoolVolumeSnapshotMountPoint(poolName string, snapshotName string) string {
-	return shared.VarPath("storage-pools", poolName, "custom-snapshots", snapshotName)
-}
-
 func createContainerMountpoint(mountPoint string, mountPointSymlink string, privileged bool) error {
 	var mode os.FileMode
 	if privileged {
diff --git a/lxd/storage/storage.go b/lxd/storage/storage.go
index 7d378ef50c..f55c9f4ef4 100644
--- a/lxd/storage/storage.go
+++ b/lxd/storage/storage.go
@@ -1,6 +1,9 @@
 package storage
 
-import "github.com/lxc/lxd/shared"
+import (
+	"github.com/lxc/lxd/lxd/project"
+	"github.com/lxc/lxd/shared"
+)
 
 // ContainerPath returns the directory of a container or snapshot.
 func ContainerPath(name string, isSnapshot bool) string {
@@ -10,3 +13,39 @@ func ContainerPath(name string, isSnapshot bool) string {
 
 	return shared.VarPath("containers", name)
 }
+
+// GetStoragePoolMountPoint returns the mountpoint of the given pool.
+// {LXD_DIR}/storage-pools/<pool>
+func GetStoragePoolMountPoint(poolName string) string {
+	return shared.VarPath("storage-pools", poolName)
+}
+
+// GetContainerMountPoint returns the mountpoint of the given container.
+// ${LXD_DIR}/storage-pools/<pool>/containers/[<project_name>_]<container_name>
+func GetContainerMountPoint(projectName string, poolName string, containerName string) string {
+	return shared.VarPath("storage-pools", poolName, "containers", project.Prefix(projectName, containerName))
+}
+
+// GetSnapshotMountPoint returns the mountpoint of the given container snapshot.
+// ${LXD_DIR}/storage-pools/<pool>/containers-snapshots/<snapshot_name>
+func GetSnapshotMountPoint(projectName, poolName string, snapshotName string) string {
+	return shared.VarPath("storage-pools", poolName, "containers-snapshots", project.Prefix(projectName, snapshotName))
+}
+
+// GetImageMountPoint returns the mountpoint of the given image.
+// ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>
+func GetImageMountPoint(poolName string, fingerprint string) string {
+	return shared.VarPath("storage-pools", poolName, "images", fingerprint)
+}
+
+// GetStoragePoolVolumeMountPoint returns the mountpoint of the given pool volume.
+// ${LXD_DIR}/storage-pools/<pool>/custom/<storage_volume>
+func GetStoragePoolVolumeMountPoint(poolName string, volumeName string) string {
+	return shared.VarPath("storage-pools", poolName, "custom", volumeName)
+}
+
+// GetStoragePoolVolumeSnapshotMountPoint returns the mountpoint of the given pool volume snapshot.
+// ${LXD_DIR}/storage-pools/<pool>/custom-snapshots/<custom volume name>/<snapshot name>
+func GetStoragePoolVolumeSnapshotMountPoint(poolName string, snapshotName string) string {
+	return shared.VarPath("storage-pools", poolName, "custom-snapshots", snapshotName)
+}
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 5be6c321a4..ef5bbf3285 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -184,7 +184,7 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 				} else {
 					cleanSource := filepath.Clean(source)
 					lxdDir := shared.VarPath()
-					poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+					poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 					if shared.PathExists(source) && !isOnBtrfs(source) {
 						return fmt.Errorf("Existing path is neither a BTRFS subvolume nor does it reside on a BTRFS filesystem")
 					} else if strings.HasPrefix(cleanSource, lxdDir) {
@@ -206,7 +206,7 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		}
 	}
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if !shared.PathExists(poolMntPoint) {
 		err := os.MkdirAll(poolMntPoint, driver.StoragePoolsDirMode)
 		if err != nil {
@@ -247,31 +247,31 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 	}
 
 	// Create default subvolumes.
-	dummyDir := getContainerMountPoint("default", s.pool.Name, "")
+	dummyDir := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	err := btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
-	dummyDir = getSnapshotMountPoint("default", s.pool.Name, "")
+	dummyDir = driver.GetSnapshotMountPoint("default", s.pool.Name, "")
 	err = btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
-	dummyDir = getImageMountPoint(s.pool.Name, "")
+	dummyDir = driver.GetImageMountPoint(s.pool.Name, "")
 	err = btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
-	dummyDir = getStoragePoolVolumeMountPoint(s.pool.Name, "")
+	dummyDir = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, "")
 	err = btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
 
-	dummyDir = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, "")
+	dummyDir = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, "")
 	err = btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
@@ -299,16 +299,16 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 	}
 
 	// Delete default subvolumes.
-	dummyDir := getContainerMountPoint("default", s.pool.Name, "")
+	dummyDir := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	btrfsSubVolumesDelete(dummyDir)
 
-	dummyDir = getSnapshotMountPoint("default", s.pool.Name, "")
+	dummyDir = driver.GetSnapshotMountPoint("default", s.pool.Name, "")
 	btrfsSubVolumesDelete(dummyDir)
 
-	dummyDir = getImageMountPoint(s.pool.Name, "")
+	dummyDir = driver.GetImageMountPoint(s.pool.Name, "")
 	btrfsSubVolumesDelete(dummyDir)
 
-	dummyDir = getStoragePoolVolumeMountPoint(s.pool.Name, "")
+	dummyDir = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, "")
 	btrfsSubVolumesDelete(dummyDir)
 
 	_, err := s.StoragePoolUmount()
@@ -349,7 +349,7 @@ func (s *storageBtrfs) StoragePoolDelete() error {
 	}
 
 	// Remove the mountpoint for the storage pool.
-	err = os.RemoveAll(getStoragePoolMountPoint(s.pool.Name))
+	err = os.RemoveAll(driver.GetStoragePoolMountPoint(s.pool.Name))
 	if err != nil && !os.IsNotExist(err) {
 		return err
 	}
@@ -370,7 +370,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 		return false, fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 	poolMountLockID := getPoolMountLockID(s.pool.Name)
 	lxdStorageMapLock.Lock()
@@ -414,7 +414,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 	isBlockDev := shared.IsBlockdevPath(source)
 	if filepath.IsAbs(source) {
 		cleanSource := filepath.Clean(source)
-		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+		poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 		loopFilePath := shared.VarPath("disks", s.pool.Name+".img")
 		if !isBlockDev && cleanSource == loopFilePath {
 			// If source == "${LXD_DIR}"/disks/{pool_name} it is a
@@ -468,7 +468,7 @@ func (s *storageBtrfs) StoragePoolMount() (bool, error) {
 func (s *storageBtrfs) StoragePoolUmount() (bool, error) {
 	logger.Debugf("Unmounting BTRFS storage pool \"%s\"", s.pool.Name)
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 	poolUmountLockID := getPoolUmountLockID(s.pool.Name)
 	lxdStorageMapLock.Lock()
@@ -573,9 +573,9 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 	var customSubvolumeName string
 
 	if isSnapshot {
-		customSubvolumeName = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		customSubvolumeName = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	} else {
-		customSubvolumeName = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		customSubvolumeName = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	err = btrfsSubVolumeCreate(customSubvolumeName)
@@ -609,7 +609,7 @@ func (s *storageBtrfs) StoragePoolVolumeDelete() error {
 	}
 
 	// Delete subvolume.
-	customSubvolumeName := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customSubvolumeName := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if shared.PathExists(customSubvolumeName) && isBtrfsSubVolume(customSubvolumeName) {
 		err = btrfsSubVolumesDelete(customSubvolumeName)
 		if err != nil {
@@ -667,7 +667,7 @@ func (s *storageBtrfs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, c
 		}
 
 		// Create a backup so we can revert.
-		targetVolumeSubvolumeName := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		targetVolumeSubvolumeName := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 		backupTargetVolumeSubvolumeName := fmt.Sprintf("%s.tmp", targetVolumeSubvolumeName)
 		err = os.Rename(targetVolumeSubvolumeName, backupTargetVolumeSubvolumeName)
 		if err != nil {
@@ -680,7 +680,7 @@ func (s *storageBtrfs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, c
 			}
 		}()
 
-		sourceVolumeSubvolumeName := getStoragePoolVolumeSnapshotMountPoint(
+		sourceVolumeSubvolumeName := driver.GetStoragePoolVolumeSnapshotMountPoint(
 			s.pool.Name, fmt.Sprintf("%s/%s", s.volume.Name, writable.Restore))
 		err = s.btrfsPoolVolumesSnapshot(sourceVolumeSubvolumeName,
 			targetVolumeSubvolumeName, false, true)
@@ -753,8 +753,8 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
 			s.volume.Name, s.pool.Name)
 	}
 
-	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	oldPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, newName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
@@ -782,8 +782,8 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
 		newVolumeName := fmt.Sprintf("%s%s%s", newName, shared.SnapshotDelimiter, snapshotName)
 
 		// Rename volume snapshots
-		oldPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, oldVolumeName)
-		newPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newVolumeName)
+		oldPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, oldVolumeName)
+		newPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newVolumeName)
 		err = os.Rename(oldPath, newPath)
 		if err != nil {
 			return err
@@ -801,7 +801,7 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
 
 // Functions dealing with container storage.
 func (s *storageBtrfs) ContainerStorageReady(container container) bool {
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	return isBtrfsSubVolume(containerMntPoint)
 }
 
@@ -828,7 +828,7 @@ func (s *storageBtrfs) doContainerCreate(projectName, name string, privileged bo
 	}
 
 	// Create empty subvolume for container.
-	containerSubvolumeName := getContainerMountPoint(projectName, s.pool.Name, name)
+	containerSubvolumeName := driver.GetContainerMountPoint(projectName, s.pool.Name, name)
 	err = btrfsSubVolumeCreate(containerSubvolumeName)
 	if err != nil {
 		return err
@@ -884,7 +884,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 
 	// Mountpoint of the image:
 	// ${LXD_DIR}/images/<fingerprint>
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
 	lxdStorageMapLock.Lock()
 	if waitChannel, ok := lxdStorageOngoingOperationMap[imageStoragePoolLockID]; ok {
@@ -917,7 +917,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container container, fingerprint
 	// ${LXD_DIR}/storage-pools/<pool>/containers/<name>
 	// from the mounted ro image snapshot mounted at
 	// ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>
-	containerSubvolumeName := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerSubvolumeName := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	err = s.btrfsPoolVolumesSnapshot(imageMntPoint, containerSubvolumeName, false, false)
 	if err != nil {
 		return errors.Wrap(err, "Failed to storage pool volume snapshot")
@@ -948,7 +948,7 @@ func (s *storageBtrfs) ContainerDelete(container container) error {
 	}
 
 	// Delete the subvolume.
-	containerSubvolumeName := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerSubvolumeName := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	if shared.PathExists(containerSubvolumeName) && isBtrfsSubVolume(containerSubvolumeName) {
 		err = btrfsSubVolumesDelete(containerSubvolumeName)
 		if err != nil {
@@ -963,7 +963,7 @@ func (s *storageBtrfs) ContainerDelete(container container) error {
 	}
 
 	// Delete potential snapshot mountpoints.
-	snapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	snapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
 	if shared.PathExists(snapshotMntPoint) {
 		err := os.RemoveAll(snapshotMntPoint)
 		if err != nil && !os.IsNotExist(err) {
@@ -986,13 +986,13 @@ func (s *storageBtrfs) ContainerDelete(container container) error {
 }
 
 func (s *storageBtrfs) copyContainer(target container, source container) error {
-	sourceContainerSubvolumeName := getContainerMountPoint(source.Project(), s.pool.Name, source.Name())
+	sourceContainerSubvolumeName := driver.GetContainerMountPoint(source.Project(), s.pool.Name, source.Name())
 	if source.IsSnapshot() {
-		sourceContainerSubvolumeName = getSnapshotMountPoint(source.Project(), s.pool.Name, source.Name())
+		sourceContainerSubvolumeName = driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, source.Name())
 	}
-	targetContainerSubvolumeName := getContainerMountPoint(target.Project(), s.pool.Name, target.Name())
+	targetContainerSubvolumeName := driver.GetContainerMountPoint(target.Project(), s.pool.Name, target.Name())
 
-	containersPath := getContainerMountPoint("default", s.pool.Name, "")
+	containersPath := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	// Ensure that the directories immediately preceding the subvolume directory exist.
 	if !shared.PathExists(containersPath) {
 		err := os.MkdirAll(containersPath, driver.ContainersDirMode)
@@ -1022,11 +1022,11 @@ func (s *storageBtrfs) copyContainer(target container, source container) error {
 func (s *storageBtrfs) copySnapshot(target container, source container) error {
 	sourceName := source.Name()
 	targetName := target.Name()
-	sourceContainerSubvolumeName := getSnapshotMountPoint(source.Project(), s.pool.Name, sourceName)
-	targetContainerSubvolumeName := getSnapshotMountPoint(target.Project(), s.pool.Name, targetName)
+	sourceContainerSubvolumeName := driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, sourceName)
+	targetContainerSubvolumeName := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetName)
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
-	containersPath := getSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
+	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1092,11 +1092,11 @@ func (s *storageBtrfs) doCrossPoolContainerCopy(target container, source contain
 		}
 	}
 
-	destContainerMntPoint := getContainerMountPoint(target.Project(), targetPool, target.Name())
+	destContainerMntPoint := driver.GetContainerMountPoint(target.Project(), targetPool, target.Name())
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	if !containerOnly {
 		for _, snap := range snapshots {
-			srcSnapshotMntPoint := getSnapshotMountPoint(target.Project(), sourcePool, snap.Name())
+			srcSnapshotMntPoint := driver.GetSnapshotMountPoint(target.Project(), sourcePool, snap.Name())
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, destContainerMntPoint, bwlimit, true)
 			if err != nil {
 				logger.Errorf("Failed to rsync into BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
@@ -1112,7 +1112,7 @@ func (s *storageBtrfs) doCrossPoolContainerCopy(target container, source contain
 		}
 	}
 
-	srcContainerMntPoint := getContainerMountPoint(source.Project(), sourcePool, source.Name())
+	srcContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, source.Name())
 	_, err = rsyncLocalCopy(srcContainerMntPoint, destContainerMntPoint, bwlimit, true)
 	if err != nil {
 		logger.Errorf("Failed to rsync into BTRFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
@@ -1234,8 +1234,8 @@ func (s *storageBtrfs) ContainerRename(container container, newName string) erro
 		return err
 	}
 
-	oldContainerSubvolumeName := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
-	newContainerSubvolumeName := getContainerMountPoint(container.Project(), s.pool.Name, newName)
+	oldContainerSubvolumeName := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	newContainerSubvolumeName := driver.GetContainerMountPoint(container.Project(), s.pool.Name, newName)
 	err = os.Rename(oldContainerSubvolumeName, newContainerSubvolumeName)
 	if err != nil {
 		return err
@@ -1247,8 +1247,8 @@ func (s *storageBtrfs) ContainerRename(container container, newName string) erro
 		return err
 	}
 
-	oldSnapshotSubvolumeName := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
-	newSnapshotSubvolumeName := getSnapshotMountPoint(container.Project(), s.pool.Name, newName)
+	oldSnapshotSubvolumeName := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	newSnapshotSubvolumeName := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, newName)
 	if shared.PathExists(oldSnapshotSubvolumeName) {
 		err = os.Rename(oldSnapshotSubvolumeName, newSnapshotSubvolumeName)
 		if err != nil {
@@ -1284,7 +1284,7 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 	}
 
 	// Create a backup so we can revert.
-	targetContainerSubvolumeName := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	targetContainerSubvolumeName := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	backupTargetContainerSubvolumeName := fmt.Sprintf("%s.tmp", targetContainerSubvolumeName)
 	err = os.Rename(targetContainerSubvolumeName, backupTargetContainerSubvolumeName)
 	if err != nil {
@@ -1310,9 +1310,9 @@ func (s *storageBtrfs) ContainerRestore(container container, sourceContainer con
 	_, sourcePool, _ := srcContainerStorage.GetContainerPoolInfo()
 	sourceContainerSubvolumeName := ""
 	if sourceContainer.IsSnapshot() {
-		sourceContainerSubvolumeName = getSnapshotMountPoint(sourceContainer.Project(), sourcePool, sourceContainer.Name())
+		sourceContainerSubvolumeName = driver.GetSnapshotMountPoint(sourceContainer.Project(), sourcePool, sourceContainer.Name())
 	} else {
-		sourceContainerSubvolumeName = getContainerMountPoint(container.Project(), sourcePool, sourceContainer.Name())
+		sourceContainerSubvolumeName = driver.GetContainerMountPoint(container.Project(), sourcePool, sourceContainer.Name())
 	}
 
 	var failure error
@@ -1401,8 +1401,8 @@ func (s *storageBtrfs) doContainerSnapshotCreate(projectName string, targetName
 		}
 	}
 
-	srcContainerSubvolumeName := getContainerMountPoint(projectName, s.pool.Name, sourceName)
-	snapshotSubvolumeName := getSnapshotMountPoint(projectName, s.pool.Name, targetName)
+	srcContainerSubvolumeName := driver.GetContainerMountPoint(projectName, s.pool.Name, sourceName)
+	snapshotSubvolumeName := driver.GetSnapshotMountPoint(projectName, s.pool.Name, targetName)
 	err = s.btrfsPoolVolumesSnapshot(srcContainerSubvolumeName, snapshotSubvolumeName, true, true)
 	if err != nil {
 		return err
@@ -1423,7 +1423,7 @@ func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer container, sour
 }
 
 func btrfsSnapshotDeleteInternal(projectName, poolName string, snapshotName string) error {
-	snapshotSubvolumeName := getSnapshotMountPoint(projectName, poolName, snapshotName)
+	snapshotSubvolumeName := driver.GetSnapshotMountPoint(projectName, poolName, snapshotName)
 	// Also delete any leftover .ro snapshot.
 	roSnapshotSubvolumeName := fmt.Sprintf("%s.ro", snapshotSubvolumeName)
 	names := []string{snapshotSubvolumeName, roSnapshotSubvolumeName}
@@ -1476,7 +1476,7 @@ func (s *storageBtrfs) ContainerSnapshotStart(container container) (bool, error)
 		return false, err
 	}
 
-	snapshotSubvolumeName := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	snapshotSubvolumeName := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
 	roSnapshotSubvolumeName := fmt.Sprintf("%s.ro", snapshotSubvolumeName)
 	if shared.PathExists(roSnapshotSubvolumeName) {
 		logger.Debugf("The BTRFS snapshot is already mounted read-write")
@@ -1505,7 +1505,7 @@ func (s *storageBtrfs) ContainerSnapshotStop(container container) (bool, error)
 		return false, err
 	}
 
-	snapshotSubvolumeName := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	snapshotSubvolumeName := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
 	roSnapshotSubvolumeName := fmt.Sprintf("%s.ro", snapshotSubvolumeName)
 	if !shared.PathExists(roSnapshotSubvolumeName) {
 		logger.Debugf("The BTRFS snapshot is currently not mounted read-write")
@@ -1540,8 +1540,8 @@ func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer container, newN
 
 	// Unmount the snapshot if it is mounted otherwise we'll get EBUSY.
 	// Rename the subvolume on the storage pool.
-	oldSnapshotSubvolumeName := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
-	newSnapshotSubvolumeName := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
+	oldSnapshotSubvolumeName := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
+	newSnapshotSubvolumeName := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
 	err = os.Rename(oldSnapshotSubvolumeName, newSnapshotSubvolumeName)
 	if err != nil {
 		return err
@@ -1565,7 +1565,7 @@ func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container)
 	// Create the snapshot subvole path on the storage pool.
 	sourceName, _, _ := containerGetParentAndSnapshotName(snapshotContainer.Name())
 	snapshotSubvolumePath := getSnapshotSubvolumePath(snapshotContainer.Project(), s.pool.Name, sourceName)
-	snapshotSubvolumeName := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
+	snapshotSubvolumeName := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
 	if !shared.PathExists(snapshotSubvolumePath) {
 		err := os.MkdirAll(snapshotSubvolumePath, driver.ContainersDirMode)
 		if err != nil {
@@ -1642,9 +1642,9 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
 			prev := ""
 			if i > 0 {
 				// /var/lib/lxd/storage-pools/<pool>/containers-snapshots/<container>/<snapshot>
-				prev = getSnapshotMountPoint(source.Project(), s.pool.Name, snapshots[i-1].Name())
+				prev = driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, snapshots[i-1].Name())
 			}
-			cur := getSnapshotMountPoint(source.Project(), s.pool.Name, snap.Name())
+			cur := driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, snap.Name())
 
 			// Make a binary btrfs backup
 			target := fmt.Sprintf("%s/%s.bin", snapshotsPath, snapName)
@@ -1658,8 +1658,8 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
 	}
 
 	// Make a temporary copy of the container
-	sourceVolume := getContainerMountPoint(source.Project(), s.pool.Name, source.Name())
-	containersPath := getContainerMountPoint("default", s.pool.Name, "")
+	sourceVolume := driver.GetContainerMountPoint(source.Project(), s.pool.Name, source.Name())
+	containersPath := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	tmpContainerMntPoint, err := ioutil.TempDir(containersPath, source.Name())
 	if err != nil {
 		return err
@@ -1728,7 +1728,7 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
 				return err
 			}
 
-			snapshotMntPoint := getSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
+			snapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
 			// Copy the snapshot
@@ -1741,8 +1741,8 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
 	}
 
 	// Make a temporary copy of the container
-	sourceVolume := getContainerMountPoint(source.Project(), s.pool.Name, source.Name())
-	containersPath := getContainerMountPoint("default", s.pool.Name, "")
+	sourceVolume := driver.GetContainerMountPoint(source.Project(), s.pool.Name, source.Name())
+	containersPath := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	tmpContainerMntPoint, err := ioutil.TempDir(containersPath, source.Name())
 	if err != nil {
 		return err
@@ -1813,7 +1813,7 @@ func (s *storageBtrfs) ContainerBackupCreate(backup backup, source container) er
 func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
 	containerName, _, _ := containerGetParentAndSnapshotName(info.Name)
 
-	containerMntPoint := getContainerMountPoint("default", s.pool.Name, "")
+	containerMntPoint := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	unpackDir, err := ioutil.TempDir(containerMntPoint, containerName)
 	if err != nil {
 		return err
@@ -1854,7 +1854,7 @@ func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.R
 		}
 
 		// create mountpoint
-		snapshotMntPoint := getSnapshotMountPoint(info.Project, s.pool.Name, containerName)
+		snapshotMntPoint := driver.GetSnapshotMountPoint(info.Project, s.pool.Name, containerName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(info.Project, containerName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(info.Project, containerName))
 		err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1892,7 +1892,7 @@ func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.R
 	tmpContainerMntPoint := fmt.Sprintf("%s/.backup", unpackDir)
 	defer btrfsSubVolumesDelete(tmpContainerMntPoint)
 
-	containerMntPoint = getContainerMountPoint(info.Project, s.pool.Name, info.Name)
+	containerMntPoint = driver.GetContainerMountPoint(info.Project, s.pool.Name, info.Name)
 	err = s.btrfsPoolVolumesSnapshot(tmpContainerMntPoint, containerMntPoint, false, true)
 	if err != nil {
 		logger.Errorf("Failed to create btrfs snapshot \"%s\" of \"%s\": %s", tmpContainerMntPoint, containerMntPoint, err)
@@ -1915,7 +1915,7 @@ func (s *storageBtrfs) doContainerBackupLoadVanilla(info backupInfo, data io.Rea
 		return err
 	}
 
-	containerMntPoint := getContainerMountPoint(info.Project, s.pool.Name, info.Name)
+	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, info.Name)
 	// Extract container
 	for _, snap := range info.Snapshots {
 		cur := fmt.Sprintf("backup/snapshots/%s", snap)
@@ -2009,7 +2009,7 @@ func (s *storageBtrfs) ImageCreate(fingerprint string, tracker *ioprogress.Progr
 	// Create a temporary rw btrfs subvolume. From this rw subvolume we'll
 	// create a ro snapshot below. The path with which we do this is
 	// ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>@<pool>_tmp.
-	imageSubvolumeName := getImageMountPoint(s.pool.Name, fingerprint)
+	imageSubvolumeName := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	tmpImageSubvolumeName := fmt.Sprintf("%s_tmp", imageSubvolumeName)
 	err = btrfsSubVolumeCreate(tmpImageSubvolumeName)
 	if err != nil {
@@ -2065,7 +2065,7 @@ func (s *storageBtrfs) ImageDelete(fingerprint string) error {
 
 	// Delete the btrfs subvolume. The path with which we
 	// do this is ${LXD_DIR}/storage-pools/<pool>/images/<fingerprint>.
-	imageSubvolumeName := getImageMountPoint(s.pool.Name, fingerprint)
+	imageSubvolumeName := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.PathExists(imageSubvolumeName) && isBtrfsSubVolume(imageSubvolumeName) {
 		err = btrfsSubVolumesDelete(imageSubvolumeName)
 		if err != nil {
@@ -2486,14 +2486,14 @@ func (s *btrfsMigrationSourceDriver) send(conn *websocket.Conn, btrfsPath string
 func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string, containerOnly bool) error {
 	_, containerPool, _ := s.container.Storage().GetContainerPoolInfo()
 	containerName := s.container.Name()
-	containersPath := getContainerMountPoint("default", containerPool, "")
+	containersPath := driver.GetContainerMountPoint("default", containerPool, "")
 	sourceName := containerName
 
 	// Deal with sending a snapshot to create a container on another LXD
 	// instance.
 	if s.container.IsSnapshot() {
 		sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
-		snapshotsPath := getSnapshotMountPoint(s.container.Project(), containerPool, sourceName)
+		snapshotsPath := driver.GetSnapshotMountPoint(s.container.Project(), containerPool, sourceName)
 		tmpContainerMntPoint, err := ioutil.TempDir(snapshotsPath, sourceName)
 		if err != nil {
 			return err
@@ -2506,7 +2506,7 @@ func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *
 		}
 
 		migrationSendSnapshot := fmt.Sprintf("%s/.migration-send", tmpContainerMntPoint)
-		snapshotMntPoint := getSnapshotMountPoint(s.container.Project(), containerPool, containerName)
+		snapshotMntPoint := driver.GetSnapshotMountPoint(s.container.Project(), containerPool, containerName)
 		err = s.btrfs.btrfsPoolVolumesSnapshot(snapshotMntPoint, migrationSendSnapshot, true, true)
 		if err != nil {
 			return err
@@ -2521,10 +2521,10 @@ func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *
 		for i, snap := range s.snapshots {
 			prev := ""
 			if i > 0 {
-				prev = getSnapshotMountPoint(snap.Project(), containerPool, s.snapshots[i-1].Name())
+				prev = driver.GetSnapshotMountPoint(snap.Project(), containerPool, s.snapshots[i-1].Name())
 			}
 
-			snapMntPoint := getSnapshotMountPoint(snap.Project(), containerPool, snap.Name())
+			snapMntPoint := driver.GetSnapshotMountPoint(snap.Project(), containerPool, snap.Name())
 			wrapper := StorageProgressReader(op, "fs_progress", snap.Name())
 			if err := s.send(conn, snapMntPoint, prev, wrapper); err != nil {
 				return err
@@ -2544,7 +2544,7 @@ func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *
 	}
 
 	migrationSendSnapshot := fmt.Sprintf("%s/.migration-send", tmpContainerMntPoint)
-	containerMntPoint := getContainerMountPoint(s.container.Project(), containerPool, sourceName)
+	containerMntPoint := driver.GetContainerMountPoint(s.container.Project(), containerPool, sourceName)
 	err = s.btrfs.btrfsPoolVolumesSnapshot(containerMntPoint, migrationSendSnapshot, true, true)
 	if err != nil {
 		return err
@@ -2561,7 +2561,7 @@ func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *
 }
 
 func (s *btrfsMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwlimit string) error {
-	tmpPath := getSnapshotMountPoint(s.container.Project(), s.btrfs.pool.Name,
+	tmpPath := driver.GetSnapshotMountPoint(s.container.Project(), s.btrfs.pool.Name,
 		fmt.Sprintf("%s/.migration-send", s.container.Name()))
 	err := os.MkdirAll(tmpPath, 0711)
 	if err != nil {
@@ -2575,7 +2575,7 @@ func (s *btrfsMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, b
 
 	s.stoppedSnapName = fmt.Sprintf("%s/.root", tmpPath)
 	parentName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
-	containerMntPt := getContainerMountPoint(s.container.Project(), s.btrfs.pool.Name, parentName)
+	containerMntPt := driver.GetContainerMountPoint(s.container.Project(), s.btrfs.pool.Name, parentName)
 	err = s.btrfs.btrfsPoolVolumesSnapshot(containerMntPt, s.stoppedSnapName, true, true)
 	if err != nil {
 		return err
@@ -2628,7 +2628,7 @@ func (s *storageBtrfs) MigrationSource(args MigrationSourceArgs) (MigrationStora
 		}
 	}
 
-	driver := &btrfsMigrationSourceDriver{
+	sourceDriver := &btrfsMigrationSourceDriver{
 		container:          args.Container,
 		snapshots:          snapshots,
 		btrfsSnapshotNames: []string{},
@@ -2637,12 +2637,12 @@ func (s *storageBtrfs) MigrationSource(args MigrationSourceArgs) (MigrationStora
 
 	if !args.ContainerOnly {
 		for _, snap := range snapshots {
-			btrfsPath := getSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
-			driver.btrfsSnapshotNames = append(driver.btrfsSnapshotNames, btrfsPath)
+			btrfsPath := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
+			sourceDriver.btrfsSnapshotNames = append(sourceDriver.btrfsSnapshotNames, btrfsPath)
 		}
 	}
 
-	return driver, nil
+	return sourceDriver, nil
 }
 
 func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args MigrationSinkArgs) error {
@@ -2721,7 +2721,7 @@ func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args M
 
 	containerName := args.Container.Name()
 	_, containerPool, _ := args.Container.Storage().GetContainerPoolInfo()
-	containersPath := getSnapshotMountPoint(args.Container.Project(), containerPool, containerName)
+	containersPath := driver.GetSnapshotMountPoint(args.Container.Project(), containerPool, containerName)
 	if !args.ContainerOnly && len(args.Snapshots) > 0 {
 		err := os.MkdirAll(containersPath, driver.ContainersDirMode)
 		if err != nil {
@@ -2769,7 +2769,7 @@ func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args M
 				}
 			}
 
-			snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), containerPool, ctArgs.Name)
+			snapshotMntPoint := driver.GetSnapshotMountPoint(args.Container.Project(), containerPool, ctArgs.Name)
 			_, err := containerCreateEmptySnapshot(args.Container.DaemonState(), ctArgs)
 			if err != nil {
 				return err
@@ -2802,7 +2802,7 @@ func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args M
 	}
 
 	/* finally, do the real container */
-	containersMntPoint := getContainerMountPoint("default", s.pool.Name, "")
+	containersMntPoint := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	tmpContainerMntPoint, err := ioutil.TempDir(containersMntPoint, project.Prefix(args.Container.Project(), containerName))
 	if err != nil {
 		return err
@@ -2815,7 +2815,7 @@ func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operation, args M
 	}
 
 	wrapper := StorageProgressWriter(op, "fs_progress", containerName)
-	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
 	err = btrfsRecv("", tmpContainerMntPoint, containerMntPoint, false, wrapper)
 	if err != nil {
 		return err
@@ -2861,9 +2861,9 @@ func (s *storageBtrfs) StorageEntitySetQuota(volumeType int, size int64, data in
 	switch volumeType {
 	case storagePoolVolumeTypeContainer:
 		c = data.(container)
-		subvol = getContainerMountPoint(c.Project(), s.pool.Name, c.Name())
+		subvol = driver.GetContainerMountPoint(c.Project(), s.pool.Name, c.Name())
 	case storagePoolVolumeTypeCustom:
-		subvol = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		subvol = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	qgroup, err := btrfsSubVolumeQGroup(subvol)
@@ -2872,7 +2872,7 @@ func (s *storageBtrfs) StorageEntitySetQuota(volumeType int, size int64, data in
 
 		if err == btrfsErrNoQuota {
 			// Enable quotas
-			poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+			poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 			output, err = shared.RunCommand("btrfs", "quota", "enable", poolMntPoint)
 			if err != nil {
@@ -2957,7 +2957,7 @@ func (s *storageBtrfs) StoragePoolResources() (*api.ResourcesStoragePool, error)
 		defer s.StoragePoolUmount()
 	}
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 	// Inode allocation is dynamic so no use in reporting them.
 
@@ -3017,23 +3017,23 @@ func (s *storageBtrfs) copyVolume(sourcePool string, sourceName string, targetNa
 	isDstSnapshot := shared.IsSnapshot(targetName)
 
 	if isSrcSnapshot {
-		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(sourcePool, sourceName)
+		srcMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, sourceName)
 	} else {
-		srcMountPoint = getStoragePoolVolumeMountPoint(sourcePool, sourceName)
+		srcMountPoint = driver.GetStoragePoolVolumeMountPoint(sourcePool, sourceName)
 	}
 
 	if isDstSnapshot {
-		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, targetName)
+		dstMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, targetName)
 	} else {
-		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, targetName)
+		dstMountPoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, targetName)
 	}
 
 	// Ensure that the directories immediately preceding the subvolume directory exist.
 	if isDstSnapshot {
 		volName, _, _ := containerGetParentAndSnapshotName(targetName)
-		customDir = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, volName)
+		customDir = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, volName)
 	} else {
-		customDir = getStoragePoolVolumeMountPoint(s.pool.Name, "")
+		customDir = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, "")
 	}
 
 	if !shared.PathExists(customDir) {
@@ -3073,7 +3073,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
 		return err
 	}
 
-	destVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	destVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 
 	if !volumeOnly {
@@ -3084,7 +3084,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
 		}
 
 		for _, snap := range snapshots {
-			srcSnapshotMntPoint := getStoragePoolVolumeSnapshotMountPoint(sourcePool, snap)
+			srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, snap)
 
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, destVolumeMntPoint, bwlimit, true)
 			if err != nil {
@@ -3106,10 +3106,10 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
 
 	if shared.IsSnapshot(sourceName) {
 		// copy snapshot to volume
-		srcVolumeMntPoint = getStoragePoolVolumeSnapshotMountPoint(sourcePool, sourceName)
+		srcVolumeMntPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, sourceName)
 	} else {
 		// copy volume to volume
-		srcVolumeMntPoint = getStoragePoolVolumeMountPoint(sourcePool, sourceName)
+		srcVolumeMntPoint = driver.GetStoragePoolVolumeMountPoint(sourcePool, sourceName)
 	}
 
 	_, err = rsyncLocalCopy(srcVolumeMntPoint, destVolumeMntPoint, bwlimit, true)
@@ -3161,15 +3161,15 @@ func (s *storageBtrfs) doVolumeSnapshotCreate(sourcePool string, sourceName stri
 		return err
 	}
 
-	customSnapshotSubvolumeName := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	customSnapshotSubvolumeName := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 
 	err = os.MkdirAll(customSnapshotSubvolumeName, driver.SnapshotsDirMode)
 	if err != nil && !os.IsNotExist(err) {
 		return err
 	}
 
-	sourcePath := getStoragePoolVolumeMountPoint(sourcePool, sourceName)
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, targetName)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(sourcePool, sourceName)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, targetName)
 
 	return s.btrfsPoolVolumesSnapshot(sourcePath, targetPath, true, true)
 }
@@ -3182,7 +3182,7 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	snapshotSubvolumeName := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	snapshotSubvolumeName := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	if shared.PathExists(snapshotSubvolumeName) && isBtrfsSubVolume(snapshotSubvolumeName) {
 		err := btrfsSubVolumesDelete(snapshotSubvolumeName)
 		if err != nil {
@@ -3196,7 +3196,7 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 	}
 
 	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
-	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
 		err := os.RemoveAll(storageVolumeSnapshotPath)
@@ -3228,8 +3228,8 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotRename(newName string) error {
 		return fmt.Errorf("Not a snapshot name")
 	}
 
-	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
 
 	err := os.Rename(oldPath, newPath)
 	if err != nil {
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 76fff33607..dc8da5b1dc 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -216,7 +216,7 @@ func (s *storageCeph) StoragePoolCreate() error {
 	}
 
 	// Create the mountpoint for the storage pool.
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	err := os.MkdirAll(poolMntPoint, 0711)
 	if err != nil {
 		logger.Errorf(`Failed to create mountpoint "%s" for ceph storage pool "%s" in cluster "%s": %s`, poolMntPoint, s.OSDPoolName, s.ClusterName, err)
@@ -272,7 +272,7 @@ func (s *storageCeph) StoragePoolDelete() error {
 	}
 
 	// Delete the mountpoint for the storage pool.
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if shared.PathExists(poolMntPoint) {
 		err := os.RemoveAll(poolMntPoint)
 		if err != nil {
@@ -366,7 +366,7 @@ func (s *storageCeph) StoragePoolVolumeCreate() error {
 	}
 	logger.Debugf(`Created filesystem type "%s" on device path "%s" for RBD storage volume "%s" on storage pool "%s"`, RBDFilesystem, RBDDevPath, s.volume.Name, s.pool.Name)
 
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(volumeMntPoint, 0711)
 	if err != nil {
 		logger.Errorf(`Failed to create mountpoint "%s" for RBD storage volume "%s" on storage pool "%s": %s"`, volumeMntPoint, s.volume.Name, s.pool.Name, err)
@@ -423,7 +423,7 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if shared.IsMountPoint(volumeMntPoint) {
 		err := driver.TryUnmount(volumeMntPoint, unix.MNT_DETACH)
 		if err != nil {
@@ -476,7 +476,7 @@ func (s *storageCeph) StoragePoolVolumeMount() (bool, error) {
 		s.volume.Name, s.pool.Name)
 
 	RBDFilesystem := s.getRBDFilesystem()
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customMountLockID := getCustomMountLockID(s.pool.Name, s.volume.Name)
 	lxdStorageMapLock.Lock()
@@ -540,7 +540,7 @@ func (s *storageCeph) StoragePoolVolumeUmount() (bool, error) {
 	logger.Debugf(`Unmounting RBD storage volume "%s" on storage pool "%s"`,
 		s.volume.Name, s.pool.Name)
 
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customMountLockID := getCustomUmountLockID(s.pool.Name, s.volume.Name)
 	lxdStorageMapLock.Lock()
@@ -713,11 +713,11 @@ func (s *storageCeph) StoragePoolVolumeRename(newName string) error {
 	var newPath string
 
 	if isSnapshot {
-		oldPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-		newPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newName)
+		oldPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		newPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newName)
 	} else {
-		oldPath = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-		newPath = getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+		oldPath = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		newPath = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, newName)
 	}
 
 	err = os.Rename(oldPath, newPath)
@@ -797,7 +797,7 @@ func (s *storageCeph) ContainerCreateFromImage(container container, fingerprint
 
 	containerPath := container.Path()
 	containerName := container.Name()
-	containerPoolVolumeMntPoint := getContainerMountPoint(container.Project(), s.pool.Name,
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name,
 		containerName)
 
 	imageStoragePoolLockID := getImageCreateLockID(s.pool.Name, fingerprint)
@@ -948,7 +948,7 @@ func (s *storageCeph) ContainerDelete(container container) error {
 
 	// umount
 	containerPath := container.Path()
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 	if shared.PathExists(containerMntPoint) {
 		_, err := s.ContainerUmount(container, containerPath)
 		if err != nil {
@@ -1039,12 +1039,12 @@ func (s *storageCeph) doCrossPoolContainerCopy(target container, source containe
 		return err
 	}
 
-	destContainerMntPoint := getContainerMountPoint(target.Project(), targetPool, target.Name())
+	destContainerMntPoint := driver.GetContainerMountPoint(target.Project(), targetPool, target.Name())
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	// Extract container
 	if !containerOnly {
 		for _, snap := range snapshots {
-			srcSnapshotMntPoint := getSnapshotMountPoint(snap.Project(), sourcePool, snap.Name())
+			srcSnapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), sourcePool, snap.Name())
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, destContainerMntPoint, bwlimit, true)
 			if err != nil {
 				return err
@@ -1072,7 +1072,7 @@ func (s *storageCeph) doCrossPoolContainerCopy(target container, source containe
 		}
 	}
 
-	srcContainerMntPoint := getContainerMountPoint(source.Project(), sourcePool, source.Name())
+	srcContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, source.Name())
 	_, err = rsyncLocalCopy(srcContainerMntPoint, destContainerMntPoint, bwlimit, true)
 	if err != nil {
 		if !refresh {
@@ -1109,7 +1109,7 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 		sourceContainerName)
 
 	targetContainerName := target.Name()
-	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
+	targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
 	if containerOnly || len(snapshots) == 0 {
 		if s.pool.Config["ceph.rbd.clone_copy"] != "" &&
 			!shared.IsTrue(s.pool.Config["ceph.rbd.clone_copy"]) {
@@ -1131,7 +1131,7 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 
 		// create mountpoint for container
 		targetContainerPath := target.Path()
-		targetContainerMountPoint := getContainerMountPoint(
+		targetContainerMountPoint := driver.GetContainerMountPoint(
 			target.Project(),
 			s.pool.Name,
 			targetContainerName)
@@ -1233,7 +1233,7 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 
 			// create snapshot mountpoint
 			newTargetName := fmt.Sprintf("%s/%s", targetContainerName, snapOnlyName)
-			containersPath := getSnapshotMountPoint(
+			containersPath := driver.GetSnapshotMountPoint(
 				target.Project(),
 				s.pool.Name,
 				newTargetName)
@@ -1342,9 +1342,9 @@ func (s *storageCeph) ContainerUmount(c container, path string) (bool, error) {
 	logger.Debugf("Unmounting RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 	name := c.Name()
 
-	containerMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, name)
+	containerMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, name)
 	if shared.IsSnapshot(name) {
-		containerMntPoint = getSnapshotMountPoint(c.Project(), s.pool.Name, name)
+		containerMntPoint = driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, name)
 	}
 
 	containerUmountLockID := getContainerUmountLockID(s.pool.Name, project.Prefix(c.Project(), name))
@@ -1465,9 +1465,9 @@ func (s *storageCeph) ContainerRename(c container, newName string) error {
 	}()
 
 	// Create new mountpoint on the storage pool.
-	oldContainerMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, oldName)
+	oldContainerMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, oldName)
 	oldContainerMntPointSymlink := containerPath
-	newContainerMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, newName)
+	newContainerMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, newName)
 	newContainerMntPointSymlink := shared.VarPath("containers", project.Prefix(c.Project(), newName))
 	err = renameContainerMountpoint(
 		oldContainerMntPoint,
@@ -1489,8 +1489,8 @@ func (s *storageCeph) ContainerRename(c container, newName string) error {
 	}()
 
 	// Rename the snapshot mountpoint on the storage pool.
-	oldSnapshotMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, oldName)
-	newSnapshotMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, newName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, oldName)
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, newName)
 	if shared.PathExists(oldSnapshotMntPoint) {
 		err := os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 		if err != nil {
@@ -1586,7 +1586,7 @@ func (s *storageCeph) ContainerGetUsage(container container) (int64, error) {
 }
 
 func (s *storageCeph) ContainerSnapshotCreate(snapshotContainer container, sourceContainer container) error {
-	containerMntPoint := getContainerMountPoint(sourceContainer.Project(), s.pool.Name, sourceContainer.Name())
+	containerMntPoint := driver.GetContainerMountPoint(sourceContainer.Project(), s.pool.Name, sourceContainer.Name())
 	if shared.IsMountPoint(containerMntPoint) {
 		// This is costly but we need to ensure that all cached data has
 		// been committed to disk. If we don't then the rbd snapshot of
@@ -1629,7 +1629,7 @@ func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer container) error
 		}
 	}
 
-	snapshotContainerMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
+	snapshotContainerMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
 		snapshotContainerName)
 	if shared.PathExists(snapshotContainerMntPoint) {
 		err := os.RemoveAll(snapshotContainerMntPoint)
@@ -1641,7 +1641,7 @@ func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer container) error
 	}
 
 	// check if snapshot directory is empty
-	snapshotContainerPath := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
+	snapshotContainerPath := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
 		sourceContainerName)
 	empty, _ := shared.PathIsEmpty(snapshotContainerPath)
 	if empty == true {
@@ -1702,8 +1702,8 @@ func (s *storageCeph) ContainerSnapshotRename(c container, newName string) error
 		}
 	}()
 
-	oldSnapshotMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, oldName)
-	newSnapshotMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, newName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, oldName)
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, newName)
 	err = os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 	if err != nil {
 		logger.Errorf(`Failed to rename mountpoint for RBD storage volume for snapshot "%s" from "%s" to "%s": %s`, oldName, oldSnapshotMntPoint, newSnapshotMntPoint, err)
@@ -1803,7 +1803,7 @@ func (s *storageCeph) ContainerSnapshotStart(c container) (bool, error) {
 		}
 	}()
 
-	containerMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, containerName)
 	RBDFilesystem := s.getRBDFilesystem()
 	mountFlags, mountOptions := driver.LXDResolveMountoptions(s.getRBDMountOptions())
 	if RBDFilesystem == "xfs" {
@@ -1838,7 +1838,7 @@ func (s *storageCeph) ContainerSnapshotStop(c container) (bool, error) {
 	logger.Debugf(`Stopping RBD storage volume for snapshot "%s" on storage pool "%s"`, c.Name(), s.pool.Name)
 
 	containerName := c.Name()
-	containerMntPoint := getSnapshotMountPoint(c.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetSnapshotMountPoint(c.Project(), s.pool.Name, containerName)
 
 	// Check if already unmounted
 	if !shared.IsMountPoint(containerMntPoint) {
@@ -1953,7 +1953,7 @@ func (s *storageCeph) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, t
 		return err
 	}
 
-	containerMntPoint := getContainerMountPoint(info.Project, s.pool.Name, info.Name)
+	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, info.Name)
 	// Extract container
 	for _, snap := range info.Snapshots {
 		cur := fmt.Sprintf("backup/snapshots/%s", snap)
@@ -2020,7 +2020,7 @@ func (s *storageCeph) ImageCreate(fingerprint string, tracker *ioprogress.Progre
 	revert := true
 
 	// create image mountpoint
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.PathExists(imageMntPoint) {
 		err := os.MkdirAll(imageMntPoint, 0700)
 		if err != nil {
@@ -2316,7 +2316,7 @@ func (s *storageCeph) ImageDelete(fingerprint string) error {
 	}
 	logger.Debugf(`Deleted database entry for RBD storage volume for image "%s" on storage pool "%s"`, fingerprint, s.pool.Name)
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.PathExists(imageMntPoint) {
 		err := os.Remove(imageMntPoint)
 		if err != nil {
@@ -2333,7 +2333,7 @@ func (s *storageCeph) ImageDelete(fingerprint string) error {
 func (s *storageCeph) ImageMount(fingerprint string) (bool, error) {
 	logger.Debugf("Mounting RBD storage volume for image \"%s\" on storage pool \"%s\"", fingerprint, s.pool.Name)
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.IsMountPoint(imageMntPoint) {
 		return false, nil
 	}
@@ -2362,7 +2362,7 @@ func (s *storageCeph) ImageMount(fingerprint string) (bool, error) {
 func (s *storageCeph) ImageUmount(fingerprint string) (bool, error) {
 	logger.Debugf("Unmounting RBD storage volume for image \"%s\" on storage pool \"%s\"", fingerprint, s.pool.Name)
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.IsMountPoint(imageMntPoint) {
 		return false, nil
 	}
@@ -2404,13 +2404,13 @@ func (s *storageCeph) StorageEntitySetQuota(volumeType int, size int64, data int
 		RBDDevPath, ret = getRBDMappedDevPath(s.ClusterName,
 			s.OSDPoolName, storagePoolVolumeTypeNameContainer,
 			s.volume.Name, true, s.UserName)
-		mountpoint = getContainerMountPoint(c.Project(), s.pool.Name, ctName)
+		mountpoint = driver.GetContainerMountPoint(c.Project(), s.pool.Name, ctName)
 		volumeName = ctName
 	default:
 		RBDDevPath, ret = getRBDMappedDevPath(s.ClusterName,
 			s.OSDPoolName, storagePoolVolumeTypeNameCustom,
 			s.volume.Name, true, s.UserName)
-		mountpoint = getStoragePoolVolumeMountPoint(s.pool.Name,
+		mountpoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name,
 			s.volume.Name)
 		volumeName = s.volume.Name
 	}
@@ -2540,7 +2540,7 @@ func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) err
 			source.Name, s.volume.Name)
 
 		revert := true
-		volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 		err = os.MkdirAll(volumeMntPoint, 0711)
 		if err != nil {
@@ -2633,7 +2633,7 @@ func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) err
 
 			// create snapshot mountpoint
 			newTargetName := fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName)
-			targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newTargetName)
+			targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, newTargetName)
 			err = os.MkdirAll(targetPath, driver.SnapshotsDirMode)
 			if err != nil {
 				logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
@@ -2694,7 +2694,7 @@ func (s *storageCeph) StorageMigrationSink(conn *websocket.Conn, op *operation,
 
 func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
 	logger.Debugf("Creating RBD storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
-	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	if shared.IsMountPoint(sourcePath) {
 		// This is costly but we need to ensure that all cached data has
@@ -2718,7 +2718,7 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 		return err
 	}
 
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
 	err = os.MkdirAll(targetPath, driver.SnapshotsDirMode)
 	if err != nil {
 		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
@@ -2746,7 +2746,7 @@ func (s *storageCeph) doPoolVolumeSnapshotDelete(name string) error {
 		}
 	}
 
-	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, name)
+	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, name)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
 		os.RemoveAll(storageVolumeSnapshotPath)
@@ -2793,8 +2793,8 @@ func (s *storageCeph) StoragePoolVolumeSnapshotRename(newName string) error {
 	logger.Debugf("Renamed RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
-	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index 517a2d4edf..df4ee7fc32 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -6,14 +6,14 @@ import (
 	"strings"
 
 	"github.com/gorilla/websocket"
+	"github.com/pborman/uuid"
 
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/project"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
-
-	"github.com/pborman/uuid"
 )
 
 type rbdMigrationSourceDriver struct {
@@ -301,7 +301,7 @@ func (s *storageCeph) MigrationSink(conn *websocket.Conn, op *operation, args Mi
 		}
 		logger.Debugf(`Received RBD storage volume "%s"`, curSnapName)
 
-		snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), s.pool.Name, fmt.Sprintf("%s/%s", containerName, *snap.Name))
+		snapshotMntPoint := driver.GetSnapshotMountPoint(args.Container.Project(), s.pool.Name, fmt.Sprintf("%s/%s", containerName, *snap.Name))
 		if !shared.PathExists(snapshotMntPoint) {
 			err := os.MkdirAll(snapshotMntPoint, 0700)
 			if err != nil {
@@ -351,7 +351,7 @@ func (s *storageCeph) MigrationSink(conn *websocket.Conn, op *operation, args Mi
 		return err
 	}
 
-	containerMntPoint := getContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(args.Container.Project(), s.pool.Name, containerName)
 	err = createContainerMountpoint(
 		containerMntPoint,
 		args.Container.Path(),
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index dacfec3b30..22ed7d4abe 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -767,7 +767,7 @@ func (s *storageCeph) copyWithoutSnapshotsFull(target container,
 	}
 
 	// Create mountpoint
-	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, target.Name())
+	targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, target.Name())
 	err = createContainerMountpoint(targetContainerMountPoint, target.Path(), target.IsPrivileged())
 	if err != nil {
 		return err
@@ -848,7 +848,7 @@ func (s *storageCeph) copyWithoutSnapshotsSparse(target container,
 	}
 
 	// Create mountpoint
-	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, target.Name())
+	targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, target.Name())
 	err = createContainerMountpoint(targetContainerMountPoint, target.Path(), target.IsPrivileged())
 	if err != nil {
 		return err
@@ -1762,7 +1762,7 @@ func (s *storageCeph) doContainerCreate(projectName, name string, privileged boo
 	logger.Debugf(`Created filesystem type "%s" on device path "%s" for RBD storage volume for container "%s" on storage pool "%s"`, RBDFilesystem, RBDDevPath, name, s.pool.Name)
 
 	containerPath := shared.VarPath("containers", project.Prefix(projectName, name))
-	containerMntPoint := getContainerMountPoint(projectName, s.pool.Name, name)
+	containerMntPoint := driver.GetContainerMountPoint(projectName, s.pool.Name, name)
 	err = createContainerMountpoint(containerMntPoint, containerPath, privileged)
 	if err != nil {
 		logger.Errorf(`Failed to create mountpoint "%s" for RBD storage volume for container "%s" on storage pool "%s": %s"`, containerMntPoint, name, s.pool.Name, err)
@@ -1790,9 +1790,9 @@ func (s *storageCeph) doContainerCreate(projectName, name string, privileged boo
 
 func (s *storageCeph) doContainerMount(projectName string, name string) (bool, error) {
 	RBDFilesystem := s.getRBDFilesystem()
-	containerMntPoint := getContainerMountPoint(projectName, s.pool.Name, name)
+	containerMntPoint := driver.GetContainerMountPoint(projectName, s.pool.Name, name)
 	if shared.IsSnapshot(name) {
-		containerMntPoint = getSnapshotMountPoint(projectName, s.pool.Name, name)
+		containerMntPoint = driver.GetSnapshotMountPoint(projectName, s.pool.Name, name)
 	}
 
 	containerMountLockID := getContainerMountLockID(s.pool.Name, name)
@@ -1872,7 +1872,7 @@ func (s *storageCeph) doContainerSnapshotCreate(projectName, targetName string,
 		}
 	}()
 
-	targetContainerMntPoint := getSnapshotMountPoint(projectName, s.pool.Name, targetName)
+	targetContainerMntPoint := driver.GetSnapshotMountPoint(projectName, s.pool.Name, targetName)
 	sourceOnlyName, _, _ := containerGetParentAndSnapshotName(sourceName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(projectName, sourceOnlyName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(projectName, sourceOnlyName))
@@ -1928,13 +1928,13 @@ func (s *storageCeph) doCrossPoolVolumeCopy(source *api.StorageVolumeSource) err
 		defer s.StoragePoolVolumeUmount()
 	}
 
-	dstVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	dstVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 
 	if !source.VolumeOnly {
 		for _, snap := range snapshots {
 			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
-			srcSnapshotMntPoint := getStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
+			srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
 
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, dstVolumeMntPoint, bwlimit, true)
 			if err != nil {
@@ -1951,9 +1951,9 @@ func (s *storageCeph) doCrossPoolVolumeCopy(source *api.StorageVolumeSource) err
 	var srcVolumeMntPoint string
 
 	if shared.IsSnapshot(source.Name) {
-		srcVolumeMntPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		srcVolumeMntPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
 	} else {
-		srcVolumeMntPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		srcVolumeMntPoint = driver.GetStoragePoolVolumeMountPoint(source.Pool, source.Name)
 	}
 
 	_, err = rsyncLocalCopy(srcVolumeMntPoint, dstVolumeMntPoint, bwlimit, true)
@@ -1993,7 +1993,7 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSo
 	}
 
 	// Create the mountpoint
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(volumeMntPoint, 0711)
 	if err != nil {
 		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
@@ -2041,7 +2041,7 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsSparse(source *api.StorageVolume
 	}
 
 	// Create the mountpoint
-	volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(volumeMntPoint, 0711)
 	if err != nil {
 		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", volumeMntPoint, s.volume.Name, s.pool.Name, err)
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 58651befec..1732289255 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -179,7 +179,7 @@ func (s *storageCephFs) StoragePoolCreate() error {
 	}
 
 	// Create the mountpoint for the storage pool.
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	err = os.MkdirAll(poolMntPoint, 0711)
 	if err != nil {
 		return err
@@ -275,7 +275,7 @@ func (s *storageCephFs) StoragePoolDelete() error {
 	}
 
 	// Delete the mountpoint for the storage pool
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if shared.PathExists(poolMntPoint) {
 		err := os.RemoveAll(poolMntPoint)
 		if err != nil {
@@ -318,7 +318,7 @@ func (s *storageCephFs) StoragePoolMount() (bool, error) {
 	defer removeLockFromMap()
 
 	// Check if already mounted
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if shared.IsMountPoint(poolMntPoint) {
 		return false, nil
 	}
@@ -390,7 +390,7 @@ func (s *storageCephFs) StoragePoolUmount() (bool, error) {
 	defer removeLockFromMap()
 
 	// Check if already unmounted
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if !shared.IsMountPoint(poolMntPoint) {
 		return false, nil
 	}
@@ -456,7 +456,7 @@ func (s *storageCephFs) StoragePoolVolumeCreate() error {
 	}
 
 	// Create the volume
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(storageVolumePath, 0711)
 	if err != nil {
 		return err
@@ -476,7 +476,7 @@ func (s *storageCephFs) StoragePoolVolumeDelete() error {
 	}
 
 	// Check if not gone already
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if !shared.PathExists(storageVolumePath) {
 		return nil
 	}
@@ -488,7 +488,7 @@ func (s *storageCephFs) StoragePoolVolumeDelete() error {
 	}
 
 	// Delete the snapshot directory
-	err = os.Remove(getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name))
+	err = os.Remove(driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name))
 	if err != nil && !os.IsNotExist(err) {
 		return err
 	}
@@ -528,7 +528,7 @@ func (s *storageCephFs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut,
 			return err
 		}
 
-		targetPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		targetPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 		sourcePath := filepath.Join(targetPath, ".snap", writable.Restore)
 
 		// Restore using rsync
@@ -601,8 +601,8 @@ func (s *storageCephFs) StoragePoolVolumeRename(newName string) error {
 	}
 
 	// Rename the directory
-	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	oldPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, newName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
@@ -619,7 +619,7 @@ func (s *storageCephFs) StoragePoolVolumeRename(newName string) error {
 }
 
 func (s *storageCephFs) ContainerStorageReady(container container) bool {
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	ok, _ := shared.PathIsEmpty(containerMntPoint)
 	return !ok
 }
@@ -740,7 +740,7 @@ func (s *storageCephFs) StorageEntitySetQuota(volumeType int, size int64, data i
 	}
 
 	// Apply the limit
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	_, err = shared.RunCommand("setfattr", "-n", "ceph.quota.max_bytes", "-v", fmt.Sprintf("%d", size), storageVolumePath)
 	if err != nil {
 		return err
@@ -756,7 +756,7 @@ func (s *storageCephFs) StoragePoolResources() (*api.ResourcesStoragePool, error
 		return nil, err
 	}
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	return driver.GetStorageResource(poolMntPoint)
 }
 
@@ -788,7 +788,7 @@ func (s *storageCephFs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) e
 	}
 
 	// Create empty volume
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(storageVolumePath, 0711)
 	if err != nil {
 		return err
@@ -856,7 +856,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolum
 	}
 
 	// Create the snapshot
-	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
 	cephSnapPath := filepath.Join(sourcePath, ".snap", snapName)
 
 	err = os.Mkdir(cephSnapPath, 0711)
@@ -865,7 +865,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolum
 	}
 
 	// Make the snapshot path a symlink
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
 	err = os.MkdirAll(filepath.Dir(targetPath), 0711)
 	if err != nil {
 		return err
@@ -896,7 +896,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotDelete() error {
 	}
 
 	// Create the snapshot
-	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
 	cephSnapPath := filepath.Join(sourcePath, ".snap", snapName)
 
 	err = os.Remove(cephSnapPath)
@@ -905,7 +905,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotDelete() error {
 	}
 
 	// Make the snapshot path a symlink
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	err = os.Remove(targetPath)
 	if err != nil && !os.IsNotExist(err) {
 		return err
@@ -933,7 +933,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotRename(newName string) error {
 
 	// Rename the snapshot entry
 	sourceName, oldSnapName, _ := containerGetParentAndSnapshotName(s.volume.Name)
-	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
 	oldCephSnapPath := filepath.Join(sourcePath, ".snap", oldSnapName)
 	newCephSnapPath := filepath.Join(sourcePath, ".snap", newName)
 
@@ -943,13 +943,13 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotRename(newName string) error {
 	}
 
 	// Re-generate the snapshot symlink
-	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	err = os.Remove(oldPath)
 	if err != nil {
 		return err
 	}
 
-	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, filepath.Join(sourceName, newName))
+	newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, filepath.Join(sourceName, newName))
 	err = os.Symlink(newCephSnapPath, newPath)
 	if err != nil {
 		return err
@@ -970,16 +970,16 @@ func (s *storageCephFs) copyVolume(sourcePool string, source string, target stri
 	// Figure out the mountpoints
 	var srcMountPoint string
 	if shared.IsSnapshot(source) {
-		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
 	} else {
-		srcMountPoint = getStoragePoolVolumeMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeMountPoint(sourcePool, source)
 	}
 
 	// Split target name
 	targetVolName, targetSnapName, ok := containerGetParentAndSnapshotName(target)
 
 	// Figure out target path
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, targetVolName)
+	dstMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, targetVolName)
 
 	// Sync data on target
 	bwlimit := s.pool.Config["rsync.bwlimit"]
@@ -998,7 +998,7 @@ func (s *storageCephFs) copyVolume(sourcePool string, source string, target stri
 		}
 
 		// Make the snapshot path a symlink
-		targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
+		targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
 		err = os.MkdirAll(filepath.Dir(targetPath), 0711)
 		if err != nil {
 			return err
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index edd26d8686..04dfcb9a8a 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -63,7 +63,7 @@ func (s *storageDir) StoragePoolCreate() error {
 
 	s.pool.Config["volatile.initial_source"] = s.pool.Config["source"]
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 	source := shared.HostPath(s.pool.Config["source"])
 	if source == "" {
@@ -156,7 +156,7 @@ func (s *storageDir) StoragePoolDelete() error {
 
 	prefix := shared.VarPath("storage-pools")
 	if !strings.HasPrefix(source, prefix) {
-		storagePoolSymlink := getStoragePoolMountPoint(s.pool.Name)
+		storagePoolSymlink := driver.GetStoragePoolMountPoint(s.pool.Name)
 		if !shared.PathExists(storagePoolSymlink) {
 			return nil
 		}
@@ -177,7 +177,7 @@ func (s *storageDir) StoragePoolMount() (bool, error) {
 		return false, fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 	cleanSource := filepath.Clean(source)
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if cleanSource == poolMntPoint {
 		return true, nil
 	}
@@ -233,7 +233,7 @@ func (s *storageDir) StoragePoolUmount() (bool, error) {
 		return false, fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 	cleanSource := filepath.Clean(source)
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if cleanSource == poolMntPoint {
 		return true, nil
 	}
@@ -328,9 +328,9 @@ func (s *storageDir) StoragePoolVolumeCreate() error {
 	var storageVolumePath string
 
 	if isSnapshot {
-		storageVolumePath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		storageVolumePath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	} else {
-		storageVolumePath = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		storageVolumePath = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	err = os.MkdirAll(storageVolumePath, 0711)
@@ -355,7 +355,7 @@ func (s *storageDir) StoragePoolVolumeDelete() error {
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	storageVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if !shared.PathExists(storageVolumePath) {
 		return nil
 	}
@@ -406,9 +406,9 @@ func (s *storageDir) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, cha
 		logger.Infof(`Restoring DIR storage volume "%s" from snapshot "%s"`,
 			s.volume.Name, writable.Restore)
 
-		sourcePath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name,
+		sourcePath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name,
 			fmt.Sprintf("%s/%s", s.volume.Name, writable.Restore))
-		targetPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		targetPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 		// Restore using rsync
 		bwlimit := s.pool.Config["rsync.bwlimit"]
@@ -474,8 +474,8 @@ func (s *storageDir) StoragePoolVolumeRename(newName string) error {
 			s.volume.Name, s.pool.Name)
 	}
 
-	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, newName)
+	oldPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, newName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
@@ -489,7 +489,7 @@ func (s *storageDir) StoragePoolVolumeRename(newName string) error {
 }
 
 func (s *storageDir) ContainerStorageReady(container container) bool {
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	ok, _ := shared.PathIsEmpty(containerMntPoint)
 	return !ok
 }
@@ -507,7 +507,7 @@ func (s *storageDir) ContainerCreate(container container) error {
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	err = createContainerMountpoint(containerMntPoint, container.Path(), container.IsPrivileged())
 	if err != nil {
 		return err
@@ -551,7 +551,7 @@ func (s *storageDir) ContainerCreateFromImage(container container, imageFingerpr
 
 	privileged := container.IsPrivileged()
 	containerName := container.Name()
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 	err = createContainerMountpoint(containerMntPoint, container.Path(), privileged)
 	if err != nil {
 		return errors.Wrap(err, "Create container mount point")
@@ -602,7 +602,7 @@ func (s *storageDir) ContainerDelete(container container) error {
 	// Delete the container on its storage pool:
 	// ${POOL}/containers/<container_name>
 	containerName := container.Name()
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 
 	err = s.deleteQuota(containerMntPoint, s.volumeID)
 	if err != nil {
@@ -626,7 +626,7 @@ func (s *storageDir) ContainerDelete(container container) error {
 	}
 
 	// Delete potential leftover snapshot mountpoints.
-	snapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	snapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
 	if shared.PathExists(snapshotMntPoint) {
 		err := os.RemoveAll(snapshotMntPoint)
 		if err != nil {
@@ -651,11 +651,11 @@ func (s *storageDir) ContainerDelete(container container) error {
 func (s *storageDir) copyContainer(target container, source container) error {
 	_, sourcePool, _ := source.Storage().GetContainerPoolInfo()
 	_, targetPool, _ := target.Storage().GetContainerPoolInfo()
-	sourceContainerMntPoint := getContainerMountPoint(source.Project(), sourcePool, source.Name())
+	sourceContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, source.Name())
 	if source.IsSnapshot() {
-		sourceContainerMntPoint = getSnapshotMountPoint(source.Project(), sourcePool, source.Name())
+		sourceContainerMntPoint = driver.GetSnapshotMountPoint(source.Project(), sourcePool, source.Name())
 	}
-	targetContainerMntPoint := getContainerMountPoint(target.Project(), targetPool, target.Name())
+	targetContainerMntPoint := driver.GetContainerMountPoint(target.Project(), targetPool, target.Name())
 
 	err := createContainerMountpoint(targetContainerMntPoint, target.Path(), target.IsPrivileged())
 	if err != nil {
@@ -684,11 +684,11 @@ func (s *storageDir) copyContainer(target container, source container) error {
 func (s *storageDir) copySnapshot(target container, targetPool string, source container, sourcePool string) error {
 	sourceName := source.Name()
 	targetName := target.Name()
-	sourceContainerMntPoint := getSnapshotMountPoint(source.Project(), sourcePool, sourceName)
-	targetContainerMntPoint := getSnapshotMountPoint(target.Project(), targetPool, targetName)
+	sourceContainerMntPoint := driver.GetSnapshotMountPoint(source.Project(), sourcePool, sourceName)
+	targetContainerMntPoint := driver.GetSnapshotMountPoint(target.Project(), targetPool, targetName)
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
-	containersPath := getSnapshotMountPoint(target.Project(), targetPool, targetParentName)
+	containersPath := driver.GetSnapshotMountPoint(target.Project(), targetPool, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", targetPool, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -837,9 +837,9 @@ func (s *storageDir) ContainerRename(container container, newName string) error
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	oldContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	oldContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	oldContainerSymlink := shared.VarPath("containers", project.Prefix(container.Project(), container.Name()))
-	newContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, newName)
+	newContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, newName)
 	newContainerSymlink := shared.VarPath("containers", project.Prefix(container.Project(), newName))
 	err = renameContainerMountpoint(oldContainerMntPoint, oldContainerSymlink, newContainerMntPoint, newContainerSymlink)
 	if err != nil {
@@ -848,8 +848,8 @@ func (s *storageDir) ContainerRename(container container, newName string) error
 
 	// Rename the snapshot mountpoint for the container if existing:
 	// ${POOL}/snapshots/<old_container_name> to ${POOL}/snapshots/<new_container_name>
-	oldSnapshotsMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
-	newSnapshotsMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, newName)
+	oldSnapshotsMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	newSnapshotsMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, newName)
 	if shared.PathExists(oldSnapshotsMntPoint) {
 		err = os.Rename(oldSnapshotsMntPoint, newSnapshotsMntPoint)
 		if err != nil {
@@ -902,7 +902,7 @@ func (s *storageDir) ContainerRestore(container container, sourceContainer conta
 }
 
 func (s *storageDir) ContainerGetUsage(c container) (int64, error) {
-	path := getContainerMountPoint(c.Project(), s.pool.Name, c.Name())
+	path := driver.GetContainerMountPoint(c.Project(), s.pool.Name, c.Name())
 
 	ok, err := quota.Supported(path)
 	if err != nil || !ok {
@@ -928,7 +928,7 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
-	targetContainerMntPoint := getSnapshotMountPoint(sourceContainer.Project(), s.pool.Name, targetContainerName)
+	targetContainerMntPoint := driver.GetSnapshotMountPoint(sourceContainer.Project(), s.pool.Name, targetContainerName)
 	err = os.MkdirAll(targetContainerMntPoint, 0711)
 	if err != nil {
 		return err
@@ -953,7 +953,7 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer container, source
 
 	_, sourcePool, _ := sourceContainer.Storage().GetContainerPoolInfo()
 	sourceContainerName := sourceContainer.Name()
-	sourceContainerMntPoint := getContainerMountPoint(sourceContainer.Project(), sourcePool, sourceContainerName)
+	sourceContainerMntPoint := driver.GetContainerMountPoint(sourceContainer.Project(), sourcePool, sourceContainerName)
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	err = rsync(snapshotContainer, sourceContainerMntPoint, targetContainerMntPoint, bwlimit)
 	if err != nil {
@@ -983,7 +983,7 @@ onSuccess:
 	// ${LXD_DIR}/snapshots/<source_container_name> to ${POOL_PATH}/snapshots/<source_container_name>
 	// exists and if not create it.
 	sourceContainerSymlink := shared.VarPath("snapshots", project.Prefix(sourceContainer.Project(), sourceContainerName))
-	sourceContainerSymlinkTarget := getSnapshotMountPoint(sourceContainer.Project(), sourcePool, sourceContainerName)
+	sourceContainerSymlinkTarget := driver.GetSnapshotMountPoint(sourceContainer.Project(), sourcePool, sourceContainerName)
 	if !shared.PathExists(sourceContainerSymlink) {
 		err = os.Symlink(sourceContainerSymlinkTarget, sourceContainerSymlink)
 		if err != nil {
@@ -1005,7 +1005,7 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 
 	// Create the path for the snapshot.
 	targetContainerName := snapshotContainer.Name()
-	targetContainerMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, targetContainerName)
+	targetContainerMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, targetContainerName)
 	err = os.MkdirAll(targetContainerMntPoint, 0711)
 	if err != nil {
 		return err
@@ -1021,7 +1021,7 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 	// Check if the symlink
 	// ${LXD_DIR}/snapshots/<source_container_name> to ${POOL_PATH}/snapshots/<source_container_name>
 	// exists and if not create it.
-	targetContainerMntPoint = getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
+	targetContainerMntPoint = driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
 		targetContainerName)
 	sourceName, _, _ := containerGetParentAndSnapshotName(targetContainerName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools",
@@ -1040,7 +1040,7 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 }
 
 func dirSnapshotDeleteInternal(projectName, poolName string, snapshotName string) error {
-	snapshotContainerMntPoint := getSnapshotMountPoint(projectName, poolName, snapshotName)
+	snapshotContainerMntPoint := driver.GetSnapshotMountPoint(projectName, poolName, snapshotName)
 	if shared.PathExists(snapshotContainerMntPoint) {
 		err := os.RemoveAll(snapshotContainerMntPoint)
 		if err != nil {
@@ -1049,7 +1049,7 @@ func dirSnapshotDeleteInternal(projectName, poolName string, snapshotName string
 	}
 
 	sourceContainerName, _, _ := containerGetParentAndSnapshotName(snapshotName)
-	snapshotContainerPath := getSnapshotMountPoint(projectName, poolName, sourceContainerName)
+	snapshotContainerPath := driver.GetSnapshotMountPoint(projectName, poolName, sourceContainerName)
 	empty, _ := shared.PathIsEmpty(snapshotContainerPath)
 	if empty == true {
 		err := os.Remove(snapshotContainerPath)
@@ -1102,8 +1102,8 @@ func (s *storageDir) ContainerSnapshotRename(snapshotContainer container, newNam
 
 	// Rename the mountpoint for the snapshot:
 	// ${POOL}/snapshots/<old_snapshot_name> to ${POOL}/snapshots/<new_snapshot_name>
-	oldSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
-	newSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
 	err = os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 	if err != nil {
 		return err
@@ -1170,7 +1170,7 @@ func (s *storageDir) ContainerBackupCreate(backup backup, source container) erro
 
 		for _, snap := range snapshots {
 			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
-			snapshotMntPoint := getSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
+			snapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
 			// Copy the snapshot
@@ -1221,7 +1221,7 @@ func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, ta
 	}
 
 	// Create mountpoints
-	containerMntPoint := getContainerMountPoint(info.Project, s.pool.Name, info.Name)
+	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, info.Name)
 	err = createContainerMountpoint(containerMntPoint, driver.ContainerPath(project.Prefix(info.Project, info.Name), false), info.Privileged)
 	if err != nil {
 		return errors.Wrap(err, "Create container mount point")
@@ -1244,7 +1244,7 @@ func (s *storageDir) ContainerBackupLoad(info backupInfo, data io.ReadSeeker, ta
 
 	if len(info.Snapshots) > 0 {
 		// Create mountpoints
-		snapshotMntPoint := getSnapshotMountPoint(info.Project, s.pool.Name, info.Name)
+		snapshotMntPoint := driver.GetSnapshotMountPoint(info.Project, s.pool.Name, info.Name)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name,
 			"containers-snapshots", project.Prefix(info.Project, info.Name))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(info.Project, info.Name))
@@ -1315,9 +1315,9 @@ func (s *storageDir) StorageEntitySetQuota(volumeType int, size int64, data inte
 	switch volumeType {
 	case storagePoolVolumeTypeContainer:
 		c := data.(container)
-		path = getContainerMountPoint(c.Project(), s.pool.Name, c.Name())
+		path = driver.GetContainerMountPoint(c.Project(), s.pool.Name, c.Name())
 	case storagePoolVolumeTypeCustom:
-		path = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		path = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	ok, err := quota.Supported(path)
@@ -1384,7 +1384,7 @@ func (s *storageDir) StoragePoolResources() (*api.ResourcesStoragePool, error) {
 		return nil, err
 	}
 
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 
 	return driver.GetStorageResource(poolMntPoint)
 }
@@ -1464,13 +1464,13 @@ func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 		return fmt.Errorf("Not a snapshot name")
 	}
 
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
 	err = os.MkdirAll(targetPath, 0711)
 	if err != nil {
 		return err
 	}
 
-	sourcePath := getStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
+	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	msg, err := rsyncLocalCopy(sourcePath, targetPath, bwlimit, true)
 	if err != nil {
@@ -1489,14 +1489,14 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	storageVolumePath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	err := os.RemoveAll(storageVolumePath)
 	if err != nil && !os.IsNotExist(err) {
 		return err
 	}
 
 	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
-	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
 		os.RemoveAll(storageVolumeSnapshotPath)
@@ -1526,8 +1526,8 @@ func (s *storageDir) StoragePoolVolumeSnapshotRename(newName string) error {
 		return fmt.Errorf("Not a snapshot name")
 	}
 
-	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
 
 	err := os.Rename(oldPath, newPath)
 	if err != nil {
@@ -1543,12 +1543,12 @@ func (s *storageDir) copyVolume(sourcePool string, source string, target string)
 	var srcMountPoint string
 
 	if shared.IsSnapshot(source) {
-		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
 	} else {
-		srcMountPoint = getStoragePoolVolumeMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeMountPoint(sourcePool, source)
 	}
 
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, target)
+	dstMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, target)
 
 	err := os.MkdirAll(dstMountPoint, 0711)
 	if err != nil {
@@ -1573,8 +1573,8 @@ func (s *storageDir) copyVolume(sourcePool string, source string, target string)
 }
 
 func (s *storageDir) copyVolumeSnapshot(sourcePool string, source string, target string) error {
-	srcMountPoint := getStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
-	dstMountPoint := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
+	srcMountPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
+	dstMountPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
 
 	err := os.MkdirAll(dstMountPoint, 0711)
 	if err != nil {
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index c168697b33..7991f4ecac 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -138,7 +138,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 	pvName := ""
 
 	// Create the mountpoint for the storage pool.
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	err := os.MkdirAll(poolMntPoint, 0711)
 	if err != nil {
 		return err
@@ -409,7 +409,7 @@ func (s *storageLvm) StoragePoolDelete() error {
 	}
 
 	// Delete the mountpoint for the storage pool.
-	poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	err = os.RemoveAll(poolMntPoint)
 	if err != nil {
 		return err
@@ -514,7 +514,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 		}
 	}()
 
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	err = os.MkdirAll(customPoolVolumeMntPoint, 0711)
 	if err != nil {
 		return err
@@ -567,7 +567,7 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	if shared.PathExists(customPoolVolumeMntPoint) {
 		err := os.RemoveAll(customPoolVolumeMntPoint)
 		if err != nil {
@@ -592,7 +592,7 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 	logger.Debugf("Mounting LVM storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	volumeLvmName := containerNameToLVName(s.volume.Name)
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	poolName := s.getOnDiskPoolName()
 	lvFsType := s.getLvmFilesystem()
 	volumeType, err := storagePoolVolumeTypeNameToAPIEndpoint(s.volume.Type)
@@ -642,7 +642,7 @@ func (s *storageLvm) StoragePoolVolumeMount() (bool, error) {
 func (s *storageLvm) StoragePoolVolumeUmount() (bool, error) {
 	logger.Debugf("Unmounting LVM storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customUmountLockID := getCustomUmountLockID(s.pool.Name, s.volume.Name)
 	lxdStorageMapLock.Lock()
@@ -818,8 +818,8 @@ func (s *storageLvm) StoragePoolVolumeUpdate(writable *api.StorageVolumePut,
 		} else {
 			poolName := s.getOnDiskPoolName()
 			sourceName := fmt.Sprintf("%s/%s", s.volume.Name, writable.Restore)
-			sourceVolumeMntPoint := getStoragePoolVolumeSnapshotMountPoint(poolName, sourceName)
-			targetVolumeMntPoint := getStoragePoolVolumeMountPoint(poolName, s.volume.Name)
+			sourceVolumeMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(poolName, sourceName)
+			targetVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(poolName, s.volume.Name)
 
 			bwlimit := s.pool.Config["rsync.bwlimit"]
 			output, err := rsyncLocalCopy(sourceVolumeMntPoint, targetVolumeMntPoint, bwlimit, true)
@@ -902,8 +902,8 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error {
 		return fmt.Errorf("Not a snapshot name")
 	}
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
-	oldPath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeMountPoint(s.pool.Name, fullSnapshotName)
+	oldPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, fullSnapshotName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
@@ -957,7 +957,7 @@ func (s *storageLvm) ContainerCreate(container container) error {
 	}()
 
 	if container.IsSnapshot() {
-		containerMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
+		containerMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
 		sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(container.Project(), sourceName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(container.Project(), sourceName))
@@ -970,7 +970,7 @@ func (s *storageLvm) ContainerCreate(container container) error {
 			return err
 		}
 	} else {
-		containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+		containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 		containerPath := container.Path()
 		err := os.MkdirAll(containerMntPoint, 0711)
 		if err != nil {
@@ -1013,7 +1013,7 @@ func (s *storageLvm) ContainerCreateFromImage(container container, fingerprint s
 		}
 	}()
 
-	containerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 	containerPath := container.Path()
 	err = os.MkdirAll(containerMntPoint, 0711)
 	if err != nil {
@@ -1067,9 +1067,9 @@ func lvmContainerDeleteInternal(projectName, poolName string, ctName string, isS
 	containerMntPoint := ""
 	containerLvmName := containerNameToLVName(ctName)
 	if isSnapshot {
-		containerMntPoint = getSnapshotMountPoint(projectName, poolName, ctName)
+		containerMntPoint = driver.GetSnapshotMountPoint(projectName, poolName, ctName)
 	} else {
-		containerMntPoint = getContainerMountPoint(projectName, poolName, ctName)
+		containerMntPoint = driver.GetContainerMountPoint(projectName, poolName, ctName)
 	}
 
 	if shared.IsMountPoint(containerMntPoint) {
@@ -1242,9 +1242,9 @@ func (s *storageLvm) doContainerMount(project, name string, snap bool) (bool, er
 	lvFsType := s.getLvmFilesystem()
 	poolName := s.getOnDiskPoolName()
 	containerLvmPath := getLvmDevPath(project, poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName)
-	containerMntPoint := getContainerMountPoint(project, s.pool.Name, name)
+	containerMntPoint := driver.GetContainerMountPoint(project, s.pool.Name, name)
 	if shared.IsSnapshot(name) {
-		containerMntPoint = getSnapshotMountPoint(project, s.pool.Name, name)
+		containerMntPoint = driver.GetSnapshotMountPoint(project, s.pool.Name, name)
 	}
 
 	containerMountLockID := getContainerMountLockID(s.pool.Name, name)
@@ -1298,9 +1298,9 @@ func (s *storageLvm) ContainerUmount(c container, path string) (bool, error) {
 
 func (s *storageLvm) umount(project, name string, path string) (bool, error) {
 	logger.Debugf("Unmounting LVM storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
-	containerMntPoint := getContainerMountPoint(project, s.pool.Name, name)
+	containerMntPoint := driver.GetContainerMountPoint(project, s.pool.Name, name)
 	if shared.IsSnapshot(name) {
-		containerMntPoint = getSnapshotMountPoint(project, s.pool.Name, name)
+		containerMntPoint = driver.GetSnapshotMountPoint(project, s.pool.Name, name)
 	}
 
 	containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
@@ -1382,17 +1382,17 @@ func (s *storageLvm) ContainerRename(container container, newContainerName strin
 			}
 		}
 
-		oldContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, oldName)
+		oldContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, oldName)
 		oldContainerMntPointSymlink := container.Path()
-		newContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, newContainerName)
+		newContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, newContainerName)
 		newContainerMntPointSymlink := shared.VarPath("containers", project.Prefix(container.Project(), newContainerName))
 		err = renameContainerMountpoint(oldContainerMntPoint, oldContainerMntPointSymlink, newContainerMntPoint, newContainerMntPointSymlink)
 		if err != nil {
 			return err
 		}
 
-		oldSnapshotPath := getSnapshotMountPoint(container.Project(), s.pool.Name, oldName)
-		newSnapshotPath := getSnapshotMountPoint(container.Project(), s.pool.Name, newContainerName)
+		oldSnapshotPath := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, oldName)
+		newSnapshotPath := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, newContainerName)
 		if shared.PathExists(oldSnapshotPath) {
 			err = os.Rename(oldSnapshotPath, newSnapshotPath)
 			if err != nil {
@@ -1478,10 +1478,10 @@ func (s *storageLvm) ContainerRestore(target container, source container) error
 
 		poolName := s.getOnDiskPoolName()
 		sourceName := source.Name()
-		targetContainerMntPoint := getContainerMountPoint(target.Project(), poolName, targetName)
-		sourceContainerMntPoint := getContainerMountPoint(target.Project(), poolName, sourceName)
+		targetContainerMntPoint := driver.GetContainerMountPoint(target.Project(), poolName, targetName)
+		sourceContainerMntPoint := driver.GetContainerMountPoint(target.Project(), poolName, sourceName)
 		if source.IsSnapshot() {
-			sourceContainerMntPoint = getSnapshotMountPoint(target.Project(), poolName, sourceName)
+			sourceContainerMntPoint = driver.GetSnapshotMountPoint(target.Project(), poolName, sourceName)
 		}
 
 		err = target.Freeze()
@@ -1547,8 +1547,8 @@ func (s *storageLvm) ContainerSnapshotRename(snapshotContainer container, newCon
 		}
 	}()
 
-	oldSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, oldName)
-	newSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newContainerName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, oldName)
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newContainerName)
 	err = os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 	if err != nil {
 		return err
@@ -1582,7 +1582,7 @@ func (s *storageLvm) ContainerSnapshotStart(container container) (bool, error) {
 	}
 
 	lvFsType := s.getLvmFilesystem()
-	containerMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
 	if !shared.IsMountPoint(containerMntPoint) {
 		mntOptString := s.getLvmMountOptions()
 		mountFlags, mountOptions := driver.LXDResolveMountoptions(mntOptString)
@@ -1614,7 +1614,7 @@ func (s *storageLvm) ContainerSnapshotStop(container container) (bool, error) {
 	logger.Debugf("Stopping LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	containerName := container.Name()
-	snapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
+	snapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
 
 	poolName := s.getOnDiskPoolName()
 
@@ -1712,7 +1712,7 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source container) erro
 
 		for _, snap := range snapshots {
 			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
-			snapshotMntPoint := getSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
+			snapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
 			// Mount the snapshot
@@ -1732,7 +1732,7 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source container) erro
 
 	// Make a temporary snapshot of the container
 	sourceLvmDatasetSnapshot := fmt.Sprintf("snapshot-%s", uuid.NewRandom().String())
-	tmpContainerMntPoint := getContainerMountPoint(source.Project(), s.pool.Name, sourceLvmDatasetSnapshot)
+	tmpContainerMntPoint := driver.GetContainerMountPoint(source.Project(), s.pool.Name, sourceLvmDatasetSnapshot)
 	err = os.MkdirAll(tmpContainerMntPoint, 0700)
 	if err != nil {
 		return err
@@ -1865,9 +1865,9 @@ func (s *storageLvm) doContainerBackupLoad(projectName, containerName string, pr
 
 	var containerMntPoint string
 	if snapshot {
-		containerMntPoint = getSnapshotMountPoint(projectName, s.pool.Name, containerName)
+		containerMntPoint = driver.GetSnapshotMountPoint(projectName, s.pool.Name, containerName)
 	} else {
-		containerMntPoint = getContainerMountPoint(projectName, s.pool.Name, containerName)
+		containerMntPoint = driver.GetContainerMountPoint(projectName, s.pool.Name, containerName)
 	}
 	err = os.MkdirAll(containerMntPoint, 0711)
 	if err != nil {
@@ -1944,7 +1944,7 @@ func (s *storageLvm) ImageCreate(fingerprint string, tracker *ioprogress.Progres
 	trySubUndo = false
 
 	// Create image mountpoint.
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.PathExists(imageMntPoint) {
 		err := os.MkdirAll(imageMntPoint, 0700)
 		if err != nil {
@@ -2000,7 +2000,7 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
 		return err
 	}
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.PathExists(imageMntPoint) {
 		err := os.Remove(imageMntPoint)
 		if err != nil {
@@ -2015,7 +2015,7 @@ func (s *storageLvm) ImageDelete(fingerprint string) error {
 func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
 	logger.Debugf("Mounting LVM storage volume for image \"%s\" on storage pool \"%s\"", fingerprint, s.pool.Name)
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.IsMountPoint(imageMntPoint) {
 		return false, nil
 	}
@@ -2042,7 +2042,7 @@ func (s *storageLvm) ImageMount(fingerprint string) (bool, error) {
 func (s *storageLvm) ImageUmount(fingerprint string) (bool, error) {
 	logger.Debugf("Unmounting LVM storage volume for image \"%s\" on storage pool \"%s\"", fingerprint, s.pool.Name)
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if !shared.IsMountPoint(imageMntPoint) {
 		return false, nil
 	}
@@ -2098,11 +2098,11 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte
 
 		ctLvmName := containerNameToLVName(ctName)
 		lvDevPath = getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointContainers, ctLvmName)
-		mountpoint = getContainerMountPoint(c.Project(), s.pool.Name, ctName)
+		mountpoint = driver.GetContainerMountPoint(c.Project(), s.pool.Name, ctName)
 	default:
 		customLvmName := containerNameToLVName(s.volume.Name)
 		lvDevPath = getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointCustom, customLvmName)
-		mountpoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		mountpoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	oldSize, err := units.ParseByteSizeString(s.volume.Config["size"])
@@ -2286,7 +2286,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 		return fmt.Errorf("Failed to create snapshot logical volume %s", err)
 	}
 
-	targetPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	targetPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
 	err = os.MkdirAll(targetPath, driver.SnapshotsDirMode)
 	if err != nil {
 		logger.Errorf("Failed to create mountpoint \"%s\" for RBD storage volume \"%s\" on storage pool \"%s\": %s", targetPath, s.volume.Name, s.pool.Name, err)
@@ -2301,7 +2301,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleting LVM storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	snapshotLVName := containerNameToLVName(s.volume.Name)
-	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	if shared.IsMountPoint(storageVolumeSnapshotPath) {
 		err := driver.TryUnmount(storageVolumeSnapshotPath, 0)
 		if err != nil {
@@ -2325,7 +2325,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 	}
 
 	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
-	storageVolumeSnapshotPath = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	storageVolumeSnapshotPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
 		os.RemoveAll(storageVolumeSnapshotPath)
@@ -2368,8 +2368,8 @@ func (s *storageLvm) StoragePoolVolumeSnapshotRename(newName string) error {
 		return fmt.Errorf("Failed to rename logical volume from \"%s\" to \"%s\": %s", s.volume.Name, fullSnapshotName, err)
 	}
 
-	oldPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-	newPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
+	oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, fullSnapshotName)
 	err = os.Rename(oldPath, newPath)
 	if err != nil {
 		return err
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 297813efa2..46ce0565fc 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -284,13 +284,13 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 		return errors.Wrap(err, "Get snapshot storage pool")
 	}
 	if targetIsSnapshot {
-		targetContainerMntPoint = getSnapshotMountPoint(sourceContainer.Project(), s.pool.Name, targetContainerName)
+		targetContainerMntPoint = driver.GetSnapshotMountPoint(sourceContainer.Project(), s.pool.Name, targetContainerName)
 		sourceName, _, _ := containerGetParentAndSnapshotName(sourceContainerName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(sourceContainer.Project(), sourceName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(sourceContainer.Project(), sourceName))
 		err = createSnapshotMountpoint(targetContainerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
 	} else {
-		targetContainerMntPoint = getContainerMountPoint(sourceContainer.Project(), targetPool, targetContainerName)
+		targetContainerMntPoint = driver.GetContainerMountPoint(sourceContainer.Project(), targetPool, targetContainerName)
 		err = createContainerMountpoint(targetContainerMntPoint, targetContainerPath, snapshotContainer.IsPrivileged())
 	}
 	if err != nil {
@@ -348,7 +348,7 @@ func (s *storageLvm) copySnapshot(target container, source container, refresh bo
 	}
 
 	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
-	containersPath := getSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
+	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
 	err = createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -407,14 +407,14 @@ func (s *storageLvm) copyContainerLv(target container, source container, readonl
 	if err != nil {
 		return err
 	}
-	sourceContainerMntPoint := getContainerMountPoint(source.Project(), sourcePool, sourceName)
+	sourceContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, sourceName)
 	if source.IsSnapshot() {
-		sourceContainerMntPoint = getSnapshotMountPoint(source.Project(), sourcePool, sourceName)
+		sourceContainerMntPoint = driver.GetSnapshotMountPoint(source.Project(), sourcePool, sourceName)
 	}
 
-	targetContainerMntPoint := getContainerMountPoint(target.Project(), s.pool.Name, targetName)
+	targetContainerMntPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, targetName)
 	if target.IsSnapshot() {
-		targetContainerMntPoint = getSnapshotMountPoint(source.Project(), s.pool.Name, targetName)
+		targetContainerMntPoint = driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, targetName)
 	}
 
 	if source.IsRunning() {
@@ -451,7 +451,7 @@ func (s *storageLvm) copyContainer(target container, source container, refresh b
 		return err
 	}
 
-	targetContainerMntPoint := getContainerMountPoint(target.Project(), targetPool, target.Name())
+	targetContainerMntPoint := driver.GetContainerMountPoint(target.Project(), targetPool, target.Name())
 	err = createContainerMountpoint(targetContainerMntPoint, target.Path(), target.IsPrivileged())
 	if err != nil {
 		return err
@@ -502,7 +502,7 @@ func (s *storageLvm) containerCreateFromImageLv(c container, fp string) error {
 	logger.Debugf(`Mounted non-thinpool LVM storage volume for container "%s" on storage pool "%s"`, containerName, s.pool.Name)
 
 	imagePath := shared.VarPath("images", fp)
-	containerMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, containerName)
 	err = unpackImage(imagePath, containerMntPoint, storageTypeLvm, s.s.OS.RunningInUserNS, nil)
 	if err != nil {
 		logger.Errorf(`Failed to unpack image "%s" into non-thinpool LVM storage volume "%s" for container "%s" on storage pool "%s": %s`, imagePath, containerMntPoint, containerName, s.pool.Name, err)
@@ -952,7 +952,7 @@ func lvmVersionIsAtLeast(sTypeVersion string, versionString string) (bool, error
 
 // Copy an LVM custom volume.
 func (s *storageLvm) copyVolume(sourcePool string, source string) error {
-	targetMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	targetMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	err := os.MkdirAll(targetMntPoint, 0711)
 	if err != nil {
@@ -974,7 +974,7 @@ func (s *storageLvm) copyVolume(sourcePool string, source string) error {
 func (s *storageLvm) copyVolumeSnapshot(sourcePool string, source string) error {
 	_, snapOnlyName, _ := containerGetParentAndSnapshotName(source)
 	target := fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName)
-	targetMntPoint := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
+	targetMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
 
 	err := os.MkdirAll(targetMntPoint, 0711)
 	if err != nil {
@@ -1000,18 +1000,18 @@ func (s *storageLvm) copyVolumeLv(sourcePool string, source string, target strin
 	sourceIsSnapshot := shared.IsSnapshot(source)
 
 	if sourceIsSnapshot {
-		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
 	} else {
-		srcMountPoint = getStoragePoolVolumeMountPoint(sourcePool, source)
+		srcMountPoint = driver.GetStoragePoolVolumeMountPoint(sourcePool, source)
 
 	}
 
 	targetIsSnapshot := shared.IsSnapshot(target)
 
 	if targetIsSnapshot {
-		dstMountPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
+		dstMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
 	} else {
-		dstMountPoint = getStoragePoolVolumeMountPoint(s.pool.Name, target)
+		dstMountPoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, target)
 	}
 
 	var err error
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 13716a39b9..82d09dffee 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -10,6 +10,7 @@ import (
 	deviceConfig "github.com/lxc/lxd/lxd/device/config"
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/project"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -65,7 +66,7 @@ func (s rsyncStorageSourceDriver) SendStorageVolume(conn *websocket.Conn, op *op
 
 		for _, snap := range snapshots {
 			wrapper := StorageProgressReader(op, "fs_progress", snap)
-			path := getStoragePoolVolumeSnapshotMountPoint(pool.Name, snap)
+			path := driver.GetStoragePoolVolumeSnapshotMountPoint(pool.Name, snap)
 			path = shared.AddSlash(path)
 			logger.Debugf("Starting to send storage volume snapshot %s on storage pool %s from %s", snap, pool.Name, path)
 
@@ -77,7 +78,7 @@ func (s rsyncStorageSourceDriver) SendStorageVolume(conn *websocket.Conn, op *op
 	}
 
 	wrapper := StorageProgressReader(op, "fs_progress", volume.Name)
-	path := getStoragePoolVolumeMountPoint(pool.Name, volume.Name)
+	path := driver.GetStoragePoolVolumeMountPoint(pool.Name, volume.Name)
 	path = shared.AddSlash(path)
 	logger.Debugf("Starting to send storage volume %s on storage pool %s from %s", volume.Name, pool.Name, path)
 	err = RsyncSend(volume.Name, path, conn, wrapper, s.rsyncFeatures, bwlimit, state.OS.ExecPath)
@@ -255,7 +256,7 @@ func rsyncStorageMigrationSink(conn *websocket.Conn, op *operation, args Migrati
 			}
 
 			wrapper := StorageProgressWriter(op, "fs_progress", target.Name)
-			path := getStoragePoolVolumeMountPoint(pool.Name, volume.Name)
+			path := driver.GetStoragePoolVolumeMountPoint(pool.Name, volume.Name)
 			path = shared.AddSlash(path)
 			logger.Debugf("Starting to receive storage volume snapshot %s on storage pool %s into %s", target.Name, pool.Name, path)
 
@@ -272,7 +273,7 @@ func rsyncStorageMigrationSink(conn *websocket.Conn, op *operation, args Migrati
 	}
 
 	wrapper := StorageProgressWriter(op, "fs_progress", volume.Name)
-	path := getStoragePoolVolumeMountPoint(pool.Name, volume.Name)
+	path := driver.GetStoragePoolVolumeMountPoint(pool.Name, volume.Name)
 	path = shared.AddSlash(path)
 	logger.Debugf("Starting to receive storage volume %s on storage pool %s into %s", volume.Name, pool.Name, path)
 	return RsyncRecv(path, conn, wrapper, args.RsyncFeatures)
diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go
index 65a55685bb..741bdfa699 100644
--- a/lxd/storage_pools.go
+++ b/lxd/storage_pools.go
@@ -9,9 +9,11 @@ import (
 	"sync"
 
 	"github.com/gorilla/mux"
+
 	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
+	driver "github.com/lxc/lxd/lxd/storage"
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -549,7 +551,7 @@ func storagePoolDelete(d *Daemon, r *http.Request) Response {
 	// notified us. We just need to delete the local mountpoint.
 	if s, ok := s.(*storageCeph); ok && isClusterNotification(r) {
 		// Delete the mountpoint for the storage pool.
-		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+		poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 		if shared.PathExists(poolMntPoint) {
 			err := os.RemoveAll(poolMntPoint)
 			if err != nil {
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index 1831ea5970..444ad2195b 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -242,7 +242,7 @@ func doStoragePoolCreateInternal(state *state.State, poolName, poolDescription s
 	// done by the node that triggered this notification. We just need to
 	// create the storage pool directory.
 	if s, ok := s.(*storageCeph); ok && isNotification {
-		volumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		volumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 		return os.MkdirAll(volumeMntPoint, 0711)
 
 	}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index cabdc2f993..412b7a396d 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -144,7 +144,7 @@ func (s *storageZfs) StoragePoolCreate() error {
 		s.StoragePoolDelete()
 	}()
 
-	storagePoolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	storagePoolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	err = os.MkdirAll(storagePoolMntPoint, 0711)
 	if err != nil {
 		return err
@@ -372,7 +372,7 @@ func (s *storageZfs) StoragePoolDelete() error {
 		}
 	}
 
-	storagePoolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+	storagePoolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
 	if shared.PathExists(storagePoolMntPoint) {
 		err := os.RemoveAll(storagePoolMntPoint)
 		if err != nil {
@@ -410,9 +410,9 @@ func (s *storageZfs) StoragePoolVolumeCreate() error {
 	var customPoolVolumeMntPoint string
 
 	if isSnapshot {
-		customPoolVolumeMntPoint = getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+		customPoolVolumeMntPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	} else {
-		customPoolVolumeMntPoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+		customPoolVolumeMntPoint = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
 	msg, err := zfsPoolVolumeCreate(dataset, "mountpoint=none", "canmount=noauto")
@@ -464,7 +464,7 @@ func (s *storageZfs) StoragePoolVolumeDelete() error {
 	logger.Infof("Deleting ZFS storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	poolName := s.getOnDiskPoolName()
 	if zfsFilesystemEntityExists(poolName, fs) {
@@ -540,7 +540,7 @@ func (s *storageZfs) StoragePoolVolumeMount() (bool, error) {
 	logger.Debugf("Mounting ZFS storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customMountLockID := getCustomMountLockID(s.pool.Name, s.volume.Name)
 	lxdStorageMapLock.Lock()
@@ -583,7 +583,7 @@ func (s *storageZfs) StoragePoolVolumeUmount() (bool, error) {
 	logger.Debugf("Unmounting ZFS storage volume \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
-	customPoolVolumeMntPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	customPoolVolumeMntPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	customUmountLockID := getCustomUmountLockID(s.pool.Name, s.volume.Name)
 	lxdStorageMapLock.Lock()
@@ -769,7 +769,7 @@ func (s *storageZfs) ContainerUmount(c container, path string) (bool, error) {
 	name := c.Name()
 
 	fs := fmt.Sprintf("containers/%s", project.Prefix(c.Project(), name))
-	containerPoolVolumeMntPoint := getContainerMountPoint(c.Project(), s.pool.Name, name)
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, name)
 
 	containerUmountLockID := getContainerUmountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
@@ -845,7 +845,7 @@ func (s *storageZfs) ContainerCreateFromImage(container container, fingerprint s
 	containerName := container.Name()
 	volumeName := project.Prefix(container.Project(), containerName)
 	fs := fmt.Sprintf("containers/%s", volumeName)
-	containerPoolVolumeMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, containerName)
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, containerName)
 
 	poolName := s.getOnDiskPoolName()
 	fsImage := fmt.Sprintf("images/%s", fingerprint)
@@ -933,7 +933,7 @@ func (s *storageZfs) copyWithoutSnapshotsSparse(target container, source contain
 
 	targetContainerName := target.Name()
 	targetContainerPath := target.Path()
-	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
+	targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
 
 	sourceZfsDataset := ""
 	sourceZfsDatasetSnapshot := ""
@@ -1093,7 +1093,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 		return err
 	}
 
-	targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, targetName)
+	targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, targetName)
 	targetfs := fmt.Sprintf("containers/%s", project.Prefix(target.Project(), targetName))
 
 	err = zfsPoolVolumeSet(poolName, targetfs, "canmount", "noauto")
@@ -1131,7 +1131,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 func (s *storageZfs) copyWithSnapshots(target container, source container, parentSnapshot string) error {
 	sourceName := source.Name()
 	targetParentName, targetSnapOnlyName, _ := containerGetParentAndSnapshotName(target.Name())
-	containersPath := getSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
+	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
 	err := createSnapshotMountpoint(containersPath, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1223,11 +1223,11 @@ func (s *storageZfs) doCrossPoolContainerCopy(target container, source container
 	}
 	defer s.ContainerUmount(target, shared.VarPath("containers", project.Prefix(target.Project(), target.Name())))
 
-	destContainerMntPoint := getContainerMountPoint(target.Project(), targetPool, target.Name())
+	destContainerMntPoint := driver.GetContainerMountPoint(target.Project(), targetPool, target.Name())
 	bwlimit := s.pool.Config["rsync.bwlimit"]
 	if !containerOnly {
 		for _, snap := range snapshots {
-			srcSnapshotMntPoint := getSnapshotMountPoint(target.Project(), sourcePool, snap.Name())
+			srcSnapshotMntPoint := driver.GetSnapshotMountPoint(target.Project(), sourcePool, snap.Name())
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, destContainerMntPoint, bwlimit, true)
 			if err != nil {
 				logger.Errorf("Failed to rsync into ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
@@ -1243,7 +1243,7 @@ func (s *storageZfs) doCrossPoolContainerCopy(target container, source container
 		}
 	}
 
-	srcContainerMntPoint := getContainerMountPoint(source.Project(), sourcePool, source.Name())
+	srcContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, source.Name())
 	_, err = rsyncLocalCopy(srcContainerMntPoint, destContainerMntPoint, bwlimit, true)
 	if err != nil {
 		logger.Errorf("Failed to rsync into ZFS storage volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
@@ -1290,7 +1290,7 @@ func (s *storageZfs) ContainerCopy(target container, source container, container
 	} else {
 		targetContainerName := target.Name()
 		targetContainerPath := target.Path()
-		targetContainerMountPoint := getContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
+		targetContainerMountPoint := driver.GetContainerMountPoint(target.Project(), s.pool.Name, targetContainerName)
 		err = createContainerMountpoint(targetContainerMountPoint, targetContainerPath, target.IsPrivileged())
 		if err != nil {
 			return err
@@ -1422,7 +1422,7 @@ func (s *storageZfs) ContainerRename(container container, newName string) error
 	}()
 
 	// Set the new mountpoint for the dataset.
-	newContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, newName)
+	newContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, newName)
 	err = zfsPoolVolumeSet(poolName, newZfsDataset, "mountpoint", newContainerMntPoint)
 	if err != nil {
 		return err
@@ -1436,7 +1436,7 @@ func (s *storageZfs) ContainerRename(container container, newName string) error
 	}
 
 	// Create new mountpoint on the storage pool.
-	oldContainerMntPoint := getContainerMountPoint(container.Project(), s.pool.Name, oldName)
+	oldContainerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, oldName)
 	oldContainerMntPointSymlink := container.Path()
 	newContainerMntPointSymlink := shared.VarPath("containers", project.Prefix(container.Project(), newName))
 	err = renameContainerMountpoint(oldContainerMntPoint, oldContainerMntPointSymlink, newContainerMntPoint, newContainerMntPointSymlink)
@@ -1445,8 +1445,8 @@ func (s *storageZfs) ContainerRename(container container, newName string) error
 	}
 
 	// Rename the snapshot mountpoint on the storage pool.
-	oldSnapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, oldName)
-	newSnapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, newName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, oldName)
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, newName)
 	if shared.PathExists(oldSnapshotMntPoint) {
 		err := os.Rename(oldSnapshotMntPoint, newSnapshotMntPoint)
 		if err != nil {
@@ -1561,7 +1561,7 @@ func (s *storageZfs) ContainerGetUsage(container container) (int64, error) {
 	}
 
 	// Shortcut for refquota
-	mountpoint := getContainerMountPoint(container.Project(), s.pool.Name, container.Name())
+	mountpoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
 	if property == "referenced" && shared.IsMountPoint(mountpoint) {
 		var stat unix.Statfs_t
 		err := unix.Statfs(mountpoint, &stat)
@@ -1600,7 +1600,7 @@ func (s *storageZfs) doContainerSnapshotCreate(projectName, targetName string, s
 		return err
 	}
 
-	snapshotMntPoint := getSnapshotMountPoint(projectName, s.pool.Name, snapshotContainerName)
+	snapshotMntPoint := driver.GetSnapshotMountPoint(projectName, s.pool.Name, snapshotContainerName)
 	if !shared.PathExists(snapshotMntPoint) {
 		err := os.MkdirAll(snapshotMntPoint, 0700)
 		if err != nil {
@@ -1664,7 +1664,7 @@ func zfsSnapshotDeleteInternal(projectName, poolName string, ctName string, onDi
 
 	// Delete the snapshot on its storage pool:
 	// ${POOL}/snapshots/<snapshot_name>
-	snapshotContainerMntPoint := getSnapshotMountPoint(projectName, poolName, ctName)
+	snapshotContainerMntPoint := driver.GetSnapshotMountPoint(projectName, poolName, ctName)
 	if shared.PathExists(snapshotContainerMntPoint) {
 		err := os.RemoveAll(snapshotContainerMntPoint)
 		if err != nil {
@@ -1675,7 +1675,7 @@ func zfsSnapshotDeleteInternal(projectName, poolName string, ctName string, onDi
 	// Check if we can remove the snapshot symlink:
 	// ${LXD_DIR}/snapshots/<container_name> to ${POOL}/snapshots/<container_name>
 	// by checking if the directory is empty.
-	snapshotContainerPath := getSnapshotMountPoint(projectName, poolName, sourceContainerName)
+	snapshotContainerPath := driver.GetSnapshotMountPoint(projectName, poolName, sourceContainerName)
 	empty, _ := shared.PathIsEmpty(snapshotContainerPath)
 	if empty == true {
 		// Remove the snapshot directory for the container:
@@ -1763,7 +1763,7 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 		}
 	}
 
-	oldSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, oldName)
+	oldSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, oldName)
 	if shared.PathExists(oldSnapshotMntPoint) {
 		err := os.Remove(oldSnapshotMntPoint)
 		if err != nil {
@@ -1771,7 +1771,7 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 		}
 	}
 
-	newSnapshotMntPoint := getSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
+	newSnapshotMntPoint := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, newName)
 	if !shared.PathExists(newSnapshotMntPoint) {
 		err := os.MkdirAll(newSnapshotMntPoint, 0700)
 		if err != nil {
@@ -1803,7 +1803,7 @@ func (s *storageZfs) ContainerSnapshotStart(container container) (bool, error) {
 	destFs := fmt.Sprintf("snapshots/%s/%s", project.Prefix(container.Project(), cName), sName)
 
 	poolName := s.getOnDiskPoolName()
-	snapshotMntPoint := getSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
+	snapshotMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, container.Name())
 	err := zfsPoolVolumeClone(container.Project(), poolName, sourceFs, sourceSnap, destFs, snapshotMntPoint)
 	if err != nil {
 		return false, err
@@ -2028,7 +2028,7 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
 				return errors.Wrap(err, "Mount snapshot")
 			}
 
-			snapshotMntPoint := getSnapshotMountPoint(projectName, s.pool.Name, snap.Name())
+			snapshotMntPoint := driver.GetSnapshotMountPoint(projectName, s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
 			// Copy the snapshot
@@ -2041,7 +2041,7 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
 	}
 
 	// Make a temporary copy of the container
-	containersPath := getContainerMountPoint("default", s.pool.Name, "")
+	containersPath := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	tmpContainerMntPoint, err := ioutil.TempDir(containersPath, source.Name())
 	if err != nil {
 		return errors.Wrap(err, "Create temporary copy dir")
@@ -2131,7 +2131,7 @@ func (s *storageZfs) ContainerBackupCreate(backup backup, source container) erro
 
 func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
 	containerName, _, _ := containerGetParentAndSnapshotName(info.Name)
-	containerMntPoint := getContainerMountPoint(info.Project, s.pool.Name, containerName)
+	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, containerName)
 	err := createContainerMountpoint(containerMntPoint, driver.ContainerPath(info.Name, false), info.Privileged)
 	if err != nil {
 		return err
@@ -2189,7 +2189,7 @@ func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.Rea
 		}
 
 		// create mountpoint
-		snapshotMntPoint := getSnapshotMountPoint(info.Project, s.pool.Name, fmt.Sprintf("%s/%s", containerName, snapshotOnlyName))
+		snapshotMntPoint := driver.GetSnapshotMountPoint(info.Project, s.pool.Name, fmt.Sprintf("%s/%s", containerName, snapshotOnlyName))
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(info.Project, containerName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(info.Project, containerName))
 		err = createSnapshotMountpoint(snapshotMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -2252,7 +2252,7 @@ func (s *storageZfs) doContainerBackupLoadVanilla(info backupInfo, data io.ReadS
 		return errors.Wrap(err, "Mount container")
 	}
 
-	containerMntPoint := getContainerMountPoint(info.Project, s.pool.Name, info.Name)
+	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, info.Name)
 	// Extract container
 	for _, snap := range info.Snapshots {
 		// Extract snapshots
@@ -2322,7 +2322,7 @@ func (s *storageZfs) ImageCreate(fingerprint string, tracker *ioprogress.Progres
 	logger.Debugf("Creating ZFS storage volume for image \"%s\" on storage pool \"%s\"", fingerprint, s.pool.Name)
 
 	poolName := s.getOnDiskPoolName()
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	fs := fmt.Sprintf("images/%s", fingerprint)
 	revert := true
 	subrevert := true
@@ -2377,7 +2377,7 @@ func (s *storageZfs) ImageCreate(fingerprint string, tracker *ioprogress.Progres
 	}
 
 	// Create temporary mountpoint directory.
-	tmp := getImageMountPoint(s.pool.Name, "")
+	tmp := driver.GetImageMountPoint(s.pool.Name, "")
 	tmpImageDir, err := ioutil.TempDir(tmp, "")
 	if err != nil {
 		return err
@@ -2479,7 +2479,7 @@ func (s *storageZfs) ImageDelete(fingerprint string) error {
 		return err
 	}
 
-	imageMntPoint := getImageMountPoint(s.pool.Name, fingerprint)
+	imageMntPoint := driver.GetImageMountPoint(s.pool.Name, fingerprint)
 	if shared.PathExists(imageMntPoint) {
 		err := os.RemoveAll(imageMntPoint)
 		if err != nil {
@@ -2789,7 +2789,7 @@ func (s *storageZfs) MigrationSink(conn *websocket.Conn, op *operation, args Mig
 			return err
 		}
 
-		snapshotMntPoint := getSnapshotMountPoint(args.Container.Project(), poolName, fmt.Sprintf("%s/%s", args.Container.Name(), *snap.Name))
+		snapshotMntPoint := driver.GetSnapshotMountPoint(args.Container.Project(), poolName, fmt.Sprintf("%s/%s", args.Container.Name(), *snap.Name))
 		if !shared.PathExists(snapshotMntPoint) {
 			err := os.MkdirAll(snapshotMntPoint, 0700)
 			if err != nil {
@@ -2954,7 +2954,7 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
 		defer s.StoragePoolVolumeUmount()
 	}
 
-	dstMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	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)
@@ -2964,7 +2964,7 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
 
 	if !source.VolumeOnly {
 		for _, snap := range snapshots {
-			srcMountPoint := getStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
+			srcMountPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
 
 			_, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit, true)
 			if err != nil {
@@ -2981,9 +2981,9 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
 	var srcMountPoint string
 
 	if strings.Contains(source.Name, "/") {
-		srcMountPoint = getStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
+		srcMountPoint = driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, source.Name)
 	} else {
-		srcMountPoint = getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+		srcMountPoint = driver.GetStoragePoolVolumeMountPoint(source.Pool, source.Name)
 	}
 
 	_, err = rsyncLocalCopy(srcMountPoint, dstMountPoint, bwlimit, true)
@@ -3059,7 +3059,7 @@ func (s *storageZfs) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSou
 		return err
 	}
 
-	targetContainerMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	targetContainerMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	targetfs := fmt.Sprintf("custom/%s", s.volume.Name)
 
 	err = zfsPoolVolumeSet(poolName, targetfs, "canmount", "noauto")
@@ -3084,10 +3084,10 @@ func (s *storageZfs) copyVolumeWithoutSnapshotsSparse(source *api.StorageVolumeS
 	poolName := s.getOnDiskPoolName()
 
 	sourceVolumeName := source.Name
-	sourceVolumePath := getStoragePoolVolumeMountPoint(source.Pool, source.Name)
+	sourceVolumePath := driver.GetStoragePoolVolumeMountPoint(source.Pool, source.Name)
 
 	targetVolumeName := s.volume.Name
-	targetVolumePath := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	targetVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 
 	sourceZfsDataset := ""
 	sourceZfsDatasetSnapshot := ""
@@ -3175,7 +3175,7 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 		}
 	}
 
-	targetStorageVolumeMountPoint := getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
+	targetStorageVolumeMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	fs := fmt.Sprintf("custom/%s", s.volume.Name)
 
 	if source.VolumeOnly || len(snapshots) == 0 {
@@ -3190,7 +3190,7 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 			return err
 		}
 	} else {
-		targetVolumeMountPoint := getStoragePoolVolumeMountPoint(poolName, s.volume.Name)
+		targetVolumeMountPoint := driver.GetStoragePoolVolumeMountPoint(poolName, s.volume.Name)
 
 		err := os.MkdirAll(targetVolumeMountPoint, 0711)
 		if err != nil {
@@ -3208,7 +3208,7 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 			sourceDataset := fmt.Sprintf("%s/custom/%s at snapshot-%s", poolName, source.Name, snap)
 			targetDataset := fmt.Sprintf("%s/custom/%s at snapshot-%s", poolName, s.volume.Name, snap)
 
-			snapshotMntPoint := getStoragePoolVolumeSnapshotMountPoint(poolName, fmt.Sprintf("%s/%s", s.volume.Name, snap))
+			snapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(poolName, fmt.Sprintf("%s/%s", s.volume.Name, snap))
 
 			err := os.MkdirAll(snapshotMntPoint, 0700)
 			if err != nil {
@@ -3355,7 +3355,7 @@ func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 		return err
 	}
 
-	snapshotMntPoint := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
+	snapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
 	if !shared.PathExists(snapshotMntPoint) {
 		err := os.MkdirAll(snapshotMntPoint, 0700)
 		if err != nil {
@@ -3390,13 +3390,13 @@ func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
 		}
 	}
 
-	storageVolumePath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
+	storageVolumePath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
 	err := os.RemoveAll(storageVolumePath)
 	if err != nil && !os.IsNotExist(err) {
 		return err
 	}
 
-	storageVolumeSnapshotPath := getStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
+	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
 		os.RemoveAll(storageVolumeSnapshotPath)
diff --git a/lxd/storage_zfs_utils.go b/lxd/storage_zfs_utils.go
index 6bd0403d59..7f0bc618a6 100644
--- a/lxd/storage_zfs_utils.go
+++ b/lxd/storage_zfs_utils.go
@@ -206,7 +206,7 @@ func zfsPoolVolumeClone(project, pool string, source string, name string, dest s
 		}
 
 		destSubvol := dest + strings.TrimPrefix(sub, source)
-		snapshotMntPoint := getSnapshotMountPoint(project, pool, destSubvol)
+		snapshotMntPoint := driver.GetSnapshotMountPoint(project, pool, destSubvol)
 
 		output, err := shared.RunCommand(
 			"zfs",
@@ -642,7 +642,7 @@ func (s *storageZfs) doContainerMount(projectName, name string, privileged bool)
 
 	volumeName := project.Prefix(projectName, name)
 	fs := fmt.Sprintf("containers/%s", volumeName)
-	containerPoolVolumeMntPoint := getContainerMountPoint(projectName, s.pool.Name, name)
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(projectName, s.pool.Name, name)
 
 	containerMountLockID := getContainerMountLockID(s.pool.Name, name)
 	lxdStorageMapLock.Lock()
@@ -708,7 +708,7 @@ func (s *storageZfs) doContainerDelete(projectName, name string) error {
 	poolName := s.getOnDiskPoolName()
 	containerName := name
 	fs := fmt.Sprintf("containers/%s", project.Prefix(projectName, containerName))
-	containerPoolVolumeMntPoint := getContainerMountPoint(projectName, s.pool.Name, containerName)
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(projectName, s.pool.Name, containerName)
 
 	if zfsFilesystemEntityExists(poolName, fs) {
 		removable := true
@@ -768,7 +768,7 @@ func (s *storageZfs) doContainerDelete(projectName, name string) error {
 	zfsPoolVolumeDestroy(poolName, snapshotZfsDataset)
 
 	// Delete potential leftover snapshot mountpoints.
-	snapshotMntPoint := getSnapshotMountPoint(projectName, s.pool.Name, containerName)
+	snapshotMntPoint := driver.GetSnapshotMountPoint(projectName, s.pool.Name, containerName)
 	if shared.PathExists(snapshotMntPoint) {
 		err := os.RemoveAll(snapshotMntPoint)
 		if err != nil {
@@ -798,7 +798,7 @@ func (s *storageZfs) doContainerCreate(projectName, name string, privileged bool
 	fs := fmt.Sprintf("containers/%s", project.Prefix(projectName, containerName))
 	poolName := s.getOnDiskPoolName()
 	dataset := fmt.Sprintf("%s/%s", poolName, fs)
-	containerPoolVolumeMntPoint := getContainerMountPoint(projectName, s.pool.Name, containerName)
+	containerPoolVolumeMntPoint := driver.GetContainerMountPoint(projectName, s.pool.Name, containerName)
 
 	// Create volume.
 	msg, err := zfsPoolVolumeCreate(dataset, "mountpoint=none", "canmount=noauto")

From 54c808e3b959a09a8d25495b48959417c5da5ac7 Mon Sep 17 00:00:00 2001
From: Thomas Hipp <thomas.hipp at canonical.com>
Date: Fri, 16 Aug 2019 08:06:09 +0200
Subject: [PATCH 2/2] lxd: Move ContainerGetParentAndSnapshotName to shared

Signed-off-by: Thomas Hipp <thomas.hipp at canonical.com>
---
 lxd/api_internal.go             |  8 ++---
 lxd/backup.go                   |  4 +--
 lxd/container.go                | 19 +++--------
 lxd/container_lxc.go            |  6 ++--
 lxd/container_snapshot.go       |  4 +--
 lxd/containers_post.go          |  4 +--
 lxd/migrate_container.go        |  6 ++--
 lxd/patches.go                  |  2 +-
 lxd/storage_btrfs.go            | 32 +++++++++----------
 lxd/storage_ceph.go             | 28 ++++++++---------
 lxd/storage_ceph_migration.go   |  4 +--
 lxd/storage_ceph_utils.go       | 18 +++++------
 lxd/storage_cephfs.go           | 10 +++---
 lxd/storage_dir.go              | 18 +++++------
 lxd/storage_lvm.go              | 20 ++++++------
 lxd/storage_lvm_utils.go        |  6 ++--
 lxd/storage_migration.go        |  6 ++--
 lxd/storage_pools_utils.go      |  2 +-
 lxd/storage_volumes.go          |  2 +-
 lxd/storage_volumes_snapshot.go |  2 +-
 lxd/storage_volumes_utils.go    |  2 +-
 lxd/storage_zfs.go              | 56 ++++++++++++++++-----------------
 shared/container.go             | 11 +++++++
 23 files changed, 135 insertions(+), 135 deletions(-)

diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 91333e3044..1a7709bab9 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -647,7 +647,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	for _, od = range onDiskSnapshots {
 		inBackupFile := false
 		for _, ib := range backup.Snapshots {
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(ib.Name)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(ib.Name)
 			if od == snapOnlyName {
 				inBackupFile = true
 				break
@@ -759,7 +759,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 			}
 
 			onDiskPoolName := backup.Pool.Config["ceph.osd.pool_name"]
-			ctName, csName, _ := containerGetParentAndSnapshotName(snap.Name)
+			ctName, csName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
 			ctName = project.Prefix(projectName, ctName)
 			csName = project.Prefix(projectName, csName)
 			snapshotName := fmt.Sprintf("snapshot_%s", csName)
@@ -775,7 +775,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 				return BadRequest(needForce)
 			}
 		case "zfs":
-			ctName, csName, _ := containerGetParentAndSnapshotName(snap.Name)
+			ctName, csName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
 			snapshotName := fmt.Sprintf("snapshot-%s", csName)
 
 			exists := zfsFilesystemEntityExists(poolName,
@@ -967,7 +967,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		// Recreate missing mountpoints and symlinks.
 		snapshotMountPoint := driver.GetSnapshotMountPoint(projectName, backup.Pool.Name,
 			snap.Name)
-		sourceName, _, _ := containerGetParentAndSnapshotName(snap.Name)
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(snap.Name)
 		sourceName = project.Prefix(projectName, sourceName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", backup.Pool.Name, "containers-snapshots", sourceName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", sourceName)
diff --git a/lxd/backup.go b/lxd/backup.go
index 8e5a926a56..36eba51b28 100644
--- a/lxd/backup.go
+++ b/lxd/backup.go
@@ -344,7 +344,7 @@ func backupCreateTarball(s *state.State, path string, backup backup) error {
 		}
 
 		for _, snap := range snaps {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			indexFile.Snapshots = append(indexFile.Snapshots, snapName)
 		}
 	}
@@ -489,7 +489,7 @@ func pruneExpiredContainerBackups(ctx context.Context, d *Daemon) error {
 	}
 
 	for _, backup := range backups {
-		containerName, _, _ := containerGetParentAndSnapshotName(backup)
+		containerName, _, _ := shared.ContainerGetParentAndSnapshotName(backup)
 		err := doBackupDelete(d.State(), backup, containerName)
 		if err != nil {
 			return errors.Wrapf(err, "Error deleting container backup %s", backup)
diff --git a/lxd/container.go b/lxd/container.go
index f01f2bc58d..ff9b166195 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -64,17 +64,6 @@ func init() {
 
 // Helper functions
 
-// Returns the parent container name, snapshot name, and whether it actually was
-// a snapshot name.
-func containerGetParentAndSnapshotName(name string) (string, string, bool) {
-	fields := strings.SplitN(name, shared.SnapshotDelimiter, 2)
-	if len(fields) == 1 {
-		return name, "", false
-	}
-
-	return fields[0], fields[1], true
-}
-
 func containerValidName(name string) error {
 	if strings.Contains(name, shared.SnapshotDelimiter) {
 		return fmt.Errorf(
@@ -1390,13 +1379,13 @@ func containerCompareSnapshots(source container, target container) ([]container,
 	toSync := []container{}
 
 	for _, snap := range sourceSnapshots {
-		_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 		sourceSnapshotsTime[snapName] = snap.CreationDate()
 	}
 
 	for _, snap := range targetSnapshots {
-		_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 		targetSnapshotsTime[snapName] = snap.CreationDate()
 		existDate, exists := sourceSnapshotsTime[snapName]
@@ -1408,7 +1397,7 @@ func containerCompareSnapshots(source container, target container) ([]container,
 	}
 
 	for _, snap := range sourceSnapshots {
-		_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 		existDate, exists := targetSnapshotsTime[snapName]
 		if !exists || existDate != snap.CreationDate() {
@@ -1673,7 +1662,7 @@ func containerDetermineNextSnapshotName(d *Daemon, c container, defaultPattern s
 	}
 
 	for _, snap := range snapshots {
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 		if snapOnlyName == pattern {
 			snapshotExists = true
 			break
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index aa4bcb7ff9..9ebdbd0e6d 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3878,7 +3878,7 @@ func (c *containerLXC) Delete() error {
 		_, poolName, _ := c.storage.GetContainerPoolInfo()
 
 		if c.IsSnapshot() {
-			cName, _, _ := containerGetParentAndSnapshotName(c.name)
+			cName, _, _ := shared.ContainerGetParentAndSnapshotName(c.name)
 			if shared.PathExists(shared.VarPath("storage-pools", poolName, "containers", cName, ".importing")) {
 				isImport = true
 			}
@@ -5240,7 +5240,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 	var endpoint string
 
 	if c.IsSnapshot() {
-		cName, sName, _ := containerGetParentAndSnapshotName(c.name)
+		cName, sName, _ := shared.ContainerGetParentAndSnapshotName(c.name)
 		endpoint = fmt.Sprintf("/1.0/containers/%s/snapshots/%s", cName, sName)
 	} else {
 		endpoint = fmt.Sprintf("/1.0/containers/%s", c.name)
@@ -5392,7 +5392,7 @@ func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
 		// Get the container's architecture
 		var arch string
 		if c.IsSnapshot() {
-			parentName, _, _ := containerGetParentAndSnapshotName(c.name)
+			parentName, _, _ := shared.ContainerGetParentAndSnapshotName(c.name)
 			parent, err := containerLoadByProjectAndName(c.state, c.project, parentName)
 			if err != nil {
 				ctw.Close()
diff --git a/lxd/container_snapshot.go b/lxd/container_snapshot.go
index 268a86d7f7..1a6384ec64 100644
--- a/lxd/container_snapshot.go
+++ b/lxd/container_snapshot.go
@@ -43,7 +43,7 @@ func containerSnapshotsGet(d *Daemon, r *http.Request) Response {
 		}
 
 		for _, snap := range snaps {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap)
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 			if project == "default" {
 				url := fmt.Sprintf("/%s/containers/%s/snapshots/%s", version.APIVersion, cname, snapName)
 				resultString = append(resultString, url)
@@ -325,7 +325,7 @@ func snapshotPost(d *Daemon, r *http.Request, sc container, containerName string
 		}
 
 		if reqNew.Live {
-			sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
+			sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 			if sourceName != reqNew.Name {
 				return BadRequest(fmt.Errorf(`Copying `+
 					`stateful containers requires that `+
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 3f0069916a..d6d6783959 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -531,7 +531,7 @@ func createFromCopy(d *Daemon, project string, req *api.ContainersPost) Response
 	}
 
 	if req.Stateful {
-		sourceName, _, _ := containerGetParentAndSnapshotName(source.Name())
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(source.Name())
 		if sourceName != req.Name {
 			return BadRequest(fmt.Errorf(`Copying stateful `+
 				`containers requires that source "%s" and `+
@@ -890,7 +890,7 @@ func clusterCopyContainerInternal(d *Daemon, source container, project string, r
 	// Setup websockets
 	var opAPI api.Operation
 	if shared.IsSnapshot(req.Source.Source) {
-		cName, sName, _ := containerGetParentAndSnapshotName(req.Source.Source)
+		cName, sName, _ := shared.ContainerGetParentAndSnapshotName(req.Source.Source)
 
 		pullReq := api.ContainerSnapshotPost{
 			Migration: true,
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index c2bda84afb..47e3e2d209 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -249,7 +249,7 @@ func (s *migrationSourceWs) preDumpLoop(args *preDumpLoopArgs) (bool, error) {
 	}
 
 	// Send the pre-dump.
-	ctName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+	ctName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 	state := s.container.DaemonState()
 	err = RsyncSend(ctName, shared.AddSlash(args.checkpointDir), s.criuConn, nil, args.rsyncFeatures, args.bwlimit, state.OS.ExecPath)
 	if err != nil {
@@ -657,7 +657,7 @@ func (s *migrationSourceWs) Do(migrateOp *operation) error {
 		 * no reason to do these in parallel. In the future when we're using
 		 * p.haul's protocol, it will make sense to do these in parallel.
 		 */
-		ctName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+		ctName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 		state := s.container.DaemonState()
 		err = RsyncSend(ctName, shared.AddSlash(checkpointDir), s.criuConn, nil, rsyncFeatures, bwlimit, state.OS.ExecPath)
 		if err != nil {
@@ -1152,7 +1152,7 @@ func migrationCompareSnapshots(sourceSnapshots []*migration.Snapshot, targetSnap
 	}
 
 	for _, snap := range targetSnapshots {
-		_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 		targetSnapshotsTime[snapName] = snap.CreationDate().Unix()
 		existDate, exists := sourceSnapshotsTime[snapName]
diff --git a/lxd/patches.go b/lxd/patches.go
index 6b2ab6438d..81d085fe32 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -3376,7 +3376,7 @@ func patchUpdateFromV11(_ *sql.Tx) error {
 	cNames := containers["default"]
 
 	for _, cName := range cNames {
-		snapParentName, snapOnlyName, _ := containerGetParentAndSnapshotName(cName)
+		snapParentName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(cName)
 		oldPath := shared.VarPath("containers", snapParentName, "snapshots", snapOnlyName)
 		newPath := shared.VarPath("snapshots", snapParentName, snapOnlyName)
 		if shared.PathExists(oldPath) && !shared.PathExists(newPath) {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index ef5bbf3285..b9e133dd16 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -777,7 +777,7 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
 	}
 
 	for _, vol := range volumes {
-		_, snapshotName, _ := containerGetParentAndSnapshotName(vol)
+		_, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(vol)
 		oldVolumeName := fmt.Sprintf("%s%s%s", s.volume.Name, shared.SnapshotDelimiter, snapshotName)
 		newVolumeName := fmt.Sprintf("%s%s%s", newName, shared.SnapshotDelimiter, snapshotName)
 
@@ -1025,7 +1025,7 @@ func (s *storageBtrfs) copySnapshot(target container, source container) error {
 	sourceContainerSubvolumeName := driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, sourceName)
 	targetContainerSubvolumeName := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetName)
 
-	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
+	targetParentName, _, _ := shared.ContainerGetParentAndSnapshotName(target.Name())
 	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
@@ -1104,7 +1104,7 @@ func (s *storageBtrfs) doCrossPoolContainerCopy(target container, source contain
 			}
 
 			// create snapshot
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			err = s.doContainerSnapshotCreate(target.Project(), fmt.Sprintf("%s/%s", target.Name(), snapOnlyName), target.Name())
 			if err != nil {
 				return err
@@ -1171,7 +1171,7 @@ func (s *storageBtrfs) ContainerCopy(target container, source container, contain
 			return err
 		}
 
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 		newSnapName := fmt.Sprintf("%s/%s", target.Name(), snapOnlyName)
 		targetSnapshot, err := containerLoadByProjectAndName(s.s, target.Project(), newSnapName)
 		if err != nil {
@@ -1440,7 +1440,7 @@ func btrfsSnapshotDeleteInternal(projectName, poolName string, snapshotName stri
 	os.Remove(sourceSnapshotMntPoint)
 	os.Remove(snapshotSubvolumeName)
 
-	sourceName, _, _ := containerGetParentAndSnapshotName(snapshotName)
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(snapshotName)
 	snapshotSubvolumePath := getSnapshotSubvolumePath(projectName, poolName, sourceName)
 	os.Remove(snapshotSubvolumePath)
 	if !shared.PathExists(snapshotSubvolumePath) {
@@ -1563,7 +1563,7 @@ func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer container)
 	}
 
 	// Create the snapshot subvole path on the storage pool.
-	sourceName, _, _ := containerGetParentAndSnapshotName(snapshotContainer.Name())
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(snapshotContainer.Name())
 	snapshotSubvolumePath := getSnapshotSubvolumePath(snapshotContainer.Project(), s.pool.Name, sourceName)
 	snapshotSubvolumeName := driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name, snapshotContainer.Name())
 	if !shared.PathExists(snapshotSubvolumePath) {
@@ -1636,7 +1636,7 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
 		}
 
 		for i, snap := range snapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 			// Figure out previous and current subvolumes
 			prev := ""
@@ -1720,7 +1720,7 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
 		}
 
 		for _, snap := range snapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 			// Mount the snapshot to a usable path
 			_, err := s.ContainerSnapshotStart(snap)
@@ -1811,7 +1811,7 @@ func (s *storageBtrfs) ContainerBackupCreate(backup backup, source container) er
 }
 
 func (s *storageBtrfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
-	containerName, _, _ := containerGetParentAndSnapshotName(info.Name)
+	containerName, _, _ := shared.ContainerGetParentAndSnapshotName(info.Name)
 
 	containerMntPoint := driver.GetContainerMountPoint("default", s.pool.Name, "")
 	unpackDir, err := ioutil.TempDir(containerMntPoint, containerName)
@@ -2492,7 +2492,7 @@ func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *
 	// Deal with sending a snapshot to create a container on another LXD
 	// instance.
 	if s.container.IsSnapshot() {
-		sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 		snapshotsPath := driver.GetSnapshotMountPoint(s.container.Project(), containerPool, sourceName)
 		tmpContainerMntPoint, err := ioutil.TempDir(snapshotsPath, sourceName)
 		if err != nil {
@@ -2574,7 +2574,7 @@ func (s *btrfsMigrationSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, b
 	}
 
 	s.stoppedSnapName = fmt.Sprintf("%s/.root", tmpPath)
-	parentName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+	parentName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 	containerMntPt := driver.GetContainerMountPoint(s.container.Project(), s.btrfs.pool.Name, parentName)
 	err = s.btrfs.btrfsPoolVolumesSnapshot(containerMntPt, s.stoppedSnapName, true, true)
 	if err != nil {
@@ -3030,7 +3030,7 @@ func (s *storageBtrfs) copyVolume(sourcePool string, sourceName string, targetNa
 
 	// Ensure that the directories immediately preceding the subvolume directory exist.
 	if isDstSnapshot {
-		volName, _, _ := containerGetParentAndSnapshotName(targetName)
+		volName, _, _ := shared.ContainerGetParentAndSnapshotName(targetName)
 		customDir = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, volName)
 	} else {
 		customDir = driver.GetStoragePoolVolumeMountPoint(s.pool.Name, "")
@@ -3093,7 +3093,7 @@ func (s *storageBtrfs) doCrossPoolVolumeCopy(sourcePool string, sourceName strin
 			}
 
 			// create snapshot
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 
 			err = s.doVolumeSnapshotCreate(s.pool.Name, s.volume.Name, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
 			if err != nil {
@@ -3156,7 +3156,7 @@ func (s *storageBtrfs) doVolumeSnapshotCreate(sourcePool string, sourceName stri
 		return err
 	}
 
-	_, _, ok := containerGetParentAndSnapshotName(targetName)
+	_, _, ok := shared.ContainerGetParentAndSnapshotName(targetName)
 	if !ok {
 		return err
 	}
@@ -3195,7 +3195,7 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 		return err
 	}
 
-	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
@@ -3220,7 +3220,7 @@ func (s *storageBtrfs) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageBtrfs) StoragePoolVolumeSnapshotRename(newName string) error {
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 
 	logger.Infof("Renaming BTRFS storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, fullSnapshotName)
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index dc8da5b1dc..bd7bbbd4e8 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -1060,7 +1060,7 @@ func (s *storageCeph) doCrossPoolContainerCopy(target container, source containe
 			logger.Debugf("Trying to freeze the filesystem: %s: %s", msg, fsFreezeErr)
 
 			// create snapshot
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			err = s.doContainerSnapshotCreate(target.Project(), fmt.Sprintf("%s/%s", target.Name(), snapOnlyName), target.Name())
 			if fsFreezeErr == nil {
 				msg, fsFreezeErr := shared.TryRunCommand("fsfreeze", "--unfreeze", destContainerMntPoint)
@@ -1193,11 +1193,11 @@ func (s *storageCeph) ContainerCopy(target container, source container,
 		for i, snap := range snapshots {
 			prev := ""
 			if i > 0 {
-				_, snapOnlyName, _ := containerGetParentAndSnapshotName(snapshots[i-1].Name())
+				_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snapshots[i-1].Name())
 				prev = fmt.Sprintf("snapshot_%s", snapOnlyName)
 			}
 
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			lastSnap = fmt.Sprintf("snapshot_%s", snapOnlyName)
 			sourceVolumeName := fmt.Sprintf(
 				"%s/container_%s at snapshot_%s",
@@ -1561,7 +1561,7 @@ func (s *storageCeph) ContainerRestore(target container, source container) error
 		defer target.StorageStart()
 	}
 
-	sourceContainerOnlyName, sourceSnapshotOnlyName, _ := containerGetParentAndSnapshotName(sourceName)
+	sourceContainerOnlyName, sourceSnapshotOnlyName, _ := shared.ContainerGetParentAndSnapshotName(sourceName)
 	prefixedSourceSnapOnlyName := fmt.Sprintf("snapshot_%s", sourceSnapshotOnlyName)
 	err = cephRBDVolumeRestore(s.ClusterName, s.OSDPoolName,
 		sourceContainerOnlyName, storagePoolVolumeTypeNameContainer,
@@ -1609,7 +1609,7 @@ func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer container) error
 
 	snapshotContainerName := snapshotContainer.Name()
 	sourceContainerName, sourceContainerSnapOnlyName, _ :=
-		containerGetParentAndSnapshotName(snapshotContainerName)
+		shared.ContainerGetParentAndSnapshotName(snapshotContainerName)
 	snapshotName := fmt.Sprintf("snapshot_%s", sourceContainerSnapOnlyName)
 
 	rbdVolumeExists := cephRBDSnapshotExists(s.ClusterName, s.OSDPoolName,
@@ -1676,10 +1676,10 @@ func (s *storageCeph) ContainerSnapshotRename(c container, newName string) error
 
 	revert := true
 
-	containerOnlyName, snapOnlyName, _ := containerGetParentAndSnapshotName(oldName)
+	containerOnlyName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(oldName)
 	containerOnlyName = project.Prefix(c.Project(), containerOnlyName)
 	oldSnapOnlyName := fmt.Sprintf("snapshot_%s", snapOnlyName)
-	_, newSnapOnlyName, _ := containerGetParentAndSnapshotName(newName)
+	_, newSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(newName)
 	newSnapOnlyName = fmt.Sprintf("snapshot_%s", newSnapOnlyName)
 	err := cephRBDVolumeSnapshotRename(s.ClusterName, s.OSDPoolName,
 		containerOnlyName, storagePoolVolumeTypeNameContainer, oldSnapOnlyName,
@@ -1724,7 +1724,7 @@ func (s *storageCeph) ContainerSnapshotStart(c container) (bool, error) {
 
 	revert := true
 
-	containerOnlyName, snapOnlyName, _ := containerGetParentAndSnapshotName(containerName)
+	containerOnlyName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 	containerOnlyName = project.Prefix(c.Project(), containerOnlyName)
 
 	// protect
@@ -1854,7 +1854,7 @@ func (s *storageCeph) ContainerSnapshotStop(c container) (bool, error) {
 
 	logger.Debugf("Unmounted %s", containerMntPoint)
 
-	containerOnlyName, snapOnlyName, _ := containerGetParentAndSnapshotName(containerName)
+	containerOnlyName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 	containerOnlyName = project.Prefix(c.Project(), containerOnlyName)
 	cloneName := fmt.Sprintf("%s_%s_start_clone", containerOnlyName, snapOnlyName)
 
@@ -2593,11 +2593,11 @@ func (s *storageCeph) StoragePoolVolumeCopy(source *api.StorageVolumeSource) err
 		for i, snap := range snapshots {
 			prev := ""
 			if i > 0 {
-				_, snapOnlyName, _ := containerGetParentAndSnapshotName(snapshots[i-1])
+				_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snapshots[i-1])
 				prev = fmt.Sprintf("snapshot_%s", snapOnlyName)
 			}
 
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 			lastSnap = fmt.Sprintf("snapshot_%s", snapOnlyName)
 			sourceVolumeName := fmt.Sprintf(
 				"%s/custom_%s at snapshot_%s",
@@ -2710,7 +2710,7 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 		}
 	}
 
-	sourceOnlyName, snapshotOnlyName, _ := containerGetParentAndSnapshotName(target.Name)
+	sourceOnlyName, snapshotOnlyName, _ := shared.ContainerGetParentAndSnapshotName(target.Name)
 	snapshotName := fmt.Sprintf("snapshot_%s", snapshotOnlyName)
 	err := cephRBDSnapshotCreate(s.ClusterName, s.OSDPoolName, sourceOnlyName, storagePoolVolumeTypeNameCustom, snapshotName, s.UserName)
 	if err != nil {
@@ -2730,7 +2730,7 @@ func (s *storageCeph) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeS
 }
 
 func (s *storageCeph) doPoolVolumeSnapshotDelete(name string) error {
-	sourceName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(name)
+	sourceName, snapshotOnlyName, ok := shared.ContainerGetParentAndSnapshotName(name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -2780,7 +2780,7 @@ func (s *storageCeph) StoragePoolVolumeSnapshotDelete() error {
 func (s *storageCeph) StoragePoolVolumeSnapshotRename(newName string) error {
 	logger.Infof("Renaming CEPH storage volume on OSD storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
 
-	sourceName, oldSnapOnlyName, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, oldSnapOnlyName, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index df4ee7fc32..70e37a3e82 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -80,7 +80,7 @@ func (s *rbdMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn,
 	if s.container.IsSnapshot() {
 		// ContainerSnapshotStart() will create the clone that is
 		// referenced by sendName here.
-		containerOnlyName, snapOnlyName, _ := containerGetParentAndSnapshotName(containerName)
+		containerOnlyName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 		sendName := fmt.Sprintf(
 			"%s/snapshots_%s_%s_start_clone",
 			s.ceph.OSDPoolName,
@@ -314,7 +314,7 @@ func (s *storageCeph) MigrationSink(conn *websocket.Conn, op *operation, args Mi
 		snaps, err := cephRBDVolumeListSnapshots(s.ClusterName, s.OSDPoolName, project.Prefix(args.Container.Project(), containerName), storagePoolVolumeTypeNameContainer, s.UserName)
 		if err == nil {
 			for _, snap := range snaps {
-				snapOnlyName, _, _ := containerGetParentAndSnapshotName(snap)
+				snapOnlyName, _, _ := shared.ContainerGetParentAndSnapshotName(snap)
 				if !strings.HasPrefix(snapOnlyName, "migration-send") {
 					continue
 				}
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 22ed7d4abe..104b151f4c 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -740,7 +740,7 @@ func (s *storageCeph) copyWithoutSnapshotsFull(target container,
 		targetContainerName)
 	if sourceIsSnapshot {
 		sourceContainerOnlyName, sourceSnapshotOnlyName, _ :=
-			containerGetParentAndSnapshotName(sourceContainerName)
+			shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 		oldVolumeName = fmt.Sprintf("%s/container_%s at snapshot_%s",
 			s.OSDPoolName, sourceContainerOnlyName,
 			sourceSnapshotOnlyName)
@@ -810,7 +810,7 @@ func (s *storageCeph) copyWithoutSnapshotsSparse(target container,
 		uuid.NewRandom().String())
 	if sourceIsSnapshot {
 		sourceContainerOnlyName, sourceSnapshotOnlyName, _ =
-			containerGetParentAndSnapshotName(sourceContainerName)
+			shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 		snapshotName = fmt.Sprintf("snapshot_%s", sourceSnapshotOnlyName)
 	} else {
 		// create snapshot
@@ -1606,7 +1606,7 @@ func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup, s
 	// Create a temporary snapshot
 	snapshotName := fmt.Sprintf("zombie_snapshot_%s", uuid.NewRandom().String())
 	if sourceIsSnapshot {
-		sourceContainerOnlyName, sourceSnapshotOnlyName, _ = containerGetParentAndSnapshotName(sourceContainerName)
+		sourceContainerOnlyName, sourceSnapshotOnlyName, _ = shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 		sourceContainerOnlyName = project.Prefix(source.Project(), sourceContainerOnlyName)
 		snapshotName = fmt.Sprintf("snapshot_%s", project.Prefix(source.Project(), sourceSnapshotOnlyName))
 	} else {
@@ -1679,7 +1679,7 @@ func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup, s
 	// Figure out the target name
 	targetName := sourceContainerName
 	if sourceIsSnapshot {
-		_, targetName, _ = containerGetParentAndSnapshotName(sourceContainerName)
+		_, targetName, _ = shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 	}
 
 	// Create the path for the backup.
@@ -1848,7 +1848,7 @@ func (s *storageCeph) doContainerSnapshotCreate(projectName, targetName string,
 
 	revert := true
 
-	_, targetSnapshotOnlyName, _ := containerGetParentAndSnapshotName(targetName)
+	_, targetSnapshotOnlyName, _ := shared.ContainerGetParentAndSnapshotName(targetName)
 	targetSnapshotName := fmt.Sprintf("snapshot_%s", targetSnapshotOnlyName)
 	err := cephRBDSnapshotCreate(s.ClusterName, s.OSDPoolName,
 		project.Prefix(projectName, sourceName), storagePoolVolumeTypeNameContainer,
@@ -1873,7 +1873,7 @@ func (s *storageCeph) doContainerSnapshotCreate(projectName, targetName string,
 	}()
 
 	targetContainerMntPoint := driver.GetSnapshotMountPoint(projectName, s.pool.Name, targetName)
-	sourceOnlyName, _, _ := containerGetParentAndSnapshotName(sourceName)
+	sourceOnlyName, _, _ := shared.ContainerGetParentAndSnapshotName(sourceName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(projectName, sourceOnlyName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(projectName, sourceOnlyName))
 	err = createSnapshotMountpoint(targetContainerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1933,7 +1933,7 @@ func (s *storageCeph) doCrossPoolVolumeCopy(source *api.StorageVolumeSource) err
 
 	if !source.VolumeOnly {
 		for _, snap := range snapshots {
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 			srcSnapshotMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(source.Pool, snap)
 
 			_, err = rsyncLocalCopy(srcSnapshotMntPoint, dstVolumeMntPoint, bwlimit, true)
@@ -1972,7 +1972,7 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSo
 	isSnapshot := shared.IsSnapshot(source.Name)
 
 	if isSnapshot {
-		_, srcSnapshotOnlyName, _ := containerGetParentAndSnapshotName(source.Name)
+		_, srcSnapshotOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name)
 		oldVolumeName = fmt.Sprintf("%s/snapshot_%s", s.OSDPoolName, srcSnapshotOnlyName)
 	} else {
 		oldVolumeName = fmt.Sprintf("%s/custom_%s", s.OSDPoolName, source.Name)
@@ -2004,7 +2004,7 @@ func (s *storageCeph) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSo
 }
 
 func (s *storageCeph) copyVolumeWithoutSnapshotsSparse(source *api.StorageVolumeSource) error {
-	sourceOnlyName, snapshotOnlyName, isSnapshot := containerGetParentAndSnapshotName(source.Name)
+	sourceOnlyName, snapshotOnlyName, isSnapshot := shared.ContainerGetParentAndSnapshotName(source.Name)
 
 	if isSnapshot {
 		snapshotOnlyName = fmt.Sprintf("snapshot_%s", snapshotOnlyName)
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 1732289255..305de37498 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -802,7 +802,7 @@ func (s *storageCephFs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) e
 		}
 
 		for _, snap := range snapshots {
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 			err = s.copyVolume(source.Pool, snap, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
 			if err != nil {
 				return err
@@ -850,7 +850,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolum
 	}
 
 	// Parse the name
-	sourceName, snapName, ok := containerGetParentAndSnapshotName(target.Name)
+	sourceName, snapName, ok := shared.ContainerGetParentAndSnapshotName(target.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -890,7 +890,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotDelete() error {
 	}
 
 	// Parse the name
-	sourceName, snapName, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, snapName, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -932,7 +932,7 @@ func (s *storageCephFs) StoragePoolVolumeSnapshotRename(newName string) error {
 	}
 
 	// Rename the snapshot entry
-	sourceName, oldSnapName, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, oldSnapName, _ := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, sourceName)
 	oldCephSnapPath := filepath.Join(sourcePath, ".snap", oldSnapName)
 	newCephSnapPath := filepath.Join(sourcePath, ".snap", newName)
@@ -976,7 +976,7 @@ func (s *storageCephFs) copyVolume(sourcePool string, source string, target stri
 	}
 
 	// Split target name
-	targetVolName, targetSnapName, ok := containerGetParentAndSnapshotName(target)
+	targetVolName, targetSnapName, ok := shared.ContainerGetParentAndSnapshotName(target)
 
 	// Figure out target path
 	dstMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, targetVolName)
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 04dfcb9a8a..21646c6111 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -687,7 +687,7 @@ func (s *storageDir) copySnapshot(target container, targetPool string, source co
 	sourceContainerMntPoint := driver.GetSnapshotMountPoint(source.Project(), sourcePool, sourceName)
 	targetContainerMntPoint := driver.GetSnapshotMountPoint(target.Project(), targetPool, targetName)
 
-	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
+	targetParentName, _, _ := shared.ContainerGetParentAndSnapshotName(target.Name())
 	containersPath := driver.GetSnapshotMountPoint(target.Project(), targetPool, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", targetPool, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
@@ -788,7 +788,7 @@ func (s *storageDir) doContainerCopy(target container, source container, contain
 			return err
 		}
 
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 		newSnapName := fmt.Sprintf("%s/%s", target.Name(), snapOnlyName)
 		targetSnapshot, err := containerLoadByProjectAndName(s.s, source.Project(), newSnapName)
 		if err != nil {
@@ -1023,7 +1023,7 @@ func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer container) e
 	// exists and if not create it.
 	targetContainerMntPoint = driver.GetSnapshotMountPoint(snapshotContainer.Project(), s.pool.Name,
 		targetContainerName)
-	sourceName, _, _ := containerGetParentAndSnapshotName(targetContainerName)
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(targetContainerName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools",
 		s.pool.Name, "containers-snapshots", project.Prefix(snapshotContainer.Project(), sourceName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(snapshotContainer.Project(), sourceName))
@@ -1048,7 +1048,7 @@ func dirSnapshotDeleteInternal(projectName, poolName string, snapshotName string
 		}
 	}
 
-	sourceContainerName, _, _ := containerGetParentAndSnapshotName(snapshotName)
+	sourceContainerName, _, _ := shared.ContainerGetParentAndSnapshotName(snapshotName)
 	snapshotContainerPath := driver.GetSnapshotMountPoint(projectName, poolName, sourceContainerName)
 	empty, _ := shared.PathIsEmpty(snapshotContainerPath)
 	if empty == true {
@@ -1169,7 +1169,7 @@ func (s *storageDir) ContainerBackupCreate(backup backup, source container) erro
 		}
 
 		for _, snap := range snapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			snapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
@@ -1427,7 +1427,7 @@ func (s *storageDir) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 	}
 
 	for _, snap := range snapshots {
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap)
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap)
 		err = s.copyVolumeSnapshot(source.Pool, snap, fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
 		if err != nil {
 			return err
@@ -1459,7 +1459,7 @@ func (s *storageDir) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 		return fmt.Errorf("no \"source\" property found for the storage pool")
 	}
 
-	sourceName, _, ok := containerGetParentAndSnapshotName(target.Name)
+	sourceName, _, ok := shared.ContainerGetParentAndSnapshotName(target.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -1495,7 +1495,7 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 		return err
 	}
 
-	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	storageVolumeSnapshotPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
@@ -1517,7 +1517,7 @@ func (s *storageDir) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageDir) StoragePoolVolumeSnapshotRename(newName string) error {
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 
 	logger.Infof("Renaming DIR storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, fullSnapshotName)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 7991f4ecac..1a52f99e54 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -897,7 +897,7 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error {
 			s.volume.Name, newName, err)
 	}
 
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -958,7 +958,7 @@ func (s *storageLvm) ContainerCreate(container container) error {
 
 	if container.IsSnapshot() {
 		containerMntPoint := driver.GetSnapshotMountPoint(container.Project(), s.pool.Name, containerName)
-		sourceName, _, _ := containerGetParentAndSnapshotName(containerName)
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(container.Project(), sourceName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(container.Project(), sourceName))
 		err := os.MkdirAll(containerMntPoint, 0711)
@@ -1093,7 +1093,7 @@ func lvmContainerDeleteInternal(projectName, poolName string, ctName string, isS
 
 	var err error
 	if isSnapshot {
-		sourceName, _, _ := containerGetParentAndSnapshotName(ctName)
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(ctName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", poolName, "containers-snapshots", project.Prefix(projectName, sourceName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(projectName, sourceName))
 		err = deleteSnapshotMountpoint(containerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -1193,7 +1193,7 @@ func (s *storageLvm) doContainerCopy(target container, source container, contain
 	}
 
 	for _, snap := range snapshots {
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 		newSnapName := fmt.Sprintf("%s/%s", target.Name(), snapOnlyName)
 
 		logger.Debugf("Copying LVM container storage for snapshot %s to %s", snap.Name(), newSnapName)
@@ -1711,7 +1711,7 @@ func (s *storageLvm) ContainerBackupCreate(backup backup, source container) erro
 		}
 
 		for _, snap := range snapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			snapshotMntPoint := driver.GetSnapshotMountPoint(snap.Project(), s.pool.Name, snap.Name())
 			target := fmt.Sprintf("%s/%s", snapshotsPath, snapName)
 
@@ -1848,7 +1848,7 @@ func (s *storageLvm) doContainerBackupLoad(projectName, containerName string, pr
 		err = lvmCreateLv(projectName, poolName, thinPoolName, containerLvmName, lvFsType, lvSize,
 			storagePoolVolumeAPIEndpointContainers, s.useThinpool)
 	} else {
-		cname, _, _ := containerGetParentAndSnapshotName(containerName)
+		cname, _, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 		_, err = s.createSnapshotLV(projectName, poolName, cname, storagePoolVolumeAPIEndpointContainers,
 			containerLvmName, storagePoolVolumeAPIEndpointContainers, false, s.useThinpool)
 	}
@@ -1875,7 +1875,7 @@ func (s *storageLvm) doContainerBackupLoad(projectName, containerName string, pr
 	}
 
 	if snapshot {
-		cname, _, _ := containerGetParentAndSnapshotName(containerName)
+		cname, _, _ := shared.ContainerGetParentAndSnapshotName(containerName)
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(projectName, cname))
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(projectName, cname))
 		err = createSnapshotMountpoint(containerMntPoint, snapshotMntPointSymlinkTarget,
@@ -2273,7 +2273,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 	logger.Debugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
 	poolName := s.getOnDiskPoolName()
-	sourceOnlyName, _, ok := containerGetParentAndSnapshotName(target.Name)
+	sourceOnlyName, _, ok := shared.ContainerGetParentAndSnapshotName(target.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot")
 	}
@@ -2324,7 +2324,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 		return err
 	}
 
-	sourceName, _, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	storageVolumeSnapshotPath = driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, sourceName)
 	empty, err := shared.PathIsEmpty(storageVolumeSnapshotPath)
 	if err == nil && empty {
@@ -2346,7 +2346,7 @@ func (s *storageLvm) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageLvm) StoragePoolVolumeSnapshotRename(newName string) error {
-	sourceName, _, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, _, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 
 	logger.Infof("Renaming LVM storage volume on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, fullSnapshotName)
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 46ce0565fc..ff92174139 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -285,7 +285,7 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer container, source
 	}
 	if targetIsSnapshot {
 		targetContainerMntPoint = driver.GetSnapshotMountPoint(sourceContainer.Project(), s.pool.Name, targetContainerName)
-		sourceName, _, _ := containerGetParentAndSnapshotName(sourceContainerName)
+		sourceName, _, _ := shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 		snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(sourceContainer.Project(), sourceName))
 		snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(sourceContainer.Project(), sourceName))
 		err = createSnapshotMountpoint(targetContainerMntPoint, snapshotMntPointSymlinkTarget, snapshotMntPointSymlink)
@@ -347,7 +347,7 @@ func (s *storageLvm) copySnapshot(target container, source container, refresh bo
 		return err
 	}
 
-	targetParentName, _, _ := containerGetParentAndSnapshotName(target.Name())
+	targetParentName, _, _ := shared.ContainerGetParentAndSnapshotName(target.Name())
 	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
@@ -972,7 +972,7 @@ func (s *storageLvm) copyVolume(sourcePool string, source string) error {
 }
 
 func (s *storageLvm) copyVolumeSnapshot(sourcePool string, source string) error {
-	_, snapOnlyName, _ := containerGetParentAndSnapshotName(source)
+	_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source)
 	target := fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName)
 	targetMntPoint := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
 
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 82d09dffee..0802a44326 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -90,7 +90,7 @@ func (s rsyncStorageSourceDriver) SendStorageVolume(conn *websocket.Conn, op *op
 }
 
 func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string, containerOnly bool) error {
-	ctName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+	ctName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 
 	if !containerOnly {
 		for _, send := range s.snapshots {
@@ -129,7 +129,7 @@ func (s rsyncStorageSourceDriver) SendWhileRunning(conn *websocket.Conn, op *ope
 }
 
 func (s rsyncStorageSourceDriver) SendAfterCheckpoint(conn *websocket.Conn, bwlimit string) error {
-	ctName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+	ctName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 	// resync anything that changed between our first send and the checkpoint
 	state := s.container.DaemonState()
 	return RsyncSend(project.Prefix(s.container.Project(), ctName), shared.AddSlash(s.container.Path()), conn, nil, s.rsyncFeatures, bwlimit, state.OS.ExecPath)
@@ -152,7 +152,7 @@ func rsyncRefreshSource(refreshSnapshots []string, args MigrationSourceArgs) (Mi
 		}
 
 		for _, snap := range allSnapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			if !shared.StringInSlice(snapName, refreshSnapshots) {
 				continue
 			}
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index 444ad2195b..e122cdcf87 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -111,7 +111,7 @@ func storagePoolUsedByGet(state *state.State, poolID int64, poolName string) ([]
 		switch apiEndpoint {
 		case storagePoolVolumeAPIEndpointContainers:
 			if strings.Index(volumes[i].Name, shared.SnapshotDelimiter) > 0 {
-				parentName, snapOnlyName, _ := containerGetParentAndSnapshotName(volumes[i].Name)
+				parentName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(volumes[i].Name)
 				poolUsedBy[i] = fmt.Sprintf("/%s/containers/%s/snapshots/%s", version.APIVersion, parentName, snapOnlyName)
 			} else {
 				poolUsedBy[i] = fmt.Sprintf("/%s/containers/%s", version.APIVersion, volumes[i].Name)
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index ce02541471..815b32064f 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -123,7 +123,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) Response {
 		}
 
 		if !recursion {
-			volName, snapName, ok := containerGetParentAndSnapshotName(volume.Name)
+			volName, snapName, ok := shared.ContainerGetParentAndSnapshotName(volume.Name)
 			if ok {
 				resultString = append(resultString,
 					fmt.Sprintf("/%s/storage-pools/%s/volumes/%s/%s/snapshots/%s",
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 6de54b156b..8c3c8b6de3 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -199,7 +199,7 @@ func storagePoolVolumeSnapshotsTypeGet(d *Daemon, r *http.Request) Response {
 	resultString := []string{}
 	resultMap := []*api.StorageVolumeSnapshot{}
 	for _, volume := range volumes {
-		_, snapshotName, _ := containerGetParentAndSnapshotName(volume)
+		_, snapshotName, _ := shared.ContainerGetParentAndSnapshotName(volume)
 
 		if !recursion {
 			apiEndpoint, err := storagePoolVolumeTypeToAPIEndpoint(volumeType)
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index f7d32012b0..1face018c0 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -433,7 +433,7 @@ func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State,
 func storagePoolVolumeUsedByGet(s *state.State, project, poolName string, volumeName string, volumeTypeName string) ([]string, error) {
 	// Handle container volumes
 	if volumeTypeName == "container" {
-		cName, sName, snap := containerGetParentAndSnapshotName(volumeName)
+		cName, sName, snap := shared.ContainerGetParentAndSnapshotName(volumeName)
 
 		if snap {
 			return []string{fmt.Sprintf("/%s/containers/%s/snapshots/%s", version.APIVersion, cName, sName)}, nil
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 412b7a396d..97b2901923 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -937,7 +937,7 @@ func (s *storageZfs) copyWithoutSnapshotsSparse(target container, source contain
 
 	sourceZfsDataset := ""
 	sourceZfsDatasetSnapshot := ""
-	sourceName, sourceSnapOnlyName, isSnapshotName := containerGetParentAndSnapshotName(sourceContainerName)
+	sourceName, sourceSnapOnlyName, isSnapshotName := shared.ContainerGetParentAndSnapshotName(sourceContainerName)
 
 	targetZfsDataset := fmt.Sprintf("containers/%s", project.Prefix(target.Project(), targetContainerName))
 
@@ -1042,7 +1042,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 	targetSnapshotDataset := ""
 
 	if sourceIsSnapshot {
-		sourceParentName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(source.Name())
+		sourceParentName, sourceSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name())
 		snapshotSuffix = fmt.Sprintf("snapshot-%s", sourceSnapOnlyName)
 		sourceDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, project.Prefix(source.Project(), sourceParentName), snapshotSuffix)
 		targetSnapshotDataset = fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, project.Prefix(target.Project(), targetName), sourceSnapOnlyName)
@@ -1130,7 +1130,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target container, source container)
 
 func (s *storageZfs) copyWithSnapshots(target container, source container, parentSnapshot string) error {
 	sourceName := source.Name()
-	targetParentName, targetSnapOnlyName, _ := containerGetParentAndSnapshotName(target.Name())
+	targetParentName, targetSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(target.Name())
 	containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
 	snapshotMntPointSymlinkTarget := shared.VarPath("storage-pools", s.pool.Name, "containers-snapshots", project.Prefix(target.Project(), targetParentName))
 	snapshotMntPointSymlink := shared.VarPath("snapshots", project.Prefix(target.Project(), targetParentName))
@@ -1140,11 +1140,11 @@ func (s *storageZfs) copyWithSnapshots(target container, source container, paren
 	}
 
 	poolName := s.getOnDiskPoolName()
-	sourceParentName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(sourceName)
+	sourceParentName, sourceSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(sourceName)
 	currentSnapshotDataset := fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, project.Prefix(source.Project(), sourceParentName), sourceSnapOnlyName)
 	args := []string{"send", currentSnapshotDataset}
 	if parentSnapshot != "" {
-		parentName, parentSnaponlyName, _ := containerGetParentAndSnapshotName(parentSnapshot)
+		parentName, parentSnaponlyName, _ := shared.ContainerGetParentAndSnapshotName(parentSnapshot)
 		parentSnapshotDataset := fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, project.Prefix(source.Project(), parentName), parentSnaponlyName)
 		args = append(args, "-i", parentSnapshotDataset)
 	}
@@ -1235,7 +1235,7 @@ func (s *storageZfs) doCrossPoolContainerCopy(target container, source container
 			}
 
 			// create snapshot
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			err = s.doContainerSnapshotCreate(snap.Project(), fmt.Sprintf("%s/%s", target.Name(), snapOnlyName), target.Name())
 			if err != nil {
 				return err
@@ -1308,7 +1308,7 @@ func (s *storageZfs) ContainerCopy(target container, source container, container
 				return err
 			}
 
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			prevSnapOnlyName = snapOnlyName
 			newSnapName := fmt.Sprintf("%s/%s", target.Name(), snapOnlyName)
 			targetSnapshot, err := containerLoadByProjectAndName(s.s, target.Project(), newSnapName)
@@ -1530,7 +1530,7 @@ func (s *storageZfs) ContainerRestore(target container, source container) error
 	}
 
 	// Restore the snapshot
-	cName, snapOnlyName, _ := containerGetParentAndSnapshotName(source.Name())
+	cName, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name())
 	snapName := fmt.Sprintf("snapshot-%s", snapOnlyName)
 
 	err = zfsPoolVolumeSnapshotRestore(s.getOnDiskPoolName(), fmt.Sprintf("containers/%s", project.Prefix(source.Project(), cName)), snapName)
@@ -1591,7 +1591,7 @@ func (s *storageZfs) doContainerSnapshotCreate(projectName, targetName string, s
 
 	sourceContainerName := sourceName
 
-	cName, snapshotSnapOnlyName, _ := containerGetParentAndSnapshotName(snapshotContainerName)
+	cName, snapshotSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snapshotContainerName)
 	snapName := fmt.Sprintf("snapshot-%s", snapshotSnapOnlyName)
 
 	sourceZfsDataset := fmt.Sprintf("containers/%s", project.Prefix(projectName, cName))
@@ -1631,7 +1631,7 @@ func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer container, source
 }
 
 func zfsSnapshotDeleteInternal(projectName, poolName string, ctName string, onDiskPoolName string) error {
-	sourceContainerName, sourceContainerSnapOnlyName, _ := containerGetParentAndSnapshotName(ctName)
+	sourceContainerName, sourceContainerSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(ctName)
 	snapName := fmt.Sprintf("snapshot-%s", sourceContainerSnapOnlyName)
 
 	if zfsFilesystemEntityExists(onDiskPoolName,
@@ -1734,10 +1734,10 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 
 	oldName := snapshotContainer.Name()
 
-	oldcName, oldSnapOnlyName, _ := containerGetParentAndSnapshotName(snapshotContainer.Name())
+	oldcName, oldSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snapshotContainer.Name())
 	oldZfsDatasetName := fmt.Sprintf("snapshot-%s", oldSnapOnlyName)
 
-	_, newSnapOnlyName, _ := containerGetParentAndSnapshotName(newName)
+	_, newSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(newName)
 	newZfsDatasetName := fmt.Sprintf("snapshot-%s", newSnapOnlyName)
 
 	if oldZfsDatasetName != newZfsDatasetName {
@@ -1797,7 +1797,7 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer container, newNam
 func (s *storageZfs) ContainerSnapshotStart(container container) (bool, error) {
 	logger.Debugf("Initializing ZFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	cName, sName, _ := containerGetParentAndSnapshotName(container.Name())
+	cName, sName, _ := shared.ContainerGetParentAndSnapshotName(container.Name())
 	sourceFs := fmt.Sprintf("containers/%s", project.Prefix(container.Project(), cName))
 	sourceSnap := fmt.Sprintf("snapshot-%s", sName)
 	destFs := fmt.Sprintf("snapshots/%s/%s", project.Prefix(container.Project(), cName), sName)
@@ -1821,7 +1821,7 @@ func (s *storageZfs) ContainerSnapshotStart(container container) (bool, error) {
 func (s *storageZfs) ContainerSnapshotStop(container container) (bool, error) {
 	logger.Debugf("Stopping ZFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	cName, sName, _ := containerGetParentAndSnapshotName(container.Name())
+	cName, sName, _ := shared.ContainerGetParentAndSnapshotName(container.Name())
 	destFs := fmt.Sprintf("snapshots/%s/%s", project.Prefix(container.Project(), cName), sName)
 
 	err := zfsPoolVolumeDestroy(s.getOnDiskPoolName(), destFs)
@@ -1847,7 +1847,7 @@ func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup, source
 	snapshotSuffix := ""
 
 	if sourceIsSnapshot {
-		sourceParentName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(source.Name())
+		sourceParentName, sourceSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name())
 		snapshotSuffix = fmt.Sprintf("backup-%s", sourceSnapOnlyName)
 		sourceDataset = fmt.Sprintf("%s/containers/%s@%s", poolName, project.Prefix(source.Project(), sourceParentName), snapshotSuffix)
 	} else {
@@ -1897,11 +1897,11 @@ func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup, source cont
 	}
 
 	poolName := s.getOnDiskPoolName()
-	sourceParentName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(sourceName)
+	sourceParentName, sourceSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(sourceName)
 	currentSnapshotDataset := fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, project.Prefix(source.Project(), sourceParentName), sourceSnapOnlyName)
 	args := []string{"send", currentSnapshotDataset}
 	if parentSnapshot != "" {
-		parentName, parentSnaponlyName, _ := containerGetParentAndSnapshotName(parentSnapshot)
+		parentName, parentSnaponlyName, _ := shared.ContainerGetParentAndSnapshotName(parentSnapshot)
 		parentSnapshotDataset := fmt.Sprintf("%s/containers/%s at snapshot-%s", poolName, project.Prefix(source.Project(), parentName), parentSnaponlyName)
 		args = append(args, "-i", parentSnapshotDataset)
 	}
@@ -1940,7 +1940,7 @@ func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup bac
 				return err
 			}
 
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 			prevSnapOnlyName = snapOnlyName
 			err = s.doSnapshotBackup(tmpPath, backup, sourceSnapshot, prev)
 			if err != nil {
@@ -2020,7 +2020,7 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
 		}
 
 		for _, snap := range snapshots {
-			_, snapName, _ := containerGetParentAndSnapshotName(snap.Name())
+			_, snapName, _ := shared.ContainerGetParentAndSnapshotName(snap.Name())
 
 			// Mount the snapshot to a usable path
 			_, err := s.ContainerSnapshotStart(snap)
@@ -2130,7 +2130,7 @@ func (s *storageZfs) ContainerBackupCreate(backup backup, source container) erro
 }
 
 func (s *storageZfs) doContainerBackupLoadOptimized(info backupInfo, data io.ReadSeeker, tarArgs []string) error {
-	containerName, _, _ := containerGetParentAndSnapshotName(info.Name)
+	containerName, _, _ := shared.ContainerGetParentAndSnapshotName(info.Name)
 	containerMntPoint := driver.GetContainerMountPoint(info.Project, s.pool.Name, containerName)
 	err := createContainerMountpoint(containerMntPoint, driver.ContainerPath(info.Name, false), info.Privileged)
 	if err != nil {
@@ -2517,7 +2517,7 @@ type zfsMigrationSourceDriver struct {
 }
 
 func (s *zfsMigrationSourceDriver) send(conn *websocket.Conn, zfsName string, zfsParent string, readWrapper func(io.ReadCloser) io.ReadCloser) error {
-	sourceParentName, _, _ := containerGetParentAndSnapshotName(s.container.Name())
+	sourceParentName, _, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 	poolName := s.zfs.getOnDiskPoolName()
 	args := []string{"send"}
 
@@ -2572,7 +2572,7 @@ func (s *zfsMigrationSourceDriver) send(conn *websocket.Conn, zfsName string, zf
 
 func (s *zfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operation, bwlimit string, containerOnly bool) error {
 	if s.container.IsSnapshot() {
-		_, snapOnlyName, _ := containerGetParentAndSnapshotName(s.container.Name())
+		_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(s.container.Name())
 		snapshotName := fmt.Sprintf("snapshot-%s", snapOnlyName)
 		wrapper := StorageProgressReader(op, "fs_progress", s.container.Name())
 		return s.send(conn, snapshotName, "", wrapper)
@@ -2972,7 +2972,7 @@ func (s *storageZfs) doCrossPoolStorageVolumeCopy(source *api.StorageVolumeSourc
 				return err
 			}
 
-			_, snapOnlyName, _ := containerGetParentAndSnapshotName(source.Name)
+			_, snapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name)
 
 			s.StoragePoolVolumeSnapshotCreate(&api.StorageVolumeSnapshotsPost{Name: fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName)})
 		}
@@ -3008,7 +3008,7 @@ func (s *storageZfs) copyVolumeWithoutSnapshotsFull(source *api.StorageVolumeSou
 	poolName := s.getOnDiskPoolName()
 
 	if sourceIsSnapshot {
-		sourceVolumeName, sourceSnapOnlyName, _ := containerGetParentAndSnapshotName(source.Name)
+		sourceVolumeName, sourceSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(source.Name)
 		snapshotSuffix = fmt.Sprintf("snapshot-%s", sourceSnapOnlyName)
 		sourceDataset = fmt.Sprintf("%s/custom/%s@%s", source.Pool, sourceVolumeName, snapshotSuffix)
 		targetSnapshotDataset = fmt.Sprintf("%s/custom/%s at snapshot-%s", poolName, s.volume.Name, sourceSnapOnlyName)
@@ -3091,7 +3091,7 @@ func (s *storageZfs) copyVolumeWithoutSnapshotsSparse(source *api.StorageVolumeS
 
 	sourceZfsDataset := ""
 	sourceZfsDatasetSnapshot := ""
-	sourceName, sourceSnapOnlyName, isSnapshotName := containerGetParentAndSnapshotName(sourceVolumeName)
+	sourceName, sourceSnapOnlyName, isSnapshotName := shared.ContainerGetParentAndSnapshotName(sourceVolumeName)
 
 	targetZfsDataset := fmt.Sprintf("custom/%s", targetVolumeName)
 
@@ -3342,7 +3342,7 @@ func (s *storageZfs) StorageMigrationSink(conn *websocket.Conn, op *operation, a
 func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSnapshotsPost) error {
 	logger.Infof("Creating ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	sourceOnlyName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(target.Name)
+	sourceOnlyName, snapshotOnlyName, ok := shared.ContainerGetParentAndSnapshotName(target.Name)
 	if !ok {
 		return fmt.Errorf("Not a snapshot name")
 	}
@@ -3370,7 +3370,7 @@ func (s *storageZfs) StoragePoolVolumeSnapshotCreate(target *api.StorageVolumeSn
 func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
 	logger.Infof("Deleting ZFS storage volume snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
 
-	sourceName, snapshotOnlyName, _ := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, snapshotOnlyName, _ := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	snapshotName := fmt.Sprintf("snapshot-%s", snapshotOnlyName)
 
 	onDiskPoolName := s.getOnDiskPoolName()
@@ -3417,7 +3417,7 @@ func (s *storageZfs) StoragePoolVolumeSnapshotDelete() error {
 }
 
 func (s *storageZfs) StoragePoolVolumeSnapshotRename(newName string) error {
-	sourceName, snapshotOnlyName, ok := containerGetParentAndSnapshotName(s.volume.Name)
+	sourceName, snapshotOnlyName, ok := shared.ContainerGetParentAndSnapshotName(s.volume.Name)
 	fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, shared.SnapshotDelimiter, newName)
 
 	logger.Infof("Renaming ZFS storage volume snapshot on storage pool \"%s\" from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, fullSnapshotName)
diff --git a/shared/container.go b/shared/container.go
index 7abf044398..b3ec158370 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -410,3 +410,14 @@ func ConfigKeyChecker(key string) (func(value string) error, error) {
 
 	return nil, fmt.Errorf("Unknown configuration key: %s", key)
 }
+
+// ContainerGetParentAndSnapshotName returns the parent container name, snapshot
+// name, and whether it actually was a snapshot name.
+func ContainerGetParentAndSnapshotName(name string) (string, string, bool) {
+	fields := strings.SplitN(name, SnapshotDelimiter, 2)
+	if len(fields) == 1 {
+		return name, "", false
+	}
+
+	return fields[0], fields[1], true
+}


More information about the lxc-devel mailing list