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