]> granicus.if.org Git - zfs/commitdiff
Fix 'zfs receive -o' when used with '-e|-d'
authorLOLi <loli10K@users.noreply.github.com>
Tue, 30 Jan 2018 23:54:33 +0000 (00:54 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 30 Jan 2018 23:54:33 +0000 (15:54 -0800)
When used in conjunction with one of '-e' or '-d' zfs receive options
none of the properties requested to be set (-o) are actually applied:
this is caused by a wrong assumption made about the toplevel dataset
in zfs_receive_one().

Fix this by correctly detecting the toplevel dataset.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #7088

lib/libzfs/libzfs_sendrecv.c
tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh

index 934da54e1c1ea69c9598f58a01b8e372194c05b8..e12a9db43f918867cd971e7d82cf2e46792a3c54 100644 (file)
@@ -3603,7 +3603,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
        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 toplevel = B_FALSE;
        boolean_t zoned = B_FALSE;
 
        begin_time = time(NULL);
@@ -4013,7 +4013,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                goto out;
        }
 
-       toplevel = chopprefix[0] != '/';
+       if (top_zfs && *top_zfs == NULL)
+               toplevel = B_TRUE;
        if (drrb->drr_type == DMU_OST_ZVOL) {
                type = ZFS_TYPE_VOLUME;
        } else if (drrb->drr_type == DMU_OST_ZFS) {
index 7137fe278f98b9de418d374e4f65444a94b6b2d4..e4e69851f3857e62b780c1c5fc8ac36bdf949ee2 100755 (executable)
@@ -371,6 +371,42 @@ log_must eval "check_prop_source $dest type filesystem -"
 log_must eval "check_prop_source $dest atime off local"
 log_must eval "check_prop_source $destsub type volume -"
 log_must eval "check_prop_source $destsub atime - -"
+# Cleanup
+log_must zfs destroy -r -f $orig
+log_must zfs destroy -r -f $dest
+
+#
+# 3.8 Verify 'zfs recv -x|-o' works correctly when used in conjunction with -d
+#     and -e options.
+#
+log_must zfs create -p $orig/1/2/3/4
+log_must eval "zfs set copies=2 $orig"
+log_must eval "zfs set atime=on $orig"
+log_must eval "zfs set '$userprop:orig'='oldval' $orig"
+log_must zfs snapshot -r $orig@snap1
+log_must eval "zfs send -R $orig/1/2@snap1 > $streamfile_repl"
+# Verify 'zfs recv -e'
+log_must zfs create $dest
+log_must eval "zfs receive -e -o copies=3 -x atime "\
+       "-o '$userprop:orig'='newval' $dest < $streamfile_repl"
+log_must datasetexists $dest/2/3/4
+log_must eval "check_prop_source $dest/2 copies 3 local"
+log_must eval "check_prop_inherit $dest/2/3/4 copies $dest/2"
+log_must eval "check_prop_source $dest/2/3/4 atime on default"
+log_must eval "check_prop_source $dest/2 '$userprop:orig' 'newval' local"
+log_must eval "check_prop_inherit $dest/2/3/4 '$userprop:orig' $dest/2"
+log_must zfs destroy -r -f $dest
+# Verify 'zfs recv -d'
+log_must zfs create $dest
+typeset fs="$(echo $orig | awk -F'/' '{print $NF}')"
+log_must eval "zfs receive -d -o copies=3 -x atime "\
+       "-o '$userprop:orig'='newval' $dest < $streamfile_repl"
+log_must datasetexists $dest/$fs/1/2/3/4
+log_must eval "check_prop_source $dest/$fs/1/2 copies 3 local"
+log_must eval "check_prop_inherit $dest/$fs/1/2/3/4 copies $dest/$fs/1/2"
+log_must eval "check_prop_source $dest/$fs/1/2/3/4 atime on default"
+log_must eval "check_prop_source $dest/$fs/1/2 '$userprop:orig' 'newval' local"
+log_must eval "check_prop_inherit $dest/$fs/1/2/3/4 '$userprop:orig' $dest/$fs/1/2"
 # We don't need to cleanup here
 
 log_pass "ZFS receive property override and exclude options passed."