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 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 #
65 function 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
77
78 log_must $ZFS snapshot $pool/$FS/vol@vsnap
79 log_must $ZFS clone $pool/$FS/vol@vsnap $pool/$FS/vclone
80 fi
81
82 log_must snapshot_tree $pool/$FS/fs1/fs2@fsnap
83 log_must $ZFS clone $pool/$FS/fs1/fs2@fsnap $pool/$FS/fs1/fclone
84 log_must $ZFS snapshot -r $pool@init
85
86 log_must snapshot_tree $pool@snapA
87 log_must snapshot_tree $pool@snapC
88 log_must snapshot_tree $pool/pclone@snapB
89 log_must snapshot_tree $pool/$FS@snapB
90 log_must snapshot_tree $pool/$FS@snapC
91 log_must snapshot_tree $pool/$FS/fs1@snapA
92 log_must snapshot_tree $pool/$FS/fs1@snapB
93 log_must snapshot_tree $pool/$FS/fs1@snapC
94 log_must snapshot_tree $pool/$FS/fs1/fclone@snapA
95
96 if is_global_zone ; then
97 log_must $ZFS snapshot $pool/vol@snapA
98 log_must $ZFS snapshot $pool/$FS/vol@snapB
99 log_must $ZFS snapshot $pool/$FS/vol@snapC
100 log_must $ZFS snapshot $pool/$FS/vclone@snapC
101 fi
102
103 log_must $ZFS snapshot -r $pool@final
104
105 return 0
106 }
107
108 #
109 # Cleanup the BACKDIR and given pool content and all the sub datasets
110 #
111 # $1 pool name
112 #
113 function cleanup_pool
114 {
115 typeset pool=$1
116 log_must $RM -rf $BACKDIR/*
117
118 if is_global_zone ; then
119 log_must $ZFS destroy -Rf $pool
120 else
121 typeset list=$($ZFS list -H -r -t filesystem,snapshot,volume -o name $pool)
122 for ds in $list ; do
123 if [[ $ds != $pool ]] ; then
124 if datasetexists $ds ; then
125 log_must $ZFS destroy -Rf $ds
126 fi
127 fi
128 done
129 fi
130
131 typeset mntpnt=$(get_prop mountpoint $pool)
132 if ! ismounted $pool ; then
133 # Make sure mountpoint directory is empty
134 if [[ -d $mntpnt ]]; then
135 log_must $RM -rf $mntpnt/*
136 fi
137
138 log_must $ZFS mount $pool
139 fi
140 if [[ -d $mntpnt ]]; then
141 log_must $RM -rf $mntpnt/*
142 fi
143
144 return 0
145 }
146
147 #
148 # Detect if the given two filesystems have same sub-datasets
149 #
150 # $1 source filesystem
151 # $2 destination filesystem
152 #
153 function cmp_ds_subs
154 {
155 typeset src_fs=$1
156 typeset dst_fs=$2
157
158 $ZFS list -r -H -t filesystem,snapshot,volume -o name $src_fs > $BACKDIR/src1
159 $ZFS list -r -H -t filesystem,snapshot,volume -o name $dst_fs > $BACKDIR/dst1
160
161 eval $SED -e 's:^$src_fs:PREFIX:g' < $BACKDIR/src1 > $BACKDIR/src
162 eval $SED -e 's:^$dst_fs:PREFIX:g' < $BACKDIR/dst1 > $BACKDIR/dst
163
164 $DIFF $BACKDIR/src $BACKDIR/dst
165 typeset -i ret=$?
166
167 $RM -f $BACKDIR/src $BACKDIR/dst $BACKDIR/src1 $BACKDIR/dst1
168
169 return $ret
170 }
171
172 #
173 # Compare all the directores and files in two filesystems
174 #
175 # $1 source filesystem
176 # $2 destination filesystem
177 #
178 function cmp_ds_cont
179 {
180 typeset src_fs=$1
181 typeset dst_fs=$2
182
183 typeset srcdir dstdir
184 srcdir=$(get_prop mountpoint $src_fs)
185 dstdir=$(get_prop mountpoint $dst_fs)
186
187 $DIFF -r $srcdir $dstdir > /dev/null 2>&1
188 echo $?
189 }
190
191 #
192 # Compare the given two dataset properties
193 #
194 # $1 dataset 1
195 # $2 dataset 2
196 #
197 function cmp_ds_prop
198 {
199 typeset dtst1=$1
200 typeset dtst2=$2
201
202 for item in "type" "origin" "volblocksize" "aclinherit" "aclmode" \
203 "atime" "canmount" "checksum" "compression" "copies" "devices" \
204 "exec" "quota" "readonly" "recordsize" "reservation" "setuid" \
205 "sharenfs" "snapdir" "version" "volsize" "xattr" "zoned" \
206 "mountpoint";
207 do
208 $ZFS get -H -o property,value,source $item $dtst1 >> \
209 $BACKDIR/dtst1
210 $ZFS get -H -o property,value,source $item $dtst2 >> \
211 $BACKDIR/dtst2
212 done
213
214 eval $SED -e 's:$dtst1:PREFIX:g' < $BACKDIR/dtst1 > $BACKDIR/dtst1
215 eval $SED -e 's:$dtst2:PREFIX:g' < $BACKDIR/dtst2 > $BACKDIR/dtst2
216
217 $DIFF $BACKDIR/dtst1 $BACKDIR/dtst2
218 typeset -i ret=$?
219
220 $RM -f $BACKDIR/dtst1 $BACKDIR/dtst2
221
222 return $ret
223
224 }
225
226 #
227 # Random create directories and files
228 #
229 # $1 directory
230 #
231 function random_tree
232 {
233 typeset dir=$1
234
235 if [[ -d $dir ]]; then
236 $RM -rf $dir
237 fi
238 $MKDIR -p $dir
239 typeset -i ret=$?
240
241 typeset -i nl nd nf
242 ((nl = RANDOM % 6 + 1))
243 ((nd = RANDOM % 3 ))
244 ((nf = RANDOM % 5 ))
245 $MKTREE -b $dir -l $nl -d $nd -f $nf
246 ((ret |= $?))
247
248 return $ret
249 }
250
251 #
252 # Put data in filesystem and take snapshot
253 #
254 # $1 snapshot name
255 #
256 function snapshot_tree
257 {
258 typeset snap=$1
259 typeset ds=${snap%%@*}
260 typeset type=$(get_prop "type" $ds)
261
262 typeset -i ret=0
263 if [[ $type == "filesystem" ]]; then
264 typeset mntpnt=$(get_prop mountpoint $ds)
265 ((ret |= $?))
266
267 if ((ret == 0)) ; then
268 eval random_tree $mntpnt/${snap##$ds}
269 ((ret |= $?))
270 fi
271 fi
272
273 if ((ret == 0)) ; then
274 $ZFS snapshot $snap
275 ((ret |= $?))
276 fi
277
278 return $ret
279 }
280
281 #
282 # Destroy the given snapshot and stuff
283 #
284 # $1 snapshot
285 #
286 function destroy_tree
287 {
288 typeset -i ret=0
289 typeset snap
290 for snap in "$@" ; do
291 $ZFS destroy $snap
292 ret=$?
293
294 typeset ds=${snap%%@*}
295 typeset type=$(get_prop "type" $ds)
296 if [[ $type == "filesystem" ]]; then
297 typeset mntpnt=$(get_prop mountpoint $ds)
298 ((ret |= $?))
299
300 if ((ret != 0)); then
301 $RM -r $mntpnt/$snap
302 ((ret |= $?))
303 fi
304 fi
305
306 if ((ret != 0)); then
307 return $ret
308 fi
309 done
310
311 return 0
312 }
313
314 #
315 # Get all the sub-datasets of give dataset with specific suffix
316 #
317 # $1 Given dataset
318 # $2 Suffix
319 #
320 function getds_with_suffix
321 {
322 typeset ds=$1
323 typeset suffix=$2
324
325 typeset list=$($ZFS list -r -H -t filesystem,snapshot,volume -o name $ds \
326 | $GREP "$suffix$")
327
328 $ECHO $list
329 }
330
331 #
332 # Output inherited properties whitch is edited for file system
333 #
334 function fs_inherit_prop
335 {
336 typeset fs_prop
337 if is_global_zone ; then
338 fs_prop=$($ZFS inherit 2>&1 | \
339 $AWK '$2=="YES" && $3=="YES" {print $1}')
340 if ! is_te_enabled ; then
341 fs_prop=$(echo $fs_prop | $GREP -v "mlslabel")
342 fi
343 else
344 fs_prop=$($ZFS inherit 2>&1 | \
345 $AWK '$2=="YES" && $3=="YES" {print $1}'|
346 $EGREP -v "devices|mlslabel|sharenfs|sharesmb|zoned")
347 fi
348
349 $ECHO $fs_prop
350 }
351
352 #
353 # Output inherited properties for volume
354 #
355 function vol_inherit_prop
356 {
357 $ECHO "checksum readonly"
358 }
359
360 #
361 # Get the destination dataset to compare
362 #
363 function get_dst_ds
364 {
365 typeset srcfs=$1
366 typeset dstfs=$2
367
368 #
369 # If the srcfs is not pool
370 #
371 if ! $ZPOOL list $srcfs > /dev/null 2>&1 ; then
372 eval dstfs="$dstfs/${srcfs#*/}"
373 fi
374
375 $ECHO $dstfs
376 }