[lxc-devel] [lxd/master] Add `rebase` mode for `zfs.clone_copy`
stgraber on Github
lxc-bot at linuxcontainers.org
Sat Oct 31 01:16:56 UTC 2020
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/20201030/7cfe91c6/attachment.bin>
-------------- next part --------------
From 3f965e407fc42df23a43432721d24b106cd10d5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Oct 2020 18:35:16 -0400
Subject: [PATCH 1/4] api: Add storage_zfs_clone_copy_rebase extension
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>
---
doc/api-extensions.md | 5 +++++
shared/version/api.go | 1 +
2 files changed, 6 insertions(+)
diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 1742003087..555e83d8c6 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -1217,3 +1217,8 @@ both at the network and NIC level.
## tpm\_device\_type
This introduces the `tpm` device type.
+
+## storage\_zfs\_clone\_copy\_rebase
+This introduces `rebase` as a value for zfs.clone\_copy causing LXD to
+track down any "image" dataset in the ancestry line and then perform
+send/receive on top of that.
diff --git a/shared/version/api.go b/shared/version/api.go
index 2ff1e77db4..2c986fa5f0 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -234,6 +234,7 @@ var APIExtensions = []string{
"network_ovn_nat",
"network_ovn_external_routes_remove",
"tpm_device_type",
+ "storage_zfs_clone_copy_rebase",
}
// APIExtensionsCount returns the number of available API extensions.
From a12c58c769865dba839680d63def728dcfc74991 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Oct 2020 18:35:34 -0400
Subject: [PATCH 2/4] doc/storage: Allow 'rebase' in zfs.clone_copy
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>
---
doc/storage.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/storage.md b/doc/storage.md
index 67dc5786f1..5d95e3808e 100644
--- a/doc/storage.md
+++ b/doc/storage.md
@@ -35,7 +35,7 @@ volume.block.mount\_options | string | block based driver (lvm)
volume.size | string | appropriate driver | unlimited (10GB for block) | storage | Default volume size
volume.zfs.remove\_snapshots | bool | zfs driver | false | storage | Remove snapshots as needed
volume.zfs.use\_refquota | bool | zfs driver | false | storage | Use refquota instead of quota for space.
-zfs.clone\_copy | bool | zfs driver | true | storage\_zfs\_clone\_copy | Whether to use ZFS lightweight clones rather than full dataset copies.
+zfs.clone\_copy | string | zfs driver | true | storage\_zfs\_clone\_copy | Whether to use ZFS lightweight clones rather than full dataset copies (boolean) or "rebase" to copy based on the initial image.
zfs.pool\_name | string | zfs driver | name of the pool | storage | Name of the zpool
Storage pool configuration keys can be set using the lxc tool with:
From ca89ffbcbaeeb33bf4dd5fd2562aba77fe2aac2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Oct 2020 18:42:22 -0400
Subject: [PATCH 3/4] lxd/storage: Allow 'rebase' as value for zfs.clone_copy
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_pools_config.go | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index 5c6892bd12..ba4470d50a 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -78,7 +78,13 @@ var storagePoolConfigKeys = map[string]func(value string) error{
"volume.zfs.use_refquota": validate.Optional(validate.IsBool),
// valid drivers: zfs
- "zfs.clone_copy": validate.Optional(validate.IsBool),
+ "zfs.clone_copy": validate.Optional(func(value string) error {
+ if value == "rebase" {
+ return nil
+ }
+
+ return validate.IsBool(value)
+ }),
"zfs.pool_name": validate.IsAny,
"rsync.bwlimit": validate.IsAny,
From 5b2865972244ebac85d521c666cd1526c6312839 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 30 Oct 2020 19:19:30 -0400
Subject: [PATCH 4/4] lxd/storage/zfs: Add support for clone_copy rebase
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #8096
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage/drivers/driver_zfs.go | 10 ++++++--
lxd/storage/drivers/driver_zfs_volumes.go | 31 ++++++++++++++++++++++-
lxd/storage_pools_config.go | 4 +--
3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/lxd/storage/drivers/driver_zfs.go b/lxd/storage/drivers/driver_zfs.go
index 956f8297fb..31c4f3e771 100644
--- a/lxd/storage/drivers/driver_zfs.go
+++ b/lxd/storage/drivers/driver_zfs.go
@@ -342,8 +342,14 @@ func (d *zfs) Delete(op *operations.Operation) error {
// Validate checks that all provide keys are supported and that no conflicting or missing configuration is present.
func (d *zfs) Validate(config map[string]string) error {
rules := map[string]func(value string) error{
- "zfs.pool_name": validate.IsAny,
- "zfs.clone_copy": validate.Optional(validate.IsBool),
+ "zfs.pool_name": validate.IsAny,
+ "zfs.clone_copy": validate.Optional(func(value string) error {
+ if value == "rebase" {
+ return nil
+ }
+
+ return validate.IsBool(value)
+ }),
"volume.zfs.remove_snapshots": validate.Optional(validate.IsBool),
"volume.zfs.use_refquota": validate.Optional(validate.IsBool),
}
diff --git a/lxd/storage/drivers/driver_zfs_volumes.go b/lxd/storage/drivers/driver_zfs_volumes.go
index 811fb11450..bcf0c016d2 100644
--- a/lxd/storage/drivers/driver_zfs_volumes.go
+++ b/lxd/storage/drivers/driver_zfs_volumes.go
@@ -510,7 +510,36 @@ func (d *zfs) CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool
if len(snapshots) > 0 {
sender = exec.Command("zfs", "send", "-R", srcSnapshot)
} else {
- sender = exec.Command("zfs", "send", srcSnapshot)
+ if d.config["zfs.clone_copy"] == "rebase" {
+ var err error
+ origin := d.dataset(srcVol, false)
+ for {
+ fields := strings.SplitN(origin, "@", 2)
+
+ // If the origin is a @readonly snapshot under a /images/ path (/images or deleted/images), we're done.
+ if len(fields) > 1 && strings.Contains(fields[0], "/images/") && fields[1] == "readonly" {
+ break
+ }
+
+ origin, err = d.getDatasetProperty(origin, "origin")
+ if err != nil {
+ return err
+ }
+
+ if origin == "" || origin == "-" {
+ origin = ""
+ break
+ }
+ }
+
+ if origin != "" && origin != srcSnapshot {
+ sender = exec.Command("zfs", "send", "-i", origin, srcSnapshot)
+ } else {
+ sender = exec.Command("zfs", "send", srcSnapshot)
+ }
+ } else {
+ sender = exec.Command("zfs", "send", srcSnapshot)
+ }
}
// Configure the pipes.
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index ba4470d50a..d593655bfd 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -85,8 +85,8 @@ var storagePoolConfigKeys = map[string]func(value string) error{
return validate.IsBool(value)
}),
- "zfs.pool_name": validate.IsAny,
- "rsync.bwlimit": validate.IsAny,
+ "zfs.pool_name": validate.IsAny,
+ "rsync.bwlimit": validate.IsAny,
// valid drivers: btrfs, ceph, cephfs, zfs
"rsync.compression": validate.Optional(validate.IsBool),
More information about the lxc-devel
mailing list