1*6ccda740Sloli#!/bin/ksh -p 2*6ccda740Sloli# 3*6ccda740Sloli# CDDL HEADER START 4*6ccda740Sloli# 5*6ccda740Sloli# This file and its contents are supplied under the terms of the 6*6ccda740Sloli# Common Development and Distribution License ("CDDL"), version 1.0. 7*6ccda740Sloli# You may only use this file in accordance with the terms of version 8*6ccda740Sloli# 1.0 of the CDDL. 9*6ccda740Sloli# 10*6ccda740Sloli# A full copy of the text of the CDDL should have accompanied this 11*6ccda740Sloli# source. A copy of the CDDL is also available via the Internet at 12*6ccda740Sloli# http://www.illumos.org/license/CDDL. 13*6ccda740Sloli# 14*6ccda740Sloli# CDDL HEADER END 15*6ccda740Sloli# 16*6ccda740Sloli 17*6ccda740Sloli# 18*6ccda740Sloli# Copyright 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved. 19*6ccda740Sloli# 20*6ccda740Sloli 21*6ccda740Sloli. $STF_SUITE/include/libtest.shlib 22*6ccda740Sloli. $STF_SUITE/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib 23*6ccda740Sloli 24*6ccda740Sloli# 25*6ccda740Sloli# DESCRIPTION: 26*6ccda740Sloli# Verify ZFS property override (-o) and exclude (-x) options work when 27*6ccda740Sloli# receiving a send stream 28*6ccda740Sloli# 29*6ccda740Sloli# STRATEGY: 30*6ccda740Sloli# 1. Create a filesystem with children. 31*6ccda740Sloli# 2. Snapshot the filesystems. 32*6ccda740Sloli# 3. Create various send streams (full, incremental, replication) and verify 33*6ccda740Sloli# we can both override and exclude native and user properties. 34*6ccda740Sloli# 35*6ccda740Sloli 36*6ccda740Sloliverify_runnable "both" 37*6ccda740Sloli 38*6ccda740Slolifunction cleanup 39*6ccda740Sloli{ 40*6ccda740Sloli log_must rm -f $streamfile_full 41*6ccda740Sloli log_must rm -f $streamfile_incr 42*6ccda740Sloli log_must rm -f $streamfile_repl 43*6ccda740Sloli log_must rm -f $streamfile_trun 44*6ccda740Sloli destroy_dataset "$orig" "-rf" 45*6ccda740Sloli destroy_dataset "$dest" "-rf" 46*6ccda740Sloli} 47*6ccda740Sloli 48*6ccda740Slolilog_assert "ZFS receive property override and exclude options work as expected." 49*6ccda740Slolilog_onexit cleanup 50*6ccda740Sloli 51*6ccda740Sloliorig=$TESTPOOL/$TESTFS1 52*6ccda740Sloliorigsub=$orig/sub 53*6ccda740Slolidest=$TESTPOOL/$TESTFS2 54*6ccda740Slolidestsub=$dest/sub 55*6ccda740Slolitypeset userprop=$(valid_user_property 8) 56*6ccda740Slolitypeset userval=$(user_property_value 8) 57*6ccda740Slolitypeset streamfile_full=$TESTDIR/streamfile_full.$$ 58*6ccda740Slolitypeset streamfile_incr=$TESTDIR/streamfile_incr.$$ 59*6ccda740Slolitypeset streamfile_repl=$TESTDIR/streamfile_repl.$$ 60*6ccda740Slolitypeset streamfile_trun=$TESTDIR/streamfile_trun.$$ 61*6ccda740Sloli 62*6ccda740Sloli# 63*6ccda740Sloli# 3.1 Verify we can't specify the same property in multiple -o or -x options 64*6ccda740Sloli# or an invalid value was specified. 65*6ccda740Sloli# 66*6ccda740Sloli# Create a full send stream 67*6ccda740Slolilog_must zfs create $orig 68*6ccda740Slolilog_must zfs snapshot $orig@snap1 69*6ccda740Slolilog_must eval "zfs send $orig@snap1 > $streamfile_full" 70*6ccda740Sloli# Verify we reject invalid options 71*6ccda740Slolilog_mustnot eval "zfs recv $dest -o atime < $streamfile_full" 72*6ccda740Slolilog_mustnot eval "zfs recv $dest -x atime=off < $streamfile_full" 73*6ccda740Slolilog_mustnot eval "zfs recv $dest -o atime=off -x atime < $streamfile_full" 74*6ccda740Slolilog_mustnot eval "zfs recv $dest -o atime=off -o atime=on < $streamfile_full" 75*6ccda740Slolilog_mustnot eval "zfs recv $dest -x atime -x atime < $streamfile_full" 76*6ccda740Slolilog_mustnot eval "zfs recv $dest -o version=1 < $streamfile_full" 77*6ccda740Slolilog_mustnot eval "zfs recv $dest -x version < $streamfile_full" 78*6ccda740Slolilog_mustnot eval "zfs recv $dest -x normalization < $streamfile_full" 79*6ccda740Sloli# Verify we also reject invalid ZVOL options 80*6ccda740Slolilog_must zfs create -V 32K -s $orig/zvol 81*6ccda740Slolilog_must eval "zfs send $orig@snap1 > $streamfile_full" 82*6ccda740Slolilog_mustnot eval "zfs recv $dest -x volsize < $streamfile_full" 83*6ccda740Slolilog_mustnot eval "zfs recv $dest -o volsize=32K < $streamfile_full" 84*6ccda740Sloli# Cleanup 85*6ccda740Sloliblock_device_wait 86*6ccda740Slolilog_must_busy zfs destroy -r -f $orig 87*6ccda740Sloli 88*6ccda740Sloli# 89*6ccda740Sloli# 3.2 Verify -o property=value works on streams without properties. 90*6ccda740Sloli# 91*6ccda740Sloli# Create a full send stream 92*6ccda740Slolilog_must zfs create $orig 93*6ccda740Slolilog_must zfs snapshot $orig@snap1 94*6ccda740Slolilog_must eval "zfs send $orig@snap1 > $streamfile_full" 95*6ccda740Sloli# Receive the full stream, override some properties 96*6ccda740Slolilog_must eval "zfs recv -o compression=on -o '$userprop:dest'='$userval' "\ 97*6ccda740Sloli "$dest < $streamfile_full" 98*6ccda740Slolilog_must eval "check_prop_source $dest compression on local" 99*6ccda740Slolilog_must eval "check_prop_source $dest '$userprop:dest' '$userval' local" 100*6ccda740Sloli# Cleanup 101*6ccda740Slolilog_must zfs destroy -r -f $orig 102*6ccda740Slolilog_must zfs destroy -r -f $dest 103*6ccda740Sloli 104*6ccda740Sloli# 105*6ccda740Sloli# 3.3 Verify -o property=value and -x work on both native and user properties 106*6ccda740Sloli# for an incremental replication send stream. 107*6ccda740Sloli# 108*6ccda740Sloli# Create a dataset tree and receive it 109*6ccda740Slolilog_must zfs create $orig 110*6ccda740Slolilog_must zfs create $origsub 111*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 112*6ccda740Slolilog_must eval "zfs send -R $orig@snap1 > $streamfile_repl" 113*6ccda740Slolilog_must eval "zfs recv $dest < $streamfile_repl" 114*6ccda740Sloli# Fill the datasets with properties and create an incremental replication stream 115*6ccda740Slolilog_must zfs snapshot -r $orig@snap2 116*6ccda740Slolilog_must zfs snapshot -r $orig@snap3 117*6ccda740Slolilog_must eval "zfs set copies=2 $orig" 118*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='$userval' $orig" 119*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='$userval' $origsub" 120*6ccda740Slolilog_must eval "zfs set '$userprop:snap'='$userval' $orig@snap1" 121*6ccda740Slolilog_must eval "zfs set '$userprop:snap'='$userval' $origsub@snap3" 122*6ccda740Slolilog_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr" 123*6ccda740Sloli# Sets various combination of override and exclude options 124*6ccda740Slolilog_must eval "zfs recv -F -o atime=off -o '$userprop:dest2'='$userval' "\ 125*6ccda740Sloli "-o quota=123456789 -x compression "\ 126*6ccda740Sloli "-x '$userprop:orig' -x '$userprop:snap3' $dest < $streamfile_incr" 127*6ccda740Sloli# Verify we can correctly override and exclude properties 128*6ccda740Slolilog_must eval "check_prop_source $dest copies 2 received" 129*6ccda740Slolilog_must eval "check_prop_source $dest atime off local" 130*6ccda740Slolilog_must eval "check_prop_source $dest '$userprop:dest2' '$userval' local" 131*6ccda740Slolilog_must eval "check_prop_source $dest quota 123456789 local" 132*6ccda740Slolilog_must eval "check_prop_inherit $destsub copies $dest" 133*6ccda740Slolilog_must eval "check_prop_inherit $destsub atime $dest" 134*6ccda740Slolilog_must eval "check_prop_inherit $destsub '$userprop:dest2' $dest" 135*6ccda740Slolilog_must eval "check_prop_source $destsub quota 0 default" 136*6ccda740Slolilog_must eval "check_prop_source $destsub compression off default" 137*6ccda740Slolilog_must eval "check_prop_missing $dest '$userprop:orig'" 138*6ccda740Slolilog_must eval "check_prop_missing $destsub '$userprop:orig'" 139*6ccda740Slolilog_must eval "check_prop_source " \ 140*6ccda740Sloli "$dest@snap1 '$userprop:snap' '$userval' received" 141*6ccda740Slolilog_must eval "check_prop_source " \ 142*6ccda740Sloli "$destsub@snap3 '$userprop:snap' '$userval' received" 143*6ccda740Slolilog_must eval "check_prop_missing $dest@snap3 '$userprop:snap3'" 144*6ccda740Slolilog_must eval "check_prop_missing $destsub@snap3 '$userprop:snap3'" 145*6ccda740Sloli# Cleanup 146*6ccda740Slolilog_must zfs destroy -r -f $orig 147*6ccda740Slolilog_must zfs destroy -r -f $dest 148*6ccda740Sloli 149*6ccda740Sloli# 150*6ccda740Sloli# 3.4 Verify '-x property' does not remove existing local properties and a 151*6ccda740Sloli# modified sent property is received and updated to the new value but can 152*6ccda740Sloli# still be excluded. 153*6ccda740Sloli# 154*6ccda740Sloli# Create a dataset tree 155*6ccda740Slolilog_must zfs create $orig 156*6ccda740Slolilog_must zfs create $origsub 157*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 158*6ccda740Slolilog_must eval "zfs set copies=2 $orig" 159*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='oldval' $orig" 160*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='oldsubval' $origsub" 161*6ccda740Slolilog_must eval "zfs send -R $orig@snap1 > $streamfile_repl" 162*6ccda740Slolilog_must eval "zfs receive $dest < $streamfile_repl" 163*6ccda740Slolilog_must eval "check_prop_source $dest copies 2 received" 164*6ccda740Slolilog_must eval "check_prop_inherit $destsub copies $dest" 165*6ccda740Slolilog_must eval "check_prop_source $dest '$userprop:orig' 'oldval' received" 166*6ccda740Slolilog_must eval "check_prop_source $destsub '$userprop:orig' 'oldsubval' received" 167*6ccda740Sloli# Set new custom properties on both source and destination 168*6ccda740Slolilog_must eval "zfs set copies=3 $orig" 169*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='newval' $orig" 170*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='newsubval' $origsub" 171*6ccda740Slolilog_must eval "zfs set compression=gzip $dest" 172*6ccda740Slolilog_must eval "zfs set '$userprop:dest'='localval' $dest" 173*6ccda740Sloli# Receive the new stream, verify we preserve locally set properties 174*6ccda740Slolilog_must zfs snapshot -r $orig@snap2 175*6ccda740Slolilog_must zfs snapshot -r $orig@snap3 176*6ccda740Slolilog_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr" 177*6ccda740Slolilog_must eval "zfs recv -F -x copies -x compression -x '$userprop:orig' " \ 178*6ccda740Sloli "-x '$userprop:dest' $dest < $streamfile_incr" 179*6ccda740Slolilog_must eval "check_prop_source $dest '$userprop:dest' 'localval' local" 180*6ccda740Slolilog_must eval "check_prop_received $dest '$userprop:orig' 'newval'" 181*6ccda740Slolilog_must eval "check_prop_received $destsub '$userprop:orig' 'newsubval'" 182*6ccda740Slolilog_must eval "check_prop_missing $dest '$userprop:orig'" 183*6ccda740Slolilog_must eval "check_prop_missing $destsub '$userprop:orig'" 184*6ccda740Slolilog_must eval "check_prop_source $dest copies 1 default" 185*6ccda740Slolilog_must eval "check_prop_received $dest copies 3" 186*6ccda740Slolilog_must eval "check_prop_source $destsub copies 1 default" 187*6ccda740Slolilog_must eval "check_prop_received $destsub copies '-'" 188*6ccda740Slolilog_must eval "check_prop_source $dest compression gzip local" 189*6ccda740Slolilog_must eval "check_prop_inherit $destsub compression $dest" 190*6ccda740Sloli# Cleanup 191*6ccda740Slolilog_must zfs destroy -r -f $orig 192*6ccda740Slolilog_must zfs destroy -r -f $dest 193*6ccda740Sloli 194*6ccda740Sloli# 195*6ccda740Sloli# 3.5 Verify we can exclude non-inheritable properties from a send stream 196*6ccda740Sloli# 197*6ccda740Sloli# Create a dataset tree and replication stream 198*6ccda740Slolilog_must zfs create $orig 199*6ccda740Slolilog_must zfs create $origsub 200*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 201*6ccda740Slolilog_must eval "zfs set quota=123456789 $orig" 202*6ccda740Slolilog_must eval "zfs send -R $orig@snap1 > $streamfile_repl" 203*6ccda740Sloli# Receive the stream excluding non-inheritable properties 204*6ccda740Slolilog_must eval "zfs recv -F -x quota $dest < $streamfile_repl" 205*6ccda740Slolilog_must eval "check_prop_source $dest quota 0 default" 206*6ccda740Slolilog_must eval "check_prop_source $destsub quota 0 default" 207*6ccda740Sloli# Set some non-inheritable properties on the destination, verify we keep them 208*6ccda740Slolilog_must eval "zfs set quota=123456789 $dest" 209*6ccda740Slolilog_must eval "zfs set canmount=off $destsub" 210*6ccda740Slolilog_must zfs snapshot -r $orig@snap2 211*6ccda740Slolilog_must zfs snapshot -r $orig@snap3 212*6ccda740Slolilog_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr" 213*6ccda740Slolilog_must eval "zfs recv -F -x quota -x canmount $dest < $streamfile_incr" 214*6ccda740Slolilog_must eval "check_prop_source $dest quota 123456789 local" 215*6ccda740Slolilog_must eval "check_prop_source $destsub quota 0 default" 216*6ccda740Slolilog_must eval "check_prop_source $destsub canmount off local" 217*6ccda740Sloli# Cleanup 218*6ccda740Slolilog_must zfs destroy -r -f $orig 219*6ccda740Slolilog_must zfs destroy -r -f $dest 220*6ccda740Sloli 221*6ccda740Sloli# 222*6ccda740Sloli# 3.6 Verify we correctly restore existing properties on a failed receive 223*6ccda740Sloli# 224*6ccda740Sloli# Receive a "clean" dataset tree 225*6ccda740Slolilog_must zfs create $orig 226*6ccda740Slolilog_must zfs create $origsub 227*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 228*6ccda740Slolilog_must eval "zfs send -R $orig@snap1 > $streamfile_repl" 229*6ccda740Slolilog_must eval "zfs receive $dest < $streamfile_repl" 230*6ccda740Sloli# Set custom properties on the destination 231*6ccda740Slolilog_must eval "zfs set atime=off $dest" 232*6ccda740Slolilog_must eval "zfs set quota=123456789 $dest" 233*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='$userval' $dest" 234*6ccda740Slolilog_must eval "zfs set '$userprop:origsub'='$userval' $destsub" 235*6ccda740Sloli# Create a truncated incremental replication stream 236*6ccda740Slolimntpnt=$(get_prop mountpoint $orig) 237*6ccda740Slolilog_must eval "dd if=/dev/urandom of=$mntpnt/file bs=1024k count=10" 238*6ccda740Slolilog_must zfs snapshot -r $orig@snap2 239*6ccda740Slolilog_must zfs snapshot -r $orig@snap3 240*6ccda740Slolilog_must eval "zfs send -R -I $orig@snap1 $orig@snap3 > $streamfile_incr" 241*6ccda740Slolilog_must eval "dd if=$streamfile_incr of=$streamfile_trun bs=1024k count=9" 242*6ccda740Sloli# Receive the truncated stream, verify original properties are kept 243*6ccda740Slolilog_mustnot eval "zfs recv -F -o copies=3 -o quota=987654321 "\ 244*6ccda740Sloli "-o '$userprop:new'='badval' $dest < $streamfile_trun" 245*6ccda740Slolilog_must eval "check_prop_source $dest copies 1 default" 246*6ccda740Slolilog_must eval "check_prop_source $destsub copies 1 default" 247*6ccda740Slolilog_must eval "check_prop_source $dest atime off local" 248*6ccda740Slolilog_must eval "check_prop_inherit $destsub atime $dest" 249*6ccda740Slolilog_must eval "check_prop_source $dest quota 123456789 local" 250*6ccda740Slolilog_must eval "check_prop_source $destsub quota 0 default" 251*6ccda740Slolilog_must eval "check_prop_source $dest '$userprop:orig' '$userval' local" 252*6ccda740Slolilog_must eval "check_prop_inherit $destsub '$userprop:orig' $dest" 253*6ccda740Slolilog_must eval "check_prop_source $destsub '$userprop:origsub' '$userval' local" 254*6ccda740Slolilog_must eval "check_prop_missing $dest '$userprop:new'" 255*6ccda740Sloli# Cleanup 256*6ccda740Slolilog_must zfs destroy -r -f $orig 257*6ccda740Slolilog_must zfs destroy -r -f $dest 258*6ccda740Sloli 259*6ccda740Sloli# 260*6ccda740Sloli# 3.7 Verify we can't receive a send stream overriding or excluding properties 261*6ccda740Sloli# invalid for the dataset type unless the stream it's recursive, in which 262*6ccda740Sloli# case only the appropriate properties are set on the destination. 263*6ccda740Sloli# 264*6ccda740Slolilog_must zfs create -V 128K -s $orig 265*6ccda740Slolilog_must zfs snapshot $orig@snap1 266*6ccda740Slolilog_must eval "zfs send $orig@snap1 > $streamfile_full" 267*6ccda740Slolilog_mustnot eval "zfs receive -x atime $dest < $streamfile_full" 268*6ccda740Slolilog_mustnot eval "zfs receive -o atime=off $dest < $streamfile_full" 269*6ccda740Slolilog_must_busy zfs destroy -r -f $orig 270*6ccda740Slolilog_must zfs create $orig 271*6ccda740Slolilog_must zfs create -V 128K -s $origsub 272*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 273*6ccda740Slolilog_must eval "zfs send -R $orig@snap1 > $streamfile_repl" 274*6ccda740Slolilog_must eval "zfs receive -o atime=off $dest < $streamfile_repl" 275*6ccda740Slolilog_must eval "check_prop_source $dest type filesystem -" 276*6ccda740Slolilog_must eval "check_prop_source $dest atime off local" 277*6ccda740Slolilog_must eval "check_prop_source $destsub type volume -" 278*6ccda740Slolilog_must eval "check_prop_source $destsub atime - -" 279*6ccda740Sloli# Cleanup 280*6ccda740Sloliblock_device_wait 281*6ccda740Slolilog_must_busy zfs destroy -r -f $orig 282*6ccda740Slolilog_must_busy zfs destroy -r -f $dest 283*6ccda740Sloli 284*6ccda740Sloli# 285*6ccda740Sloli# 3.8 Verify 'zfs recv -x|-o' works correctly when used in conjunction with -d 286*6ccda740Sloli# and -e options. 287*6ccda740Sloli# 288*6ccda740Slolilog_must zfs create -p $orig/1/2/3/4 289*6ccda740Slolilog_must eval "zfs set copies=2 $orig" 290*6ccda740Slolilog_must eval "zfs set atime=on $orig" 291*6ccda740Slolilog_must eval "zfs set '$userprop:orig'='oldval' $orig" 292*6ccda740Slolilog_must zfs snapshot -r $orig@snap1 293*6ccda740Slolilog_must eval "zfs send -R $orig/1/2@snap1 > $streamfile_repl" 294*6ccda740Sloli# Verify 'zfs recv -e' 295*6ccda740Slolilog_must zfs create $dest 296*6ccda740Slolilog_must eval "zfs receive -e -o copies=3 -x atime "\ 297*6ccda740Sloli "-o '$userprop:orig'='newval' $dest < $streamfile_repl" 298*6ccda740Slolilog_must datasetexists $dest/2/3/4 299*6ccda740Slolilog_must eval "check_prop_source $dest/2 copies 3 local" 300*6ccda740Slolilog_must eval "check_prop_inherit $dest/2/3/4 copies $dest/2" 301*6ccda740Slolilog_must eval "check_prop_source $dest/2/3/4 atime on default" 302*6ccda740Slolilog_must eval "check_prop_source $dest/2 '$userprop:orig' 'newval' local" 303*6ccda740Slolilog_must eval "check_prop_inherit $dest/2/3/4 '$userprop:orig' $dest/2" 304*6ccda740Slolilog_must zfs destroy -r -f $dest 305*6ccda740Sloli# Verify 'zfs recv -d' 306*6ccda740Slolilog_must zfs create $dest 307*6ccda740Slolitypeset fs="$(echo $orig | awk -F'/' '{print $NF}')" 308*6ccda740Slolilog_must eval "zfs receive -d -o copies=3 -x atime "\ 309*6ccda740Sloli "-o '$userprop:orig'='newval' $dest < $streamfile_repl" 310*6ccda740Slolilog_must datasetexists $dest/$fs/1/2/3/4 311*6ccda740Slolilog_must eval "check_prop_source $dest/$fs/1/2 copies 3 local" 312*6ccda740Slolilog_must eval "check_prop_inherit $dest/$fs/1/2/3/4 copies $dest/$fs/1/2" 313*6ccda740Slolilog_must eval "check_prop_source $dest/$fs/1/2/3/4 atime on default" 314*6ccda740Slolilog_must eval "check_prop_source $dest/$fs/1/2 '$userprop:orig' 'newval' local" 315*6ccda740Slolilog_must eval "check_prop_inherit $dest/$fs/1/2/3/4 '$userprop:orig' $dest/$fs/1/2" 316*6ccda740Sloli# We don't need to cleanup here 317*6ccda740Sloli 318*6ccda740Slolilog_pass "ZFS receive property override and exclude options passed." 319