1185029Spjd# $FreeBSD$
2185029Spjd
3185029Spjdntest=1
4185029Spjdos=`uname -s`
5185029Spjd
6185029Spjdecho ${dir} | egrep '^/' >/dev/null 2>&1
7185029Spjdif [ $? -eq 0 ]; then
8185029Spjd	maindir="${dir}/../.."
9185029Spjdelse
10185029Spjd	maindir="`pwd`/${dir}/../.."
11185029Spjdfi
12185029Spjd
13185029Spjd# Set up correct command names and switches
14185029Spjdif [ -z "${LUSTRE}" ]; then
15185029Spjd	ZPOOL="zpool"
16185029Spjd	ZFS="zfs"
17185029Spjd	ZDB="zdb"
18185029Spjd	zpool_f_flag="-f"
19185029Spjdelse
20185029Spjd	ZPOOL="lzpool"
21185029Spjd	ZFS="lzfs"
22185029Spjd	ZDB="lzdb"
23185029Spjd	zpool_f_flag="-F"
24185029Spjd	no_mountpoint=1
25185029Spjdfi
26185029Spjd
27185029Spjd# Use correct arguments to cmd line programs
28185029Spjdstat --version 2>/dev/null | grep GNU >/dev/null
29185029Spjdif [ $? -eq 0 ]; then
30185029Spjd	GNU_STAT="yes"
31185029Spjdfi
32185029Spjdif [ "${os}" = "SunOS" ]; then
33185029Spjd	import_flags="-d /dev/lofi"
34185029Spjd	mount_t_flag="-F"
35185029Spjdelse
36185029Spjd	mount_t_flag="-t"
37185029Spjdfi
38185029Spjd
39185029Spjddie()
40185029Spjd{
41185029Spjd	echo "${1}" > /dev/stderr
42274543Sngie	echo "Bail out!"
43185029Spjd	exit 1
44185029Spjd}
45185029Spjd
46185029Spjdcalcsum()
47185029Spjd{
48185029Spjd	dd if="${1}" bs=1M 2>/dev/null | openssl md5
49185029Spjd}
50185029Spjd
51185029Spjdcreate_file()
52185029Spjd{
53185029Spjd	name="${1}"
54185029Spjd	size="${2}"
55185029Spjd
56185029Spjd	dd if=/dev/urandom of=${name} bs=${size} count=1 >/dev/null 2>&1
57185029Spjd	sync
58185029Spjd}
59185029Spjd
60185029Spjdexpect()
61185029Spjd{
62185029Spjd	eorig="${1}"
63185029Spjd	eexp=`echo "${eorig}" | egrep -v '^[ 	]*$' | sed 's/^[ 	][ 	]*//g;s/[ 	][ 	]*$//g;s/[ 	][ 	]*/ /g;s/$/%EoL%/' | xargs`
64185029Spjd	shift
65185029Spjd	gorig=`sh -c "$*" 2>&1`
66185029Spjd	got=`echo "${gorig}" | egrep -v '^[ 	]*$' | sed 's/^[ 	][ 	]*//g;s/[ 	][ 	]*$//g;s/[ 	][ 	]*/ /g;s/$/%EoL%/' | xargs`
67185029Spjd	echo "${got}" | egrep "${eexp}" >/dev/null
68185029Spjd	if [ $? -eq 0 ]; then
69185029Spjd		echo "ok ${ntest} ${add_msg}"
70185029Spjd	else
71185029Spjd		echo "not ok ${ntest} ${add_msg}"
72185029Spjd		echo "# ----- expected from: $*"
73185029Spjd		echo "${eorig}" | sed 's/^/# /'
74185029Spjd		echo "# ----- got:"
75185029Spjd		echo "${gorig}" | sed 's/^/# /'
76185029Spjd		echo "# ----- end"
77185029Spjd	fi
78185029Spjd	ntest=`expr $ntest + 1`
79185029Spjd}
80185029Spjd
81185029Spjdexpect_ok()
82185029Spjd{
83185029Spjd	out=`$* 2>&1`
84185029Spjd	ec=$?
85185029Spjd	if [ $ec -eq 0 ]; then
86185029Spjd		echo "ok ${ntest} ${add_msg}"
87185029Spjd		echo "# ----- expected success from: $*"
88185029Spjd		if [ ! -z "${out}" ]; then
89185029Spjd			echo "# ----- output (exit code=${ec}):"
90185029Spjd			echo "${out}" | sed 's/^/# /'
91185029Spjd			echo "# ----- end"
92185029Spjd		fi
93185029Spjd	else
94185029Spjd		echo "not ok ${ntest} ${add_msg}"
95185029Spjd		echo "# ----- expected success from: $*"
96185029Spjd		echo "# ----- output (exit code=${ec}):"
97185029Spjd		echo "${out}" | sed 's/^/# /'
98185029Spjd		echo "# ----- end"
99185029Spjd	fi
100185029Spjd	ntest=`expr $ntest + 1`
101185029Spjd}
102185029Spjd
103185029Spjdexpect_fl()
104185029Spjd{
105185029Spjd	out=`$* 2>&1`
106185029Spjd	ec=$?
107185029Spjd	if [ $ec -ne 0 ]; then
108185029Spjd		echo "ok ${ntest} ${add_msg}"
109185029Spjd		echo "# ----- expected failure from: $*"
110185029Spjd		if [ ! -z "${out}" ]; then
111185029Spjd			echo "# ----- output (exit code=${ec}):"
112185029Spjd			echo "${out}" | sed 's/^/# /'
113185029Spjd			echo "# ----- end"
114185029Spjd		fi
115185029Spjd	else
116185029Spjd		echo "not ok ${ntest} ${add_msg}"
117185029Spjd		echo "# ----- expected failure from: $*"
118185029Spjd		echo "# ----- output (exit code=${ec}):"
119185029Spjd		echo "${out}" | sed 's/^/# /'
120185029Spjd		echo "# ----- end"
121185029Spjd	fi
122185029Spjd	ntest=`expr $ntest + 1`
123185029Spjd}
124185029Spjd
125185029Spjdquick_exit()
126185029Spjd{
127185029Spjd	echo "1..1"
128185029Spjd	echo "ok 1"
129185029Spjd	exit 0
130185029Spjd}
131185029Spjd
132185029Spjd# Set up a scratch tmpfs directory (Linux only)
133185029Spjdsetup_tmpfs()
134185029Spjd{
135185029Spjd	cmd="mktemp -d /tmp/zfs-regression.XXXXXXXXXX"
136185029Spjd	TMPDIR=`${cmd}` || die "failed: ${cmd}"
137185029Spjd	cmd="mount -t tmpfs none ${TMPDIR}"
138185029Spjd	${cmd} || die "failed: ${cmd}"
139185029Spjd}
140185029Spjd
141185029Spjd# Clean up the tmpfs directory (Linux only)
142185029Spjdcleanup_tmpfs()
143185029Spjd{
144185029Spjd	if [ -n "${TMPDIR}" ]; then
145185029Spjd		cmd="umount ${TMPDIR} && rmdir ${TMPDIR}"
146185029Spjd		eval "${cmd}" || die "failed: ${cmd}"
147185029Spjd	fi
148185029Spjd}
149185029Spjd
150185029Spjd# Truncate a file
151185029Spjdtruncate_cmd()
152185029Spjd{
153185029Spjd	size="${1}"
154185029Spjd	file="${2}"
155185029Spjd
156185029Spjd	cmd="dd if=/dev/null of=${file} bs=1 count=0 seek=${size}"
157185029Spjd	${cmd} > /dev/null 2>&1 || die "failed: ${cmd}"
158185029Spjd}
159185029Spjd
160185029Spjd# Create a memory-backed block device
161185029Spjdcreate_memdisk()
162185029Spjd{
163185029Spjd	size="${1}"
164185029Spjd	devname="${2}"
165185029Spjd
166185029Spjd	if [ "${os}" = "FreeBSD" ]; then
167185029Spjd		if [ -n "${devname}" ]; then
168185029Spjd			devparam="-u ${devname}"
169185029Spjd		fi
170274543Sngie		cmd="mdconfig -a -t swap -s ${size} ${devparam}"
171274543Sngie		DISKNAME=`$cmd 2>/dev/null` || die "failed: ${cmd}"
172185029Spjd		if [ -n "${devname}" ]; then
173185029Spjd			DISKNAME="${devname}"
174185029Spjd		fi
175185029Spjd		FDISKNAME="/dev/${DISKNAME}"
176185029Spjd	elif [ "${os}" = "SunOS" ]; then
177185029Spjd		cmd="mktemp /tmp/zfstest.XXXXXXXXXX"
178185029Spjd		fname=`${cmd}` || die "failed: ${cmd}"
179185029Spjd
180185029Spjd		truncate_cmd "${size}" "${fname}"
181185029Spjd
182185029Spjd		if [ -n "${devname}" ]; then
183185029Spjd			cmd="lofiadm -a ${fname} ${devname}"
184185029Spjd			${cmd} || die "failed: ${cmd}"
185185029Spjd			DISKNAME="${devname}"
186185029Spjd		else
187185029Spjd			cmd="lofiadm -a ${fname}"
188185029Spjd			DISKNAME=`${cmd}` || die "failed: ${cmd}"
189185029Spjd		fi
190185029Spjd		FDISKNAME="${DISKNAME}"
191185029Spjd	elif [ "${os}" = "Linux" ]; then
192185029Spjd		if [ -z "${TMPDIR_DISKS}" ]; then
193185029Spjd			setup_tmpfs
194185029Spjd			TMPDIR_DISKS="${TMPDIR}"
195185029Spjd		fi
196185029Spjd
197185029Spjd		cmd="mktemp ${TMPDIR_DISKS}/disk.XXXXXXXXXX"
198185029Spjd		fname=`${cmd}` || die "failed: ${cmd}"
199185029Spjd
200185029Spjd		truncate_cmd "${size}" "${fname}"
201185029Spjd
202185029Spjd		if [ -n "${devname}" ]; then
203185029Spjd			devname=`echo ${devname} | cut -c 9-`
204185029Spjd			cmd="losetup /dev/${devname} ${fname} 2>&1"
205185029Spjd			eval ${cmd} || die "failed: ${cmd}"
206185029Spjd			DISKNAME="${devname}"
207185029Spjd		else
208185029Spjd			cmd="losetup -s -f ${fname} 2>&1"
209185029Spjd			diskname=`eval ${cmd}`
210185029Spjd
211185029Spjd			if [ "${diskname}" = "losetup: could not find any free loop device" ]; then
212185029Spjd				# If there are no free loopback devices, create one more
213185029Spjd				max=`echo /dev/loop* | awk 'BEGIN { RS=" "; FS="loop" } {if ($2 > max) max = $2} END {print max}'`
214185029Spjd				max=$((max + 1))
215185029Spjd				cmd="mknod /dev/loop${max} b 7 ${max}"
216185029Spjd				${cmd} || die "failed: ${cmd}"
217185029Spjd
218185029Spjd				cmd="losetup -s -f ${fname}"
219185029Spjd				diskname=`${cmd}` || die "failed: ${cmd}"
220185029Spjd			fi
221185029Spjd			DISKNAME=`eval echo ${diskname} | sed 's/^\/dev\///'`
222185029Spjd		fi
223185029Spjd		ln /dev/${DISKNAME} /dev/zfstest_${DISKNAME}
224185029Spjd		DISKNAME="zfstest_${DISKNAME}"
225185029Spjd		FDISKNAME="/dev/${DISKNAME}"
226185029Spjd	else
227185029Spjd		die "Sorry, your OS is not supported"
228185029Spjd	fi
229185029Spjd}
230185029Spjd
231185029Spjd# Destroy a memory-backed block device
232185029Spjddestroy_memdisk()
233185029Spjd{
234185029Spjd	disk="${1}"
235185029Spjd
236185029Spjd	if [ "${os}" = "FreeBSD" ]; then
237185029Spjd		cmd="mdconfig -d -u ${disk}"
238185029Spjd		${cmd} || die "failed: ${cmd}"
239185029Spjd	elif [ "${os}" = "SunOS" ]; then
240185029Spjd		cmd="lofiadm ${disk}"
241185029Spjd		fname=`${cmd}` || die "failed: ${cmd}"
242185029Spjd
243185029Spjd		cmd="lofiadm -d ${disk}"
244185029Spjd		${cmd} || die "failed: ${cmd}"
245185029Spjd
246185029Spjd		cmd="rm ${fname}"
247185029Spjd		${cmd} || die "failed: ${cmd}"
248185029Spjd	elif [ "${os}" = "Linux" ]; then
249185029Spjd		cmd="rm /dev/${disk}"
250185029Spjd		${cmd} || die "failed: ${cmd}"
251185029Spjd		disk=`echo ${disk} | cut -c 9-`
252185029Spjd
253185029Spjd		cmd="losetup /dev/${disk} | awk '{print substr(\$3, 2, length(\$3)-2)}'"
254185029Spjd		fname=`eval ${cmd}` || die "failed: ${cmd}"
255185029Spjd
256185029Spjd		cmd="losetup -d /dev/${disk}"
257185029Spjd		${cmd} || die "failed: ${cmd}"
258185029Spjd
259185029Spjd		cmd="rm ${fname}"
260185029Spjd		${cmd} || die "failed: ${cmd}"
261185029Spjd	else
262185029Spjd		die "Sorry, your OS is not supported"
263185029Spjd	fi
264185029Spjd}
265185029Spjd
266185029Spjddisks_create()
267185029Spjd{
268185029Spjd	if [ -z "${ndisks}" ]; then
269185029Spjd		start=0
270185029Spjd	else
271185029Spjd		start=${ndisks}
272185029Spjd	fi
273185029Spjd	ndisks=$((start+$1))
274185029Spjd	n=$((ndisks-$start))
275185029Spjd	if [ -z "${2}" ]; then
276185029Spjd		size="96M"
277185029Spjd	else
278185029Spjd		size="${2}"
279185029Spjd	fi
280185029Spjd	for i in `nums $n $start`; do
281185029Spjd		create_memdisk ${size}
282185029Spjd		eval disk${i}="${DISKNAME}"
283185029Spjd		eval fdisk${i}="${FDISKNAME}"
284185029Spjd	done
285185029Spjd}
286185029Spjd
287185029Spjddisks_destroy()
288185029Spjd{
289185029Spjd	for i in `nums $ndisks 0`; do
290185029Spjd		eval disk=\$disk${i}
291185029Spjd		if [ ! -z "${disk}" ]; then
292185029Spjd			destroy_memdisk ${disk}
293185029Spjd		fi
294185029Spjd	done
295185029Spjd	[ -n "${TMPDIR_DISKS}" ] && TMPDIR="${TMPDIR_DISKS}" cleanup_tmpfs
296185029Spjd	return 0
297185029Spjd}
298185029Spjd
299185029Spjddisk_create()
300185029Spjd{
301185029Spjd	diskno=${1}
302185029Spjd	eval disk=\$disk${diskno}
303185029Spjd	if [ ! -z ${disk} ]; then
304185029Spjd		die "disk${diskno} is already set"
305185029Spjd	fi
306185029Spjd	dname=${2}
307185029Spjd	if [ -z "${3}" ]; then
308185029Spjd		size="96M"
309185029Spjd	else
310185029Spjd		size="${3}"
311185029Spjd	fi
312185029Spjd	create_memdisk ${size} ${dname}
313185029Spjd	[ "${DISKNAME}" = "${dname}" ] || die "${DISKNAME} != ${dname}"
314185029Spjd	eval disk${diskno}="${DISKNAME}"
315185029Spjd	eval fdisk${diskno}="${FDISKNAME}"
316185029Spjd}
317185029Spjd
318185029Spjddisk_destroy()
319185029Spjd{
320185029Spjd	eval disk=\$disk${1}
321185029Spjd	destroy_memdisk ${disk}
322185029Spjd	eval disk${1}=""
323185029Spjd}
324185029Spjd
325185029Spjdfiles_create()
326185029Spjd{
327185029Spjd	if [ -z "${nfiles}" ]; then
328185029Spjd		start=0
329185029Spjd	else
330185029Spjd		start=${nfiles}
331185029Spjd	fi
332185029Spjd	nfiles=$((start+$1))
333185029Spjd	n=$((nfiles-$start))
334185029Spjd	if [ -z "${2}" ]; then
335185029Spjd		size="96M"
336185029Spjd	else
337185029Spjd		size="${2}"
338185029Spjd	fi
339185029Spjd	for i in `nums $n $start`; do
340185029Spjd		if [ "${os}" = "Linux" ]; then
341185029Spjd			if [ -z "${TMPDIR_FILES}" ]; then
342185029Spjd				setup_tmpfs
343185029Spjd				TMPDIR_FILES="${TMPDIR}"
344185029Spjd			fi
345185029Spjd			file=`mktemp ${TMPDIR_FILES}/zfstest.XXXXXXXX`
346185029Spjd		else
347185029Spjd			file=`mktemp /tmp/zfstest.XXXXXXXX`
348185029Spjd		fi
349185029Spjd		truncate_cmd ${size} ${file}
350185029Spjd		eval file${i}=${file}
351185029Spjd	done
352185029Spjd}
353185029Spjd
354185029Spjdfiles_destroy()
355185029Spjd{
356185029Spjd	for i in `nums $nfiles 0`; do
357185029Spjd		eval file=\$file${i}
358185029Spjd		rm -f ${file}
359185029Spjd	done
360185029Spjd	nfiles=0
361185029Spjd	[ -n "${TMPDIR_FILES}" ] && TMPDIR="${TMPDIR_FILES}" cleanup_tmpfs
362185029Spjd	return 0
363185029Spjd}
364185029Spjd
365185029Spjdname_create()
366185029Spjd{
367274543Sngie	echo "zfstest_`dd if=/dev/urandom bs=1k count=1 2>/dev/null | openssl md5 | awk '{ print $NF }'`"
368185029Spjd}
369185029Spjd
370185029Spjdnames_create()
371185029Spjd{
372185029Spjd	nnames=$1
373185029Spjd	for i in `nums $nnames 0`; do
374185029Spjd		eval name${i}=`name_create`
375185029Spjd	done
376185029Spjd}
377185029Spjd
378185029Spjdis_mountpoint()
379185029Spjd{
380185029Spjd	dir="${1}"
381185029Spjd	if [ ! -d "${dir}" ]; then
382185029Spjd		return 1
383185029Spjd	fi
384185029Spjd	if [ -n "${GNU_STAT}" ]; then
385185029Spjd		statcmd="stat -c"
386185029Spjd	else
387185029Spjd		statcmd="stat -f"
388185029Spjd	fi
389185029Spjd	if [ "`${statcmd} '%d' ${dir} 2>/dev/null`" -eq "`${statcmd} '%d' ${dir}/.. 2>/dev/null`" ]; then
390185029Spjd		return 1
391185029Spjd	fi
392185029Spjd	return 0
393185029Spjd}
394185029Spjd
395185029Spjdnums()
396185029Spjd{
397185029Spjd	which jot >/dev/null 2>&1
398185029Spjd	if [ $? -eq 0 ]; then
399185029Spjd		jot ${1} ${2}
400185029Spjd		return $?
401185029Spjd	fi
402185029Spjd
403185029Spjd	start="${2}"
404185029Spjd	[ -z "${start}" ] && start="1";
405185029Spjd	end=$((${1}+${start}-1))
406185029Spjd
407185029Spjd	which seq >/dev/null 2>&1
408185029Spjd	if [ $? -eq 0 ]; then
409185029Spjd		seq ${start} ${end}
410185029Spjd		return $?
411185029Spjd	fi
412185029Spjd
413185029Spjd	i=1
414185029Spjd	while :; do
415185029Spjd		echo $i
416185029Spjd		if [ $i -eq ${1} ]; then
417185029Spjd			break
418185029Spjd		fi
419185029Spjd		i=$((i+1))
420185029Spjd	done
421185029Spjd}
422185029Spjd
423185029Spjdwait_for_resilver()
424185029Spjd{
425185029Spjd	for i in `nums 64`; do
426185029Spjd		${ZPOOL} status ${1} | grep replacing >/dev/null
427185029Spjd		if [ $? -ne 0 ]; then
428185029Spjd			break
429185029Spjd		fi
430185029Spjd		sleep 1
431185029Spjd	done
432185029Spjd}
433185029Spjd
434185029Spjdget_guid()
435185029Spjd{ 
436185029Spjd	${ZDB} -l ${1} | grep -B1 ${1} | grep guid | head -n1 | awk 'BEGIN {FS="="} {print $2}'
437185029Spjd} 
438