[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