]> granicus.if.org Git - zfs/commitdiff
Fix zfs incremental send remove '-o' properties
authorLOLi <loli10K@users.noreply.github.com>
Tue, 1 May 2018 03:58:29 +0000 (05:58 +0200)
committerTony Hutter <hutter2@llnl.gov>
Fri, 6 Jul 2018 09:46:51 +0000 (02:46 -0700)
When receiving an incremental send stream with intermediary snapshots
zfs_receive_one() does not correctly identify the top-level dataset:
consequently we restore said snapshots as if they were children
datasets in the hierarchy, forcing inheritance of any property received
with 'zfs send -o' and effectively removing any locally set value.

The test case did not correctly verify this situation because it uses
adjacent snapshots, basically testing 'zfs send -i' instead of
'zfs send -I': this commit adds an additional intermediary snapshot to
the test script.

Reviewed-by: Paul Dagnelie <pcd@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #7478

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

index 5490581abe38ef79e28a2e078f5de389479c69c4..c5acd21a522266fdaa97e9c4b93e30678316da04 100644 (file)
@@ -3592,7 +3592,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                goto out;
        }
 
-       if (top_zfs && *top_zfs == NULL)
+       if (top_zfs && (*top_zfs == NULL || strcmp(*top_zfs, name) == 0))
                toplevel = B_TRUE;
        if (drrb->drr_type == DMU_OST_ZVOL) {
                type = ZFS_TYPE_VOLUME;
index e4e69851f3857e62b780c1c5fc8ac36bdf949ee2..4e3a53933472a0091f2eae451053e5d4d724b600 100755 (executable)
@@ -212,16 +212,17 @@ log_must eval "zfs send -R $orig@snap1 > $streamfile_repl"
 log_must eval "zfs recv $dest < $streamfile_repl"
 # Fill the datasets with properties and create an incremental replication stream
 log_must zfs snapshot -r $orig@snap2
+log_must zfs snapshot -r $orig@snap3
 log_must eval "zfs set copies=2 $orig"
 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_incr"
+log_must eval "zfs set '$userprop:snap'='$userval' $origsub@snap3"
+log_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr"
 # Sets various combination of override and exclude options
 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_incr"
+       "-x '$userprop:snap3' $dest < $streamfile_incr"
 # Verify we can correctly override and exclude properties
 log_must eval "check_prop_source $dest copies 2 received"
 log_must eval "check_prop_source $dest atime off local"
@@ -237,9 +238,9 @@ log_must eval "check_prop_missing $destsub '$userprop:orig'"
 log_must eval "check_prop_source " \
        "$dest@snap1 '$userprop:snap' '$userval' received"
 log_must eval "check_prop_source " \
-       "$destsub@snap2 '$userprop:snap' '$userval' received"
-log_must eval "check_prop_missing $dest@snap2 '$userprop:snap2'"
-log_must eval "check_prop_missing $destsub@snap2 '$userprop:snap2'"
+       "$destsub@snap3 '$userprop:snap' '$userval' received"
+log_must eval "check_prop_missing $dest@snap3 '$userprop:snap3'"
+log_must eval "check_prop_missing $destsub@snap3 '$userprop:snap3'"
 # Cleanup
 log_must zfs destroy -r -f $orig
 log_must zfs destroy -r -f $dest
@@ -270,7 +271,8 @@ log_must eval "zfs set compression=gzip $dest"
 log_must eval "zfs set '$userprop:dest'='localval' $dest"
 # Receive the new stream, verify we preserve locally set properties
 log_must zfs snapshot -r $orig@snap2
-log_must eval "zfs send -R -I $orig@snap1 $orig@snap2 > $streamfile_incr"
+log_must zfs snapshot -r $orig@snap3
+log_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr"
 log_must eval "zfs recv -F -x copies -x compression -x '$userprop:orig' " \
        "-x '$userprop:dest' $dest < $streamfile_incr"
 log_must eval "check_prop_source $dest '$userprop:dest' 'localval' local"
@@ -305,7 +307,8 @@ log_must eval "check_prop_source $destsub quota 0 default"
 log_must eval "zfs set quota=123456789 $dest"
 log_must eval "zfs set canmount=off $destsub"
 log_must zfs snapshot -r $orig@snap2
-log_must eval "zfs send -R -I $orig@snap1 $orig@snap2 > $streamfile_incr"
+log_must zfs snapshot -r $orig@snap3
+log_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr"
 log_must eval "zfs recv -F -x quota -x canmount $dest < $streamfile_incr"
 log_must eval "check_prop_source $dest quota 123456789 local"
 log_must eval "check_prop_source $destsub quota 0 default"
@@ -332,7 +335,8 @@ log_must eval "zfs set '$userprop:origsub'='$userval' $destsub"
 mntpnt=$(get_prop mountpoint $orig)
 log_must eval "dd if=/dev/urandom of=$mntpnt/file bs=1024k count=10"
 log_must zfs snapshot -r $orig@snap2
-log_must eval "zfs send -R -I $orig@snap1 $orig@snap2 > $streamfile_incr"
+log_must zfs snapshot -r $orig@snap3
+log_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr"
 log_must eval "dd if=$streamfile_incr of=$streamfile_trun bs=1024k count=9"
 # Receive the truncated stream, verify original properties are kept
 log_mustnot eval "zfs recv -F -o copies=3 -o quota=987654321 "\