xref: /freebsd/tests/sys/cddl/zfs/tests/rsend/rsend.kshlib (revision e0c4386e)
1# vim: filetype=sh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26
27. $STF_SUITE/include/libtest.kshlib
28
29#
30# Set up test model which includes various datasets
31#
32#               @final
33#               @snapB
34#               @init
35#               |
36#   ______ pclone
37#  |      /
38#  |@psnap
39#  ||                         @final
40#  ||@final       @final      @snapC
41#  ||@snapC       @snapC      @snapB
42#  ||@snapA       @snapB      @snapA
43#  ||@init        @init       @init
44#  |||            |           |
45# $pool -------- $FS ------- fs1 ------- fs2
46#    \             \\_____     \          |
47#     vol           vol   \____ \         @fsnap
48#      |              |        \ \              \
49#      @init          @vsnap   |  ------------ fclone
50#      @snapA         @init \  |                    |
51#      @final         @snapB \ |                    @init
52#                     @snapC  vclone                @snapA
53#                     @final       |                @final
54#                                 @init
55#                                 @snapC
56#                                 @final
57#
58# $1 pool name
59#
60function setup_test_model
61{
62	typeset pool=$1
63
64	log_must $ZFS create -p $pool/$FS/fs1/fs2
65
66	log_must $ZFS snapshot $pool@psnap
67	log_must $ZFS clone $pool@psnap $pool/pclone
68
69	if is_global_zone ; then
70		log_must $ZFS create -V 16M $pool/vol
71		log_must $ZFS create -V 16M $pool/$FS/vol
72
73		log_must $ZFS snapshot $pool/$FS/vol@vsnap
74		log_must $ZFS clone $pool/$FS/vol@vsnap $pool/$FS/vclone
75	fi
76
77	log_must snapshot_tree $pool/$FS/fs1/fs2@fsnap
78	log_must $ZFS clone $pool/$FS/fs1/fs2@fsnap $pool/$FS/fs1/fclone
79	log_must $ZFS snapshot -r $pool@init
80
81	log_must snapshot_tree $pool@snapA
82	log_must snapshot_tree $pool@snapC
83	log_must snapshot_tree $pool/pclone@snapB
84	log_must snapshot_tree $pool/$FS@snapB
85	log_must snapshot_tree $pool/$FS@snapC
86	log_must snapshot_tree $pool/$FS/fs1@snapA
87	log_must snapshot_tree $pool/$FS/fs1@snapB
88	log_must snapshot_tree $pool/$FS/fs1@snapC
89	log_must snapshot_tree $pool/$FS/fs1/fclone@snapA
90
91	if is_global_zone ; then
92		log_must $ZFS snapshot $pool/vol@snapA
93		log_must $ZFS snapshot $pool/$FS/vol@snapB
94		log_must $ZFS snapshot $pool/$FS/vol@snapC
95		log_must $ZFS snapshot $pool/$FS/vclone@snapC
96	fi
97
98	log_must $ZFS snapshot -r $pool@final
99
100	return 0
101}
102
103#
104# Cleanup the BACKDIR and given pool content and all the sub datasets
105#
106# $1 pool name
107#
108function cleanup_pool
109{
110	typeset pool=$1
111	log_must $RM -rf $BACKDIR/*
112
113	if is_global_zone ; then
114		log_must $ZFS destroy -Rf $pool
115	else
116		typeset list=$($ZFS list -H -r -t filesystem,snapshot,volume -o name $pool)
117		for ds in $list ; do
118			if [[ $ds != $pool ]] ; then
119				if datasetexists $ds ; then
120					log_must $ZFS destroy -Rf $ds
121				fi
122			fi
123		done
124	fi
125
126	typeset mntpnt=$(get_prop mountpoint $pool)
127	if ! ismounted $pool ; then
128		# Make sure mountpoint directory is empty
129		if [[ -d $mntpnt ]]; then
130			log_must $RM -rf $mntpnt/*
131		fi
132
133		log_must $ZFS mount $pool
134	fi
135	if [[ -d $mntpnt ]]; then
136		log_must $RM -rf $mntpnt/*
137	fi
138
139	return 0
140}
141
142#
143# Detect if the given two filesystems have same sub-datasets
144#
145# $1 source filesystem
146# $2 destination filesystem
147#
148function cmp_ds_subs
149{
150	typeset src_fs=$1
151	typeset dst_fs=$2
152
153	$ZFS list -r -H -t filesystem,snapshot,volume -o name $src_fs > $BACKDIR/src1
154	$ZFS list -r -H -t filesystem,snapshot,volume -o name $dst_fs > $BACKDIR/dst1
155
156	eval $SED -e 's:^$src_fs:PREFIX:g' < $BACKDIR/src1 > $BACKDIR/src
157	eval $SED -e 's:^$dst_fs:PREFIX:g' < $BACKDIR/dst1 > $BACKDIR/dst
158
159	$DIFF $BACKDIR/src $BACKDIR/dst
160	typeset -i ret=$?
161
162	$RM -f $BACKDIR/src $BACKDIR/dst $BACKDIR/src1 $BACKDIR/dst1
163
164	return $ret
165}
166
167#
168# Compare all the directores and files in two filesystems
169#
170# $1 source filesystem
171# $2 destination filesystem
172#
173function cmp_ds_cont
174{
175	typeset src_fs=$1
176	typeset dst_fs=$2
177
178	typeset srcdir dstdir
179	srcdir=$(get_prop mountpoint $src_fs)
180	dstdir=$(get_prop mountpoint $dst_fs)
181
182	$DIFF -r $srcdir $dstdir > /dev/null 2>&1
183	print $?
184}
185
186#
187# Compare the given two dataset properties
188#
189# $1 dataset 1
190# $2 dataset 2
191#
192function cmp_ds_prop
193{
194	typeset dtst1=$1
195	typeset dtst2=$2
196
197	for item in "type" "origin" "volblocksize" "aclinherit" "aclmode" \
198		"atime" "canmount" "checksum" "compression" "copies" "devices" \
199		"exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
200		"shareiscsi" "sharenfs" "snapdir" "version" "volsize" "xattr" \
201		"zoned" "mountpoint";
202	do
203		$ZFS get -H -o property,value,source $item $dtst1 >> \
204			$BACKDIR/dtst1
205		$ZFS get -H -o property,value,source $item $dtst2 >> \
206			$BACKDIR/dtst2
207	done
208
209	eval $SED -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
210	eval $SED -e 's:$dtst2:PREFIX:g' < $BACKDIR/dtst2 > $BACKDIR/dtst2
211
212	$DIFF $BACKDIR/dtst1 $BACKDIR/dtst2
213	typeset -i ret=$?
214
215	$RM -f $BACKDIR/dtst1 $BACKDIR/dtst2
216
217	return $ret
218
219}
220
221#
222# Random create directories and files
223#
224# $1 directory
225#
226function random_tree
227{
228	typeset dir=$1
229
230	if [[ -d $dir ]]; then
231		$RM -rf $dir
232	fi
233	$MKDIR -p $dir
234	typeset -i ret=$?
235
236	typeset -i nl nd nf
237	((nl = RANDOM % 6 + 1))
238	((nd = RANDOM % 3 ))
239	((nf = RANDOM % 5 ))
240	$MKTREE -b $dir -l $nl -d $nd -f $nf
241	((ret |= $?))
242
243	return $ret
244}
245
246#
247# Put data in filesystem and take snapshot
248#
249# $1 snapshot name
250#
251function snapshot_tree
252{
253	typeset snap=$1
254	typeset ds=${snap%%@*}
255	typeset type=$(get_prop "type" $ds)
256
257	typeset -i ret=0
258	if [[ $type == "filesystem" ]]; then
259		typeset mntpnt=$(get_prop mountpoint $ds)
260		((ret |= $?))
261
262		if ((ret == 0)) ; then
263			eval random_tree $mntpnt/${snap##$ds}
264			((ret |= $?))
265		fi
266	fi
267
268	if ((ret == 0)) ; then
269		$ZFS snapshot $snap
270		((ret |= $?))
271	fi
272
273	return $ret
274}
275
276#
277# Destroy the given snapshot and stuff
278#
279# $1 snapshot
280#
281function destroy_tree
282{
283	typeset -i ret=0
284	typeset snap
285	for snap in "$@" ; do
286		$ZFS destroy $snap
287		ret=$?
288
289		typeset ds=${snap%%@*}
290		typeset type=$(get_prop "type" $ds)
291		if [[ $type == "filesystem" ]]; then
292			typeset mntpnt=$(get_prop mountpoint $ds)
293			((ret |= $?))
294
295			if ((ret != 0)); then
296				$RM -r $mntpnt/$snap
297				((ret |= $?))
298			fi
299		fi
300
301		if ((ret != 0)); then
302			return $ret
303		fi
304	done
305
306	return 0
307}
308
309#
310# Get all the sub-datasets of give dataset with specific suffix
311#
312# $1 Given dataset
313# $2 Suffix
314#
315function getds_with_suffix
316{
317	typeset ds=$1
318	typeset suffix=$2
319
320	typeset list=$($ZFS list -r -H -t filesystem,snapshot,volume -o name $ds \
321		| $GREP "$suffix$")
322
323	$ECHO $list
324}
325
326#
327# Output inherited properties whitch is edited for file system
328#
329function fs_inherit_prop
330{
331	typeset fs_prop
332	if is_global_zone ; then
333		fs_prop=$($ZFS inherit 2>&1 | \
334			$AWK '$2=="YES" && $3=="YES" {print $1}')
335	else
336		fs_prop=$($ZFS inherit 2>&1 | \
337			$AWK '$2=="YES" && $3=="YES" {print $1}'|
338			$EGREP -v "devices|sharenfs|sharesmb|zoned")
339	fi
340
341	$ECHO $fs_prop
342}
343
344#
345# Output inherited properties for volume
346#
347function vol_inherit_prop
348{
349	$ECHO "checksum readonly shareiscsi"
350}
351
352#
353# Get the destination dataset to compare
354#
355function get_dst_ds
356{
357	typeset srcfs=$1
358	typeset dstfs=$2
359
360	#
361	# If the srcfs is not pool
362	#
363	if ! $ZPOOL list $srcfs > /dev/null 2>&1 ; then
364		eval dstfs="$dstfs/${srcfs#*/}"
365	fi
366
367	$ECHO $dstfs
368}
369