1d583b39bSJohn Wren Kennedy#
2d583b39bSJohn Wren Kennedy# CDDL HEADER START
3d583b39bSJohn Wren Kennedy#
4d583b39bSJohn Wren Kennedy# The contents of this file are subject to the terms of the
5d583b39bSJohn Wren Kennedy# Common Development and Distribution License (the "License").
6d583b39bSJohn Wren Kennedy# You may not use this file except in compliance with the License.
7d583b39bSJohn Wren Kennedy#
8d583b39bSJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d583b39bSJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing.
10d583b39bSJohn Wren Kennedy# See the License for the specific language governing permissions
11d583b39bSJohn Wren Kennedy# and limitations under the License.
12d583b39bSJohn Wren Kennedy#
13d583b39bSJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each
14d583b39bSJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d583b39bSJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the
16d583b39bSJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying
17d583b39bSJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner]
18d583b39bSJohn Wren Kennedy#
19d583b39bSJohn Wren Kennedy# CDDL HEADER END
20d583b39bSJohn Wren Kennedy#
21d583b39bSJohn Wren Kennedy
22d583b39bSJohn Wren Kennedy#
23d583b39bSJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24d583b39bSJohn Wren Kennedy# Use is subject to license terms.
2586714001SSerapheim Dimitropoulos# Copyright (c) 2012, 2017 by Delphix. All rights reserved.
26084fd14fSBrian Behlendorf# Copyright (c) 2017 by Tim Chase. All rights reserved.
27084fd14fSBrian Behlendorf# Copyright (c) 2017 by Nexenta Systems, Inc. All rights reserved.
281702cce7SAlek Pinchuk# Copyright (c) 2017 Datto Inc.
29dd50e0ccSTony Hutter# Copyright 2020 Joyent, Inc.
30d583b39bSJohn Wren Kennedy#
31d583b39bSJohn Wren Kennedy
32d583b39bSJohn Wren Kennedy. ${STF_TOOLS}/contrib/include/logapi.shlib
33084fd14fSBrian Behlendorf. ${STF_SUITE}/include/math.shlib
34a60ca23dSTom Caputi. ${STF_SUITE}/include/blkdev.shlib
35a60ca23dSTom Caputi
36a60ca23dSTom Caputi# Determine if this is a Linux test system
37a60ca23dSTom Caputi#
38a60ca23dSTom Caputi# Return 0 if platform Linux, 1 if otherwise
39a60ca23dSTom Caputi
40a60ca23dSTom Caputifunction is_linux
41a60ca23dSTom Caputi{
42a60ca23dSTom Caputi	if [[ $(uname -o) == "GNU/Linux" ]]; then
43a60ca23dSTom Caputi		return 0
44a60ca23dSTom Caputi	else
45a60ca23dSTom Caputi		return 1
46a60ca23dSTom Caputi	fi
47a60ca23dSTom Caputi}
48d583b39bSJohn Wren Kennedy
49d583b39bSJohn Wren Kennedy# Determine whether a dataset is mounted
50d583b39bSJohn Wren Kennedy#
51d583b39bSJohn Wren Kennedy# $1 dataset name
52d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
53d583b39bSJohn Wren Kennedy#
54d583b39bSJohn Wren Kennedy# Return 0 if dataset is mounted; 1 if unmounted; 2 on error
55d583b39bSJohn Wren Kennedy
56d583b39bSJohn Wren Kennedyfunction ismounted
57d583b39bSJohn Wren Kennedy{
58d583b39bSJohn Wren Kennedy	typeset fstype=$2
59d583b39bSJohn Wren Kennedy	[[ -z $fstype ]] && fstype=zfs
60d583b39bSJohn Wren Kennedy	typeset out dir name ret
61d583b39bSJohn Wren Kennedy
62d583b39bSJohn Wren Kennedy	case $fstype in
63d583b39bSJohn Wren Kennedy		zfs)
64d583b39bSJohn Wren Kennedy			if [[ "$1" == "/"* ]] ; then
651d32ba66SJohn Wren Kennedy				for out in $(zfs mount | awk '{print $2}'); do
66d583b39bSJohn Wren Kennedy					[[ $1 == $out ]] && return 0
67d583b39bSJohn Wren Kennedy				done
68d583b39bSJohn Wren Kennedy			else
691d32ba66SJohn Wren Kennedy				for out in $(zfs mount | awk '{print $1}'); do
70d583b39bSJohn Wren Kennedy					[[ $1 == $out ]] && return 0
71d583b39bSJohn Wren Kennedy				done
72d583b39bSJohn Wren Kennedy			fi
73d583b39bSJohn Wren Kennedy		;;
74d583b39bSJohn Wren Kennedy		ufs|nfs)
751d32ba66SJohn Wren Kennedy			out=$(df -F $fstype $1 2>/dev/null)
76d583b39bSJohn Wren Kennedy			ret=$?
77d583b39bSJohn Wren Kennedy			(($ret != 0)) && return $ret
78d583b39bSJohn Wren Kennedy
79d583b39bSJohn Wren Kennedy			dir=${out%%\(*}
80d583b39bSJohn Wren Kennedy			dir=${dir%% *}
81d583b39bSJohn Wren Kennedy			name=${out##*\(}
82d583b39bSJohn Wren Kennedy			name=${name%%\)*}
83d583b39bSJohn Wren Kennedy			name=${name%% *}
84d583b39bSJohn Wren Kennedy
85d583b39bSJohn Wren Kennedy			[[ "$1" == "$dir" || "$1" == "$name" ]] && return 0
86d583b39bSJohn Wren Kennedy		;;
87d583b39bSJohn Wren Kennedy	esac
88d583b39bSJohn Wren Kennedy
89d583b39bSJohn Wren Kennedy	return 1
90d583b39bSJohn Wren Kennedy}
91d583b39bSJohn Wren Kennedy
92d583b39bSJohn Wren Kennedy# Return 0 if a dataset is mounted; 1 otherwise
93d583b39bSJohn Wren Kennedy#
94d583b39bSJohn Wren Kennedy# $1 dataset name
95d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
96d583b39bSJohn Wren Kennedy
97d583b39bSJohn Wren Kennedyfunction mounted
98d583b39bSJohn Wren Kennedy{
99d583b39bSJohn Wren Kennedy	ismounted $1 $2
100d583b39bSJohn Wren Kennedy	(($? == 0)) && return 0
101d583b39bSJohn Wren Kennedy	return 1
102d583b39bSJohn Wren Kennedy}
103d583b39bSJohn Wren Kennedy
104d583b39bSJohn Wren Kennedy# Return 0 if a dataset is unmounted; 1 otherwise
105d583b39bSJohn Wren Kennedy#
106d583b39bSJohn Wren Kennedy# $1 dataset name
107d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
108d583b39bSJohn Wren Kennedy
109d583b39bSJohn Wren Kennedyfunction unmounted
110d583b39bSJohn Wren Kennedy{
111d583b39bSJohn Wren Kennedy	ismounted $1 $2
112d583b39bSJohn Wren Kennedy	(($? == 1)) && return 0
113d583b39bSJohn Wren Kennedy	return 1
114d583b39bSJohn Wren Kennedy}
115d583b39bSJohn Wren Kennedy
116d583b39bSJohn Wren Kennedy# split line on ","
117d583b39bSJohn Wren Kennedy#
118d583b39bSJohn Wren Kennedy# $1 - line to split
119d583b39bSJohn Wren Kennedy
120d583b39bSJohn Wren Kennedyfunction splitline
121d583b39bSJohn Wren Kennedy{
1221d32ba66SJohn Wren Kennedy	echo $1 | sed "s/,/ /g"
123d583b39bSJohn Wren Kennedy}
124d583b39bSJohn Wren Kennedy
125d583b39bSJohn Wren Kennedyfunction default_setup
126d583b39bSJohn Wren Kennedy{
127d583b39bSJohn Wren Kennedy	default_setup_noexit "$@"
128d583b39bSJohn Wren Kennedy
129d583b39bSJohn Wren Kennedy	log_pass
130d583b39bSJohn Wren Kennedy}
131d583b39bSJohn Wren Kennedy
132d583b39bSJohn Wren Kennedy#
133d583b39bSJohn Wren Kennedy# Given a list of disks, setup storage pools and datasets.
134d583b39bSJohn Wren Kennedy#
135d583b39bSJohn Wren Kennedyfunction default_setup_noexit
136d583b39bSJohn Wren Kennedy{
137d583b39bSJohn Wren Kennedy	typeset disklist=$1
138d583b39bSJohn Wren Kennedy	typeset container=$2
139d583b39bSJohn Wren Kennedy	typeset volume=$3
140d583b39bSJohn Wren Kennedy
141d583b39bSJohn Wren Kennedy	if is_global_zone; then
142d583b39bSJohn Wren Kennedy		if poolexists $TESTPOOL ; then
143d583b39bSJohn Wren Kennedy			destroy_pool $TESTPOOL
144d583b39bSJohn Wren Kennedy		fi
1451d32ba66SJohn Wren Kennedy		[[ -d /$TESTPOOL ]] && rm -rf /$TESTPOOL
1461d32ba66SJohn Wren Kennedy		log_must zpool create -f $TESTPOOL $disklist
147d583b39bSJohn Wren Kennedy	else
148d583b39bSJohn Wren Kennedy		reexport_pool
149d583b39bSJohn Wren Kennedy	fi
150d583b39bSJohn Wren Kennedy
1511d32ba66SJohn Wren Kennedy	rm -rf $TESTDIR  || log_unresolved Could not remove $TESTDIR
1521d32ba66SJohn Wren Kennedy	mkdir -p $TESTDIR || log_unresolved Could not create $TESTDIR
153d583b39bSJohn Wren Kennedy
1541d32ba66SJohn Wren Kennedy	log_must zfs create $TESTPOOL/$TESTFS
1551d32ba66SJohn Wren Kennedy	log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
156d583b39bSJohn Wren Kennedy
157d583b39bSJohn Wren Kennedy	if [[ -n $container ]]; then
1581d32ba66SJohn Wren Kennedy		rm -rf $TESTDIR1  || \
159d583b39bSJohn Wren Kennedy			log_unresolved Could not remove $TESTDIR1
1601d32ba66SJohn Wren Kennedy		mkdir -p $TESTDIR1 || \
161d583b39bSJohn Wren Kennedy			log_unresolved Could not create $TESTDIR1
162d583b39bSJohn Wren Kennedy
1631d32ba66SJohn Wren Kennedy		log_must zfs create $TESTPOOL/$TESTCTR
1641d32ba66SJohn Wren Kennedy		log_must zfs set canmount=off $TESTPOOL/$TESTCTR
1651d32ba66SJohn Wren Kennedy		log_must zfs create $TESTPOOL/$TESTCTR/$TESTFS1
1661d32ba66SJohn Wren Kennedy		log_must zfs set mountpoint=$TESTDIR1 \
167d583b39bSJohn Wren Kennedy		    $TESTPOOL/$TESTCTR/$TESTFS1
168d583b39bSJohn Wren Kennedy	fi
169d583b39bSJohn Wren Kennedy
170d583b39bSJohn Wren Kennedy	if [[ -n $volume ]]; then
171d583b39bSJohn Wren Kennedy		if is_global_zone ; then
1721d32ba66SJohn Wren Kennedy			log_must zfs create -V $VOLSIZE $TESTPOOL/$TESTVOL
173d583b39bSJohn Wren Kennedy		else
1741d32ba66SJohn Wren Kennedy			log_must zfs create $TESTPOOL/$TESTVOL
175d583b39bSJohn Wren Kennedy		fi
176d583b39bSJohn Wren Kennedy	fi
177d583b39bSJohn Wren Kennedy}
178d583b39bSJohn Wren Kennedy
179d583b39bSJohn Wren Kennedy#
180d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool, file system and
181d583b39bSJohn Wren Kennedy# a container.
182d583b39bSJohn Wren Kennedy#
183d583b39bSJohn Wren Kennedyfunction default_container_setup
184d583b39bSJohn Wren Kennedy{
185d583b39bSJohn Wren Kennedy	typeset disklist=$1
186d583b39bSJohn Wren Kennedy
187d583b39bSJohn Wren Kennedy	default_setup "$disklist" "true"
188d583b39bSJohn Wren Kennedy}
189d583b39bSJohn Wren Kennedy
190d583b39bSJohn Wren Kennedy#
191d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool,file system
192d583b39bSJohn Wren Kennedy# and a volume.
193d583b39bSJohn Wren Kennedy#
194d583b39bSJohn Wren Kennedyfunction default_volume_setup
195d583b39bSJohn Wren Kennedy{
196d583b39bSJohn Wren Kennedy	typeset disklist=$1
197d583b39bSJohn Wren Kennedy
198d583b39bSJohn Wren Kennedy	default_setup "$disklist" "" "true"
199d583b39bSJohn Wren Kennedy}
200d583b39bSJohn Wren Kennedy
201d583b39bSJohn Wren Kennedy#
202d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool,file system,
203d583b39bSJohn Wren Kennedy# a container and a volume.
204d583b39bSJohn Wren Kennedy#
205d583b39bSJohn Wren Kennedyfunction default_container_volume_setup
206d583b39bSJohn Wren Kennedy{
207d583b39bSJohn Wren Kennedy	typeset disklist=$1
208d583b39bSJohn Wren Kennedy
209d583b39bSJohn Wren Kennedy	default_setup "$disklist" "true" "true"
210d583b39bSJohn Wren Kennedy}
211d583b39bSJohn Wren Kennedy
212d583b39bSJohn Wren Kennedy#
213d583b39bSJohn Wren Kennedy# Create a snapshot on a filesystem or volume. Defaultly create a snapshot on
214d583b39bSJohn Wren Kennedy# filesystem
215d583b39bSJohn Wren Kennedy#
216dfc11533SChris Williamson# $1 Existing filesystem or volume name. Default, $TESTPOOL/$TESTFS
217d583b39bSJohn Wren Kennedy# $2 snapshot name. Default, $TESTSNAP
218d583b39bSJohn Wren Kennedy#
219d583b39bSJohn Wren Kennedyfunction create_snapshot
220d583b39bSJohn Wren Kennedy{
221dfc11533SChris Williamson	typeset fs_vol=${1:-$TESTPOOL/$TESTFS}
222d583b39bSJohn Wren Kennedy	typeset snap=${2:-$TESTSNAP}
223d583b39bSJohn Wren Kennedy
224d583b39bSJohn Wren Kennedy	[[ -z $fs_vol ]] && log_fail "Filesystem or volume's name is undefined."
225d583b39bSJohn Wren Kennedy	[[ -z $snap ]] && log_fail "Snapshot's name is undefined."
226d583b39bSJohn Wren Kennedy
227d583b39bSJohn Wren Kennedy	if snapexists $fs_vol@$snap; then
228d583b39bSJohn Wren Kennedy		log_fail "$fs_vol@$snap already exists."
229d583b39bSJohn Wren Kennedy	fi
230d583b39bSJohn Wren Kennedy	datasetexists $fs_vol || \
231d583b39bSJohn Wren Kennedy		log_fail "$fs_vol must exist."
232d583b39bSJohn Wren Kennedy
2331d32ba66SJohn Wren Kennedy	log_must zfs snapshot $fs_vol@$snap
234d583b39bSJohn Wren Kennedy}
235d583b39bSJohn Wren Kennedy
236d583b39bSJohn Wren Kennedy#
237d583b39bSJohn Wren Kennedy# Create a clone from a snapshot, default clone name is $TESTCLONE.
238d583b39bSJohn Wren Kennedy#
239d583b39bSJohn Wren Kennedy# $1 Existing snapshot, $TESTPOOL/$TESTFS@$TESTSNAP is default.
240d583b39bSJohn Wren Kennedy# $2 Clone name, $TESTPOOL/$TESTCLONE is default.
241d583b39bSJohn Wren Kennedy#
242d583b39bSJohn Wren Kennedyfunction create_clone   # snapshot clone
243d583b39bSJohn Wren Kennedy{
244d583b39bSJohn Wren Kennedy	typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
245d583b39bSJohn Wren Kennedy	typeset clone=${2:-$TESTPOOL/$TESTCLONE}
246d583b39bSJohn Wren Kennedy
247d583b39bSJohn Wren Kennedy	[[ -z $snap ]] && \
248d583b39bSJohn Wren Kennedy		log_fail "Snapshot name is undefined."
249d583b39bSJohn Wren Kennedy	[[ -z $clone ]] && \
250d583b39bSJohn Wren Kennedy		log_fail "Clone name is undefined."
251d583b39bSJohn Wren Kennedy
2521d32ba66SJohn Wren Kennedy	log_must zfs clone $snap $clone
253d583b39bSJohn Wren Kennedy}
254d583b39bSJohn Wren Kennedy
255edb901aaSMarcel Telka#
256edb901aaSMarcel Telka# Create a bookmark of the given snapshot.  Defaultly create a bookmark on
257edb901aaSMarcel Telka# filesystem.
258edb901aaSMarcel Telka#
259edb901aaSMarcel Telka# $1 Existing filesystem or volume name. Default, $TESTFS
260edb901aaSMarcel Telka# $2 Existing snapshot name. Default, $TESTSNAP
261edb901aaSMarcel Telka# $3 bookmark name. Default, $TESTBKMARK
262edb901aaSMarcel Telka#
263edb901aaSMarcel Telkafunction create_bookmark
264edb901aaSMarcel Telka{
265edb901aaSMarcel Telka	typeset fs_vol=${1:-$TESTFS}
266edb901aaSMarcel Telka	typeset snap=${2:-$TESTSNAP}
267edb901aaSMarcel Telka	typeset bkmark=${3:-$TESTBKMARK}
268edb901aaSMarcel Telka
269edb901aaSMarcel Telka	[[ -z $fs_vol ]] && log_fail "Filesystem or volume's name is undefined."
270edb901aaSMarcel Telka	[[ -z $snap ]] && log_fail "Snapshot's name is undefined."
271edb901aaSMarcel Telka	[[ -z $bkmark ]] && log_fail "Bookmark's name is undefined."
272edb901aaSMarcel Telka
273edb901aaSMarcel Telka	if bkmarkexists $fs_vol#$bkmark; then
274edb901aaSMarcel Telka		log_fail "$fs_vol#$bkmark already exists."
275edb901aaSMarcel Telka	fi
276edb901aaSMarcel Telka	datasetexists $fs_vol || \
277edb901aaSMarcel Telka		log_fail "$fs_vol must exist."
278edb901aaSMarcel Telka	snapexists $fs_vol@$snap || \
279edb901aaSMarcel Telka		log_fail "$fs_vol@$snap must exist."
280edb901aaSMarcel Telka
281f5fb56deSJohn Wren Kennedy	log_must zfs bookmark $fs_vol@$snap $fs_vol#$bkmark
282edb901aaSMarcel Telka}
283edb901aaSMarcel Telka
284add927f8Sloli#
285add927f8Sloli# Create a temporary clone result of an interrupted resumable 'zfs receive'
286add927f8Sloli# $1 Destination filesystem name. Must not exist, will be created as the result
287add927f8Sloli#    of this function along with its %recv temporary clone
288add927f8Sloli# $2 Source filesystem name. Must not exist, will be created and destroyed
289add927f8Sloli#
290add927f8Slolifunction create_recv_clone
291add927f8Sloli{
292add927f8Sloli	typeset recvfs="$1"
293add927f8Sloli	typeset sendfs="${2:-$TESTPOOL/create_recv_clone}"
294add927f8Sloli	typeset snap="$sendfs@snap1"
295add927f8Sloli	typeset incr="$sendfs@snap2"
296add927f8Sloli	typeset mountpoint="$TESTDIR/create_recv_clone"
297add927f8Sloli	typeset sendfile="$TESTDIR/create_recv_clone.zsnap"
298add927f8Sloli
299add927f8Sloli	[[ -z $recvfs ]] && log_fail "Recv filesystem's name is undefined."
300add927f8Sloli
301add927f8Sloli	datasetexists $recvfs && log_fail "Recv filesystem must not exist."
302add927f8Sloli	datasetexists $sendfs && log_fail "Send filesystem must not exist."
303add927f8Sloli
304add927f8Sloli	log_must zfs create -o mountpoint="$mountpoint" $sendfs
305add927f8Sloli	log_must zfs snapshot $snap
306add927f8Sloli	log_must eval "zfs send $snap | zfs recv -u $recvfs"
307add927f8Sloli	log_must mkfile 1m "$mountpoint/data"
308add927f8Sloli	log_must zfs snapshot $incr
309add927f8Sloli	log_must eval "zfs send -i $snap $incr | dd bs=10k count=1 > $sendfile"
310add927f8Sloli	log_mustnot eval "zfs recv -su $recvfs < $sendfile"
311add927f8Sloli	log_must zfs destroy -r $sendfs
312add927f8Sloli	log_must rm -f "$sendfile"
313add927f8Sloli
314add927f8Sloli	if [[ $(get_prop 'inconsistent' "$recvfs/%recv") -ne 1 ]]; then
315add927f8Sloli		log_fail "Error creating temporary $recvfs/%recv clone"
316add927f8Sloli	fi
317add927f8Sloli}
318add927f8Sloli
319d583b39bSJohn Wren Kennedyfunction default_mirror_setup
320d583b39bSJohn Wren Kennedy{
321d583b39bSJohn Wren Kennedy	default_mirror_setup_noexit $1 $2 $3
322d583b39bSJohn Wren Kennedy
323d583b39bSJohn Wren Kennedy	log_pass
324d583b39bSJohn Wren Kennedy}
325d583b39bSJohn Wren Kennedy
326e830fb12SKody A Kantorfunction default_mirror_2way_setup
327e830fb12SKody A Kantor{
328e830fb12SKody A Kantor	default_mirror_setup_noexit $1 $2
329e830fb12SKody A Kantor
330e830fb12SKody A Kantor	log_pass
331e830fb12SKody A Kantor}
332e830fb12SKody A Kantor
333d583b39bSJohn Wren Kennedy#
334d583b39bSJohn Wren Kennedy# Given a pair of disks, set up a storage pool and dataset for the mirror
335d583b39bSJohn Wren Kennedy# @parameters: $1 the primary side of the mirror
336d583b39bSJohn Wren Kennedy#   $2 the secondary side of the mirror
337d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL TESTFS
338d583b39bSJohn Wren Kennedyfunction default_mirror_setup_noexit
339d583b39bSJohn Wren Kennedy{
340d583b39bSJohn Wren Kennedy	readonly func="default_mirror_setup_noexit"
341d583b39bSJohn Wren Kennedy	typeset primary=$1
342d583b39bSJohn Wren Kennedy	typeset secondary=$2
343d583b39bSJohn Wren Kennedy
344d583b39bSJohn Wren Kennedy	[[ -z $primary ]] && \
345d583b39bSJohn Wren Kennedy		log_fail "$func: No parameters passed"
346d583b39bSJohn Wren Kennedy	[[ -z $secondary ]] && \
347d583b39bSJohn Wren Kennedy		log_fail "$func: No secondary partition passed"
3481d32ba66SJohn Wren Kennedy	[[ -d /$TESTPOOL ]] && rm -rf /$TESTPOOL
3491d32ba66SJohn Wren Kennedy	log_must zpool create -f $TESTPOOL mirror $@
3501d32ba66SJohn Wren Kennedy	log_must zfs create $TESTPOOL/$TESTFS
3511d32ba66SJohn Wren Kennedy	log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
352d583b39bSJohn Wren Kennedy}
353d583b39bSJohn Wren Kennedy
354d583b39bSJohn Wren Kennedy#
355d583b39bSJohn Wren Kennedy# create a number of mirrors.
356d583b39bSJohn Wren Kennedy# We create a number($1) of 2 way mirrors using the pairs of disks named
357d583b39bSJohn Wren Kennedy# on the command line. These mirrors are *not* mounted
358d583b39bSJohn Wren Kennedy# @parameters: $1 the number of mirrors to create
359d583b39bSJohn Wren Kennedy#  $... the devices to use to create the mirrors on
360d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
361d583b39bSJohn Wren Kennedyfunction setup_mirrors
362d583b39bSJohn Wren Kennedy{
363d583b39bSJohn Wren Kennedy	typeset -i nmirrors=$1
364d583b39bSJohn Wren Kennedy
365d583b39bSJohn Wren Kennedy	shift
366d583b39bSJohn Wren Kennedy	while ((nmirrors > 0)); do
367d583b39bSJohn Wren Kennedy		log_must test -n "$1" -a -n "$2"
3681d32ba66SJohn Wren Kennedy		[[ -d /$TESTPOOL$nmirrors ]] && rm -rf /$TESTPOOL$nmirrors
3691d32ba66SJohn Wren Kennedy		log_must zpool create -f $TESTPOOL$nmirrors mirror $1 $2
370d583b39bSJohn Wren Kennedy		shift 2
371d583b39bSJohn Wren Kennedy		((nmirrors = nmirrors - 1))
372d583b39bSJohn Wren Kennedy	done
373d583b39bSJohn Wren Kennedy}
374d583b39bSJohn Wren Kennedy
375d583b39bSJohn Wren Kennedy#
376d583b39bSJohn Wren Kennedy# create a number of raidz pools.
377d583b39bSJohn Wren Kennedy# We create a number($1) of 2 raidz pools  using the pairs of disks named
378d583b39bSJohn Wren Kennedy# on the command line. These pools are *not* mounted
379d583b39bSJohn Wren Kennedy# @parameters: $1 the number of pools to create
380d583b39bSJohn Wren Kennedy#  $... the devices to use to create the pools on
381d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
382d583b39bSJohn Wren Kennedyfunction setup_raidzs
383d583b39bSJohn Wren Kennedy{
384d583b39bSJohn Wren Kennedy	typeset -i nraidzs=$1
385d583b39bSJohn Wren Kennedy
386d583b39bSJohn Wren Kennedy	shift
387d583b39bSJohn Wren Kennedy	while ((nraidzs > 0)); do
388d583b39bSJohn Wren Kennedy		log_must test -n "$1" -a -n "$2"
3891d32ba66SJohn Wren Kennedy		[[ -d /$TESTPOOL$nraidzs ]] && rm -rf /$TESTPOOL$nraidzs
3901d32ba66SJohn Wren Kennedy		log_must zpool create -f $TESTPOOL$nraidzs raidz $1 $2
391d583b39bSJohn Wren Kennedy		shift 2
392d583b39bSJohn Wren Kennedy		((nraidzs = nraidzs - 1))
393d583b39bSJohn Wren Kennedy	done
394d583b39bSJohn Wren Kennedy}
395d583b39bSJohn Wren Kennedy
396d583b39bSJohn Wren Kennedy#
397d583b39bSJohn Wren Kennedy# Destroy the configured testpool mirrors.
398d583b39bSJohn Wren Kennedy# the mirrors are of the form ${TESTPOOL}{number}
399d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
400d583b39bSJohn Wren Kennedyfunction destroy_mirrors
401d583b39bSJohn Wren Kennedy{
402d583b39bSJohn Wren Kennedy	default_cleanup_noexit
403d583b39bSJohn Wren Kennedy
404d583b39bSJohn Wren Kennedy	log_pass
405d583b39bSJohn Wren Kennedy}
406d583b39bSJohn Wren Kennedy
407d583b39bSJohn Wren Kennedy#
408d583b39bSJohn Wren Kennedy# Given a minimum of two disks, set up a storage pool and dataset for the raid-z
409d583b39bSJohn Wren Kennedy# $1 the list of disks
410d583b39bSJohn Wren Kennedy#
411d583b39bSJohn Wren Kennedyfunction default_raidz_setup
412d583b39bSJohn Wren Kennedy{
413d583b39bSJohn Wren Kennedy	typeset disklist="$*"
414d583b39bSJohn Wren Kennedy	disks=(${disklist[*]})
415d583b39bSJohn Wren Kennedy
416d583b39bSJohn Wren Kennedy	if [[ ${#disks[*]} -lt 2 ]]; then
417d583b39bSJohn Wren Kennedy		log_fail "A raid-z requires a minimum of two disks."
418d583b39bSJohn Wren Kennedy	fi
419d583b39bSJohn Wren Kennedy
4201d32ba66SJohn Wren Kennedy	[[ -d /$TESTPOOL ]] && rm -rf /$TESTPOOL
421*cc8ea7eaSToomas Soome	log_must zpool create -f $TESTPOOL raidz $disklist
4221d32ba66SJohn Wren Kennedy	log_must zfs create $TESTPOOL/$TESTFS
4231d32ba66SJohn Wren Kennedy	log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
424d583b39bSJohn Wren Kennedy
425d583b39bSJohn Wren Kennedy	log_pass
426d583b39bSJohn Wren Kennedy}
427d583b39bSJohn Wren Kennedy
428d583b39bSJohn Wren Kennedy#
429d583b39bSJohn Wren Kennedy# Common function used to cleanup storage pools and datasets.
430d583b39bSJohn Wren Kennedy#
431d583b39bSJohn Wren Kennedy# Invoked at the start of the test suite to ensure the system
432d583b39bSJohn Wren Kennedy# is in a known state, and also at the end of each set of
433d583b39bSJohn Wren Kennedy# sub-tests to ensure errors from one set of tests doesn't
434d583b39bSJohn Wren Kennedy# impact the execution of the next set.
435d583b39bSJohn Wren Kennedy
436d583b39bSJohn Wren Kennedyfunction default_cleanup
437d583b39bSJohn Wren Kennedy{
438d583b39bSJohn Wren Kennedy	default_cleanup_noexit
439d583b39bSJohn Wren Kennedy
440d583b39bSJohn Wren Kennedy	log_pass
441d583b39bSJohn Wren Kennedy}
442d583b39bSJohn Wren Kennedy
443d583b39bSJohn Wren Kennedyfunction default_cleanup_noexit
444d583b39bSJohn Wren Kennedy{
445d583b39bSJohn Wren Kennedy	typeset exclude=""
446d583b39bSJohn Wren Kennedy	typeset pool=""
447d583b39bSJohn Wren Kennedy	#
448d583b39bSJohn Wren Kennedy	# Destroying the pool will also destroy any
449d583b39bSJohn Wren Kennedy	# filesystems it contains.
450d583b39bSJohn Wren Kennedy	#
451d583b39bSJohn Wren Kennedy	if is_global_zone; then
4521d32ba66SJohn Wren Kennedy		zfs unmount -a > /dev/null 2>&1
4531d32ba66SJohn Wren Kennedy		exclude=`eval echo \"'(${KEEP})'\"`
4541d32ba66SJohn Wren Kennedy		ALL_POOLS=$(zpool list -H -o name \
4551d32ba66SJohn Wren Kennedy		    | grep -v "$NO_POOLS" | egrep -v "$exclude")
456d583b39bSJohn Wren Kennedy		# Here, we loop through the pools we're allowed to
457d583b39bSJohn Wren Kennedy		# destroy, only destroying them if it's safe to do
458d583b39bSJohn Wren Kennedy		# so.
459d583b39bSJohn Wren Kennedy		while [ ! -z ${ALL_POOLS} ]
460d583b39bSJohn Wren Kennedy		do
461d583b39bSJohn Wren Kennedy			for pool in ${ALL_POOLS}
462d583b39bSJohn Wren Kennedy			do
463d583b39bSJohn Wren Kennedy				if safe_to_destroy_pool $pool ;
464d583b39bSJohn Wren Kennedy				then
465d583b39bSJohn Wren Kennedy					destroy_pool $pool
466d583b39bSJohn Wren Kennedy				fi
4671d32ba66SJohn Wren Kennedy				ALL_POOLS=$(zpool list -H -o name \
4681d32ba66SJohn Wren Kennedy				    | grep -v "$NO_POOLS" \
4691d32ba66SJohn Wren Kennedy				    | egrep -v "$exclude")
470d583b39bSJohn Wren Kennedy			done
471d583b39bSJohn Wren Kennedy		done
472d583b39bSJohn Wren Kennedy
4731d32ba66SJohn Wren Kennedy		zfs mount -a
474d583b39bSJohn Wren Kennedy	else
475d583b39bSJohn Wren Kennedy		typeset fs=""
4761d32ba66SJohn Wren Kennedy		for fs in $(zfs list -H -o name \
4771d32ba66SJohn Wren Kennedy		    | grep "^$ZONE_POOL/$ZONE_CTR[01234]/"); do
478d583b39bSJohn Wren Kennedy			datasetexists $fs && \
4791d32ba66SJohn Wren Kennedy				log_must zfs destroy -Rf $fs
480d583b39bSJohn Wren Kennedy		done
481d583b39bSJohn Wren Kennedy
482d583b39bSJohn Wren Kennedy		# Need cleanup here to avoid garbage dir left.
4831d32ba66SJohn Wren Kennedy		for fs in $(zfs list -H -o name); do
484d583b39bSJohn Wren Kennedy			[[ $fs == /$ZONE_POOL ]] && continue
4851d32ba66SJohn Wren Kennedy			[[ -d $fs ]] && log_must rm -rf $fs/*
486d583b39bSJohn Wren Kennedy		done
487d583b39bSJohn Wren Kennedy
488d583b39bSJohn Wren Kennedy		#
489d583b39bSJohn Wren Kennedy		# Reset the $ZONE_POOL/$ZONE_CTR[01234] file systems property to
490d583b39bSJohn Wren Kennedy		# the default value
491d583b39bSJohn Wren Kennedy		#
4921d32ba66SJohn Wren Kennedy		for fs in $(zfs list -H -o name); do
493d583b39bSJohn Wren Kennedy			if [[ $fs == $ZONE_POOL/$ZONE_CTR[01234] ]]; then
4941d32ba66SJohn Wren Kennedy				log_must zfs set reservation=none $fs
4951d32ba66SJohn Wren Kennedy				log_must zfs set recordsize=128K $fs
4961d32ba66SJohn Wren Kennedy				log_must zfs set mountpoint=/$fs $fs
497d583b39bSJohn Wren Kennedy				typeset enc=""
498d583b39bSJohn Wren Kennedy				enc=$(get_prop encryption $fs)
499d583b39bSJohn Wren Kennedy				if [[ $? -ne 0 ]] || [[ -z "$enc" ]] || \
500d583b39bSJohn Wren Kennedy					[[ "$enc" == "off" ]]; then
5011d32ba66SJohn Wren Kennedy					log_must zfs set checksum=on $fs
502d583b39bSJohn Wren Kennedy				fi
5031d32ba66SJohn Wren Kennedy				log_must zfs set compression=off $fs
5041d32ba66SJohn Wren Kennedy				log_must zfs set atime=on $fs
5051d32ba66SJohn Wren Kennedy				log_must zfs set devices=off $fs
5061d32ba66SJohn Wren Kennedy				log_must zfs set exec=on $fs
5071d32ba66SJohn Wren Kennedy				log_must zfs set setuid=on $fs
5081d32ba66SJohn Wren Kennedy				log_must zfs set readonly=off $fs
5091d32ba66SJohn Wren Kennedy				log_must zfs set snapdir=hidden $fs
5101d32ba66SJohn Wren Kennedy				log_must zfs set aclmode=groupmask $fs
5111d32ba66SJohn Wren Kennedy				log_must zfs set aclinherit=secure $fs
512d583b39bSJohn Wren Kennedy			fi
513d583b39bSJohn Wren Kennedy		done
514d583b39bSJohn Wren Kennedy	fi
515d583b39bSJohn Wren Kennedy
516d583b39bSJohn Wren Kennedy	[[ -d $TESTDIR ]] && \
5171d32ba66SJohn Wren Kennedy		log_must rm -rf $TESTDIR
518d583b39bSJohn Wren Kennedy}
519d583b39bSJohn Wren Kennedy
520d583b39bSJohn Wren Kennedy
521d583b39bSJohn Wren Kennedy#
522d583b39bSJohn Wren Kennedy# Common function used to cleanup storage pools, file systems
523d583b39bSJohn Wren Kennedy# and containers.
524d583b39bSJohn Wren Kennedy#
525d583b39bSJohn Wren Kennedyfunction default_container_cleanup
526d583b39bSJohn Wren Kennedy{
527d583b39bSJohn Wren Kennedy	if ! is_global_zone; then
528d583b39bSJohn Wren Kennedy		reexport_pool
529d583b39bSJohn Wren Kennedy	fi
530d583b39bSJohn Wren Kennedy
531d583b39bSJohn Wren Kennedy	ismounted $TESTPOOL/$TESTCTR/$TESTFS1
532d583b39bSJohn Wren Kennedy	[[ $? -eq 0 ]] && \
5331d32ba66SJohn Wren Kennedy	    log_must zfs unmount $TESTPOOL/$TESTCTR/$TESTFS1
534d583b39bSJohn Wren Kennedy
535d583b39bSJohn Wren Kennedy	datasetexists $TESTPOOL/$TESTCTR/$TESTFS1 && \
5361d32ba66SJohn Wren Kennedy	    log_must zfs destroy -R $TESTPOOL/$TESTCTR/$TESTFS1
537d583b39bSJohn Wren Kennedy
538d583b39bSJohn Wren Kennedy	datasetexists $TESTPOOL/$TESTCTR && \
5391d32ba66SJohn Wren Kennedy	    log_must zfs destroy -Rf $TESTPOOL/$TESTCTR
540d583b39bSJohn Wren Kennedy
541d583b39bSJohn Wren Kennedy	[[ -e $TESTDIR1 ]] && \
5421d32ba66SJohn Wren Kennedy	    log_must rm -rf $TESTDIR1 > /dev/null 2>&1
543d583b39bSJohn Wren Kennedy
544d583b39bSJohn Wren Kennedy	default_cleanup
545d583b39bSJohn Wren Kennedy}
546d583b39bSJohn Wren Kennedy
547d583b39bSJohn Wren Kennedy#
548d583b39bSJohn Wren Kennedy# Common function used to cleanup snapshot of file system or volume. Default to
549d583b39bSJohn Wren Kennedy# delete the file system's snapshot
550d583b39bSJohn Wren Kennedy#
551d583b39bSJohn Wren Kennedy# $1 snapshot name
552d583b39bSJohn Wren Kennedy#
553d583b39bSJohn Wren Kennedyfunction destroy_snapshot
554d583b39bSJohn Wren Kennedy{
555d583b39bSJohn Wren Kennedy	typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
556d583b39bSJohn Wren Kennedy
557d583b39bSJohn Wren Kennedy	if ! snapexists $snap; then
558d583b39bSJohn Wren Kennedy		log_fail "'$snap' does not existed."
559d583b39bSJohn Wren Kennedy	fi
560d583b39bSJohn Wren Kennedy
561d583b39bSJohn Wren Kennedy	#
562d583b39bSJohn Wren Kennedy	# For the sake of the value which come from 'get_prop' is not equal
563d583b39bSJohn Wren Kennedy	# to the really mountpoint when the snapshot is unmounted. So, firstly
564d583b39bSJohn Wren Kennedy	# check and make sure this snapshot's been mounted in current system.
565d583b39bSJohn Wren Kennedy	#
566d583b39bSJohn Wren Kennedy	typeset mtpt=""
567d583b39bSJohn Wren Kennedy	if ismounted $snap; then
568d583b39bSJohn Wren Kennedy		mtpt=$(get_prop mountpoint $snap)
569d583b39bSJohn Wren Kennedy		(($? != 0)) && \
570d583b39bSJohn Wren Kennedy			log_fail "get_prop mountpoint $snap failed."
571d583b39bSJohn Wren Kennedy	fi
572d583b39bSJohn Wren Kennedy
5731d32ba66SJohn Wren Kennedy	log_must zfs destroy $snap
574d583b39bSJohn Wren Kennedy	[[ $mtpt != "" && -d $mtpt ]] && \
5751d32ba66SJohn Wren Kennedy		log_must rm -rf $mtpt
576d583b39bSJohn Wren Kennedy}
577d583b39bSJohn Wren Kennedy
578d583b39bSJohn Wren Kennedy#
579d583b39bSJohn Wren Kennedy# Common function used to cleanup clone.
580d583b39bSJohn Wren Kennedy#
581d583b39bSJohn Wren Kennedy# $1 clone name
582d583b39bSJohn Wren Kennedy#
583d583b39bSJohn Wren Kennedyfunction destroy_clone
584d583b39bSJohn Wren Kennedy{
585d583b39bSJohn Wren Kennedy	typeset clone=${1:-$TESTPOOL/$TESTCLONE}
586d583b39bSJohn Wren Kennedy
587d583b39bSJohn Wren Kennedy	if ! datasetexists $clone; then
588d583b39bSJohn Wren Kennedy		log_fail "'$clone' does not existed."
589d583b39bSJohn Wren Kennedy	fi
590d583b39bSJohn Wren Kennedy
591d583b39bSJohn Wren Kennedy	# With the same reason in destroy_snapshot
592d583b39bSJohn Wren Kennedy	typeset mtpt=""
593d583b39bSJohn Wren Kennedy	if ismounted $clone; then
594d583b39bSJohn Wren Kennedy		mtpt=$(get_prop mountpoint $clone)
595d583b39bSJohn Wren Kennedy		(($? != 0)) && \
596d583b39bSJohn Wren Kennedy			log_fail "get_prop mountpoint $clone failed."
597d583b39bSJohn Wren Kennedy	fi
598d583b39bSJohn Wren Kennedy
5991d32ba66SJohn Wren Kennedy	log_must zfs destroy $clone
600d583b39bSJohn Wren Kennedy	[[ $mtpt != "" && -d $mtpt ]] && \
6011d32ba66SJohn Wren Kennedy		log_must rm -rf $mtpt
602d583b39bSJohn Wren Kennedy}
603d583b39bSJohn Wren Kennedy
604edb901aaSMarcel Telka#
605edb901aaSMarcel Telka# Common function used to cleanup bookmark of file system or volume.  Default
606edb901aaSMarcel Telka# to delete the file system's bookmark.
607edb901aaSMarcel Telka#
608edb901aaSMarcel Telka# $1 bookmark name
609edb901aaSMarcel Telka#
610edb901aaSMarcel Telkafunction destroy_bookmark
611edb901aaSMarcel Telka{
612edb901aaSMarcel Telka	typeset bkmark=${1:-$TESTPOOL/$TESTFS#$TESTBKMARK}
613edb901aaSMarcel Telka
614edb901aaSMarcel Telka	if ! bkmarkexists $bkmark; then
615edb901aaSMarcel Telka		log_fail "'$bkmarkp' does not existed."
616edb901aaSMarcel Telka	fi
617edb901aaSMarcel Telka
618f5fb56deSJohn Wren Kennedy	log_must zfs destroy $bkmark
619edb901aaSMarcel Telka}
620edb901aaSMarcel Telka
621d583b39bSJohn Wren Kennedy# Return 0 if a snapshot exists; $? otherwise
622d583b39bSJohn Wren Kennedy#
623d583b39bSJohn Wren Kennedy# $1 - snapshot name
624d583b39bSJohn Wren Kennedy
625d583b39bSJohn Wren Kennedyfunction snapexists
626d583b39bSJohn Wren Kennedy{
6271d32ba66SJohn Wren Kennedy	zfs list -H -t snapshot "$1" > /dev/null 2>&1
628d583b39bSJohn Wren Kennedy	return $?
629d583b39bSJohn Wren Kennedy}
630d583b39bSJohn Wren Kennedy
631edb901aaSMarcel Telka#
632edb901aaSMarcel Telka# Return 0 if a bookmark exists; $? otherwise
633edb901aaSMarcel Telka#
634edb901aaSMarcel Telka# $1 - bookmark name
635edb901aaSMarcel Telka#
636edb901aaSMarcel Telkafunction bkmarkexists
637edb901aaSMarcel Telka{
638f5fb56deSJohn Wren Kennedy	zfs list -H -t bookmark "$1" > /dev/null 2>&1
639edb901aaSMarcel Telka	return $?
640edb901aaSMarcel Telka}
641edb901aaSMarcel Telka
642d583b39bSJohn Wren Kennedy#
643d583b39bSJohn Wren Kennedy# Set a property to a certain value on a dataset.
644d583b39bSJohn Wren Kennedy# Sets a property of the dataset to the value as passed in.
645d583b39bSJohn Wren Kennedy# @param:
646d583b39bSJohn Wren Kennedy#	$1 dataset who's property is being set
647d583b39bSJohn Wren Kennedy#	$2 property to set
648d583b39bSJohn Wren Kennedy#	$3 value to set property to
649d583b39bSJohn Wren Kennedy# @return:
650d583b39bSJohn Wren Kennedy#	0 if the property could be set.
651d583b39bSJohn Wren Kennedy#	non-zero otherwise.
652d583b39bSJohn Wren Kennedy# @use: ZFS
653d583b39bSJohn Wren Kennedy#
654d583b39bSJohn Wren Kennedyfunction dataset_setprop
655d583b39bSJohn Wren Kennedy{
656d583b39bSJohn Wren Kennedy	typeset fn=dataset_setprop
657d583b39bSJohn Wren Kennedy
658d583b39bSJohn Wren Kennedy	if (($# < 3)); then
659d583b39bSJohn Wren Kennedy		log_note "$fn: Insufficient parameters (need 3, had $#)"
660d583b39bSJohn Wren Kennedy		return 1
661d583b39bSJohn Wren Kennedy	fi
662d583b39bSJohn Wren Kennedy	typeset output=
6631d32ba66SJohn Wren Kennedy	output=$(zfs set $2=$3 $1 2>&1)
664d583b39bSJohn Wren Kennedy	typeset rv=$?
665d583b39bSJohn Wren Kennedy	if ((rv != 0)); then
666d583b39bSJohn Wren Kennedy		log_note "Setting property on $1 failed."
667d583b39bSJohn Wren Kennedy		log_note "property $2=$3"
668d583b39bSJohn Wren Kennedy		log_note "Return Code: $rv"
669d583b39bSJohn Wren Kennedy		log_note "Output: $output"
670d583b39bSJohn Wren Kennedy		return $rv
671d583b39bSJohn Wren Kennedy	fi
672d583b39bSJohn Wren Kennedy	return 0
673d583b39bSJohn Wren Kennedy}
674d583b39bSJohn Wren Kennedy
675d583b39bSJohn Wren Kennedy#
676d583b39bSJohn Wren Kennedy# Assign suite defined dataset properties.
677d583b39bSJohn Wren Kennedy# This function is used to apply the suite's defined default set of
678d583b39bSJohn Wren Kennedy# properties to a dataset.
679d583b39bSJohn Wren Kennedy# @parameters: $1 dataset to use
680d583b39bSJohn Wren Kennedy# @uses: ZFS COMPRESSION_PROP CHECKSUM_PROP
681d583b39bSJohn Wren Kennedy# @returns:
682d583b39bSJohn Wren Kennedy#   0 if the dataset has been altered.
683d583b39bSJohn Wren Kennedy#   1 if no pool name was passed in.
684d583b39bSJohn Wren Kennedy#   2 if the dataset could not be found.
685d583b39bSJohn Wren Kennedy#   3 if the dataset could not have it's properties set.
686d583b39bSJohn Wren Kennedy#
687d583b39bSJohn Wren Kennedyfunction dataset_set_defaultproperties
688d583b39bSJohn Wren Kennedy{
689d583b39bSJohn Wren Kennedy	typeset dataset="$1"
690d583b39bSJohn Wren Kennedy
691d583b39bSJohn Wren Kennedy	[[ -z $dataset ]] && return 1
692d583b39bSJohn Wren Kennedy
693d583b39bSJohn Wren Kennedy	typeset confset=
694d583b39bSJohn Wren Kennedy	typeset -i found=0
6951d32ba66SJohn Wren Kennedy	for confset in $(zfs list); do
696d583b39bSJohn Wren Kennedy		if [[ $dataset = $confset ]]; then
697d583b39bSJohn Wren Kennedy			found=1
698d583b39bSJohn Wren Kennedy			break
699d583b39bSJohn Wren Kennedy		fi
700d583b39bSJohn Wren Kennedy	done
701d583b39bSJohn Wren Kennedy	[[ $found -eq 0 ]] && return 2
702d583b39bSJohn Wren Kennedy	if [[ -n $COMPRESSION_PROP ]]; then
703d583b39bSJohn Wren Kennedy		dataset_setprop $dataset compression $COMPRESSION_PROP || \
704d583b39bSJohn Wren Kennedy			return 3
705d583b39bSJohn Wren Kennedy		log_note "Compression set to '$COMPRESSION_PROP' on $dataset"
706d583b39bSJohn Wren Kennedy	fi
707d583b39bSJohn Wren Kennedy	if [[ -n $CHECKSUM_PROP ]]; then
708d583b39bSJohn Wren Kennedy		dataset_setprop $dataset checksum $CHECKSUM_PROP || \
709d583b39bSJohn Wren Kennedy			return 3
710d583b39bSJohn Wren Kennedy		log_note "Checksum set to '$CHECKSUM_PROP' on $dataset"
711d583b39bSJohn Wren Kennedy	fi
712d583b39bSJohn Wren Kennedy	return 0
713d583b39bSJohn Wren Kennedy}
714d583b39bSJohn Wren Kennedy
715d583b39bSJohn Wren Kennedy#
716d583b39bSJohn Wren Kennedy# Check a numeric assertion
717d583b39bSJohn Wren Kennedy# @parameter: $@ the assertion to check
718d583b39bSJohn Wren Kennedy# @output: big loud notice if assertion failed
719d583b39bSJohn Wren Kennedy# @use: log_fail
720d583b39bSJohn Wren Kennedy#
721d583b39bSJohn Wren Kennedyfunction assert
722d583b39bSJohn Wren Kennedy{
723d583b39bSJohn Wren Kennedy	(($@)) || log_fail "$@"
724d583b39bSJohn Wren Kennedy}
725d583b39bSJohn Wren Kennedy
726d583b39bSJohn Wren Kennedy#
727d583b39bSJohn Wren Kennedy# Function to format partition size of a disk
728d583b39bSJohn Wren Kennedy# Given a disk cxtxdx reduces all partitions
729d583b39bSJohn Wren Kennedy# to 0 size
730d583b39bSJohn Wren Kennedy#
731d583b39bSJohn Wren Kennedyfunction zero_partitions #<whole_disk_name>
732d583b39bSJohn Wren Kennedy{
733d583b39bSJohn Wren Kennedy	typeset diskname=$1
734d583b39bSJohn Wren Kennedy	typeset i
735d583b39bSJohn Wren Kennedy
736d583b39bSJohn Wren Kennedy	for i in 0 1 3 4 5 6 7
737d583b39bSJohn Wren Kennedy	do
738d583b39bSJohn Wren Kennedy		set_partition $i "" 0mb $diskname
739d583b39bSJohn Wren Kennedy	done
740d583b39bSJohn Wren Kennedy}
741d583b39bSJohn Wren Kennedy
742d583b39bSJohn Wren Kennedy#
743d583b39bSJohn Wren Kennedy# Given a slice, size and disk, this function
744d583b39bSJohn Wren Kennedy# formats the slice to the specified size.
745d583b39bSJohn Wren Kennedy# Size should be specified with units as per
746d583b39bSJohn Wren Kennedy# the `format` command requirements eg. 100mb 3gb
747d583b39bSJohn Wren Kennedy#
748d583b39bSJohn Wren Kennedyfunction set_partition #<slice_num> <slice_start> <size_plus_units>  <whole_disk_name>
749d583b39bSJohn Wren Kennedy{
750d583b39bSJohn Wren Kennedy	typeset -i slicenum=$1
751d583b39bSJohn Wren Kennedy	typeset start=$2
752d583b39bSJohn Wren Kennedy	typeset size=$3
753d583b39bSJohn Wren Kennedy	typeset disk=$4
754d583b39bSJohn Wren Kennedy	[[ -z $slicenum || -z $size || -z $disk ]] && \
755d583b39bSJohn Wren Kennedy	    log_fail "The slice, size or disk name is unspecified."
756d583b39bSJohn Wren Kennedy	typeset format_file=/var/tmp/format_in.$$
757d583b39bSJohn Wren Kennedy
7581d32ba66SJohn Wren Kennedy	echo "partition" >$format_file
7591d32ba66SJohn Wren Kennedy	echo "$slicenum" >> $format_file
7601d32ba66SJohn Wren Kennedy	echo "" >> $format_file
7611d32ba66SJohn Wren Kennedy	echo "" >> $format_file
7621d32ba66SJohn Wren Kennedy	echo "$start" >> $format_file
7631d32ba66SJohn Wren Kennedy	echo "$size" >> $format_file
7641d32ba66SJohn Wren Kennedy	echo "label" >> $format_file
7651d32ba66SJohn Wren Kennedy	echo "" >> $format_file
7661d32ba66SJohn Wren Kennedy	echo "q" >> $format_file
7671d32ba66SJohn Wren Kennedy	echo "q" >> $format_file
7681d32ba66SJohn Wren Kennedy
7691d32ba66SJohn Wren Kennedy	format -e -s -d $disk -f $format_file
770d583b39bSJohn Wren Kennedy	typeset ret_val=$?
7711d32ba66SJohn Wren Kennedy	rm -f $format_file
772d583b39bSJohn Wren Kennedy	[[ $ret_val -ne 0 ]] && \
773d583b39bSJohn Wren Kennedy	    log_fail "Unable to format $disk slice $slicenum to $size"
774d583b39bSJohn Wren Kennedy	return 0
775d583b39bSJohn Wren Kennedy}
776d583b39bSJohn Wren Kennedy
777d583b39bSJohn Wren Kennedy#
778d583b39bSJohn Wren Kennedy# Get the end cyl of the given slice
779d583b39bSJohn Wren Kennedy#
780d583b39bSJohn Wren Kennedyfunction get_endslice #<disk> <slice>
781d583b39bSJohn Wren Kennedy{
782d583b39bSJohn Wren Kennedy	typeset disk=$1
783d583b39bSJohn Wren Kennedy	typeset slice=$2
784d583b39bSJohn Wren Kennedy	if [[ -z $disk || -z $slice ]] ; then
785d583b39bSJohn Wren Kennedy		log_fail "The disk name or slice number is unspecified."
786d583b39bSJohn Wren Kennedy	fi
787d583b39bSJohn Wren Kennedy
788d583b39bSJohn Wren Kennedy	disk=${disk#/dev/dsk/}
789d583b39bSJohn Wren Kennedy	disk=${disk#/dev/rdsk/}
790d583b39bSJohn Wren Kennedy	disk=${disk%s*}
791d583b39bSJohn Wren Kennedy
792d583b39bSJohn Wren Kennedy	typeset -i ratio=0
7931d32ba66SJohn Wren Kennedy	ratio=$(prtvtoc /dev/rdsk/${disk}s2 | \
7941d32ba66SJohn Wren Kennedy		grep "sectors\/cylinder" | \
7951d32ba66SJohn Wren Kennedy		awk '{print $2}')
796d583b39bSJohn Wren Kennedy
797d583b39bSJohn Wren Kennedy	if ((ratio == 0)); then
798d583b39bSJohn Wren Kennedy		return
799d583b39bSJohn Wren Kennedy	fi
800d583b39bSJohn Wren Kennedy
8011d32ba66SJohn Wren Kennedy	typeset -i endcyl=$(prtvtoc -h /dev/rdsk/${disk}s2 |
8021d32ba66SJohn Wren Kennedy		nawk -v token="$slice" '{if ($1==token) print $6}')
803d583b39bSJohn Wren Kennedy
804d583b39bSJohn Wren Kennedy	((endcyl = (endcyl + 1) / ratio))
805d583b39bSJohn Wren Kennedy	echo $endcyl
806d583b39bSJohn Wren Kennedy}
807d583b39bSJohn Wren Kennedy
808d583b39bSJohn Wren Kennedy
809d583b39bSJohn Wren Kennedy#
810d583b39bSJohn Wren Kennedy# Given a size,disk and total slice number,  this function formats the
811d583b39bSJohn Wren Kennedy# disk slices from 0 to the total slice number with the same specified
812d583b39bSJohn Wren Kennedy# size.
813d583b39bSJohn Wren Kennedy#
814d583b39bSJohn Wren Kennedyfunction partition_disk	#<slice_size> <whole_disk_name>	<total_slices>
815d583b39bSJohn Wren Kennedy{
816d583b39bSJohn Wren Kennedy	typeset -i i=0
817d583b39bSJohn Wren Kennedy	typeset slice_size=$1
818d583b39bSJohn Wren Kennedy	typeset disk_name=$2
819d583b39bSJohn Wren Kennedy	typeset total_slices=$3
820d583b39bSJohn Wren Kennedy	typeset cyl
821d583b39bSJohn Wren Kennedy
822d583b39bSJohn Wren Kennedy	zero_partitions $disk_name
823d583b39bSJohn Wren Kennedy	while ((i < $total_slices)); do
824d583b39bSJohn Wren Kennedy		if ((i == 2)); then
825d583b39bSJohn Wren Kennedy			((i = i + 1))
826d583b39bSJohn Wren Kennedy			continue
827d583b39bSJohn Wren Kennedy		fi
828d583b39bSJohn Wren Kennedy		set_partition $i "$cyl" $slice_size $disk_name
829d583b39bSJohn Wren Kennedy		cyl=$(get_endslice $disk_name $i)
830d583b39bSJohn Wren Kennedy		((i = i+1))
831d583b39bSJohn Wren Kennedy	done
832d583b39bSJohn Wren Kennedy}
833d583b39bSJohn Wren Kennedy
834d583b39bSJohn Wren Kennedy#
835d583b39bSJohn Wren Kennedy# This function continues to write to a filenum number of files into dirnum
8361d32ba66SJohn Wren Kennedy# number of directories until either file_write returns an error or the
837d583b39bSJohn Wren Kennedy# maximum number of files per directory have been written.
838d583b39bSJohn Wren Kennedy#
839d583b39bSJohn Wren Kennedy# Usage:
840d583b39bSJohn Wren Kennedy# fill_fs [destdir] [dirnum] [filenum] [bytes] [num_writes] [data]
841d583b39bSJohn Wren Kennedy#
842d583b39bSJohn Wren Kennedy# Return value: 0 on success
843d583b39bSJohn Wren Kennedy#		non 0 on error
844d583b39bSJohn Wren Kennedy#
845d583b39bSJohn Wren Kennedy# Where :
846d583b39bSJohn Wren Kennedy#	destdir:    is the directory where everything is to be created under
847d583b39bSJohn Wren Kennedy#	dirnum:	    the maximum number of subdirectories to use, -1 no limit
848d583b39bSJohn Wren Kennedy#	filenum:    the maximum number of files per subdirectory
849d583b39bSJohn Wren Kennedy#	bytes:	    number of bytes to write
850d583b39bSJohn Wren Kennedy#	num_writes: numer of types to write out bytes
851d583b39bSJohn Wren Kennedy#	data:	    the data that will be writen
852d583b39bSJohn Wren Kennedy#
853d583b39bSJohn Wren Kennedy#	E.g.
854d583b39bSJohn Wren Kennedy#	file_fs /testdir 20 25 1024 256 0
855d583b39bSJohn Wren Kennedy#
856d583b39bSJohn Wren Kennedy# Note: bytes * num_writes equals the size of the testfile
857d583b39bSJohn Wren Kennedy#
858d583b39bSJohn Wren Kennedyfunction fill_fs # destdir dirnum filenum bytes num_writes data
859d583b39bSJohn Wren Kennedy{
860d583b39bSJohn Wren Kennedy	typeset destdir=${1:-$TESTDIR}
861d583b39bSJohn Wren Kennedy	typeset -i dirnum=${2:-50}
862d583b39bSJohn Wren Kennedy	typeset -i filenum=${3:-50}
863d583b39bSJohn Wren Kennedy	typeset -i bytes=${4:-8192}
864d583b39bSJohn Wren Kennedy	typeset -i num_writes=${5:-10240}
865084fd14fSBrian Behlendorf	typeset data=${6:-0}
866d583b39bSJohn Wren Kennedy
867d583b39bSJohn Wren Kennedy	typeset -i odirnum=1
868d583b39bSJohn Wren Kennedy	typeset -i idirnum=0
869d583b39bSJohn Wren Kennedy	typeset -i fn=0
870d583b39bSJohn Wren Kennedy	typeset -i retval=0
871d583b39bSJohn Wren Kennedy
872084fd14fSBrian Behlendorf	mkdir -p $destdir/$idirnum
873d583b39bSJohn Wren Kennedy	while (($odirnum > 0)); do
874d583b39bSJohn Wren Kennedy		if ((dirnum >= 0 && idirnum >= dirnum)); then
875d583b39bSJohn Wren Kennedy			odirnum=0
876d583b39bSJohn Wren Kennedy			break
877d583b39bSJohn Wren Kennedy		fi
8781d32ba66SJohn Wren Kennedy		file_write -o create -f $destdir/$idirnum/$TESTFILE.$fn \
879d583b39bSJohn Wren Kennedy		    -b $bytes -c $num_writes -d $data
880d583b39bSJohn Wren Kennedy		retval=$?
881d583b39bSJohn Wren Kennedy		if (($retval != 0)); then
882d583b39bSJohn Wren Kennedy			odirnum=0
883d583b39bSJohn Wren Kennedy			break
884d583b39bSJohn Wren Kennedy		fi
885d583b39bSJohn Wren Kennedy		if (($fn >= $filenum)); then
886d583b39bSJohn Wren Kennedy			fn=0
887d583b39bSJohn Wren Kennedy			((idirnum = idirnum + 1))
888084fd14fSBrian Behlendorf			mkdir -p $destdir/$idirnum
889d583b39bSJohn Wren Kennedy		else
890d583b39bSJohn Wren Kennedy			((fn = fn + 1))
891d583b39bSJohn Wren Kennedy		fi
892d583b39bSJohn Wren Kennedy	done
893d583b39bSJohn Wren Kennedy	return $retval
894d583b39bSJohn Wren Kennedy}
895d583b39bSJohn Wren Kennedy
896d583b39bSJohn Wren Kennedy#
897d583b39bSJohn Wren Kennedy# Simple function to get the specified property. If unable to
898d583b39bSJohn Wren Kennedy# get the property then exits.
899d583b39bSJohn Wren Kennedy#
900d583b39bSJohn Wren Kennedy# Note property is in 'parsable' format (-p)
901d583b39bSJohn Wren Kennedy#
902d583b39bSJohn Wren Kennedyfunction get_prop # property dataset
903d583b39bSJohn Wren Kennedy{
904d583b39bSJohn Wren Kennedy	typeset prop_val
905d583b39bSJohn Wren Kennedy	typeset prop=$1
906d583b39bSJohn Wren Kennedy	typeset dataset=$2
907d583b39bSJohn Wren Kennedy
9081d32ba66SJohn Wren Kennedy	prop_val=$(zfs get -pH -o value $prop $dataset 2>/dev/null)
909d583b39bSJohn Wren Kennedy	if [[ $? -ne 0 ]]; then
910d583b39bSJohn Wren Kennedy		log_note "Unable to get $prop property for dataset " \
911d583b39bSJohn Wren Kennedy		"$dataset"
912d583b39bSJohn Wren Kennedy		return 1
913d583b39bSJohn Wren Kennedy	fi
914d583b39bSJohn Wren Kennedy
9150e93dddeSMatthew Ahrens	echo "$prop_val"
916d583b39bSJohn Wren Kennedy	return 0
917d583b39bSJohn Wren Kennedy}
918d583b39bSJohn Wren Kennedy
919d583b39bSJohn Wren Kennedy#
920d583b39bSJohn Wren Kennedy# Simple function to get the specified property of pool. If unable to
921d583b39bSJohn Wren Kennedy# get the property then exits.
922d583b39bSJohn Wren Kennedy#
923d583b39bSJohn Wren Kennedyfunction get_pool_prop # property pool
924d583b39bSJohn Wren Kennedy{
925d583b39bSJohn Wren Kennedy	typeset prop_val
926d583b39bSJohn Wren Kennedy	typeset prop=$1
927d583b39bSJohn Wren Kennedy	typeset pool=$2
928d583b39bSJohn Wren Kennedy
929d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
9301d32ba66SJohn Wren Kennedy		prop_val=$(zpool get $prop $pool 2>/dev/null | tail -1 | \
9311d32ba66SJohn Wren Kennedy			awk '{print $3}')
932d583b39bSJohn Wren Kennedy		if [[ $? -ne 0 ]]; then
933d583b39bSJohn Wren Kennedy			log_note "Unable to get $prop property for pool " \
934d583b39bSJohn Wren Kennedy			"$pool"
935d583b39bSJohn Wren Kennedy			return 1
936d583b39bSJohn Wren Kennedy		fi
937d583b39bSJohn Wren Kennedy	else
938d583b39bSJohn Wren Kennedy		log_note "Pool $pool not exists."
939d583b39bSJohn Wren Kennedy		return 1
940d583b39bSJohn Wren Kennedy	fi
941d583b39bSJohn Wren Kennedy
9421d32ba66SJohn Wren Kennedy	echo $prop_val
943d583b39bSJohn Wren Kennedy	return 0
944d583b39bSJohn Wren Kennedy}
945d583b39bSJohn Wren Kennedy
946d583b39bSJohn Wren Kennedy# Return 0 if a pool exists; $? otherwise
947d583b39bSJohn Wren Kennedy#
948d583b39bSJohn Wren Kennedy# $1 - pool name
949d583b39bSJohn Wren Kennedy
950d583b39bSJohn Wren Kennedyfunction poolexists
951d583b39bSJohn Wren Kennedy{
952d583b39bSJohn Wren Kennedy	typeset pool=$1
953d583b39bSJohn Wren Kennedy
954d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
955d583b39bSJohn Wren Kennedy		log_note "No pool name given."
956d583b39bSJohn Wren Kennedy		return 1
957d583b39bSJohn Wren Kennedy	fi
958d583b39bSJohn Wren Kennedy
9591d32ba66SJohn Wren Kennedy	zpool get name "$pool" > /dev/null 2>&1
960d583b39bSJohn Wren Kennedy	return $?
961d583b39bSJohn Wren Kennedy}
962d583b39bSJohn Wren Kennedy
963d583b39bSJohn Wren Kennedy# Return 0 if all the specified datasets exist; $? otherwise
964d583b39bSJohn Wren Kennedy#
965d583b39bSJohn Wren Kennedy# $1-n  dataset name
966d583b39bSJohn Wren Kennedyfunction datasetexists
967d583b39bSJohn Wren Kennedy{
968d583b39bSJohn Wren Kennedy	if (($# == 0)); then
969d583b39bSJohn Wren Kennedy		log_note "No dataset name given."
970d583b39bSJohn Wren Kennedy		return 1
971d583b39bSJohn Wren Kennedy	fi
972d583b39bSJohn Wren Kennedy
973d583b39bSJohn Wren Kennedy	while (($# > 0)); do
9741d32ba66SJohn Wren Kennedy		zfs get name $1 > /dev/null 2>&1 || \
975d583b39bSJohn Wren Kennedy			return $?
976d583b39bSJohn Wren Kennedy		shift
977d583b39bSJohn Wren Kennedy	done
978d583b39bSJohn Wren Kennedy
979d583b39bSJohn Wren Kennedy	return 0
980d583b39bSJohn Wren Kennedy}
981d583b39bSJohn Wren Kennedy
982d583b39bSJohn Wren Kennedy# return 0 if none of the specified datasets exists, otherwise return 1.
983d583b39bSJohn Wren Kennedy#
984d583b39bSJohn Wren Kennedy# $1-n  dataset name
985d583b39bSJohn Wren Kennedyfunction datasetnonexists
986d583b39bSJohn Wren Kennedy{
987d583b39bSJohn Wren Kennedy	if (($# == 0)); then
988d583b39bSJohn Wren Kennedy		log_note "No dataset name given."
989d583b39bSJohn Wren Kennedy		return 1
990d583b39bSJohn Wren Kennedy	fi
991d583b39bSJohn Wren Kennedy
992d583b39bSJohn Wren Kennedy	while (($# > 0)); do
9931d32ba66SJohn Wren Kennedy		zfs list -H -t filesystem,snapshot,volume $1 > /dev/null 2>&1 \
994d583b39bSJohn Wren Kennedy		    && return 1
995d583b39bSJohn Wren Kennedy		shift
996d583b39bSJohn Wren Kennedy	done
997d583b39bSJohn Wren Kennedy
998d583b39bSJohn Wren Kennedy	return 0
999d583b39bSJohn Wren Kennedy}
1000d583b39bSJohn Wren Kennedy
1001d583b39bSJohn Wren Kennedy#
1002d583b39bSJohn Wren Kennedy# Given a mountpoint, or a dataset name, determine if it is shared.
1003d583b39bSJohn Wren Kennedy#
1004d583b39bSJohn Wren Kennedy# Returns 0 if shared, 1 otherwise.
1005d583b39bSJohn Wren Kennedy#
1006d583b39bSJohn Wren Kennedyfunction is_shared
1007d583b39bSJohn Wren Kennedy{
1008d583b39bSJohn Wren Kennedy	typeset fs=$1
1009d583b39bSJohn Wren Kennedy	typeset mtpt
1010d583b39bSJohn Wren Kennedy
1011d583b39bSJohn Wren Kennedy	if [[ $fs != "/"* ]] ; then
1012d583b39bSJohn Wren Kennedy		if datasetnonexists "$fs" ; then
1013d583b39bSJohn Wren Kennedy			return 1
1014d583b39bSJohn Wren Kennedy		else
1015d583b39bSJohn Wren Kennedy			mtpt=$(get_prop mountpoint "$fs")
1016d583b39bSJohn Wren Kennedy			case $mtpt in
1017d583b39bSJohn Wren Kennedy				none|legacy|-) return 1
1018d583b39bSJohn Wren Kennedy					;;
1019d583b39bSJohn Wren Kennedy				*)	fs=$mtpt
1020d583b39bSJohn Wren Kennedy					;;
1021d583b39bSJohn Wren Kennedy			esac
1022d583b39bSJohn Wren Kennedy		fi
1023d583b39bSJohn Wren Kennedy	fi
1024d583b39bSJohn Wren Kennedy
10251d32ba66SJohn Wren Kennedy	for mtpt in `share | awk '{print $2}'` ; do
1026d583b39bSJohn Wren Kennedy		if [[ $mtpt == $fs ]] ; then
1027d583b39bSJohn Wren Kennedy			return 0
1028d583b39bSJohn Wren Kennedy		fi
1029d583b39bSJohn Wren Kennedy	done
1030d583b39bSJohn Wren Kennedy
10311d32ba66SJohn Wren Kennedy	typeset stat=$(svcs -H -o STA nfs/server:default)
1032d583b39bSJohn Wren Kennedy	if [[ $stat != "ON" ]]; then
1033d583b39bSJohn Wren Kennedy		log_note "Current nfs/server status: $stat"
1034d583b39bSJohn Wren Kennedy	fi
1035d583b39bSJohn Wren Kennedy
1036d583b39bSJohn Wren Kennedy	return 1
1037d583b39bSJohn Wren Kennedy}
1038d583b39bSJohn Wren Kennedy
1039d583b39bSJohn Wren Kennedy#
1040d583b39bSJohn Wren Kennedy# Given a mountpoint, determine if it is not shared.
1041d583b39bSJohn Wren Kennedy#
1042d583b39bSJohn Wren Kennedy# Returns 0 if not shared, 1 otherwise.
1043d583b39bSJohn Wren Kennedy#
1044d583b39bSJohn Wren Kennedyfunction not_shared
1045d583b39bSJohn Wren Kennedy{
1046d583b39bSJohn Wren Kennedy	typeset fs=$1
1047d583b39bSJohn Wren Kennedy
1048d583b39bSJohn Wren Kennedy	is_shared $fs
1049d583b39bSJohn Wren Kennedy	if (($? == 0)); then
1050d583b39bSJohn Wren Kennedy		return 1
1051d583b39bSJohn Wren Kennedy	fi
1052d583b39bSJohn Wren Kennedy
1053d583b39bSJohn Wren Kennedy	return 0
1054d583b39bSJohn Wren Kennedy}
1055d583b39bSJohn Wren Kennedy
1056d583b39bSJohn Wren Kennedy#
1057d583b39bSJohn Wren Kennedy# Helper function to unshare a mountpoint.
1058d583b39bSJohn Wren Kennedy#
1059d583b39bSJohn Wren Kennedyfunction unshare_fs #fs
1060d583b39bSJohn Wren Kennedy{
1061d583b39bSJohn Wren Kennedy	typeset fs=$1
1062d583b39bSJohn Wren Kennedy
1063d583b39bSJohn Wren Kennedy	is_shared $fs
1064d583b39bSJohn Wren Kennedy	if (($? == 0)); then
10651d32ba66SJohn Wren Kennedy		log_must zfs unshare $fs
1066d583b39bSJohn Wren Kennedy	fi
1067d583b39bSJohn Wren Kennedy
1068d583b39bSJohn Wren Kennedy	return 0
1069d583b39bSJohn Wren Kennedy}
1070d583b39bSJohn Wren Kennedy
1071d583b39bSJohn Wren Kennedy#
1072d583b39bSJohn Wren Kennedy# Check NFS server status and trigger it online.
1073d583b39bSJohn Wren Kennedy#
1074d583b39bSJohn Wren Kennedyfunction setup_nfs_server
1075d583b39bSJohn Wren Kennedy{
1076d583b39bSJohn Wren Kennedy	# Cannot share directory in non-global zone.
1077d583b39bSJohn Wren Kennedy	#
1078d583b39bSJohn Wren Kennedy	if ! is_global_zone; then
1079d583b39bSJohn Wren Kennedy		log_note "Cannot trigger NFS server by sharing in LZ."
1080d583b39bSJohn Wren Kennedy		return
1081d583b39bSJohn Wren Kennedy	fi
1082d583b39bSJohn Wren Kennedy
1083d583b39bSJohn Wren Kennedy	typeset nfs_fmri="svc:/network/nfs/server:default"
10841d32ba66SJohn Wren Kennedy	if [[ $(svcs -Ho STA $nfs_fmri) != "ON" ]]; then
1085d583b39bSJohn Wren Kennedy		#
1086d583b39bSJohn Wren Kennedy		# Only really sharing operation can enable NFS server
1087d583b39bSJohn Wren Kennedy		# to online permanently.
1088d583b39bSJohn Wren Kennedy		#
1089d583b39bSJohn Wren Kennedy		typeset dummy=/tmp/dummy
1090d583b39bSJohn Wren Kennedy
1091d583b39bSJohn Wren Kennedy		if [[ -d $dummy ]]; then
10921d32ba66SJohn Wren Kennedy			log_must rm -rf $dummy
1093d583b39bSJohn Wren Kennedy		fi
1094d583b39bSJohn Wren Kennedy
10951d32ba66SJohn Wren Kennedy		log_must mkdir $dummy
10961d32ba66SJohn Wren Kennedy		log_must share $dummy
1097d583b39bSJohn Wren Kennedy
1098d583b39bSJohn Wren Kennedy		#
1099d583b39bSJohn Wren Kennedy		# Waiting for fmri's status to be the final status.
1100d583b39bSJohn Wren Kennedy		# Otherwise, in transition, an asterisk (*) is appended for
1101d583b39bSJohn Wren Kennedy		# instances, unshare will reverse status to 'DIS' again.
1102d583b39bSJohn Wren Kennedy		#
1103d583b39bSJohn Wren Kennedy		# Waiting for 1's at least.
1104d583b39bSJohn Wren Kennedy		#
11051d32ba66SJohn Wren Kennedy		log_must sleep 1
1106d583b39bSJohn Wren Kennedy		timeout=10
11071d32ba66SJohn Wren Kennedy		while [[ timeout -ne 0 && $(svcs -Ho STA $nfs_fmri) == *'*' ]]
1108d583b39bSJohn Wren Kennedy		do
11091d32ba66SJohn Wren Kennedy			log_must sleep 1
1110d583b39bSJohn Wren Kennedy
1111d583b39bSJohn Wren Kennedy			((timeout -= 1))
1112d583b39bSJohn Wren Kennedy		done
1113d583b39bSJohn Wren Kennedy
11141d32ba66SJohn Wren Kennedy		log_must unshare $dummy
11151d32ba66SJohn Wren Kennedy		log_must rm -rf $dummy
1116d583b39bSJohn Wren Kennedy	fi
1117d583b39bSJohn Wren Kennedy
11181d32ba66SJohn Wren Kennedy	log_note "Current NFS status: '$(svcs -Ho STA,FMRI $nfs_fmri)'"
1119d583b39bSJohn Wren Kennedy}
1120d583b39bSJohn Wren Kennedy
1121d583b39bSJohn Wren Kennedy#
1122d583b39bSJohn Wren Kennedy# To verify whether calling process is in global zone
1123d583b39bSJohn Wren Kennedy#
1124d583b39bSJohn Wren Kennedy# Return 0 if in global zone, 1 in non-global zone
1125d583b39bSJohn Wren Kennedy#
1126d583b39bSJohn Wren Kennedyfunction is_global_zone
1127d583b39bSJohn Wren Kennedy{
11281d32ba66SJohn Wren Kennedy	typeset cur_zone=$(zonename 2>/dev/null)
1129d583b39bSJohn Wren Kennedy	if [[ $cur_zone != "global" ]]; then
1130d583b39bSJohn Wren Kennedy		return 1
1131d583b39bSJohn Wren Kennedy	fi
1132d583b39bSJohn Wren Kennedy	return 0
1133d583b39bSJohn Wren Kennedy}
1134d583b39bSJohn Wren Kennedy
1135d583b39bSJohn Wren Kennedy#
1136d583b39bSJohn Wren Kennedy# Verify whether test is permitted to run from
1137d583b39bSJohn Wren Kennedy# global zone, local zone, or both
1138d583b39bSJohn Wren Kennedy#
1139d583b39bSJohn Wren Kennedy# $1 zone limit, could be "global", "local", or "both"(no limit)
1140d583b39bSJohn Wren Kennedy#
1141d583b39bSJohn Wren Kennedy# Return 0 if permitted, otherwise exit with log_unsupported
1142d583b39bSJohn Wren Kennedy#
1143d583b39bSJohn Wren Kennedyfunction verify_runnable # zone limit
1144d583b39bSJohn Wren Kennedy{
1145d583b39bSJohn Wren Kennedy	typeset limit=$1
1146d583b39bSJohn Wren Kennedy
1147d583b39bSJohn Wren Kennedy	[[ -z $limit ]] && return 0
1148d583b39bSJohn Wren Kennedy
1149d583b39bSJohn Wren Kennedy	if is_global_zone ; then
1150d583b39bSJohn Wren Kennedy		case $limit in
1151d583b39bSJohn Wren Kennedy			global|both)
1152d583b39bSJohn Wren Kennedy				;;
1153d583b39bSJohn Wren Kennedy			local)	log_unsupported "Test is unable to run from "\
1154d583b39bSJohn Wren Kennedy					"global zone."
1155d583b39bSJohn Wren Kennedy				;;
1156d583b39bSJohn Wren Kennedy			*)	log_note "Warning: unknown limit $limit - " \
1157d583b39bSJohn Wren Kennedy					"use both."
1158d583b39bSJohn Wren Kennedy				;;
1159d583b39bSJohn Wren Kennedy		esac
1160d583b39bSJohn Wren Kennedy	else
1161d583b39bSJohn Wren Kennedy		case $limit in
1162d583b39bSJohn Wren Kennedy			local|both)
1163d583b39bSJohn Wren Kennedy				;;
1164d583b39bSJohn Wren Kennedy			global)	log_unsupported "Test is unable to run from "\
1165d583b39bSJohn Wren Kennedy					"local zone."
1166d583b39bSJohn Wren Kennedy				;;
1167d583b39bSJohn Wren Kennedy			*)	log_note "Warning: unknown limit $limit - " \
1168d583b39bSJohn Wren Kennedy					"use both."
1169d583b39bSJohn Wren Kennedy				;;
1170d583b39bSJohn Wren Kennedy		esac
1171d583b39bSJohn Wren Kennedy
1172d583b39bSJohn Wren Kennedy		reexport_pool
1173d583b39bSJohn Wren Kennedy	fi
1174d583b39bSJohn Wren Kennedy
1175d583b39bSJohn Wren Kennedy	return 0
1176d583b39bSJohn Wren Kennedy}
1177d583b39bSJohn Wren Kennedy
1178d583b39bSJohn Wren Kennedy# Return 0 if create successfully or the pool exists; $? otherwise
1179d583b39bSJohn Wren Kennedy# Note: In local zones, this function should return 0 silently.
1180d583b39bSJohn Wren Kennedy#
1181d583b39bSJohn Wren Kennedy# $1 - pool name
1182d583b39bSJohn Wren Kennedy# $2-n - [keyword] devs_list
1183d583b39bSJohn Wren Kennedy
1184d583b39bSJohn Wren Kennedyfunction create_pool #pool devs_list
1185d583b39bSJohn Wren Kennedy{
1186d583b39bSJohn Wren Kennedy	typeset pool=${1%%/*}
1187d583b39bSJohn Wren Kennedy
1188d583b39bSJohn Wren Kennedy	shift
1189d583b39bSJohn Wren Kennedy
1190d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
1191d583b39bSJohn Wren Kennedy		log_note "Missing pool name."
1192d583b39bSJohn Wren Kennedy		return 1
1193d583b39bSJohn Wren Kennedy	fi
1194d583b39bSJohn Wren Kennedy
1195d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
1196d583b39bSJohn Wren Kennedy		destroy_pool $pool
1197d583b39bSJohn Wren Kennedy	fi
1198d583b39bSJohn Wren Kennedy
1199d583b39bSJohn Wren Kennedy	if is_global_zone ; then
12001d32ba66SJohn Wren Kennedy		[[ -d /$pool ]] && rm -rf /$pool
12011d32ba66SJohn Wren Kennedy		log_must zpool create -f $pool $@
1202d583b39bSJohn Wren Kennedy	fi
1203d583b39bSJohn Wren Kennedy
1204d583b39bSJohn Wren Kennedy	return 0
1205d583b39bSJohn Wren Kennedy}
1206d583b39bSJohn Wren Kennedy
1207d583b39bSJohn Wren Kennedy# Return 0 if destroy successfully or the pool exists; $? otherwise
1208d583b39bSJohn Wren Kennedy# Note: In local zones, this function should return 0 silently.
1209d583b39bSJohn Wren Kennedy#
1210d583b39bSJohn Wren Kennedy# $1 - pool name
1211d583b39bSJohn Wren Kennedy# Destroy pool with the given parameters.
1212d583b39bSJohn Wren Kennedy
1213d583b39bSJohn Wren Kennedyfunction destroy_pool #pool
1214d583b39bSJohn Wren Kennedy{
1215d583b39bSJohn Wren Kennedy	typeset pool=${1%%/*}
1216d583b39bSJohn Wren Kennedy	typeset mtpt
1217d583b39bSJohn Wren Kennedy
1218d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
1219d583b39bSJohn Wren Kennedy		log_note "No pool name given."
1220d583b39bSJohn Wren Kennedy		return 1
1221d583b39bSJohn Wren Kennedy	fi
1222d583b39bSJohn Wren Kennedy
1223d583b39bSJohn Wren Kennedy	if is_global_zone ; then
1224d583b39bSJohn Wren Kennedy		if poolexists "$pool" ; then
1225d583b39bSJohn Wren Kennedy			mtpt=$(get_prop mountpoint "$pool")
1226999dc7aaSJohn Wren Kennedy
1227999dc7aaSJohn Wren Kennedy			# At times, syseventd activity can cause attempts to
1228999dc7aaSJohn Wren Kennedy			# destroy a pool to fail with EBUSY. We retry a few
1229999dc7aaSJohn Wren Kennedy			# times allowing failures before requiring the destroy
1230999dc7aaSJohn Wren Kennedy			# to succeed.
1231999dc7aaSJohn Wren Kennedy			typeset -i wait_time=10 ret=1 count=0
1232999dc7aaSJohn Wren Kennedy			must=""
1233999dc7aaSJohn Wren Kennedy			while [[ $ret -ne 0 ]]; do
12341d32ba66SJohn Wren Kennedy				$must zpool destroy -f $pool
1235999dc7aaSJohn Wren Kennedy				ret=$?
1236999dc7aaSJohn Wren Kennedy				[[ $ret -eq 0 ]] && break
1237999dc7aaSJohn Wren Kennedy				log_note "zpool destroy failed with $ret"
1238999dc7aaSJohn Wren Kennedy				[[ count++ -ge 7 ]] && must=log_must
12391d32ba66SJohn Wren Kennedy				sleep $wait_time
1240999dc7aaSJohn Wren Kennedy			done
1241d583b39bSJohn Wren Kennedy
1242d583b39bSJohn Wren Kennedy			[[ -d $mtpt ]] && \
12431d32ba66SJohn Wren Kennedy				log_must rm -rf $mtpt
1244d583b39bSJohn Wren Kennedy		else
1245999dc7aaSJohn Wren Kennedy			log_note "Pool does not exist. ($pool)"
1246d583b39bSJohn Wren Kennedy			return 1
1247d583b39bSJohn Wren Kennedy		fi
1248d583b39bSJohn Wren Kennedy	fi
1249d583b39bSJohn Wren Kennedy
1250d583b39bSJohn Wren Kennedy	return 0
1251d583b39bSJohn Wren Kennedy}
1252d583b39bSJohn Wren Kennedy
1253c373aa8bSJohn Wren Kennedy# Return 0 if created successfully; $? otherwise
1254c373aa8bSJohn Wren Kennedy#
1255c373aa8bSJohn Wren Kennedy# $1 - dataset name
1256c373aa8bSJohn Wren Kennedy# $2-n - dataset options
1257c373aa8bSJohn Wren Kennedy
1258c373aa8bSJohn Wren Kennedyfunction create_dataset #dataset dataset_options
1259c373aa8bSJohn Wren Kennedy{
1260c373aa8bSJohn Wren Kennedy	typeset dataset=$1
1261c373aa8bSJohn Wren Kennedy
1262c373aa8bSJohn Wren Kennedy	shift
1263c373aa8bSJohn Wren Kennedy
1264c373aa8bSJohn Wren Kennedy	if [[ -z $dataset ]]; then
1265c373aa8bSJohn Wren Kennedy		log_note "Missing dataset name."
1266c373aa8bSJohn Wren Kennedy		return 1
1267c373aa8bSJohn Wren Kennedy	fi
1268c373aa8bSJohn Wren Kennedy
1269c373aa8bSJohn Wren Kennedy	if datasetexists $dataset ; then
1270c373aa8bSJohn Wren Kennedy		destroy_dataset $dataset
1271c373aa8bSJohn Wren Kennedy	fi
1272c373aa8bSJohn Wren Kennedy
1273c373aa8bSJohn Wren Kennedy	log_must zfs create $@ $dataset
1274c373aa8bSJohn Wren Kennedy
1275c373aa8bSJohn Wren Kennedy	return 0
1276c373aa8bSJohn Wren Kennedy}
1277c373aa8bSJohn Wren Kennedy
1278c373aa8bSJohn Wren Kennedy# Return 0 if destroy successfully or the dataset exists; $? otherwise
1279c373aa8bSJohn Wren Kennedy# Note: In local zones, this function should return 0 silently.
1280c373aa8bSJohn Wren Kennedy#
1281c373aa8bSJohn Wren Kennedy# $1 - dataset name
1282c373aa8bSJohn Wren Kennedy
1283c373aa8bSJohn Wren Kennedyfunction destroy_dataset #dataset
1284c373aa8bSJohn Wren Kennedy{
1285c373aa8bSJohn Wren Kennedy	typeset dataset=$1
1286c373aa8bSJohn Wren Kennedy	typeset mtpt
1287c373aa8bSJohn Wren Kennedy
1288c373aa8bSJohn Wren Kennedy	if [[ -z $dataset ]]; then
1289c373aa8bSJohn Wren Kennedy		log_note "No dataset name given."
1290c373aa8bSJohn Wren Kennedy		return 1
1291c373aa8bSJohn Wren Kennedy	fi
1292c373aa8bSJohn Wren Kennedy
1293c373aa8bSJohn Wren Kennedy	if datasetexists "$dataset" ; then
1294c373aa8bSJohn Wren Kennedy		mtpt=$(get_prop mountpoint "$dataset")
1295c373aa8bSJohn Wren Kennedy		log_must zfs destroy -r $dataset
1296c373aa8bSJohn Wren Kennedy		[[ -d $mtpt ]] && log_must rm -rf $mtpt
1297c373aa8bSJohn Wren Kennedy	else
1298c373aa8bSJohn Wren Kennedy		log_note "Dataset does not exist. ($dataset)"
1299c373aa8bSJohn Wren Kennedy		return 1
1300c373aa8bSJohn Wren Kennedy	fi
1301c373aa8bSJohn Wren Kennedy
1302c373aa8bSJohn Wren Kennedy	return 0
1303c373aa8bSJohn Wren Kennedy}
1304c373aa8bSJohn Wren Kennedy
1305d583b39bSJohn Wren Kennedy#
1306d583b39bSJohn Wren Kennedy# Firstly, create a pool with 5 datasets. Then, create a single zone and
1307d583b39bSJohn Wren Kennedy# export the 5 datasets to it. In addition, we also add a ZFS filesystem
1308d583b39bSJohn Wren Kennedy# and a zvol device to the zone.
1309d583b39bSJohn Wren Kennedy#
1310d583b39bSJohn Wren Kennedy# $1 zone name
1311d583b39bSJohn Wren Kennedy# $2 zone root directory prefix
1312d583b39bSJohn Wren Kennedy# $3 zone ip
1313d583b39bSJohn Wren Kennedy#
1314d583b39bSJohn Wren Kennedyfunction zfs_zones_setup #zone_name zone_root zone_ip
1315d583b39bSJohn Wren Kennedy{
1316d583b39bSJohn Wren Kennedy	typeset zone_name=${1:-$(hostname)-z}
1317d583b39bSJohn Wren Kennedy	typeset zone_root=${2:-"/zone_root"}
1318d583b39bSJohn Wren Kennedy	typeset zone_ip=${3:-"10.1.1.10"}
1319d583b39bSJohn Wren Kennedy	typeset prefix_ctr=$ZONE_CTR
1320d583b39bSJohn Wren Kennedy	typeset pool_name=$ZONE_POOL
1321d583b39bSJohn Wren Kennedy	typeset -i cntctr=5
1322d583b39bSJohn Wren Kennedy	typeset -i i=0
1323d583b39bSJohn Wren Kennedy
1324d583b39bSJohn Wren Kennedy	# Create pool and 5 container within it
1325d583b39bSJohn Wren Kennedy	#
13261d32ba66SJohn Wren Kennedy	[[ -d /$pool_name ]] && rm -rf /$pool_name
13271d32ba66SJohn Wren Kennedy	log_must zpool create -f $pool_name $DISKS
1328d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
13291d32ba66SJohn Wren Kennedy		log_must zfs create $pool_name/$prefix_ctr$i
1330d583b39bSJohn Wren Kennedy		((i += 1))
1331d583b39bSJohn Wren Kennedy	done
1332d583b39bSJohn Wren Kennedy
1333d583b39bSJohn Wren Kennedy	# create a zvol
13341d32ba66SJohn Wren Kennedy	log_must zfs create -V 1g $pool_name/zone_zvol
1335d583b39bSJohn Wren Kennedy
1336d583b39bSJohn Wren Kennedy	#
1337d583b39bSJohn Wren Kennedy	# If current system support slog, add slog device for pool
1338d583b39bSJohn Wren Kennedy	#
1339d583b39bSJohn Wren Kennedy	if verify_slog_support ; then
1340d583b39bSJohn Wren Kennedy		typeset sdevs="/var/tmp/sdev1 /var/tmp/sdev2"
13411d32ba66SJohn Wren Kennedy		log_must mkfile $MINVDEVSIZE $sdevs
13421d32ba66SJohn Wren Kennedy		log_must zpool add $pool_name log mirror $sdevs
1343d583b39bSJohn Wren Kennedy	fi
1344d583b39bSJohn Wren Kennedy
1345d583b39bSJohn Wren Kennedy	# this isn't supported just yet.
1346d583b39bSJohn Wren Kennedy	# Create a filesystem. In order to add this to
1347d583b39bSJohn Wren Kennedy	# the zone, it must have it's mountpoint set to 'legacy'
13481d32ba66SJohn Wren Kennedy	# log_must zfs create $pool_name/zfs_filesystem
13491d32ba66SJohn Wren Kennedy	# log_must zfs set mountpoint=legacy $pool_name/zfs_filesystem
1350d583b39bSJohn Wren Kennedy
1351d583b39bSJohn Wren Kennedy	[[ -d $zone_root ]] && \
13521d32ba66SJohn Wren Kennedy		log_must rm -rf $zone_root/$zone_name
1353d583b39bSJohn Wren Kennedy	[[ ! -d $zone_root ]] && \
13541d32ba66SJohn Wren Kennedy		log_must mkdir -p -m 0700 $zone_root/$zone_name
1355d583b39bSJohn Wren Kennedy
1356d583b39bSJohn Wren Kennedy	# Create zone configure file and configure the zone
1357d583b39bSJohn Wren Kennedy	#
1358d583b39bSJohn Wren Kennedy	typeset zone_conf=/tmp/zone_conf.$$
13591d32ba66SJohn Wren Kennedy	echo "create" > $zone_conf
13601d32ba66SJohn Wren Kennedy	echo "set zonepath=$zone_root/$zone_name" >> $zone_conf
13611d32ba66SJohn Wren Kennedy	echo "set autoboot=true" >> $zone_conf
1362d583b39bSJohn Wren Kennedy	i=0
1363d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
13641d32ba66SJohn Wren Kennedy		echo "add dataset" >> $zone_conf
13651d32ba66SJohn Wren Kennedy		echo "set name=$pool_name/$prefix_ctr$i" >> \
1366d583b39bSJohn Wren Kennedy			$zone_conf
13671d32ba66SJohn Wren Kennedy		echo "end" >> $zone_conf
1368d583b39bSJohn Wren Kennedy		((i += 1))
1369d583b39bSJohn Wren Kennedy	done
1370d583b39bSJohn Wren Kennedy
1371d583b39bSJohn Wren Kennedy	# add our zvol to the zone
13721d32ba66SJohn Wren Kennedy	echo "add device" >> $zone_conf
13731d32ba66SJohn Wren Kennedy	echo "set match=/dev/zvol/dsk/$pool_name/zone_zvol" >> $zone_conf
13741d32ba66SJohn Wren Kennedy	echo "end" >> $zone_conf
1375d583b39bSJohn Wren Kennedy
1376d583b39bSJohn Wren Kennedy	# add a corresponding zvol rdsk to the zone
13771d32ba66SJohn Wren Kennedy	echo "add device" >> $zone_conf
13781d32ba66SJohn Wren Kennedy	echo "set match=/dev/zvol/rdsk/$pool_name/zone_zvol" >> $zone_conf
13791d32ba66SJohn Wren Kennedy	echo "end" >> $zone_conf
1380d583b39bSJohn Wren Kennedy
1381d583b39bSJohn Wren Kennedy	# once it's supported, we'll add our filesystem to the zone
13821d32ba66SJohn Wren Kennedy	# echo "add fs" >> $zone_conf
13831d32ba66SJohn Wren Kennedy	# echo "set type=zfs" >> $zone_conf
13841d32ba66SJohn Wren Kennedy	# echo "set special=$pool_name/zfs_filesystem" >> $zone_conf
13851d32ba66SJohn Wren Kennedy	# echo "set dir=/export/zfs_filesystem" >> $zone_conf
13861d32ba66SJohn Wren Kennedy	# echo "end" >> $zone_conf
1387d583b39bSJohn Wren Kennedy
13881d32ba66SJohn Wren Kennedy	echo "verify" >> $zone_conf
13891d32ba66SJohn Wren Kennedy	echo "commit" >> $zone_conf
13901d32ba66SJohn Wren Kennedy	log_must zonecfg -z $zone_name -f $zone_conf
13911d32ba66SJohn Wren Kennedy	log_must rm -f $zone_conf
1392d583b39bSJohn Wren Kennedy
1393d583b39bSJohn Wren Kennedy	# Install the zone
13941d32ba66SJohn Wren Kennedy	zoneadm -z $zone_name install
1395d583b39bSJohn Wren Kennedy	if (($? == 0)); then
13961d32ba66SJohn Wren Kennedy		log_note "SUCCESS: zoneadm -z $zone_name install"
1397d583b39bSJohn Wren Kennedy	else
13981d32ba66SJohn Wren Kennedy		log_fail "FAIL: zoneadm -z $zone_name install"
1399d583b39bSJohn Wren Kennedy	fi
1400d583b39bSJohn Wren Kennedy
1401d583b39bSJohn Wren Kennedy	# Install sysidcfg file
1402d583b39bSJohn Wren Kennedy	#
1403d583b39bSJohn Wren Kennedy	typeset sysidcfg=$zone_root/$zone_name/root/etc/sysidcfg
14041d32ba66SJohn Wren Kennedy	echo "system_locale=C" > $sysidcfg
14051d32ba66SJohn Wren Kennedy	echo  "terminal=dtterm" >> $sysidcfg
14061d32ba66SJohn Wren Kennedy	echo  "network_interface=primary {" >> $sysidcfg
14071d32ba66SJohn Wren Kennedy	echo  "hostname=$zone_name" >> $sysidcfg
14081d32ba66SJohn Wren Kennedy	echo  "}" >> $sysidcfg
14091d32ba66SJohn Wren Kennedy	echo  "name_service=NONE" >> $sysidcfg
14101d32ba66SJohn Wren Kennedy	echo  "root_password=mo791xfZ/SFiw" >> $sysidcfg
14111d32ba66SJohn Wren Kennedy	echo  "security_policy=NONE" >> $sysidcfg
14121d32ba66SJohn Wren Kennedy	echo  "timezone=US/Eastern" >> $sysidcfg
1413d583b39bSJohn Wren Kennedy
1414d583b39bSJohn Wren Kennedy	# Boot this zone
14151d32ba66SJohn Wren Kennedy	log_must zoneadm -z $zone_name boot
1416d583b39bSJohn Wren Kennedy}
1417d583b39bSJohn Wren Kennedy
1418d583b39bSJohn Wren Kennedy#
1419d583b39bSJohn Wren Kennedy# Reexport TESTPOOL & TESTPOOL(1-4)
1420d583b39bSJohn Wren Kennedy#
1421d583b39bSJohn Wren Kennedyfunction reexport_pool
1422d583b39bSJohn Wren Kennedy{
1423d583b39bSJohn Wren Kennedy	typeset -i cntctr=5
1424d583b39bSJohn Wren Kennedy	typeset -i i=0
1425d583b39bSJohn Wren Kennedy
1426d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
1427d583b39bSJohn Wren Kennedy		if ((i == 0)); then
1428d583b39bSJohn Wren Kennedy			TESTPOOL=$ZONE_POOL/$ZONE_CTR$i
1429d583b39bSJohn Wren Kennedy			if ! ismounted $TESTPOOL; then
14301d32ba66SJohn Wren Kennedy				log_must zfs mount $TESTPOOL
1431d583b39bSJohn Wren Kennedy			fi
1432d583b39bSJohn Wren Kennedy		else
1433d583b39bSJohn Wren Kennedy			eval TESTPOOL$i=$ZONE_POOL/$ZONE_CTR$i
1434d583b39bSJohn Wren Kennedy			if eval ! ismounted \$TESTPOOL$i; then
14351d32ba66SJohn Wren Kennedy				log_must eval zfs mount \$TESTPOOL$i
1436d583b39bSJohn Wren Kennedy			fi
1437d583b39bSJohn Wren Kennedy		fi
1438d583b39bSJohn Wren Kennedy		((i += 1))
1439d583b39bSJohn Wren Kennedy	done
1440d583b39bSJohn Wren Kennedy}
1441d583b39bSJohn Wren Kennedy
1442d583b39bSJohn Wren Kennedy#
1443d583b39bSJohn Wren Kennedy# Verify a given disk is online or offline
1444d583b39bSJohn Wren Kennedy#
1445d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1446d583b39bSJohn Wren Kennedy#
1447d583b39bSJohn Wren Kennedyfunction check_state # pool disk state{online,offline}
1448d583b39bSJohn Wren Kennedy{
1449d583b39bSJohn Wren Kennedy	typeset pool=$1
1450d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1451d583b39bSJohn Wren Kennedy	typeset state=$3
1452d583b39bSJohn Wren Kennedy
14531d32ba66SJohn Wren Kennedy	zpool status -v $pool | grep "$disk"  \
1454d583b39bSJohn Wren Kennedy	    | grep -i "$state" > /dev/null 2>&1
1455d583b39bSJohn Wren Kennedy
1456d583b39bSJohn Wren Kennedy	return $?
1457d583b39bSJohn Wren Kennedy}
1458d583b39bSJohn Wren Kennedy
1459d583b39bSJohn Wren Kennedy#
1460d583b39bSJohn Wren Kennedy# Get the mountpoint of snapshot
1461d583b39bSJohn Wren Kennedy# For the snapshot use <mp_filesystem>/.zfs/snapshot/<snap>
1462d583b39bSJohn Wren Kennedy# as its mountpoint
1463d583b39bSJohn Wren Kennedy#
1464d583b39bSJohn Wren Kennedyfunction snapshot_mountpoint
1465d583b39bSJohn Wren Kennedy{
1466d583b39bSJohn Wren Kennedy	typeset dataset=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
1467d583b39bSJohn Wren Kennedy
1468d583b39bSJohn Wren Kennedy	if [[ $dataset != *@* ]]; then
1469d583b39bSJohn Wren Kennedy		log_fail "Error name of snapshot '$dataset'."
1470d583b39bSJohn Wren Kennedy	fi
1471d583b39bSJohn Wren Kennedy
1472d583b39bSJohn Wren Kennedy	typeset fs=${dataset%@*}
1473d583b39bSJohn Wren Kennedy	typeset snap=${dataset#*@}
1474d583b39bSJohn Wren Kennedy
1475d583b39bSJohn Wren Kennedy	if [[ -z $fs || -z $snap ]]; then
1476d583b39bSJohn Wren Kennedy		log_fail "Error name of snapshot '$dataset'."
1477d583b39bSJohn Wren Kennedy	fi
1478d583b39bSJohn Wren Kennedy
14791d32ba66SJohn Wren Kennedy	echo $(get_prop mountpoint $fs)/.zfs/snapshot/$snap
1480d583b39bSJohn Wren Kennedy}
1481d583b39bSJohn Wren Kennedy
14825711d393Sloli#
14835711d393Sloli# Given a device and 'ashift' value verify it's correctly set on every label
14845711d393Sloli#
14855711d393Slolifunction verify_ashift # device ashift
14865711d393Sloli{
14875711d393Sloli	typeset device="$1"
14885711d393Sloli	typeset ashift="$2"
14895711d393Sloli
14905711d393Sloli	zdb -e -lll $device | nawk -v ashift=$ashift '/ashift: / {
14915711d393Sloli	    if (ashift != $2)
14925711d393Sloli	        exit 1;
14935711d393Sloli	    else
14945711d393Sloli	        count++;
14955711d393Sloli	    } END {
14965711d393Sloli	    if (count != 4)
14975711d393Sloli	        exit 1;
14985711d393Sloli	    else
14995711d393Sloli	        exit 0;
15005711d393Sloli	    }'
15015711d393Sloli
15025711d393Sloli	return $?
15035711d393Sloli}
15045711d393Sloli
1505d583b39bSJohn Wren Kennedy#
1506d583b39bSJohn Wren Kennedy# Given a pool and file system, this function will verify the file system
1507d583b39bSJohn Wren Kennedy# using the zdb internal tool. Note that the pool is exported and imported
1508d583b39bSJohn Wren Kennedy# to ensure it has consistent state.
1509d583b39bSJohn Wren Kennedy#
1510d583b39bSJohn Wren Kennedyfunction verify_filesys # pool filesystem dir
1511d583b39bSJohn Wren Kennedy{
1512d583b39bSJohn Wren Kennedy	typeset pool="$1"
1513d583b39bSJohn Wren Kennedy	typeset filesys="$2"
1514d583b39bSJohn Wren Kennedy	typeset zdbout="/tmp/zdbout.$$"
1515d583b39bSJohn Wren Kennedy
1516d583b39bSJohn Wren Kennedy	shift
1517d583b39bSJohn Wren Kennedy	shift
1518d583b39bSJohn Wren Kennedy	typeset dirs=$@
1519d583b39bSJohn Wren Kennedy	typeset search_path=""
1520d583b39bSJohn Wren Kennedy
15211d32ba66SJohn Wren Kennedy	log_note "Calling zdb to verify filesystem '$filesys'"
15221d32ba66SJohn Wren Kennedy	zfs unmount -a > /dev/null 2>&1
15231d32ba66SJohn Wren Kennedy	log_must zpool export $pool
1524d583b39bSJohn Wren Kennedy
1525d583b39bSJohn Wren Kennedy	if [[ -n $dirs ]] ; then
1526d583b39bSJohn Wren Kennedy		for dir in $dirs ; do
1527d583b39bSJohn Wren Kennedy			search_path="$search_path -d $dir"
1528d583b39bSJohn Wren Kennedy		done
1529d583b39bSJohn Wren Kennedy	fi
1530d583b39bSJohn Wren Kennedy
15311d32ba66SJohn Wren Kennedy	log_must zpool import $search_path $pool
1532d583b39bSJohn Wren Kennedy
15331d32ba66SJohn Wren Kennedy	zdb -cudi $filesys > $zdbout 2>&1
1534d583b39bSJohn Wren Kennedy	if [[ $? != 0 ]]; then
15351d32ba66SJohn Wren Kennedy		log_note "Output: zdb -cudi $filesys"
15361d32ba66SJohn Wren Kennedy		cat $zdbout
15371d32ba66SJohn Wren Kennedy		log_fail "zdb detected errors with: '$filesys'"
1538d583b39bSJohn Wren Kennedy	fi
1539d583b39bSJohn Wren Kennedy
15401d32ba66SJohn Wren Kennedy	log_must zfs mount -a
15411d32ba66SJohn Wren Kennedy	log_must rm -rf $zdbout
1542d583b39bSJohn Wren Kennedy}
1543d583b39bSJohn Wren Kennedy
1544ed54d13fSJerry Jelinek#
1545ed54d13fSJerry Jelinek# Given a pool issue a scrub and verify that no checksum errors are reported.
1546ed54d13fSJerry Jelinek#
1547ed54d13fSJerry Jelinekfunction verify_pool
1548ed54d13fSJerry Jelinek{
1549ed54d13fSJerry Jelinek	typeset pool=${1:-$TESTPOOL}
1550ed54d13fSJerry Jelinek
1551ed54d13fSJerry Jelinek	log_must zpool scrub $pool
1552ed54d13fSJerry Jelinek	log_must wait_scrubbed $pool
1553ed54d13fSJerry Jelinek
1554ed54d13fSJerry Jelinek	cksum=$(zpool status $pool | \
1555ed54d13fSJerry Jelinek	    awk '{if ($5 == "CKSUM"){L=1; next} if (L) {print $NF;L=0}}')
1556ed54d13fSJerry Jelinek	if [[ $cksum != 0 ]]; then
1557ed54d13fSJerry Jelinek		log_must zpool status -v
1558ed54d13fSJerry Jelinek	        log_fail "Unexpected CKSUM errors found on $pool ($cksum)"
1559ed54d13fSJerry Jelinek	fi
1560ed54d13fSJerry Jelinek}
1561ed54d13fSJerry Jelinek
1562d583b39bSJohn Wren Kennedy#
1563d583b39bSJohn Wren Kennedy# Given a pool, and this function list all disks in the pool
1564d583b39bSJohn Wren Kennedy#
1565d583b39bSJohn Wren Kennedyfunction get_disklist # pool
1566d583b39bSJohn Wren Kennedy{
1567d583b39bSJohn Wren Kennedy	typeset disklist=""
1568d583b39bSJohn Wren Kennedy
15691d32ba66SJohn Wren Kennedy	disklist=$(zpool iostat -v $1 | nawk '(NR >4) {print $1}' | \
15701d32ba66SJohn Wren Kennedy	    grep -v "\-\-\-\-\-" | \
1571dd50e0ccSTony Hutter	    egrep -v -e "^(mirror|raidz[1-3]|spare|log|cache|special|dedup)$")
1572d583b39bSJohn Wren Kennedy
15731d32ba66SJohn Wren Kennedy	echo $disklist
1574d583b39bSJohn Wren Kennedy}
1575d583b39bSJohn Wren Kennedy
1576d583b39bSJohn Wren Kennedy# /**
1577d583b39bSJohn Wren Kennedy#  This function kills a given list of processes after a time period. We use
1578d583b39bSJohn Wren Kennedy#  this in the stress tests instead of STF_TIMEOUT so that we can have processes
1579d583b39bSJohn Wren Kennedy#  run for a fixed amount of time, yet still pass. Tests that hit STF_TIMEOUT
1580d583b39bSJohn Wren Kennedy#  would be listed as FAIL, which we don't want : we're happy with stress tests
1581d583b39bSJohn Wren Kennedy#  running for a certain amount of time, then finishing.
1582d583b39bSJohn Wren Kennedy#
1583d583b39bSJohn Wren Kennedy# @param $1 the time in seconds after which we should terminate these processes
1584d583b39bSJohn Wren Kennedy# @param $2..$n the processes we wish to terminate.
1585d583b39bSJohn Wren Kennedy# */
1586d583b39bSJohn Wren Kennedyfunction stress_timeout
1587d583b39bSJohn Wren Kennedy{
1588d583b39bSJohn Wren Kennedy	typeset -i TIMEOUT=$1
1589d583b39bSJohn Wren Kennedy	shift
1590d583b39bSJohn Wren Kennedy	typeset cpids="$@"
1591d583b39bSJohn Wren Kennedy
1592d583b39bSJohn Wren Kennedy	log_note "Waiting for child processes($cpids). " \
1593d583b39bSJohn Wren Kennedy		"It could last dozens of minutes, please be patient ..."
15941d32ba66SJohn Wren Kennedy	log_must sleep $TIMEOUT
1595d583b39bSJohn Wren Kennedy
1596d583b39bSJohn Wren Kennedy	log_note "Killing child processes after ${TIMEOUT} stress timeout."
1597d583b39bSJohn Wren Kennedy	typeset pid
1598d583b39bSJohn Wren Kennedy	for pid in $cpids; do
15991d32ba66SJohn Wren Kennedy		ps -p $pid > /dev/null 2>&1
1600d583b39bSJohn Wren Kennedy		if (($? == 0)); then
16011d32ba66SJohn Wren Kennedy			log_must kill -USR1 $pid
1602d583b39bSJohn Wren Kennedy		fi
1603d583b39bSJohn Wren Kennedy	done
1604d583b39bSJohn Wren Kennedy}
1605d583b39bSJohn Wren Kennedy
1606d583b39bSJohn Wren Kennedy#
1607d583b39bSJohn Wren Kennedy# Verify a given hotspare disk is inuse or avail
1608d583b39bSJohn Wren Kennedy#
1609d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1610d583b39bSJohn Wren Kennedy#
1611d583b39bSJohn Wren Kennedyfunction check_hotspare_state # pool disk state{inuse,avail}
1612d583b39bSJohn Wren Kennedy{
1613d583b39bSJohn Wren Kennedy	typeset pool=$1
1614d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1615d583b39bSJohn Wren Kennedy	typeset state=$3
1616d583b39bSJohn Wren Kennedy
1617d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk "spares")
1618d583b39bSJohn Wren Kennedy
1619d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1620d583b39bSJohn Wren Kennedy		return 1
1621d583b39bSJohn Wren Kennedy	fi
1622d583b39bSJohn Wren Kennedy	return 0
1623d583b39bSJohn Wren Kennedy}
1624d583b39bSJohn Wren Kennedy
1625ac0215f4Sloli#
1626ac0215f4Sloli# Wait until a hotspare transitions to a given state or times out.
1627ac0215f4Sloli#
1628ac0215f4Sloli# Return 0 when  pool/disk matches expected state, 1 on timeout.
1629ac0215f4Sloli#
1630ac0215f4Slolifunction wait_hotspare_state # pool disk state timeout
1631ac0215f4Sloli{
1632ac0215f4Sloli	typeset pool=$1
1633ac0215f4Sloli	typeset disk=${2#$/DEV_DSKDIR/}
1634ac0215f4Sloli	typeset state=$3
1635ac0215f4Sloli	typeset timeout=${4:-60}
1636ac0215f4Sloli	typeset -i i=0
1637ac0215f4Sloli
1638ac0215f4Sloli	while [[ $i -lt $timeout ]]; do
1639ac0215f4Sloli		if check_hotspare_state $pool $disk $state; then
1640ac0215f4Sloli			return 0
1641ac0215f4Sloli		fi
1642ac0215f4Sloli
1643ac0215f4Sloli		i=$((i+1))
1644ac0215f4Sloli		sleep 1
1645ac0215f4Sloli	done
1646ac0215f4Sloli
1647ac0215f4Sloli	return 1
1648ac0215f4Sloli}
1649ac0215f4Sloli
1650d583b39bSJohn Wren Kennedy#
1651d583b39bSJohn Wren Kennedy# Verify a given slog disk is inuse or avail
1652d583b39bSJohn Wren Kennedy#
1653d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1654d583b39bSJohn Wren Kennedy#
1655d583b39bSJohn Wren Kennedyfunction check_slog_state # pool disk state{online,offline,unavail}
1656d583b39bSJohn Wren Kennedy{
1657d583b39bSJohn Wren Kennedy	typeset pool=$1
1658d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1659d583b39bSJohn Wren Kennedy	typeset state=$3
1660d583b39bSJohn Wren Kennedy
1661d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk "logs")
1662d583b39bSJohn Wren Kennedy
1663d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1664d583b39bSJohn Wren Kennedy		return 1
1665d583b39bSJohn Wren Kennedy	fi
1666d583b39bSJohn Wren Kennedy	return 0
1667d583b39bSJohn Wren Kennedy}
1668d583b39bSJohn Wren Kennedy
1669d583b39bSJohn Wren Kennedy#
1670d583b39bSJohn Wren Kennedy# Verify a given vdev disk is inuse or avail
1671d583b39bSJohn Wren Kennedy#
1672d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1673d583b39bSJohn Wren Kennedy#
1674d583b39bSJohn Wren Kennedyfunction check_vdev_state # pool disk state{online,offline,unavail}
1675d583b39bSJohn Wren Kennedy{
1676d583b39bSJohn Wren Kennedy	typeset pool=$1
1677d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1678d583b39bSJohn Wren Kennedy	typeset state=$3
1679d583b39bSJohn Wren Kennedy
1680d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk)
1681d583b39bSJohn Wren Kennedy
1682d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1683d583b39bSJohn Wren Kennedy		return 1
1684d583b39bSJohn Wren Kennedy	fi
1685d583b39bSJohn Wren Kennedy	return 0
1686d583b39bSJohn Wren Kennedy}
1687d583b39bSJohn Wren Kennedy
1688ac0215f4Sloli#
1689ac0215f4Sloli# Wait until a vdev transitions to a given state or times out.
1690ac0215f4Sloli#
1691ac0215f4Sloli# Return 0 when  pool/disk matches expected state, 1 on timeout.
1692ac0215f4Sloli#
1693ac0215f4Slolifunction wait_vdev_state # pool disk state timeout
1694ac0215f4Sloli{
1695ac0215f4Sloli	typeset pool=$1
1696ac0215f4Sloli	typeset disk=${2#$/DEV_DSKDIR/}
1697ac0215f4Sloli	typeset state=$3
1698ac0215f4Sloli	typeset timeout=${4:-60}
1699ac0215f4Sloli	typeset -i i=0
1700ac0215f4Sloli
1701ac0215f4Sloli	while [[ $i -lt $timeout ]]; do
1702ac0215f4Sloli		if check_vdev_state $pool $disk $state; then
1703ac0215f4Sloli			return 0
1704ac0215f4Sloli		fi
1705ac0215f4Sloli
1706ac0215f4Sloli		i=$((i+1))
1707ac0215f4Sloli		sleep 1
1708ac0215f4Sloli	done
1709ac0215f4Sloli
1710ac0215f4Sloli	return 1
1711ac0215f4Sloli}
1712ac0215f4Sloli
1713d583b39bSJohn Wren Kennedy#
1714d583b39bSJohn Wren Kennedy# Check the output of 'zpool status -v <pool>',
1715d583b39bSJohn Wren Kennedy# and to see if the content of <token> contain the <keyword> specified.
1716d583b39bSJohn Wren Kennedy#
1717d583b39bSJohn Wren Kennedy# Return 0 is contain, 1 otherwise
1718d583b39bSJohn Wren Kennedy#
17191702cce7SAlek Pinchukfunction check_pool_status # pool token keyword <verbose>
1720d583b39bSJohn Wren Kennedy{
1721d583b39bSJohn Wren Kennedy	typeset pool=$1
1722d583b39bSJohn Wren Kennedy	typeset token=$2
1723d583b39bSJohn Wren Kennedy	typeset keyword=$3
17241702cce7SAlek Pinchuk	typeset verbose=${4:-false}
1725d583b39bSJohn Wren Kennedy
17261702cce7SAlek Pinchuk	scan=$(zpool status -v "$pool" 2>/dev/null | nawk -v token="$token:" '
17271702cce7SAlek Pinchuk		($1==token) {print $0}')
17281702cce7SAlek Pinchuk	if [[ $verbose == true ]]; then
17291702cce7SAlek Pinchuk		log_note $scan
17301702cce7SAlek Pinchuk	fi
17311702cce7SAlek Pinchuk	echo $scan | grep -i "$keyword" > /dev/null 2>&1
1732d583b39bSJohn Wren Kennedy
1733d583b39bSJohn Wren Kennedy	return $?
1734d583b39bSJohn Wren Kennedy}
1735d583b39bSJohn Wren Kennedy
1736d583b39bSJohn Wren Kennedy#
17371702cce7SAlek Pinchuk# These 6 following functions are instance of check_pool_status()
1738d583b39bSJohn Wren Kennedy#	is_pool_resilvering - to check if the pool is resilver in progress
1739d583b39bSJohn Wren Kennedy#	is_pool_resilvered - to check if the pool is resilver completed
1740d583b39bSJohn Wren Kennedy#	is_pool_scrubbing - to check if the pool is scrub in progress
1741d583b39bSJohn Wren Kennedy#	is_pool_scrubbed - to check if the pool is scrub completed
1742d583b39bSJohn Wren Kennedy#	is_pool_scrub_stopped - to check if the pool is scrub stopped
17431702cce7SAlek Pinchuk#	is_pool_scrub_paused - to check if the pool has scrub paused
17445cabbc6bSPrashanth Sreenivasa#	is_pool_removing - to check if the pool is removing a vdev
17455cabbc6bSPrashanth Sreenivasa#	is_pool_removed - to check if the pool is remove completed
1746d583b39bSJohn Wren Kennedy#
17471702cce7SAlek Pinchukfunction is_pool_resilvering #pool <verbose>
17481702cce7SAlek Pinchuk{
17491702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "resilver in progress since " $2
17501702cce7SAlek Pinchuk	return $?
17511702cce7SAlek Pinchuk}
17521702cce7SAlek Pinchuk
17531702cce7SAlek Pinchukfunction is_pool_resilvered #pool <verbose>
1754d583b39bSJohn Wren Kennedy{
17551702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "resilvered " $2
1756d583b39bSJohn Wren Kennedy	return $?
1757d583b39bSJohn Wren Kennedy}
1758d583b39bSJohn Wren Kennedy
17591702cce7SAlek Pinchukfunction is_pool_scrubbing #pool <verbose>
1760d583b39bSJohn Wren Kennedy{
17611702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "scrub in progress since " $2
1762d583b39bSJohn Wren Kennedy	return $?
1763d583b39bSJohn Wren Kennedy}
1764d583b39bSJohn Wren Kennedy
17651702cce7SAlek Pinchukfunction is_pool_scrubbed #pool <verbose>
1766d583b39bSJohn Wren Kennedy{
17671702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "scrub repaired" $2
1768d583b39bSJohn Wren Kennedy	return $?
1769d583b39bSJohn Wren Kennedy}
1770d583b39bSJohn Wren Kennedy
17711702cce7SAlek Pinchukfunction is_pool_scrub_stopped #pool <verbose>
1772d583b39bSJohn Wren Kennedy{
17731702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "scrub canceled" $2
1774d583b39bSJohn Wren Kennedy	return $?
1775d583b39bSJohn Wren Kennedy}
1776d583b39bSJohn Wren Kennedy
17771702cce7SAlek Pinchukfunction is_pool_scrub_paused #pool <verbose>
1778d583b39bSJohn Wren Kennedy{
17791702cce7SAlek Pinchuk	check_pool_status "$1" "scan" "scrub paused since " $2
1780d583b39bSJohn Wren Kennedy	return $?
1781d583b39bSJohn Wren Kennedy}
1782d583b39bSJohn Wren Kennedy
17835cabbc6bSPrashanth Sreenivasafunction is_pool_removing #pool
17845cabbc6bSPrashanth Sreenivasa{
17855cabbc6bSPrashanth Sreenivasa	check_pool_status "$1" "remove" "in progress since "
17865cabbc6bSPrashanth Sreenivasa	return $?
17875cabbc6bSPrashanth Sreenivasa}
17885cabbc6bSPrashanth Sreenivasa
17895cabbc6bSPrashanth Sreenivasafunction is_pool_removed #pool
17905cabbc6bSPrashanth Sreenivasa{
17915cabbc6bSPrashanth Sreenivasa	check_pool_status "$1" "remove" "completed on"
17925cabbc6bSPrashanth Sreenivasa	return $?
17935cabbc6bSPrashanth Sreenivasa}
17945cabbc6bSPrashanth Sreenivasa
179520596fe4SJohn Wren Kennedyfunction wait_for_degraded
179620596fe4SJohn Wren Kennedy{
179720596fe4SJohn Wren Kennedy	typeset pool=$1
179820596fe4SJohn Wren Kennedy	typeset timeout=${2:-30}
179920596fe4SJohn Wren Kennedy	typeset t0=$SECONDS
180020596fe4SJohn Wren Kennedy
180120596fe4SJohn Wren Kennedy	while :; do
180220596fe4SJohn Wren Kennedy		[[ $(get_pool_prop health $pool) == "DEGRADED" ]] && break
180320596fe4SJohn Wren Kennedy		log_note "$pool is not yet degraded."
180420596fe4SJohn Wren Kennedy		sleep 1
180520596fe4SJohn Wren Kennedy		if ((SECONDS - t0 > $timeout)); then
180620596fe4SJohn Wren Kennedy			log_note "$pool not degraded after $timeout seconds."
180720596fe4SJohn Wren Kennedy			return 1
180820596fe4SJohn Wren Kennedy		fi
180920596fe4SJohn Wren Kennedy	done
181020596fe4SJohn Wren Kennedy
181120596fe4SJohn Wren Kennedy	return 0
181220596fe4SJohn Wren Kennedy}
181320596fe4SJohn Wren Kennedy
181412a8814cSTom Caputi#
181512a8814cSTom Caputi# Wait for a pool to be scrubbed
181612a8814cSTom Caputi#
181712a8814cSTom Caputi# $1 pool name
181812a8814cSTom Caputi# $2 number of seconds to wait (optional)
181912a8814cSTom Caputi#
182012a8814cSTom Caputi# Returns true when pool has been scrubbed, or false if there's a timeout or if
182112a8814cSTom Caputi# no scrub was done.
182212a8814cSTom Caputi#
182312a8814cSTom Caputifunction wait_scrubbed
182412a8814cSTom Caputi{
182512a8814cSTom Caputi	typeset pool=${1:-$TESTPOOL}
182612a8814cSTom Caputi	while true ; do
182712a8814cSTom Caputi		is_pool_scrubbed $pool && break
182812a8814cSTom Caputi		log_must sleep 1
182912a8814cSTom Caputi	done
183012a8814cSTom Caputi}
183112a8814cSTom Caputi
1832d583b39bSJohn Wren Kennedy#
1833d583b39bSJohn Wren Kennedy# Use create_pool()/destroy_pool() to clean up the infomation in
1834d583b39bSJohn Wren Kennedy# in the given disk to avoid slice overlapping.
1835d583b39bSJohn Wren Kennedy#
1836d583b39bSJohn Wren Kennedyfunction cleanup_devices #vdevs
1837d583b39bSJohn Wren Kennedy{
1838d583b39bSJohn Wren Kennedy	typeset pool="foopool$$"
1839d583b39bSJohn Wren Kennedy
1840d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
1841d583b39bSJohn Wren Kennedy		destroy_pool $pool
1842d583b39bSJohn Wren Kennedy	fi
1843d583b39bSJohn Wren Kennedy
1844d583b39bSJohn Wren Kennedy	create_pool $pool $@
1845d583b39bSJohn Wren Kennedy	destroy_pool $pool
1846d583b39bSJohn Wren Kennedy
1847d583b39bSJohn Wren Kennedy	return 0
1848d583b39bSJohn Wren Kennedy}
1849d583b39bSJohn Wren Kennedy
1850d583b39bSJohn Wren Kennedy#/**
1851d583b39bSJohn Wren Kennedy# A function to find and locate free disks on a system or from given
1852d583b39bSJohn Wren Kennedy# disks as the parameter. It works by locating disks that are in use
18534eab410fSMatthew Ahrens# as swap devices and dump devices, and also disks listed in /etc/vfstab
1854d583b39bSJohn Wren Kennedy#
1855d583b39bSJohn Wren Kennedy# $@ given disks to find which are free, default is all disks in
1856d583b39bSJohn Wren Kennedy# the test system
1857d583b39bSJohn Wren Kennedy#
1858d583b39bSJohn Wren Kennedy# @return a string containing the list of available disks
1859d583b39bSJohn Wren Kennedy#*/
1860d583b39bSJohn Wren Kennedyfunction find_disks
1861d583b39bSJohn Wren Kennedy{
1862d583b39bSJohn Wren Kennedy	sfi=/tmp/swaplist.$$
1863d583b39bSJohn Wren Kennedy	dmpi=/tmp/dumpdev.$$
1864d583b39bSJohn Wren Kennedy	max_finddisksnum=${MAX_FINDDISKSNUM:-6}
1865d583b39bSJohn Wren Kennedy
18661d32ba66SJohn Wren Kennedy	swap -l > $sfi
18671d32ba66SJohn Wren Kennedy	dumpadm > $dmpi 2>/dev/null
1868d583b39bSJohn Wren Kennedy
1869d583b39bSJohn Wren Kennedy# write an awk script that can process the output of format
1870d583b39bSJohn Wren Kennedy# to produce a list of disks we know about. Note that we have
1871d583b39bSJohn Wren Kennedy# to escape "$2" so that the shell doesn't interpret it while
1872d583b39bSJohn Wren Kennedy# we're creating the awk script.
1873d583b39bSJohn Wren Kennedy# -------------------
18741d32ba66SJohn Wren Kennedy	cat > /tmp/find_disks.awk <<EOF
1875d583b39bSJohn Wren Kennedy#!/bin/nawk -f
1876d583b39bSJohn Wren Kennedy	BEGIN { FS="."; }
1877d583b39bSJohn Wren Kennedy
1878d583b39bSJohn Wren Kennedy	/^Specify disk/{
1879d583b39bSJohn Wren Kennedy		searchdisks=0;
1880d583b39bSJohn Wren Kennedy	}
1881d583b39bSJohn Wren Kennedy
1882d583b39bSJohn Wren Kennedy	{
1883d583b39bSJohn Wren Kennedy		if (searchdisks && \$2 !~ "^$"){
1884d583b39bSJohn Wren Kennedy			split(\$2,arr," ");
1885d583b39bSJohn Wren Kennedy			print arr[1];
1886d583b39bSJohn Wren Kennedy		}
1887d583b39bSJohn Wren Kennedy	}
1888d583b39bSJohn Wren Kennedy
1889d583b39bSJohn Wren Kennedy	/^AVAILABLE DISK SELECTIONS:/{
1890d583b39bSJohn Wren Kennedy		searchdisks=1;
1891d583b39bSJohn Wren Kennedy	}
1892d583b39bSJohn Wren KennedyEOF
1893d583b39bSJohn Wren Kennedy#---------------------
1894d583b39bSJohn Wren Kennedy
18951d32ba66SJohn Wren Kennedy	chmod 755 /tmp/find_disks.awk
18961d32ba66SJohn Wren Kennedy	disks=${@:-$(echo "" | format -e 2>/dev/null | /tmp/find_disks.awk)}
18971d32ba66SJohn Wren Kennedy	rm /tmp/find_disks.awk
1898d583b39bSJohn Wren Kennedy
1899d583b39bSJohn Wren Kennedy	unused=""
1900d583b39bSJohn Wren Kennedy	for disk in $disks; do
1901d583b39bSJohn Wren Kennedy	# Check for mounted
19021d32ba66SJohn Wren Kennedy		grep "${disk}[sp]" /etc/mnttab >/dev/null
1903d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1904d583b39bSJohn Wren Kennedy	# Check for swap
19051d32ba66SJohn Wren Kennedy		grep "${disk}[sp]" $sfi >/dev/null
1906d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1907d583b39bSJohn Wren Kennedy	# check for dump device
19081d32ba66SJohn Wren Kennedy		grep "${disk}[sp]" $dmpi >/dev/null
1909d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1910d583b39bSJohn Wren Kennedy	# check to see if this disk hasn't been explicitly excluded
1911d583b39bSJohn Wren Kennedy	# by a user-set environment variable
19121d32ba66SJohn Wren Kennedy		echo "${ZFS_HOST_DEVICES_IGNORE}" | grep "${disk}" > /dev/null
1913d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1914d583b39bSJohn Wren Kennedy		unused_candidates="$unused_candidates $disk"
1915d583b39bSJohn Wren Kennedy	done
19161d32ba66SJohn Wren Kennedy	rm $sfi
19171d32ba66SJohn Wren Kennedy	rm $dmpi
1918d583b39bSJohn Wren Kennedy
1919d583b39bSJohn Wren Kennedy# now just check to see if those disks do actually exist
1920d583b39bSJohn Wren Kennedy# by looking for a device pointing to the first slice in
1921d583b39bSJohn Wren Kennedy# each case. limit the number to max_finddisksnum
1922d583b39bSJohn Wren Kennedy	count=0
1923d583b39bSJohn Wren Kennedy	for disk in $unused_candidates; do
1924d583b39bSJohn Wren Kennedy		if [ -b /dev/dsk/${disk}s0 ]; then
1925d583b39bSJohn Wren Kennedy		if [ $count -lt $max_finddisksnum ]; then
1926d583b39bSJohn Wren Kennedy			unused="$unused $disk"
1927d583b39bSJohn Wren Kennedy			# do not impose limit if $@ is provided
1928d583b39bSJohn Wren Kennedy			[[ -z $@ ]] && ((count = count + 1))
1929d583b39bSJohn Wren Kennedy		fi
1930d583b39bSJohn Wren Kennedy		fi
1931d583b39bSJohn Wren Kennedy	done
1932d583b39bSJohn Wren Kennedy
1933d583b39bSJohn Wren Kennedy# finally, return our disk list
19341d32ba66SJohn Wren Kennedy	echo $unused
1935d583b39bSJohn Wren Kennedy}
1936d583b39bSJohn Wren Kennedy
1937d583b39bSJohn Wren Kennedy#
1938d583b39bSJohn Wren Kennedy# Add specified user to specified group
1939d583b39bSJohn Wren Kennedy#
1940d583b39bSJohn Wren Kennedy# $1 group name
1941d583b39bSJohn Wren Kennedy# $2 user name
1942d583b39bSJohn Wren Kennedy# $3 base of the homedir (optional)
1943d583b39bSJohn Wren Kennedy#
1944d583b39bSJohn Wren Kennedyfunction add_user #<group_name> <user_name> <basedir>
1945d583b39bSJohn Wren Kennedy{
1946d583b39bSJohn Wren Kennedy	typeset gname=$1
1947d583b39bSJohn Wren Kennedy	typeset uname=$2
1948d583b39bSJohn Wren Kennedy	typeset basedir=${3:-"/var/tmp"}
1949d583b39bSJohn Wren Kennedy
1950d583b39bSJohn Wren Kennedy	if ((${#gname} == 0 || ${#uname} == 0)); then
1951d583b39bSJohn Wren Kennedy		log_fail "group name or user name are not defined."
1952d583b39bSJohn Wren Kennedy	fi
1953d583b39bSJohn Wren Kennedy
19541d32ba66SJohn Wren Kennedy	log_must useradd -g $gname -d $basedir/$uname -m $uname
195509b2abb4SIgor Kozhukhov	log_must passwd -N $uname
1956d583b39bSJohn Wren Kennedy
1957d583b39bSJohn Wren Kennedy	return 0
1958d583b39bSJohn Wren Kennedy}
1959d583b39bSJohn Wren Kennedy
1960d583b39bSJohn Wren Kennedy#
1961d583b39bSJohn Wren Kennedy# Delete the specified user.
1962d583b39bSJohn Wren Kennedy#
1963d583b39bSJohn Wren Kennedy# $1 login name
1964d583b39bSJohn Wren Kennedy# $2 base of the homedir (optional)
1965d583b39bSJohn Wren Kennedy#
1966d583b39bSJohn Wren Kennedyfunction del_user #<logname> <basedir>
1967d583b39bSJohn Wren Kennedy{
1968d583b39bSJohn Wren Kennedy	typeset user=$1
1969d583b39bSJohn Wren Kennedy	typeset basedir=${2:-"/var/tmp"}
1970d583b39bSJohn Wren Kennedy
1971d583b39bSJohn Wren Kennedy	if ((${#user} == 0)); then
1972d583b39bSJohn Wren Kennedy		log_fail "login name is necessary."
1973d583b39bSJohn Wren Kennedy	fi
1974d583b39bSJohn Wren Kennedy
19751d32ba66SJohn Wren Kennedy	if id $user > /dev/null 2>&1; then
19761d32ba66SJohn Wren Kennedy		log_must userdel $user
1977d583b39bSJohn Wren Kennedy	fi
1978d583b39bSJohn Wren Kennedy
19791d32ba66SJohn Wren Kennedy	[[ -d $basedir/$user ]] && rm -fr $basedir/$user
1980d583b39bSJohn Wren Kennedy
1981d583b39bSJohn Wren Kennedy	return 0
1982d583b39bSJohn Wren Kennedy}
1983d583b39bSJohn Wren Kennedy
1984d583b39bSJohn Wren Kennedy#
1985d583b39bSJohn Wren Kennedy# Select valid gid and create specified group.
1986d583b39bSJohn Wren Kennedy#
1987d583b39bSJohn Wren Kennedy# $1 group name
1988d583b39bSJohn Wren Kennedy#
1989d583b39bSJohn Wren Kennedyfunction add_group #<group_name>
1990d583b39bSJohn Wren Kennedy{
1991d583b39bSJohn Wren Kennedy	typeset group=$1
1992d583b39bSJohn Wren Kennedy
1993d583b39bSJohn Wren Kennedy	if ((${#group} == 0)); then
1994d583b39bSJohn Wren Kennedy		log_fail "group name is necessary."
1995d583b39bSJohn Wren Kennedy	fi
1996d583b39bSJohn Wren Kennedy
1997d583b39bSJohn Wren Kennedy	# Assign 100 as the base gid
1998d583b39bSJohn Wren Kennedy	typeset -i gid=100
1999d583b39bSJohn Wren Kennedy	while true; do
20001d32ba66SJohn Wren Kennedy		groupadd -g $gid $group > /dev/null 2>&1
2001d583b39bSJohn Wren Kennedy		typeset -i ret=$?
2002d583b39bSJohn Wren Kennedy		case $ret in
2003d583b39bSJohn Wren Kennedy			0) return 0 ;;
2004d583b39bSJohn Wren Kennedy			# The gid is not  unique
2005d583b39bSJohn Wren Kennedy			4) ((gid += 1)) ;;
2006d583b39bSJohn Wren Kennedy			*) return 1 ;;
2007d583b39bSJohn Wren Kennedy		esac
2008d583b39bSJohn Wren Kennedy	done
2009d583b39bSJohn Wren Kennedy}
2010d583b39bSJohn Wren Kennedy
2011d583b39bSJohn Wren Kennedy#
2012d583b39bSJohn Wren Kennedy# Delete the specified group.
2013d583b39bSJohn Wren Kennedy#
2014d583b39bSJohn Wren Kennedy# $1 group name
2015d583b39bSJohn Wren Kennedy#
2016d583b39bSJohn Wren Kennedyfunction del_group #<group_name>
2017d583b39bSJohn Wren Kennedy{
2018d583b39bSJohn Wren Kennedy	typeset grp=$1
2019d583b39bSJohn Wren Kennedy	if ((${#grp} == 0)); then
2020d583b39bSJohn Wren Kennedy		log_fail "group name is necessary."
2021d583b39bSJohn Wren Kennedy	fi
2022d583b39bSJohn Wren Kennedy
20231d32ba66SJohn Wren Kennedy	groupmod -n $grp $grp > /dev/null 2>&1
2024d583b39bSJohn Wren Kennedy	typeset -i ret=$?
2025d583b39bSJohn Wren Kennedy	case $ret in
2026d583b39bSJohn Wren Kennedy		# Group does not exist.
2027d583b39bSJohn Wren Kennedy		6) return 0 ;;
2028d583b39bSJohn Wren Kennedy		# Name already exists as a group name
20291d32ba66SJohn Wren Kennedy		9) log_must groupdel $grp ;;
2030d583b39bSJohn Wren Kennedy		*) return 1 ;;
2031d583b39bSJohn Wren Kennedy	esac
2032d583b39bSJohn Wren Kennedy
2033d583b39bSJohn Wren Kennedy	return 0
2034d583b39bSJohn Wren Kennedy}
2035d583b39bSJohn Wren Kennedy
2036d583b39bSJohn Wren Kennedy#
2037d583b39bSJohn Wren Kennedy# This function will return true if it's safe to destroy the pool passed
2038d583b39bSJohn Wren Kennedy# as argument 1. It checks for pools based on zvols and files, and also
2039d583b39bSJohn Wren Kennedy# files contained in a pool that may have a different mountpoint.
2040d583b39bSJohn Wren Kennedy#
2041d583b39bSJohn Wren Kennedyfunction safe_to_destroy_pool { # $1 the pool name
2042d583b39bSJohn Wren Kennedy
2043d583b39bSJohn Wren Kennedy	typeset pool=""
2044d583b39bSJohn Wren Kennedy	typeset DONT_DESTROY=""
2045d583b39bSJohn Wren Kennedy
2046d583b39bSJohn Wren Kennedy	# We check that by deleting the $1 pool, we're not
2047d583b39bSJohn Wren Kennedy	# going to pull the rug out from other pools. Do this
2048d583b39bSJohn Wren Kennedy	# by looking at all other pools, ensuring that they
2049d583b39bSJohn Wren Kennedy	# aren't built from files or zvols contained in this pool.
2050d583b39bSJohn Wren Kennedy
20511d32ba66SJohn Wren Kennedy	for pool in $(zpool list -H -o name)
2052d583b39bSJohn Wren Kennedy	do
2053d583b39bSJohn Wren Kennedy		ALTMOUNTPOOL=""
2054d583b39bSJohn Wren Kennedy
2055d583b39bSJohn Wren Kennedy		# this is a list of the top-level directories in each of the
2056d583b39bSJohn Wren Kennedy		# files that make up the path to the files the pool is based on
20571d32ba66SJohn Wren Kennedy		FILEPOOL=$(zpool status -v $pool | grep /$1/ | \
20581d32ba66SJohn Wren Kennedy			awk '{print $1}')
2059d583b39bSJohn Wren Kennedy
2060d583b39bSJohn Wren Kennedy		# this is a list of the zvols that make up the pool
20611d32ba66SJohn Wren Kennedy		ZVOLPOOL=$(zpool status -v $pool | grep "/dev/zvol/dsk/$1$" \
20621d32ba66SJohn Wren Kennedy		    | awk '{print $1}')
2063d583b39bSJohn Wren Kennedy
2064d583b39bSJohn Wren Kennedy		# also want to determine if it's a file-based pool using an
2065d583b39bSJohn Wren Kennedy		# alternate mountpoint...
20661d32ba66SJohn Wren Kennedy		POOL_FILE_DIRS=$(zpool status -v $pool | \
20671d32ba66SJohn Wren Kennedy					grep / | awk '{print $1}' | \
20681d32ba66SJohn Wren Kennedy					awk -F/ '{print $2}' | grep -v "dev")
2069d583b39bSJohn Wren Kennedy
2070d583b39bSJohn Wren Kennedy		for pooldir in $POOL_FILE_DIRS
2071d583b39bSJohn Wren Kennedy		do
20721d32ba66SJohn Wren Kennedy			OUTPUT=$(zfs list -H -r -o mountpoint $1 | \
20731d32ba66SJohn Wren Kennedy					grep "${pooldir}$" | awk '{print $1}')
2074d583b39bSJohn Wren Kennedy
2075d583b39bSJohn Wren Kennedy			ALTMOUNTPOOL="${ALTMOUNTPOOL}${OUTPUT}"
2076d583b39bSJohn Wren Kennedy		done
2077d583b39bSJohn Wren Kennedy
2078d583b39bSJohn Wren Kennedy
2079d583b39bSJohn Wren Kennedy		if [ ! -z "$ZVOLPOOL" ]
2080d583b39bSJohn Wren Kennedy		then
2081d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
2082d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $ZVOLPOOL on $1"
2083d583b39bSJohn Wren Kennedy		fi
2084d583b39bSJohn Wren Kennedy
2085d583b39bSJohn Wren Kennedy		if [ ! -z "$FILEPOOL" ]
2086d583b39bSJohn Wren Kennedy		then
2087d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
2088d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $FILEPOOL on $1"
2089d583b39bSJohn Wren Kennedy		fi
2090d583b39bSJohn Wren Kennedy
2091d583b39bSJohn Wren Kennedy		if [ ! -z "$ALTMOUNTPOOL" ]
2092d583b39bSJohn Wren Kennedy		then
2093d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
2094d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $ALTMOUNTPOOL on $1"
2095d583b39bSJohn Wren Kennedy		fi
2096d583b39bSJohn Wren Kennedy	done
2097d583b39bSJohn Wren Kennedy
2098d583b39bSJohn Wren Kennedy	if [ -z "${DONT_DESTROY}" ]
2099d583b39bSJohn Wren Kennedy	then
2100d583b39bSJohn Wren Kennedy		return 0
2101d583b39bSJohn Wren Kennedy	else
2102d583b39bSJohn Wren Kennedy		log_note "Warning: it is not safe to destroy $1!"
2103d583b39bSJohn Wren Kennedy		return 1
2104d583b39bSJohn Wren Kennedy	fi
2105d583b39bSJohn Wren Kennedy}
2106d583b39bSJohn Wren Kennedy
2107d583b39bSJohn Wren Kennedy#
2108d583b39bSJohn Wren Kennedy# Get the available ZFS compression options
2109d583b39bSJohn Wren Kennedy# $1 option type zfs_set|zfs_compress
2110d583b39bSJohn Wren Kennedy#
2111d583b39bSJohn Wren Kennedyfunction get_compress_opts
2112d583b39bSJohn Wren Kennedy{
2113d583b39bSJohn Wren Kennedy	typeset COMPRESS_OPTS
2114d583b39bSJohn Wren Kennedy	typeset GZIP_OPTS="gzip gzip-1 gzip-2 gzip-3 gzip-4 gzip-5 \
2115d583b39bSJohn Wren Kennedy			gzip-6 gzip-7 gzip-8 gzip-9"
2116d583b39bSJohn Wren Kennedy
2117d583b39bSJohn Wren Kennedy	if [[ $1 == "zfs_compress" ]] ; then
2118d583b39bSJohn Wren Kennedy		COMPRESS_OPTS="on lzjb"
2119d583b39bSJohn Wren Kennedy	elif [[ $1 == "zfs_set" ]] ; then
2120d583b39bSJohn Wren Kennedy		COMPRESS_OPTS="on off lzjb"
2121d583b39bSJohn Wren Kennedy	fi
2122d583b39bSJohn Wren Kennedy	typeset valid_opts="$COMPRESS_OPTS"
21231d32ba66SJohn Wren Kennedy	zfs get 2>&1 | grep gzip >/dev/null 2>&1
2124d583b39bSJohn Wren Kennedy	if [[ $? -eq 0 ]]; then
2125d583b39bSJohn Wren Kennedy		valid_opts="$valid_opts $GZIP_OPTS"
2126d583b39bSJohn Wren Kennedy	fi
21271d32ba66SJohn Wren Kennedy	echo "$valid_opts"
2128d583b39bSJohn Wren Kennedy}
2129d583b39bSJohn Wren Kennedy
2130d583b39bSJohn Wren Kennedy#
2131d583b39bSJohn Wren Kennedy# Verify zfs operation with -p option work as expected
2132d583b39bSJohn Wren Kennedy# $1 operation, value could be create, clone or rename
2133d583b39bSJohn Wren Kennedy# $2 dataset type, value could be fs or vol
2134d583b39bSJohn Wren Kennedy# $3 dataset name
2135d583b39bSJohn Wren Kennedy# $4 new dataset name
2136d583b39bSJohn Wren Kennedy#
2137d583b39bSJohn Wren Kennedyfunction verify_opt_p_ops
2138d583b39bSJohn Wren Kennedy{
2139d583b39bSJohn Wren Kennedy	typeset ops=$1
2140d583b39bSJohn Wren Kennedy	typeset datatype=$2
2141d583b39bSJohn Wren Kennedy	typeset dataset=$3
2142d583b39bSJohn Wren Kennedy	typeset newdataset=$4
2143d583b39bSJohn Wren Kennedy
2144d583b39bSJohn Wren Kennedy	if [[ $datatype != "fs" && $datatype != "vol" ]]; then
2145d583b39bSJohn Wren Kennedy		log_fail "$datatype is not supported."
2146d583b39bSJohn Wren Kennedy	fi
2147d583b39bSJohn Wren Kennedy
2148d583b39bSJohn Wren Kennedy	# check parameters accordingly
2149d583b39bSJohn Wren Kennedy	case $ops in
2150d583b39bSJohn Wren Kennedy		create)
2151d583b39bSJohn Wren Kennedy			newdataset=$dataset
2152d583b39bSJohn Wren Kennedy			dataset=""
2153d583b39bSJohn Wren Kennedy			if [[ $datatype == "vol" ]]; then
2154d583b39bSJohn Wren Kennedy				ops="create -V $VOLSIZE"
2155d583b39bSJohn Wren Kennedy			fi
2156d583b39bSJohn Wren Kennedy			;;
2157d583b39bSJohn Wren Kennedy		clone)
2158d583b39bSJohn Wren Kennedy			if [[ -z $newdataset ]]; then
2159d583b39bSJohn Wren Kennedy				log_fail "newdataset should not be empty" \
2160d583b39bSJohn Wren Kennedy					"when ops is $ops."
2161d583b39bSJohn Wren Kennedy			fi
2162d583b39bSJohn Wren Kennedy			log_must datasetexists $dataset
2163d583b39bSJohn Wren Kennedy			log_must snapexists $dataset
2164d583b39bSJohn Wren Kennedy			;;
2165d583b39bSJohn Wren Kennedy		rename)
2166d583b39bSJohn Wren Kennedy			if [[ -z $newdataset ]]; then
2167d583b39bSJohn Wren Kennedy				log_fail "newdataset should not be empty" \
2168d583b39bSJohn Wren Kennedy					"when ops is $ops."
2169d583b39bSJohn Wren Kennedy			fi
2170d583b39bSJohn Wren Kennedy			log_must datasetexists $dataset
2171d583b39bSJohn Wren Kennedy			log_mustnot snapexists $dataset
2172d583b39bSJohn Wren Kennedy			;;
2173d583b39bSJohn Wren Kennedy		*)
2174d583b39bSJohn Wren Kennedy			log_fail "$ops is not supported."
2175d583b39bSJohn Wren Kennedy			;;
2176d583b39bSJohn Wren Kennedy	esac
2177d583b39bSJohn Wren Kennedy
2178d583b39bSJohn Wren Kennedy	# make sure the upper level filesystem does not exist
2179d583b39bSJohn Wren Kennedy	if datasetexists ${newdataset%/*} ; then
21801d32ba66SJohn Wren Kennedy		log_must zfs destroy -rRf ${newdataset%/*}
2181d583b39bSJohn Wren Kennedy	fi
2182d583b39bSJohn Wren Kennedy
2183d583b39bSJohn Wren Kennedy	# without -p option, operation will fail
21841d32ba66SJohn Wren Kennedy	log_mustnot zfs $ops $dataset $newdataset
2185d583b39bSJohn Wren Kennedy	log_mustnot datasetexists $newdataset ${newdataset%/*}
2186d583b39bSJohn Wren Kennedy
2187d583b39bSJohn Wren Kennedy	# with -p option, operation should succeed
21881d32ba66SJohn Wren Kennedy	log_must zfs $ops -p $dataset $newdataset
2189d583b39bSJohn Wren Kennedy	if ! datasetexists $newdataset ; then
2190d583b39bSJohn Wren Kennedy		log_fail "-p option does not work for $ops"
2191d583b39bSJohn Wren Kennedy	fi
2192d583b39bSJohn Wren Kennedy
2193d583b39bSJohn Wren Kennedy	# when $ops is create or clone, redo the operation still return zero
2194d583b39bSJohn Wren Kennedy	if [[ $ops != "rename" ]]; then
21951d32ba66SJohn Wren Kennedy		log_must zfs $ops -p $dataset $newdataset
2196d583b39bSJohn Wren Kennedy	fi
2197d583b39bSJohn Wren Kennedy
2198d583b39bSJohn Wren Kennedy	return 0
2199d583b39bSJohn Wren Kennedy}
2200d583b39bSJohn Wren Kennedy
2201d583b39bSJohn Wren Kennedy#
2202d583b39bSJohn Wren Kennedy# Get configuration of pool
2203d583b39bSJohn Wren Kennedy# $1 pool name
2204d583b39bSJohn Wren Kennedy# $2 config name
2205d583b39bSJohn Wren Kennedy#
2206d583b39bSJohn Wren Kennedyfunction get_config
2207d583b39bSJohn Wren Kennedy{
2208d583b39bSJohn Wren Kennedy	typeset pool=$1
2209d583b39bSJohn Wren Kennedy	typeset config=$2
2210d583b39bSJohn Wren Kennedy	typeset alt_root
2211d583b39bSJohn Wren Kennedy
2212d583b39bSJohn Wren Kennedy	if ! poolexists "$pool" ; then
2213d583b39bSJohn Wren Kennedy		return 1
2214d583b39bSJohn Wren Kennedy	fi
22151d32ba66SJohn Wren Kennedy	alt_root=$(zpool list -H $pool | awk '{print $NF}')
2216d583b39bSJohn Wren Kennedy	if [[ $alt_root == "-" ]]; then
22171d32ba66SJohn Wren Kennedy		value=$(zdb -C $pool | grep "$config:" | awk -F: \
2218d583b39bSJohn Wren Kennedy		    '{print $2}')
2219d583b39bSJohn Wren Kennedy	else
22201d32ba66SJohn Wren Kennedy		value=$(zdb -e $pool | grep "$config:" | awk -F: \
2221d583b39bSJohn Wren Kennedy		    '{print $2}')
2222d583b39bSJohn Wren Kennedy	fi
2223d583b39bSJohn Wren Kennedy	if [[ -n $value ]] ; then
2224d583b39bSJohn Wren Kennedy		value=${value#'}
2225d583b39bSJohn Wren Kennedy		value=${value%'}
2226d583b39bSJohn Wren Kennedy	fi
2227d583b39bSJohn Wren Kennedy	echo $value
2228d583b39bSJohn Wren Kennedy
2229d583b39bSJohn Wren Kennedy	return 0
2230d583b39bSJohn Wren Kennedy}
2231d583b39bSJohn Wren Kennedy
2232d583b39bSJohn Wren Kennedy#
2233d583b39bSJohn Wren Kennedy# Privated function. Random select one of items from arguments.
2234d583b39bSJohn Wren Kennedy#
2235d583b39bSJohn Wren Kennedy# $1 count
2236d583b39bSJohn Wren Kennedy# $2-n string
2237d583b39bSJohn Wren Kennedy#
2238d583b39bSJohn Wren Kennedyfunction _random_get
2239d583b39bSJohn Wren Kennedy{
2240d583b39bSJohn Wren Kennedy	typeset cnt=$1
2241d583b39bSJohn Wren Kennedy	shift
2242d583b39bSJohn Wren Kennedy
2243d583b39bSJohn Wren Kennedy	typeset str="$@"
2244d583b39bSJohn Wren Kennedy	typeset -i ind
2245d583b39bSJohn Wren Kennedy	((ind = RANDOM % cnt + 1))
2246d583b39bSJohn Wren Kennedy
22471d32ba66SJohn Wren Kennedy	typeset ret=$(echo "$str" | cut -f $ind -d ' ')
22481d32ba66SJohn Wren Kennedy	echo $ret
2249d583b39bSJohn Wren Kennedy}
2250d583b39bSJohn Wren Kennedy
2251d583b39bSJohn Wren Kennedy#
2252d583b39bSJohn Wren Kennedy# Random select one of item from arguments which include NONE string
2253d583b39bSJohn Wren Kennedy#
2254d583b39bSJohn Wren Kennedyfunction random_get_with_non
2255d583b39bSJohn Wren Kennedy{
2256d583b39bSJohn Wren Kennedy	typeset -i cnt=$#
2257d583b39bSJohn Wren Kennedy	((cnt =+ 1))
2258d583b39bSJohn Wren Kennedy
2259d583b39bSJohn Wren Kennedy	_random_get "$cnt" "$@"
2260d583b39bSJohn Wren Kennedy}
2261d583b39bSJohn Wren Kennedy
2262d583b39bSJohn Wren Kennedy#
2263d583b39bSJohn Wren Kennedy# Random select one of item from arguments which doesn't include NONE string
2264d583b39bSJohn Wren Kennedy#
2265d583b39bSJohn Wren Kennedyfunction random_get
2266d583b39bSJohn Wren Kennedy{
2267d583b39bSJohn Wren Kennedy	_random_get "$#" "$@"
2268d583b39bSJohn Wren Kennedy}
2269d583b39bSJohn Wren Kennedy
2270d583b39bSJohn Wren Kennedy#
2271d583b39bSJohn Wren Kennedy# Detect if the current system support slog
2272d583b39bSJohn Wren Kennedy#
2273d583b39bSJohn Wren Kennedyfunction verify_slog_support
2274d583b39bSJohn Wren Kennedy{
2275d583b39bSJohn Wren Kennedy	typeset dir=/tmp/disk.$$
2276d583b39bSJohn Wren Kennedy	typeset pool=foo.$$
2277d583b39bSJohn Wren Kennedy	typeset vdev=$dir/a
2278d583b39bSJohn Wren Kennedy	typeset sdev=$dir/b
2279d583b39bSJohn Wren Kennedy
22801d32ba66SJohn Wren Kennedy	mkdir -p $dir
22811d32ba66SJohn Wren Kennedy	mkfile $MINVDEVSIZE $vdev $sdev
2282d583b39bSJohn Wren Kennedy
2283d583b39bSJohn Wren Kennedy	typeset -i ret=0
22841d32ba66SJohn Wren Kennedy	if ! zpool create -n $pool $vdev log $sdev > /dev/null 2>&1; then
2285d583b39bSJohn Wren Kennedy		ret=1
2286d583b39bSJohn Wren Kennedy	fi
22871d32ba66SJohn Wren Kennedy	rm -r $dir
2288d583b39bSJohn Wren Kennedy
2289d583b39bSJohn Wren Kennedy	return $ret
2290d583b39bSJohn Wren Kennedy}
2291d583b39bSJohn Wren Kennedy
2292d583b39bSJohn Wren Kennedy#
2293d583b39bSJohn Wren Kennedy# The function will generate a dataset name with specific length
2294d583b39bSJohn Wren Kennedy# $1, the length of the name
2295d583b39bSJohn Wren Kennedy# $2, the base string to construct the name
2296d583b39bSJohn Wren Kennedy#
2297d583b39bSJohn Wren Kennedyfunction gen_dataset_name
2298d583b39bSJohn Wren Kennedy{
2299d583b39bSJohn Wren Kennedy	typeset -i len=$1
2300d583b39bSJohn Wren Kennedy	typeset basestr="$2"
2301d583b39bSJohn Wren Kennedy	typeset -i baselen=${#basestr}
2302d583b39bSJohn Wren Kennedy	typeset -i iter=0
2303d583b39bSJohn Wren Kennedy	typeset l_name=""
2304d583b39bSJohn Wren Kennedy
2305d583b39bSJohn Wren Kennedy	if ((len % baselen == 0)); then
2306d583b39bSJohn Wren Kennedy		((iter = len / baselen))
2307d583b39bSJohn Wren Kennedy	else
2308d583b39bSJohn Wren Kennedy		((iter = len / baselen + 1))
2309d583b39bSJohn Wren Kennedy	fi
2310d583b39bSJohn Wren Kennedy	while ((iter > 0)); do
2311d583b39bSJohn Wren Kennedy		l_name="${l_name}$basestr"
2312d583b39bSJohn Wren Kennedy
2313d583b39bSJohn Wren Kennedy		((iter -= 1))
2314d583b39bSJohn Wren Kennedy	done
2315d583b39bSJohn Wren Kennedy
23161d32ba66SJohn Wren Kennedy	echo $l_name
2317d583b39bSJohn Wren Kennedy}
2318d583b39bSJohn Wren Kennedy
2319d583b39bSJohn Wren Kennedy#
2320d583b39bSJohn Wren Kennedy# Get cksum tuple of dataset
2321d583b39bSJohn Wren Kennedy# $1 dataset name
2322d583b39bSJohn Wren Kennedy#
2323d583b39bSJohn Wren Kennedy# sample zdb output:
2324d583b39bSJohn Wren Kennedy# Dataset data/test [ZPL], ID 355, cr_txg 2413856, 31.0K, 7 objects, rootbp
2325d583b39bSJohn Wren Kennedy# DVA[0]=<0:803046400:200> DVA[1]=<0:81199000:200> [L0 DMU objset] fletcher4
2326d583b39bSJohn Wren Kennedy# lzjb LE contiguous unique double size=800L/200P birth=2413856L/2413856P
2327d583b39bSJohn Wren Kennedy# fill=7 cksum=11ce125712:643a9c18ee2:125e25238fca0:254a3f74b59744
2328d583b39bSJohn Wren Kennedyfunction datasetcksum
2329d583b39bSJohn Wren Kennedy{
2330d583b39bSJohn Wren Kennedy	typeset cksum
23311d32ba66SJohn Wren Kennedy	sync
233209fbbb7dSAllan Jude	sync_all_pools
23331d32ba66SJohn Wren Kennedy	cksum=$(zdb -vvv $1 | grep "^Dataset $1 \[" | grep "cksum" \
23341d32ba66SJohn Wren Kennedy		| awk -F= '{print $7}')
23351d32ba66SJohn Wren Kennedy	echo $cksum
2336d583b39bSJohn Wren Kennedy}
2337d583b39bSJohn Wren Kennedy
2338d583b39bSJohn Wren Kennedy#
2339d583b39bSJohn Wren Kennedy# Get cksum of file
2340d583b39bSJohn Wren Kennedy# #1 file path
2341d583b39bSJohn Wren Kennedy#
2342d583b39bSJohn Wren Kennedyfunction checksum
2343d583b39bSJohn Wren Kennedy{
2344d583b39bSJohn Wren Kennedy	typeset cksum
23451d32ba66SJohn Wren Kennedy	cksum=$(cksum $1 | awk '{print $1}')
23461d32ba66SJohn Wren Kennedy	echo $cksum
2347d583b39bSJohn Wren Kennedy}
2348d583b39bSJohn Wren Kennedy
2349d583b39bSJohn Wren Kennedy#
2350d583b39bSJohn Wren Kennedy# Get the given disk/slice state from the specific field of the pool
2351d583b39bSJohn Wren Kennedy#
2352d583b39bSJohn Wren Kennedyfunction get_device_state #pool disk field("", "spares","logs")
2353d583b39bSJohn Wren Kennedy{
2354d583b39bSJohn Wren Kennedy	typeset pool=$1
2355d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
2356d583b39bSJohn Wren Kennedy	typeset field=${3:-$pool}
2357d583b39bSJohn Wren Kennedy
23581d32ba66SJohn Wren Kennedy	state=$(zpool status -v "$pool" 2>/dev/null | \
23591d32ba66SJohn Wren Kennedy		nawk -v device=$disk -v pool=$pool -v field=$field \
2360d583b39bSJohn Wren Kennedy		'BEGIN {startconfig=0; startfield=0; }
2361d583b39bSJohn Wren Kennedy		/config:/ {startconfig=1}
2362d583b39bSJohn Wren Kennedy		(startconfig==1) && ($1==field) {startfield=1; next;}
2363d583b39bSJohn Wren Kennedy		(startfield==1) && ($1==device) {print $2; exit;}
2364d583b39bSJohn Wren Kennedy		(startfield==1) &&
2365d583b39bSJohn Wren Kennedy		($1==field || $1 ~ "^spares$" || $1 ~ "^logs$") {startfield=0}')
2366d583b39bSJohn Wren Kennedy	echo $state
2367d583b39bSJohn Wren Kennedy}
2368d583b39bSJohn Wren Kennedy
2369d583b39bSJohn Wren Kennedy
2370d583b39bSJohn Wren Kennedy#
2371d583b39bSJohn Wren Kennedy# print the given directory filesystem type
2372d583b39bSJohn Wren Kennedy#
2373d583b39bSJohn Wren Kennedy# $1 directory name
2374d583b39bSJohn Wren Kennedy#
2375d583b39bSJohn Wren Kennedyfunction get_fstype
2376d583b39bSJohn Wren Kennedy{
2377d583b39bSJohn Wren Kennedy	typeset dir=$1
2378d583b39bSJohn Wren Kennedy
2379d583b39bSJohn Wren Kennedy	if [[ -z $dir ]]; then
2380d583b39bSJohn Wren Kennedy		log_fail "Usage: get_fstype <directory>"
2381d583b39bSJohn Wren Kennedy	fi
2382d583b39bSJohn Wren Kennedy
2383d583b39bSJohn Wren Kennedy	#
2384d583b39bSJohn Wren Kennedy	#  $ df -n /
2385d583b39bSJohn Wren Kennedy	#  /		  : ufs
2386d583b39bSJohn Wren Kennedy	#
23871d32ba66SJohn Wren Kennedy	df -n $dir | awk '{print $3}'
2388d583b39bSJohn Wren Kennedy}
2389d583b39bSJohn Wren Kennedy
2390d583b39bSJohn Wren Kennedy#
2391d583b39bSJohn Wren Kennedy# Given a disk, label it to VTOC regardless what label was on the disk
2392d583b39bSJohn Wren Kennedy# $1 disk
2393d583b39bSJohn Wren Kennedy#
2394d583b39bSJohn Wren Kennedyfunction labelvtoc
2395d583b39bSJohn Wren Kennedy{
2396d583b39bSJohn Wren Kennedy	typeset disk=$1
2397d583b39bSJohn Wren Kennedy	if [[ -z $disk ]]; then
2398d583b39bSJohn Wren Kennedy		log_fail "The disk name is unspecified."
2399d583b39bSJohn Wren Kennedy	fi
2400d583b39bSJohn Wren Kennedy	typeset label_file=/var/tmp/labelvtoc.$$
24011d32ba66SJohn Wren Kennedy	typeset arch=$(uname -p)
2402d583b39bSJohn Wren Kennedy
2403d583b39bSJohn Wren Kennedy	if [[ $arch == "i386" ]]; then
24041d32ba66SJohn Wren Kennedy		echo "label" > $label_file
24051d32ba66SJohn Wren Kennedy		echo "0" >> $label_file
24061d32ba66SJohn Wren Kennedy		echo "" >> $label_file
24071d32ba66SJohn Wren Kennedy		echo "q" >> $label_file
24081d32ba66SJohn Wren Kennedy		echo "q" >> $label_file
2409d583b39bSJohn Wren Kennedy
24101d32ba66SJohn Wren Kennedy		fdisk -B $disk >/dev/null 2>&1
2411d583b39bSJohn Wren Kennedy		# wait a while for fdisk finishes
24121d32ba66SJohn Wren Kennedy		sleep 60
2413d583b39bSJohn Wren Kennedy	elif [[ $arch == "sparc" ]]; then
24141d32ba66SJohn Wren Kennedy		echo "label" > $label_file
24151d32ba66SJohn Wren Kennedy		echo "0" >> $label_file
24161d32ba66SJohn Wren Kennedy		echo "" >> $label_file
24171d32ba66SJohn Wren Kennedy		echo "" >> $label_file
24181d32ba66SJohn Wren Kennedy		echo "" >> $label_file
24191d32ba66SJohn Wren Kennedy		echo "q" >> $label_file
2420d583b39bSJohn Wren Kennedy	else
2421d583b39bSJohn Wren Kennedy		log_fail "unknown arch type"
2422d583b39bSJohn Wren Kennedy	fi
2423d583b39bSJohn Wren Kennedy
24241d32ba66SJohn Wren Kennedy	format -e -s -d $disk -f $label_file
2425d583b39bSJohn Wren Kennedy	typeset -i ret_val=$?
24261d32ba66SJohn Wren Kennedy	rm -f $label_file
2427d583b39bSJohn Wren Kennedy	#
2428d583b39bSJohn Wren Kennedy	# wait the format to finish
2429d583b39bSJohn Wren Kennedy	#
24301d32ba66SJohn Wren Kennedy	sleep 60
2431d583b39bSJohn Wren Kennedy	if ((ret_val != 0)); then
2432d583b39bSJohn Wren Kennedy		log_fail "unable to label $disk as VTOC."
2433d583b39bSJohn Wren Kennedy	fi
2434d583b39bSJohn Wren Kennedy
2435d583b39bSJohn Wren Kennedy	return 0
2436d583b39bSJohn Wren Kennedy}
2437d583b39bSJohn Wren Kennedy
2438d583b39bSJohn Wren Kennedy#
2439d583b39bSJohn Wren Kennedy# check if the system was installed as zfsroot or not
2440d583b39bSJohn Wren Kennedy# return: 0 ture, otherwise false
2441d583b39bSJohn Wren Kennedy#
2442d583b39bSJohn Wren Kennedyfunction is_zfsroot
2443d583b39bSJohn Wren Kennedy{
24441d32ba66SJohn Wren Kennedy	df -n / | grep zfs > /dev/null 2>&1
2445d583b39bSJohn Wren Kennedy	return $?
2446d583b39bSJohn Wren Kennedy}
2447d583b39bSJohn Wren Kennedy
2448d583b39bSJohn Wren Kennedy#
2449d583b39bSJohn Wren Kennedy# get the root filesystem name if it's zfsroot system.
2450d583b39bSJohn Wren Kennedy#
2451d583b39bSJohn Wren Kennedy# return: root filesystem name
2452d583b39bSJohn Wren Kennedyfunction get_rootfs
2453d583b39bSJohn Wren Kennedy{
2454d583b39bSJohn Wren Kennedy	typeset rootfs=""
24551d32ba66SJohn Wren Kennedy	rootfs=$(awk '{if ($2 == "/" && $3 == "zfs") print $1}' \
2456d583b39bSJohn Wren Kennedy		/etc/mnttab)
2457d583b39bSJohn Wren Kennedy	if [[ -z "$rootfs" ]]; then
2458d583b39bSJohn Wren Kennedy		log_fail "Can not get rootfs"
2459d583b39bSJohn Wren Kennedy	fi
24601d32ba66SJohn Wren Kennedy	zfs list $rootfs > /dev/null 2>&1
2461d583b39bSJohn Wren Kennedy	if (($? == 0)); then
24621d32ba66SJohn Wren Kennedy		echo $rootfs
2463d583b39bSJohn Wren Kennedy	else
2464d583b39bSJohn Wren Kennedy		log_fail "This is not a zfsroot system."
2465d583b39bSJohn Wren Kennedy	fi
2466d583b39bSJohn Wren Kennedy}
2467d583b39bSJohn Wren Kennedy
2468d583b39bSJohn Wren Kennedy#
2469d583b39bSJohn Wren Kennedy# get the rootfs's pool name
2470d583b39bSJohn Wren Kennedy# return:
2471d583b39bSJohn Wren Kennedy#       rootpool name
2472d583b39bSJohn Wren Kennedy#
2473d583b39bSJohn Wren Kennedyfunction get_rootpool
2474d583b39bSJohn Wren Kennedy{
2475d583b39bSJohn Wren Kennedy	typeset rootfs=""
2476d583b39bSJohn Wren Kennedy	typeset rootpool=""
24771d32ba66SJohn Wren Kennedy	rootfs=$(awk '{if ($2 == "/" && $3 =="zfs") print $1}' \
2478d583b39bSJohn Wren Kennedy		 /etc/mnttab)
2479d583b39bSJohn Wren Kennedy	if [[ -z "$rootfs" ]]; then
2480d583b39bSJohn Wren Kennedy		log_fail "Can not get rootpool"
2481d583b39bSJohn Wren Kennedy	fi
24821d32ba66SJohn Wren Kennedy	zfs list $rootfs > /dev/null 2>&1
2483d583b39bSJohn Wren Kennedy	if (($? == 0)); then
24841d32ba66SJohn Wren Kennedy		rootpool=`echo $rootfs | awk -F\/ '{print $1}'`
24851d32ba66SJohn Wren Kennedy		echo $rootpool
2486d583b39bSJohn Wren Kennedy	else
2487d583b39bSJohn Wren Kennedy		log_fail "This is not a zfsroot system."
2488d583b39bSJohn Wren Kennedy	fi
2489d583b39bSJohn Wren Kennedy}
2490d583b39bSJohn Wren Kennedy
2491d583b39bSJohn Wren Kennedy#
2492d583b39bSJohn Wren Kennedy# Check if the given device is physical device
2493d583b39bSJohn Wren Kennedy#
2494d583b39bSJohn Wren Kennedyfunction is_physical_device #device
2495d583b39bSJohn Wren Kennedy{
2496d583b39bSJohn Wren Kennedy	typeset device=${1#/dev/dsk/}
2497d583b39bSJohn Wren Kennedy	device=${device#/dev/rdsk/}
2498d583b39bSJohn Wren Kennedy
24991d32ba66SJohn Wren Kennedy	echo $device | egrep "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
2500d583b39bSJohn Wren Kennedy	return $?
2501d583b39bSJohn Wren Kennedy}
2502d583b39bSJohn Wren Kennedy
2503d583b39bSJohn Wren Kennedy#
2504d583b39bSJohn Wren Kennedy# Get the directory path of given device
2505d583b39bSJohn Wren Kennedy#
2506d583b39bSJohn Wren Kennedyfunction get_device_dir #device
2507d583b39bSJohn Wren Kennedy{
2508d583b39bSJohn Wren Kennedy	typeset device=$1
2509d583b39bSJohn Wren Kennedy
2510d583b39bSJohn Wren Kennedy	if ! $(is_physical_device $device) ; then
2511d583b39bSJohn Wren Kennedy		if [[ $device != "/" ]]; then
2512d583b39bSJohn Wren Kennedy			device=${device%/*}
2513d583b39bSJohn Wren Kennedy		fi
25141d32ba66SJohn Wren Kennedy		echo $device
2515d583b39bSJohn Wren Kennedy	else
25161d32ba66SJohn Wren Kennedy		echo "/dev/dsk"
2517d583b39bSJohn Wren Kennedy	fi
2518d583b39bSJohn Wren Kennedy}
2519d583b39bSJohn Wren Kennedy
2520d583b39bSJohn Wren Kennedy#
2521d583b39bSJohn Wren Kennedy# Get the package name
2522d583b39bSJohn Wren Kennedy#
2523d583b39bSJohn Wren Kennedyfunction get_package_name
2524d583b39bSJohn Wren Kennedy{
2525d583b39bSJohn Wren Kennedy	typeset dirpath=${1:-$STC_NAME}
2526d583b39bSJohn Wren Kennedy
2527d583b39bSJohn Wren Kennedy	echo "SUNWstc-${dirpath}" | /usr/bin/sed -e "s/\//-/g"
2528d583b39bSJohn Wren Kennedy}
2529d583b39bSJohn Wren Kennedy
2530d583b39bSJohn Wren Kennedy#
2531d583b39bSJohn Wren Kennedy# Get the word numbers from a string separated by white space
2532d583b39bSJohn Wren Kennedy#
2533d583b39bSJohn Wren Kennedyfunction get_word_count
2534d583b39bSJohn Wren Kennedy{
25351d32ba66SJohn Wren Kennedy	echo $1 | wc -w
2536d583b39bSJohn Wren Kennedy}
2537d583b39bSJohn Wren Kennedy
2538d583b39bSJohn Wren Kennedy#
2539d583b39bSJohn Wren Kennedy# To verify if the require numbers of disks is given
2540d583b39bSJohn Wren Kennedy#
2541d583b39bSJohn Wren Kennedyfunction verify_disk_count
2542d583b39bSJohn Wren Kennedy{
2543d583b39bSJohn Wren Kennedy	typeset -i min=${2:-1}
2544d583b39bSJohn Wren Kennedy
2545d583b39bSJohn Wren Kennedy	typeset -i count=$(get_word_count "$1")
2546d583b39bSJohn Wren Kennedy
2547d583b39bSJohn Wren Kennedy	if ((count < min)); then
2548d583b39bSJohn Wren Kennedy		log_untested "A minimum of $min disks is required to run." \
2549d583b39bSJohn Wren Kennedy			" You specified $count disk(s)"
2550d583b39bSJohn Wren Kennedy	fi
2551d583b39bSJohn Wren Kennedy}
2552d583b39bSJohn Wren Kennedy
2553d583b39bSJohn Wren Kennedyfunction ds_is_volume
2554d583b39bSJohn Wren Kennedy{
2555d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2556d583b39bSJohn Wren Kennedy	[[ $type = "volume" ]] && return 0
2557d583b39bSJohn Wren Kennedy	return 1
2558d583b39bSJohn Wren Kennedy}
2559d583b39bSJohn Wren Kennedy
2560d583b39bSJohn Wren Kennedyfunction ds_is_filesystem
2561d583b39bSJohn Wren Kennedy{
2562d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2563d583b39bSJohn Wren Kennedy	[[ $type = "filesystem" ]] && return 0
2564d583b39bSJohn Wren Kennedy	return 1
2565d583b39bSJohn Wren Kennedy}
2566d583b39bSJohn Wren Kennedy
2567d583b39bSJohn Wren Kennedyfunction ds_is_snapshot
2568d583b39bSJohn Wren Kennedy{
2569d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2570d583b39bSJohn Wren Kennedy	[[ $type = "snapshot" ]] && return 0
2571d583b39bSJohn Wren Kennedy	return 1
2572d583b39bSJohn Wren Kennedy}
2573d583b39bSJohn Wren Kennedy
2574d583b39bSJohn Wren Kennedy#
2575d583b39bSJohn Wren Kennedy# Check if Trusted Extensions are installed and enabled
2576d583b39bSJohn Wren Kennedy#
2577d583b39bSJohn Wren Kennedyfunction is_te_enabled
2578d583b39bSJohn Wren Kennedy{
25791d32ba66SJohn Wren Kennedy	svcs -H -o state labeld 2>/dev/null | grep "enabled"
2580d583b39bSJohn Wren Kennedy	if (($? != 0)); then
2581d583b39bSJohn Wren Kennedy		return 1
2582d583b39bSJohn Wren Kennedy	else
2583d583b39bSJohn Wren Kennedy		return 0
2584d583b39bSJohn Wren Kennedy	fi
2585d583b39bSJohn Wren Kennedy}
2586f38cb554SJohn Wren Kennedy
2587f38cb554SJohn Wren Kennedy# Utility function to determine if a system has multiple cpus.
2588f38cb554SJohn Wren Kennedyfunction is_mp
2589f38cb554SJohn Wren Kennedy{
25901d32ba66SJohn Wren Kennedy	(($(psrinfo | wc -l) > 1))
2591f38cb554SJohn Wren Kennedy}
2592f38cb554SJohn Wren Kennedy
259345818ee1SMatthew Ahrensfunction get_cpu_freq
259445818ee1SMatthew Ahrens{
25951d32ba66SJohn Wren Kennedy	psrinfo -v 0 | awk '/processor operates at/ {print $6}'
259645818ee1SMatthew Ahrens}
259745818ee1SMatthew Ahrens
2598f38cb554SJohn Wren Kennedy# Run the given command as the user provided.
2599f38cb554SJohn Wren Kennedyfunction user_run
2600f38cb554SJohn Wren Kennedy{
2601f38cb554SJohn Wren Kennedy	typeset user=$1
2602f38cb554SJohn Wren Kennedy	shift
2603f38cb554SJohn Wren Kennedy
26041d32ba66SJohn Wren Kennedy	eval su \$user -c \"$@\" > /tmp/out 2>/tmp/err
2605f38cb554SJohn Wren Kennedy	return $?
2606f38cb554SJohn Wren Kennedy}
260752244c09SJohn Wren Kennedy
260852244c09SJohn Wren Kennedy#
260952244c09SJohn Wren Kennedy# Check if the pool contains the specified vdevs
261052244c09SJohn Wren Kennedy#
261152244c09SJohn Wren Kennedy# $1 pool
261252244c09SJohn Wren Kennedy# $2..n <vdev> ...
261352244c09SJohn Wren Kennedy#
261452244c09SJohn Wren Kennedy# Return 0 if the vdevs are contained in the pool, 1 if any of the specified
261552244c09SJohn Wren Kennedy# vdevs is not in the pool, and 2 if pool name is missing.
261652244c09SJohn Wren Kennedy#
261752244c09SJohn Wren Kennedyfunction vdevs_in_pool
261852244c09SJohn Wren Kennedy{
261952244c09SJohn Wren Kennedy	typeset pool=$1
262052244c09SJohn Wren Kennedy	typeset vdev
262152244c09SJohn Wren Kennedy
262252244c09SJohn Wren Kennedy        if [[ -z $pool ]]; then
262352244c09SJohn Wren Kennedy                log_note "Missing pool name."
262452244c09SJohn Wren Kennedy                return 2
262552244c09SJohn Wren Kennedy        fi
262652244c09SJohn Wren Kennedy
262752244c09SJohn Wren Kennedy	shift
262852244c09SJohn Wren Kennedy
26291d32ba66SJohn Wren Kennedy	typeset tmpfile=$(mktemp)
26301d32ba66SJohn Wren Kennedy	zpool list -Hv "$pool" >$tmpfile
263152244c09SJohn Wren Kennedy	for vdev in $@; do
26321d32ba66SJohn Wren Kennedy		grep -w ${vdev##*/} $tmpfile >/dev/null 2>&1
263352244c09SJohn Wren Kennedy		[[ $? -ne 0 ]] && return 1
263452244c09SJohn Wren Kennedy	done
263552244c09SJohn Wren Kennedy
26361d32ba66SJohn Wren Kennedy	rm -f $tmpfile
263752244c09SJohn Wren Kennedy
263852244c09SJohn Wren Kennedy	return 0;
263952244c09SJohn Wren Kennedy}
2640dcbf3bd6SGeorge Wilson
2641dcbf3bd6SGeorge Wilsonfunction get_max
2642dcbf3bd6SGeorge Wilson{
2643dcbf3bd6SGeorge Wilson	typeset -l i max=$1
2644dcbf3bd6SGeorge Wilson	shift
2645dcbf3bd6SGeorge Wilson
2646dcbf3bd6SGeorge Wilson	for i in "$@"; do
2647dcbf3bd6SGeorge Wilson		max=$(echo $((max > i ? max : i)))
2648dcbf3bd6SGeorge Wilson	done
2649dcbf3bd6SGeorge Wilson
2650dcbf3bd6SGeorge Wilson	echo $max
2651dcbf3bd6SGeorge Wilson}
2652dcbf3bd6SGeorge Wilson
2653dcbf3bd6SGeorge Wilsonfunction get_min
2654dcbf3bd6SGeorge Wilson{
2655dcbf3bd6SGeorge Wilson	typeset -l i min=$1
2656dcbf3bd6SGeorge Wilson	shift
2657dcbf3bd6SGeorge Wilson
2658dcbf3bd6SGeorge Wilson	for i in "$@"; do
2659dcbf3bd6SGeorge Wilson		min=$(echo $((min < i ? min : i)))
2660dcbf3bd6SGeorge Wilson	done
2661dcbf3bd6SGeorge Wilson
2662dcbf3bd6SGeorge Wilson	echo $min
2663dcbf3bd6SGeorge Wilson}
26645602294fSDan Kimmel
26655602294fSDan Kimmel#
26665602294fSDan Kimmel# Generate a random number between 1 and the argument.
26675602294fSDan Kimmel#
26685602294fSDan Kimmelfunction random
26695602294fSDan Kimmel{
26705602294fSDan Kimmel        typeset max=$1
26715602294fSDan Kimmel        echo $(( ($RANDOM % $max) + 1 ))
26725602294fSDan Kimmel}
26735602294fSDan Kimmel
26745602294fSDan Kimmel# Write data that can be compressed into a directory
26755602294fSDan Kimmelfunction write_compressible
26765602294fSDan Kimmel{
26775602294fSDan Kimmel	typeset dir=$1
26785602294fSDan Kimmel	typeset megs=$2
26795602294fSDan Kimmel	typeset nfiles=${3:-1}
26805602294fSDan Kimmel	typeset bs=${4:-1024k}
26815602294fSDan Kimmel	typeset fname=${5:-file}
26825602294fSDan Kimmel
26835602294fSDan Kimmel	[[ -d $dir ]] || log_fail "No directory: $dir"
26845602294fSDan Kimmel
26855602294fSDan Kimmel	log_must eval "fio \
26865602294fSDan Kimmel	    --name=job \
26875602294fSDan Kimmel	    --fallocate=0 \
26885602294fSDan Kimmel	    --minimal \
26895602294fSDan Kimmel	    --randrepeat=0 \
26905602294fSDan Kimmel	    --buffer_compress_percentage=66 \
26915602294fSDan Kimmel	    --buffer_compress_chunk=4096 \
26925602294fSDan Kimmel	    --directory=$dir \
26935602294fSDan Kimmel	    --numjobs=$nfiles \
26945602294fSDan Kimmel	    --rw=write \
26955602294fSDan Kimmel	    --bs=$bs \
26965602294fSDan Kimmel	    --filesize=$megs \
26975602294fSDan Kimmel	    --filename_format='$fname.\$jobnum' >/dev/null"
26985602294fSDan Kimmel}
26995602294fSDan Kimmel
27005602294fSDan Kimmelfunction get_objnum
27015602294fSDan Kimmel{
27025602294fSDan Kimmel	typeset pathname=$1
27035602294fSDan Kimmel	typeset objnum
27045602294fSDan Kimmel
27055602294fSDan Kimmel	[[ -e $pathname ]] || log_fail "No such file or directory: $pathname"
27065602294fSDan Kimmel	objnum=$(stat -c %i $pathname)
27075602294fSDan Kimmel	echo $objnum
27089c2acf00SAlek Pinchuk}
27099c2acf00SAlek Pinchuk
27109c2acf00SAlek Pinchuk#
27119c2acf00SAlek Pinchuk# Sync data to the pool
27129c2acf00SAlek Pinchuk#
27139c2acf00SAlek Pinchuk# $1 pool name
27149c2acf00SAlek Pinchuk# $2 boolean to force uberblock (and config including zpool cache file) update
27159c2acf00SAlek Pinchuk#
27169c2acf00SAlek Pinchukfunction sync_pool #pool <force>
27179c2acf00SAlek Pinchuk{
27189c2acf00SAlek Pinchuk	typeset pool=${1:-$TESTPOOL}
27199c2acf00SAlek Pinchuk	typeset force=${2:-false}
27209c2acf00SAlek Pinchuk
27219c2acf00SAlek Pinchuk	if [[ $force == true ]]; then
27229c2acf00SAlek Pinchuk		log_must zpool sync -f $pool
27239c2acf00SAlek Pinchuk	else
27249c2acf00SAlek Pinchuk		log_must zpool sync $pool
27259c2acf00SAlek Pinchuk	fi
27269c2acf00SAlek Pinchuk
27279c2acf00SAlek Pinchuk	return 0
27285602294fSDan Kimmel}
27295cabbc6bSPrashanth Sreenivasa
273009fbbb7dSAllan Jude#
273109fbbb7dSAllan Jude# Sync all pools
273209fbbb7dSAllan Jude#
273309fbbb7dSAllan Jude# $1 boolean to force uberblock (and config including zpool cache file) update
273409fbbb7dSAllan Jude#
273509fbbb7dSAllan Judefunction sync_all_pools #<force>
273609fbbb7dSAllan Jude{
273709fbbb7dSAllan Jude	typeset force=${1:-false}
273809fbbb7dSAllan Jude
273909fbbb7dSAllan Jude	if [[ $force == true ]]; then
274009fbbb7dSAllan Jude		log_must zpool sync -f
274109fbbb7dSAllan Jude	else
274209fbbb7dSAllan Jude		log_must zpool sync
274309fbbb7dSAllan Jude	fi
274409fbbb7dSAllan Jude
274509fbbb7dSAllan Jude	return 0
274609fbbb7dSAllan Jude}
274709fbbb7dSAllan Jude
27485cabbc6bSPrashanth Sreenivasa#
27495cabbc6bSPrashanth Sreenivasa# Prints the current time in seconds since UNIX Epoch.
27505cabbc6bSPrashanth Sreenivasa#
27515cabbc6bSPrashanth Sreenivasafunction current_epoch
27525cabbc6bSPrashanth Sreenivasa{
27535cabbc6bSPrashanth Sreenivasa	printf '%(%s)T'
27545cabbc6bSPrashanth Sreenivasa}
27555cabbc6bSPrashanth Sreenivasa
27565cabbc6bSPrashanth Sreenivasa#
27575cabbc6bSPrashanth Sreenivasa# Get decimal value of global uint32_t variable using mdb.
27585cabbc6bSPrashanth Sreenivasa#
27595cabbc6bSPrashanth Sreenivasafunction mdb_get_uint32
27605cabbc6bSPrashanth Sreenivasa{
27615cabbc6bSPrashanth Sreenivasa	typeset variable=$1
27625cabbc6bSPrashanth Sreenivasa	typeset value
27635cabbc6bSPrashanth Sreenivasa
27645cabbc6bSPrashanth Sreenivasa	value=$(mdb -k -e "$variable/X | ::eval .=U")
27655cabbc6bSPrashanth Sreenivasa	if [[ $? -ne 0 ]]; then
27665cabbc6bSPrashanth Sreenivasa		log_fail "Failed to get value of '$variable' from mdb."
27675cabbc6bSPrashanth Sreenivasa		return 1
27685cabbc6bSPrashanth Sreenivasa	fi
27695cabbc6bSPrashanth Sreenivasa
27705cabbc6bSPrashanth Sreenivasa	echo $value
27715cabbc6bSPrashanth Sreenivasa	return 0
27725cabbc6bSPrashanth Sreenivasa}
27735cabbc6bSPrashanth Sreenivasa
27745711d393Sloli#
27755711d393Sloli# Wait for every device replace operation to complete
27765711d393Sloli#
27775711d393Sloli# $1 pool name
27785711d393Sloli#
27795711d393Slolifunction wait_replacing #pool
27805711d393Sloli{
27815711d393Sloli	typeset pool=${1:-$TESTPOOL}
27825711d393Sloli	while true; do
27835711d393Sloli		[[ "" == "$(zpool status $pool |
27845711d393Sloli		    awk '/replacing-[0-9]+/ {print $1}')" ]] && break
27855711d393Sloli		log_must sleep 1
27865711d393Sloli	done
27875711d393Sloli}
27885711d393Sloli
27895cabbc6bSPrashanth Sreenivasa#
27905cabbc6bSPrashanth Sreenivasa# Set global uint32_t variable to a decimal value using mdb.
27915cabbc6bSPrashanth Sreenivasa#
27925cabbc6bSPrashanth Sreenivasafunction mdb_set_uint32
27935cabbc6bSPrashanth Sreenivasa{
27945cabbc6bSPrashanth Sreenivasa	typeset variable=$1
27955cabbc6bSPrashanth Sreenivasa	typeset value=$2
27965cabbc6bSPrashanth Sreenivasa
27975cabbc6bSPrashanth Sreenivasa	mdb -kw -e "$variable/W 0t$value" > /dev/null
27985cabbc6bSPrashanth Sreenivasa	if [[ $? -ne 0 ]]; then
27995cabbc6bSPrashanth Sreenivasa		echo "Failed to set '$variable' to '$value' in mdb."
28005cabbc6bSPrashanth Sreenivasa		return 1
28015cabbc6bSPrashanth Sreenivasa	fi
28025cabbc6bSPrashanth Sreenivasa
28035cabbc6bSPrashanth Sreenivasa	return 0
28045cabbc6bSPrashanth Sreenivasa}
280586714001SSerapheim Dimitropoulos
280686714001SSerapheim Dimitropoulos#
280786714001SSerapheim Dimitropoulos# Set global scalar integer variable to a hex value using mdb.
280886714001SSerapheim Dimitropoulos# Note: Target should have CTF data loaded.
280986714001SSerapheim Dimitropoulos#
281086714001SSerapheim Dimitropoulosfunction mdb_ctf_set_int
281186714001SSerapheim Dimitropoulos{
281286714001SSerapheim Dimitropoulos	typeset variable=$1
281386714001SSerapheim Dimitropoulos	typeset value=$2
281486714001SSerapheim Dimitropoulos
281586714001SSerapheim Dimitropoulos	mdb -kw -e "$variable/z $value" > /dev/null
281686714001SSerapheim Dimitropoulos	if [[ $? -ne 0 ]]; then
281786714001SSerapheim Dimitropoulos		echo "Failed to set '$variable' to '$value' in mdb."
281886714001SSerapheim Dimitropoulos		return 1
281986714001SSerapheim Dimitropoulos	fi
282086714001SSerapheim Dimitropoulos
282186714001SSerapheim Dimitropoulos	return 0
282286714001SSerapheim Dimitropoulos}
2823e0f1c0afSOlaf Faaland
2824e0f1c0afSOlaf Faaland#
2825e0f1c0afSOlaf Faaland# Set a global system tunable (64-bit value)
2826e0f1c0afSOlaf Faaland#
2827e0f1c0afSOlaf Faaland# $1 tunable name
2828e0f1c0afSOlaf Faaland# $2 tunable values
2829e0f1c0afSOlaf Faaland#
2830e0f1c0afSOlaf Faalandfunction set_tunable64
2831e0f1c0afSOlaf Faaland{
2832e0f1c0afSOlaf Faaland	set_tunable_impl "$1" "$2" Z
2833e0f1c0afSOlaf Faaland}
2834e0f1c0afSOlaf Faaland
2835e0f1c0afSOlaf Faaland#
2836e0f1c0afSOlaf Faaland# Set a global system tunable (32-bit value)
2837e0f1c0afSOlaf Faaland#
2838e0f1c0afSOlaf Faaland# $1 tunable name
2839e0f1c0afSOlaf Faaland# $2 tunable values
2840e0f1c0afSOlaf Faaland#
2841e0f1c0afSOlaf Faalandfunction set_tunable32
2842e0f1c0afSOlaf Faaland{
2843e0f1c0afSOlaf Faaland	set_tunable_impl "$1" "$2" W
2844e0f1c0afSOlaf Faaland}
2845e0f1c0afSOlaf Faaland
2846e0f1c0afSOlaf Faalandfunction set_tunable_impl
2847e0f1c0afSOlaf Faaland{
2848e0f1c0afSOlaf Faaland	typeset tunable="$1"
2849e0f1c0afSOlaf Faaland	typeset value="$2"
2850e0f1c0afSOlaf Faaland	typeset mdb_cmd="$3"
2851e0f1c0afSOlaf Faaland	typeset module="${4:-zfs}"
2852e0f1c0afSOlaf Faaland
2853e0f1c0afSOlaf Faaland	[[ -z "$tunable" ]] && return 1
2854e0f1c0afSOlaf Faaland	[[ -z "$value" ]] && return 1
2855e0f1c0afSOlaf Faaland	[[ -z "$mdb_cmd" ]] && return 1
2856e0f1c0afSOlaf Faaland
2857e0f1c0afSOlaf Faaland	case "$(uname)" in
2858e0f1c0afSOlaf Faaland	Linux)
2859e0f1c0afSOlaf Faaland		typeset zfs_tunables="/sys/module/$module/parameters"
2860e0f1c0afSOlaf Faaland		[[ -w "$zfs_tunables/$tunable" ]] || return 1
28614348eb90SOlaf Faaland		cat >"$zfs_tunables/$tunable" <<<"$value"
28624348eb90SOlaf Faaland		return $?
2863e0f1c0afSOlaf Faaland		;;
2864e0f1c0afSOlaf Faaland	SunOS)
2865e0f1c0afSOlaf Faaland		[[ "$module" -eq "zfs" ]] || return 1
2866e0f1c0afSOlaf Faaland		echo "${tunable}/${mdb_cmd}0t${value}" | mdb -kw
28674348eb90SOlaf Faaland		return $?
2868e0f1c0afSOlaf Faaland		;;
2869e0f1c0afSOlaf Faaland	esac
2870e0f1c0afSOlaf Faaland}
2871e0f1c0afSOlaf Faaland
2872e0f1c0afSOlaf Faaland#
2873e0f1c0afSOlaf Faaland# Get a global system tunable
2874e0f1c0afSOlaf Faaland#
2875e0f1c0afSOlaf Faaland# $1 tunable name
2876e0f1c0afSOlaf Faaland#
2877e0f1c0afSOlaf Faalandfunction get_tunable
2878e0f1c0afSOlaf Faaland{
2879e0f1c0afSOlaf Faaland	get_tunable_impl "$1"
2880e0f1c0afSOlaf Faaland}
2881e0f1c0afSOlaf Faaland
2882e0f1c0afSOlaf Faalandfunction get_tunable_impl
2883e0f1c0afSOlaf Faaland{
2884e0f1c0afSOlaf Faaland	typeset tunable="$1"
2885e0f1c0afSOlaf Faaland	typeset module="${2:-zfs}"
2886e0f1c0afSOlaf Faaland
2887e0f1c0afSOlaf Faaland	[[ -z "$tunable" ]] && return 1
2888e0f1c0afSOlaf Faaland
2889e0f1c0afSOlaf Faaland	case "$(uname)" in
2890e0f1c0afSOlaf Faaland	Linux)
2891e0f1c0afSOlaf Faaland		typeset zfs_tunables="/sys/module/$module/parameters"
2892e0f1c0afSOlaf Faaland		[[ -f "$zfs_tunables/$tunable" ]] || return 1
2893e0f1c0afSOlaf Faaland		cat $zfs_tunables/$tunable
28944348eb90SOlaf Faaland		return $?
2895e0f1c0afSOlaf Faaland		;;
2896e0f1c0afSOlaf Faaland	SunOS)
2897e0f1c0afSOlaf Faaland		typeset value=$(mdb -k -e "$tunable/X | ::eval .=U")
2898e0f1c0afSOlaf Faaland		if [[ $? -ne 0 ]]; then
2899e0f1c0afSOlaf Faaland			log_fail "Failed to get value of '$tunable' from mdb."
2900e0f1c0afSOlaf Faaland			return 1
2901e0f1c0afSOlaf Faaland		fi
2902e0f1c0afSOlaf Faaland		echo $value
2903e0f1c0afSOlaf Faaland		return 0
2904e0f1c0afSOlaf Faaland		;;
2905e0f1c0afSOlaf Faaland	esac
2906e0f1c0afSOlaf Faaland
2907e0f1c0afSOlaf Faaland	return 1
2908e0f1c0afSOlaf Faaland}
2909d8849d7dSChunwei Chen
29109e3493cbSJason King#
29119e3493cbSJason King# Wait for the specified arcstat to reach non-zero quiescence.
29129e3493cbSJason King# If echo is 1 echo the value after reaching quiescence, otherwise
29139e3493cbSJason King# if echo is 0 print the arcstat we are waiting on.
29149e3493cbSJason King#
29159e3493cbSJason Kingfunction arcstat_quiescence # stat echo
29169e3493cbSJason King{
29179e3493cbSJason King	typeset stat=$1
29189e3493cbSJason King	typeset echo=$2
29199e3493cbSJason King	typeset do_once=true
29209e3493cbSJason King
29219e3493cbSJason King	if [[ $echo -eq 0 ]]; then
29229e3493cbSJason King		echo "Waiting for arcstat $1 quiescence."
29239e3493cbSJason King	fi
29249e3493cbSJason King
29259e3493cbSJason King	while $do_once || [ $stat1 -ne $stat2 ] || [ $stat2 -eq 0 ]; do
29269e3493cbSJason King		typeset stat1=$(get_arcstat $stat)
29279e3493cbSJason King		sleep 2
29289e3493cbSJason King		typeset stat2=$(get_arcstat $stat)
29299e3493cbSJason King		do_once=false
29309e3493cbSJason King	done
29319e3493cbSJason King
29329e3493cbSJason King	if [[ $echo -eq 1 ]]; then
29339e3493cbSJason King		echo $stat2
29349e3493cbSJason King	fi
29359e3493cbSJason King}
29369e3493cbSJason King
29379e3493cbSJason Kingfunction arcstat_quiescence_noecho # stat
29389e3493cbSJason King{
29399e3493cbSJason King	typeset stat=$1
29409e3493cbSJason King	arcstat_quiescence $stat 0
29419e3493cbSJason King}
29429e3493cbSJason King
29439e3493cbSJason Kingfunction arcstat_quiescence_echo # stat
29449e3493cbSJason King{
29459e3493cbSJason King	typeset stat=$1
29469e3493cbSJason King	arcstat_quiescence $stat 1
29479e3493cbSJason King}
29489e3493cbSJason King
2949d8849d7dSChunwei Chen#
2950d8849d7dSChunwei Chen# Compute SHA256 digest for given file or stdin if no file given.
2951d8849d7dSChunwei Chen# Note: file path must not contain spaces
2952d8849d7dSChunwei Chen#
2953d8849d7dSChunwei Chenfunction sha256digest
2954d8849d7dSChunwei Chen{
2955d8849d7dSChunwei Chen        typeset file=$1
2956d8849d7dSChunwei Chen
2957d8849d7dSChunwei Chen	if [ -x /usr/bin/digest ]; then
2958d8849d7dSChunwei Chen		/usr/bin/digest -a sha256 $file
2959d8849d7dSChunwei Chen	elif [ -x /usr/bin/sha256sum ]; then
2960d8849d7dSChunwei Chen		/usr/bin/sha256sum -b $file | awk '{ print $1 }'
2961d8849d7dSChunwei Chen	else
2962d8849d7dSChunwei Chen		echo "Cannot calculate SHA256 digest"
2963d8849d7dSChunwei Chen		return 1
2964d8849d7dSChunwei Chen	fi
2965d8849d7dSChunwei Chen	return 0
2966d8849d7dSChunwei Chen}
2967f0a05239SGeorge Amanakis
2968f0a05239SGeorge Amanakisfunction get_arcstat # stat
2969f0a05239SGeorge Amanakis{
2970f0a05239SGeorge Amanakis	if is_linux; then
2971f0a05239SGeorge Amanakis		typeset stat=$1
2972f0a05239SGeorge Amanakis		typeset zfs_arcstats="/proc/spl/kstat/zfs/arcstats"
2973f0a05239SGeorge Amanakis		[[ -f "$zfs_arcstats" ]] || return 1
2974f0a05239SGeorge Amanakis		grep $stat $zfs_arcstats | awk '{print $3}'
2975f0a05239SGeorge Amanakis		return $?
2976f0a05239SGeorge Amanakis	else
2977f0a05239SGeorge Amanakis		kstat -p zfs::arcstats:$1 | awk '{ print $2 }'
2978f0a05239SGeorge Amanakis		return $?
2979f0a05239SGeorge Amanakis	fi
2980f0a05239SGeorge Amanakis}
2981