xref: /titanic_54/usr/src/test/zfs-tests/include/libtest.shlib (revision d583b39bfb4e2571d3e41097c5c357ffe353ad45)
1*d583b39bSJohn Wren Kennedy#
2*d583b39bSJohn Wren Kennedy# CDDL HEADER START
3*d583b39bSJohn Wren Kennedy#
4*d583b39bSJohn Wren Kennedy# The contents of this file are subject to the terms of the
5*d583b39bSJohn Wren Kennedy# Common Development and Distribution License (the "License").
6*d583b39bSJohn Wren Kennedy# You may not use this file except in compliance with the License.
7*d583b39bSJohn Wren Kennedy#
8*d583b39bSJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d583b39bSJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing.
10*d583b39bSJohn Wren Kennedy# See the License for the specific language governing permissions
11*d583b39bSJohn Wren Kennedy# and limitations under the License.
12*d583b39bSJohn Wren Kennedy#
13*d583b39bSJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each
14*d583b39bSJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d583b39bSJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the
16*d583b39bSJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying
17*d583b39bSJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner]
18*d583b39bSJohn Wren Kennedy#
19*d583b39bSJohn Wren Kennedy# CDDL HEADER END
20*d583b39bSJohn Wren Kennedy#
21*d583b39bSJohn Wren Kennedy
22*d583b39bSJohn Wren Kennedy#
23*d583b39bSJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*d583b39bSJohn Wren Kennedy# Use is subject to license terms.
25*d583b39bSJohn Wren Kennedy#
26*d583b39bSJohn Wren Kennedy
27*d583b39bSJohn Wren Kennedy#
28*d583b39bSJohn Wren Kennedy# Copyright (c) 2012 by Delphix. All rights reserved.
29*d583b39bSJohn Wren Kennedy#
30*d583b39bSJohn Wren Kennedy
31*d583b39bSJohn Wren Kennedy. ${STF_TOOLS}/contrib/include/logapi.shlib
32*d583b39bSJohn Wren Kennedy
33*d583b39bSJohn Wren KennedyZFS=${ZFS:-/usr/sbin/zfs}
34*d583b39bSJohn Wren KennedyZPOOL=${ZPOOL:-/usr/sbin/zpool}
35*d583b39bSJohn Wren Kennedy
36*d583b39bSJohn Wren Kennedy# Determine whether a dataset is mounted
37*d583b39bSJohn Wren Kennedy#
38*d583b39bSJohn Wren Kennedy# $1 dataset name
39*d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
40*d583b39bSJohn Wren Kennedy#
41*d583b39bSJohn Wren Kennedy# Return 0 if dataset is mounted; 1 if unmounted; 2 on error
42*d583b39bSJohn Wren Kennedy
43*d583b39bSJohn Wren Kennedyfunction ismounted
44*d583b39bSJohn Wren Kennedy{
45*d583b39bSJohn Wren Kennedy	typeset fstype=$2
46*d583b39bSJohn Wren Kennedy	[[ -z $fstype ]] && fstype=zfs
47*d583b39bSJohn Wren Kennedy	typeset out dir name ret
48*d583b39bSJohn Wren Kennedy
49*d583b39bSJohn Wren Kennedy	case $fstype in
50*d583b39bSJohn Wren Kennedy		zfs)
51*d583b39bSJohn Wren Kennedy			if [[ "$1" == "/"* ]] ; then
52*d583b39bSJohn Wren Kennedy				for out in $($ZFS mount | $AWK '{print $2}'); do
53*d583b39bSJohn Wren Kennedy					[[ $1 == $out ]] && return 0
54*d583b39bSJohn Wren Kennedy				done
55*d583b39bSJohn Wren Kennedy			else
56*d583b39bSJohn Wren Kennedy				for out in $($ZFS mount | $AWK '{print $1}'); do
57*d583b39bSJohn Wren Kennedy					[[ $1 == $out ]] && return 0
58*d583b39bSJohn Wren Kennedy				done
59*d583b39bSJohn Wren Kennedy			fi
60*d583b39bSJohn Wren Kennedy		;;
61*d583b39bSJohn Wren Kennedy		ufs|nfs)
62*d583b39bSJohn Wren Kennedy			out=$($DF -F $fstype $1 2>/dev/null)
63*d583b39bSJohn Wren Kennedy			ret=$?
64*d583b39bSJohn Wren Kennedy			(($ret != 0)) && return $ret
65*d583b39bSJohn Wren Kennedy
66*d583b39bSJohn Wren Kennedy			dir=${out%%\(*}
67*d583b39bSJohn Wren Kennedy			dir=${dir%% *}
68*d583b39bSJohn Wren Kennedy			name=${out##*\(}
69*d583b39bSJohn Wren Kennedy			name=${name%%\)*}
70*d583b39bSJohn Wren Kennedy			name=${name%% *}
71*d583b39bSJohn Wren Kennedy
72*d583b39bSJohn Wren Kennedy			[[ "$1" == "$dir" || "$1" == "$name" ]] && return 0
73*d583b39bSJohn Wren Kennedy		;;
74*d583b39bSJohn Wren Kennedy	esac
75*d583b39bSJohn Wren Kennedy
76*d583b39bSJohn Wren Kennedy	return 1
77*d583b39bSJohn Wren Kennedy}
78*d583b39bSJohn Wren Kennedy
79*d583b39bSJohn Wren Kennedy# Return 0 if a dataset is mounted; 1 otherwise
80*d583b39bSJohn Wren Kennedy#
81*d583b39bSJohn Wren Kennedy# $1 dataset name
82*d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
83*d583b39bSJohn Wren Kennedy
84*d583b39bSJohn Wren Kennedyfunction mounted
85*d583b39bSJohn Wren Kennedy{
86*d583b39bSJohn Wren Kennedy	ismounted $1 $2
87*d583b39bSJohn Wren Kennedy	(($? == 0)) && return 0
88*d583b39bSJohn Wren Kennedy	return 1
89*d583b39bSJohn Wren Kennedy}
90*d583b39bSJohn Wren Kennedy
91*d583b39bSJohn Wren Kennedy# Return 0 if a dataset is unmounted; 1 otherwise
92*d583b39bSJohn Wren Kennedy#
93*d583b39bSJohn Wren Kennedy# $1 dataset name
94*d583b39bSJohn Wren Kennedy# $2 filesystem type; optional - defaulted to zfs
95*d583b39bSJohn Wren Kennedy
96*d583b39bSJohn Wren Kennedyfunction unmounted
97*d583b39bSJohn Wren Kennedy{
98*d583b39bSJohn Wren Kennedy	ismounted $1 $2
99*d583b39bSJohn Wren Kennedy	(($? == 1)) && return 0
100*d583b39bSJohn Wren Kennedy	return 1
101*d583b39bSJohn Wren Kennedy}
102*d583b39bSJohn Wren Kennedy
103*d583b39bSJohn Wren Kennedy# split line on ","
104*d583b39bSJohn Wren Kennedy#
105*d583b39bSJohn Wren Kennedy# $1 - line to split
106*d583b39bSJohn Wren Kennedy
107*d583b39bSJohn Wren Kennedyfunction splitline
108*d583b39bSJohn Wren Kennedy{
109*d583b39bSJohn Wren Kennedy	$ECHO $1 | $SED "s/,/ /g"
110*d583b39bSJohn Wren Kennedy}
111*d583b39bSJohn Wren Kennedy
112*d583b39bSJohn Wren Kennedyfunction default_setup
113*d583b39bSJohn Wren Kennedy{
114*d583b39bSJohn Wren Kennedy	default_setup_noexit "$@"
115*d583b39bSJohn Wren Kennedy
116*d583b39bSJohn Wren Kennedy	log_pass
117*d583b39bSJohn Wren Kennedy}
118*d583b39bSJohn Wren Kennedy
119*d583b39bSJohn Wren Kennedy#
120*d583b39bSJohn Wren Kennedy# Given a list of disks, setup storage pools and datasets.
121*d583b39bSJohn Wren Kennedy#
122*d583b39bSJohn Wren Kennedyfunction default_setup_noexit
123*d583b39bSJohn Wren Kennedy{
124*d583b39bSJohn Wren Kennedy	typeset disklist=$1
125*d583b39bSJohn Wren Kennedy	typeset container=$2
126*d583b39bSJohn Wren Kennedy	typeset volume=$3
127*d583b39bSJohn Wren Kennedy
128*d583b39bSJohn Wren Kennedy	if is_global_zone; then
129*d583b39bSJohn Wren Kennedy		if poolexists $TESTPOOL ; then
130*d583b39bSJohn Wren Kennedy			destroy_pool $TESTPOOL
131*d583b39bSJohn Wren Kennedy		fi
132*d583b39bSJohn Wren Kennedy		[[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL
133*d583b39bSJohn Wren Kennedy		log_must $ZPOOL create -f $TESTPOOL $disklist
134*d583b39bSJohn Wren Kennedy	else
135*d583b39bSJohn Wren Kennedy		reexport_pool
136*d583b39bSJohn Wren Kennedy	fi
137*d583b39bSJohn Wren Kennedy
138*d583b39bSJohn Wren Kennedy	$RM -rf $TESTDIR  || log_unresolved Could not remove $TESTDIR
139*d583b39bSJohn Wren Kennedy	$MKDIR -p $TESTDIR || log_unresolved Could not create $TESTDIR
140*d583b39bSJohn Wren Kennedy
141*d583b39bSJohn Wren Kennedy	log_must $ZFS create $TESTPOOL/$TESTFS
142*d583b39bSJohn Wren Kennedy	log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
143*d583b39bSJohn Wren Kennedy
144*d583b39bSJohn Wren Kennedy	if [[ -n $container ]]; then
145*d583b39bSJohn Wren Kennedy		$RM -rf $TESTDIR1  || \
146*d583b39bSJohn Wren Kennedy			log_unresolved Could not remove $TESTDIR1
147*d583b39bSJohn Wren Kennedy		$MKDIR -p $TESTDIR1 || \
148*d583b39bSJohn Wren Kennedy			log_unresolved Could not create $TESTDIR1
149*d583b39bSJohn Wren Kennedy
150*d583b39bSJohn Wren Kennedy		log_must $ZFS create $TESTPOOL/$TESTCTR
151*d583b39bSJohn Wren Kennedy		log_must $ZFS set canmount=off $TESTPOOL/$TESTCTR
152*d583b39bSJohn Wren Kennedy		log_must $ZFS create $TESTPOOL/$TESTCTR/$TESTFS1
153*d583b39bSJohn Wren Kennedy		log_must $ZFS set mountpoint=$TESTDIR1 \
154*d583b39bSJohn Wren Kennedy		    $TESTPOOL/$TESTCTR/$TESTFS1
155*d583b39bSJohn Wren Kennedy	fi
156*d583b39bSJohn Wren Kennedy
157*d583b39bSJohn Wren Kennedy	if [[ -n $volume ]]; then
158*d583b39bSJohn Wren Kennedy		if is_global_zone ; then
159*d583b39bSJohn Wren Kennedy			log_must $ZFS create -V $VOLSIZE $TESTPOOL/$TESTVOL
160*d583b39bSJohn Wren Kennedy		else
161*d583b39bSJohn Wren Kennedy			log_must $ZFS create $TESTPOOL/$TESTVOL
162*d583b39bSJohn Wren Kennedy		fi
163*d583b39bSJohn Wren Kennedy	fi
164*d583b39bSJohn Wren Kennedy}
165*d583b39bSJohn Wren Kennedy
166*d583b39bSJohn Wren Kennedy#
167*d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool, file system and
168*d583b39bSJohn Wren Kennedy# a container.
169*d583b39bSJohn Wren Kennedy#
170*d583b39bSJohn Wren Kennedyfunction default_container_setup
171*d583b39bSJohn Wren Kennedy{
172*d583b39bSJohn Wren Kennedy	typeset disklist=$1
173*d583b39bSJohn Wren Kennedy
174*d583b39bSJohn Wren Kennedy	default_setup "$disklist" "true"
175*d583b39bSJohn Wren Kennedy}
176*d583b39bSJohn Wren Kennedy
177*d583b39bSJohn Wren Kennedy#
178*d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool,file system
179*d583b39bSJohn Wren Kennedy# and a volume.
180*d583b39bSJohn Wren Kennedy#
181*d583b39bSJohn Wren Kennedyfunction default_volume_setup
182*d583b39bSJohn Wren Kennedy{
183*d583b39bSJohn Wren Kennedy	typeset disklist=$1
184*d583b39bSJohn Wren Kennedy
185*d583b39bSJohn Wren Kennedy	default_setup "$disklist" "" "true"
186*d583b39bSJohn Wren Kennedy}
187*d583b39bSJohn Wren Kennedy
188*d583b39bSJohn Wren Kennedy#
189*d583b39bSJohn Wren Kennedy# Given a list of disks, setup a storage pool,file system,
190*d583b39bSJohn Wren Kennedy# a container and a volume.
191*d583b39bSJohn Wren Kennedy#
192*d583b39bSJohn Wren Kennedyfunction default_container_volume_setup
193*d583b39bSJohn Wren Kennedy{
194*d583b39bSJohn Wren Kennedy	typeset disklist=$1
195*d583b39bSJohn Wren Kennedy
196*d583b39bSJohn Wren Kennedy	default_setup "$disklist" "true" "true"
197*d583b39bSJohn Wren Kennedy}
198*d583b39bSJohn Wren Kennedy
199*d583b39bSJohn Wren Kennedy#
200*d583b39bSJohn Wren Kennedy# Create a snapshot on a filesystem or volume. Defaultly create a snapshot on
201*d583b39bSJohn Wren Kennedy# filesystem
202*d583b39bSJohn Wren Kennedy#
203*d583b39bSJohn Wren Kennedy# $1 Existing filesystem or volume name. Default, $TESTFS
204*d583b39bSJohn Wren Kennedy# $2 snapshot name. Default, $TESTSNAP
205*d583b39bSJohn Wren Kennedy#
206*d583b39bSJohn Wren Kennedyfunction create_snapshot
207*d583b39bSJohn Wren Kennedy{
208*d583b39bSJohn Wren Kennedy	typeset fs_vol=${1:-$TESTFS}
209*d583b39bSJohn Wren Kennedy	typeset snap=${2:-$TESTSNAP}
210*d583b39bSJohn Wren Kennedy
211*d583b39bSJohn Wren Kennedy	[[ -z $fs_vol ]] && log_fail "Filesystem or volume's name is undefined."
212*d583b39bSJohn Wren Kennedy	[[ -z $snap ]] && log_fail "Snapshot's name is undefined."
213*d583b39bSJohn Wren Kennedy
214*d583b39bSJohn Wren Kennedy	if snapexists $fs_vol@$snap; then
215*d583b39bSJohn Wren Kennedy		log_fail "$fs_vol@$snap already exists."
216*d583b39bSJohn Wren Kennedy	fi
217*d583b39bSJohn Wren Kennedy	datasetexists $fs_vol || \
218*d583b39bSJohn Wren Kennedy		log_fail "$fs_vol must exist."
219*d583b39bSJohn Wren Kennedy
220*d583b39bSJohn Wren Kennedy	log_must $ZFS snapshot $fs_vol@$snap
221*d583b39bSJohn Wren Kennedy}
222*d583b39bSJohn Wren Kennedy
223*d583b39bSJohn Wren Kennedy#
224*d583b39bSJohn Wren Kennedy# Create a clone from a snapshot, default clone name is $TESTCLONE.
225*d583b39bSJohn Wren Kennedy#
226*d583b39bSJohn Wren Kennedy# $1 Existing snapshot, $TESTPOOL/$TESTFS@$TESTSNAP is default.
227*d583b39bSJohn Wren Kennedy# $2 Clone name, $TESTPOOL/$TESTCLONE is default.
228*d583b39bSJohn Wren Kennedy#
229*d583b39bSJohn Wren Kennedyfunction create_clone   # snapshot clone
230*d583b39bSJohn Wren Kennedy{
231*d583b39bSJohn Wren Kennedy	typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
232*d583b39bSJohn Wren Kennedy	typeset clone=${2:-$TESTPOOL/$TESTCLONE}
233*d583b39bSJohn Wren Kennedy
234*d583b39bSJohn Wren Kennedy	[[ -z $snap ]] && \
235*d583b39bSJohn Wren Kennedy		log_fail "Snapshot name is undefined."
236*d583b39bSJohn Wren Kennedy	[[ -z $clone ]] && \
237*d583b39bSJohn Wren Kennedy		log_fail "Clone name is undefined."
238*d583b39bSJohn Wren Kennedy
239*d583b39bSJohn Wren Kennedy	log_must $ZFS clone $snap $clone
240*d583b39bSJohn Wren Kennedy}
241*d583b39bSJohn Wren Kennedy
242*d583b39bSJohn Wren Kennedyfunction default_mirror_setup
243*d583b39bSJohn Wren Kennedy{
244*d583b39bSJohn Wren Kennedy	default_mirror_setup_noexit $1 $2 $3
245*d583b39bSJohn Wren Kennedy
246*d583b39bSJohn Wren Kennedy	log_pass
247*d583b39bSJohn Wren Kennedy}
248*d583b39bSJohn Wren Kennedy
249*d583b39bSJohn Wren Kennedy#
250*d583b39bSJohn Wren Kennedy# Given a pair of disks, set up a storage pool and dataset for the mirror
251*d583b39bSJohn Wren Kennedy# @parameters: $1 the primary side of the mirror
252*d583b39bSJohn Wren Kennedy#   $2 the secondary side of the mirror
253*d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL TESTFS
254*d583b39bSJohn Wren Kennedyfunction default_mirror_setup_noexit
255*d583b39bSJohn Wren Kennedy{
256*d583b39bSJohn Wren Kennedy	readonly func="default_mirror_setup_noexit"
257*d583b39bSJohn Wren Kennedy	typeset primary=$1
258*d583b39bSJohn Wren Kennedy	typeset secondary=$2
259*d583b39bSJohn Wren Kennedy
260*d583b39bSJohn Wren Kennedy	[[ -z $primary ]] && \
261*d583b39bSJohn Wren Kennedy		log_fail "$func: No parameters passed"
262*d583b39bSJohn Wren Kennedy	[[ -z $secondary ]] && \
263*d583b39bSJohn Wren Kennedy		log_fail "$func: No secondary partition passed"
264*d583b39bSJohn Wren Kennedy	[[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL
265*d583b39bSJohn Wren Kennedy	log_must $ZPOOL create -f $TESTPOOL mirror $@
266*d583b39bSJohn Wren Kennedy	log_must $ZFS create $TESTPOOL/$TESTFS
267*d583b39bSJohn Wren Kennedy	log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
268*d583b39bSJohn Wren Kennedy}
269*d583b39bSJohn Wren Kennedy
270*d583b39bSJohn Wren Kennedy#
271*d583b39bSJohn Wren Kennedy# create a number of mirrors.
272*d583b39bSJohn Wren Kennedy# We create a number($1) of 2 way mirrors using the pairs of disks named
273*d583b39bSJohn Wren Kennedy# on the command line. These mirrors are *not* mounted
274*d583b39bSJohn Wren Kennedy# @parameters: $1 the number of mirrors to create
275*d583b39bSJohn Wren Kennedy#  $... the devices to use to create the mirrors on
276*d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
277*d583b39bSJohn Wren Kennedyfunction setup_mirrors
278*d583b39bSJohn Wren Kennedy{
279*d583b39bSJohn Wren Kennedy	typeset -i nmirrors=$1
280*d583b39bSJohn Wren Kennedy
281*d583b39bSJohn Wren Kennedy	shift
282*d583b39bSJohn Wren Kennedy	while ((nmirrors > 0)); do
283*d583b39bSJohn Wren Kennedy		log_must test -n "$1" -a -n "$2"
284*d583b39bSJohn Wren Kennedy		[[ -d /$TESTPOOL$nmirrors ]] && $RM -rf /$TESTPOOL$nmirrors
285*d583b39bSJohn Wren Kennedy		log_must $ZPOOL create -f $TESTPOOL$nmirrors mirror $1 $2
286*d583b39bSJohn Wren Kennedy		shift 2
287*d583b39bSJohn Wren Kennedy		((nmirrors = nmirrors - 1))
288*d583b39bSJohn Wren Kennedy	done
289*d583b39bSJohn Wren Kennedy}
290*d583b39bSJohn Wren Kennedy
291*d583b39bSJohn Wren Kennedy#
292*d583b39bSJohn Wren Kennedy# create a number of raidz pools.
293*d583b39bSJohn Wren Kennedy# We create a number($1) of 2 raidz pools  using the pairs of disks named
294*d583b39bSJohn Wren Kennedy# on the command line. These pools are *not* mounted
295*d583b39bSJohn Wren Kennedy# @parameters: $1 the number of pools to create
296*d583b39bSJohn Wren Kennedy#  $... the devices to use to create the pools on
297*d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
298*d583b39bSJohn Wren Kennedyfunction setup_raidzs
299*d583b39bSJohn Wren Kennedy{
300*d583b39bSJohn Wren Kennedy	typeset -i nraidzs=$1
301*d583b39bSJohn Wren Kennedy
302*d583b39bSJohn Wren Kennedy	shift
303*d583b39bSJohn Wren Kennedy	while ((nraidzs > 0)); do
304*d583b39bSJohn Wren Kennedy		log_must test -n "$1" -a -n "$2"
305*d583b39bSJohn Wren Kennedy		[[ -d /$TESTPOOL$nraidzs ]] && $RM -rf /$TESTPOOL$nraidzs
306*d583b39bSJohn Wren Kennedy		log_must $ZPOOL create -f $TESTPOOL$nraidzs raidz $1 $2
307*d583b39bSJohn Wren Kennedy		shift 2
308*d583b39bSJohn Wren Kennedy		((nraidzs = nraidzs - 1))
309*d583b39bSJohn Wren Kennedy	done
310*d583b39bSJohn Wren Kennedy}
311*d583b39bSJohn Wren Kennedy
312*d583b39bSJohn Wren Kennedy#
313*d583b39bSJohn Wren Kennedy# Destroy the configured testpool mirrors.
314*d583b39bSJohn Wren Kennedy# the mirrors are of the form ${TESTPOOL}{number}
315*d583b39bSJohn Wren Kennedy# @uses: ZPOOL ZFS TESTPOOL
316*d583b39bSJohn Wren Kennedyfunction destroy_mirrors
317*d583b39bSJohn Wren Kennedy{
318*d583b39bSJohn Wren Kennedy	default_cleanup_noexit
319*d583b39bSJohn Wren Kennedy
320*d583b39bSJohn Wren Kennedy	log_pass
321*d583b39bSJohn Wren Kennedy}
322*d583b39bSJohn Wren Kennedy
323*d583b39bSJohn Wren Kennedy#
324*d583b39bSJohn Wren Kennedy# Given a minimum of two disks, set up a storage pool and dataset for the raid-z
325*d583b39bSJohn Wren Kennedy# $1 the list of disks
326*d583b39bSJohn Wren Kennedy#
327*d583b39bSJohn Wren Kennedyfunction default_raidz_setup
328*d583b39bSJohn Wren Kennedy{
329*d583b39bSJohn Wren Kennedy	typeset disklist="$*"
330*d583b39bSJohn Wren Kennedy	disks=(${disklist[*]})
331*d583b39bSJohn Wren Kennedy
332*d583b39bSJohn Wren Kennedy	if [[ ${#disks[*]} -lt 2 ]]; then
333*d583b39bSJohn Wren Kennedy		log_fail "A raid-z requires a minimum of two disks."
334*d583b39bSJohn Wren Kennedy	fi
335*d583b39bSJohn Wren Kennedy
336*d583b39bSJohn Wren Kennedy	[[ -d /$TESTPOOL ]] && $RM -rf /$TESTPOOL
337*d583b39bSJohn Wren Kennedy	log_must $ZPOOL create -f $TESTPOOL raidz $1 $2 $3
338*d583b39bSJohn Wren Kennedy	log_must $ZFS create $TESTPOOL/$TESTFS
339*d583b39bSJohn Wren Kennedy	log_must $ZFS set mountpoint=$TESTDIR $TESTPOOL/$TESTFS
340*d583b39bSJohn Wren Kennedy
341*d583b39bSJohn Wren Kennedy	log_pass
342*d583b39bSJohn Wren Kennedy}
343*d583b39bSJohn Wren Kennedy
344*d583b39bSJohn Wren Kennedy#
345*d583b39bSJohn Wren Kennedy# Common function used to cleanup storage pools and datasets.
346*d583b39bSJohn Wren Kennedy#
347*d583b39bSJohn Wren Kennedy# Invoked at the start of the test suite to ensure the system
348*d583b39bSJohn Wren Kennedy# is in a known state, and also at the end of each set of
349*d583b39bSJohn Wren Kennedy# sub-tests to ensure errors from one set of tests doesn't
350*d583b39bSJohn Wren Kennedy# impact the execution of the next set.
351*d583b39bSJohn Wren Kennedy
352*d583b39bSJohn Wren Kennedyfunction default_cleanup
353*d583b39bSJohn Wren Kennedy{
354*d583b39bSJohn Wren Kennedy	default_cleanup_noexit
355*d583b39bSJohn Wren Kennedy
356*d583b39bSJohn Wren Kennedy	log_pass
357*d583b39bSJohn Wren Kennedy}
358*d583b39bSJohn Wren Kennedy
359*d583b39bSJohn Wren Kennedyfunction default_cleanup_noexit
360*d583b39bSJohn Wren Kennedy{
361*d583b39bSJohn Wren Kennedy	typeset exclude=""
362*d583b39bSJohn Wren Kennedy	typeset pool=""
363*d583b39bSJohn Wren Kennedy	#
364*d583b39bSJohn Wren Kennedy	# Destroying the pool will also destroy any
365*d583b39bSJohn Wren Kennedy	# filesystems it contains.
366*d583b39bSJohn Wren Kennedy	#
367*d583b39bSJohn Wren Kennedy	if is_global_zone; then
368*d583b39bSJohn Wren Kennedy		$ZFS unmount -a > /dev/null 2>&1
369*d583b39bSJohn Wren Kennedy		exclude=`eval $ECHO \"'(${KEEP})'\"`
370*d583b39bSJohn Wren Kennedy		ALL_POOLS=$($ZPOOL list -H -o name \
371*d583b39bSJohn Wren Kennedy		    | $GREP -v "$NO_POOLS" | $EGREP -v "$exclude")
372*d583b39bSJohn Wren Kennedy		# Here, we loop through the pools we're allowed to
373*d583b39bSJohn Wren Kennedy		# destroy, only destroying them if it's safe to do
374*d583b39bSJohn Wren Kennedy		# so.
375*d583b39bSJohn Wren Kennedy		while [ ! -z ${ALL_POOLS} ]
376*d583b39bSJohn Wren Kennedy		do
377*d583b39bSJohn Wren Kennedy			for pool in ${ALL_POOLS}
378*d583b39bSJohn Wren Kennedy			do
379*d583b39bSJohn Wren Kennedy				if safe_to_destroy_pool $pool ;
380*d583b39bSJohn Wren Kennedy				then
381*d583b39bSJohn Wren Kennedy					destroy_pool $pool
382*d583b39bSJohn Wren Kennedy				fi
383*d583b39bSJohn Wren Kennedy				ALL_POOLS=$($ZPOOL list -H -o name \
384*d583b39bSJohn Wren Kennedy				    | $GREP -v "$NO_POOLS" \
385*d583b39bSJohn Wren Kennedy				    | $EGREP -v "$exclude")
386*d583b39bSJohn Wren Kennedy			done
387*d583b39bSJohn Wren Kennedy		done
388*d583b39bSJohn Wren Kennedy
389*d583b39bSJohn Wren Kennedy		$ZFS mount -a
390*d583b39bSJohn Wren Kennedy	else
391*d583b39bSJohn Wren Kennedy		typeset fs=""
392*d583b39bSJohn Wren Kennedy		for fs in $($ZFS list -H -o name \
393*d583b39bSJohn Wren Kennedy		    | $GREP "^$ZONE_POOL/$ZONE_CTR[01234]/"); do
394*d583b39bSJohn Wren Kennedy			datasetexists $fs && \
395*d583b39bSJohn Wren Kennedy				log_must $ZFS destroy -Rf $fs
396*d583b39bSJohn Wren Kennedy		done
397*d583b39bSJohn Wren Kennedy
398*d583b39bSJohn Wren Kennedy		# Need cleanup here to avoid garbage dir left.
399*d583b39bSJohn Wren Kennedy		for fs in $($ZFS list -H -o name); do
400*d583b39bSJohn Wren Kennedy			[[ $fs == /$ZONE_POOL ]] && continue
401*d583b39bSJohn Wren Kennedy			[[ -d $fs ]] && log_must $RM -rf $fs/*
402*d583b39bSJohn Wren Kennedy		done
403*d583b39bSJohn Wren Kennedy
404*d583b39bSJohn Wren Kennedy		#
405*d583b39bSJohn Wren Kennedy		# Reset the $ZONE_POOL/$ZONE_CTR[01234] file systems property to
406*d583b39bSJohn Wren Kennedy		# the default value
407*d583b39bSJohn Wren Kennedy		#
408*d583b39bSJohn Wren Kennedy		for fs in $($ZFS list -H -o name); do
409*d583b39bSJohn Wren Kennedy			if [[ $fs == $ZONE_POOL/$ZONE_CTR[01234] ]]; then
410*d583b39bSJohn Wren Kennedy				log_must $ZFS set reservation=none $fs
411*d583b39bSJohn Wren Kennedy				log_must $ZFS set recordsize=128K $fs
412*d583b39bSJohn Wren Kennedy				log_must $ZFS set mountpoint=/$fs $fs
413*d583b39bSJohn Wren Kennedy				typeset enc=""
414*d583b39bSJohn Wren Kennedy				enc=$(get_prop encryption $fs)
415*d583b39bSJohn Wren Kennedy				if [[ $? -ne 0 ]] || [[ -z "$enc" ]] || \
416*d583b39bSJohn Wren Kennedy					[[ "$enc" == "off" ]]; then
417*d583b39bSJohn Wren Kennedy					log_must $ZFS set checksum=on $fs
418*d583b39bSJohn Wren Kennedy				fi
419*d583b39bSJohn Wren Kennedy				log_must $ZFS set compression=off $fs
420*d583b39bSJohn Wren Kennedy				log_must $ZFS set atime=on $fs
421*d583b39bSJohn Wren Kennedy				log_must $ZFS set devices=off $fs
422*d583b39bSJohn Wren Kennedy				log_must $ZFS set exec=on $fs
423*d583b39bSJohn Wren Kennedy				log_must $ZFS set setuid=on $fs
424*d583b39bSJohn Wren Kennedy				log_must $ZFS set readonly=off $fs
425*d583b39bSJohn Wren Kennedy				log_must $ZFS set snapdir=hidden $fs
426*d583b39bSJohn Wren Kennedy				log_must $ZFS set aclmode=groupmask $fs
427*d583b39bSJohn Wren Kennedy				log_must $ZFS set aclinherit=secure $fs
428*d583b39bSJohn Wren Kennedy			fi
429*d583b39bSJohn Wren Kennedy		done
430*d583b39bSJohn Wren Kennedy	fi
431*d583b39bSJohn Wren Kennedy
432*d583b39bSJohn Wren Kennedy	[[ -d $TESTDIR ]] && \
433*d583b39bSJohn Wren Kennedy		log_must $RM -rf $TESTDIR
434*d583b39bSJohn Wren Kennedy}
435*d583b39bSJohn Wren Kennedy
436*d583b39bSJohn Wren Kennedy
437*d583b39bSJohn Wren Kennedy#
438*d583b39bSJohn Wren Kennedy# Common function used to cleanup storage pools, file systems
439*d583b39bSJohn Wren Kennedy# and containers.
440*d583b39bSJohn Wren Kennedy#
441*d583b39bSJohn Wren Kennedyfunction default_container_cleanup
442*d583b39bSJohn Wren Kennedy{
443*d583b39bSJohn Wren Kennedy	if ! is_global_zone; then
444*d583b39bSJohn Wren Kennedy		reexport_pool
445*d583b39bSJohn Wren Kennedy	fi
446*d583b39bSJohn Wren Kennedy
447*d583b39bSJohn Wren Kennedy	ismounted $TESTPOOL/$TESTCTR/$TESTFS1
448*d583b39bSJohn Wren Kennedy	[[ $? -eq 0 ]] && \
449*d583b39bSJohn Wren Kennedy	    log_must $ZFS unmount $TESTPOOL/$TESTCTR/$TESTFS1
450*d583b39bSJohn Wren Kennedy
451*d583b39bSJohn Wren Kennedy	datasetexists $TESTPOOL/$TESTCTR/$TESTFS1 && \
452*d583b39bSJohn Wren Kennedy	    log_must $ZFS destroy -R $TESTPOOL/$TESTCTR/$TESTFS1
453*d583b39bSJohn Wren Kennedy
454*d583b39bSJohn Wren Kennedy	datasetexists $TESTPOOL/$TESTCTR && \
455*d583b39bSJohn Wren Kennedy	    log_must $ZFS destroy -Rf $TESTPOOL/$TESTCTR
456*d583b39bSJohn Wren Kennedy
457*d583b39bSJohn Wren Kennedy	[[ -e $TESTDIR1 ]] && \
458*d583b39bSJohn Wren Kennedy	    log_must $RM -rf $TESTDIR1 > /dev/null 2>&1
459*d583b39bSJohn Wren Kennedy
460*d583b39bSJohn Wren Kennedy	default_cleanup
461*d583b39bSJohn Wren Kennedy}
462*d583b39bSJohn Wren Kennedy
463*d583b39bSJohn Wren Kennedy#
464*d583b39bSJohn Wren Kennedy# Common function used to cleanup snapshot of file system or volume. Default to
465*d583b39bSJohn Wren Kennedy# delete the file system's snapshot
466*d583b39bSJohn Wren Kennedy#
467*d583b39bSJohn Wren Kennedy# $1 snapshot name
468*d583b39bSJohn Wren Kennedy#
469*d583b39bSJohn Wren Kennedyfunction destroy_snapshot
470*d583b39bSJohn Wren Kennedy{
471*d583b39bSJohn Wren Kennedy	typeset snap=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
472*d583b39bSJohn Wren Kennedy
473*d583b39bSJohn Wren Kennedy	if ! snapexists $snap; then
474*d583b39bSJohn Wren Kennedy		log_fail "'$snap' does not existed."
475*d583b39bSJohn Wren Kennedy	fi
476*d583b39bSJohn Wren Kennedy
477*d583b39bSJohn Wren Kennedy	#
478*d583b39bSJohn Wren Kennedy	# For the sake of the value which come from 'get_prop' is not equal
479*d583b39bSJohn Wren Kennedy	# to the really mountpoint when the snapshot is unmounted. So, firstly
480*d583b39bSJohn Wren Kennedy	# check and make sure this snapshot's been mounted in current system.
481*d583b39bSJohn Wren Kennedy	#
482*d583b39bSJohn Wren Kennedy	typeset mtpt=""
483*d583b39bSJohn Wren Kennedy	if ismounted $snap; then
484*d583b39bSJohn Wren Kennedy		mtpt=$(get_prop mountpoint $snap)
485*d583b39bSJohn Wren Kennedy		(($? != 0)) && \
486*d583b39bSJohn Wren Kennedy			log_fail "get_prop mountpoint $snap failed."
487*d583b39bSJohn Wren Kennedy	fi
488*d583b39bSJohn Wren Kennedy
489*d583b39bSJohn Wren Kennedy	log_must $ZFS destroy $snap
490*d583b39bSJohn Wren Kennedy	[[ $mtpt != "" && -d $mtpt ]] && \
491*d583b39bSJohn Wren Kennedy		log_must $RM -rf $mtpt
492*d583b39bSJohn Wren Kennedy}
493*d583b39bSJohn Wren Kennedy
494*d583b39bSJohn Wren Kennedy#
495*d583b39bSJohn Wren Kennedy# Common function used to cleanup clone.
496*d583b39bSJohn Wren Kennedy#
497*d583b39bSJohn Wren Kennedy# $1 clone name
498*d583b39bSJohn Wren Kennedy#
499*d583b39bSJohn Wren Kennedyfunction destroy_clone
500*d583b39bSJohn Wren Kennedy{
501*d583b39bSJohn Wren Kennedy	typeset clone=${1:-$TESTPOOL/$TESTCLONE}
502*d583b39bSJohn Wren Kennedy
503*d583b39bSJohn Wren Kennedy	if ! datasetexists $clone; then
504*d583b39bSJohn Wren Kennedy		log_fail "'$clone' does not existed."
505*d583b39bSJohn Wren Kennedy	fi
506*d583b39bSJohn Wren Kennedy
507*d583b39bSJohn Wren Kennedy	# With the same reason in destroy_snapshot
508*d583b39bSJohn Wren Kennedy	typeset mtpt=""
509*d583b39bSJohn Wren Kennedy	if ismounted $clone; then
510*d583b39bSJohn Wren Kennedy		mtpt=$(get_prop mountpoint $clone)
511*d583b39bSJohn Wren Kennedy		(($? != 0)) && \
512*d583b39bSJohn Wren Kennedy			log_fail "get_prop mountpoint $clone failed."
513*d583b39bSJohn Wren Kennedy	fi
514*d583b39bSJohn Wren Kennedy
515*d583b39bSJohn Wren Kennedy	log_must $ZFS destroy $clone
516*d583b39bSJohn Wren Kennedy	[[ $mtpt != "" && -d $mtpt ]] && \
517*d583b39bSJohn Wren Kennedy		log_must $RM -rf $mtpt
518*d583b39bSJohn Wren Kennedy}
519*d583b39bSJohn Wren Kennedy
520*d583b39bSJohn Wren Kennedy# Return 0 if a snapshot exists; $? otherwise
521*d583b39bSJohn Wren Kennedy#
522*d583b39bSJohn Wren Kennedy# $1 - snapshot name
523*d583b39bSJohn Wren Kennedy
524*d583b39bSJohn Wren Kennedyfunction snapexists
525*d583b39bSJohn Wren Kennedy{
526*d583b39bSJohn Wren Kennedy	$ZFS list -H -t snapshot "$1" > /dev/null 2>&1
527*d583b39bSJohn Wren Kennedy	return $?
528*d583b39bSJohn Wren Kennedy}
529*d583b39bSJohn Wren Kennedy
530*d583b39bSJohn Wren Kennedy#
531*d583b39bSJohn Wren Kennedy# Set a property to a certain value on a dataset.
532*d583b39bSJohn Wren Kennedy# Sets a property of the dataset to the value as passed in.
533*d583b39bSJohn Wren Kennedy# @param:
534*d583b39bSJohn Wren Kennedy#	$1 dataset who's property is being set
535*d583b39bSJohn Wren Kennedy#	$2 property to set
536*d583b39bSJohn Wren Kennedy#	$3 value to set property to
537*d583b39bSJohn Wren Kennedy# @return:
538*d583b39bSJohn Wren Kennedy#	0 if the property could be set.
539*d583b39bSJohn Wren Kennedy#	non-zero otherwise.
540*d583b39bSJohn Wren Kennedy# @use: ZFS
541*d583b39bSJohn Wren Kennedy#
542*d583b39bSJohn Wren Kennedyfunction dataset_setprop
543*d583b39bSJohn Wren Kennedy{
544*d583b39bSJohn Wren Kennedy	typeset fn=dataset_setprop
545*d583b39bSJohn Wren Kennedy
546*d583b39bSJohn Wren Kennedy	if (($# < 3)); then
547*d583b39bSJohn Wren Kennedy		log_note "$fn: Insufficient parameters (need 3, had $#)"
548*d583b39bSJohn Wren Kennedy		return 1
549*d583b39bSJohn Wren Kennedy	fi
550*d583b39bSJohn Wren Kennedy	typeset output=
551*d583b39bSJohn Wren Kennedy	output=$($ZFS set $2=$3 $1 2>&1)
552*d583b39bSJohn Wren Kennedy	typeset rv=$?
553*d583b39bSJohn Wren Kennedy	if ((rv != 0)); then
554*d583b39bSJohn Wren Kennedy		log_note "Setting property on $1 failed."
555*d583b39bSJohn Wren Kennedy		log_note "property $2=$3"
556*d583b39bSJohn Wren Kennedy		log_note "Return Code: $rv"
557*d583b39bSJohn Wren Kennedy		log_note "Output: $output"
558*d583b39bSJohn Wren Kennedy		return $rv
559*d583b39bSJohn Wren Kennedy	fi
560*d583b39bSJohn Wren Kennedy	return 0
561*d583b39bSJohn Wren Kennedy}
562*d583b39bSJohn Wren Kennedy
563*d583b39bSJohn Wren Kennedy#
564*d583b39bSJohn Wren Kennedy# Assign suite defined dataset properties.
565*d583b39bSJohn Wren Kennedy# This function is used to apply the suite's defined default set of
566*d583b39bSJohn Wren Kennedy# properties to a dataset.
567*d583b39bSJohn Wren Kennedy# @parameters: $1 dataset to use
568*d583b39bSJohn Wren Kennedy# @uses: ZFS COMPRESSION_PROP CHECKSUM_PROP
569*d583b39bSJohn Wren Kennedy# @returns:
570*d583b39bSJohn Wren Kennedy#   0 if the dataset has been altered.
571*d583b39bSJohn Wren Kennedy#   1 if no pool name was passed in.
572*d583b39bSJohn Wren Kennedy#   2 if the dataset could not be found.
573*d583b39bSJohn Wren Kennedy#   3 if the dataset could not have it's properties set.
574*d583b39bSJohn Wren Kennedy#
575*d583b39bSJohn Wren Kennedyfunction dataset_set_defaultproperties
576*d583b39bSJohn Wren Kennedy{
577*d583b39bSJohn Wren Kennedy	typeset dataset="$1"
578*d583b39bSJohn Wren Kennedy
579*d583b39bSJohn Wren Kennedy	[[ -z $dataset ]] && return 1
580*d583b39bSJohn Wren Kennedy
581*d583b39bSJohn Wren Kennedy	typeset confset=
582*d583b39bSJohn Wren Kennedy	typeset -i found=0
583*d583b39bSJohn Wren Kennedy	for confset in $($ZFS list); do
584*d583b39bSJohn Wren Kennedy		if [[ $dataset = $confset ]]; then
585*d583b39bSJohn Wren Kennedy			found=1
586*d583b39bSJohn Wren Kennedy			break
587*d583b39bSJohn Wren Kennedy		fi
588*d583b39bSJohn Wren Kennedy	done
589*d583b39bSJohn Wren Kennedy	[[ $found -eq 0 ]] && return 2
590*d583b39bSJohn Wren Kennedy	if [[ -n $COMPRESSION_PROP ]]; then
591*d583b39bSJohn Wren Kennedy		dataset_setprop $dataset compression $COMPRESSION_PROP || \
592*d583b39bSJohn Wren Kennedy			return 3
593*d583b39bSJohn Wren Kennedy		log_note "Compression set to '$COMPRESSION_PROP' on $dataset"
594*d583b39bSJohn Wren Kennedy	fi
595*d583b39bSJohn Wren Kennedy	if [[ -n $CHECKSUM_PROP ]]; then
596*d583b39bSJohn Wren Kennedy		dataset_setprop $dataset checksum $CHECKSUM_PROP || \
597*d583b39bSJohn Wren Kennedy			return 3
598*d583b39bSJohn Wren Kennedy		log_note "Checksum set to '$CHECKSUM_PROP' on $dataset"
599*d583b39bSJohn Wren Kennedy	fi
600*d583b39bSJohn Wren Kennedy	return 0
601*d583b39bSJohn Wren Kennedy}
602*d583b39bSJohn Wren Kennedy
603*d583b39bSJohn Wren Kennedy#
604*d583b39bSJohn Wren Kennedy# Check a numeric assertion
605*d583b39bSJohn Wren Kennedy# @parameter: $@ the assertion to check
606*d583b39bSJohn Wren Kennedy# @output: big loud notice if assertion failed
607*d583b39bSJohn Wren Kennedy# @use: log_fail
608*d583b39bSJohn Wren Kennedy#
609*d583b39bSJohn Wren Kennedyfunction assert
610*d583b39bSJohn Wren Kennedy{
611*d583b39bSJohn Wren Kennedy	(($@)) || log_fail "$@"
612*d583b39bSJohn Wren Kennedy}
613*d583b39bSJohn Wren Kennedy
614*d583b39bSJohn Wren Kennedy#
615*d583b39bSJohn Wren Kennedy# Function to format partition size of a disk
616*d583b39bSJohn Wren Kennedy# Given a disk cxtxdx reduces all partitions
617*d583b39bSJohn Wren Kennedy# to 0 size
618*d583b39bSJohn Wren Kennedy#
619*d583b39bSJohn Wren Kennedyfunction zero_partitions #<whole_disk_name>
620*d583b39bSJohn Wren Kennedy{
621*d583b39bSJohn Wren Kennedy	typeset diskname=$1
622*d583b39bSJohn Wren Kennedy	typeset i
623*d583b39bSJohn Wren Kennedy
624*d583b39bSJohn Wren Kennedy	for i in 0 1 3 4 5 6 7
625*d583b39bSJohn Wren Kennedy	do
626*d583b39bSJohn Wren Kennedy		set_partition $i "" 0mb $diskname
627*d583b39bSJohn Wren Kennedy	done
628*d583b39bSJohn Wren Kennedy}
629*d583b39bSJohn Wren Kennedy
630*d583b39bSJohn Wren Kennedy#
631*d583b39bSJohn Wren Kennedy# Given a slice, size and disk, this function
632*d583b39bSJohn Wren Kennedy# formats the slice to the specified size.
633*d583b39bSJohn Wren Kennedy# Size should be specified with units as per
634*d583b39bSJohn Wren Kennedy# the `format` command requirements eg. 100mb 3gb
635*d583b39bSJohn Wren Kennedy#
636*d583b39bSJohn Wren Kennedyfunction set_partition #<slice_num> <slice_start> <size_plus_units>  <whole_disk_name>
637*d583b39bSJohn Wren Kennedy{
638*d583b39bSJohn Wren Kennedy	typeset -i slicenum=$1
639*d583b39bSJohn Wren Kennedy	typeset start=$2
640*d583b39bSJohn Wren Kennedy	typeset size=$3
641*d583b39bSJohn Wren Kennedy	typeset disk=$4
642*d583b39bSJohn Wren Kennedy	[[ -z $slicenum || -z $size || -z $disk ]] && \
643*d583b39bSJohn Wren Kennedy	    log_fail "The slice, size or disk name is unspecified."
644*d583b39bSJohn Wren Kennedy	typeset format_file=/var/tmp/format_in.$$
645*d583b39bSJohn Wren Kennedy
646*d583b39bSJohn Wren Kennedy	$ECHO "partition" >$format_file
647*d583b39bSJohn Wren Kennedy	$ECHO "$slicenum" >> $format_file
648*d583b39bSJohn Wren Kennedy	$ECHO "" >> $format_file
649*d583b39bSJohn Wren Kennedy	$ECHO "" >> $format_file
650*d583b39bSJohn Wren Kennedy	$ECHO "$start" >> $format_file
651*d583b39bSJohn Wren Kennedy	$ECHO "$size" >> $format_file
652*d583b39bSJohn Wren Kennedy	$ECHO "label" >> $format_file
653*d583b39bSJohn Wren Kennedy	$ECHO "" >> $format_file
654*d583b39bSJohn Wren Kennedy	$ECHO "q" >> $format_file
655*d583b39bSJohn Wren Kennedy	$ECHO "q" >> $format_file
656*d583b39bSJohn Wren Kennedy
657*d583b39bSJohn Wren Kennedy	$FORMAT -e -s -d $disk -f $format_file
658*d583b39bSJohn Wren Kennedy	typeset ret_val=$?
659*d583b39bSJohn Wren Kennedy	$RM -f $format_file
660*d583b39bSJohn Wren Kennedy	[[ $ret_val -ne 0 ]] && \
661*d583b39bSJohn Wren Kennedy	    log_fail "Unable to format $disk slice $slicenum to $size"
662*d583b39bSJohn Wren Kennedy	return 0
663*d583b39bSJohn Wren Kennedy}
664*d583b39bSJohn Wren Kennedy
665*d583b39bSJohn Wren Kennedy#
666*d583b39bSJohn Wren Kennedy# Get the end cyl of the given slice
667*d583b39bSJohn Wren Kennedy#
668*d583b39bSJohn Wren Kennedyfunction get_endslice #<disk> <slice>
669*d583b39bSJohn Wren Kennedy{
670*d583b39bSJohn Wren Kennedy	typeset disk=$1
671*d583b39bSJohn Wren Kennedy	typeset slice=$2
672*d583b39bSJohn Wren Kennedy	if [[ -z $disk || -z $slice ]] ; then
673*d583b39bSJohn Wren Kennedy		log_fail "The disk name or slice number is unspecified."
674*d583b39bSJohn Wren Kennedy	fi
675*d583b39bSJohn Wren Kennedy
676*d583b39bSJohn Wren Kennedy	disk=${disk#/dev/dsk/}
677*d583b39bSJohn Wren Kennedy	disk=${disk#/dev/rdsk/}
678*d583b39bSJohn Wren Kennedy	disk=${disk%s*}
679*d583b39bSJohn Wren Kennedy
680*d583b39bSJohn Wren Kennedy	typeset -i ratio=0
681*d583b39bSJohn Wren Kennedy	ratio=$($PRTVTOC /dev/rdsk/${disk}s2 | \
682*d583b39bSJohn Wren Kennedy		$GREP "sectors\/cylinder" | \
683*d583b39bSJohn Wren Kennedy		$AWK '{print $2}')
684*d583b39bSJohn Wren Kennedy
685*d583b39bSJohn Wren Kennedy	if ((ratio == 0)); then
686*d583b39bSJohn Wren Kennedy		return
687*d583b39bSJohn Wren Kennedy	fi
688*d583b39bSJohn Wren Kennedy
689*d583b39bSJohn Wren Kennedy	typeset -i endcyl=$($PRTVTOC -h /dev/rdsk/${disk}s2 |
690*d583b39bSJohn Wren Kennedy		$NAWK -v token="$slice" '{if ($1==token) print $6}')
691*d583b39bSJohn Wren Kennedy
692*d583b39bSJohn Wren Kennedy	((endcyl = (endcyl + 1) / ratio))
693*d583b39bSJohn Wren Kennedy	echo $endcyl
694*d583b39bSJohn Wren Kennedy}
695*d583b39bSJohn Wren Kennedy
696*d583b39bSJohn Wren Kennedy
697*d583b39bSJohn Wren Kennedy#
698*d583b39bSJohn Wren Kennedy# Given a size,disk and total slice number,  this function formats the
699*d583b39bSJohn Wren Kennedy# disk slices from 0 to the total slice number with the same specified
700*d583b39bSJohn Wren Kennedy# size.
701*d583b39bSJohn Wren Kennedy#
702*d583b39bSJohn Wren Kennedyfunction partition_disk	#<slice_size> <whole_disk_name>	<total_slices>
703*d583b39bSJohn Wren Kennedy{
704*d583b39bSJohn Wren Kennedy	typeset -i i=0
705*d583b39bSJohn Wren Kennedy	typeset slice_size=$1
706*d583b39bSJohn Wren Kennedy	typeset disk_name=$2
707*d583b39bSJohn Wren Kennedy	typeset total_slices=$3
708*d583b39bSJohn Wren Kennedy	typeset cyl
709*d583b39bSJohn Wren Kennedy
710*d583b39bSJohn Wren Kennedy	zero_partitions $disk_name
711*d583b39bSJohn Wren Kennedy	while ((i < $total_slices)); do
712*d583b39bSJohn Wren Kennedy		if ((i == 2)); then
713*d583b39bSJohn Wren Kennedy			((i = i + 1))
714*d583b39bSJohn Wren Kennedy			continue
715*d583b39bSJohn Wren Kennedy		fi
716*d583b39bSJohn Wren Kennedy		set_partition $i "$cyl" $slice_size $disk_name
717*d583b39bSJohn Wren Kennedy		cyl=$(get_endslice $disk_name $i)
718*d583b39bSJohn Wren Kennedy		((i = i+1))
719*d583b39bSJohn Wren Kennedy	done
720*d583b39bSJohn Wren Kennedy}
721*d583b39bSJohn Wren Kennedy
722*d583b39bSJohn Wren Kennedy#
723*d583b39bSJohn Wren Kennedy# This function continues to write to a filenum number of files into dirnum
724*d583b39bSJohn Wren Kennedy# number of directories until either $FILE_WRITE returns an error or the
725*d583b39bSJohn Wren Kennedy# maximum number of files per directory have been written.
726*d583b39bSJohn Wren Kennedy#
727*d583b39bSJohn Wren Kennedy# Usage:
728*d583b39bSJohn Wren Kennedy# fill_fs [destdir] [dirnum] [filenum] [bytes] [num_writes] [data]
729*d583b39bSJohn Wren Kennedy#
730*d583b39bSJohn Wren Kennedy# Return value: 0 on success
731*d583b39bSJohn Wren Kennedy#		non 0 on error
732*d583b39bSJohn Wren Kennedy#
733*d583b39bSJohn Wren Kennedy# Where :
734*d583b39bSJohn Wren Kennedy#	destdir:    is the directory where everything is to be created under
735*d583b39bSJohn Wren Kennedy#	dirnum:	    the maximum number of subdirectories to use, -1 no limit
736*d583b39bSJohn Wren Kennedy#	filenum:    the maximum number of files per subdirectory
737*d583b39bSJohn Wren Kennedy#	bytes:	    number of bytes to write
738*d583b39bSJohn Wren Kennedy#	num_writes: numer of types to write out bytes
739*d583b39bSJohn Wren Kennedy#	data:	    the data that will be writen
740*d583b39bSJohn Wren Kennedy#
741*d583b39bSJohn Wren Kennedy#	E.g.
742*d583b39bSJohn Wren Kennedy#	file_fs /testdir 20 25 1024 256 0
743*d583b39bSJohn Wren Kennedy#
744*d583b39bSJohn Wren Kennedy# Note: bytes * num_writes equals the size of the testfile
745*d583b39bSJohn Wren Kennedy#
746*d583b39bSJohn Wren Kennedyfunction fill_fs # destdir dirnum filenum bytes num_writes data
747*d583b39bSJohn Wren Kennedy{
748*d583b39bSJohn Wren Kennedy	typeset destdir=${1:-$TESTDIR}
749*d583b39bSJohn Wren Kennedy	typeset -i dirnum=${2:-50}
750*d583b39bSJohn Wren Kennedy	typeset -i filenum=${3:-50}
751*d583b39bSJohn Wren Kennedy	typeset -i bytes=${4:-8192}
752*d583b39bSJohn Wren Kennedy	typeset -i num_writes=${5:-10240}
753*d583b39bSJohn Wren Kennedy	typeset -i data=${6:-0}
754*d583b39bSJohn Wren Kennedy
755*d583b39bSJohn Wren Kennedy	typeset -i odirnum=1
756*d583b39bSJohn Wren Kennedy	typeset -i idirnum=0
757*d583b39bSJohn Wren Kennedy	typeset -i fn=0
758*d583b39bSJohn Wren Kennedy	typeset -i retval=0
759*d583b39bSJohn Wren Kennedy
760*d583b39bSJohn Wren Kennedy	log_must $MKDIR -p $destdir/$idirnum
761*d583b39bSJohn Wren Kennedy	while (($odirnum > 0)); do
762*d583b39bSJohn Wren Kennedy		if ((dirnum >= 0 && idirnum >= dirnum)); then
763*d583b39bSJohn Wren Kennedy			odirnum=0
764*d583b39bSJohn Wren Kennedy			break
765*d583b39bSJohn Wren Kennedy		fi
766*d583b39bSJohn Wren Kennedy		$FILE_WRITE -o create -f $destdir/$idirnum/$TESTFILE.$fn \
767*d583b39bSJohn Wren Kennedy		    -b $bytes -c $num_writes -d $data
768*d583b39bSJohn Wren Kennedy		retval=$?
769*d583b39bSJohn Wren Kennedy		if (($retval != 0)); then
770*d583b39bSJohn Wren Kennedy			odirnum=0
771*d583b39bSJohn Wren Kennedy			break
772*d583b39bSJohn Wren Kennedy		fi
773*d583b39bSJohn Wren Kennedy		if (($fn >= $filenum)); then
774*d583b39bSJohn Wren Kennedy			fn=0
775*d583b39bSJohn Wren Kennedy			((idirnum = idirnum + 1))
776*d583b39bSJohn Wren Kennedy			log_must $MKDIR -p $destdir/$idirnum
777*d583b39bSJohn Wren Kennedy		else
778*d583b39bSJohn Wren Kennedy			((fn = fn + 1))
779*d583b39bSJohn Wren Kennedy		fi
780*d583b39bSJohn Wren Kennedy	done
781*d583b39bSJohn Wren Kennedy	return $retval
782*d583b39bSJohn Wren Kennedy}
783*d583b39bSJohn Wren Kennedy
784*d583b39bSJohn Wren Kennedy#
785*d583b39bSJohn Wren Kennedy# Simple function to get the specified property. If unable to
786*d583b39bSJohn Wren Kennedy# get the property then exits.
787*d583b39bSJohn Wren Kennedy#
788*d583b39bSJohn Wren Kennedy# Note property is in 'parsable' format (-p)
789*d583b39bSJohn Wren Kennedy#
790*d583b39bSJohn Wren Kennedyfunction get_prop # property dataset
791*d583b39bSJohn Wren Kennedy{
792*d583b39bSJohn Wren Kennedy	typeset prop_val
793*d583b39bSJohn Wren Kennedy	typeset prop=$1
794*d583b39bSJohn Wren Kennedy	typeset dataset=$2
795*d583b39bSJohn Wren Kennedy
796*d583b39bSJohn Wren Kennedy	prop_val=$($ZFS get -pH -o value $prop $dataset 2>/dev/null)
797*d583b39bSJohn Wren Kennedy	if [[ $? -ne 0 ]]; then
798*d583b39bSJohn Wren Kennedy		log_note "Unable to get $prop property for dataset " \
799*d583b39bSJohn Wren Kennedy		"$dataset"
800*d583b39bSJohn Wren Kennedy		return 1
801*d583b39bSJohn Wren Kennedy	fi
802*d583b39bSJohn Wren Kennedy
803*d583b39bSJohn Wren Kennedy	$ECHO $prop_val
804*d583b39bSJohn Wren Kennedy	return 0
805*d583b39bSJohn Wren Kennedy}
806*d583b39bSJohn Wren Kennedy
807*d583b39bSJohn Wren Kennedy#
808*d583b39bSJohn Wren Kennedy# Simple function to get the specified property of pool. If unable to
809*d583b39bSJohn Wren Kennedy# get the property then exits.
810*d583b39bSJohn Wren Kennedy#
811*d583b39bSJohn Wren Kennedyfunction get_pool_prop # property pool
812*d583b39bSJohn Wren Kennedy{
813*d583b39bSJohn Wren Kennedy	typeset prop_val
814*d583b39bSJohn Wren Kennedy	typeset prop=$1
815*d583b39bSJohn Wren Kennedy	typeset pool=$2
816*d583b39bSJohn Wren Kennedy
817*d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
818*d583b39bSJohn Wren Kennedy		prop_val=$($ZPOOL get $prop $pool 2>/dev/null | $TAIL -1 | \
819*d583b39bSJohn Wren Kennedy			$AWK '{print $3}')
820*d583b39bSJohn Wren Kennedy		if [[ $? -ne 0 ]]; then
821*d583b39bSJohn Wren Kennedy			log_note "Unable to get $prop property for pool " \
822*d583b39bSJohn Wren Kennedy			"$pool"
823*d583b39bSJohn Wren Kennedy			return 1
824*d583b39bSJohn Wren Kennedy		fi
825*d583b39bSJohn Wren Kennedy	else
826*d583b39bSJohn Wren Kennedy		log_note "Pool $pool not exists."
827*d583b39bSJohn Wren Kennedy		return 1
828*d583b39bSJohn Wren Kennedy	fi
829*d583b39bSJohn Wren Kennedy
830*d583b39bSJohn Wren Kennedy	$ECHO $prop_val
831*d583b39bSJohn Wren Kennedy	return 0
832*d583b39bSJohn Wren Kennedy}
833*d583b39bSJohn Wren Kennedy
834*d583b39bSJohn Wren Kennedy# Return 0 if a pool exists; $? otherwise
835*d583b39bSJohn Wren Kennedy#
836*d583b39bSJohn Wren Kennedy# $1 - pool name
837*d583b39bSJohn Wren Kennedy
838*d583b39bSJohn Wren Kennedyfunction poolexists
839*d583b39bSJohn Wren Kennedy{
840*d583b39bSJohn Wren Kennedy	typeset pool=$1
841*d583b39bSJohn Wren Kennedy
842*d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
843*d583b39bSJohn Wren Kennedy		log_note "No pool name given."
844*d583b39bSJohn Wren Kennedy		return 1
845*d583b39bSJohn Wren Kennedy	fi
846*d583b39bSJohn Wren Kennedy
847*d583b39bSJohn Wren Kennedy	$ZPOOL get name "$pool" > /dev/null 2>&1
848*d583b39bSJohn Wren Kennedy	return $?
849*d583b39bSJohn Wren Kennedy}
850*d583b39bSJohn Wren Kennedy
851*d583b39bSJohn Wren Kennedy# Return 0 if all the specified datasets exist; $? otherwise
852*d583b39bSJohn Wren Kennedy#
853*d583b39bSJohn Wren Kennedy# $1-n  dataset name
854*d583b39bSJohn Wren Kennedyfunction datasetexists
855*d583b39bSJohn Wren Kennedy{
856*d583b39bSJohn Wren Kennedy	if (($# == 0)); then
857*d583b39bSJohn Wren Kennedy		log_note "No dataset name given."
858*d583b39bSJohn Wren Kennedy		return 1
859*d583b39bSJohn Wren Kennedy	fi
860*d583b39bSJohn Wren Kennedy
861*d583b39bSJohn Wren Kennedy	while (($# > 0)); do
862*d583b39bSJohn Wren Kennedy		$ZFS get name $1 > /dev/null 2>&1 || \
863*d583b39bSJohn Wren Kennedy			return $?
864*d583b39bSJohn Wren Kennedy		shift
865*d583b39bSJohn Wren Kennedy	done
866*d583b39bSJohn Wren Kennedy
867*d583b39bSJohn Wren Kennedy	return 0
868*d583b39bSJohn Wren Kennedy}
869*d583b39bSJohn Wren Kennedy
870*d583b39bSJohn Wren Kennedy# return 0 if none of the specified datasets exists, otherwise return 1.
871*d583b39bSJohn Wren Kennedy#
872*d583b39bSJohn Wren Kennedy# $1-n  dataset name
873*d583b39bSJohn Wren Kennedyfunction datasetnonexists
874*d583b39bSJohn Wren Kennedy{
875*d583b39bSJohn Wren Kennedy	if (($# == 0)); then
876*d583b39bSJohn Wren Kennedy		log_note "No dataset name given."
877*d583b39bSJohn Wren Kennedy		return 1
878*d583b39bSJohn Wren Kennedy	fi
879*d583b39bSJohn Wren Kennedy
880*d583b39bSJohn Wren Kennedy	while (($# > 0)); do
881*d583b39bSJohn Wren Kennedy		$ZFS list -H -t filesystem,snapshot,volume $1 > /dev/null 2>&1 \
882*d583b39bSJohn Wren Kennedy		    && return 1
883*d583b39bSJohn Wren Kennedy		shift
884*d583b39bSJohn Wren Kennedy	done
885*d583b39bSJohn Wren Kennedy
886*d583b39bSJohn Wren Kennedy	return 0
887*d583b39bSJohn Wren Kennedy}
888*d583b39bSJohn Wren Kennedy
889*d583b39bSJohn Wren Kennedy#
890*d583b39bSJohn Wren Kennedy# Given a mountpoint, or a dataset name, determine if it is shared.
891*d583b39bSJohn Wren Kennedy#
892*d583b39bSJohn Wren Kennedy# Returns 0 if shared, 1 otherwise.
893*d583b39bSJohn Wren Kennedy#
894*d583b39bSJohn Wren Kennedyfunction is_shared
895*d583b39bSJohn Wren Kennedy{
896*d583b39bSJohn Wren Kennedy	typeset fs=$1
897*d583b39bSJohn Wren Kennedy	typeset mtpt
898*d583b39bSJohn Wren Kennedy
899*d583b39bSJohn Wren Kennedy	if [[ $fs != "/"* ]] ; then
900*d583b39bSJohn Wren Kennedy		if datasetnonexists "$fs" ; then
901*d583b39bSJohn Wren Kennedy			return 1
902*d583b39bSJohn Wren Kennedy		else
903*d583b39bSJohn Wren Kennedy			mtpt=$(get_prop mountpoint "$fs")
904*d583b39bSJohn Wren Kennedy			case $mtpt in
905*d583b39bSJohn Wren Kennedy				none|legacy|-) return 1
906*d583b39bSJohn Wren Kennedy					;;
907*d583b39bSJohn Wren Kennedy				*)	fs=$mtpt
908*d583b39bSJohn Wren Kennedy					;;
909*d583b39bSJohn Wren Kennedy			esac
910*d583b39bSJohn Wren Kennedy		fi
911*d583b39bSJohn Wren Kennedy	fi
912*d583b39bSJohn Wren Kennedy
913*d583b39bSJohn Wren Kennedy	for mtpt in `$SHARE | $AWK '{print $2}'` ; do
914*d583b39bSJohn Wren Kennedy		if [[ $mtpt == $fs ]] ; then
915*d583b39bSJohn Wren Kennedy			return 0
916*d583b39bSJohn Wren Kennedy		fi
917*d583b39bSJohn Wren Kennedy	done
918*d583b39bSJohn Wren Kennedy
919*d583b39bSJohn Wren Kennedy	typeset stat=$($SVCS -H -o STA nfs/server:default)
920*d583b39bSJohn Wren Kennedy	if [[ $stat != "ON" ]]; then
921*d583b39bSJohn Wren Kennedy		log_note "Current nfs/server status: $stat"
922*d583b39bSJohn Wren Kennedy	fi
923*d583b39bSJohn Wren Kennedy
924*d583b39bSJohn Wren Kennedy	return 1
925*d583b39bSJohn Wren Kennedy}
926*d583b39bSJohn Wren Kennedy
927*d583b39bSJohn Wren Kennedy#
928*d583b39bSJohn Wren Kennedy# Given a mountpoint, determine if it is not shared.
929*d583b39bSJohn Wren Kennedy#
930*d583b39bSJohn Wren Kennedy# Returns 0 if not shared, 1 otherwise.
931*d583b39bSJohn Wren Kennedy#
932*d583b39bSJohn Wren Kennedyfunction not_shared
933*d583b39bSJohn Wren Kennedy{
934*d583b39bSJohn Wren Kennedy	typeset fs=$1
935*d583b39bSJohn Wren Kennedy
936*d583b39bSJohn Wren Kennedy	is_shared $fs
937*d583b39bSJohn Wren Kennedy	if (($? == 0)); then
938*d583b39bSJohn Wren Kennedy		return 1
939*d583b39bSJohn Wren Kennedy	fi
940*d583b39bSJohn Wren Kennedy
941*d583b39bSJohn Wren Kennedy	return 0
942*d583b39bSJohn Wren Kennedy}
943*d583b39bSJohn Wren Kennedy
944*d583b39bSJohn Wren Kennedy#
945*d583b39bSJohn Wren Kennedy# Helper function to unshare a mountpoint.
946*d583b39bSJohn Wren Kennedy#
947*d583b39bSJohn Wren Kennedyfunction unshare_fs #fs
948*d583b39bSJohn Wren Kennedy{
949*d583b39bSJohn Wren Kennedy	typeset fs=$1
950*d583b39bSJohn Wren Kennedy
951*d583b39bSJohn Wren Kennedy	is_shared $fs
952*d583b39bSJohn Wren Kennedy	if (($? == 0)); then
953*d583b39bSJohn Wren Kennedy		log_must $ZFS unshare $fs
954*d583b39bSJohn Wren Kennedy	fi
955*d583b39bSJohn Wren Kennedy
956*d583b39bSJohn Wren Kennedy	return 0
957*d583b39bSJohn Wren Kennedy}
958*d583b39bSJohn Wren Kennedy
959*d583b39bSJohn Wren Kennedy#
960*d583b39bSJohn Wren Kennedy# Check NFS server status and trigger it online.
961*d583b39bSJohn Wren Kennedy#
962*d583b39bSJohn Wren Kennedyfunction setup_nfs_server
963*d583b39bSJohn Wren Kennedy{
964*d583b39bSJohn Wren Kennedy	# Cannot share directory in non-global zone.
965*d583b39bSJohn Wren Kennedy	#
966*d583b39bSJohn Wren Kennedy	if ! is_global_zone; then
967*d583b39bSJohn Wren Kennedy		log_note "Cannot trigger NFS server by sharing in LZ."
968*d583b39bSJohn Wren Kennedy		return
969*d583b39bSJohn Wren Kennedy	fi
970*d583b39bSJohn Wren Kennedy
971*d583b39bSJohn Wren Kennedy	typeset nfs_fmri="svc:/network/nfs/server:default"
972*d583b39bSJohn Wren Kennedy	if [[ $($SVCS -Ho STA $nfs_fmri) != "ON" ]]; then
973*d583b39bSJohn Wren Kennedy		#
974*d583b39bSJohn Wren Kennedy		# Only really sharing operation can enable NFS server
975*d583b39bSJohn Wren Kennedy		# to online permanently.
976*d583b39bSJohn Wren Kennedy		#
977*d583b39bSJohn Wren Kennedy		typeset dummy=/tmp/dummy
978*d583b39bSJohn Wren Kennedy
979*d583b39bSJohn Wren Kennedy		if [[ -d $dummy ]]; then
980*d583b39bSJohn Wren Kennedy			log_must $RM -rf $dummy
981*d583b39bSJohn Wren Kennedy		fi
982*d583b39bSJohn Wren Kennedy
983*d583b39bSJohn Wren Kennedy		log_must $MKDIR $dummy
984*d583b39bSJohn Wren Kennedy		log_must $SHARE $dummy
985*d583b39bSJohn Wren Kennedy
986*d583b39bSJohn Wren Kennedy		#
987*d583b39bSJohn Wren Kennedy		# Waiting for fmri's status to be the final status.
988*d583b39bSJohn Wren Kennedy		# Otherwise, in transition, an asterisk (*) is appended for
989*d583b39bSJohn Wren Kennedy		# instances, unshare will reverse status to 'DIS' again.
990*d583b39bSJohn Wren Kennedy		#
991*d583b39bSJohn Wren Kennedy		# Waiting for 1's at least.
992*d583b39bSJohn Wren Kennedy		#
993*d583b39bSJohn Wren Kennedy		log_must $SLEEP 1
994*d583b39bSJohn Wren Kennedy		timeout=10
995*d583b39bSJohn Wren Kennedy		while [[ timeout -ne 0 && $($SVCS -Ho STA $nfs_fmri) == *'*' ]]
996*d583b39bSJohn Wren Kennedy		do
997*d583b39bSJohn Wren Kennedy			log_must $SLEEP 1
998*d583b39bSJohn Wren Kennedy
999*d583b39bSJohn Wren Kennedy			((timeout -= 1))
1000*d583b39bSJohn Wren Kennedy		done
1001*d583b39bSJohn Wren Kennedy
1002*d583b39bSJohn Wren Kennedy		log_must $UNSHARE $dummy
1003*d583b39bSJohn Wren Kennedy		log_must $RM -rf $dummy
1004*d583b39bSJohn Wren Kennedy	fi
1005*d583b39bSJohn Wren Kennedy
1006*d583b39bSJohn Wren Kennedy	log_note "Current NFS status: '$($SVCS -Ho STA,FMRI $nfs_fmri)'"
1007*d583b39bSJohn Wren Kennedy}
1008*d583b39bSJohn Wren Kennedy
1009*d583b39bSJohn Wren Kennedy#
1010*d583b39bSJohn Wren Kennedy# To verify whether calling process is in global zone
1011*d583b39bSJohn Wren Kennedy#
1012*d583b39bSJohn Wren Kennedy# Return 0 if in global zone, 1 in non-global zone
1013*d583b39bSJohn Wren Kennedy#
1014*d583b39bSJohn Wren Kennedyfunction is_global_zone
1015*d583b39bSJohn Wren Kennedy{
1016*d583b39bSJohn Wren Kennedy	typeset cur_zone=$($ZONENAME 2>/dev/null)
1017*d583b39bSJohn Wren Kennedy	if [[ $cur_zone != "global" ]]; then
1018*d583b39bSJohn Wren Kennedy		return 1
1019*d583b39bSJohn Wren Kennedy	fi
1020*d583b39bSJohn Wren Kennedy	return 0
1021*d583b39bSJohn Wren Kennedy}
1022*d583b39bSJohn Wren Kennedy
1023*d583b39bSJohn Wren Kennedy#
1024*d583b39bSJohn Wren Kennedy# Verify whether test is permitted to run from
1025*d583b39bSJohn Wren Kennedy# global zone, local zone, or both
1026*d583b39bSJohn Wren Kennedy#
1027*d583b39bSJohn Wren Kennedy# $1 zone limit, could be "global", "local", or "both"(no limit)
1028*d583b39bSJohn Wren Kennedy#
1029*d583b39bSJohn Wren Kennedy# Return 0 if permitted, otherwise exit with log_unsupported
1030*d583b39bSJohn Wren Kennedy#
1031*d583b39bSJohn Wren Kennedyfunction verify_runnable # zone limit
1032*d583b39bSJohn Wren Kennedy{
1033*d583b39bSJohn Wren Kennedy	typeset limit=$1
1034*d583b39bSJohn Wren Kennedy
1035*d583b39bSJohn Wren Kennedy	[[ -z $limit ]] && return 0
1036*d583b39bSJohn Wren Kennedy
1037*d583b39bSJohn Wren Kennedy	if is_global_zone ; then
1038*d583b39bSJohn Wren Kennedy		case $limit in
1039*d583b39bSJohn Wren Kennedy			global|both)
1040*d583b39bSJohn Wren Kennedy				;;
1041*d583b39bSJohn Wren Kennedy			local)	log_unsupported "Test is unable to run from "\
1042*d583b39bSJohn Wren Kennedy					"global zone."
1043*d583b39bSJohn Wren Kennedy				;;
1044*d583b39bSJohn Wren Kennedy			*)	log_note "Warning: unknown limit $limit - " \
1045*d583b39bSJohn Wren Kennedy					"use both."
1046*d583b39bSJohn Wren Kennedy				;;
1047*d583b39bSJohn Wren Kennedy		esac
1048*d583b39bSJohn Wren Kennedy	else
1049*d583b39bSJohn Wren Kennedy		case $limit in
1050*d583b39bSJohn Wren Kennedy			local|both)
1051*d583b39bSJohn Wren Kennedy				;;
1052*d583b39bSJohn Wren Kennedy			global)	log_unsupported "Test is unable to run from "\
1053*d583b39bSJohn Wren Kennedy					"local zone."
1054*d583b39bSJohn Wren Kennedy				;;
1055*d583b39bSJohn Wren Kennedy			*)	log_note "Warning: unknown limit $limit - " \
1056*d583b39bSJohn Wren Kennedy					"use both."
1057*d583b39bSJohn Wren Kennedy				;;
1058*d583b39bSJohn Wren Kennedy		esac
1059*d583b39bSJohn Wren Kennedy
1060*d583b39bSJohn Wren Kennedy		reexport_pool
1061*d583b39bSJohn Wren Kennedy	fi
1062*d583b39bSJohn Wren Kennedy
1063*d583b39bSJohn Wren Kennedy	return 0
1064*d583b39bSJohn Wren Kennedy}
1065*d583b39bSJohn Wren Kennedy
1066*d583b39bSJohn Wren Kennedy# Return 0 if create successfully or the pool exists; $? otherwise
1067*d583b39bSJohn Wren Kennedy# Note: In local zones, this function should return 0 silently.
1068*d583b39bSJohn Wren Kennedy#
1069*d583b39bSJohn Wren Kennedy# $1 - pool name
1070*d583b39bSJohn Wren Kennedy# $2-n - [keyword] devs_list
1071*d583b39bSJohn Wren Kennedy
1072*d583b39bSJohn Wren Kennedyfunction create_pool #pool devs_list
1073*d583b39bSJohn Wren Kennedy{
1074*d583b39bSJohn Wren Kennedy	typeset pool=${1%%/*}
1075*d583b39bSJohn Wren Kennedy
1076*d583b39bSJohn Wren Kennedy	shift
1077*d583b39bSJohn Wren Kennedy
1078*d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
1079*d583b39bSJohn Wren Kennedy		log_note "Missing pool name."
1080*d583b39bSJohn Wren Kennedy		return 1
1081*d583b39bSJohn Wren Kennedy	fi
1082*d583b39bSJohn Wren Kennedy
1083*d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
1084*d583b39bSJohn Wren Kennedy		destroy_pool $pool
1085*d583b39bSJohn Wren Kennedy	fi
1086*d583b39bSJohn Wren Kennedy
1087*d583b39bSJohn Wren Kennedy	if is_global_zone ; then
1088*d583b39bSJohn Wren Kennedy		[[ -d /$pool ]] && $RM -rf /$pool
1089*d583b39bSJohn Wren Kennedy		log_must $ZPOOL create -f $pool $@
1090*d583b39bSJohn Wren Kennedy	fi
1091*d583b39bSJohn Wren Kennedy
1092*d583b39bSJohn Wren Kennedy	return 0
1093*d583b39bSJohn Wren Kennedy}
1094*d583b39bSJohn Wren Kennedy
1095*d583b39bSJohn Wren Kennedy# Return 0 if destroy successfully or the pool exists; $? otherwise
1096*d583b39bSJohn Wren Kennedy# Note: In local zones, this function should return 0 silently.
1097*d583b39bSJohn Wren Kennedy#
1098*d583b39bSJohn Wren Kennedy# $1 - pool name
1099*d583b39bSJohn Wren Kennedy# Destroy pool with the given parameters.
1100*d583b39bSJohn Wren Kennedy
1101*d583b39bSJohn Wren Kennedyfunction destroy_pool #pool
1102*d583b39bSJohn Wren Kennedy{
1103*d583b39bSJohn Wren Kennedy	typeset pool=${1%%/*}
1104*d583b39bSJohn Wren Kennedy	typeset mtpt
1105*d583b39bSJohn Wren Kennedy
1106*d583b39bSJohn Wren Kennedy	if [[ -z $pool ]]; then
1107*d583b39bSJohn Wren Kennedy		log_note "No pool name given."
1108*d583b39bSJohn Wren Kennedy		return 1
1109*d583b39bSJohn Wren Kennedy	fi
1110*d583b39bSJohn Wren Kennedy
1111*d583b39bSJohn Wren Kennedy	if is_global_zone ; then
1112*d583b39bSJohn Wren Kennedy		if poolexists "$pool" ; then
1113*d583b39bSJohn Wren Kennedy			mtpt=$(get_prop mountpoint "$pool")
1114*d583b39bSJohn Wren Kennedy			log_must $ZPOOL destroy -f $pool
1115*d583b39bSJohn Wren Kennedy
1116*d583b39bSJohn Wren Kennedy			[[ -d $mtpt ]] && \
1117*d583b39bSJohn Wren Kennedy				log_must $RM -rf $mtpt
1118*d583b39bSJohn Wren Kennedy		else
1119*d583b39bSJohn Wren Kennedy			log_note "Pool not exist. ($pool)"
1120*d583b39bSJohn Wren Kennedy			return 1
1121*d583b39bSJohn Wren Kennedy		fi
1122*d583b39bSJohn Wren Kennedy	fi
1123*d583b39bSJohn Wren Kennedy
1124*d583b39bSJohn Wren Kennedy	return 0
1125*d583b39bSJohn Wren Kennedy}
1126*d583b39bSJohn Wren Kennedy
1127*d583b39bSJohn Wren Kennedy#
1128*d583b39bSJohn Wren Kennedy# Firstly, create a pool with 5 datasets. Then, create a single zone and
1129*d583b39bSJohn Wren Kennedy# export the 5 datasets to it. In addition, we also add a ZFS filesystem
1130*d583b39bSJohn Wren Kennedy# and a zvol device to the zone.
1131*d583b39bSJohn Wren Kennedy#
1132*d583b39bSJohn Wren Kennedy# $1 zone name
1133*d583b39bSJohn Wren Kennedy# $2 zone root directory prefix
1134*d583b39bSJohn Wren Kennedy# $3 zone ip
1135*d583b39bSJohn Wren Kennedy#
1136*d583b39bSJohn Wren Kennedyfunction zfs_zones_setup #zone_name zone_root zone_ip
1137*d583b39bSJohn Wren Kennedy{
1138*d583b39bSJohn Wren Kennedy	typeset zone_name=${1:-$(hostname)-z}
1139*d583b39bSJohn Wren Kennedy	typeset zone_root=${2:-"/zone_root"}
1140*d583b39bSJohn Wren Kennedy	typeset zone_ip=${3:-"10.1.1.10"}
1141*d583b39bSJohn Wren Kennedy	typeset prefix_ctr=$ZONE_CTR
1142*d583b39bSJohn Wren Kennedy	typeset pool_name=$ZONE_POOL
1143*d583b39bSJohn Wren Kennedy	typeset -i cntctr=5
1144*d583b39bSJohn Wren Kennedy	typeset -i i=0
1145*d583b39bSJohn Wren Kennedy
1146*d583b39bSJohn Wren Kennedy	# Create pool and 5 container within it
1147*d583b39bSJohn Wren Kennedy	#
1148*d583b39bSJohn Wren Kennedy	[[ -d /$pool_name ]] && $RM -rf /$pool_name
1149*d583b39bSJohn Wren Kennedy	log_must $ZPOOL create -f $pool_name $DISKS
1150*d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
1151*d583b39bSJohn Wren Kennedy		log_must $ZFS create $pool_name/$prefix_ctr$i
1152*d583b39bSJohn Wren Kennedy		((i += 1))
1153*d583b39bSJohn Wren Kennedy	done
1154*d583b39bSJohn Wren Kennedy
1155*d583b39bSJohn Wren Kennedy	# create a zvol
1156*d583b39bSJohn Wren Kennedy	log_must $ZFS create -V 1g $pool_name/zone_zvol
1157*d583b39bSJohn Wren Kennedy
1158*d583b39bSJohn Wren Kennedy	#
1159*d583b39bSJohn Wren Kennedy	# If current system support slog, add slog device for pool
1160*d583b39bSJohn Wren Kennedy	#
1161*d583b39bSJohn Wren Kennedy	if verify_slog_support ; then
1162*d583b39bSJohn Wren Kennedy		typeset sdevs="/var/tmp/sdev1 /var/tmp/sdev2"
1163*d583b39bSJohn Wren Kennedy		log_must $MKFILE 100M $sdevs
1164*d583b39bSJohn Wren Kennedy		log_must $ZPOOL add $pool_name log mirror $sdevs
1165*d583b39bSJohn Wren Kennedy	fi
1166*d583b39bSJohn Wren Kennedy
1167*d583b39bSJohn Wren Kennedy	# this isn't supported just yet.
1168*d583b39bSJohn Wren Kennedy	# Create a filesystem. In order to add this to
1169*d583b39bSJohn Wren Kennedy	# the zone, it must have it's mountpoint set to 'legacy'
1170*d583b39bSJohn Wren Kennedy	# log_must $ZFS create $pool_name/zfs_filesystem
1171*d583b39bSJohn Wren Kennedy	# log_must $ZFS set mountpoint=legacy $pool_name/zfs_filesystem
1172*d583b39bSJohn Wren Kennedy
1173*d583b39bSJohn Wren Kennedy	[[ -d $zone_root ]] && \
1174*d583b39bSJohn Wren Kennedy		log_must $RM -rf $zone_root/$zone_name
1175*d583b39bSJohn Wren Kennedy	[[ ! -d $zone_root ]] && \
1176*d583b39bSJohn Wren Kennedy		log_must $MKDIR -p -m 0700 $zone_root/$zone_name
1177*d583b39bSJohn Wren Kennedy
1178*d583b39bSJohn Wren Kennedy	# Create zone configure file and configure the zone
1179*d583b39bSJohn Wren Kennedy	#
1180*d583b39bSJohn Wren Kennedy	typeset zone_conf=/tmp/zone_conf.$$
1181*d583b39bSJohn Wren Kennedy	$ECHO "create" > $zone_conf
1182*d583b39bSJohn Wren Kennedy	$ECHO "set zonepath=$zone_root/$zone_name" >> $zone_conf
1183*d583b39bSJohn Wren Kennedy	$ECHO "set autoboot=true" >> $zone_conf
1184*d583b39bSJohn Wren Kennedy	i=0
1185*d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
1186*d583b39bSJohn Wren Kennedy		$ECHO "add dataset" >> $zone_conf
1187*d583b39bSJohn Wren Kennedy		$ECHO "set name=$pool_name/$prefix_ctr$i" >> \
1188*d583b39bSJohn Wren Kennedy			$zone_conf
1189*d583b39bSJohn Wren Kennedy		$ECHO "end" >> $zone_conf
1190*d583b39bSJohn Wren Kennedy		((i += 1))
1191*d583b39bSJohn Wren Kennedy	done
1192*d583b39bSJohn Wren Kennedy
1193*d583b39bSJohn Wren Kennedy	# add our zvol to the zone
1194*d583b39bSJohn Wren Kennedy	$ECHO "add device" >> $zone_conf
1195*d583b39bSJohn Wren Kennedy	$ECHO "set match=/dev/zvol/dsk/$pool_name/zone_zvol" >> $zone_conf
1196*d583b39bSJohn Wren Kennedy	$ECHO "end" >> $zone_conf
1197*d583b39bSJohn Wren Kennedy
1198*d583b39bSJohn Wren Kennedy	# add a corresponding zvol rdsk to the zone
1199*d583b39bSJohn Wren Kennedy	$ECHO "add device" >> $zone_conf
1200*d583b39bSJohn Wren Kennedy	$ECHO "set match=/dev/zvol/rdsk/$pool_name/zone_zvol" >> $zone_conf
1201*d583b39bSJohn Wren Kennedy	$ECHO "end" >> $zone_conf
1202*d583b39bSJohn Wren Kennedy
1203*d583b39bSJohn Wren Kennedy	# once it's supported, we'll add our filesystem to the zone
1204*d583b39bSJohn Wren Kennedy	# $ECHO "add fs" >> $zone_conf
1205*d583b39bSJohn Wren Kennedy	# $ECHO "set type=zfs" >> $zone_conf
1206*d583b39bSJohn Wren Kennedy	# $ECHO "set special=$pool_name/zfs_filesystem" >> $zone_conf
1207*d583b39bSJohn Wren Kennedy	# $ECHO "set dir=/export/zfs_filesystem" >> $zone_conf
1208*d583b39bSJohn Wren Kennedy	# $ECHO "end" >> $zone_conf
1209*d583b39bSJohn Wren Kennedy
1210*d583b39bSJohn Wren Kennedy	$ECHO "verify" >> $zone_conf
1211*d583b39bSJohn Wren Kennedy	$ECHO "commit" >> $zone_conf
1212*d583b39bSJohn Wren Kennedy	log_must $ZONECFG -z $zone_name -f $zone_conf
1213*d583b39bSJohn Wren Kennedy	log_must $RM -f $zone_conf
1214*d583b39bSJohn Wren Kennedy
1215*d583b39bSJohn Wren Kennedy	# Install the zone
1216*d583b39bSJohn Wren Kennedy	$ZONEADM -z $zone_name install
1217*d583b39bSJohn Wren Kennedy	if (($? == 0)); then
1218*d583b39bSJohn Wren Kennedy		log_note "SUCCESS: $ZONEADM -z $zone_name install"
1219*d583b39bSJohn Wren Kennedy	else
1220*d583b39bSJohn Wren Kennedy		log_fail "FAIL: $ZONEADM -z $zone_name install"
1221*d583b39bSJohn Wren Kennedy	fi
1222*d583b39bSJohn Wren Kennedy
1223*d583b39bSJohn Wren Kennedy	# Install sysidcfg file
1224*d583b39bSJohn Wren Kennedy	#
1225*d583b39bSJohn Wren Kennedy	typeset sysidcfg=$zone_root/$zone_name/root/etc/sysidcfg
1226*d583b39bSJohn Wren Kennedy	$ECHO "system_locale=C" > $sysidcfg
1227*d583b39bSJohn Wren Kennedy	$ECHO  "terminal=dtterm" >> $sysidcfg
1228*d583b39bSJohn Wren Kennedy	$ECHO  "network_interface=primary {" >> $sysidcfg
1229*d583b39bSJohn Wren Kennedy	$ECHO  "hostname=$zone_name" >> $sysidcfg
1230*d583b39bSJohn Wren Kennedy	$ECHO  "}" >> $sysidcfg
1231*d583b39bSJohn Wren Kennedy	$ECHO  "name_service=NONE" >> $sysidcfg
1232*d583b39bSJohn Wren Kennedy	$ECHO  "root_password=mo791xfZ/SFiw" >> $sysidcfg
1233*d583b39bSJohn Wren Kennedy	$ECHO  "security_policy=NONE" >> $sysidcfg
1234*d583b39bSJohn Wren Kennedy	$ECHO  "timezone=US/Eastern" >> $sysidcfg
1235*d583b39bSJohn Wren Kennedy
1236*d583b39bSJohn Wren Kennedy	# Boot this zone
1237*d583b39bSJohn Wren Kennedy	log_must $ZONEADM -z $zone_name boot
1238*d583b39bSJohn Wren Kennedy}
1239*d583b39bSJohn Wren Kennedy
1240*d583b39bSJohn Wren Kennedy#
1241*d583b39bSJohn Wren Kennedy# Reexport TESTPOOL & TESTPOOL(1-4)
1242*d583b39bSJohn Wren Kennedy#
1243*d583b39bSJohn Wren Kennedyfunction reexport_pool
1244*d583b39bSJohn Wren Kennedy{
1245*d583b39bSJohn Wren Kennedy	typeset -i cntctr=5
1246*d583b39bSJohn Wren Kennedy	typeset -i i=0
1247*d583b39bSJohn Wren Kennedy
1248*d583b39bSJohn Wren Kennedy	while ((i < cntctr)); do
1249*d583b39bSJohn Wren Kennedy		if ((i == 0)); then
1250*d583b39bSJohn Wren Kennedy			TESTPOOL=$ZONE_POOL/$ZONE_CTR$i
1251*d583b39bSJohn Wren Kennedy			if ! ismounted $TESTPOOL; then
1252*d583b39bSJohn Wren Kennedy				log_must $ZFS mount $TESTPOOL
1253*d583b39bSJohn Wren Kennedy			fi
1254*d583b39bSJohn Wren Kennedy		else
1255*d583b39bSJohn Wren Kennedy			eval TESTPOOL$i=$ZONE_POOL/$ZONE_CTR$i
1256*d583b39bSJohn Wren Kennedy			if eval ! ismounted \$TESTPOOL$i; then
1257*d583b39bSJohn Wren Kennedy				log_must eval $ZFS mount \$TESTPOOL$i
1258*d583b39bSJohn Wren Kennedy			fi
1259*d583b39bSJohn Wren Kennedy		fi
1260*d583b39bSJohn Wren Kennedy		((i += 1))
1261*d583b39bSJohn Wren Kennedy	done
1262*d583b39bSJohn Wren Kennedy}
1263*d583b39bSJohn Wren Kennedy
1264*d583b39bSJohn Wren Kennedy#
1265*d583b39bSJohn Wren Kennedy# Verify a given disk is online or offline
1266*d583b39bSJohn Wren Kennedy#
1267*d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1268*d583b39bSJohn Wren Kennedy#
1269*d583b39bSJohn Wren Kennedyfunction check_state # pool disk state{online,offline}
1270*d583b39bSJohn Wren Kennedy{
1271*d583b39bSJohn Wren Kennedy	typeset pool=$1
1272*d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1273*d583b39bSJohn Wren Kennedy	typeset state=$3
1274*d583b39bSJohn Wren Kennedy
1275*d583b39bSJohn Wren Kennedy	$ZPOOL status -v $pool | grep "$disk"  \
1276*d583b39bSJohn Wren Kennedy	    | grep -i "$state" > /dev/null 2>&1
1277*d583b39bSJohn Wren Kennedy
1278*d583b39bSJohn Wren Kennedy	return $?
1279*d583b39bSJohn Wren Kennedy}
1280*d583b39bSJohn Wren Kennedy
1281*d583b39bSJohn Wren Kennedy#
1282*d583b39bSJohn Wren Kennedy# Get the mountpoint of snapshot
1283*d583b39bSJohn Wren Kennedy# For the snapshot use <mp_filesystem>/.zfs/snapshot/<snap>
1284*d583b39bSJohn Wren Kennedy# as its mountpoint
1285*d583b39bSJohn Wren Kennedy#
1286*d583b39bSJohn Wren Kennedyfunction snapshot_mountpoint
1287*d583b39bSJohn Wren Kennedy{
1288*d583b39bSJohn Wren Kennedy	typeset dataset=${1:-$TESTPOOL/$TESTFS@$TESTSNAP}
1289*d583b39bSJohn Wren Kennedy
1290*d583b39bSJohn Wren Kennedy	if [[ $dataset != *@* ]]; then
1291*d583b39bSJohn Wren Kennedy		log_fail "Error name of snapshot '$dataset'."
1292*d583b39bSJohn Wren Kennedy	fi
1293*d583b39bSJohn Wren Kennedy
1294*d583b39bSJohn Wren Kennedy	typeset fs=${dataset%@*}
1295*d583b39bSJohn Wren Kennedy	typeset snap=${dataset#*@}
1296*d583b39bSJohn Wren Kennedy
1297*d583b39bSJohn Wren Kennedy	if [[ -z $fs || -z $snap ]]; then
1298*d583b39bSJohn Wren Kennedy		log_fail "Error name of snapshot '$dataset'."
1299*d583b39bSJohn Wren Kennedy	fi
1300*d583b39bSJohn Wren Kennedy
1301*d583b39bSJohn Wren Kennedy	$ECHO $(get_prop mountpoint $fs)/.zfs/snapshot/$snap
1302*d583b39bSJohn Wren Kennedy}
1303*d583b39bSJohn Wren Kennedy
1304*d583b39bSJohn Wren Kennedy#
1305*d583b39bSJohn Wren Kennedy# Given a pool and file system, this function will verify the file system
1306*d583b39bSJohn Wren Kennedy# using the zdb internal tool. Note that the pool is exported and imported
1307*d583b39bSJohn Wren Kennedy# to ensure it has consistent state.
1308*d583b39bSJohn Wren Kennedy#
1309*d583b39bSJohn Wren Kennedyfunction verify_filesys # pool filesystem dir
1310*d583b39bSJohn Wren Kennedy{
1311*d583b39bSJohn Wren Kennedy	typeset pool="$1"
1312*d583b39bSJohn Wren Kennedy	typeset filesys="$2"
1313*d583b39bSJohn Wren Kennedy	typeset zdbout="/tmp/zdbout.$$"
1314*d583b39bSJohn Wren Kennedy
1315*d583b39bSJohn Wren Kennedy	shift
1316*d583b39bSJohn Wren Kennedy	shift
1317*d583b39bSJohn Wren Kennedy	typeset dirs=$@
1318*d583b39bSJohn Wren Kennedy	typeset search_path=""
1319*d583b39bSJohn Wren Kennedy
1320*d583b39bSJohn Wren Kennedy	log_note "Calling $ZDB to verify filesystem '$filesys'"
1321*d583b39bSJohn Wren Kennedy	$ZFS unmount -a > /dev/null 2>&1
1322*d583b39bSJohn Wren Kennedy	log_must $ZPOOL export $pool
1323*d583b39bSJohn Wren Kennedy
1324*d583b39bSJohn Wren Kennedy	if [[ -n $dirs ]] ; then
1325*d583b39bSJohn Wren Kennedy		for dir in $dirs ; do
1326*d583b39bSJohn Wren Kennedy			search_path="$search_path -d $dir"
1327*d583b39bSJohn Wren Kennedy		done
1328*d583b39bSJohn Wren Kennedy	fi
1329*d583b39bSJohn Wren Kennedy
1330*d583b39bSJohn Wren Kennedy	log_must $ZPOOL import $search_path $pool
1331*d583b39bSJohn Wren Kennedy
1332*d583b39bSJohn Wren Kennedy	$ZDB -cudi $filesys > $zdbout 2>&1
1333*d583b39bSJohn Wren Kennedy	if [[ $? != 0 ]]; then
1334*d583b39bSJohn Wren Kennedy		log_note "Output: $ZDB -cudi $filesys"
1335*d583b39bSJohn Wren Kennedy		$CAT $zdbout
1336*d583b39bSJohn Wren Kennedy		log_fail "$ZDB detected errors with: '$filesys'"
1337*d583b39bSJohn Wren Kennedy	fi
1338*d583b39bSJohn Wren Kennedy
1339*d583b39bSJohn Wren Kennedy	log_must $ZFS mount -a
1340*d583b39bSJohn Wren Kennedy	log_must $RM -rf $zdbout
1341*d583b39bSJohn Wren Kennedy}
1342*d583b39bSJohn Wren Kennedy
1343*d583b39bSJohn Wren Kennedy#
1344*d583b39bSJohn Wren Kennedy# Given a pool, and this function list all disks in the pool
1345*d583b39bSJohn Wren Kennedy#
1346*d583b39bSJohn Wren Kennedyfunction get_disklist # pool
1347*d583b39bSJohn Wren Kennedy{
1348*d583b39bSJohn Wren Kennedy	typeset disklist=""
1349*d583b39bSJohn Wren Kennedy
1350*d583b39bSJohn Wren Kennedy	disklist=$($ZPOOL iostat -v $1 | $NAWK '(NR >4) {print $1}' | \
1351*d583b39bSJohn Wren Kennedy	    $GREP -v "\-\-\-\-\-" | \
1352*d583b39bSJohn Wren Kennedy	    $EGREP -v -e "^(mirror|raidz1|raidz2|spare|log|cache)$")
1353*d583b39bSJohn Wren Kennedy
1354*d583b39bSJohn Wren Kennedy	$ECHO $disklist
1355*d583b39bSJohn Wren Kennedy}
1356*d583b39bSJohn Wren Kennedy
1357*d583b39bSJohn Wren Kennedy#
1358*d583b39bSJohn Wren Kennedy# Destroy all existing metadevices and state database
1359*d583b39bSJohn Wren Kennedy#
1360*d583b39bSJohn Wren Kennedyfunction destroy_metas
1361*d583b39bSJohn Wren Kennedy{
1362*d583b39bSJohn Wren Kennedy	typeset metad
1363*d583b39bSJohn Wren Kennedy
1364*d583b39bSJohn Wren Kennedy	for metad in $($METASTAT -p | $AWK '{print $1}'); do
1365*d583b39bSJohn Wren Kennedy		log_must $METACLEAR -rf $metad
1366*d583b39bSJohn Wren Kennedy	done
1367*d583b39bSJohn Wren Kennedy
1368*d583b39bSJohn Wren Kennedy	for metad in $($METADB | $CUT -f6 | $GREP dev | $UNIQ); do
1369*d583b39bSJohn Wren Kennedy		log_must $METADB -fd $metad
1370*d583b39bSJohn Wren Kennedy	done
1371*d583b39bSJohn Wren Kennedy}
1372*d583b39bSJohn Wren Kennedy
1373*d583b39bSJohn Wren Kennedy# /**
1374*d583b39bSJohn Wren Kennedy#  This function kills a given list of processes after a time period. We use
1375*d583b39bSJohn Wren Kennedy#  this in the stress tests instead of STF_TIMEOUT so that we can have processes
1376*d583b39bSJohn Wren Kennedy#  run for a fixed amount of time, yet still pass. Tests that hit STF_TIMEOUT
1377*d583b39bSJohn Wren Kennedy#  would be listed as FAIL, which we don't want : we're happy with stress tests
1378*d583b39bSJohn Wren Kennedy#  running for a certain amount of time, then finishing.
1379*d583b39bSJohn Wren Kennedy#
1380*d583b39bSJohn Wren Kennedy# @param $1 the time in seconds after which we should terminate these processes
1381*d583b39bSJohn Wren Kennedy# @param $2..$n the processes we wish to terminate.
1382*d583b39bSJohn Wren Kennedy# */
1383*d583b39bSJohn Wren Kennedyfunction stress_timeout
1384*d583b39bSJohn Wren Kennedy{
1385*d583b39bSJohn Wren Kennedy	typeset -i TIMEOUT=$1
1386*d583b39bSJohn Wren Kennedy	shift
1387*d583b39bSJohn Wren Kennedy	typeset cpids="$@"
1388*d583b39bSJohn Wren Kennedy
1389*d583b39bSJohn Wren Kennedy	log_note "Waiting for child processes($cpids). " \
1390*d583b39bSJohn Wren Kennedy		"It could last dozens of minutes, please be patient ..."
1391*d583b39bSJohn Wren Kennedy	log_must $SLEEP $TIMEOUT
1392*d583b39bSJohn Wren Kennedy
1393*d583b39bSJohn Wren Kennedy	log_note "Killing child processes after ${TIMEOUT} stress timeout."
1394*d583b39bSJohn Wren Kennedy	typeset pid
1395*d583b39bSJohn Wren Kennedy	for pid in $cpids; do
1396*d583b39bSJohn Wren Kennedy		$PS -p $pid > /dev/null 2>&1
1397*d583b39bSJohn Wren Kennedy		if (($? == 0)); then
1398*d583b39bSJohn Wren Kennedy			log_must $KILL -USR1 $pid
1399*d583b39bSJohn Wren Kennedy		fi
1400*d583b39bSJohn Wren Kennedy	done
1401*d583b39bSJohn Wren Kennedy}
1402*d583b39bSJohn Wren Kennedy
1403*d583b39bSJohn Wren Kennedy#
1404*d583b39bSJohn Wren Kennedy# Verify a given hotspare disk is inuse or avail
1405*d583b39bSJohn Wren Kennedy#
1406*d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1407*d583b39bSJohn Wren Kennedy#
1408*d583b39bSJohn Wren Kennedyfunction check_hotspare_state # pool disk state{inuse,avail}
1409*d583b39bSJohn Wren Kennedy{
1410*d583b39bSJohn Wren Kennedy	typeset pool=$1
1411*d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1412*d583b39bSJohn Wren Kennedy	typeset state=$3
1413*d583b39bSJohn Wren Kennedy
1414*d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk "spares")
1415*d583b39bSJohn Wren Kennedy
1416*d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1417*d583b39bSJohn Wren Kennedy		return 1
1418*d583b39bSJohn Wren Kennedy	fi
1419*d583b39bSJohn Wren Kennedy	return 0
1420*d583b39bSJohn Wren Kennedy}
1421*d583b39bSJohn Wren Kennedy
1422*d583b39bSJohn Wren Kennedy#
1423*d583b39bSJohn Wren Kennedy# Verify a given slog disk is inuse or avail
1424*d583b39bSJohn Wren Kennedy#
1425*d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1426*d583b39bSJohn Wren Kennedy#
1427*d583b39bSJohn Wren Kennedyfunction check_slog_state # pool disk state{online,offline,unavail}
1428*d583b39bSJohn Wren Kennedy{
1429*d583b39bSJohn Wren Kennedy	typeset pool=$1
1430*d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1431*d583b39bSJohn Wren Kennedy	typeset state=$3
1432*d583b39bSJohn Wren Kennedy
1433*d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk "logs")
1434*d583b39bSJohn Wren Kennedy
1435*d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1436*d583b39bSJohn Wren Kennedy		return 1
1437*d583b39bSJohn Wren Kennedy	fi
1438*d583b39bSJohn Wren Kennedy	return 0
1439*d583b39bSJohn Wren Kennedy}
1440*d583b39bSJohn Wren Kennedy
1441*d583b39bSJohn Wren Kennedy#
1442*d583b39bSJohn Wren Kennedy# Verify a given vdev disk is inuse or avail
1443*d583b39bSJohn Wren Kennedy#
1444*d583b39bSJohn Wren Kennedy# Return 0 is pool/disk matches expected state, 1 otherwise
1445*d583b39bSJohn Wren Kennedy#
1446*d583b39bSJohn Wren Kennedyfunction check_vdev_state # pool disk state{online,offline,unavail}
1447*d583b39bSJohn Wren Kennedy{
1448*d583b39bSJohn Wren Kennedy	typeset pool=$1
1449*d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
1450*d583b39bSJohn Wren Kennedy	typeset state=$3
1451*d583b39bSJohn Wren Kennedy
1452*d583b39bSJohn Wren Kennedy	cur_state=$(get_device_state $pool $disk)
1453*d583b39bSJohn Wren Kennedy
1454*d583b39bSJohn Wren Kennedy	if [[ $state != ${cur_state} ]]; then
1455*d583b39bSJohn Wren Kennedy		return 1
1456*d583b39bSJohn Wren Kennedy	fi
1457*d583b39bSJohn Wren Kennedy	return 0
1458*d583b39bSJohn Wren Kennedy}
1459*d583b39bSJohn Wren Kennedy
1460*d583b39bSJohn Wren Kennedy#
1461*d583b39bSJohn Wren Kennedy# Check the output of 'zpool status -v <pool>',
1462*d583b39bSJohn Wren Kennedy# and to see if the content of <token> contain the <keyword> specified.
1463*d583b39bSJohn Wren Kennedy#
1464*d583b39bSJohn Wren Kennedy# Return 0 is contain, 1 otherwise
1465*d583b39bSJohn Wren Kennedy#
1466*d583b39bSJohn Wren Kennedyfunction check_pool_status # pool token keyword
1467*d583b39bSJohn Wren Kennedy{
1468*d583b39bSJohn Wren Kennedy	typeset pool=$1
1469*d583b39bSJohn Wren Kennedy	typeset token=$2
1470*d583b39bSJohn Wren Kennedy	typeset keyword=$3
1471*d583b39bSJohn Wren Kennedy
1472*d583b39bSJohn Wren Kennedy	$ZPOOL status -v "$pool" 2>/dev/null | $NAWK -v token="$token:" '
1473*d583b39bSJohn Wren Kennedy		($1==token) {print $0}' \
1474*d583b39bSJohn Wren Kennedy	| $GREP -i "$keyword" > /dev/null 2>&1
1475*d583b39bSJohn Wren Kennedy
1476*d583b39bSJohn Wren Kennedy	return $?
1477*d583b39bSJohn Wren Kennedy}
1478*d583b39bSJohn Wren Kennedy
1479*d583b39bSJohn Wren Kennedy#
1480*d583b39bSJohn Wren Kennedy# These 5 following functions are instance of check_pool_status()
1481*d583b39bSJohn Wren Kennedy#	is_pool_resilvering - to check if the pool is resilver in progress
1482*d583b39bSJohn Wren Kennedy#	is_pool_resilvered - to check if the pool is resilver completed
1483*d583b39bSJohn Wren Kennedy#	is_pool_scrubbing - to check if the pool is scrub in progress
1484*d583b39bSJohn Wren Kennedy#	is_pool_scrubbed - to check if the pool is scrub completed
1485*d583b39bSJohn Wren Kennedy#	is_pool_scrub_stopped - to check if the pool is scrub stopped
1486*d583b39bSJohn Wren Kennedy#
1487*d583b39bSJohn Wren Kennedyfunction is_pool_resilvering #pool
1488*d583b39bSJohn Wren Kennedy{
1489*d583b39bSJohn Wren Kennedy	check_pool_status "$1" "scan" "resilver in progress since "
1490*d583b39bSJohn Wren Kennedy	return $?
1491*d583b39bSJohn Wren Kennedy}
1492*d583b39bSJohn Wren Kennedy
1493*d583b39bSJohn Wren Kennedyfunction is_pool_resilvered #pool
1494*d583b39bSJohn Wren Kennedy{
1495*d583b39bSJohn Wren Kennedy	check_pool_status "$1" "scan" "resilvered "
1496*d583b39bSJohn Wren Kennedy	return $?
1497*d583b39bSJohn Wren Kennedy}
1498*d583b39bSJohn Wren Kennedy
1499*d583b39bSJohn Wren Kennedyfunction is_pool_scrubbing #pool
1500*d583b39bSJohn Wren Kennedy{
1501*d583b39bSJohn Wren Kennedy	check_pool_status "$1" "scan" "scrub in progress since "
1502*d583b39bSJohn Wren Kennedy	return $?
1503*d583b39bSJohn Wren Kennedy}
1504*d583b39bSJohn Wren Kennedy
1505*d583b39bSJohn Wren Kennedyfunction is_pool_scrubbed #pool
1506*d583b39bSJohn Wren Kennedy{
1507*d583b39bSJohn Wren Kennedy	check_pool_status "$1" "scan" "scrub repaired"
1508*d583b39bSJohn Wren Kennedy	return $?
1509*d583b39bSJohn Wren Kennedy}
1510*d583b39bSJohn Wren Kennedy
1511*d583b39bSJohn Wren Kennedyfunction is_pool_scrub_stopped #pool
1512*d583b39bSJohn Wren Kennedy{
1513*d583b39bSJohn Wren Kennedy	check_pool_status "$1" "scan" "scrub canceled"
1514*d583b39bSJohn Wren Kennedy	return $?
1515*d583b39bSJohn Wren Kennedy}
1516*d583b39bSJohn Wren Kennedy
1517*d583b39bSJohn Wren Kennedy#
1518*d583b39bSJohn Wren Kennedy# Use create_pool()/destroy_pool() to clean up the infomation in
1519*d583b39bSJohn Wren Kennedy# in the given disk to avoid slice overlapping.
1520*d583b39bSJohn Wren Kennedy#
1521*d583b39bSJohn Wren Kennedyfunction cleanup_devices #vdevs
1522*d583b39bSJohn Wren Kennedy{
1523*d583b39bSJohn Wren Kennedy	typeset pool="foopool$$"
1524*d583b39bSJohn Wren Kennedy
1525*d583b39bSJohn Wren Kennedy	if poolexists $pool ; then
1526*d583b39bSJohn Wren Kennedy		destroy_pool $pool
1527*d583b39bSJohn Wren Kennedy	fi
1528*d583b39bSJohn Wren Kennedy
1529*d583b39bSJohn Wren Kennedy	create_pool $pool $@
1530*d583b39bSJohn Wren Kennedy	destroy_pool $pool
1531*d583b39bSJohn Wren Kennedy
1532*d583b39bSJohn Wren Kennedy	return 0
1533*d583b39bSJohn Wren Kennedy}
1534*d583b39bSJohn Wren Kennedy
1535*d583b39bSJohn Wren Kennedy#
1536*d583b39bSJohn Wren Kennedy# Verify the rsh connectivity to each remote host in RHOSTS.
1537*d583b39bSJohn Wren Kennedy#
1538*d583b39bSJohn Wren Kennedy# Return 0 if remote host is accessible; otherwise 1.
1539*d583b39bSJohn Wren Kennedy# $1 remote host name
1540*d583b39bSJohn Wren Kennedy# $2 username
1541*d583b39bSJohn Wren Kennedy#
1542*d583b39bSJohn Wren Kennedyfunction verify_rsh_connect #rhost, username
1543*d583b39bSJohn Wren Kennedy{
1544*d583b39bSJohn Wren Kennedy	typeset rhost=$1
1545*d583b39bSJohn Wren Kennedy	typeset username=$2
1546*d583b39bSJohn Wren Kennedy	typeset rsh_cmd="$RSH -n"
1547*d583b39bSJohn Wren Kennedy	typeset cur_user=
1548*d583b39bSJohn Wren Kennedy
1549*d583b39bSJohn Wren Kennedy	$GETENT hosts $rhost >/dev/null 2>&1
1550*d583b39bSJohn Wren Kennedy	if (($? != 0)); then
1551*d583b39bSJohn Wren Kennedy		log_note "$rhost cannot be found from" \
1552*d583b39bSJohn Wren Kennedy			"administrative database."
1553*d583b39bSJohn Wren Kennedy		return 1
1554*d583b39bSJohn Wren Kennedy	fi
1555*d583b39bSJohn Wren Kennedy
1556*d583b39bSJohn Wren Kennedy	$PING $rhost 3 >/dev/null 2>&1
1557*d583b39bSJohn Wren Kennedy	if (($? != 0)); then
1558*d583b39bSJohn Wren Kennedy		log_note "$rhost is not reachable."
1559*d583b39bSJohn Wren Kennedy		return 1
1560*d583b39bSJohn Wren Kennedy	fi
1561*d583b39bSJohn Wren Kennedy
1562*d583b39bSJohn Wren Kennedy	if ((${#username} != 0)); then
1563*d583b39bSJohn Wren Kennedy		rsh_cmd="$rsh_cmd -l $username"
1564*d583b39bSJohn Wren Kennedy		cur_user="given user \"$username\""
1565*d583b39bSJohn Wren Kennedy	else
1566*d583b39bSJohn Wren Kennedy		cur_user="current user \"`$LOGNAME`\""
1567*d583b39bSJohn Wren Kennedy	fi
1568*d583b39bSJohn Wren Kennedy
1569*d583b39bSJohn Wren Kennedy	 if ! $rsh_cmd $rhost $TRUE; then
1570*d583b39bSJohn Wren Kennedy		log_note "$RSH to $rhost is not accessible" \
1571*d583b39bSJohn Wren Kennedy			"with $cur_user."
1572*d583b39bSJohn Wren Kennedy		return 1
1573*d583b39bSJohn Wren Kennedy	fi
1574*d583b39bSJohn Wren Kennedy
1575*d583b39bSJohn Wren Kennedy	return 0
1576*d583b39bSJohn Wren Kennedy}
1577*d583b39bSJohn Wren Kennedy
1578*d583b39bSJohn Wren Kennedy#
1579*d583b39bSJohn Wren Kennedy# Verify the remote host connection via rsh after rebooting
1580*d583b39bSJohn Wren Kennedy# $1 remote host
1581*d583b39bSJohn Wren Kennedy#
1582*d583b39bSJohn Wren Kennedyfunction verify_remote
1583*d583b39bSJohn Wren Kennedy{
1584*d583b39bSJohn Wren Kennedy	rhost=$1
1585*d583b39bSJohn Wren Kennedy
1586*d583b39bSJohn Wren Kennedy	#
1587*d583b39bSJohn Wren Kennedy	# The following loop waits for the remote system rebooting.
1588*d583b39bSJohn Wren Kennedy	# Each iteration will wait for 150 seconds. there are
1589*d583b39bSJohn Wren Kennedy	# total 5 iterations, so the total timeout value will
1590*d583b39bSJohn Wren Kennedy	# be 12.5  minutes for the system rebooting. This number
1591*d583b39bSJohn Wren Kennedy	# is an approxiate number.
1592*d583b39bSJohn Wren Kennedy	#
1593*d583b39bSJohn Wren Kennedy	typeset -i count=0
1594*d583b39bSJohn Wren Kennedy	while ! verify_rsh_connect $rhost; do
1595*d583b39bSJohn Wren Kennedy		sleep 150
1596*d583b39bSJohn Wren Kennedy		((count = count + 1))
1597*d583b39bSJohn Wren Kennedy		if ((count > 5)); then
1598*d583b39bSJohn Wren Kennedy			return 1
1599*d583b39bSJohn Wren Kennedy		fi
1600*d583b39bSJohn Wren Kennedy	done
1601*d583b39bSJohn Wren Kennedy	return 0
1602*d583b39bSJohn Wren Kennedy}
1603*d583b39bSJohn Wren Kennedy
1604*d583b39bSJohn Wren Kennedy#
1605*d583b39bSJohn Wren Kennedy# Replacement function for /usr/bin/rsh. This function will include
1606*d583b39bSJohn Wren Kennedy# the /usr/bin/rsh and meanwhile return the execution status of the
1607*d583b39bSJohn Wren Kennedy# last command.
1608*d583b39bSJohn Wren Kennedy#
1609*d583b39bSJohn Wren Kennedy# $1 usrname passing down to -l option of /usr/bin/rsh
1610*d583b39bSJohn Wren Kennedy# $2 remote machine hostname
1611*d583b39bSJohn Wren Kennedy# $3... command string
1612*d583b39bSJohn Wren Kennedy#
1613*d583b39bSJohn Wren Kennedy
1614*d583b39bSJohn Wren Kennedyfunction rsh_status
1615*d583b39bSJohn Wren Kennedy{
1616*d583b39bSJohn Wren Kennedy	typeset ruser=$1
1617*d583b39bSJohn Wren Kennedy	typeset rhost=$2
1618*d583b39bSJohn Wren Kennedy	typeset -i ret=0
1619*d583b39bSJohn Wren Kennedy	typeset cmd_str=""
1620*d583b39bSJohn Wren Kennedy	typeset rsh_str=""
1621*d583b39bSJohn Wren Kennedy
1622*d583b39bSJohn Wren Kennedy	shift; shift
1623*d583b39bSJohn Wren Kennedy	cmd_str="$@"
1624*d583b39bSJohn Wren Kennedy
1625*d583b39bSJohn Wren Kennedy	err_file=/tmp/${rhost}.$$.err
1626*d583b39bSJohn Wren Kennedy	if ((${#ruser} == 0)); then
1627*d583b39bSJohn Wren Kennedy		rsh_str="$RSH -n"
1628*d583b39bSJohn Wren Kennedy	else
1629*d583b39bSJohn Wren Kennedy		rsh_str="$RSH -n -l $ruser"
1630*d583b39bSJohn Wren Kennedy	fi
1631*d583b39bSJohn Wren Kennedy
1632*d583b39bSJohn Wren Kennedy	$rsh_str $rhost /usr/bin/ksh -c "'$cmd_str; \
1633*d583b39bSJohn Wren Kennedy		print -u 2 \"status=\$?\"'" \
1634*d583b39bSJohn Wren Kennedy		>/dev/null 2>$err_file
1635*d583b39bSJohn Wren Kennedy	ret=$?
1636*d583b39bSJohn Wren Kennedy	if (($ret != 0)); then
1637*d583b39bSJohn Wren Kennedy		$CAT $err_file
1638*d583b39bSJohn Wren Kennedy		$RM -f $std_file $err_file
1639*d583b39bSJohn Wren Kennedy		log_fail  "$RSH itself failed with exit code $ret..."
1640*d583b39bSJohn Wren Kennedy	fi
1641*d583b39bSJohn Wren Kennedy
1642*d583b39bSJohn Wren Kennedy	 ret=$($GREP -v 'print -u 2' $err_file | $GREP 'status=' | \
1643*d583b39bSJohn Wren Kennedy		$CUT -d= -f2)
1644*d583b39bSJohn Wren Kennedy	(($ret != 0)) && $CAT $err_file >&2
1645*d583b39bSJohn Wren Kennedy
1646*d583b39bSJohn Wren Kennedy	$RM -f $err_file >/dev/null 2>&1
1647*d583b39bSJohn Wren Kennedy	return $ret
1648*d583b39bSJohn Wren Kennedy}
1649*d583b39bSJohn Wren Kennedy
1650*d583b39bSJohn Wren Kennedy#
1651*d583b39bSJohn Wren Kennedy# Get the SUNWstc-fs-zfs package installation path in a remote host
1652*d583b39bSJohn Wren Kennedy# $1 remote host name
1653*d583b39bSJohn Wren Kennedy#
1654*d583b39bSJohn Wren Kennedyfunction get_remote_pkgpath
1655*d583b39bSJohn Wren Kennedy{
1656*d583b39bSJohn Wren Kennedy	typeset rhost=$1
1657*d583b39bSJohn Wren Kennedy	typeset pkgpath=""
1658*d583b39bSJohn Wren Kennedy
1659*d583b39bSJohn Wren Kennedy	pkgpath=$($RSH -n $rhost "$PKGINFO -l SUNWstc-fs-zfs | $GREP BASEDIR: |\
1660*d583b39bSJohn Wren Kennedy			$CUT -d: -f2")
1661*d583b39bSJohn Wren Kennedy
1662*d583b39bSJohn Wren Kennedy	$ECHO $pkgpath
1663*d583b39bSJohn Wren Kennedy}
1664*d583b39bSJohn Wren Kennedy
1665*d583b39bSJohn Wren Kennedy#/**
1666*d583b39bSJohn Wren Kennedy# A function to find and locate free disks on a system or from given
1667*d583b39bSJohn Wren Kennedy# disks as the parameter. It works by locating disks that are in use
1668*d583b39bSJohn Wren Kennedy# as swap devices, SVM devices, and dump devices, and also disks
1669*d583b39bSJohn Wren Kennedy# listed in /etc/vfstab
1670*d583b39bSJohn Wren Kennedy#
1671*d583b39bSJohn Wren Kennedy# $@ given disks to find which are free, default is all disks in
1672*d583b39bSJohn Wren Kennedy# the test system
1673*d583b39bSJohn Wren Kennedy#
1674*d583b39bSJohn Wren Kennedy# @return a string containing the list of available disks
1675*d583b39bSJohn Wren Kennedy#*/
1676*d583b39bSJohn Wren Kennedyfunction find_disks
1677*d583b39bSJohn Wren Kennedy{
1678*d583b39bSJohn Wren Kennedy	sfi=/tmp/swaplist.$$
1679*d583b39bSJohn Wren Kennedy	msi=/tmp/metastat.$$
1680*d583b39bSJohn Wren Kennedy	dmpi=/tmp/dumpdev.$$
1681*d583b39bSJohn Wren Kennedy	max_finddisksnum=${MAX_FINDDISKSNUM:-6}
1682*d583b39bSJohn Wren Kennedy
1683*d583b39bSJohn Wren Kennedy	$SWAP -l > $sfi
1684*d583b39bSJohn Wren Kennedy	$METASTAT -c > $msi 2>/dev/null
1685*d583b39bSJohn Wren Kennedy	$DUMPADM > $dmpi 2>/dev/null
1686*d583b39bSJohn Wren Kennedy
1687*d583b39bSJohn Wren Kennedy# write an awk script that can process the output of format
1688*d583b39bSJohn Wren Kennedy# to produce a list of disks we know about. Note that we have
1689*d583b39bSJohn Wren Kennedy# to escape "$2" so that the shell doesn't interpret it while
1690*d583b39bSJohn Wren Kennedy# we're creating the awk script.
1691*d583b39bSJohn Wren Kennedy# -------------------
1692*d583b39bSJohn Wren Kennedy	$CAT > /tmp/find_disks.awk <<EOF
1693*d583b39bSJohn Wren Kennedy#!/bin/nawk -f
1694*d583b39bSJohn Wren Kennedy	BEGIN { FS="."; }
1695*d583b39bSJohn Wren Kennedy
1696*d583b39bSJohn Wren Kennedy	/^Specify disk/{
1697*d583b39bSJohn Wren Kennedy		searchdisks=0;
1698*d583b39bSJohn Wren Kennedy	}
1699*d583b39bSJohn Wren Kennedy
1700*d583b39bSJohn Wren Kennedy	{
1701*d583b39bSJohn Wren Kennedy		if (searchdisks && \$2 !~ "^$"){
1702*d583b39bSJohn Wren Kennedy			split(\$2,arr," ");
1703*d583b39bSJohn Wren Kennedy			print arr[1];
1704*d583b39bSJohn Wren Kennedy		}
1705*d583b39bSJohn Wren Kennedy	}
1706*d583b39bSJohn Wren Kennedy
1707*d583b39bSJohn Wren Kennedy	/^AVAILABLE DISK SELECTIONS:/{
1708*d583b39bSJohn Wren Kennedy		searchdisks=1;
1709*d583b39bSJohn Wren Kennedy	}
1710*d583b39bSJohn Wren KennedyEOF
1711*d583b39bSJohn Wren Kennedy#---------------------
1712*d583b39bSJohn Wren Kennedy
1713*d583b39bSJohn Wren Kennedy	$CHMOD 755 /tmp/find_disks.awk
1714*d583b39bSJohn Wren Kennedy	disks=${@:-$($ECHO "" | $FORMAT -e 2>/dev/null | /tmp/find_disks.awk)}
1715*d583b39bSJohn Wren Kennedy	$RM /tmp/find_disks.awk
1716*d583b39bSJohn Wren Kennedy
1717*d583b39bSJohn Wren Kennedy	unused=""
1718*d583b39bSJohn Wren Kennedy	for disk in $disks; do
1719*d583b39bSJohn Wren Kennedy	# Check for mounted
1720*d583b39bSJohn Wren Kennedy		$GREP "${disk}[sp]" /etc/mnttab >/dev/null
1721*d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1722*d583b39bSJohn Wren Kennedy	# Check for swap
1723*d583b39bSJohn Wren Kennedy		$GREP "${disk}[sp]" $sfi >/dev/null
1724*d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1725*d583b39bSJohn Wren Kennedy	# Check for SVM
1726*d583b39bSJohn Wren Kennedy		$GREP "${disk}" $msi >/dev/null
1727*d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1728*d583b39bSJohn Wren Kennedy	# check for dump device
1729*d583b39bSJohn Wren Kennedy		$GREP "${disk}[sp]" $dmpi >/dev/null
1730*d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1731*d583b39bSJohn Wren Kennedy	# check to see if this disk hasn't been explicitly excluded
1732*d583b39bSJohn Wren Kennedy	# by a user-set environment variable
1733*d583b39bSJohn Wren Kennedy		$ECHO "${ZFS_HOST_DEVICES_IGNORE}" | $GREP "${disk}" > /dev/null
1734*d583b39bSJohn Wren Kennedy		(($? == 0)) && continue
1735*d583b39bSJohn Wren Kennedy		unused_candidates="$unused_candidates $disk"
1736*d583b39bSJohn Wren Kennedy	done
1737*d583b39bSJohn Wren Kennedy	$RM $sfi
1738*d583b39bSJohn Wren Kennedy	$RM $msi
1739*d583b39bSJohn Wren Kennedy	$RM $dmpi
1740*d583b39bSJohn Wren Kennedy
1741*d583b39bSJohn Wren Kennedy# now just check to see if those disks do actually exist
1742*d583b39bSJohn Wren Kennedy# by looking for a device pointing to the first slice in
1743*d583b39bSJohn Wren Kennedy# each case. limit the number to max_finddisksnum
1744*d583b39bSJohn Wren Kennedy	count=0
1745*d583b39bSJohn Wren Kennedy	for disk in $unused_candidates; do
1746*d583b39bSJohn Wren Kennedy		if [ -b /dev/dsk/${disk}s0 ]; then
1747*d583b39bSJohn Wren Kennedy		if [ $count -lt $max_finddisksnum ]; then
1748*d583b39bSJohn Wren Kennedy			unused="$unused $disk"
1749*d583b39bSJohn Wren Kennedy			# do not impose limit if $@ is provided
1750*d583b39bSJohn Wren Kennedy			[[ -z $@ ]] && ((count = count + 1))
1751*d583b39bSJohn Wren Kennedy		fi
1752*d583b39bSJohn Wren Kennedy		fi
1753*d583b39bSJohn Wren Kennedy	done
1754*d583b39bSJohn Wren Kennedy
1755*d583b39bSJohn Wren Kennedy# finally, return our disk list
1756*d583b39bSJohn Wren Kennedy	$ECHO $unused
1757*d583b39bSJohn Wren Kennedy}
1758*d583b39bSJohn Wren Kennedy
1759*d583b39bSJohn Wren Kennedy#
1760*d583b39bSJohn Wren Kennedy# Add specified user to specified group
1761*d583b39bSJohn Wren Kennedy#
1762*d583b39bSJohn Wren Kennedy# $1 group name
1763*d583b39bSJohn Wren Kennedy# $2 user name
1764*d583b39bSJohn Wren Kennedy# $3 base of the homedir (optional)
1765*d583b39bSJohn Wren Kennedy#
1766*d583b39bSJohn Wren Kennedyfunction add_user #<group_name> <user_name> <basedir>
1767*d583b39bSJohn Wren Kennedy{
1768*d583b39bSJohn Wren Kennedy	typeset gname=$1
1769*d583b39bSJohn Wren Kennedy	typeset uname=$2
1770*d583b39bSJohn Wren Kennedy	typeset basedir=${3:-"/var/tmp"}
1771*d583b39bSJohn Wren Kennedy
1772*d583b39bSJohn Wren Kennedy	if ((${#gname} == 0 || ${#uname} == 0)); then
1773*d583b39bSJohn Wren Kennedy		log_fail "group name or user name are not defined."
1774*d583b39bSJohn Wren Kennedy	fi
1775*d583b39bSJohn Wren Kennedy
1776*d583b39bSJohn Wren Kennedy	log_must $USERADD -g $gname -d $basedir/$uname -m $uname
1777*d583b39bSJohn Wren Kennedy
1778*d583b39bSJohn Wren Kennedy	return 0
1779*d583b39bSJohn Wren Kennedy}
1780*d583b39bSJohn Wren Kennedy
1781*d583b39bSJohn Wren Kennedy#
1782*d583b39bSJohn Wren Kennedy# Delete the specified user.
1783*d583b39bSJohn Wren Kennedy#
1784*d583b39bSJohn Wren Kennedy# $1 login name
1785*d583b39bSJohn Wren Kennedy# $2 base of the homedir (optional)
1786*d583b39bSJohn Wren Kennedy#
1787*d583b39bSJohn Wren Kennedyfunction del_user #<logname> <basedir>
1788*d583b39bSJohn Wren Kennedy{
1789*d583b39bSJohn Wren Kennedy	typeset user=$1
1790*d583b39bSJohn Wren Kennedy	typeset basedir=${2:-"/var/tmp"}
1791*d583b39bSJohn Wren Kennedy
1792*d583b39bSJohn Wren Kennedy	if ((${#user} == 0)); then
1793*d583b39bSJohn Wren Kennedy		log_fail "login name is necessary."
1794*d583b39bSJohn Wren Kennedy	fi
1795*d583b39bSJohn Wren Kennedy
1796*d583b39bSJohn Wren Kennedy	if $ID $user > /dev/null 2>&1; then
1797*d583b39bSJohn Wren Kennedy		log_must $USERDEL $user
1798*d583b39bSJohn Wren Kennedy	fi
1799*d583b39bSJohn Wren Kennedy
1800*d583b39bSJohn Wren Kennedy	[[ -d $basedir/$user ]] && $RM -fr $basedir/$user
1801*d583b39bSJohn Wren Kennedy
1802*d583b39bSJohn Wren Kennedy	return 0
1803*d583b39bSJohn Wren Kennedy}
1804*d583b39bSJohn Wren Kennedy
1805*d583b39bSJohn Wren Kennedy#
1806*d583b39bSJohn Wren Kennedy# Select valid gid and create specified group.
1807*d583b39bSJohn Wren Kennedy#
1808*d583b39bSJohn Wren Kennedy# $1 group name
1809*d583b39bSJohn Wren Kennedy#
1810*d583b39bSJohn Wren Kennedyfunction add_group #<group_name>
1811*d583b39bSJohn Wren Kennedy{
1812*d583b39bSJohn Wren Kennedy	typeset group=$1
1813*d583b39bSJohn Wren Kennedy
1814*d583b39bSJohn Wren Kennedy	if ((${#group} == 0)); then
1815*d583b39bSJohn Wren Kennedy		log_fail "group name is necessary."
1816*d583b39bSJohn Wren Kennedy	fi
1817*d583b39bSJohn Wren Kennedy
1818*d583b39bSJohn Wren Kennedy	# Assign 100 as the base gid
1819*d583b39bSJohn Wren Kennedy	typeset -i gid=100
1820*d583b39bSJohn Wren Kennedy	while true; do
1821*d583b39bSJohn Wren Kennedy		$GROUPADD -g $gid $group > /dev/null 2>&1
1822*d583b39bSJohn Wren Kennedy		typeset -i ret=$?
1823*d583b39bSJohn Wren Kennedy		case $ret in
1824*d583b39bSJohn Wren Kennedy			0) return 0 ;;
1825*d583b39bSJohn Wren Kennedy			# The gid is not  unique
1826*d583b39bSJohn Wren Kennedy			4) ((gid += 1)) ;;
1827*d583b39bSJohn Wren Kennedy			*) return 1 ;;
1828*d583b39bSJohn Wren Kennedy		esac
1829*d583b39bSJohn Wren Kennedy	done
1830*d583b39bSJohn Wren Kennedy}
1831*d583b39bSJohn Wren Kennedy
1832*d583b39bSJohn Wren Kennedy#
1833*d583b39bSJohn Wren Kennedy# Delete the specified group.
1834*d583b39bSJohn Wren Kennedy#
1835*d583b39bSJohn Wren Kennedy# $1 group name
1836*d583b39bSJohn Wren Kennedy#
1837*d583b39bSJohn Wren Kennedyfunction del_group #<group_name>
1838*d583b39bSJohn Wren Kennedy{
1839*d583b39bSJohn Wren Kennedy	typeset grp=$1
1840*d583b39bSJohn Wren Kennedy	if ((${#grp} == 0)); then
1841*d583b39bSJohn Wren Kennedy		log_fail "group name is necessary."
1842*d583b39bSJohn Wren Kennedy	fi
1843*d583b39bSJohn Wren Kennedy
1844*d583b39bSJohn Wren Kennedy	$GROUPMOD -n $grp $grp > /dev/null 2>&1
1845*d583b39bSJohn Wren Kennedy	typeset -i ret=$?
1846*d583b39bSJohn Wren Kennedy	case $ret in
1847*d583b39bSJohn Wren Kennedy		# Group does not exist.
1848*d583b39bSJohn Wren Kennedy		6) return 0 ;;
1849*d583b39bSJohn Wren Kennedy		# Name already exists as a group name
1850*d583b39bSJohn Wren Kennedy		9) log_must $GROUPDEL $grp ;;
1851*d583b39bSJohn Wren Kennedy		*) return 1 ;;
1852*d583b39bSJohn Wren Kennedy	esac
1853*d583b39bSJohn Wren Kennedy
1854*d583b39bSJohn Wren Kennedy	return 0
1855*d583b39bSJohn Wren Kennedy}
1856*d583b39bSJohn Wren Kennedy
1857*d583b39bSJohn Wren Kennedy#
1858*d583b39bSJohn Wren Kennedy# This function will return true if it's safe to destroy the pool passed
1859*d583b39bSJohn Wren Kennedy# as argument 1. It checks for pools based on zvols and files, and also
1860*d583b39bSJohn Wren Kennedy# files contained in a pool that may have a different mountpoint.
1861*d583b39bSJohn Wren Kennedy#
1862*d583b39bSJohn Wren Kennedyfunction safe_to_destroy_pool { # $1 the pool name
1863*d583b39bSJohn Wren Kennedy
1864*d583b39bSJohn Wren Kennedy	typeset pool=""
1865*d583b39bSJohn Wren Kennedy	typeset DONT_DESTROY=""
1866*d583b39bSJohn Wren Kennedy
1867*d583b39bSJohn Wren Kennedy	# We check that by deleting the $1 pool, we're not
1868*d583b39bSJohn Wren Kennedy	# going to pull the rug out from other pools. Do this
1869*d583b39bSJohn Wren Kennedy	# by looking at all other pools, ensuring that they
1870*d583b39bSJohn Wren Kennedy	# aren't built from files or zvols contained in this pool.
1871*d583b39bSJohn Wren Kennedy
1872*d583b39bSJohn Wren Kennedy	for pool in $($ZPOOL list -H -o name)
1873*d583b39bSJohn Wren Kennedy	do
1874*d583b39bSJohn Wren Kennedy		ALTMOUNTPOOL=""
1875*d583b39bSJohn Wren Kennedy
1876*d583b39bSJohn Wren Kennedy		# this is a list of the top-level directories in each of the
1877*d583b39bSJohn Wren Kennedy		# files that make up the path to the files the pool is based on
1878*d583b39bSJohn Wren Kennedy		FILEPOOL=$($ZPOOL status -v $pool | $GREP /$1/ | \
1879*d583b39bSJohn Wren Kennedy			$AWK '{print $1}')
1880*d583b39bSJohn Wren Kennedy
1881*d583b39bSJohn Wren Kennedy		# this is a list of the zvols that make up the pool
1882*d583b39bSJohn Wren Kennedy		ZVOLPOOL=$($ZPOOL status -v $pool | $GREP "/dev/zvol/dsk/$1$" \
1883*d583b39bSJohn Wren Kennedy		    | $AWK '{print $1}')
1884*d583b39bSJohn Wren Kennedy
1885*d583b39bSJohn Wren Kennedy		# also want to determine if it's a file-based pool using an
1886*d583b39bSJohn Wren Kennedy		# alternate mountpoint...
1887*d583b39bSJohn Wren Kennedy		POOL_FILE_DIRS=$($ZPOOL status -v $pool | \
1888*d583b39bSJohn Wren Kennedy					$GREP / | $AWK '{print $1}' | \
1889*d583b39bSJohn Wren Kennedy					$AWK -F/ '{print $2}' | $GREP -v "dev")
1890*d583b39bSJohn Wren Kennedy
1891*d583b39bSJohn Wren Kennedy		for pooldir in $POOL_FILE_DIRS
1892*d583b39bSJohn Wren Kennedy		do
1893*d583b39bSJohn Wren Kennedy			OUTPUT=$($ZFS list -H -r -o mountpoint $1 | \
1894*d583b39bSJohn Wren Kennedy					$GREP "${pooldir}$" | $AWK '{print $1}')
1895*d583b39bSJohn Wren Kennedy
1896*d583b39bSJohn Wren Kennedy			ALTMOUNTPOOL="${ALTMOUNTPOOL}${OUTPUT}"
1897*d583b39bSJohn Wren Kennedy		done
1898*d583b39bSJohn Wren Kennedy
1899*d583b39bSJohn Wren Kennedy
1900*d583b39bSJohn Wren Kennedy		if [ ! -z "$ZVOLPOOL" ]
1901*d583b39bSJohn Wren Kennedy		then
1902*d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
1903*d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $ZVOLPOOL on $1"
1904*d583b39bSJohn Wren Kennedy		fi
1905*d583b39bSJohn Wren Kennedy
1906*d583b39bSJohn Wren Kennedy		if [ ! -z "$FILEPOOL" ]
1907*d583b39bSJohn Wren Kennedy		then
1908*d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
1909*d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $FILEPOOL on $1"
1910*d583b39bSJohn Wren Kennedy		fi
1911*d583b39bSJohn Wren Kennedy
1912*d583b39bSJohn Wren Kennedy		if [ ! -z "$ALTMOUNTPOOL" ]
1913*d583b39bSJohn Wren Kennedy		then
1914*d583b39bSJohn Wren Kennedy			DONT_DESTROY="true"
1915*d583b39bSJohn Wren Kennedy			log_note "Pool $pool is built from $ALTMOUNTPOOL on $1"
1916*d583b39bSJohn Wren Kennedy		fi
1917*d583b39bSJohn Wren Kennedy	done
1918*d583b39bSJohn Wren Kennedy
1919*d583b39bSJohn Wren Kennedy	if [ -z "${DONT_DESTROY}" ]
1920*d583b39bSJohn Wren Kennedy	then
1921*d583b39bSJohn Wren Kennedy		return 0
1922*d583b39bSJohn Wren Kennedy	else
1923*d583b39bSJohn Wren Kennedy		log_note "Warning: it is not safe to destroy $1!"
1924*d583b39bSJohn Wren Kennedy		return 1
1925*d583b39bSJohn Wren Kennedy	fi
1926*d583b39bSJohn Wren Kennedy}
1927*d583b39bSJohn Wren Kennedy
1928*d583b39bSJohn Wren Kennedy#
1929*d583b39bSJohn Wren Kennedy# Get IP address of hostname
1930*d583b39bSJohn Wren Kennedy# $1 hostname
1931*d583b39bSJohn Wren Kennedy#
1932*d583b39bSJohn Wren Kennedyfunction getipbyhost
1933*d583b39bSJohn Wren Kennedy{
1934*d583b39bSJohn Wren Kennedy	typeset ip
1935*d583b39bSJohn Wren Kennedy	ip=`$ARP $1 2>/dev/null | $AWK -F\) '{print $1}' \
1936*d583b39bSJohn Wren Kennedy		| $AWK -F\('{print $2}'`
1937*d583b39bSJohn Wren Kennedy	$ECHO $ip
1938*d583b39bSJohn Wren Kennedy}
1939*d583b39bSJohn Wren Kennedy
1940*d583b39bSJohn Wren Kennedy#
1941*d583b39bSJohn Wren Kennedy# Setup iSCSI initiator to target
1942*d583b39bSJohn Wren Kennedy# $1 target hostname
1943*d583b39bSJohn Wren Kennedy#
1944*d583b39bSJohn Wren Kennedyfunction iscsi_isetup
1945*d583b39bSJohn Wren Kennedy{
1946*d583b39bSJohn Wren Kennedy	# check svc:/network/iscsi_initiator:default state, try to enable it
1947*d583b39bSJohn Wren Kennedy	# if the state is not ON
1948*d583b39bSJohn Wren Kennedy	typeset ISCSII_FMRI="svc:/network/iscsi_initiator:default"
1949*d583b39bSJohn Wren Kennedy	if [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) ]]; then
1950*d583b39bSJohn Wren Kennedy		log_must $SVCADM enable $ISCSII_FMRI
1951*d583b39bSJohn Wren Kennedy
1952*d583b39bSJohn Wren Kennedy		typeset -i retry=20
1953*d583b39bSJohn Wren Kennedy		while [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) && \
1954*d583b39bSJohn Wren Kennedy			($retry -ne 0) ]]
1955*d583b39bSJohn Wren Kennedy		do
1956*d583b39bSJohn Wren Kennedy			((retry = retry - 1))
1957*d583b39bSJohn Wren Kennedy			$SLEEP 1
1958*d583b39bSJohn Wren Kennedy		done
1959*d583b39bSJohn Wren Kennedy
1960*d583b39bSJohn Wren Kennedy		if [[ "ON" != $($SVCS -H -o sta $ISCSII_FMRI) ]]; then
1961*d583b39bSJohn Wren Kennedy			log_fail "$ISCSII_FMRI service can not be enabled!"
1962*d583b39bSJohn Wren Kennedy		fi
1963*d583b39bSJohn Wren Kennedy	fi
1964*d583b39bSJohn Wren Kennedy
1965*d583b39bSJohn Wren Kennedy	log_must $ISCSIADM add discovery-address $(getipbyhost $1)
1966*d583b39bSJohn Wren Kennedy	log_must $ISCSIADM modify discovery --sendtargets enable
1967*d583b39bSJohn Wren Kennedy	log_must $DEVFSADM -i iscsi
1968*d583b39bSJohn Wren Kennedy}
1969*d583b39bSJohn Wren Kennedy
1970*d583b39bSJohn Wren Kennedy#
1971*d583b39bSJohn Wren Kennedy# Check whether iscsi parameter is set as remote
1972*d583b39bSJohn Wren Kennedy#
1973*d583b39bSJohn Wren Kennedy# return 0 if iscsi is set as remote, otherwise 1
1974*d583b39bSJohn Wren Kennedy#
1975*d583b39bSJohn Wren Kennedyfunction check_iscsi_remote
1976*d583b39bSJohn Wren Kennedy{
1977*d583b39bSJohn Wren Kennedy	if [[ $iscsi == "remote" ]] ; then
1978*d583b39bSJohn Wren Kennedy		return 0
1979*d583b39bSJohn Wren Kennedy	else
1980*d583b39bSJohn Wren Kennedy		return 1
1981*d583b39bSJohn Wren Kennedy	fi
1982*d583b39bSJohn Wren Kennedy}
1983*d583b39bSJohn Wren Kennedy
1984*d583b39bSJohn Wren Kennedy#
1985*d583b39bSJohn Wren Kennedy# Check if a volume is a valide iscsi target
1986*d583b39bSJohn Wren Kennedy# $1 volume name
1987*d583b39bSJohn Wren Kennedy# return 0 if suceeds, otherwise, return 1
1988*d583b39bSJohn Wren Kennedy#
1989*d583b39bSJohn Wren Kennedyfunction is_iscsi_target
1990*d583b39bSJohn Wren Kennedy{
1991*d583b39bSJohn Wren Kennedy	typeset dataset=$1
1992*d583b39bSJohn Wren Kennedy	typeset target targets
1993*d583b39bSJohn Wren Kennedy
1994*d583b39bSJohn Wren Kennedy	[[ -z $dataset ]] && return 1
1995*d583b39bSJohn Wren Kennedy
1996*d583b39bSJohn Wren Kennedy	targets=$($ISCSITADM list target | $GREP "Target:" | $AWK '{print $2}')
1997*d583b39bSJohn Wren Kennedy	[[ -z $targets ]] && return 1
1998*d583b39bSJohn Wren Kennedy
1999*d583b39bSJohn Wren Kennedy	for target in $targets; do
2000*d583b39bSJohn Wren Kennedy		[[ $dataset == $target ]] && return 0
2001*d583b39bSJohn Wren Kennedy	done
2002*d583b39bSJohn Wren Kennedy
2003*d583b39bSJohn Wren Kennedy	return 1
2004*d583b39bSJohn Wren Kennedy}
2005*d583b39bSJohn Wren Kennedy
2006*d583b39bSJohn Wren Kennedy#
2007*d583b39bSJohn Wren Kennedy# Get the iSCSI name of a target
2008*d583b39bSJohn Wren Kennedy# $1 target name
2009*d583b39bSJohn Wren Kennedy#
2010*d583b39bSJohn Wren Kennedyfunction iscsi_name
2011*d583b39bSJohn Wren Kennedy{
2012*d583b39bSJohn Wren Kennedy	typeset target=$1
2013*d583b39bSJohn Wren Kennedy	typeset name
2014*d583b39bSJohn Wren Kennedy
2015*d583b39bSJohn Wren Kennedy	[[ -z $target ]] && log_fail "No parameter."
2016*d583b39bSJohn Wren Kennedy
2017*d583b39bSJohn Wren Kennedy	if ! is_iscsi_target $target ; then
2018*d583b39bSJohn Wren Kennedy		log_fail "Not a target."
2019*d583b39bSJohn Wren Kennedy	fi
2020*d583b39bSJohn Wren Kennedy
2021*d583b39bSJohn Wren Kennedy	name=$($ISCSITADM list target $target | $GREP "iSCSI Name:" \
2022*d583b39bSJohn Wren Kennedy		| $AWK '{print $2}')
2023*d583b39bSJohn Wren Kennedy
2024*d583b39bSJohn Wren Kennedy	return $name
2025*d583b39bSJohn Wren Kennedy}
2026*d583b39bSJohn Wren Kennedy
2027*d583b39bSJohn Wren Kennedy#
2028*d583b39bSJohn Wren Kennedy# check svc:/system/iscsitgt:default state, try to enable it if the state
2029*d583b39bSJohn Wren Kennedy# is not ON
2030*d583b39bSJohn Wren Kennedy#
2031*d583b39bSJohn Wren Kennedyfunction iscsitgt_setup
2032*d583b39bSJohn Wren Kennedy{
2033*d583b39bSJohn Wren Kennedy	log_must $RM -f $ISCSITGTFILE
2034*d583b39bSJohn Wren Kennedy	if [[ "ON" == $($SVCS -H -o sta $ISCSITGT_FMRI) ]]; then
2035*d583b39bSJohn Wren Kennedy		log_note "iscsitgt is already enabled"
2036*d583b39bSJohn Wren Kennedy		return
2037*d583b39bSJohn Wren Kennedy	fi
2038*d583b39bSJohn Wren Kennedy
2039*d583b39bSJohn Wren Kennedy	log_must $SVCADM enable -t $ISCSITGT_FMRI
2040*d583b39bSJohn Wren Kennedy
2041*d583b39bSJohn Wren Kennedy	typeset -i retry=20
2042*d583b39bSJohn Wren Kennedy	while [[ "ON" != $($SVCS -H -o sta $ISCSITGT_FMRI) && \
2043*d583b39bSJohn Wren Kennedy		($retry -ne 0) ]]
2044*d583b39bSJohn Wren Kennedy	do
2045*d583b39bSJohn Wren Kennedy		$SLEEP 1
2046*d583b39bSJohn Wren Kennedy		((retry = retry - 1))
2047*d583b39bSJohn Wren Kennedy	done
2048*d583b39bSJohn Wren Kennedy
2049*d583b39bSJohn Wren Kennedy	if [[ "ON" != $($SVCS -H -o sta $ISCSITGT_FMRI) ]]; then
2050*d583b39bSJohn Wren Kennedy		log_fail "$ISCSITGT_FMRI service can not be enabled!"
2051*d583b39bSJohn Wren Kennedy	fi
2052*d583b39bSJohn Wren Kennedy
2053*d583b39bSJohn Wren Kennedy	log_must $TOUCH $ISCSITGTFILE
2054*d583b39bSJohn Wren Kennedy}
2055*d583b39bSJohn Wren Kennedy
2056*d583b39bSJohn Wren Kennedy#
2057*d583b39bSJohn Wren Kennedy# set DISABLED state of svc:/system/iscsitgt:default
2058*d583b39bSJohn Wren Kennedy# which is the most suiteable state if $ISCSITGTFILE exists
2059*d583b39bSJohn Wren Kennedy#
2060*d583b39bSJohn Wren Kennedyfunction iscsitgt_cleanup
2061*d583b39bSJohn Wren Kennedy{
2062*d583b39bSJohn Wren Kennedy	if [[ -e $ISCSITGTFILE ]]; then
2063*d583b39bSJohn Wren Kennedy		log_must $SVCADM disable $ISCSITGT_FMRI
2064*d583b39bSJohn Wren Kennedy		log_must $RM -f $ISCSITGTFILE
2065*d583b39bSJohn Wren Kennedy	fi
2066*d583b39bSJohn Wren Kennedy}
2067*d583b39bSJohn Wren Kennedy
2068*d583b39bSJohn Wren Kennedy#
2069*d583b39bSJohn Wren Kennedy# Close iSCSI initiator to target
2070*d583b39bSJohn Wren Kennedy# $1 target hostname
2071*d583b39bSJohn Wren Kennedy#
2072*d583b39bSJohn Wren Kennedyfunction iscsi_iclose
2073*d583b39bSJohn Wren Kennedy{
2074*d583b39bSJohn Wren Kennedy	log_must $ISCSIADM modify discovery --sendtargets disable
2075*d583b39bSJohn Wren Kennedy	log_must $ISCSIADM remove discovery-address $(getipbyhost $1)
2076*d583b39bSJohn Wren Kennedy	$DEVFSADM -Cv
2077*d583b39bSJohn Wren Kennedy}
2078*d583b39bSJohn Wren Kennedy
2079*d583b39bSJohn Wren Kennedy#
2080*d583b39bSJohn Wren Kennedy# Get the available ZFS compression options
2081*d583b39bSJohn Wren Kennedy# $1 option type zfs_set|zfs_compress
2082*d583b39bSJohn Wren Kennedy#
2083*d583b39bSJohn Wren Kennedyfunction get_compress_opts
2084*d583b39bSJohn Wren Kennedy{
2085*d583b39bSJohn Wren Kennedy	typeset COMPRESS_OPTS
2086*d583b39bSJohn Wren Kennedy	typeset GZIP_OPTS="gzip gzip-1 gzip-2 gzip-3 gzip-4 gzip-5 \
2087*d583b39bSJohn Wren Kennedy			gzip-6 gzip-7 gzip-8 gzip-9"
2088*d583b39bSJohn Wren Kennedy
2089*d583b39bSJohn Wren Kennedy	if [[ $1 == "zfs_compress" ]] ; then
2090*d583b39bSJohn Wren Kennedy		COMPRESS_OPTS="on lzjb"
2091*d583b39bSJohn Wren Kennedy	elif [[ $1 == "zfs_set" ]] ; then
2092*d583b39bSJohn Wren Kennedy		COMPRESS_OPTS="on off lzjb"
2093*d583b39bSJohn Wren Kennedy	fi
2094*d583b39bSJohn Wren Kennedy	typeset valid_opts="$COMPRESS_OPTS"
2095*d583b39bSJohn Wren Kennedy	$ZFS get 2>&1 | $GREP gzip >/dev/null 2>&1
2096*d583b39bSJohn Wren Kennedy	if [[ $? -eq 0 ]]; then
2097*d583b39bSJohn Wren Kennedy		valid_opts="$valid_opts $GZIP_OPTS"
2098*d583b39bSJohn Wren Kennedy	fi
2099*d583b39bSJohn Wren Kennedy	$ECHO "$valid_opts"
2100*d583b39bSJohn Wren Kennedy}
2101*d583b39bSJohn Wren Kennedy
2102*d583b39bSJohn Wren Kennedy#
2103*d583b39bSJohn Wren Kennedy# Verify zfs operation with -p option work as expected
2104*d583b39bSJohn Wren Kennedy# $1 operation, value could be create, clone or rename
2105*d583b39bSJohn Wren Kennedy# $2 dataset type, value could be fs or vol
2106*d583b39bSJohn Wren Kennedy# $3 dataset name
2107*d583b39bSJohn Wren Kennedy# $4 new dataset name
2108*d583b39bSJohn Wren Kennedy#
2109*d583b39bSJohn Wren Kennedyfunction verify_opt_p_ops
2110*d583b39bSJohn Wren Kennedy{
2111*d583b39bSJohn Wren Kennedy	typeset ops=$1
2112*d583b39bSJohn Wren Kennedy	typeset datatype=$2
2113*d583b39bSJohn Wren Kennedy	typeset dataset=$3
2114*d583b39bSJohn Wren Kennedy	typeset newdataset=$4
2115*d583b39bSJohn Wren Kennedy
2116*d583b39bSJohn Wren Kennedy	if [[ $datatype != "fs" && $datatype != "vol" ]]; then
2117*d583b39bSJohn Wren Kennedy		log_fail "$datatype is not supported."
2118*d583b39bSJohn Wren Kennedy	fi
2119*d583b39bSJohn Wren Kennedy
2120*d583b39bSJohn Wren Kennedy	# check parameters accordingly
2121*d583b39bSJohn Wren Kennedy	case $ops in
2122*d583b39bSJohn Wren Kennedy		create)
2123*d583b39bSJohn Wren Kennedy			newdataset=$dataset
2124*d583b39bSJohn Wren Kennedy			dataset=""
2125*d583b39bSJohn Wren Kennedy			if [[ $datatype == "vol" ]]; then
2126*d583b39bSJohn Wren Kennedy				ops="create -V $VOLSIZE"
2127*d583b39bSJohn Wren Kennedy			fi
2128*d583b39bSJohn Wren Kennedy			;;
2129*d583b39bSJohn Wren Kennedy		clone)
2130*d583b39bSJohn Wren Kennedy			if [[ -z $newdataset ]]; then
2131*d583b39bSJohn Wren Kennedy				log_fail "newdataset should not be empty" \
2132*d583b39bSJohn Wren Kennedy					"when ops is $ops."
2133*d583b39bSJohn Wren Kennedy			fi
2134*d583b39bSJohn Wren Kennedy			log_must datasetexists $dataset
2135*d583b39bSJohn Wren Kennedy			log_must snapexists $dataset
2136*d583b39bSJohn Wren Kennedy			;;
2137*d583b39bSJohn Wren Kennedy		rename)
2138*d583b39bSJohn Wren Kennedy			if [[ -z $newdataset ]]; then
2139*d583b39bSJohn Wren Kennedy				log_fail "newdataset should not be empty" \
2140*d583b39bSJohn Wren Kennedy					"when ops is $ops."
2141*d583b39bSJohn Wren Kennedy			fi
2142*d583b39bSJohn Wren Kennedy			log_must datasetexists $dataset
2143*d583b39bSJohn Wren Kennedy			log_mustnot snapexists $dataset
2144*d583b39bSJohn Wren Kennedy			;;
2145*d583b39bSJohn Wren Kennedy		*)
2146*d583b39bSJohn Wren Kennedy			log_fail "$ops is not supported."
2147*d583b39bSJohn Wren Kennedy			;;
2148*d583b39bSJohn Wren Kennedy	esac
2149*d583b39bSJohn Wren Kennedy
2150*d583b39bSJohn Wren Kennedy	# make sure the upper level filesystem does not exist
2151*d583b39bSJohn Wren Kennedy	if datasetexists ${newdataset%/*} ; then
2152*d583b39bSJohn Wren Kennedy		log_must $ZFS destroy -rRf ${newdataset%/*}
2153*d583b39bSJohn Wren Kennedy	fi
2154*d583b39bSJohn Wren Kennedy
2155*d583b39bSJohn Wren Kennedy	# without -p option, operation will fail
2156*d583b39bSJohn Wren Kennedy	log_mustnot $ZFS $ops $dataset $newdataset
2157*d583b39bSJohn Wren Kennedy	log_mustnot datasetexists $newdataset ${newdataset%/*}
2158*d583b39bSJohn Wren Kennedy
2159*d583b39bSJohn Wren Kennedy	# with -p option, operation should succeed
2160*d583b39bSJohn Wren Kennedy	log_must $ZFS $ops -p $dataset $newdataset
2161*d583b39bSJohn Wren Kennedy	if ! datasetexists $newdataset ; then
2162*d583b39bSJohn Wren Kennedy		log_fail "-p option does not work for $ops"
2163*d583b39bSJohn Wren Kennedy	fi
2164*d583b39bSJohn Wren Kennedy
2165*d583b39bSJohn Wren Kennedy	# when $ops is create or clone, redo the operation still return zero
2166*d583b39bSJohn Wren Kennedy	if [[ $ops != "rename" ]]; then
2167*d583b39bSJohn Wren Kennedy		log_must $ZFS $ops -p $dataset $newdataset
2168*d583b39bSJohn Wren Kennedy	fi
2169*d583b39bSJohn Wren Kennedy
2170*d583b39bSJohn Wren Kennedy	return 0
2171*d583b39bSJohn Wren Kennedy}
2172*d583b39bSJohn Wren Kennedy
2173*d583b39bSJohn Wren Kennedy#
2174*d583b39bSJohn Wren Kennedy# Get configuration of pool
2175*d583b39bSJohn Wren Kennedy# $1 pool name
2176*d583b39bSJohn Wren Kennedy# $2 config name
2177*d583b39bSJohn Wren Kennedy#
2178*d583b39bSJohn Wren Kennedyfunction get_config
2179*d583b39bSJohn Wren Kennedy{
2180*d583b39bSJohn Wren Kennedy	typeset pool=$1
2181*d583b39bSJohn Wren Kennedy	typeset config=$2
2182*d583b39bSJohn Wren Kennedy	typeset alt_root
2183*d583b39bSJohn Wren Kennedy
2184*d583b39bSJohn Wren Kennedy	if ! poolexists "$pool" ; then
2185*d583b39bSJohn Wren Kennedy		return 1
2186*d583b39bSJohn Wren Kennedy	fi
2187*d583b39bSJohn Wren Kennedy	alt_root=$($ZPOOL list -H $pool | $AWK '{print $NF}')
2188*d583b39bSJohn Wren Kennedy	if [[ $alt_root == "-" ]]; then
2189*d583b39bSJohn Wren Kennedy		value=$($ZDB -C $pool | $GREP "$config:" | $AWK -F: \
2190*d583b39bSJohn Wren Kennedy		    '{print $2}')
2191*d583b39bSJohn Wren Kennedy	else
2192*d583b39bSJohn Wren Kennedy		value=$($ZDB -e $pool | $GREP "$config:" | $AWK -F: \
2193*d583b39bSJohn Wren Kennedy		    '{print $2}')
2194*d583b39bSJohn Wren Kennedy	fi
2195*d583b39bSJohn Wren Kennedy	if [[ -n $value ]] ; then
2196*d583b39bSJohn Wren Kennedy		value=${value#'}
2197*d583b39bSJohn Wren Kennedy		value=${value%'}
2198*d583b39bSJohn Wren Kennedy	fi
2199*d583b39bSJohn Wren Kennedy	echo $value
2200*d583b39bSJohn Wren Kennedy
2201*d583b39bSJohn Wren Kennedy	return 0
2202*d583b39bSJohn Wren Kennedy}
2203*d583b39bSJohn Wren Kennedy
2204*d583b39bSJohn Wren Kennedy#
2205*d583b39bSJohn Wren Kennedy# Privated function. Random select one of items from arguments.
2206*d583b39bSJohn Wren Kennedy#
2207*d583b39bSJohn Wren Kennedy# $1 count
2208*d583b39bSJohn Wren Kennedy# $2-n string
2209*d583b39bSJohn Wren Kennedy#
2210*d583b39bSJohn Wren Kennedyfunction _random_get
2211*d583b39bSJohn Wren Kennedy{
2212*d583b39bSJohn Wren Kennedy	typeset cnt=$1
2213*d583b39bSJohn Wren Kennedy	shift
2214*d583b39bSJohn Wren Kennedy
2215*d583b39bSJohn Wren Kennedy	typeset str="$@"
2216*d583b39bSJohn Wren Kennedy	typeset -i ind
2217*d583b39bSJohn Wren Kennedy	((ind = RANDOM % cnt + 1))
2218*d583b39bSJohn Wren Kennedy
2219*d583b39bSJohn Wren Kennedy	typeset ret=$($ECHO "$str" | $CUT -f $ind -d ' ')
2220*d583b39bSJohn Wren Kennedy	$ECHO $ret
2221*d583b39bSJohn Wren Kennedy}
2222*d583b39bSJohn Wren Kennedy
2223*d583b39bSJohn Wren Kennedy#
2224*d583b39bSJohn Wren Kennedy# Random select one of item from arguments which include NONE string
2225*d583b39bSJohn Wren Kennedy#
2226*d583b39bSJohn Wren Kennedyfunction random_get_with_non
2227*d583b39bSJohn Wren Kennedy{
2228*d583b39bSJohn Wren Kennedy	typeset -i cnt=$#
2229*d583b39bSJohn Wren Kennedy	((cnt =+ 1))
2230*d583b39bSJohn Wren Kennedy
2231*d583b39bSJohn Wren Kennedy	_random_get "$cnt" "$@"
2232*d583b39bSJohn Wren Kennedy}
2233*d583b39bSJohn Wren Kennedy
2234*d583b39bSJohn Wren Kennedy#
2235*d583b39bSJohn Wren Kennedy# Random select one of item from arguments which doesn't include NONE string
2236*d583b39bSJohn Wren Kennedy#
2237*d583b39bSJohn Wren Kennedyfunction random_get
2238*d583b39bSJohn Wren Kennedy{
2239*d583b39bSJohn Wren Kennedy	_random_get "$#" "$@"
2240*d583b39bSJohn Wren Kennedy}
2241*d583b39bSJohn Wren Kennedy
2242*d583b39bSJohn Wren Kennedy#
2243*d583b39bSJohn Wren Kennedy# Detect if the current system support slog
2244*d583b39bSJohn Wren Kennedy#
2245*d583b39bSJohn Wren Kennedyfunction verify_slog_support
2246*d583b39bSJohn Wren Kennedy{
2247*d583b39bSJohn Wren Kennedy	typeset dir=/tmp/disk.$$
2248*d583b39bSJohn Wren Kennedy	typeset pool=foo.$$
2249*d583b39bSJohn Wren Kennedy	typeset vdev=$dir/a
2250*d583b39bSJohn Wren Kennedy	typeset sdev=$dir/b
2251*d583b39bSJohn Wren Kennedy
2252*d583b39bSJohn Wren Kennedy	$MKDIR -p $dir
2253*d583b39bSJohn Wren Kennedy	$MKFILE 64M $vdev $sdev
2254*d583b39bSJohn Wren Kennedy
2255*d583b39bSJohn Wren Kennedy	typeset -i ret=0
2256*d583b39bSJohn Wren Kennedy	if ! $ZPOOL create -n $pool $vdev log $sdev > /dev/null 2>&1; then
2257*d583b39bSJohn Wren Kennedy		ret=1
2258*d583b39bSJohn Wren Kennedy	fi
2259*d583b39bSJohn Wren Kennedy	$RM -r $dir
2260*d583b39bSJohn Wren Kennedy
2261*d583b39bSJohn Wren Kennedy	return $ret
2262*d583b39bSJohn Wren Kennedy}
2263*d583b39bSJohn Wren Kennedy
2264*d583b39bSJohn Wren Kennedy#
2265*d583b39bSJohn Wren Kennedy# The function will generate a dataset name with specific length
2266*d583b39bSJohn Wren Kennedy# $1, the length of the name
2267*d583b39bSJohn Wren Kennedy# $2, the base string to construct the name
2268*d583b39bSJohn Wren Kennedy#
2269*d583b39bSJohn Wren Kennedyfunction gen_dataset_name
2270*d583b39bSJohn Wren Kennedy{
2271*d583b39bSJohn Wren Kennedy	typeset -i len=$1
2272*d583b39bSJohn Wren Kennedy	typeset basestr="$2"
2273*d583b39bSJohn Wren Kennedy	typeset -i baselen=${#basestr}
2274*d583b39bSJohn Wren Kennedy	typeset -i iter=0
2275*d583b39bSJohn Wren Kennedy	typeset l_name=""
2276*d583b39bSJohn Wren Kennedy
2277*d583b39bSJohn Wren Kennedy	if ((len % baselen == 0)); then
2278*d583b39bSJohn Wren Kennedy		((iter = len / baselen))
2279*d583b39bSJohn Wren Kennedy	else
2280*d583b39bSJohn Wren Kennedy		((iter = len / baselen + 1))
2281*d583b39bSJohn Wren Kennedy	fi
2282*d583b39bSJohn Wren Kennedy	while ((iter > 0)); do
2283*d583b39bSJohn Wren Kennedy		l_name="${l_name}$basestr"
2284*d583b39bSJohn Wren Kennedy
2285*d583b39bSJohn Wren Kennedy		((iter -= 1))
2286*d583b39bSJohn Wren Kennedy	done
2287*d583b39bSJohn Wren Kennedy
2288*d583b39bSJohn Wren Kennedy	$ECHO $l_name
2289*d583b39bSJohn Wren Kennedy}
2290*d583b39bSJohn Wren Kennedy
2291*d583b39bSJohn Wren Kennedy#
2292*d583b39bSJohn Wren Kennedy# Get cksum tuple of dataset
2293*d583b39bSJohn Wren Kennedy# $1 dataset name
2294*d583b39bSJohn Wren Kennedy#
2295*d583b39bSJohn Wren Kennedy# sample zdb output:
2296*d583b39bSJohn Wren Kennedy# Dataset data/test [ZPL], ID 355, cr_txg 2413856, 31.0K, 7 objects, rootbp
2297*d583b39bSJohn Wren Kennedy# DVA[0]=<0:803046400:200> DVA[1]=<0:81199000:200> [L0 DMU objset] fletcher4
2298*d583b39bSJohn Wren Kennedy# lzjb LE contiguous unique double size=800L/200P birth=2413856L/2413856P
2299*d583b39bSJohn Wren Kennedy# fill=7 cksum=11ce125712:643a9c18ee2:125e25238fca0:254a3f74b59744
2300*d583b39bSJohn Wren Kennedyfunction datasetcksum
2301*d583b39bSJohn Wren Kennedy{
2302*d583b39bSJohn Wren Kennedy	typeset cksum
2303*d583b39bSJohn Wren Kennedy	$SYNC
2304*d583b39bSJohn Wren Kennedy	cksum=$($ZDB -vvv $1 | $GREP "^Dataset $1 \[" | $GREP "cksum" \
2305*d583b39bSJohn Wren Kennedy		| $AWK -F= '{print $7}')
2306*d583b39bSJohn Wren Kennedy	$ECHO $cksum
2307*d583b39bSJohn Wren Kennedy}
2308*d583b39bSJohn Wren Kennedy
2309*d583b39bSJohn Wren Kennedy#
2310*d583b39bSJohn Wren Kennedy# Get cksum of file
2311*d583b39bSJohn Wren Kennedy# #1 file path
2312*d583b39bSJohn Wren Kennedy#
2313*d583b39bSJohn Wren Kennedyfunction checksum
2314*d583b39bSJohn Wren Kennedy{
2315*d583b39bSJohn Wren Kennedy	typeset cksum
2316*d583b39bSJohn Wren Kennedy	cksum=$($CKSUM $1 | $AWK '{print $1}')
2317*d583b39bSJohn Wren Kennedy	$ECHO $cksum
2318*d583b39bSJohn Wren Kennedy}
2319*d583b39bSJohn Wren Kennedy
2320*d583b39bSJohn Wren Kennedy#
2321*d583b39bSJohn Wren Kennedy# Get the given disk/slice state from the specific field of the pool
2322*d583b39bSJohn Wren Kennedy#
2323*d583b39bSJohn Wren Kennedyfunction get_device_state #pool disk field("", "spares","logs")
2324*d583b39bSJohn Wren Kennedy{
2325*d583b39bSJohn Wren Kennedy	typeset pool=$1
2326*d583b39bSJohn Wren Kennedy	typeset disk=${2#/dev/dsk/}
2327*d583b39bSJohn Wren Kennedy	typeset field=${3:-$pool}
2328*d583b39bSJohn Wren Kennedy
2329*d583b39bSJohn Wren Kennedy	state=$($ZPOOL status -v "$pool" 2>/dev/null | \
2330*d583b39bSJohn Wren Kennedy		$NAWK -v device=$disk -v pool=$pool -v field=$field \
2331*d583b39bSJohn Wren Kennedy		'BEGIN {startconfig=0; startfield=0; }
2332*d583b39bSJohn Wren Kennedy		/config:/ {startconfig=1}
2333*d583b39bSJohn Wren Kennedy		(startconfig==1) && ($1==field) {startfield=1; next;}
2334*d583b39bSJohn Wren Kennedy		(startfield==1) && ($1==device) {print $2; exit;}
2335*d583b39bSJohn Wren Kennedy		(startfield==1) &&
2336*d583b39bSJohn Wren Kennedy		($1==field || $1 ~ "^spares$" || $1 ~ "^logs$") {startfield=0}')
2337*d583b39bSJohn Wren Kennedy	echo $state
2338*d583b39bSJohn Wren Kennedy}
2339*d583b39bSJohn Wren Kennedy
2340*d583b39bSJohn Wren Kennedy
2341*d583b39bSJohn Wren Kennedy#
2342*d583b39bSJohn Wren Kennedy# print the given directory filesystem type
2343*d583b39bSJohn Wren Kennedy#
2344*d583b39bSJohn Wren Kennedy# $1 directory name
2345*d583b39bSJohn Wren Kennedy#
2346*d583b39bSJohn Wren Kennedyfunction get_fstype
2347*d583b39bSJohn Wren Kennedy{
2348*d583b39bSJohn Wren Kennedy	typeset dir=$1
2349*d583b39bSJohn Wren Kennedy
2350*d583b39bSJohn Wren Kennedy	if [[ -z $dir ]]; then
2351*d583b39bSJohn Wren Kennedy		log_fail "Usage: get_fstype <directory>"
2352*d583b39bSJohn Wren Kennedy	fi
2353*d583b39bSJohn Wren Kennedy
2354*d583b39bSJohn Wren Kennedy	#
2355*d583b39bSJohn Wren Kennedy	#  $ df -n /
2356*d583b39bSJohn Wren Kennedy	#  /		  : ufs
2357*d583b39bSJohn Wren Kennedy	#
2358*d583b39bSJohn Wren Kennedy	$DF -n $dir | $AWK '{print $3}'
2359*d583b39bSJohn Wren Kennedy}
2360*d583b39bSJohn Wren Kennedy
2361*d583b39bSJohn Wren Kennedy#
2362*d583b39bSJohn Wren Kennedy# Given a disk, label it to VTOC regardless what label was on the disk
2363*d583b39bSJohn Wren Kennedy# $1 disk
2364*d583b39bSJohn Wren Kennedy#
2365*d583b39bSJohn Wren Kennedyfunction labelvtoc
2366*d583b39bSJohn Wren Kennedy{
2367*d583b39bSJohn Wren Kennedy	typeset disk=$1
2368*d583b39bSJohn Wren Kennedy	if [[ -z $disk ]]; then
2369*d583b39bSJohn Wren Kennedy		log_fail "The disk name is unspecified."
2370*d583b39bSJohn Wren Kennedy	fi
2371*d583b39bSJohn Wren Kennedy	typeset label_file=/var/tmp/labelvtoc.$$
2372*d583b39bSJohn Wren Kennedy	typeset arch=$($UNAME -p)
2373*d583b39bSJohn Wren Kennedy
2374*d583b39bSJohn Wren Kennedy	if [[ $arch == "i386" ]]; then
2375*d583b39bSJohn Wren Kennedy		$ECHO "label" > $label_file
2376*d583b39bSJohn Wren Kennedy		$ECHO "0" >> $label_file
2377*d583b39bSJohn Wren Kennedy		$ECHO "" >> $label_file
2378*d583b39bSJohn Wren Kennedy		$ECHO "q" >> $label_file
2379*d583b39bSJohn Wren Kennedy		$ECHO "q" >> $label_file
2380*d583b39bSJohn Wren Kennedy
2381*d583b39bSJohn Wren Kennedy		$FDISK -B $disk >/dev/null 2>&1
2382*d583b39bSJohn Wren Kennedy		# wait a while for fdisk finishes
2383*d583b39bSJohn Wren Kennedy		$SLEEP 60
2384*d583b39bSJohn Wren Kennedy	elif [[ $arch == "sparc" ]]; then
2385*d583b39bSJohn Wren Kennedy		$ECHO "label" > $label_file
2386*d583b39bSJohn Wren Kennedy		$ECHO "0" >> $label_file
2387*d583b39bSJohn Wren Kennedy		$ECHO "" >> $label_file
2388*d583b39bSJohn Wren Kennedy		$ECHO "" >> $label_file
2389*d583b39bSJohn Wren Kennedy		$ECHO "" >> $label_file
2390*d583b39bSJohn Wren Kennedy		$ECHO "q" >> $label_file
2391*d583b39bSJohn Wren Kennedy	else
2392*d583b39bSJohn Wren Kennedy		log_fail "unknown arch type"
2393*d583b39bSJohn Wren Kennedy	fi
2394*d583b39bSJohn Wren Kennedy
2395*d583b39bSJohn Wren Kennedy	$FORMAT -e -s -d $disk -f $label_file
2396*d583b39bSJohn Wren Kennedy	typeset -i ret_val=$?
2397*d583b39bSJohn Wren Kennedy	$RM -f $label_file
2398*d583b39bSJohn Wren Kennedy	#
2399*d583b39bSJohn Wren Kennedy	# wait the format to finish
2400*d583b39bSJohn Wren Kennedy	#
2401*d583b39bSJohn Wren Kennedy	$SLEEP 60
2402*d583b39bSJohn Wren Kennedy	if ((ret_val != 0)); then
2403*d583b39bSJohn Wren Kennedy		log_fail "unable to label $disk as VTOC."
2404*d583b39bSJohn Wren Kennedy	fi
2405*d583b39bSJohn Wren Kennedy
2406*d583b39bSJohn Wren Kennedy	return 0
2407*d583b39bSJohn Wren Kennedy}
2408*d583b39bSJohn Wren Kennedy
2409*d583b39bSJohn Wren Kennedy#
2410*d583b39bSJohn Wren Kennedy# check if the system was installed as zfsroot or not
2411*d583b39bSJohn Wren Kennedy# return: 0 ture, otherwise false
2412*d583b39bSJohn Wren Kennedy#
2413*d583b39bSJohn Wren Kennedyfunction is_zfsroot
2414*d583b39bSJohn Wren Kennedy{
2415*d583b39bSJohn Wren Kennedy	$DF -n / | $GREP zfs > /dev/null 2>&1
2416*d583b39bSJohn Wren Kennedy	return $?
2417*d583b39bSJohn Wren Kennedy}
2418*d583b39bSJohn Wren Kennedy
2419*d583b39bSJohn Wren Kennedy#
2420*d583b39bSJohn Wren Kennedy# get the root filesystem name if it's zfsroot system.
2421*d583b39bSJohn Wren Kennedy#
2422*d583b39bSJohn Wren Kennedy# return: root filesystem name
2423*d583b39bSJohn Wren Kennedyfunction get_rootfs
2424*d583b39bSJohn Wren Kennedy{
2425*d583b39bSJohn Wren Kennedy	typeset rootfs=""
2426*d583b39bSJohn Wren Kennedy	rootfs=$($AWK '{if ($2 == "/" && $3 == "zfs") print $1}' \
2427*d583b39bSJohn Wren Kennedy		/etc/mnttab)
2428*d583b39bSJohn Wren Kennedy	if [[ -z "$rootfs" ]]; then
2429*d583b39bSJohn Wren Kennedy		log_fail "Can not get rootfs"
2430*d583b39bSJohn Wren Kennedy	fi
2431*d583b39bSJohn Wren Kennedy	$ZFS list $rootfs > /dev/null 2>&1
2432*d583b39bSJohn Wren Kennedy	if (($? == 0)); then
2433*d583b39bSJohn Wren Kennedy		$ECHO $rootfs
2434*d583b39bSJohn Wren Kennedy	else
2435*d583b39bSJohn Wren Kennedy		log_fail "This is not a zfsroot system."
2436*d583b39bSJohn Wren Kennedy	fi
2437*d583b39bSJohn Wren Kennedy}
2438*d583b39bSJohn Wren Kennedy
2439*d583b39bSJohn Wren Kennedy#
2440*d583b39bSJohn Wren Kennedy# get the rootfs's pool name
2441*d583b39bSJohn Wren Kennedy# return:
2442*d583b39bSJohn Wren Kennedy#       rootpool name
2443*d583b39bSJohn Wren Kennedy#
2444*d583b39bSJohn Wren Kennedyfunction get_rootpool
2445*d583b39bSJohn Wren Kennedy{
2446*d583b39bSJohn Wren Kennedy	typeset rootfs=""
2447*d583b39bSJohn Wren Kennedy	typeset rootpool=""
2448*d583b39bSJohn Wren Kennedy	rootfs=$($AWK '{if ($2 == "/" && $3 =="zfs") print $1}' \
2449*d583b39bSJohn Wren Kennedy		 /etc/mnttab)
2450*d583b39bSJohn Wren Kennedy	if [[ -z "$rootfs" ]]; then
2451*d583b39bSJohn Wren Kennedy		log_fail "Can not get rootpool"
2452*d583b39bSJohn Wren Kennedy	fi
2453*d583b39bSJohn Wren Kennedy	$ZFS list $rootfs > /dev/null 2>&1
2454*d583b39bSJohn Wren Kennedy	if (($? == 0)); then
2455*d583b39bSJohn Wren Kennedy		rootpool=`$ECHO $rootfs | awk -F\/ '{print $1}'`
2456*d583b39bSJohn Wren Kennedy		$ECHO $rootpool
2457*d583b39bSJohn Wren Kennedy	else
2458*d583b39bSJohn Wren Kennedy		log_fail "This is not a zfsroot system."
2459*d583b39bSJohn Wren Kennedy	fi
2460*d583b39bSJohn Wren Kennedy}
2461*d583b39bSJohn Wren Kennedy
2462*d583b39bSJohn Wren Kennedy#
2463*d583b39bSJohn Wren Kennedy# Get the sub string from specified source string
2464*d583b39bSJohn Wren Kennedy#
2465*d583b39bSJohn Wren Kennedy# $1 source string
2466*d583b39bSJohn Wren Kennedy# $2 start position. Count from 1
2467*d583b39bSJohn Wren Kennedy# $3 offset
2468*d583b39bSJohn Wren Kennedy#
2469*d583b39bSJohn Wren Kennedyfunction get_substr #src_str pos offset
2470*d583b39bSJohn Wren Kennedy{
2471*d583b39bSJohn Wren Kennedy	typeset pos offset
2472*d583b39bSJohn Wren Kennedy
2473*d583b39bSJohn Wren Kennedy	$ECHO $1 | \
2474*d583b39bSJohn Wren Kennedy		$NAWK -v pos=$2 -v offset=$3 '{print substr($0, pos, offset)}'
2475*d583b39bSJohn Wren Kennedy}
2476*d583b39bSJohn Wren Kennedy
2477*d583b39bSJohn Wren Kennedy#
2478*d583b39bSJohn Wren Kennedy# Check if the given device is physical device
2479*d583b39bSJohn Wren Kennedy#
2480*d583b39bSJohn Wren Kennedyfunction is_physical_device #device
2481*d583b39bSJohn Wren Kennedy{
2482*d583b39bSJohn Wren Kennedy	typeset device=${1#/dev/dsk/}
2483*d583b39bSJohn Wren Kennedy	device=${device#/dev/rdsk/}
2484*d583b39bSJohn Wren Kennedy
2485*d583b39bSJohn Wren Kennedy	$ECHO $device | $EGREP "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
2486*d583b39bSJohn Wren Kennedy	return $?
2487*d583b39bSJohn Wren Kennedy}
2488*d583b39bSJohn Wren Kennedy
2489*d583b39bSJohn Wren Kennedy#
2490*d583b39bSJohn Wren Kennedy# Get the directory path of given device
2491*d583b39bSJohn Wren Kennedy#
2492*d583b39bSJohn Wren Kennedyfunction get_device_dir #device
2493*d583b39bSJohn Wren Kennedy{
2494*d583b39bSJohn Wren Kennedy	typeset device=$1
2495*d583b39bSJohn Wren Kennedy
2496*d583b39bSJohn Wren Kennedy	if ! $(is_physical_device $device) ; then
2497*d583b39bSJohn Wren Kennedy		if [[ $device != "/" ]]; then
2498*d583b39bSJohn Wren Kennedy			device=${device%/*}
2499*d583b39bSJohn Wren Kennedy		fi
2500*d583b39bSJohn Wren Kennedy		$ECHO $device
2501*d583b39bSJohn Wren Kennedy	else
2502*d583b39bSJohn Wren Kennedy		$ECHO "/dev/dsk"
2503*d583b39bSJohn Wren Kennedy	fi
2504*d583b39bSJohn Wren Kennedy}
2505*d583b39bSJohn Wren Kennedy
2506*d583b39bSJohn Wren Kennedy#
2507*d583b39bSJohn Wren Kennedy# Get the package name
2508*d583b39bSJohn Wren Kennedy#
2509*d583b39bSJohn Wren Kennedyfunction get_package_name
2510*d583b39bSJohn Wren Kennedy{
2511*d583b39bSJohn Wren Kennedy	typeset dirpath=${1:-$STC_NAME}
2512*d583b39bSJohn Wren Kennedy
2513*d583b39bSJohn Wren Kennedy	echo "SUNWstc-${dirpath}" | /usr/bin/sed -e "s/\//-/g"
2514*d583b39bSJohn Wren Kennedy}
2515*d583b39bSJohn Wren Kennedy
2516*d583b39bSJohn Wren Kennedy#
2517*d583b39bSJohn Wren Kennedy# Get the word numbers from a string separated by white space
2518*d583b39bSJohn Wren Kennedy#
2519*d583b39bSJohn Wren Kennedyfunction get_word_count
2520*d583b39bSJohn Wren Kennedy{
2521*d583b39bSJohn Wren Kennedy	$ECHO $1 | $WC -w
2522*d583b39bSJohn Wren Kennedy}
2523*d583b39bSJohn Wren Kennedy
2524*d583b39bSJohn Wren Kennedy#
2525*d583b39bSJohn Wren Kennedy# To verify if the require numbers of disks is given
2526*d583b39bSJohn Wren Kennedy#
2527*d583b39bSJohn Wren Kennedyfunction verify_disk_count
2528*d583b39bSJohn Wren Kennedy{
2529*d583b39bSJohn Wren Kennedy	typeset -i min=${2:-1}
2530*d583b39bSJohn Wren Kennedy
2531*d583b39bSJohn Wren Kennedy	typeset -i count=$(get_word_count "$1")
2532*d583b39bSJohn Wren Kennedy
2533*d583b39bSJohn Wren Kennedy	if ((count < min)); then
2534*d583b39bSJohn Wren Kennedy		log_untested "A minimum of $min disks is required to run." \
2535*d583b39bSJohn Wren Kennedy			" You specified $count disk(s)"
2536*d583b39bSJohn Wren Kennedy	fi
2537*d583b39bSJohn Wren Kennedy}
2538*d583b39bSJohn Wren Kennedy
2539*d583b39bSJohn Wren Kennedyfunction ds_is_volume
2540*d583b39bSJohn Wren Kennedy{
2541*d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2542*d583b39bSJohn Wren Kennedy	[[ $type = "volume" ]] && return 0
2543*d583b39bSJohn Wren Kennedy	return 1
2544*d583b39bSJohn Wren Kennedy}
2545*d583b39bSJohn Wren Kennedy
2546*d583b39bSJohn Wren Kennedyfunction ds_is_filesystem
2547*d583b39bSJohn Wren Kennedy{
2548*d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2549*d583b39bSJohn Wren Kennedy	[[ $type = "filesystem" ]] && return 0
2550*d583b39bSJohn Wren Kennedy	return 1
2551*d583b39bSJohn Wren Kennedy}
2552*d583b39bSJohn Wren Kennedy
2553*d583b39bSJohn Wren Kennedyfunction ds_is_snapshot
2554*d583b39bSJohn Wren Kennedy{
2555*d583b39bSJohn Wren Kennedy	typeset type=$(get_prop type $1)
2556*d583b39bSJohn Wren Kennedy	[[ $type = "snapshot" ]] && return 0
2557*d583b39bSJohn Wren Kennedy	return 1
2558*d583b39bSJohn Wren Kennedy}
2559*d583b39bSJohn Wren Kennedy
2560*d583b39bSJohn Wren Kennedy#
2561*d583b39bSJohn Wren Kennedy# Check if Trusted Extensions are installed and enabled
2562*d583b39bSJohn Wren Kennedy#
2563*d583b39bSJohn Wren Kennedyfunction is_te_enabled
2564*d583b39bSJohn Wren Kennedy{
2565*d583b39bSJohn Wren Kennedy	$SVCS -H -o state labeld 2>/dev/null | $GREP "enabled"
2566*d583b39bSJohn Wren Kennedy	if (($? != 0)); then
2567*d583b39bSJohn Wren Kennedy		return 1
2568*d583b39bSJohn Wren Kennedy	else
2569*d583b39bSJohn Wren Kennedy		return 0
2570*d583b39bSJohn Wren Kennedy	fi
2571*d583b39bSJohn Wren Kennedy}
2572