xref: /illumos-gate/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rollback/zfs_rollback_common.kshlib (revision 41278390879703388be2320f582043bc61edf39d)
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, 2016 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 new_fs ${ZVOL_RDEVDIR}/$VOL
79
80		[[ ! -d $TESTDIR1 ]] && log_must mkdir $TESTDIR1
81
82		# Make sure the ufs filesystem hasn't been mounted,
83		# then mount the new ufs filesystem.
84		df -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1
85		if (( $? != 0 )); then
86			log_must mount \
87				${ZVOL_DEVDIR}/$TESTPOOL/$TESTVOL $TESTDIR1
88		fi
89	fi
90
91	# Separately Create three snapshots for file system & volume
92	typeset -i ind=0
93	typeset dtst
94	for dtst in $FS $VOL; do
95		# Volume can be created in Local Zone.
96		if [[ $dtst == $VOL ]]; then
97			if ! is_global_zone; then
98				break
99			fi
100		fi
101
102		ind=0
103		while (( ind < cnt )); do
104			case $dtst in
105			$FS)
106				eval typeset snap=\$FSSNAP$ind
107				eval typeset clone=\$FSCLONE$ind
108				eval typeset fname=\$TESTDIR/\$TESTFILE$ind
109				;;
110			$VOL)
111				eval typeset snap=\$VOLSNAP$ind
112				eval typeset clone=\$VOLCLONE$ind
113				eval typeset fname=\$TESTDIR1/\$TESTFILE$ind
114				;;
115			esac
116
117			if datasetnonexists $snap; then
118				log_must cp /etc/passwd $fname
119				#
120				# using 'lockfs -f' to flush the writes to disk
121				# before taking a snapshot.
122				#
123				if [[ $dtst == $VOL ]]; then
124					log_must lockfs -f $TESTDIR1
125				fi
126				log_must zfs snapshot $snap
127			fi
128			if [[ $createclone == "true" ]]; then
129				if datasetnonexists $clone; then
130					log_must zfs clone $snap $clone
131				fi
132			fi
133			(( ind += 1 ))
134		done
135	done
136}
137
138function setup_clone_env
139{
140	setup_snap_env $1 "true"
141}
142
143#
144# Clean up the test environmnet
145#
146# $1 number of snapshot Note: Currently only support three snapshots.
147#
148function cleanup_env
149{
150	typeset -i cnt=${1:-3}
151	typeset -i ind=0
152	typeset dtst
153	typeset snap
154
155	pkill ${DD##*/}
156
157	df -lhF ufs "/dev/zvol/dsk/$VOL" > /dev/null 2>&1
158	if (( $? == 0 )); then
159		log_must umount -f $TESTDIR1
160	fi
161
162	[[ -d $TESTDIR ]] && log_must rm -rf $TESTDIR/*
163	[[ -d $TESTDIR1 ]] && log_must rm -rf $TESTDIR1/*
164
165	for dtst in $FS $VOL; do
166		for snap in $TESTSNAP $TESTSNAP1 $TESTSNAP2; do
167			if snapexists $dtst@$snap; then
168				 log_must zfs destroy -Rf $dtst@$snap
169			fi
170		done
171	done
172
173	# Restore original test environment
174	if datasetnonexists $FS ; then
175		log_must zfs create $FS
176	fi
177	if datasetnonexists $VOL ; then
178		if is_global_zone ; then
179			log_must zfs create -V $VOLSIZE $VOL
180		else
181			log_must zfs create $VOL
182		fi
183	fi
184}
185
186#
187# check if the specified files have specified status.
188#
189# $1 expected status
190# $2-n full file name
191# If it is true return 0, else return 1
192#
193function file_status
194{
195	(( $# == 0 )) && \
196		log_fail "The file name is not defined."
197
198	typeset opt
199	case $1 in
200		exist)	opt="-e" ;;
201		nonexist) opt="! -e" ;;
202		*)	log_fail "Unsupported file status." ;;
203	esac
204
205	shift
206	while (( $# > 0 )); do
207		eval [[ $opt $1 ]] || return 1
208		shift
209	done
210
211	return 0
212}
213
214function files_exist
215{
216	file_status "exist" $@
217}
218
219function files_nonexist
220{
221	file_status "nonexist" $@
222}
223
224#
225# According to snapshot check if the file system was recovered to the right
226# point.
227#
228# $1 snapshot. fs@snap or vol@snap
229#
230function check_files
231{
232	typeset dtst=$1
233
234	if [[ $(get_prop type $dtst) != snapshot ]]; then
235		log_fail "Parameter must be a snapshot."
236	fi
237
238	typeset fsvol=${dtst%%@*}
239	typeset snap=${dtst##*@}
240	if [[ $(get_prop type $fsvol) == "filesystem" ]]; then
241		ind=""
242	else
243		ind="1"
244	fi
245
246	eval typeset file0=\$TESTDIR$ind/\$TESTFILE0
247	eval typeset file1=\$TESTDIR$ind/\$TESTFILE1
248	eval typeset file2=\$TESTDIR$ind/\$TESTFILE2
249
250	case $snap in
251		$TESTSNAP2)
252			log_must files_exist $file0 $file1 $file2
253
254			typeset sum0=$(getsum $file0)
255			typeset sum1=$(getsum $file1)
256			typeset sum2=$(getsum $file2)
257			if [[ $sum0 != $origsum || \
258				$sum1 != $origsum || sum2 != $origsum ]]
259			then
260				log_fail "After rollback, file sum is changed."
261			fi
262			;;
263		$TESTSNAP1)
264			log_must files_exist $file0 $file1
265			log_must files_nonexist $file2
266
267			typeset sum0=$(getsum $file0)
268			typeset sum1=$(getsum $file1)
269			if [[ $sum0 != $origsum || $sum1 != $origsum ]]
270			then
271				log_fail "After rollback, file sum is changed."
272			fi
273			;;
274		$TESTSNAP)
275			log_must files_exist $file0
276			log_must files_nonexist $file1 $file2
277
278			typeset sum0=$(getsum $file0)
279			if [[ $sum0 != $origsum ]]; then
280				log_fail "After rollback, file sum is changed."
281			fi
282			;;
283	esac
284}
285
286# According to dataset type, write file to different directories.
287#
288# $1 dataset
289#
290function write_mountpoint_dir
291{
292	typeset dtst=$1
293	typeset dir
294
295	if [[ $dtst == $FS ]]; then
296		dir=$TESTDIR
297		log_must ismounted $dir
298	else
299		dir=$TESTDIR1
300		log_must ismounted $dir "ufs"
301	fi
302	dd if=/dev/urandom of=$dir/$TESTFILE1 &
303	log_must sleep 3
304}
305