Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

receive: don't fail inheriting (-x) properties on wrong dataset type #11864

Merged
merged 1 commit into from
Apr 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3941,24 +3941,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) {
Expand Down Expand Up @@ -3987,6 +3969,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.
Expand Down Expand Up @@ -4014,6 +4006,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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down