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