[lxc-devel] [lxd/master] Storage: Generic VFS functions

tomponline on Github lxc-bot at linuxcontainers.org
Thu Jan 16 17:51:35 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 499 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200116/c888dc2e/attachment-0001.bin>
-------------- next part --------------
From 3bcc775644dbcbea3f3589b551564b3b69913ec1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 16 Jan 2020 17:48:04 +0000
Subject: [PATCH 1/3] lxd/storage/drivers/driver/common: Removes generic vfs
 functions as not common to all driver types

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_common.go | 229 ---------------------------
 1 file changed, 229 deletions(-)

diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index baa353abee..cc42344d8a 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -2,21 +2,12 @@ package drivers
 
 import (
 	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
 	"strings"
 
 	"github.com/pkg/errors"
 
 	"github.com/lxc/lxd/lxd/migration"
-	"github.com/lxc/lxd/lxd/operations"
-	"github.com/lxc/lxd/lxd/rsync"
 	"github.com/lxc/lxd/lxd/state"
-	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/api"
-	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -183,223 +174,3 @@ func (d *common) ApplyPatch(name string) error {
 
 	return patch()
 }
-
-// vfsGetResources is a generic GetResources implementation for VFS-only drivers.
-func (d *common) vfsGetResources() (*api.ResourcesStoragePool, error) {
-	// Get the VFS information
-	st, err := shared.Statvfs(GetPoolMountPath(d.name))
-	if err != nil {
-		return nil, err
-	}
-
-	// Fill in the struct
-	res := api.ResourcesStoragePool{}
-	res.Space.Total = st.Blocks * uint64(st.Bsize)
-	res.Space.Used = (st.Blocks - st.Bfree) * uint64(st.Bsize)
-
-	// Some filesystems don't report inodes since they allocate them
-	// dynamically e.g. btrfs.
-	if st.Files > 0 {
-		res.Inodes.Total = st.Files
-		res.Inodes.Used = st.Files - st.Ffree
-	}
-
-	return &res, nil
-}
-
-// vfsRenameVolume is a generic RenameVolume implementation for VFS-only drivers.
-func (d *common) vfsRenameVolume(vol Volume, newVolName string, op *operations.Operation) error {
-	// Rename the volume itself.
-	srcVolumePath := GetVolumeMountPath(d.name, vol.volType, vol.name)
-	dstVolumePath := GetVolumeMountPath(d.name, vol.volType, newVolName)
-
-	err := os.Rename(srcVolumePath, dstVolumePath)
-	if err != nil {
-		return errors.Wrapf(err, "Failed to rename '%s' to '%s'", srcVolumePath, dstVolumePath)
-	}
-
-	revertRename := true
-	defer func() {
-		if !revertRename {
-			return
-		}
-
-		os.Rename(dstVolumePath, srcVolumePath)
-	}()
-
-	// And if present, the snapshots too.
-	srcSnapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, vol.name)
-	dstSnapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, newVolName)
-
-	if shared.PathExists(srcSnapshotDir) {
-		err = os.Rename(srcSnapshotDir, dstSnapshotDir)
-		if err != nil {
-			return errors.Wrapf(err, "Failed to rename '%s' to '%s'", srcSnapshotDir, dstSnapshotDir)
-		}
-	}
-
-	revertRename = false
-	return nil
-}
-
-// vfsVolumeSnapshots is a generic VolumeSnapshots implementation for VFS-only drivers.
-func (d *common) vfsVolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error) {
-	snapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, vol.name)
-	snapshots := []string{}
-
-	ents, err := ioutil.ReadDir(snapshotDir)
-	if err != nil {
-		// If the snapshots directory doesn't exist, there are no snapshots.
-		if os.IsNotExist(err) {
-			return snapshots, nil
-		}
-
-		return nil, errors.Wrapf(err, "Failed to list directory '%s'", snapshotDir)
-	}
-
-	for _, ent := range ents {
-		fileInfo, err := os.Stat(filepath.Join(snapshotDir, ent.Name()))
-		if err != nil {
-			return nil, err
-		}
-
-		if !fileInfo.IsDir() {
-			continue
-		}
-
-		snapshots = append(snapshots, ent.Name())
-	}
-
-	return snapshots, nil
-}
-
-// vfsRenameVolumeSnapshot is a generic RenameVolumeSnapshot implementation for VFS-only drivers.
-func (d *common) vfsRenameVolumeSnapshot(snapVol Volume, newSnapshotName string, op *operations.Operation) error {
-	parentName, _, _ := shared.InstanceGetParentAndSnapshotName(snapVol.name)
-	oldPath := snapVol.MountPath()
-	newPath := GetVolumeMountPath(d.name, snapVol.volType, GetSnapshotVolumeName(parentName, newSnapshotName))
-
-	err := os.Rename(oldPath, newPath)
-	if err != nil {
-		return errors.Wrapf(err, "Failed to rename '%s' to '%s'", oldPath, newPath)
-	}
-
-	return nil
-}
-
-// vfsMigrateVolume is a generic MigrateVolume implementation for VFS-only drivers.
-func (d *common) vfsMigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *migration.VolumeSourceArgs, op *operations.Operation) error {
-	bwlimit := d.config["rsync.bwlimit"]
-
-	for _, snapName := range volSrcArgs.Snapshots {
-		snapshot, err := vol.NewSnapshot(snapName)
-		if err != nil {
-			return err
-		}
-
-		// Send snapshot to recipient (ensure local snapshot volume is mounted if needed).
-		err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error {
-			var wrapper *ioprogress.ProgressTracker
-			if volSrcArgs.TrackProgress {
-				wrapper = migration.ProgressTracker(op, "fs_progress", snapshot.name)
-			}
-
-			path := shared.AddSlash(mountPath)
-			return rsync.Send(snapshot.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath)
-		}, op)
-		if err != nil {
-			return err
-		}
-	}
-
-	// Send volume to recipient (ensure local volume is mounted if needed).
-	return vol.MountTask(func(mountPath string, op *operations.Operation) error {
-		var wrapper *ioprogress.ProgressTracker
-		if volSrcArgs.TrackProgress {
-			wrapper = migration.ProgressTracker(op, "fs_progress", vol.name)
-		}
-
-		path := shared.AddSlash(mountPath)
-		return rsync.Send(vol.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, d.state.OS.ExecPath)
-	}, op)
-}
-
-// vfsHasVolume is a generic HasVolume implementation for VFS-only drivers.
-func (d *common) vfsHasVolume(vol Volume) bool {
-	if shared.PathExists(vol.MountPath()) {
-		return true
-	}
-
-	return false
-}
-
-// vfsGetVolumeDiskPath is a generic GetVolumeDiskPath implementation for VFS-only drivers.
-func (d *common) vfsGetVolumeDiskPath(vol Volume) (string, error) {
-	if vol.contentType != ContentTypeBlock {
-		return "", fmt.Errorf("No disk paths for filesystems")
-	}
-
-	return filepath.Join(vol.MountPath(), "root.img"), nil
-}
-
-// vfsBackupVolume is a generic BackupVolume implementation for VFS-only drivers.
-func (d *common) vfsBackupVolume(vol Volume, targetPath string, snapshots bool, op *operations.Operation) error {
-	bwlimit := d.config["rsync.bwlimit"]
-
-	// Backups only implemented for containers currently.
-	if vol.volType != VolumeTypeContainer {
-		return ErrNotImplemented
-	}
-	// Handle snapshots.
-	if snapshots {
-		snapshotsPath := filepath.Join(targetPath, "snapshots")
-
-		// List the snapshots.
-		snapshots, err := vol.Snapshots(op)
-		if err != nil {
-			return err
-		}
-
-		// Create the snapshot path.
-		if len(snapshots) > 0 {
-			err = os.MkdirAll(snapshotsPath, 0711)
-			if err != nil {
-				return errors.Wrapf(err, "Failed to create directory '%s'", snapshotsPath)
-			}
-		}
-
-		for _, snapshot := range snapshots {
-			_, snapName, _ := shared.InstanceGetParentAndSnapshotName(snapshot.Name())
-			target := filepath.Join(snapshotsPath, snapName)
-
-			// Copy the snapshot.
-			err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error {
-				_, err := rsync.LocalCopy(mountPath, target, bwlimit, true)
-				if err != nil {
-					return err
-				}
-
-				return nil
-			}, op)
-			if err != nil {
-				return err
-			}
-		}
-	}
-
-	// Copy the parent volume itself.
-	target := filepath.Join(targetPath, "container")
-	err := vol.MountTask(func(mountPath string, op *operations.Operation) error {
-		_, err := rsync.LocalCopy(mountPath, target, bwlimit, true)
-		if err != nil {
-			return err
-		}
-
-		return nil
-	}, op)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}

From 0c0d64b034419839e9bbb882bdfd91685a8b5dcb Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 16 Jan 2020 17:48:36 +0000
Subject: [PATCH 2/3] lxd/storage/drivers/generic/vfs: Moves generic VFS
 drivers into standalone file

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/generic_vfs.go | 239 +++++++++++++++++++++++++++++
 1 file changed, 239 insertions(+)
 create mode 100644 lxd/storage/drivers/generic_vfs.go

diff --git a/lxd/storage/drivers/generic_vfs.go b/lxd/storage/drivers/generic_vfs.go
new file mode 100644
index 0000000000..dadeeab8ab
--- /dev/null
+++ b/lxd/storage/drivers/generic_vfs.go
@@ -0,0 +1,239 @@
+package drivers
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+
+	"github.com/pkg/errors"
+
+	"github.com/lxc/lxd/lxd/migration"
+	"github.com/lxc/lxd/lxd/operations"
+	"github.com/lxc/lxd/lxd/rsync"
+	"github.com/lxc/lxd/lxd/state"
+	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/ioprogress"
+)
+
+// genericVFSGetResources is a generic GetResources implementation for VFS-only drivers.
+func genericVFSGetResources(d Driver) (*api.ResourcesStoragePool, error) {
+	// Get the VFS information
+	st, err := shared.Statvfs(GetPoolMountPath(d.Name()))
+	if err != nil {
+		return nil, err
+	}
+
+	// Fill in the struct
+	res := api.ResourcesStoragePool{}
+	res.Space.Total = st.Blocks * uint64(st.Bsize)
+	res.Space.Used = (st.Blocks - st.Bfree) * uint64(st.Bsize)
+
+	// Some filesystems don't report inodes since they allocate them
+	// dynamically e.g. btrfs.
+	if st.Files > 0 {
+		res.Inodes.Total = st.Files
+		res.Inodes.Used = st.Files - st.Ffree
+	}
+
+	return &res, nil
+}
+
+// genericVFSRenameVolume is a generic RenameVolume implementation for VFS-only drivers.
+func genericVFSRenameVolume(d Driver, vol Volume, newVolName string, op *operations.Operation) error {
+	// Rename the volume itself.
+	srcVolumePath := GetVolumeMountPath(d.Name(), vol.volType, vol.name)
+	dstVolumePath := GetVolumeMountPath(d.Name(), vol.volType, newVolName)
+
+	err := os.Rename(srcVolumePath, dstVolumePath)
+	if err != nil {
+		return errors.Wrapf(err, "Failed to rename '%s' to '%s'", srcVolumePath, dstVolumePath)
+	}
+
+	revertRename := true
+	defer func() {
+		if !revertRename {
+			return
+		}
+
+		os.Rename(dstVolumePath, srcVolumePath)
+	}()
+
+	// And if present, the snapshots too.
+	srcSnapshotDir := GetVolumeSnapshotDir(d.Name(), vol.volType, vol.name)
+	dstSnapshotDir := GetVolumeSnapshotDir(d.Name(), vol.volType, newVolName)
+
+	if shared.PathExists(srcSnapshotDir) {
+		err = os.Rename(srcSnapshotDir, dstSnapshotDir)
+		if err != nil {
+			return errors.Wrapf(err, "Failed to rename '%s' to '%s'", srcSnapshotDir, dstSnapshotDir)
+		}
+	}
+
+	revertRename = false
+	return nil
+}
+
+// genericVFSVolumeSnapshots is a generic VolumeSnapshots implementation for VFS-only drivers.
+func genericVFSVolumeSnapshots(d Driver, vol Volume, op *operations.Operation) ([]string, error) {
+	snapshotDir := GetVolumeSnapshotDir(d.Name(), vol.volType, vol.name)
+	snapshots := []string{}
+
+	ents, err := ioutil.ReadDir(snapshotDir)
+	if err != nil {
+		// If the snapshots directory doesn't exist, there are no snapshots.
+		if os.IsNotExist(err) {
+			return snapshots, nil
+		}
+
+		return nil, errors.Wrapf(err, "Failed to list directory '%s'", snapshotDir)
+	}
+
+	for _, ent := range ents {
+		fileInfo, err := os.Stat(filepath.Join(snapshotDir, ent.Name()))
+		if err != nil {
+			return nil, err
+		}
+
+		if !fileInfo.IsDir() {
+			continue
+		}
+
+		snapshots = append(snapshots, ent.Name())
+	}
+
+	return snapshots, nil
+}
+
+// genericVFSRenameVolumeSnapshot is a generic RenameVolumeSnapshot implementation for VFS-only drivers.
+func genericVFSRenameVolumeSnapshot(d Driver, snapVol Volume, newSnapshotName string, op *operations.Operation) error {
+	parentName, _, _ := shared.InstanceGetParentAndSnapshotName(snapVol.name)
+	oldPath := snapVol.MountPath()
+	newPath := GetVolumeMountPath(d.Name(), snapVol.volType, GetSnapshotVolumeName(parentName, newSnapshotName))
+
+	err := os.Rename(oldPath, newPath)
+	if err != nil {
+		return errors.Wrapf(err, "Failed to rename '%s' to '%s'", oldPath, newPath)
+	}
+
+	return nil
+}
+
+// genericVFSMigrateVolume is a generic MigrateVolume implementation for VFS-only drivers.
+func genericVFSMigrateVolume(d Driver, s *state.State, vol Volume, conn io.ReadWriteCloser, volSrcArgs *migration.VolumeSourceArgs, op *operations.Operation) error {
+	bwlimit := d.Config()["rsync.bwlimit"]
+
+	for _, snapName := range volSrcArgs.Snapshots {
+		snapshot, err := vol.NewSnapshot(snapName)
+		if err != nil {
+			return err
+		}
+
+		// Send snapshot to recipient (ensure local snapshot volume is mounted if needed).
+		err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error {
+			var wrapper *ioprogress.ProgressTracker
+			if volSrcArgs.TrackProgress {
+				wrapper = migration.ProgressTracker(op, "fs_progress", snapshot.name)
+			}
+
+			path := shared.AddSlash(mountPath)
+			return rsync.Send(snapshot.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, s.OS.ExecPath)
+		}, op)
+		if err != nil {
+			return err
+		}
+	}
+
+	// Send volume to recipient (ensure local volume is mounted if needed).
+	return vol.MountTask(func(mountPath string, op *operations.Operation) error {
+		var wrapper *ioprogress.ProgressTracker
+		if volSrcArgs.TrackProgress {
+			wrapper = migration.ProgressTracker(op, "fs_progress", vol.name)
+		}
+
+		path := shared.AddSlash(mountPath)
+		return rsync.Send(vol.name, path, conn, wrapper, volSrcArgs.MigrationType.Features, bwlimit, s.OS.ExecPath)
+	}, op)
+}
+
+// genericVFSHasVolume is a generic HasVolume implementation for VFS-only drivers.
+func genericVFSHasVolume(vol Volume) bool {
+	if shared.PathExists(vol.MountPath()) {
+		return true
+	}
+
+	return false
+}
+
+// genericVFSGetVolumeDiskPath is a generic GetVolumeDiskPath implementation for VFS-only drivers.
+func genericVFSGetVolumeDiskPath(vol Volume) (string, error) {
+	if vol.contentType != ContentTypeBlock {
+		return "", fmt.Errorf("No disk paths for filesystems")
+	}
+
+	return filepath.Join(vol.MountPath(), "root.img"), nil
+}
+
+// genericVFSBackupVolume is a generic BackupVolume implementation for VFS-only drivers.
+func genericVFSBackupVolume(d Driver, vol Volume, targetPath string, snapshots bool, op *operations.Operation) error {
+	bwlimit := d.Config()["rsync.bwlimit"]
+
+	// Backups only implemented for containers currently.
+	if vol.volType != VolumeTypeContainer {
+		return ErrNotImplemented
+	}
+	// Handle snapshots.
+	if snapshots {
+		snapshotsPath := filepath.Join(targetPath, "snapshots")
+
+		// List the snapshots.
+		snapshots, err := vol.Snapshots(op)
+		if err != nil {
+			return err
+		}
+
+		// Create the snapshot path.
+		if len(snapshots) > 0 {
+			err = os.MkdirAll(snapshotsPath, 0711)
+			if err != nil {
+				return errors.Wrapf(err, "Failed to create directory '%s'", snapshotsPath)
+			}
+		}
+
+		for _, snapshot := range snapshots {
+			_, snapName, _ := shared.InstanceGetParentAndSnapshotName(snapshot.Name())
+			target := filepath.Join(snapshotsPath, snapName)
+
+			// Copy the snapshot.
+			err = snapshot.MountTask(func(mountPath string, op *operations.Operation) error {
+				_, err := rsync.LocalCopy(mountPath, target, bwlimit, true)
+				if err != nil {
+					return err
+				}
+
+				return nil
+			}, op)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	// Copy the parent volume itself.
+	target := filepath.Join(targetPath, "container")
+	err := vol.MountTask(func(mountPath string, op *operations.Operation) error {
+		_, err := rsync.LocalCopy(mountPath, target, bwlimit, true)
+		if err != nil {
+			return err
+		}
+
+		return nil
+	}, op)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

From 985f90245111ee922a1a9fc62e8a79b3f67ba0ea Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 16 Jan 2020 17:49:05 +0000
Subject: [PATCH 3/3] lxd/storage/drivers: Updates usage of generic VFS
 functions

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/storage/drivers/driver_btrfs.go          |  2 +-
 lxd/storage/drivers/driver_btrfs_volumes.go  | 14 +++++++-------
 lxd/storage/drivers/driver_cephfs.go         |  2 +-
 lxd/storage/drivers/driver_cephfs_volumes.go |  6 +++---
 lxd/storage/drivers/driver_dir.go            |  2 +-
 lxd/storage/drivers/driver_dir_volumes.go    | 14 +++++++-------
 lxd/storage/drivers/driver_lvm_volumes.go    |  6 +++---
 lxd/storage/drivers/driver_zfs_volumes.go    | 12 ++++++------
 8 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/lxd/storage/drivers/driver_btrfs.go b/lxd/storage/drivers/driver_btrfs.go
index bf747f1b49..0ea6fdebf9 100644
--- a/lxd/storage/drivers/driver_btrfs.go
+++ b/lxd/storage/drivers/driver_btrfs.go
@@ -357,7 +357,7 @@ func (d *btrfs) Unmount() (bool, error) {
 
 // GetResources returns the pool resource usage information.
 func (d *btrfs) GetResources() (*api.ResourcesStoragePool, error) {
-	return d.vfsGetResources()
+	return genericVFSGetResources(d)
 }
 
 // MigrationType returns the type of transfer methods to be used when doing migrations between pools in preference order.
diff --git a/lxd/storage/drivers/driver_btrfs_volumes.go b/lxd/storage/drivers/driver_btrfs_volumes.go
index 354325a137..1d8af0fc03 100644
--- a/lxd/storage/drivers/driver_btrfs_volumes.go
+++ b/lxd/storage/drivers/driver_btrfs_volumes.go
@@ -340,7 +340,7 @@ func (d *btrfs) DeleteVolume(vol Volume, op *operations.Operation) error {
 
 // HasVolume indicates whether a specific volume exists on the storage pool.
 func (d *btrfs) HasVolume(vol Volume) bool {
-	return d.vfsHasVolume(vol)
+	return genericVFSHasVolume(vol)
 }
 
 // ValidateVolume validates the supplied volume config.
@@ -455,7 +455,7 @@ func (d *btrfs) SetVolumeQuota(vol Volume, size string, op *operations.Operation
 
 // GetVolumeDiskPath returns the location and file format of a disk volume.
 func (d *btrfs) GetVolumeDiskPath(vol Volume) (string, error) {
-	return d.vfsGetVolumeDiskPath(vol)
+	return genericVFSGetVolumeDiskPath(vol)
 }
 
 // MountVolume simulates mounting a volume.
@@ -470,7 +470,7 @@ func (d *btrfs) UnmountVolume(vol Volume, op *operations.Operation) (bool, error
 
 // RenameVolume renames a volume and its snapshots.
 func (d *btrfs) RenameVolume(vol Volume, newVolName string, op *operations.Operation) error {
-	return d.vfsRenameVolume(vol, newVolName, op)
+	return genericVFSRenameVolume(d, vol, newVolName, op)
 }
 
 // MigrateVolume sends a volume for migration.
@@ -481,7 +481,7 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 
 	// Handle simple rsync through generic.
 	if volSrcArgs.MigrationType.FSType == migration.MigrationFSType_RSYNC {
-		return d.vfsMigrateVolume(vol, conn, volSrcArgs, op)
+		return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op)
 	} else if volSrcArgs.MigrationType.FSType != migration.MigrationFSType_BTRFS {
 		return ErrNotSupported
 	}
@@ -564,7 +564,7 @@ func (d *btrfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *m
 func (d *btrfs) BackupVolume(vol Volume, targetPath string, optimized bool, snapshots bool, op *operations.Operation) error {
 	// Handle the non-optimized tarballs through the generic packer.
 	if !optimized {
-		return d.vfsBackupVolume(vol, targetPath, snapshots, op)
+		return genericVFSBackupVolume(d, vol, targetPath, snapshots, op)
 	}
 
 	// Handle the optimized tarballs.
@@ -717,7 +717,7 @@ func (d *btrfs) UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation)
 
 // VolumeSnapshots returns a list of snapshots for the volume.
 func (d *btrfs) VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error) {
-	return d.vfsVolumeSnapshots(vol, op)
+	return genericVFSVolumeSnapshots(d, vol, op)
 }
 
 // RestoreVolume restores a volume from a snapshot.
@@ -752,5 +752,5 @@ func (d *btrfs) RestoreVolume(vol Volume, snapshotName string, op *operations.Op
 
 // RenameVolumeSnapshot renames a volume snapshot.
 func (d *btrfs) RenameVolumeSnapshot(snapVol Volume, newSnapshotName string, op *operations.Operation) error {
-	return d.vfsRenameVolumeSnapshot(snapVol, newSnapshotName, op)
+	return genericVFSRenameVolumeSnapshot(d, snapVol, newSnapshotName, op)
 }
diff --git a/lxd/storage/drivers/driver_cephfs.go b/lxd/storage/drivers/driver_cephfs.go
index fc14f98c8b..782582f993 100644
--- a/lxd/storage/drivers/driver_cephfs.go
+++ b/lxd/storage/drivers/driver_cephfs.go
@@ -279,7 +279,7 @@ func (d *cephfs) Unmount() (bool, error) {
 
 // GetResources returns the pool resource usage information.
 func (d *cephfs) GetResources() (*api.ResourcesStoragePool, error) {
-	return d.vfsGetResources()
+	return genericVFSGetResources(d)
 }
 
 // MigrationTypes returns the supported migration types and options supported by the driver.
diff --git a/lxd/storage/drivers/driver_cephfs_volumes.go b/lxd/storage/drivers/driver_cephfs_volumes.go
index 746a8ce0c3..852f967167 100644
--- a/lxd/storage/drivers/driver_cephfs_volumes.go
+++ b/lxd/storage/drivers/driver_cephfs_volumes.go
@@ -267,7 +267,7 @@ func (d *cephfs) DeleteVolume(vol Volume, op *operations.Operation) error {
 
 // HasVolume indicates whether a specific volume exists on the storage pool.
 func (d *cephfs) HasVolume(vol Volume) bool {
-	return d.vfsHasVolume(vol)
+	return genericVFSHasVolume(vol)
 }
 
 // ValidateVolume validates the supplied volume config. Optionally removes invalid keys from the volume's config.
@@ -433,7 +433,7 @@ func (d *cephfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *
 		return ErrNotSupported
 	}
 
-	return d.vfsMigrateVolume(vol, conn, volSrcArgs, op)
+	return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op)
 }
 
 // BackupVolume creates an exported version of a volume.
@@ -505,7 +505,7 @@ func (d *cephfs) UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation)
 
 // VolumeSnapshots returns a list of snapshot names for the volume.
 func (d *cephfs) VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error) {
-	return d.vfsVolumeSnapshots(vol, op)
+	return genericVFSVolumeSnapshots(d, vol, op)
 }
 
 // RestoreVolume resets a volume to its snapshotted state.
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index 901724a4c1..0e80182384 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -137,5 +137,5 @@ func (d *dir) Unmount() (bool, error) {
 
 // GetResources returns the pool resource usage information.
 func (d *dir) GetResources() (*api.ResourcesStoragePool, error) {
-	return d.vfsGetResources()
+	return genericVFSGetResources(d)
 }
diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go
index 78ac040f25..5ee7f11354 100644
--- a/lxd/storage/drivers/driver_dir_volumes.go
+++ b/lxd/storage/drivers/driver_dir_volumes.go
@@ -185,7 +185,7 @@ func (d *dir) DeleteVolume(vol Volume, op *operations.Operation) error {
 
 // HasVolume indicates whether a specific volume exists on the storage pool.
 func (d *dir) HasVolume(vol Volume) bool {
-	return d.vfsHasVolume(vol)
+	return genericVFSHasVolume(vol)
 }
 
 // ValidateVolume validates the supplied volume config. Optionally removes invalid keys from the volume's config.
@@ -248,7 +248,7 @@ func (d *dir) SetVolumeQuota(vol Volume, size string, op *operations.Operation)
 
 // GetVolumeDiskPath returns the location of a disk volume.
 func (d *dir) GetVolumeDiskPath(vol Volume) (string, error) {
-	return d.vfsGetVolumeDiskPath(vol)
+	return genericVFSGetVolumeDiskPath(vol)
 }
 
 // MountVolume simulates mounting a volume. As dir driver doesn't have volumes to mount it returns
@@ -265,7 +265,7 @@ func (d *dir) UnmountVolume(vol Volume, op *operations.Operation) (bool, error)
 
 // RenameVolume renames a volume and its snapshots.
 func (d *dir) RenameVolume(vol Volume, newVolName string, op *operations.Operation) error {
-	return d.vfsRenameVolume(vol, newVolName, op)
+	return genericVFSRenameVolume(d, vol, newVolName, op)
 }
 
 // MigrateVolume sends a volume for migration.
@@ -278,13 +278,13 @@ func (d *dir) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *mig
 		return ErrNotSupported
 	}
 
-	return d.vfsMigrateVolume(vol, conn, volSrcArgs, op)
+	return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op)
 }
 
 // BackupVolume copies a volume (and optionally its snapshots) to a specified target path.
 // This driver does not support optimized backups.
 func (d *dir) BackupVolume(vol Volume, targetPath string, optimized bool, snapshots bool, op *operations.Operation) error {
-	return d.vfsBackupVolume(vol, targetPath, snapshots, op)
+	return genericVFSBackupVolume(d, vol, targetPath, snapshots, op)
 }
 
 // CreateVolumeSnapshot creates a snapshot of a volume.
@@ -360,7 +360,7 @@ func (d *dir) UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation) (b
 
 // VolumeSnapshots returns a list of snapshots for the volume.
 func (d *dir) VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error) {
-	return d.vfsVolumeSnapshots(vol, op)
+	return genericVFSVolumeSnapshots(d, vol, op)
 }
 
 // RestoreVolume restores a volume from a snapshot.
@@ -384,5 +384,5 @@ func (d *dir) RestoreVolume(vol Volume, snapshotName string, op *operations.Oper
 
 // RenameVolumeSnapshot renames a volume snapshot.
 func (d *dir) RenameVolumeSnapshot(snapVol Volume, newSnapshotName string, op *operations.Operation) error {
-	return d.vfsRenameVolumeSnapshot(snapVol, newSnapshotName, op)
+	return genericVFSRenameVolumeSnapshot(d, snapVol, newSnapshotName, op)
 }
diff --git a/lxd/storage/drivers/driver_lvm_volumes.go b/lxd/storage/drivers/driver_lvm_volumes.go
index d2b316f3c9..d55449964e 100644
--- a/lxd/storage/drivers/driver_lvm_volumes.go
+++ b/lxd/storage/drivers/driver_lvm_volumes.go
@@ -518,13 +518,13 @@ func (d *lvm) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *mig
 		return ErrNotSupported
 	}
 
-	return d.vfsMigrateVolume(vol, conn, volSrcArgs, op)
+	return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op)
 }
 
 // BackupVolume copies a volume (and optionally its snapshots) to a specified target path.
 // This driver does not support optimized backups.
 func (d *lvm) BackupVolume(vol Volume, targetPath string, _, snapshots bool, op *operations.Operation) error {
-	return d.vfsBackupVolume(vol, targetPath, snapshots, op)
+	return genericVFSBackupVolume(d, vol, targetPath, snapshots, op)
 }
 
 // CreateVolumeSnapshot creates a snapshot of a volume.
@@ -731,7 +731,7 @@ func (d *lvm) VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, e
 	// We use the vfsVolumeSnapshots rather than inspecting the logical volumes themselves because the origin
 	// property of an LVM snapshot can be removed/changed when restoring snapshots, such that they are no
 	// marked as origin of the parent volume.
-	return d.vfsVolumeSnapshots(vol, op)
+	return genericVFSVolumeSnapshots(d, vol, op)
 }
 
 // RestoreVolume restores a volume from a snapshot.
diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go
index d033cb3e76..2e6546f5d4 100644
--- a/lxd/storage/drivers/driver_zfs_volumes.go
+++ b/lxd/storage/drivers/driver_zfs_volumes.go
@@ -918,13 +918,13 @@ func (d *zfs) RenameVolume(vol Volume, newVolName string, op *operations.Operati
 	defer revert.Fail()
 
 	// First rename the VFS paths.
-	err := d.vfsRenameVolume(vol, newVolName, op)
+	err := genericVFSRenameVolume(d, vol, newVolName, op)
 	if err != nil {
 		return err
 	}
 
 	revert.Add(func() {
-		d.vfsRenameVolume(newVol, vol.name, op)
+		genericVFSRenameVolume(d, newVol, vol.name, op)
 	})
 
 	// Rename the ZFS datasets.
@@ -971,7 +971,7 @@ func (d *zfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *mig
 
 	// Handle simple rsync through generic.
 	if volSrcArgs.MigrationType.FSType == migration.MigrationFSType_RSYNC {
-		return d.vfsMigrateVolume(vol, conn, volSrcArgs, op)
+		return genericVFSMigrateVolume(d, d.state, vol, conn, volSrcArgs, op)
 	} else if volSrcArgs.MigrationType.FSType != migration.MigrationFSType_ZFS {
 		return ErrNotSupported
 	}
@@ -1047,7 +1047,7 @@ func (d *zfs) MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs *mig
 func (d *zfs) BackupVolume(vol Volume, targetPath string, optimized bool, snapshots bool, op *operations.Operation) error {
 	// Handle the non-optimized tarballs through the generic packer.
 	if !optimized {
-		return d.vfsBackupVolume(vol, targetPath, snapshots, op)
+		return genericVFSBackupVolume(d, vol, targetPath, snapshots, op)
 	}
 
 	// Handle the optimized tarballs.
@@ -1352,13 +1352,13 @@ func (d *zfs) RenameVolumeSnapshot(vol Volume, newSnapshotName string, op *opera
 	defer revert.Fail()
 
 	// First rename the VFS paths.
-	err := d.vfsRenameVolumeSnapshot(vol, newSnapshotName, op)
+	err := genericVFSRenameVolume(d, vol, newSnapshotName, op)
 	if err != nil {
 		return err
 	}
 
 	revert.Add(func() {
-		d.vfsRenameVolumeSnapshot(newVol, vol.name, op)
+		genericVFSRenameVolume(d, newVol, vol.name, op)
 	})
 
 	// Rename the ZFS datasets.


More information about the lxc-devel mailing list