The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8104
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From 3f965e407fc42df23a43432721d24b106cd10d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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),
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel