summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrawn <Insane.Prawny@gmail.com>2021-04-27 02:23:51 +0200
committerTony Hutter <hutter2@llnl.gov>2021-06-23 13:22:14 -0700
commit28fdc5f8113d81d79f7aef4f78220a78dd84e8f8 (patch)
tree07ff665c67e41aadff205332bad80cb369f9f87e
parenta78a93e67e883db4d984bf673d1155a6906999fc (diff)
receive: don't fail inheriting (-x) properties on wrong dataset type
Receiving datasets while blanket inheriting properties like zfs receive -x mountpoint can generally be desirable, e.g. to avoid unexpected mounts on backup hosts. Currently this will fail to receive zvols due to the mountpoint property being applicable to filesystems only. This limitation currently requires operators to special-case their minds and tools for zvols. This change gets rid of this limitation for inherit (-x) by Spiting up the dataset type handling: Warnings for inheriting (-x), errors for overriding (-o). Reviewed-by: Paul Dagnelie <pcd@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #11416 Closes #11840 Closes #11864
-rw-r--r--lib/libzfs/libzfs_sendrecv.c46
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh15
2 files changed, 38 insertions, 23 deletions
diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c
index 2f39cc246..00723ff52 100644
--- a/lib/libzfs/libzfs_sendrecv.c
+++ b/lib/libzfs/libzfs_sendrecv.c
@@ -3956,24 +3956,6 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
if (prop == ZFS_PROP_ORIGIN)
continue;
- /*
- * we're trying to override or exclude a property that does not
- * make sense for this type of dataset, but we don't want to
- * fail if the receive is recursive: this comes in handy when
- * the send stream contains, for instance, a child ZVOL and
- * we're trying to receive it with "-o atime=on"
- */
- if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
- !zfs_prop_user(name)) {
- if (recursive)
- continue;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "property '%s' does not apply to datasets of this "
- "type"), name);
- ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto error;
- }
-
/* raw streams can't override encryption properties */
if ((zfs_prop_encryption_key_param(prop) ||
prop == ZFS_PROP_ENCRYPTION) && raw) {
@@ -4002,6 +3984,16 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
* a property: this is done by forcing an explicit
* inherit on the destination so the effective value is
* not the one we received from the send stream.
+ */
+ if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
+ !zfs_prop_user(name)) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "Warning: %s: property '%s' does not "
+ "apply to datasets of this type\n"),
+ fsname, name);
+ continue;
+ }
+ /*
* We do this only if the property is not already
* locally-set, in which case its value will take
* priority over the received anyway.
@@ -4029,6 +4021,24 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
fnvlist_add_nvpair(*oxprops, nvp);
break;
case DATA_TYPE_STRING: /* -o property=value */
+ /*
+ * we're trying to override a property that does not
+ * make sense for this type of dataset, but we don't
+ * want to fail if the receive is recursive: this comes
+ * in handy when the send stream contains, for
+ * instance, a child ZVOL and we're trying to receive
+ * it with "-o atime=on"
+ */
+ if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
+ !zfs_prop_user(name)) {
+ if (recursive)
+ continue;
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "property '%s' does not apply to datasets "
+ "of this type"), name);
+ ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
+ goto error;
+ }
fnvlist_add_nvpair(oprops, nvp);
break;
default:
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh
index 6f897a96f..2d3c15c62 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh
@@ -259,16 +259,21 @@ log_must zfs destroy -r -f $orig
log_must zfs destroy -r -f $dest
#
-# 3.7 Verify we can't receive a send stream overriding or excluding properties
-# invalid for the dataset type unless the stream it's recursive, in which
-# case only the appropriate properties are set on the destination.
-#
+# 3.7 Verify we can receive a send stream excluding but not overriding
+# properties invalid for the dataset type, in which case only the
+# appropriate properties are set on the destination.
log_must zfs create -V 128K -s $orig
log_must zfs snapshot $orig@snap1
log_must eval "zfs send $orig@snap1 > $streamfile_full"
-log_mustnot eval "zfs receive -x atime $dest < $streamfile_full"
log_mustnot eval "zfs receive -o atime=off $dest < $streamfile_full"
+log_mustnot eval "zfs receive -o atime=off -x canmount $dest < $streamfile_full"
+log_must eval "zfs receive -x atime -x canmount $dest < $streamfile_full"
+log_must eval "check_prop_source $dest type volume -"
+log_must eval "check_prop_source $dest atime - -"
+log_must eval "check_prop_source $dest canmount - -"
log_must_busy zfs destroy -r -f $orig
+log_must_busy zfs destroy -r -f $dest
+# Recursive sends also accept (and ignore) such overrides
log_must zfs create $orig
log_must zfs create -V 128K -s $origsub
log_must zfs snapshot -r $orig@snap1