Skip to content

Commit b0269cd

Browse files
authored
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 <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: InsanePrawn <[email protected]> Closes #11416 Closes #11840 Closes #11864
1 parent f172f75 commit b0269cd

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

lib/libzfs/libzfs_sendrecv.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3951,24 +3951,6 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
39513951
if (prop == ZFS_PROP_ORIGIN)
39523952
continue;
39533953

3954-
/*
3955-
* we're trying to override or exclude a property that does not
3956-
* make sense for this type of dataset, but we don't want to
3957-
* fail if the receive is recursive: this comes in handy when
3958-
* the send stream contains, for instance, a child ZVOL and
3959-
* we're trying to receive it with "-o atime=on"
3960-
*/
3961-
if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
3962-
!zfs_prop_user(name)) {
3963-
if (recursive)
3964-
continue;
3965-
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3966-
"property '%s' does not apply to datasets of this "
3967-
"type"), name);
3968-
ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
3969-
goto error;
3970-
}
3971-
39723954
/* raw streams can't override encryption properties */
39733955
if ((zfs_prop_encryption_key_param(prop) ||
39743956
prop == ZFS_PROP_ENCRYPTION) && raw) {
@@ -3997,6 +3979,16 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
39973979
* a property: this is done by forcing an explicit
39983980
* inherit on the destination so the effective value is
39993981
* not the one we received from the send stream.
3982+
*/
3983+
if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
3984+
!zfs_prop_user(name)) {
3985+
(void) fprintf(stderr, dgettext(TEXT_DOMAIN,
3986+
"Warning: %s: property '%s' does not "
3987+
"apply to datasets of this type\n"),
3988+
fsname, name);
3989+
continue;
3990+
}
3991+
/*
40003992
* We do this only if the property is not already
40013993
* locally-set, in which case its value will take
40023994
* priority over the received anyway.
@@ -4024,6 +4016,24 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
40244016
fnvlist_add_nvpair(*oxprops, nvp);
40254017
break;
40264018
case DATA_TYPE_STRING: /* -o property=value */
4019+
/*
4020+
* we're trying to override a property that does not
4021+
* make sense for this type of dataset, but we don't
4022+
* want to fail if the receive is recursive: this comes
4023+
* in handy when the send stream contains, for
4024+
* instance, a child ZVOL and we're trying to receive
4025+
* it with "-o atime=on"
4026+
*/
4027+
if (!zfs_prop_valid_for_type(prop, type, B_FALSE) &&
4028+
!zfs_prop_user(name)) {
4029+
if (recursive)
4030+
continue;
4031+
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4032+
"property '%s' does not apply to datasets "
4033+
"of this type"), name);
4034+
ret = zfs_error(hdl, EZFS_BADPROP, errbuf);
4035+
goto error;
4036+
}
40274037
fnvlist_add_nvpair(oprops, nvp);
40284038
break;
40294039
default:

tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,16 +259,21 @@ log_must zfs destroy -r -f $orig
259259
log_must zfs destroy -r -f $dest
260260

261261
#
262-
# 3.7 Verify we can't receive a send stream overriding or excluding properties
263-
# invalid for the dataset type unless the stream it's recursive, in which
264-
# case only the appropriate properties are set on the destination.
265-
#
262+
# 3.7 Verify we can receive a send stream excluding but not overriding
263+
# properties invalid for the dataset type, in which case only the
264+
# appropriate properties are set on the destination.
266265
log_must zfs create -V 128K -s $orig
267266
log_must zfs snapshot $orig@snap1
268267
log_must eval "zfs send $orig@snap1 > $streamfile_full"
269-
log_mustnot eval "zfs receive -x atime $dest < $streamfile_full"
270268
log_mustnot eval "zfs receive -o atime=off $dest < $streamfile_full"
269+
log_mustnot eval "zfs receive -o atime=off -x canmount $dest < $streamfile_full"
270+
log_must eval "zfs receive -x atime -x canmount $dest < $streamfile_full"
271+
log_must eval "check_prop_source $dest type volume -"
272+
log_must eval "check_prop_source $dest atime - -"
273+
log_must eval "check_prop_source $dest canmount - -"
271274
log_must_busy zfs destroy -r -f $orig
275+
log_must_busy zfs destroy -r -f $dest
276+
# Recursive sends also accept (and ignore) such overrides
272277
log_must zfs create $orig
273278
log_must zfs create -V 128K -s $origsub
274279
log_must zfs snapshot -r $orig@snap1

0 commit comments

Comments
 (0)