1f38cb554SJohn Wren Kennedy#
2f38cb554SJohn Wren Kennedy# CDDL HEADER START
3f38cb554SJohn Wren Kennedy#
4f38cb554SJohn Wren Kennedy# The contents of this file are subject to the terms of the
5f38cb554SJohn Wren Kennedy# Common Development and Distribution License (the "License").
6f38cb554SJohn Wren Kennedy# You may not use this file except in compliance with the License.
7f38cb554SJohn Wren Kennedy#
8f38cb554SJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f38cb554SJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing.
10f38cb554SJohn Wren Kennedy# See the License for the specific language governing permissions
11f38cb554SJohn Wren Kennedy# and limitations under the License.
12f38cb554SJohn Wren Kennedy#
13f38cb554SJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each
14f38cb554SJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f38cb554SJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the
16f38cb554SJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying
17f38cb554SJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner]
18f38cb554SJohn Wren Kennedy#
19f38cb554SJohn Wren Kennedy# CDDL HEADER END
20f38cb554SJohn Wren Kennedy#
21f38cb554SJohn Wren Kennedy
22f38cb554SJohn Wren Kennedy#
23f38cb554SJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24f38cb554SJohn Wren Kennedy# Use is subject to license terms.
25f38cb554SJohn Wren Kennedy#
26f38cb554SJohn Wren Kennedy
27f38cb554SJohn Wren Kennedy#
281d32ba66SJohn Wren Kennedy# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
29f38cb554SJohn Wren Kennedy#
30f38cb554SJohn Wren Kennedy
31f38cb554SJohn Wren Kennedy. $STF_SUITE/include/libtest.shlib
325602294fSDan Kimmel. $STF_SUITE/include/math.shlib
33*6ccda740Sloli10K. $STF_SUITE/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib
34f38cb554SJohn Wren Kennedy. $STF_SUITE/tests/functional/rsend/rsend.cfg
35f38cb554SJohn Wren Kennedy
36f38cb554SJohn Wren Kennedy#
37f38cb554SJohn Wren Kennedy# Set up test model which includes various datasets
38f38cb554SJohn Wren Kennedy#
39f38cb554SJohn Wren Kennedy#               @final
40f38cb554SJohn Wren Kennedy#               @snapB
41f38cb554SJohn Wren Kennedy#               @init
42f38cb554SJohn Wren Kennedy#               |
43f38cb554SJohn Wren Kennedy#   ______ pclone
44f38cb554SJohn Wren Kennedy#  |      /
45f38cb554SJohn Wren Kennedy#  |@psnap
46f38cb554SJohn Wren Kennedy#  ||                         @final
47f38cb554SJohn Wren Kennedy#  ||@final       @final      @snapC
48f38cb554SJohn Wren Kennedy#  ||@snapC       @snapC      @snapB
49f38cb554SJohn Wren Kennedy#  ||@snapA       @snapB      @snapA
50f38cb554SJohn Wren Kennedy#  ||@init        @init       @init
51f38cb554SJohn Wren Kennedy#  |||            |           |
52f38cb554SJohn Wren Kennedy# $pool -------- $FS ------- fs1 ------- fs2
53f38cb554SJohn Wren Kennedy#    \             \\_____     \          |
54f38cb554SJohn Wren Kennedy#     vol           vol   \____ \         @fsnap
55f38cb554SJohn Wren Kennedy#      |              |        \ \              \
56f38cb554SJohn Wren Kennedy#      @init          @vsnap   |  ------------ fclone
57f38cb554SJohn Wren Kennedy#      @snapA         @init \  |                    |
58f38cb554SJohn Wren Kennedy#      @final         @snapB \ |                    @init
59f38cb554SJohn Wren Kennedy#                     @snapC  vclone                @snapA
60f38cb554SJohn Wren Kennedy#                     @final       |                @final
61f38cb554SJohn Wren Kennedy#                                 @init
62f38cb554SJohn Wren Kennedy#                                 @snapC
63f38cb554SJohn Wren Kennedy#                                 @final
64f38cb554SJohn Wren Kennedy#
65f38cb554SJohn Wren Kennedy# $1 pool name
66f38cb554SJohn Wren Kennedy#
67f38cb554SJohn Wren Kennedyfunction setup_test_model
68f38cb554SJohn Wren Kennedy{
69f38cb554SJohn Wren Kennedy	typeset pool=$1
70f38cb554SJohn Wren Kennedy
711d32ba66SJohn Wren Kennedy	log_must zfs create -p $pool/$FS/fs1/fs2
72f38cb554SJohn Wren Kennedy
731d32ba66SJohn Wren Kennedy	log_must zfs snapshot $pool@psnap
741d32ba66SJohn Wren Kennedy	log_must zfs clone $pool@psnap $pool/pclone
75f38cb554SJohn Wren Kennedy
76f38cb554SJohn Wren Kennedy	if is_global_zone ; then
771d32ba66SJohn Wren Kennedy		log_must zfs create -V 16M $pool/vol
781d32ba66SJohn Wren Kennedy		log_must zfs create -V 16M $pool/$FS/vol
79f38cb554SJohn Wren Kennedy
801d32ba66SJohn Wren Kennedy		log_must zfs snapshot $pool/$FS/vol@vsnap
811d32ba66SJohn Wren Kennedy		log_must zfs clone $pool/$FS/vol@vsnap $pool/$FS/vclone
82f38cb554SJohn Wren Kennedy	fi
83f38cb554SJohn Wren Kennedy
84f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS/fs1/fs2@fsnap
851d32ba66SJohn Wren Kennedy	log_must zfs clone $pool/$FS/fs1/fs2@fsnap $pool/$FS/fs1/fclone
861d32ba66SJohn Wren Kennedy	log_must zfs snapshot -r $pool@init
87f38cb554SJohn Wren Kennedy
88f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool@snapA
89f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool@snapC
90f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/pclone@snapB
91f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS@snapB
92f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS@snapC
93f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS/fs1@snapA
94f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS/fs1@snapB
95f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS/fs1@snapC
96f38cb554SJohn Wren Kennedy	log_must snapshot_tree $pool/$FS/fs1/fclone@snapA
97f38cb554SJohn Wren Kennedy
98f38cb554SJohn Wren Kennedy	if is_global_zone ; then
991d32ba66SJohn Wren Kennedy		log_must zfs snapshot $pool/vol@snapA
1001d32ba66SJohn Wren Kennedy		log_must zfs snapshot $pool/$FS/vol@snapB
1011d32ba66SJohn Wren Kennedy		log_must zfs snapshot $pool/$FS/vol@snapC
1021d32ba66SJohn Wren Kennedy		log_must zfs snapshot $pool/$FS/vclone@snapC
103f38cb554SJohn Wren Kennedy	fi
104f38cb554SJohn Wren Kennedy
1051d32ba66SJohn Wren Kennedy	log_must zfs snapshot -r $pool@final
106f38cb554SJohn Wren Kennedy
107f38cb554SJohn Wren Kennedy	return 0
108f38cb554SJohn Wren Kennedy}
109f38cb554SJohn Wren Kennedy
110f38cb554SJohn Wren Kennedy#
111f38cb554SJohn Wren Kennedy# Cleanup the BACKDIR and given pool content and all the sub datasets
112f38cb554SJohn Wren Kennedy#
113f38cb554SJohn Wren Kennedy# $1 pool name
114f38cb554SJohn Wren Kennedy#
115f38cb554SJohn Wren Kennedyfunction cleanup_pool
116f38cb554SJohn Wren Kennedy{
117f38cb554SJohn Wren Kennedy	typeset pool=$1
1181d32ba66SJohn Wren Kennedy	log_must rm -rf $BACKDIR/*
119f38cb554SJohn Wren Kennedy
120f38cb554SJohn Wren Kennedy	if is_global_zone ; then
1211d32ba66SJohn Wren Kennedy		log_must zfs destroy -Rf $pool
122f38cb554SJohn Wren Kennedy	else
123ac89d1e8SJohn Kennedy		typeset list=$(zfs list -H -r -t all -o name $pool)
124f38cb554SJohn Wren Kennedy		for ds in $list ; do
125f38cb554SJohn Wren Kennedy			if [[ $ds != $pool ]] ; then
126f38cb554SJohn Wren Kennedy				if datasetexists $ds ; then
1271d32ba66SJohn Wren Kennedy					log_must zfs destroy -Rf $ds
128f38cb554SJohn Wren Kennedy				fi
129f38cb554SJohn Wren Kennedy			fi
130f38cb554SJohn Wren Kennedy		done
131f38cb554SJohn Wren Kennedy	fi
132f38cb554SJohn Wren Kennedy
133f38cb554SJohn Wren Kennedy	typeset mntpnt=$(get_prop mountpoint $pool)
134f38cb554SJohn Wren Kennedy	if ! ismounted $pool ; then
135f38cb554SJohn Wren Kennedy		# Make sure mountpoint directory is empty
136f38cb554SJohn Wren Kennedy		if [[ -d $mntpnt ]]; then
1371d32ba66SJohn Wren Kennedy			log_must rm -rf $mntpnt/*
138f38cb554SJohn Wren Kennedy		fi
139f38cb554SJohn Wren Kennedy
1401d32ba66SJohn Wren Kennedy		log_must zfs mount $pool
141f38cb554SJohn Wren Kennedy	fi
142f38cb554SJohn Wren Kennedy	if [[ -d $mntpnt ]]; then
143ac89d1e8SJohn Kennedy		rm -rf $mntpnt/*
144f38cb554SJohn Wren Kennedy	fi
145f38cb554SJohn Wren Kennedy
146f38cb554SJohn Wren Kennedy	return 0
147f38cb554SJohn Wren Kennedy}
148f38cb554SJohn Wren Kennedy
149ac89d1e8SJohn Kennedyfunction cleanup_pools
150ac89d1e8SJohn Kennedy{
151ac89d1e8SJohn Kennedy	cleanup_pool $POOL2
152ac89d1e8SJohn Kennedy	destroy_pool $POOL3
153ac89d1e8SJohn Kennedy}
154ac89d1e8SJohn Kennedy
155f38cb554SJohn Wren Kennedy#
156f38cb554SJohn Wren Kennedy# Detect if the given two filesystems have same sub-datasets
157f38cb554SJohn Wren Kennedy#
158f38cb554SJohn Wren Kennedy# $1 source filesystem
159f38cb554SJohn Wren Kennedy# $2 destination filesystem
160f38cb554SJohn Wren Kennedy#
161f38cb554SJohn Wren Kennedyfunction cmp_ds_subs
162f38cb554SJohn Wren Kennedy{
163f38cb554SJohn Wren Kennedy	typeset src_fs=$1
164f38cb554SJohn Wren Kennedy	typeset dst_fs=$2
165f38cb554SJohn Wren Kennedy
166ac89d1e8SJohn Kennedy	zfs list -r -H -t all -o name $src_fs > $BACKDIR/src1
167ac89d1e8SJohn Kennedy	zfs list -r -H -t all -o name $dst_fs > $BACKDIR/dst1
168f38cb554SJohn Wren Kennedy
1691d32ba66SJohn Wren Kennedy	eval sed -e 's:^$src_fs:PREFIX:g' < $BACKDIR/src1 > $BACKDIR/src
1701d32ba66SJohn Wren Kennedy	eval sed -e 's:^$dst_fs:PREFIX:g' < $BACKDIR/dst1 > $BACKDIR/dst
171f38cb554SJohn Wren Kennedy
1721d32ba66SJohn Wren Kennedy	diff $BACKDIR/src $BACKDIR/dst
173f38cb554SJohn Wren Kennedy	typeset -i ret=$?
174f38cb554SJohn Wren Kennedy
1751d32ba66SJohn Wren Kennedy	rm -f $BACKDIR/src $BACKDIR/dst $BACKDIR/src1 $BACKDIR/dst1
176f38cb554SJohn Wren Kennedy
177f38cb554SJohn Wren Kennedy	return $ret
178f38cb554SJohn Wren Kennedy}
179f38cb554SJohn Wren Kennedy
180f38cb554SJohn Wren Kennedy#
181f38cb554SJohn Wren Kennedy# Compare all the directores and files in two filesystems
182f38cb554SJohn Wren Kennedy#
183f38cb554SJohn Wren Kennedy# $1 source filesystem
184f38cb554SJohn Wren Kennedy# $2 destination filesystem
185f38cb554SJohn Wren Kennedy#
186f38cb554SJohn Wren Kennedyfunction cmp_ds_cont
187f38cb554SJohn Wren Kennedy{
188f38cb554SJohn Wren Kennedy	typeset src_fs=$1
189f38cb554SJohn Wren Kennedy	typeset dst_fs=$2
190f38cb554SJohn Wren Kennedy
191f38cb554SJohn Wren Kennedy	typeset srcdir dstdir
192f38cb554SJohn Wren Kennedy	srcdir=$(get_prop mountpoint $src_fs)
193f38cb554SJohn Wren Kennedy	dstdir=$(get_prop mountpoint $dst_fs)
194f38cb554SJohn Wren Kennedy
1951d32ba66SJohn Wren Kennedy	diff -r $srcdir $dstdir > /dev/null 2>&1
1965dc1fd74SJohn Wren Kennedy	return $?
197f38cb554SJohn Wren Kennedy}
198f38cb554SJohn Wren Kennedy
199f38cb554SJohn Wren Kennedy#
200f38cb554SJohn Wren Kennedy# Compare the given two dataset properties
201f38cb554SJohn Wren Kennedy#
202f38cb554SJohn Wren Kennedy# $1 dataset 1
203f38cb554SJohn Wren Kennedy# $2 dataset 2
204f38cb554SJohn Wren Kennedy#
205f38cb554SJohn Wren Kennedyfunction cmp_ds_prop
206f38cb554SJohn Wren Kennedy{
207f38cb554SJohn Wren Kennedy	typeset dtst1=$1
208f38cb554SJohn Wren Kennedy	typeset dtst2=$2
209f38cb554SJohn Wren Kennedy
210f38cb554SJohn Wren Kennedy	for item in "type" "origin" "volblocksize" "aclinherit" "aclmode" \
211f38cb554SJohn Wren Kennedy	    "atime" "canmount" "checksum" "compression" "copies" "devices" \
2120774d909SNed Bass	    "dnodesize" "exec" "quota" "readonly" "recordsize" "reservation" \
2130774d909SNed Bass	    "setuid" "sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
214f38cb554SJohn Wren Kennedy	    "mountpoint";
215f38cb554SJohn Wren Kennedy	do
2161d32ba66SJohn Wren Kennedy		zfs get -H -o property,value,source $item $dtst1 >> \
217f38cb554SJohn Wren Kennedy		    $BACKDIR/dtst1
2181d32ba66SJohn Wren Kennedy		zfs get -H -o property,value,source $item $dtst2 >> \
219f38cb554SJohn Wren Kennedy		    $BACKDIR/dtst2
220f38cb554SJohn Wren Kennedy	done
221f38cb554SJohn Wren Kennedy
2221d32ba66SJohn Wren Kennedy	eval sed -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
2231d32ba66SJohn Wren Kennedy	eval sed -e 's:$dtst2:PREFIX:g' < $BACKDIR/dtst2 > $BACKDIR/dtst2
224f38cb554SJohn Wren Kennedy
2251d32ba66SJohn Wren Kennedy	diff $BACKDIR/dtst1 $BACKDIR/dtst2
226f38cb554SJohn Wren Kennedy	typeset -i ret=$?
227f38cb554SJohn Wren Kennedy
2281d32ba66SJohn Wren Kennedy	rm -f $BACKDIR/dtst1 $BACKDIR/dtst2
229f38cb554SJohn Wren Kennedy
230f38cb554SJohn Wren Kennedy	return $ret
231f38cb554SJohn Wren Kennedy
232f38cb554SJohn Wren Kennedy}
233f38cb554SJohn Wren Kennedy
234f38cb554SJohn Wren Kennedy#
235f38cb554SJohn Wren Kennedy# Random create directories and files
236f38cb554SJohn Wren Kennedy#
237f38cb554SJohn Wren Kennedy# $1 directory
238f38cb554SJohn Wren Kennedy#
239f38cb554SJohn Wren Kennedyfunction random_tree
240f38cb554SJohn Wren Kennedy{
241f38cb554SJohn Wren Kennedy	typeset dir=$1
242f38cb554SJohn Wren Kennedy
243f38cb554SJohn Wren Kennedy	if [[ -d $dir ]]; then
2441d32ba66SJohn Wren Kennedy		rm -rf $dir
245f38cb554SJohn Wren Kennedy	fi
2461d32ba66SJohn Wren Kennedy	mkdir -p $dir
247f38cb554SJohn Wren Kennedy	typeset -i ret=$?
248f38cb554SJohn Wren Kennedy
249f38cb554SJohn Wren Kennedy	typeset -i nl nd nf
250f38cb554SJohn Wren Kennedy	((nl = RANDOM % 6 + 1))
251f38cb554SJohn Wren Kennedy	((nd = RANDOM % 3 ))
252f38cb554SJohn Wren Kennedy	((nf = RANDOM % 5 ))
2531d32ba66SJohn Wren Kennedy	mktree -b $dir -l $nl -d $nd -f $nf
254f38cb554SJohn Wren Kennedy	((ret |= $?))
255f38cb554SJohn Wren Kennedy
256f38cb554SJohn Wren Kennedy	return $ret
257f38cb554SJohn Wren Kennedy}
258f38cb554SJohn Wren Kennedy
259f38cb554SJohn Wren Kennedy#
260f38cb554SJohn Wren Kennedy# Put data in filesystem and take snapshot
261f38cb554SJohn Wren Kennedy#
262f38cb554SJohn Wren Kennedy# $1 snapshot name
263f38cb554SJohn Wren Kennedy#
264f38cb554SJohn Wren Kennedyfunction snapshot_tree
265f38cb554SJohn Wren Kennedy{
266f38cb554SJohn Wren Kennedy	typeset snap=$1
267f38cb554SJohn Wren Kennedy	typeset ds=${snap%%@*}
268f38cb554SJohn Wren Kennedy	typeset type=$(get_prop "type" $ds)
269f38cb554SJohn Wren Kennedy
270f38cb554SJohn Wren Kennedy	typeset -i ret=0
271f38cb554SJohn Wren Kennedy	if [[ $type == "filesystem" ]]; then
272f38cb554SJohn Wren Kennedy		typeset mntpnt=$(get_prop mountpoint $ds)
273f38cb554SJohn Wren Kennedy		((ret |= $?))
274f38cb554SJohn Wren Kennedy
275f38cb554SJohn Wren Kennedy		if ((ret == 0)) ; then
276f38cb554SJohn Wren Kennedy			eval random_tree $mntpnt/${snap##$ds}
277f38cb554SJohn Wren Kennedy			((ret |= $?))
278f38cb554SJohn Wren Kennedy		fi
279f38cb554SJohn Wren Kennedy	fi
280f38cb554SJohn Wren Kennedy
281f38cb554SJohn Wren Kennedy	if ((ret == 0)) ; then
2821d32ba66SJohn Wren Kennedy		zfs snapshot $snap
283f38cb554SJohn Wren Kennedy		((ret |= $?))
284f38cb554SJohn Wren Kennedy	fi
285f38cb554SJohn Wren Kennedy
286f38cb554SJohn Wren Kennedy	return $ret
287f38cb554SJohn Wren Kennedy}
288f38cb554SJohn Wren Kennedy
289f38cb554SJohn Wren Kennedy#
290f38cb554SJohn Wren Kennedy# Destroy the given snapshot and stuff
291f38cb554SJohn Wren Kennedy#
292f38cb554SJohn Wren Kennedy# $1 snapshot
293f38cb554SJohn Wren Kennedy#
294f38cb554SJohn Wren Kennedyfunction destroy_tree
295f38cb554SJohn Wren Kennedy{
296f38cb554SJohn Wren Kennedy	typeset -i ret=0
297f38cb554SJohn Wren Kennedy	typeset snap
298f38cb554SJohn Wren Kennedy	for snap in "$@" ; do
2991d32ba66SJohn Wren Kennedy		zfs destroy $snap
300f38cb554SJohn Wren Kennedy		ret=$?
301f38cb554SJohn Wren Kennedy
302f38cb554SJohn Wren Kennedy		typeset ds=${snap%%@*}
303f38cb554SJohn Wren Kennedy		typeset type=$(get_prop "type" $ds)
304f38cb554SJohn Wren Kennedy		if [[ $type == "filesystem" ]]; then
305f38cb554SJohn Wren Kennedy			typeset mntpnt=$(get_prop mountpoint $ds)
306f38cb554SJohn Wren Kennedy			((ret |= $?))
307f38cb554SJohn Wren Kennedy
308f38cb554SJohn Wren Kennedy			if ((ret != 0)); then
3091d32ba66SJohn Wren Kennedy				rm -r $mntpnt/$snap
310f38cb554SJohn Wren Kennedy				((ret |= $?))
311f38cb554SJohn Wren Kennedy			fi
312f38cb554SJohn Wren Kennedy		fi
313f38cb554SJohn Wren Kennedy
314f38cb554SJohn Wren Kennedy		if ((ret != 0)); then
315f38cb554SJohn Wren Kennedy			return $ret
316f38cb554SJohn Wren Kennedy		fi
317f38cb554SJohn Wren Kennedy	done
318f38cb554SJohn Wren Kennedy
319f38cb554SJohn Wren Kennedy	return 0
320f38cb554SJohn Wren Kennedy}
321f38cb554SJohn Wren Kennedy
322f38cb554SJohn Wren Kennedy#
323f38cb554SJohn Wren Kennedy# Get all the sub-datasets of give dataset with specific suffix
324f38cb554SJohn Wren Kennedy#
325f38cb554SJohn Wren Kennedy# $1 Given dataset
326f38cb554SJohn Wren Kennedy# $2 Suffix
327f38cb554SJohn Wren Kennedy#
328f38cb554SJohn Wren Kennedyfunction getds_with_suffix
329f38cb554SJohn Wren Kennedy{
330f38cb554SJohn Wren Kennedy	typeset ds=$1
331f38cb554SJohn Wren Kennedy	typeset suffix=$2
332f38cb554SJohn Wren Kennedy
333ac89d1e8SJohn Kennedy	typeset list=$(zfs list -r -H -t all -o name $ds | grep "$suffix$")
334f38cb554SJohn Wren Kennedy
3351d32ba66SJohn Wren Kennedy	echo $list
336f38cb554SJohn Wren Kennedy}
337f38cb554SJohn Wren Kennedy
338f38cb554SJohn Wren Kennedy#
339f38cb554SJohn Wren Kennedy# Output inherited properties whitch is edited for file system
340f38cb554SJohn Wren Kennedy#
341f38cb554SJohn Wren Kennedyfunction fs_inherit_prop
342f38cb554SJohn Wren Kennedy{
343f38cb554SJohn Wren Kennedy	typeset fs_prop
344f38cb554SJohn Wren Kennedy	if is_global_zone ; then
3451d32ba66SJohn Wren Kennedy		fs_prop=$(zfs inherit 2>&1 | \
3461d32ba66SJohn Wren Kennedy		    awk '$2=="YES" && $3=="YES" {print $1}')
347f38cb554SJohn Wren Kennedy		if ! is_te_enabled ; then
3481d32ba66SJohn Wren Kennedy		        fs_prop=$(echo $fs_prop | grep -v "mlslabel")
349f38cb554SJohn Wren Kennedy		fi
350f38cb554SJohn Wren Kennedy	else
3511d32ba66SJohn Wren Kennedy		fs_prop=$(zfs inherit 2>&1 | \
3521d32ba66SJohn Wren Kennedy		    awk '$2=="YES" && $3=="YES" {print $1}'|
3531d32ba66SJohn Wren Kennedy		    egrep -v "devices|mlslabel|sharenfs|sharesmb|zoned")
354f38cb554SJohn Wren Kennedy	fi
355f38cb554SJohn Wren Kennedy
3561d32ba66SJohn Wren Kennedy	echo $fs_prop
357f38cb554SJohn Wren Kennedy}
358f38cb554SJohn Wren Kennedy
359f38cb554SJohn Wren Kennedy#
360f38cb554SJohn Wren Kennedy# Output inherited properties for volume
361f38cb554SJohn Wren Kennedy#
362f38cb554SJohn Wren Kennedyfunction vol_inherit_prop
363f38cb554SJohn Wren Kennedy{
3641d32ba66SJohn Wren Kennedy	echo "checksum readonly"
365f38cb554SJohn Wren Kennedy}
366f38cb554SJohn Wren Kennedy
367f38cb554SJohn Wren Kennedy#
368f38cb554SJohn Wren Kennedy# Get the destination dataset to compare
369f38cb554SJohn Wren Kennedy#
370f38cb554SJohn Wren Kennedyfunction get_dst_ds
371f38cb554SJohn Wren Kennedy{
372f38cb554SJohn Wren Kennedy	typeset srcfs=$1
373f38cb554SJohn Wren Kennedy	typeset dstfs=$2
374f38cb554SJohn Wren Kennedy
375f38cb554SJohn Wren Kennedy	#
376f38cb554SJohn Wren Kennedy	# If the srcfs is not pool
377f38cb554SJohn Wren Kennedy	#
3781d32ba66SJohn Wren Kennedy	if ! zpool list $srcfs > /dev/null 2>&1 ; then
379f38cb554SJohn Wren Kennedy		eval dstfs="$dstfs/${srcfs#*/}"
380f38cb554SJohn Wren Kennedy	fi
381f38cb554SJohn Wren Kennedy
3821d32ba66SJohn Wren Kennedy	echo $dstfs
383f38cb554SJohn Wren Kennedy}
3849c3fd121SMatthew Ahrens
3859c3fd121SMatthew Ahrens#
3869c3fd121SMatthew Ahrens# Make test files
3879c3fd121SMatthew Ahrens#
3889c3fd121SMatthew Ahrens# $1 Number of files to create
3899c3fd121SMatthew Ahrens# $2 Maximum file size
3909c3fd121SMatthew Ahrens# $3 File ID offset
3919c3fd121SMatthew Ahrens# $4 File system to create the files on
3929c3fd121SMatthew Ahrens#
3939c3fd121SMatthew Ahrensfunction mk_files
3949c3fd121SMatthew Ahrens{
3959c3fd121SMatthew Ahrens	nfiles=$1
3969c3fd121SMatthew Ahrens	maxsize=$2
3979c3fd121SMatthew Ahrens	file_id_offset=$3
3989c3fd121SMatthew Ahrens	fs=$4
3999c3fd121SMatthew Ahrens
4009c3fd121SMatthew Ahrens	for ((i=0; i<$nfiles; i=i+1)); do
4011d32ba66SJohn Wren Kennedy		dd if=/dev/urandom \
4029c3fd121SMatthew Ahrens		    of=/$fs/file-$maxsize-$((i+$file_id_offset)) \
4039c3fd121SMatthew Ahrens		    bs=$(($RANDOM * $RANDOM % $maxsize)) \
4049c3fd121SMatthew Ahrens		    count=1 >/dev/null 2>&1 || log_fail \
4059c3fd121SMatthew Ahrens		    "Failed to create /$fs/file-$maxsize-$((i+$file_id_offset))"
4069c3fd121SMatthew Ahrens	done
4071d32ba66SJohn Wren Kennedy	echo Created $nfiles files of random sizes up to $maxsize bytes
4089c3fd121SMatthew Ahrens}
4099c3fd121SMatthew Ahrens
4109c3fd121SMatthew Ahrens#
4119c3fd121SMatthew Ahrens# Remove test files
4129c3fd121SMatthew Ahrens#
4139c3fd121SMatthew Ahrens# $1 Number of files to remove
4149c3fd121SMatthew Ahrens# $2 Maximum file size
4159c3fd121SMatthew Ahrens# $3 File ID offset
4169c3fd121SMatthew Ahrens# $4 File system to remove the files from
4179c3fd121SMatthew Ahrens#
4189c3fd121SMatthew Ahrensfunction rm_files
4199c3fd121SMatthew Ahrens{
4209c3fd121SMatthew Ahrens	nfiles=$1
4219c3fd121SMatthew Ahrens	maxsize=$2
4229c3fd121SMatthew Ahrens	file_id_offset=$3
4239c3fd121SMatthew Ahrens	fs=$4
4249c3fd121SMatthew Ahrens
4259c3fd121SMatthew Ahrens	for ((i=0; i<$nfiles; i=i+1)); do
4261d32ba66SJohn Wren Kennedy		rm -f /$fs/file-$maxsize-$((i+$file_id_offset))
4279c3fd121SMatthew Ahrens	done
4281d32ba66SJohn Wren Kennedy	echo Removed $nfiles files of random sizes up to $maxsize bytes
4299c3fd121SMatthew Ahrens}
4309c3fd121SMatthew Ahrens
4319c3fd121SMatthew Ahrens#
432eb633035STom Caputi# Simulate a random set of operations which could be reasonably expected
433eb633035STom Caputi# to occur on an average filesystem.
434eb633035STom Caputi#
435eb633035STom Caputi# $1 Number of files to modify
436eb633035STom Caputi# $2 Maximum file size
437eb633035STom Caputi# $3 File system to modify the file on
438eb633035STom Caputi# $4 Enabled xattrs (optional)
439eb633035STom Caputi#
440eb633035STom Caputifunction churn_files
441eb633035STom Caputi{
442eb633035STom Caputi        nfiles=$1
443eb633035STom Caputi        maxsize=$2
444eb633035STom Caputi        fs=$3
445eb633035STom Caputi        xattrs=${4:-1}
446eb633035STom Caputi
447eb633035STom Caputi        #
448eb633035STom Caputi        # Remove roughly half of the files in order to make it more
449eb633035STom Caputi        # likely that a dnode will be reallocated.
450eb633035STom Caputi        #
451eb633035STom Caputi        for ((i=0; i<$nfiles; i=i+1)); do
452eb633035STom Caputi                file_name="/$fs/file-$i"
453eb633035STom Caputi
454eb633035STom Caputi                if [[ -e $file_name ]]; then
455eb633035STom Caputi                        if [ $((RANDOM % 2)) -eq 0 ]; then
456eb633035STom Caputi                                rm $file_name || \
457eb633035STom Caputi                                    log_fail "Failed to remove $file_name"
458eb633035STom Caputi                        fi
459eb633035STom Caputi                fi
460eb633035STom Caputi        done
461eb633035STom Caputi
462eb633035STom Caputi        #
463eb633035STom Caputi        # Remount the filesystem to simulate normal usage.  This resets
464eb633035STom Caputi        # the last allocated object id allowing for new objects to be
465eb633035STom Caputi        # reallocated in the locations of previously freed objects.
466eb633035STom Caputi        #
467eb633035STom Caputi        log_must zfs unmount $fs
468eb633035STom Caputi        log_must zfs mount $fs
469eb633035STom Caputi
470eb633035STom Caputi        for i in {0..$nfiles}; do
471eb633035STom Caputi                file_name="/$fs/file-$i"
472eb633035STom Caputi                file_size=$((($RANDOM * $RANDOM % ($maxsize - 1)) + 1))
473eb633035STom Caputi
474eb633035STom Caputi                #
475eb633035STom Caputi                # When the file exists modify it in one of five ways to
476eb633035STom Caputi                # simulate normal usage:
477eb633035STom Caputi                # - (20%) Remove and set and extended attribute on the file
478eb633035STom Caputi                # - (20%) Overwrite the existing file
479eb633035STom Caputi                # - (20%) Truncate the existing file to a random length
480eb633035STom Caputi                # - (20%) Truncate the existing file to zero length
481eb633035STom Caputi                # - (20%) Remove the file
482eb633035STom Caputi                #
483eb633035STom Caputi                # Otherwise create the missing file.  20% of the created
484eb633035STom Caputi                # files will be small and use embedded block pointers, the
485eb633035STom Caputi                # remainder with have random sizes up to the maximum size.
486eb633035STom Caputi                # Three extended attributes are attached to all of the files.
487eb633035STom Caputi                #
488eb633035STom Caputi                if [[ -e $file_name ]]; then
489eb633035STom Caputi                        value=$((RANDOM % 5))
490eb633035STom Caputi                        if [ $value -eq 0 -a $xattrs -ne 0 ]; then
491eb633035STom Caputi                                attrname="testattr$((RANDOM % 3))"
492*6ccda740Sloli10K				attrlen="$(((RANDOM % 1000) + 1))"
493*6ccda740Sloli10K				attrvalue="$(random_string VALID_NAME_CHAR \
494*6ccda740Sloli10K				    $attrlen)"
495eb633035STom Caputi                                attr -qr $attrname $file_name || \
496eb633035STom Caputi                                    log_fail "Failed to remove $attrname"
497*6ccda740Sloli10K				attr -qs $attrname \
498*6ccda740Sloli10K				    -V "$attrvalue" $file_name || \
499eb633035STom Caputi                                    log_fail "Failed to set $attrname"
500eb633035STom Caputi                        elif [ $value -eq 1 ]; then
501eb633035STom Caputi                                dd if=/dev/urandom of=$file_name \
502eb633035STom Caputi                                    bs=$file_size count=1 >/dev/null 2>&1 || \
503eb633035STom Caputi                                    log_fail "Failed to overwrite $file_name"
504eb633035STom Caputi                        elif [ $value -eq 2 ]; then
505eb633035STom Caputi                                truncate -s $file_size $file_name || \
506eb633035STom Caputi                                    log_fail "Failed to truncate $file_name"
507eb633035STom Caputi                        elif [ $value -eq 3 ]; then
508eb633035STom Caputi                                truncate -s 0 $file_name || \
509eb633035STom Caputi                                    log_fail "Failed to truncate $file_name"
510eb633035STom Caputi                        else
511eb633035STom Caputi                                rm $file_name || \
512eb633035STom Caputi                                    log_fail "Failed to remove $file_name"
513eb633035STom Caputi                        fi
514eb633035STom Caputi                else
515eb633035STom Caputi                        if [ $((RANDOM % 5)) -eq 0 ]; then
516eb633035STom Caputi                                file_size=$((($RANDOM % 64) + 1))
517eb633035STom Caputi                        fi
518eb633035STom Caputi
519eb633035STom Caputi                        dd if=/dev/urandom of=$file_name \
520eb633035STom Caputi                            bs=$file_size count=1 >/dev/null 2>&1 || \
521eb633035STom Caputi                            log_fail "Failed to create $file_name"
522eb633035STom Caputi
523eb633035STom Caputi                        if [ $xattrs -ne 0 ]; then
524eb633035STom Caputi                                for j in {0..2}; do
525eb633035STom Caputi                                        attrname="testattr$j"
526*6ccda740Sloli10K					attrlen="$(((RANDOM % 1000) + 1))"
527*6ccda740Sloli10K					attrvalue="$(random_string \
528*6ccda740Sloli10K					    VALID_NAME_CHAR $attrlen)"
529*6ccda740Sloli10K					attr -qs $attrname \
530*6ccda740Sloli10K					    -V "$attrvalue" $file_name || \
531*6ccda740Sloli10K					    log_fail "Failed to set $attrname"
532eb633035STom Caputi                                done
533eb633035STom Caputi                        fi
534eb633035STom Caputi                fi
535eb633035STom Caputi        done
536eb633035STom Caputi
537eb633035STom Caputi        return 0
538eb633035STom Caputi}
539eb633035STom Caputi
540eb633035STom Caputi#
5419c3fd121SMatthew Ahrens# Mess up file contents
5429c3fd121SMatthew Ahrens#
5439c3fd121SMatthew Ahrens# $1 The file path
5449c3fd121SMatthew Ahrens#
5459c3fd121SMatthew Ahrensfunction mess_file
5469c3fd121SMatthew Ahrens{
5479c3fd121SMatthew Ahrens	file=$1
5489c3fd121SMatthew Ahrens
5491d32ba66SJohn Wren Kennedy	filesize=$(stat -c '%s' $file)
5509c3fd121SMatthew Ahrens	offset=$(($RANDOM * $RANDOM % $filesize))
5519c3fd121SMatthew Ahrens	if (($RANDOM % 7 <= 1)); then
5529c3fd121SMatthew Ahrens		#
5539c3fd121SMatthew Ahrens		# We corrupt 2 bytes to minimize the chance that we
5549c3fd121SMatthew Ahrens		# write the same value that's already there.
5559c3fd121SMatthew Ahrens		#
5561d32ba66SJohn Wren Kennedy		log_must eval "dd if=/dev/random of=$file conv=notrunc " \
5579c3fd121SMatthew Ahrens		    "bs=1 count=2 oseek=$offset >/dev/null 2>&1"
5589c3fd121SMatthew Ahrens	else
5591d32ba66SJohn Wren Kennedy		log_must truncate -s $offset $file
5609c3fd121SMatthew Ahrens	fi
5619c3fd121SMatthew Ahrens}
5629c3fd121SMatthew Ahrens
5639c3fd121SMatthew Ahrens#
5649c3fd121SMatthew Ahrens# Diff the send/receive filesystems
5659c3fd121SMatthew Ahrens#
5669c3fd121SMatthew Ahrens# $1 The sent filesystem
5679c3fd121SMatthew Ahrens# $2 The received filesystem
5689c3fd121SMatthew Ahrens#
5699c3fd121SMatthew Ahrensfunction file_check
5709c3fd121SMatthew Ahrens{
5719c3fd121SMatthew Ahrens	sendfs=$1
5729c3fd121SMatthew Ahrens	recvfs=$2
5739c3fd121SMatthew Ahrens
5749c3fd121SMatthew Ahrens	if [[ -d /$recvfs/.zfs/snapshot/a && -d \
5759c3fd121SMatthew Ahrens	    /$sendfs/.zfs/snapshot/a ]]; then
5761d32ba66SJohn Wren Kennedy		diff -r /$recvfs/.zfs/snapshot/a /$sendfs/.zfs/snapshot/a
5779c3fd121SMatthew Ahrens		[[ $? -eq 0 ]] || log_fail "Differences found in snap a"
5789c3fd121SMatthew Ahrens	fi
5799c3fd121SMatthew Ahrens	if [[ -d /$recvfs/.zfs/snapshot/b && -d \
5809c3fd121SMatthew Ahrens	    /$sendfs/.zfs/snapshot/b ]]; then
5811d32ba66SJohn Wren Kennedy		diff -r /$recvfs/.zfs/snapshot/b /$sendfs/.zfs/snapshot/b
5829c3fd121SMatthew Ahrens		[[ $? -eq 0 ]] || log_fail "Differences found in snap b"
5839c3fd121SMatthew Ahrens	fi
5849c3fd121SMatthew Ahrens}
5859c3fd121SMatthew Ahrens
5869c3fd121SMatthew Ahrens#
5879c3fd121SMatthew Ahrens# Resume test helper
5889c3fd121SMatthew Ahrens#
5899c3fd121SMatthew Ahrens# $1 The ZFS send command
5909c3fd121SMatthew Ahrens# $2 The filesystem where the streams are sent
5919c3fd121SMatthew Ahrens# $3 The receive filesystem
5929c3fd121SMatthew Ahrens#
5939c3fd121SMatthew Ahrensfunction resume_test
5949c3fd121SMatthew Ahrens{
5959c3fd121SMatthew Ahrens	sendcmd=$1
5969c3fd121SMatthew Ahrens	streamfs=$2
5979c3fd121SMatthew Ahrens	recvfs=$3
5989c3fd121SMatthew Ahrens
5999c3fd121SMatthew Ahrens	stream_num=1
6009c3fd121SMatthew Ahrens	log_must eval "$sendcmd >/$streamfs/$stream_num"
6019c3fd121SMatthew Ahrens
6029c3fd121SMatthew Ahrens	for ((i=0; i<2; i=i+1)); do
6039c3fd121SMatthew Ahrens		mess_file /$streamfs/$stream_num
604ac89d1e8SJohn Kennedy		log_mustnot zfs recv -suv $recvfs </$streamfs/$stream_num
6059c3fd121SMatthew Ahrens		stream_num=$((stream_num+1))
6069c3fd121SMatthew Ahrens
6071d32ba66SJohn Wren Kennedy		token=$(zfs get -Hp -o value receive_resume_token $recvfs)
6081d32ba66SJohn Wren Kennedy		log_must eval "zfs send -v -t $token >/$streamfs/$stream_num"
6099c3fd121SMatthew Ahrens		[[ -f /$streamfs/$stream_num ]] || \
6109c3fd121SMatthew Ahrens		    log_fail "NO FILE /$streamfs/$stream_num"
6119c3fd121SMatthew Ahrens	done
612ac89d1e8SJohn Kennedy	log_must zfs recv -suv $recvfs </$streamfs/$stream_num
6139c3fd121SMatthew Ahrens}
6149c3fd121SMatthew Ahrens
6159c3fd121SMatthew Ahrens#
6169c3fd121SMatthew Ahrens# Setup filesystems for the resumable send/receive tests
6179c3fd121SMatthew Ahrens#
618ac89d1e8SJohn Kennedy# $1 The "send" filesystem
619ac89d1e8SJohn Kennedy# $2 The "recv" filesystem
6209c3fd121SMatthew Ahrens#
6219c3fd121SMatthew Ahrensfunction test_fs_setup
6229c3fd121SMatthew Ahrens{
623ac89d1e8SJohn Kennedy	typeset sendfs=$1
624ac89d1e8SJohn Kennedy	typeset recvfs=$2
625544132fcSloli10K	typeset streamfs=$3
626ac89d1e8SJohn Kennedy	typeset sendpool=${sendfs%%/*}
627ac89d1e8SJohn Kennedy	typeset recvpool=${recvfs%%/*}
6289c3fd121SMatthew Ahrens
6295602294fSDan Kimmel	datasetexists $sendfs && log_must zfs destroy -r $sendpool
6305602294fSDan Kimmel	datasetexists $recvfs && log_must zfs destroy -r $recvpool
631544132fcSloli10K	datasetexists $streamfs && log_must zfs destroy -r $streamfs
6329c3fd121SMatthew Ahrens
633ac89d1e8SJohn Kennedy	if $(datasetexists $sendfs || zfs create -o compress=lz4 $sendfs); then
6349c3fd121SMatthew Ahrens		mk_files 1000 256 0 $sendfs &
6359c3fd121SMatthew Ahrens		mk_files 1000 131072 0 $sendfs &
6369c3fd121SMatthew Ahrens		mk_files 100 1048576 0 $sendfs &
6379c3fd121SMatthew Ahrens		mk_files 10 10485760 0 $sendfs &
6389c3fd121SMatthew Ahrens		mk_files 1 104857600 0 $sendfs &
6391d32ba66SJohn Wren Kennedy		log_must wait
6401d32ba66SJohn Wren Kennedy		log_must zfs snapshot $sendfs@a
6419c3fd121SMatthew Ahrens
6429c3fd121SMatthew Ahrens		rm_files 200 256 0 $sendfs &
6439c3fd121SMatthew Ahrens		rm_files 200 131072 0 $sendfs &
6449c3fd121SMatthew Ahrens		rm_files 20 1048576 0 $sendfs &
6459c3fd121SMatthew Ahrens		rm_files 2 10485760 0 $sendfs &
6461d32ba66SJohn Wren Kennedy		log_must wait
6479c3fd121SMatthew Ahrens
6489c3fd121SMatthew Ahrens		mk_files 400 256 0 $sendfs &
6499c3fd121SMatthew Ahrens		mk_files 400 131072 0 $sendfs &
6509c3fd121SMatthew Ahrens		mk_files 40 1048576 0 $sendfs &
6519c3fd121SMatthew Ahrens		mk_files 4 10485760 0 $sendfs &
6521d32ba66SJohn Wren Kennedy		log_must wait
6539c3fd121SMatthew Ahrens
6541d32ba66SJohn Wren Kennedy		log_must zfs snapshot $sendfs@b
6551d32ba66SJohn Wren Kennedy		log_must eval "zfs send -v $sendfs@a >/$sendpool/initial.zsend"
6561d32ba66SJohn Wren Kennedy		log_must eval "zfs send -v -i @a $sendfs@b " \
6579c3fd121SMatthew Ahrens		    ">/$sendpool/incremental.zsend"
6589c3fd121SMatthew Ahrens	fi
6599c3fd121SMatthew Ahrens
660544132fcSloli10K	log_must zfs create -o compress=lz4 $streamfs
6619c3fd121SMatthew Ahrens}
6625602294fSDan Kimmel
6635602294fSDan Kimmel#
6645602294fSDan Kimmel# Check to see if the specified features are set in a send stream.
6655602294fSDan Kimmel# The values for these features are found in uts/common/fs/zfs/sys/zfs_ioctl.h
6665602294fSDan Kimmel#
6675602294fSDan Kimmel# $1 The stream file
6685602294fSDan Kimmel# $2-$n The flags expected in the stream
6695602294fSDan Kimmel#
6705602294fSDan Kimmelfunction stream_has_features
6715602294fSDan Kimmel{
6725602294fSDan Kimmel	typeset file=$1
6735602294fSDan Kimmel	shift
6745602294fSDan Kimmel
6755602294fSDan Kimmel	[[ -f $file ]] || log_fail "Couldn't find file: $file"
6765602294fSDan Kimmel	typeset flags=$(cat $file | zstreamdump | awk '/features =/ {print $3}')
6775602294fSDan Kimmel	typeset -A feature
6785602294fSDan Kimmel	feature[dedup]="1"
6795602294fSDan Kimmel	feature[dedupprops]="2"
6805602294fSDan Kimmel	feature[sa_spill]="4"
6815602294fSDan Kimmel	feature[embed_data]="10000"
6825602294fSDan Kimmel	feature[lz4]="20000"
6835602294fSDan Kimmel	feature[mooch_byteswap]="40000"
6845602294fSDan Kimmel	feature[large_blocks]="80000"
6855602294fSDan Kimmel	feature[resuming]="100000"
6865602294fSDan Kimmel	feature[redacted]="200000"
6875602294fSDan Kimmel	feature[compressed]="400000"
6885602294fSDan Kimmel
6895602294fSDan Kimmel	typeset flag known derived=0
6905602294fSDan Kimmel	for flag in "$@"; do
6915602294fSDan Kimmel		known=${feature[$flag]}
6925602294fSDan Kimmel		[[ -z $known ]] && log_fail "Unknown feature: $flag"
6935602294fSDan Kimmel
6945602294fSDan Kimmel		derived=$(echo "$flags & ${feature[$flag]} = X" | mdb | sed 's/ //g')
6955602294fSDan Kimmel		[[ $derived = $known ]] || return 1
6965602294fSDan Kimmel	done
6975602294fSDan Kimmel
6985602294fSDan Kimmel	return 0
6995602294fSDan Kimmel}
7005602294fSDan Kimmel
7015602294fSDan Kimmel#
7025602294fSDan Kimmel# Parse zstreamdump -v output.  The output varies for each kind of record:
7035602294fSDan Kimmel# BEGIN records are simply output as "BEGIN"
7045602294fSDan Kimmel# END records are output as "END"
7055602294fSDan Kimmel# OBJECT records become "OBJECT <object num>"
7065602294fSDan Kimmel# FREEOBJECTS records become "FREEOBJECTS <startobj> <numobjs>"
7075602294fSDan Kimmel# FREE records become "<record type> <start> <length>"
7085602294fSDan Kimmel# WRITE records become:
7095602294fSDan Kimmel# "<record type> <compression type> <start> <logical size> <compressed size>
7105602294fSDan Kimmel#  <data size>"
7115602294fSDan Kimmel#
7125602294fSDan Kimmelfunction parse_dump
7135602294fSDan Kimmel{
7145602294fSDan Kimmel	sed '/^WRITE/{N;s/\n/ /;}' | grep "^[A-Z]" | awk '{
7155602294fSDan Kimmel	    if ($1 == "BEGIN" || $1 == "END") print $1
7165602294fSDan Kimmel	    if ($1 == "OBJECT") print $1" "$4
7175602294fSDan Kimmel	    if ($1 == "FREEOBJECTS") print $1" "$4" "$7
7185602294fSDan Kimmel	    if ($1 == "FREE") print $1" "$7" "$10
719eb633035STom Caputi	    if ($1 == "WRITE") print $1" "$15" "$21" "$24" "$27" "$30}'
7205602294fSDan Kimmel}
7215602294fSDan Kimmel
7225602294fSDan Kimmel#
7235602294fSDan Kimmel# Given a send stream, verify that the size of the stream matches what's
7245602294fSDan Kimmel# expected based on the source or target dataset. If the stream is an
7255602294fSDan Kimmel# incremental stream, subtract the size of the source snapshot before
7265602294fSDan Kimmel# comparing. This function does not currently handle incremental streams
7275602294fSDan Kimmel# that remove data.
7285602294fSDan Kimmel#
7295602294fSDan Kimmel# $1 The zstreamdump output file
7305602294fSDan Kimmel# $2 The dataset to compare against
7315602294fSDan Kimmel#    This can be a source of a send or recv target (fs, not snapshot)
7325602294fSDan Kimmel# $3 The percentage below which verification is deemed a failure
7335602294fSDan Kimmel# $4 The source snapshot of an incremental send
7345602294fSDan Kimmel#
7355602294fSDan Kimmel
7365602294fSDan Kimmelfunction verify_stream_size
7375602294fSDan Kimmel{
7385602294fSDan Kimmel	typeset stream=$1
7395602294fSDan Kimmel	typeset ds=$2
7405602294fSDan Kimmel	typeset percent=${3:-90}
7415602294fSDan Kimmel	typeset inc_src=$4
7425602294fSDan Kimmel
7435602294fSDan Kimmel	[[ -f $stream ]] || log_fail "No such file: $stream"
7445602294fSDan Kimmel	datasetexists $ds || log_fail "No such dataset: $ds"
7455602294fSDan Kimmel
7465602294fSDan Kimmel	typeset stream_size=$(cat $stream | zstreamdump | sed -n \
7475602294fSDan Kimmel	    's/	Total write size = \(.*\) (0x.*)/\1/p')
7485602294fSDan Kimmel
7495602294fSDan Kimmel	typeset inc_size=0
7505602294fSDan Kimmel	if [[ -n $inc_src ]]; then
7515602294fSDan Kimmel		inc_size=$(get_prop lrefer $inc_src)
7525602294fSDan Kimmel		if stream_has_features $stream compressed; then
7535602294fSDan Kimmel			inc_size=$(get_prop refer $inc_src)
7545602294fSDan Kimmel		fi
7555602294fSDan Kimmel	fi
7565602294fSDan Kimmel
7575602294fSDan Kimmel	if stream_has_features $stream compressed; then
7585602294fSDan Kimmel		ds_size=$(get_prop refer $ds)
7595602294fSDan Kimmel	else
7605602294fSDan Kimmel		ds_size=$(get_prop lrefer $ds)
7615602294fSDan Kimmel	fi
7625602294fSDan Kimmel	ds_size=$((ds_size - inc_size))
7635602294fSDan Kimmel
7645602294fSDan Kimmel	within_percent $stream_size $ds_size $percent || log_fail \
7655602294fSDan Kimmel	    "$stream_size $ds_size differed by too much"
7665602294fSDan Kimmel}
7675602294fSDan Kimmel
7685602294fSDan Kimmel# Cleanup function for tests involving resumable send
7695602294fSDan Kimmelfunction resume_cleanup
7705602294fSDan Kimmel{
7715602294fSDan Kimmel	typeset sendfs=$1
7725602294fSDan Kimmel	typeset streamfs=$2
773544132fcSloli10K	typeset sendpool=${sendfs%%/*}
7745602294fSDan Kimmel
7755602294fSDan Kimmel	datasetexists $sendfs && log_must zfs destroy -r $sendfs
7765602294fSDan Kimmel	datasetexists $streamfs && log_must zfs destroy -r $streamfs
7775602294fSDan Kimmel	cleanup_pool $POOL2
778544132fcSloli10K	rm -f /$sendpool/initial.zsend /$sendpool/incremental.zsend
7795602294fSDan Kimmel}
780*6ccda740Sloli10K
781*6ccda740Sloli10K# Randomly set the property to one of the enumerated values.
782*6ccda740Sloli10Kfunction rand_set_prop
783*6ccda740Sloli10K{
784*6ccda740Sloli10K	typeset dtst=$1
785*6ccda740Sloli10K	typeset prop=$2
786*6ccda740Sloli10K	shift 2
787*6ccda740Sloli10K	typeset value=$(random_get $@)
788*6ccda740Sloli10K
789*6ccda740Sloli10K	log_must eval "zfs set $prop='$value' $dtst"
790*6ccda740Sloli10K}
791*6ccda740Sloli10K
792*6ccda740Sloli10K# Generate a recursive checksum of a filesystems contents.  Only file
793*6ccda740Sloli10K# data is included in the checksum (no meta data, or xattrs).
794*6ccda740Sloli10Kfunction recursive_cksum
795*6ccda740Sloli10K{
796*6ccda740Sloli10K	find $1 -type f -exec sha256sum {} \; | \
797*6ccda740Sloli10K	    sort -k 2 | awk '{ print $1 }' | sha256sum
798*6ccda740Sloli10K}
799