xref: /illumos-gate/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rollback/zfs_rollback_common.kshlib (revision b6805bf78d2bbbeeaea8909a05623587b42d58b3)
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 2008 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26
27#
28# Copyright (c) 2012 by Delphix. All rights reserved.
29#
30
31. $STF_SUITE/include/libtest.shlib
32. $STF_SUITE/tests/functional/cli_root/zfs_rollback/zfs_rollback.cfg
33
34# Get file sum
35#
36# $1 full file name
37function getsum #fname
38{
39	(( ${#1} == 0 )) && \
40		log_fail "Need give file name."
41	return $($SUM $1 | $AWK '{print $1}')
42}
43
44# Define global variable checksum, get the original file sum.
45#
46origsum=$(getsum /etc/passwd)
47
48#
49# Setup or recover the test environment. Firstly, copy /etc/passwd to ZFS file
50# system or volume, then make a snapshot or clone. Repeat up to three times.
51#
52# $1 number of snapshot. Note: Currently only support three snapshots.
53# $2 indicate if it is necessary to create clone
54#
55function setup_snap_env
56{
57	typeset -i cnt=${1:-3}
58	typeset createclone=${2:-"false"}
59
60	if datasetnonexists $FS; then
61		log_must $ZFS create $FS
62		log_must $ZFS set mountpoint=$TESTDIR $FS
63	fi
64	# Volume can't be created in Local Zone.
65	if datasetnonexists $VOL && is_global_zone; then
66		log_must $ZFS create -V $VOLSIZE $VOL
67	fi
68
69	# Make sure $VOL is volume
70	typeset type=$(get_prop type $VOL)
71	if datasetexists $VOL && \
72		[[ $type == 'volume' ]]; then
73		#
74		# At the first time, Make a UFS file system in volume and
75		# mount it. Otherwise, only check if this ufs file system
76		# was mounted.
77		#
78		log_must eval "$ECHO "y" | \
79			$NEWFS -v /dev/zvol/dsk/$VOL > /dev/null 2>&1"
80
81		[[ ! -d $TESTDIR1 ]] && log_must $MKDIR $TESTDIR1
82
83		# Make sure the ufs filesystem hasn't been mounted,
84		# then mount the new ufs filesystem.
85		$DF -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1
86		if (( $? != 0 )); then
87			log_must $MOUNT \
88				/dev/zvol/dsk/$TESTPOOL/$TESTVOL $TESTDIR1
89		fi
90	fi
91
92	# Separately Create three snapshots for file system & volume
93	typeset -i ind=0
94	typeset dtst
95	for dtst in $FS $VOL; do
96		# Volume can be created in Local Zone.
97		if [[ $dtst == $VOL ]]; then
98			if ! is_global_zone; then
99				break
100			fi
101		fi
102
103		ind=0
104		while (( ind < cnt )); do
105			case $dtst in
106			$FS)
107				eval typeset snap=\$FSSNAP$ind
108				eval typeset clone=\$FSCLONE$ind
109				eval typeset fname=\$TESTDIR/\$TESTFILE$ind
110				;;
111			$VOL)
112				eval typeset snap=\$VOLSNAP$ind
113				eval typeset clone=\$VOLCLONE$ind
114				eval typeset fname=\$TESTDIR1/\$TESTFILE$ind
115				;;
116			esac
117
118			if datasetnonexists $snap; then
119				log_must $CP /etc/passwd $fname
120				#
121				# using 'lockfs -f' to flush the writes to disk
122				# before taking a snapshot.
123				#
124				if [[ $dtst == $VOL ]]; then
125					log_must /usr/sbin/lockfs -f $TESTDIR1
126				fi
127				log_must $ZFS snapshot $snap
128			fi
129			if [[ $createclone == "true" ]]; then
130				if datasetnonexists $clone; then
131					log_must $ZFS clone $snap $clone
132				fi
133			fi
134			(( ind += 1 ))
135		done
136	done
137}
138
139function setup_clone_env
140{
141	setup_snap_env $1 "true"
142}
143
144#
145# Clean up the test environmnet
146#
147# $1 number of snapshot Note: Currently only support three snapshots.
148#
149function cleanup_env
150{
151	typeset -i cnt=${1:-3}
152	typeset -i ind=0
153	typeset dtst
154	typeset snap
155
156	$PKILL ${DD##*/}
157
158	$DF -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1
159	if (( $? == 0 )); then
160		log_must $UMOUNT -f $TESTDIR1
161	fi
162
163	[[ -d $TESTDIR ]] && log_must $RM -rf $TESTDIR/*
164	[[ -d $TESTDIR1 ]] && log_must $RM -rf $TESTDIR1/*
165
166	for dtst in $FS $VOL; do
167		for snap in $TESTSNAP $TESTSNAP1 $TESTSNAP2; do
168			if snapexists $dtst@$snap; then
169				 log_must $ZFS destroy -Rf $dtst@$snap
170			fi
171		done
172	done
173
174	# Restore original test environment
175	if datasetnonexists $FS ; then
176		log_must $ZFS create $FS
177	fi
178	if datasetnonexists $VOL ; then
179		if is_global_zone ; then
180			log_must $ZFS create -V $VOLSIZE $VOL
181		else
182			log_must $ZFS create $VOL
183		fi
184	fi
185}
186
187#
188# check if the specified files have specified status.
189#
190# $1 expected status
191# $2-n full file name
192# If it is true return 0, else return 1
193#
194function file_status
195{
196	(( $# == 0 )) && \
197		log_fail "The file name is not defined."
198
199	typeset opt
200	case $1 in
201		exist)	opt="-e" ;;
202		nonexist) opt="! -e" ;;
203		*)	log_fail "Unsupported file status." ;;
204	esac
205
206	shift
207	while (( $# > 0 )); do
208		eval [[ $opt $1 ]] || return 1
209		shift
210	done
211
212	return 0
213}
214
215function files_exist
216{
217	file_status "exist" $@
218}
219
220function files_nonexist
221{
222	file_status "nonexist" $@
223}
224
225#
226# According to snapshot check if the file system was recovered to the right
227# point.
228#
229# $1 snapshot. fs@snap or vol@snap
230#
231function check_files
232{
233	typeset dtst=$1
234
235	if [[ $(get_prop type $dtst) != snapshot ]]; then
236		log_fail "Parameter must be a snapshot."
237	fi
238
239	typeset fsvol=${dtst%%@*}
240	typeset snap=${dtst##*@}
241	if [[ $(get_prop type $fsvol) == "filesystem" ]]; then
242		ind=""
243	else
244		ind="1"
245	fi
246
247	eval typeset file0=\$TESTDIR$ind/\$TESTFILE0
248	eval typeset file1=\$TESTDIR$ind/\$TESTFILE1
249	eval typeset file2=\$TESTDIR$ind/\$TESTFILE2
250
251	case $snap in
252		$TESTSNAP2)
253			log_must files_exist $file0 $file1 $file2
254
255			typeset sum0=$(getsum $file0)
256			typeset sum1=$(getsum $file1)
257			typeset sum2=$(getsum $file2)
258			if [[ $sum0 != $origsum || \
259				$sum1 != $origsum || sum2 != $origsum ]]
260			then
261				log_fail "After rollback, file sum is changed."
262			fi
263			;;
264		$TESTSNAP1)
265			log_must files_exist $file0 $file1
266			log_must files_nonexist $file2
267
268			typeset sum0=$(getsum $file0)
269			typeset sum1=$(getsum $file1)
270			if [[ $sum0 != $origsum || $sum1 != $origsum ]]
271			then
272				log_fail "After rollback, file sum is changed."
273			fi
274			;;
275		$TESTSNAP)
276			log_must files_exist $file0
277			log_must files_nonexist $file1 $file2
278
279			typeset sum0=$(getsum $file0)
280			if [[ $sum0 != $origsum ]]; then
281				log_fail "After rollback, file sum is changed."
282			fi
283			;;
284	esac
285}
286
287# According to dataset type, write file to different directories.
288#
289# $1 dataset
290#
291function write_mountpoint_dir
292{
293	typeset dtst=$1
294	typeset dir
295
296	if [[ $dtst == $FS ]]; then
297		dir=$TESTDIR
298		log_must ismounted $dir
299	else
300		dir=$TESTDIR1
301		log_must ismounted $dir "ufs"
302	fi
303	$DD if=/dev/urandom of=$dir/$TESTFILE1 &
304	log_must $SLEEP 3
305}
306