[lxc-devel] [lxd/master] Simplify adding new storage drivers

stgraber on Github lxc-bot at linuxcontainers.org
Sun Dec 15 03:16:22 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/20191214/2d99cb21/attachment.bin>
-------------- next part --------------
From 53d0ae9e500d5ea559848978fdced6d4666c96e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 14 Dec 2019 21:32:16 -0500
Subject: [PATCH 1/5] lxd/storage/dir: Use MountPath
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_dir.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index a879d16f7c..693c495ab5 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -139,7 +139,7 @@ func (d *dir) GetResources() (*api.ResourcesStoragePool, error) {
 
 // GetVolumeUsage returns the disk space used by the volume.
 func (d *dir) GetVolumeUsage(vol Volume) (int64, error) {
-	volPath := GetVolumeMountPath(d.name, vol.volType, vol.name)
+	volPath := vol.MountPath()
 	ok, err := quota.Supported(volPath)
 	if err != nil || !ok {
 		return 0, nil
@@ -169,7 +169,7 @@ func (d *dir) ValidateVolume(vol Volume, removeUnknownKeys bool) error {
 
 // HasVolume indicates whether a specific volume exists on the storage pool.
 func (d *dir) HasVolume(vol Volume) bool {
-	if shared.PathExists(GetVolumeMountPath(d.name, vol.volType, vol.name)) {
+	if shared.PathExists(vol.MountPath()) {
 		return true
 	}
 
@@ -178,7 +178,7 @@ func (d *dir) HasVolume(vol Volume) bool {
 
 // GetVolumeDiskPath returns the location of a disk volume.
 func (d *dir) GetVolumeDiskPath(vol Volume) (string, error) {
-	return filepath.Join(GetVolumeMountPath(d.name, vol.volType, vol.name), "root.img"), nil
+	return filepath.Join(vol.MountPath(), "root.img"), nil
 }
 
 // setupInitialQuota enables quota on a new volume and sets with an initial quota from config.
@@ -757,7 +757,7 @@ func (d *dir) DeleteVolume(vol Volume, op *operations.Operation) error {
 		return fmt.Errorf("Cannot remove a volume that has snapshots")
 	}
 
-	volPath := GetVolumeMountPath(d.name, vol.volType, vol.name)
+	volPath := vol.MountPath()
 
 	// If the volume doesn't exist, then nothing more to do.
 	if !shared.PathExists(volPath) {
@@ -818,7 +818,7 @@ func (d *dir) UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation) (b
 
 // SetVolumeQuota sets the quota on the volume.
 func (d *dir) SetVolumeQuota(vol Volume, size string, op *operations.Operation) error {
-	volPath := GetVolumeMountPath(d.name, vol.volType, vol.name)
+	volPath := vol.MountPath()
 	volID, err := d.getVolID(vol.volType, vol.name)
 	if err != nil {
 		return err

From 8afc53cee9d12c38cd3be58c7ca19b8625b37c21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 14 Dec 2019 21:34:44 -0500
Subject: [PATCH 2/5] lxd/storage/dir: Move vfsResources
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_cephfs.go |  3 +--
 lxd/storage/drivers/driver_common.go | 25 +++++++++++++++++++++++++
 lxd/storage/drivers/driver_dir.go    |  3 +--
 lxd/storage/drivers/utils.go         | 23 -----------------------
 4 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/lxd/storage/drivers/driver_cephfs.go b/lxd/storage/drivers/driver_cephfs.go
index c13bfbd1be..7049a0568c 100644
--- a/lxd/storage/drivers/driver_cephfs.go
+++ b/lxd/storage/drivers/driver_cephfs.go
@@ -280,8 +280,7 @@ func (d *cephfs) Unmount() (bool, error) {
 }
 
 func (d *cephfs) GetResources() (*api.ResourcesStoragePool, error) {
-	// Use the generic VFS resources.
-	return vfsResources(GetPoolMountPath(d.name))
+	return d.vfsGetResources()
 }
 
 func (d *cephfs) ValidateVolume(vol Volume, removeUnknownKeys bool) error {
diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index 1b022472d2..f87a350a3f 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -6,6 +6,8 @@ import (
 
 	"github.com/lxc/lxd/lxd/migration"
 	"github.com/lxc/lxd/lxd/state"
+	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 )
 
@@ -108,3 +110,26 @@ func (d *common) Config() map[string]string {
 
 	return confCopy
 }
+
+// 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
+}
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index 693c495ab5..13c038c792 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -133,8 +133,7 @@ func (d *dir) Unmount() (bool, error) {
 }
 
 func (d *dir) GetResources() (*api.ResourcesStoragePool, error) {
-	// Use the generic VFS resources.
-	return vfsResources(GetPoolMountPath(d.name))
+	return d.vfsGetResources()
 }
 
 // GetVolumeUsage returns the disk space used by the volume.
diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index 7f065aa97b..d3606a28a3 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -12,7 +12,6 @@ import (
 
 	"github.com/lxc/lxd/lxd/project"
 	"github.com/lxc/lxd/shared"
-	"github.com/lxc/lxd/shared/api"
 )
 
 // MkfsOptions represents options for filesystem creation.
@@ -148,28 +147,6 @@ func tryMount(src string, dst string, fs string, flags uintptr, options string)
 	return nil
 }
 
-func vfsResources(path string) (*api.ResourcesStoragePool, error) {
-	// Get the VFS information
-	st, err := shared.Statvfs(path)
-	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
-}
-
 // GetPoolMountPath returns the mountpoint of the given pool.
 // {LXD_DIR}/storage-pools/<pool>
 func GetPoolMountPath(poolName string) string {

From 71ac6e1e9b0317c037352ee288c098359a81b0d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 14 Dec 2019 21:37:40 -0500
Subject: [PATCH 3/5] lxd/storage/common: Add vfsRenameVolume
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_common.go | 77 ++++++++++++++++++++++++++++
 lxd/storage/drivers/driver_dir.go    | 72 +-------------------------
 2 files changed, 78 insertions(+), 71 deletions(-)

diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index f87a350a3f..8b41f98a93 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -2,9 +2,11 @@ package drivers
 
 import (
 	"fmt"
+	"os"
 	"strings"
 
 	"github.com/lxc/lxd/lxd/migration"
+	"github.com/lxc/lxd/lxd/operations"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -133,3 +135,78 @@ func (d *common) vfsGetResources() (*api.ResourcesStoragePool, error) {
 
 	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 {
+	// Create new snapshots directory.
+	snapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, newVolName)
+
+	err := os.MkdirAll(snapshotDir, 0711)
+	if err != nil {
+		return err
+	}
+
+	type volRevert struct {
+		oldPath string
+		newPath string
+	}
+
+	// Create slice to record paths renamed if revert needed later.
+	revertPaths := []volRevert{}
+	defer func() {
+		// Remove any paths rename if we are reverting.
+		for _, vol := range revertPaths {
+			os.Rename(vol.newPath, vol.oldPath)
+		}
+
+		// Remove the new snapshot directory if we are reverting.
+		if len(revertPaths) > 0 {
+			err = os.RemoveAll(snapshotDir)
+		}
+	}()
+
+	// Rename any snapshots of the volume too.
+	snapshots, err := vol.Snapshots(op)
+	if err != nil {
+		return err
+	}
+
+	for _, snapshot := range snapshots {
+		oldPath := snapshot.MountPath()
+		_, snapName, _ := shared.InstanceGetParentAndSnapshotName(snapshot.name)
+		newPath := GetVolumeMountPath(d.name, vol.volType, GetSnapshotVolumeName(newVolName, snapName))
+
+		err := os.Rename(oldPath, newPath)
+		if err != nil {
+			return err
+		}
+
+		revertPaths = append(revertPaths, volRevert{
+			oldPath: oldPath,
+			newPath: newPath,
+		})
+	}
+
+	oldPath := GetVolumeMountPath(d.name, vol.volType, vol.name)
+	newPath := GetVolumeMountPath(d.name, vol.volType, newVolName)
+	err = os.Rename(oldPath, newPath)
+	if err != nil {
+		return err
+	}
+
+	revertPaths = append(revertPaths, volRevert{
+		oldPath: oldPath,
+		newPath: newPath,
+	})
+
+	// Remove old snapshots directory.
+	oldSnapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, vol.name)
+
+	err = os.RemoveAll(oldSnapshotDir)
+	if err != nil {
+		return err
+	}
+
+	revertPaths = nil
+	return nil
+}
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index 13c038c792..da5acafb6d 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -652,77 +652,7 @@ func (d *dir) UpdateVolume(vol Volume, changedConfig map[string]string) error {
 
 // RenameVolume renames a volume and its snapshots.
 func (d *dir) RenameVolume(vol Volume, newVolName string, op *operations.Operation) error {
-	// Create new snapshots directory.
-	snapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, newVolName)
-
-	err := os.MkdirAll(snapshotDir, 0711)
-	if err != nil {
-		return err
-	}
-
-	type volRevert struct {
-		oldPath string
-		newPath string
-	}
-
-	// Create slice to record paths renamed if revert needed later.
-	revertPaths := []volRevert{}
-	defer func() {
-		// Remove any paths rename if we are reverting.
-		for _, vol := range revertPaths {
-			os.Rename(vol.newPath, vol.oldPath)
-		}
-
-		// Remove the new snapshot directory if we are reverting.
-		if len(revertPaths) > 0 {
-			err = os.RemoveAll(snapshotDir)
-		}
-	}()
-
-	// Rename any snapshots of the volume too.
-	snapshots, err := vol.Snapshots(op)
-	if err != nil {
-		return err
-	}
-
-	for _, snapshot := range snapshots {
-		oldPath := snapshot.MountPath()
-		_, snapName, _ := shared.InstanceGetParentAndSnapshotName(snapshot.name)
-		newPath := GetVolumeMountPath(d.name, vol.volType, GetSnapshotVolumeName(newVolName, snapName))
-
-		err := os.Rename(oldPath, newPath)
-		if err != nil {
-			return err
-		}
-
-		revertPaths = append(revertPaths, volRevert{
-			oldPath: oldPath,
-			newPath: newPath,
-		})
-	}
-
-	oldPath := GetVolumeMountPath(d.name, vol.volType, vol.name)
-	newPath := GetVolumeMountPath(d.name, vol.volType, newVolName)
-	err = os.Rename(oldPath, newPath)
-	if err != nil {
-		return err
-	}
-
-	revertPaths = append(revertPaths, volRevert{
-		oldPath: oldPath,
-		newPath: newPath,
-	})
-
-	// Remove old snapshots directory.
-	oldSnapshotDir := GetVolumeSnapshotDir(d.name, vol.volType, vol.name)
-
-	err = os.RemoveAll(oldSnapshotDir)
-	if err != nil {
-		return err
-	}
-
-	revertPaths = nil
-	return nil
+	return d.vfsRenameVolume(vol, newVolName, op)
 }
 
 // RestoreVolume restores a volume from a snapshot.

From 7bc4ff0604a08056c718ff30864a626213c1b274 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 14 Dec 2019 21:43:04 -0500
Subject: [PATCH 4/5] lxd/storage/common: Add vfsVolumeSnapshots
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_common.go | 33 ++++++++++++++++++++++++++++
 lxd/storage/drivers/driver_dir.go    | 29 +-----------------------
 2 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index 8b41f98a93..92ce8c71a3 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -2,7 +2,9 @@ package drivers
 
 import (
 	"fmt"
+	"io/ioutil"
 	"os"
+	"path/filepath"
 	"strings"
 
 	"github.com/lxc/lxd/lxd/migration"
@@ -210,3 +212,34 @@ func (d *common) vfsRenameVolume(vol Volume, newVolName string, op *operations.O
 	revertPaths = nil
 	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, err
+	}
+
+	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
+}
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index da5acafb6d..02fb1c8406 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -3,7 +3,6 @@ package drivers
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -599,33 +598,7 @@ func (d *dir) copyVolume(vol Volume, srcVol Volume, srcSnapshots []Volume, op *o
 
 // VolumeSnapshots returns a list of snapshots for the volume.
 func (d *dir) VolumeSnapshots(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, err
-	}
-
-	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
+	return d.vfsVolumeSnapshots(vol, op)
 }
 
 // UpdateVolume applies config changes to the volume.

From 8a0d596f2c49ecc8bedb5c160451363f89094270 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 14 Dec 2019 21:55:45 -0500
Subject: [PATCH 5/5] lxd/storage/common: Add vfsRenameVolumeSnapshot
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_common.go | 14 ++++++++++++++
 lxd/storage/drivers/driver_dir.go    | 11 +----------
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index 92ce8c71a3..b71309d7b9 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -243,3 +243,17 @@ func (d *common) vfsVolumeSnapshots(vol Volume, op *operations.Operation) ([]str
 
 	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 err
+	}
+
+	return nil
+}
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index 02fb1c8406..5e3788dd9e 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -867,16 +867,7 @@ func (d *dir) DeleteVolumeSnapshot(snapVol Volume, op *operations.Operation) err
 
 // RenameVolumeSnapshot renames a volume snapshot.
 func (d *dir) RenameVolumeSnapshot(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 err
-	}
-
-	return nil
+	return d.vfsRenameVolumeSnapshot(snapVol, newSnapshotName, op)
 }
 
 // BackupVolume copies a volume (and optionally its snapshots) to a specified target path.


More information about the lxc-devel mailing list