xref: /illumos-gate/usr/src/test/zfs-tests/cmd/scripts/zfstest.ksh (revision 006a630c5c37082d949b36c96b2f405c3551e43e)
1#!/usr/bin/ksh
2
3#
4# This file and its contents are supplied under the terms of the
5# Common Development and Distribution License ("CDDL"), version 1.0.
6# You may only use this file in accordance with the terms of version
7# 1.0 of the CDDL.
8#
9# A full copy of the text of the CDDL should have accompanied this
10# source.  A copy of the CDDL is also available via the Internet at
11# http://www.illumos.org/license/CDDL.
12#
13
14#
15# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
16# Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
17# Copyright 2021 Tintri by DDN, Inc. All rights reserved.
18# Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
19#
20
21export LC_ALL=C.UTF-8
22export PATH="/usr/bin"
23export NOINUSE_CHECK=1
24export STF_SUITE="/opt/zfs-tests"
25export COMMON="$STF_SUITE/runfiles/common.run"
26export STF_TOOLS="/opt/test-runner/stf"
27export PATHDIR=""
28runner="/opt/test-runner/bin/run"
29auto_detect=false
30
31if [[ -z "$TESTFAIL_CALLBACKS" ]] ; then
32	export TESTFAIL_CALLBACKS="$STF_SUITE/callbacks/zfs_dbgmsg"
33fi
34
35function fail
36{
37	echo $1
38	exit ${2:-1}
39}
40
41function find_disks
42{
43	typeset all_disks=$(echo '' | sudo -k format | awk \
44	    '/c[0-9]/ {print $2}')
45	typeset used_disks=$(zpool status | awk \
46	    '/c[0-9]+(t[0-9a-fA-F]+)?d[0-9]+/ {print $1}' | sed -E \
47	    's/(s|p)[0-9]+//g')
48
49	typeset disk used avail_disks
50	for disk in $all_disks; do
51		for used in $used_disks; do
52			[[ "$disk" == "$used" ]] && continue 2
53		done
54		[[ -n $avail_disks ]] && avail_disks="$avail_disks $disk"
55		[[ -z $avail_disks ]] && avail_disks="$disk"
56	done
57
58	echo $avail_disks
59}
60
61function find_rpool
62{
63	typeset ds=$(mount | awk '/^\/ / {print $3}')
64	echo ${ds%%/*}
65}
66
67function find_runfile
68{
69	typeset distro=
70	if [[ -d /opt/delphix && -h /etc/delphix/version ]]; then
71		distro=delphix
72	elif grep -qs OpenIndiana /etc/release; then
73		distro=openindiana
74	elif grep -qs OmniOS /etc/release; then
75		distro=omnios
76	fi
77
78	[[ -n $distro ]] && echo $COMMON,$STF_SUITE/runfiles/$distro.run
79}
80
81function verify_id
82{
83	[[ $(id -u) == "0" ]] && fail "This script must not be run as root."
84
85	sudo -k -n id >/dev/null 2>&1 ||
86		fail "User must be able to sudo without a password."
87}
88
89function verify_disks
90{
91	typeset disk
92	typeset path
93	typeset -lu expected_size
94	typeset -lu size
95
96	# Ensure disks are large enough for the tests: no less than 10GB
97	# and large enough for a crash dump plus overheads: the disk partition
98	# table (about 34k), zpool with 4.5MB for pool label and 128k for pool
99	# data, so we round up pool data + labels to 5MB.
100	expected_size=$(sudo -k -n dumpadm -epH)
101	(( expected_size = expected_size + 5 * 1024 * 1024 ))
102
103	if (( expected_size < 10 * 1024 * 1024 * 1024 )); then
104		(( expected_size = 10 * 1024 * 1024 * 1024 ))
105	fi
106
107	for disk in $DISKS; do
108		case $disk in
109		/*) path=$disk;;
110		*) path=/dev/rdsk/${disk}s0
111		esac
112		set -A disksize $(sudo -k prtvtoc $path 2>&1 |
113			awk '$3 == "bytes/sector" ||
114			    ($3 == "accessible" && $4 == "sectors") {print $2}')
115
116		if [[ (-n "${disksize[0]}") && (-n "${disksize[1]}") ]]; then
117			(( size = disksize[0] * disksize[1] ))
118		else
119			return 1
120		fi
121		if (( size <  expected_size )); then
122			(( size = expected_size / 1024 / 1024 / 1024 ))
123			fail "$disk is too small, need at least ${size}GB"
124		fi
125	done
126	return 0
127}
128
129function create_links
130{
131	typeset dir=$1
132	typeset file_list=$2
133
134	[[ -n $PATHDIR ]] || fail "PATHDIR wasn't correctly set"
135
136	for i in $file_list; do
137		[[ ! -e $PATHDIR/$i ]] || fail "$i already exists"
138		ln -s $dir/$i $PATHDIR/$i || fail "Couldn't link $i"
139	done
140
141}
142
143function constrain_path
144{
145	. $STF_SUITE/include/commands.cfg
146
147	PATHDIR=$(/usr/bin/mktemp -d /var/tmp/constrained_path.XXXX)
148	chmod 755 $PATHDIR || fail "Couldn't chmod $PATHDIR"
149
150	create_links "/usr/bin" "$USR_BIN_FILES"
151	create_links "/usr/sbin" "$USR_SBIN_FILES"
152	create_links "/sbin" "$SBIN_FILES"
153	create_links "/opt/zfs-tests/bin" "$ZFSTEST_FILES"
154
155	# Special case links
156	ln -s /usr/gnu/bin/dd $PATHDIR/gnu_dd
157}
158
159constrain_path
160export PATH=$PATHDIR
161
162verify_id
163while getopts ac:l:qT: c; do
164	case $c in
165	'a')
166		auto_detect=true
167		;;
168	'c')
169		runfile=$OPTARG
170		[[ -f $runfile ]] || fail "Cannot read file: $runfile"
171		if [[ -z $runfiles ]]; then
172			runfiles=$runfile
173		else
174			runfiles+=",$runfile"
175		fi
176		;;
177	'l')
178		logfile=$OPTARG
179		[[ -f $logfile ]] || fail "Cannot read file: $logfile"
180		xargs+=" -l $logfile"
181		;;
182	'q')
183		xargs+=" -q"
184		;;
185	'T')
186		xargs+=" -T $OPTARG"
187		;;
188	esac
189done
190shift $((OPTIND - 1))
191
192# If the user specified -a, then use free disks, otherwise use those in $DISKS.
193if $auto_detect; then
194	export DISKS=$(find_disks)
195elif [[ -z $DISKS ]]; then
196	fail "\$DISKS not set in env, and -a not specified."
197else
198	verify_disks || fail "Couldn't verify all the disks in \$DISKS"
199fi
200
201# Add the root pool to $KEEP according to its contents.
202# It's ok to list it twice.
203if [[ -z $KEEP ]]; then
204	KEEP="$(find_rpool)"
205else
206	KEEP+=" $(find_rpool)"
207fi
208
209export __ZFS_POOL_EXCLUDE="$KEEP"
210export KEEP="^$(echo $KEEP | sed 's/ /$|^/g')\$"
211
212[[ -z $runfiles ]] && runfiles=$(find_runfile)
213[[ -z $runfiles ]] && fail "Couldn't determine distro"
214
215. $STF_SUITE/include/default.cfg
216
217num_disks=$(echo $DISKS | awk '{print NF}')
218(( num_disks < 3 )) && fail "Not enough disks to run ZFS Test Suite"
219
220# Ensure user has only basic privileges.
221ppriv -s EIP=basic -e $runner -c $runfiles $xargs
222ret=$?
223
224rm -rf $PATHDIR || fail "Couldn't remove $PATHDIR"
225
226exit $ret
227