]> git.proxmox.com Git - mirror_zfs.git/blame - tests/zfs-tests/tests/functional/rsend/rsend.kshlib
OpenZFS 2605, 6980, 6902
[mirror_zfs.git] / tests / zfs-tests / tests / functional / rsend / rsend.kshlib
CommitLineData
6bb24f4d
BB
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21
22#
23# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24# Use is subject to license terms.
25#
26
27#
28# Copyright (c) 2013, 2015 by Delphix. All rights reserved.
29#
30
31. $STF_SUITE/include/libtest.shlib
32. $STF_SUITE/tests/functional/rsend/rsend.cfg
33
34#
35# Set up test model which includes various datasets
36#
37# @final
38# @snapB
39# @init
40# |
41# ______ pclone
42# | /
43# |@psnap
44# || @final
45# ||@final @final @snapC
46# ||@snapC @snapC @snapB
47# ||@snapA @snapB @snapA
48# ||@init @init @init
49# ||| | |
50# $pool -------- $FS ------- fs1 ------- fs2
51# \ \\_____ \ |
52# vol vol \____ \ @fsnap
53# | | \ \ \
54# @init @vsnap | ------------ fclone
55# @snapA @init \ | |
56# @final @snapB \ | @init
57# @snapC vclone @snapA
58# @final | @final
59# @init
60# @snapC
61# @final
62#
63# $1 pool name
64#
65function setup_test_model
66{
67 typeset pool=$1
68
69 log_must $ZFS create -p $pool/$FS/fs1/fs2
70
71 log_must $ZFS snapshot $pool@psnap
72 log_must $ZFS clone $pool@psnap $pool/pclone
73
74 if is_global_zone ; then
75 log_must $ZFS create -V 16M $pool/vol
76 log_must $ZFS create -V 16M $pool/$FS/vol
47dfff3b 77 block_device_wait
6bb24f4d
BB
78
79 log_must $ZFS snapshot $pool/$FS/vol@vsnap
80 log_must $ZFS clone $pool/$FS/vol@vsnap $pool/$FS/vclone
47dfff3b 81 block_device_wait
6bb24f4d
BB
82 fi
83
84 log_must snapshot_tree $pool/$FS/fs1/fs2@fsnap
85 log_must $ZFS clone $pool/$FS/fs1/fs2@fsnap $pool/$FS/fs1/fclone
86 log_must $ZFS snapshot -r $pool@init
87
88 log_must snapshot_tree $pool@snapA
89 log_must snapshot_tree $pool@snapC
90 log_must snapshot_tree $pool/pclone@snapB
91 log_must snapshot_tree $pool/$FS@snapB
92 log_must snapshot_tree $pool/$FS@snapC
93 log_must snapshot_tree $pool/$FS/fs1@snapA
94 log_must snapshot_tree $pool/$FS/fs1@snapB
95 log_must snapshot_tree $pool/$FS/fs1@snapC
96 log_must snapshot_tree $pool/$FS/fs1/fclone@snapA
97
98 if is_global_zone ; then
99 log_must $ZFS snapshot $pool/vol@snapA
100 log_must $ZFS snapshot $pool/$FS/vol@snapB
101 log_must $ZFS snapshot $pool/$FS/vol@snapC
102 log_must $ZFS snapshot $pool/$FS/vclone@snapC
103 fi
104
105 log_must $ZFS snapshot -r $pool@final
106
107 return 0
108}
109
110#
111# Cleanup the BACKDIR and given pool content and all the sub datasets
112#
113# $1 pool name
114#
115function cleanup_pool
116{
117 typeset pool=$1
118 log_must $RM -rf $BACKDIR/*
119
120 if is_global_zone ; then
121 log_must $ZFS destroy -Rf $pool
122 else
123 typeset list=$($ZFS list -H -r -t filesystem,snapshot,volume -o name $pool)
124 for ds in $list ; do
125 if [[ $ds != $pool ]] ; then
126 if datasetexists $ds ; then
127 log_must $ZFS destroy -Rf $ds
128 fi
129 fi
130 done
131 fi
132
133 typeset mntpnt=$(get_prop mountpoint $pool)
134 if ! ismounted $pool ; then
135 # Make sure mountpoint directory is empty
136 if [[ -d $mntpnt ]]; then
137 log_must $RM -rf $mntpnt/*
138 fi
139
140 log_must $ZFS mount $pool
141 fi
142 if [[ -d $mntpnt ]]; then
143 log_must $RM -rf $mntpnt/*
144 fi
145
146 return 0
147}
148
149#
150# Detect if the given two filesystems have same sub-datasets
151#
152# $1 source filesystem
153# $2 destination filesystem
154#
155function cmp_ds_subs
156{
157 typeset src_fs=$1
158 typeset dst_fs=$2
159
160 $ZFS list -r -H -t filesystem,snapshot,volume -o name $src_fs > $BACKDIR/src1
161 $ZFS list -r -H -t filesystem,snapshot,volume -o name $dst_fs > $BACKDIR/dst1
162
163 eval $SED -e 's:^$src_fs:PREFIX:g' < $BACKDIR/src1 > $BACKDIR/src
164 eval $SED -e 's:^$dst_fs:PREFIX:g' < $BACKDIR/dst1 > $BACKDIR/dst
165
166 $DIFF $BACKDIR/src $BACKDIR/dst
167 typeset -i ret=$?
168
169 $RM -f $BACKDIR/src $BACKDIR/dst $BACKDIR/src1 $BACKDIR/dst1
170
171 return $ret
172}
173
174#
175# Compare all the directores and files in two filesystems
176#
177# $1 source filesystem
178# $2 destination filesystem
179#
180function cmp_ds_cont
181{
182 typeset src_fs=$1
183 typeset dst_fs=$2
184
185 typeset srcdir dstdir
186 srcdir=$(get_prop mountpoint $src_fs)
187 dstdir=$(get_prop mountpoint $dst_fs)
188
189 $DIFF -r $srcdir $dstdir > /dev/null 2>&1
190 echo $?
191}
192
193#
194# Compare the given two dataset properties
195#
196# $1 dataset 1
197# $2 dataset 2
198#
199function cmp_ds_prop
200{
201 typeset dtst1=$1
202 typeset dtst2=$2
203
47dfff3b 204 for item in "type" "origin" "volblocksize" "aclinherit" "acltype" \
6bb24f4d 205 "atime" "canmount" "checksum" "compression" "copies" "devices" \
50c957f7 206 "dnodesize" "exec" "quota" "readonly" "recordsize" "reservation" \
47dfff3b 207 "setuid" "snapdir" "version" "volsize" "xattr" "zoned" \
6bb24f4d
BB
208 "mountpoint";
209 do
210 $ZFS get -H -o property,value,source $item $dtst1 >> \
211 $BACKDIR/dtst1
212 $ZFS get -H -o property,value,source $item $dtst2 >> \
213 $BACKDIR/dtst2
214 done
215
216 eval $SED -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
217 eval $SED -e 's:$dtst2:PREFIX:g' < $BACKDIR/dtst2 > $BACKDIR/dtst2
218
219 $DIFF $BACKDIR/dtst1 $BACKDIR/dtst2
220 typeset -i ret=$?
221
222 $RM -f $BACKDIR/dtst1 $BACKDIR/dtst2
223
224 return $ret
225
226}
227
228#
229# Random create directories and files
230#
231# $1 directory
232#
233function random_tree
234{
235 typeset dir=$1
236
237 if [[ -d $dir ]]; then
238 $RM -rf $dir
239 fi
240 $MKDIR -p $dir
241 typeset -i ret=$?
242
243 typeset -i nl nd nf
244 ((nl = RANDOM % 6 + 1))
245 ((nd = RANDOM % 3 ))
246 ((nf = RANDOM % 5 ))
247 $MKTREE -b $dir -l $nl -d $nd -f $nf
248 ((ret |= $?))
249
250 return $ret
251}
252
253#
254# Put data in filesystem and take snapshot
255#
256# $1 snapshot name
257#
258function snapshot_tree
259{
260 typeset snap=$1
261 typeset ds=${snap%%@*}
262 typeset type=$(get_prop "type" $ds)
263
264 typeset -i ret=0
265 if [[ $type == "filesystem" ]]; then
266 typeset mntpnt=$(get_prop mountpoint $ds)
267 ((ret |= $?))
268
269 if ((ret == 0)) ; then
270 eval random_tree $mntpnt/${snap##$ds}
271 ((ret |= $?))
272 fi
273 fi
274
275 if ((ret == 0)) ; then
276 $ZFS snapshot $snap
277 ((ret |= $?))
278 fi
279
280 return $ret
281}
282
283#
284# Destroy the given snapshot and stuff
285#
286# $1 snapshot
287#
288function destroy_tree
289{
290 typeset -i ret=0
291 typeset snap
292 for snap in "$@" ; do
293 $ZFS destroy $snap
294 ret=$?
295
296 typeset ds=${snap%%@*}
297 typeset type=$(get_prop "type" $ds)
298 if [[ $type == "filesystem" ]]; then
299 typeset mntpnt=$(get_prop mountpoint $ds)
300 ((ret |= $?))
301
302 if ((ret != 0)); then
303 $RM -r $mntpnt/$snap
304 ((ret |= $?))
305 fi
306 fi
307
308 if ((ret != 0)); then
309 return $ret
310 fi
311 done
312
313 return 0
314}
315
316#
317# Get all the sub-datasets of give dataset with specific suffix
318#
319# $1 Given dataset
320# $2 Suffix
321#
322function getds_with_suffix
323{
324 typeset ds=$1
325 typeset suffix=$2
326
327 typeset list=$($ZFS list -r -H -t filesystem,snapshot,volume -o name $ds \
328 | $GREP "$suffix$")
329
330 $ECHO $list
331}
332
333#
334# Output inherited properties whitch is edited for file system
335#
336function fs_inherit_prop
337{
338 typeset fs_prop
339 if is_global_zone ; then
340 fs_prop=$($ZFS inherit 2>&1 | \
341 $AWK '$2=="YES" && $3=="YES" {print $1}')
342 if ! is_te_enabled ; then
343 fs_prop=$(echo $fs_prop | $GREP -v "mlslabel")
344 fi
345 else
346 fs_prop=$($ZFS inherit 2>&1 | \
347 $AWK '$2=="YES" && $3=="YES" {print $1}'|
348 $EGREP -v "devices|mlslabel|sharenfs|sharesmb|zoned")
349 fi
350
351 $ECHO $fs_prop
352}
353
354#
355# Output inherited properties for volume
356#
357function vol_inherit_prop
358{
359 $ECHO "checksum readonly"
360}
361
362#
363# Get the destination dataset to compare
364#
365function get_dst_ds
366{
367 typeset srcfs=$1
368 typeset dstfs=$2
369
370 #
371 # If the srcfs is not pool
372 #
373 if ! $ZPOOL list $srcfs > /dev/null 2>&1 ; then
374 eval dstfs="$dstfs/${srcfs#*/}"
375 fi
376
377 $ECHO $dstfs
378}
379
380#
381# Make test files
382#
383# $1 Number of files to create
384# $2 Maximum file size
385# $3 File ID offset
386# $4 File system to create the files on
387#
388function mk_files
389{
390 nfiles=$1
391 maxsize=$2
392 file_id_offset=$3
393 fs=$4
394
395 for ((i=0; i<$nfiles; i=i+1)); do
396 $DD if=/dev/urandom \
397 of=/$fs/file-$maxsize-$((i+$file_id_offset)) \
47dfff3b 398 bs=$((($RANDOM * $RANDOM % ($maxsize - 1)) + 1)) \
6bb24f4d
BB
399 count=1 >/dev/null 2>&1 || log_fail \
400 "Failed to create /$fs/file-$maxsize-$((i+$file_id_offset))"
401 done
402 $ECHO Created $nfiles files of random sizes up to $maxsize bytes
403}
404
405#
406# Remove test files
407#
408# $1 Number of files to remove
409# $2 Maximum file size
410# $3 File ID offset
411# $4 File system to remove the files from
412#
413function rm_files
414{
415 nfiles=$1
416 maxsize=$2
417 file_id_offset=$3
418 fs=$4
419
420 for ((i=0; i<$nfiles; i=i+1)); do
421 $RM -f /$fs/file-$maxsize-$((i+$file_id_offset))
422 done
423 $ECHO Removed $nfiles files of random sizes up to $maxsize bytes
424}
425
426#
427# Mess up file contents
428#
429# $1 The file path
430#
431function mess_file
432{
433 file=$1
434
435 filesize=$($STAT -c '%s' $file)
436 offset=$(($RANDOM * $RANDOM % $filesize))
437 if (($RANDOM % 7 <= 1)); then
438 #
439 # We corrupt 2 bytes to minimize the chance that we
440 # write the same value that's already there.
441 #
442 log_must eval "$DD if=/dev/urandom of=$file conv=notrunc " \
47dfff3b 443 "bs=1 count=2 seek=$offset >/dev/null 2>&1"
6bb24f4d
BB
444 else
445 log_must $TRUNCATE -s $offset $file
446 fi
447}
448
449#
450# Diff the send/receive filesystems
451#
452# $1 The sent filesystem
453# $2 The received filesystem
454#
455function file_check
456{
457 sendfs=$1
458 recvfs=$2
459
460 if [[ -d /$recvfs/.zfs/snapshot/a && -d \
461 /$sendfs/.zfs/snapshot/a ]]; then
462 $DIFF -r /$recvfs/.zfs/snapshot/a /$sendfs/.zfs/snapshot/a
463 [[ $? -eq 0 ]] || log_fail "Differences found in snap a"
464 fi
465 if [[ -d /$recvfs/.zfs/snapshot/b && -d \
466 /$sendfs/.zfs/snapshot/b ]]; then
467 $DIFF -r /$recvfs/.zfs/snapshot/b /$sendfs/.zfs/snapshot/b
468 [[ $? -eq 0 ]] || log_fail "Differences found in snap b"
469 fi
470}
471
472#
473# Resume test helper
474#
475# $1 The ZFS send command
476# $2 The filesystem where the streams are sent
477# $3 The receive filesystem
478#
479function resume_test
480{
481 sendcmd=$1
482 streamfs=$2
483 recvfs=$3
484
485 stream_num=1
486 log_must eval "$sendcmd >/$streamfs/$stream_num"
487
488 for ((i=0; i<2; i=i+1)); do
489 mess_file /$streamfs/$stream_num
490 log_mustnot $ZFS recv -sv $recvfs </$streamfs/$stream_num
491 stream_num=$((stream_num+1))
492
493 token=$($ZFS get -Hp -o value receive_resume_token $recvfs)
494 log_must eval "$ZFS send -v -t $token >/$streamfs/$stream_num"
495 [[ -f /$streamfs/$stream_num ]] || \
496 log_fail "NO FILE /$streamfs/$stream_num"
497 done
498 log_must $ZFS recv -sv $recvfs </$streamfs/$stream_num
499}
500
501#
502# Setup filesystems for the resumable send/receive tests
503#
504# $1 The pool to set up with the "send" filesystems
505# $2 The pool for receive
506#
507function test_fs_setup
508{
509 sendpool=$1
510 recvpool=$2
511
512 sendfs=$sendpool/sendfs
513 recvfs=$recvpool/recvfs
514 streamfs=$sendpool/stream
515
516 if datasetexists $recvfs; then
517 log_must $ZFS destroy -r $recvfs
518 fi
519 if datasetexists $sendfs; then
520 log_must $ZFS destroy -r $sendfs
521 fi
522 if $($ZFS create -o compress=lz4 $sendfs); then
523 mk_files 1000 256 0 $sendfs &
524 mk_files 1000 131072 0 $sendfs &
525 mk_files 100 1048576 0 $sendfs &
526 mk_files 10 10485760 0 $sendfs &
527 mk_files 1 104857600 0 $sendfs &
47dfff3b 528 wait
6bb24f4d
BB
529 log_must $ZFS snapshot $sendfs@a
530
531 rm_files 200 256 0 $sendfs &
532 rm_files 200 131072 0 $sendfs &
533 rm_files 20 1048576 0 $sendfs &
534 rm_files 2 10485760 0 $sendfs &
47dfff3b 535 wait
6bb24f4d
BB
536
537 mk_files 400 256 0 $sendfs &
538 mk_files 400 131072 0 $sendfs &
539 mk_files 40 1048576 0 $sendfs &
540 mk_files 4 10485760 0 $sendfs &
47dfff3b 541 wait
6bb24f4d
BB
542
543 log_must $ZFS snapshot $sendfs@b
544 log_must eval "$ZFS send -v $sendfs@a >/$sendpool/initial.zsend"
545 log_must eval "$ZFS send -v -i @a $sendfs@b " \
546 ">/$sendpool/incremental.zsend"
547 fi
548
549 if datasetexists $streamfs; then
550 log_must $ZFS destroy -r $streamfs
551 fi
552 log_must $ZFS create -o compress=lz4 $sendpool/stream
553}