Skip to content

Commit

Permalink
Don't inherit locally set properties
Browse files Browse the repository at this point in the history
  • Loading branch information
loli10K committed Jan 9, 2017
1 parent 4b046f3 commit bdce0c5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
24 changes: 18 additions & 6 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3073,13 +3073,14 @@ recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
/*
* Prepare a new nvlist of properties that are to override (-o) or be excluded
* (-x) from the received dataset
* cmdprops: input properties from command line (nvlist)
* oxprops: output properties (nvlist)
* cmdprops: input properties from command line
* origprops: original properties if the destination exists, NULL otherwise
* oxprops: output override (-o) and excluded (-x) properties
*/
static int
zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, boolean_t zoned,
boolean_t recursive, boolean_t toplevel, nvlist_t *cmdprops,
nvlist_t **oxprops, const char *errbuf)
nvlist_t *origprops, nvlist_t **oxprops, const char *errbuf)
{
nvpair_t *nvp;
nvlist_t *oprops, *voprops;
Expand Down Expand Up @@ -3124,7 +3125,8 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type, boolean_t zoned,

switch (nvpair_type(nvp)) {
case DATA_TYPE_BOOLEAN: /* -x property */
fnvlist_add_nvpair(*oxprops, nvp);
if (!nvlist_exists(origprops, name))
fnvlist_add_nvpair(*oxprops, nvp);
break;
case DATA_TYPE_STRING: /* -o property=value */
fnvlist_add_nvpair(oprops, nvp);
Expand Down Expand Up @@ -3197,7 +3199,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
char origin[MAXNAMELEN];
char name[MAXPATHLEN];
nvlist_t *rcvprops = NULL; /* props received from the send stream */
nvlist_t *oxprops = NULL; /* props passed via the cli (-o|-x) */
nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
nvlist_t *origprops = NULL; /* original props (if destination exists) */
zfs_type_t type;
boolean_t toplevel;
boolean_t zoned = B_FALSE;
Expand Down Expand Up @@ -3482,6 +3485,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
/* we want to know if we're zoned when validating -o|-x props */
zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);

/* gather existing properties on destination dataset */
(void) zfs_refresh_properties(zhp);
origprops = fnvlist_alloc();
(void) fnvlist_merge(origprops, zhp->zfs_props);
(void) fnvlist_merge(origprops, zhp->zfs_user_props);

zfs_close(zhp);
} else {
/*
Expand Down Expand Up @@ -3534,7 +3543,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
else
type = ZFS_TYPE_FILESYSTEM;
if ((err = zfs_setup_cmdline_props(hdl, type, zoned, recursive,
toplevel, cmdprops, &oxprops, errbuf)) != 0)
toplevel, cmdprops, origprops, &oxprops, errbuf)) != 0)
goto out;

err = ioctl_err = lzc_receive_one(destsnap, rcvprops, oxprops, origin,
Expand Down Expand Up @@ -3755,6 +3764,9 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
if (newprops)
nvlist_free(rcvprops);

if (origprops != NULL)
nvlist_free(origprops);

return (err);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ destsub=$dest/sub
typeset userprop=$(valid_user_property 8)
typeset userval=$(user_property_value 8)
typeset streamfile_full=/var/tmp/streamfile_full.$$
typeset streamfile_repl=/var/tmp/streamfile_repl.$$
typeset streamfile_repl1=/var/tmp/streamfile_repl1.$$
typeset streamfile_repl2=/var/tmp/streamfile_repl2.$$

function cleanup
{
log_must $RM $streamfile_full
log_must $RM $streamfile_repl
log_must $RM $streamfile_repl1
log_must $RM $streamfile_repl2
log_must $ZFS destroy -rf $orig
log_must $ZFS destroy -rf $dest
}
Expand Down Expand Up @@ -147,6 +149,7 @@ log_must $ZFS create $origsub
# 2. Snapshot the filesystems.
log_must $ZFS snapshot $orig@snap1
log_must $ZFS snapshot -r $orig@snap2
log_must $ZFS snapshot -r $orig@snap3

# 3. Create a full stream without properties.
log_must eval "$ZFS send $orig@snap1 > $streamfile_full"
Expand All @@ -156,7 +159,8 @@ log_must eval "$ZFS set '$userprop:orig'='$userval' $orig"
log_must eval "$ZFS set '$userprop:orig'='$userval' $origsub"
log_must eval "$ZFS set '$userprop:snap'='$userval' $orig@snap1"
log_must eval "$ZFS set '$userprop:snap'='$userval' $origsub@snap2"
log_must eval "$ZFS send -R -I $orig@snap1 $orig@snap2 > $streamfile_repl"
log_must eval "$ZFS send -R -I $orig@snap1 $orig@snap2 > $streamfile_repl1"
log_must eval "$ZFS send -R -I $orig@snap2 $orig@snap3 > $streamfile_repl2"

# 5. Receive the send streams and verify we can override properties.
# 5.1 Error results if the same property is specified in multiple -o or
Expand All @@ -179,7 +183,7 @@ log_must eval "check_prop_source $dest '$userprop:dest1' '$userval' local"
# properties for an incremental replication send stream.
log_must eval "$ZFS recv -F -o atime=off -o '$userprop:dest2'='$userval' "\
"-o quota=123456789 -x compression -x '$userprop:orig' -x '$userprop:snap2' "\
"$dest < $streamfile_repl"
"$dest < $streamfile_repl1"
log_must eval "check_prop_source $dest atime off local"
log_must eval "check_prop_source $dest '$userprop:dest2' '$userval' local"
log_must eval "check_prop_source $dest quota 123456789 local"
Expand All @@ -194,4 +198,10 @@ log_must eval "check_prop_received $destsub@snap2 '$userprop:snap'"
log_must eval "check_prop_missing $dest@snap2 '$userprop:snap2'"
log_must eval "check_prop_missing $destsub@snap2 '$userprop:snap2'"


# 5.4 Verify -x property does not remove existing local properties
log_must eval "$ZFS set '$userprop:orig'='newval' $destsub"
log_must eval "$ZFS recv -F -x '$userprop:orig' $dest < $streamfile_repl2"
log_must eval "check_prop_source $destsub '$userprop:orig' 'newval' local"

log_pass "ZFS receive property override options passed."

0 comments on commit bdce0c5

Please sign in to comment.