xref: /freebsd/tools/regression/zfs/misc.sh (revision dd41de95a84d979615a2ef11df6850622bf6184e)
1# $FreeBSD$
2
3ntest=1
4os=`uname -s`
5
6echo ${dir} | egrep '^/' >/dev/null 2>&1
7if [ $? -eq 0 ]; then
8	maindir="${dir}/../.."
9else
10	maindir="`pwd`/${dir}/../.."
11fi
12
13# Set up correct command names and switches
14if [ -z "${LUSTRE}" ]; then
15	ZPOOL="zpool"
16	ZFS="zfs"
17	ZDB="zdb"
18	zpool_f_flag="-f"
19else
20	ZPOOL="lzpool"
21	ZFS="lzfs"
22	ZDB="lzdb"
23	zpool_f_flag="-F"
24	no_mountpoint=1
25fi
26
27# Use correct arguments to cmd line programs
28stat --version 2>/dev/null | grep GNU >/dev/null
29if [ $? -eq 0 ]; then
30	GNU_STAT="yes"
31fi
32if [ "${os}" = "SunOS" ]; then
33	import_flags="-d /dev/lofi"
34	mount_t_flag="-F"
35else
36	mount_t_flag="-t"
37fi
38
39die()
40{
41	echo "${1}" > /dev/stderr
42	echo "Bail out!"
43	exit 1
44}
45
46calcsum()
47{
48	dd if="${1}" bs=1M 2>/dev/null | openssl md5
49}
50
51create_file()
52{
53	name="${1}"
54	size="${2}"
55
56	dd if=/dev/urandom of=${name} bs=${size} count=1 >/dev/null 2>&1
57	sync
58}
59
60expect()
61{
62	eorig="${1}"
63	eexp=`echo "${eorig}" | egrep -v '^[ 	]*$' | sed 's/^[ 	][ 	]*//g;s/[ 	][ 	]*$//g;s/[ 	][ 	]*/ /g;s/$/%EoL%/' | xargs`
64	shift
65	gorig=`sh -c "$*" 2>&1`
66	got=`echo "${gorig}" | egrep -v '^[ 	]*$' | sed 's/^[ 	][ 	]*//g;s/[ 	][ 	]*$//g;s/[ 	][ 	]*/ /g;s/$/%EoL%/' | xargs`
67	echo "${got}" | egrep "${eexp}" >/dev/null
68	if [ $? -eq 0 ]; then
69		echo "ok ${ntest} ${add_msg}"
70	else
71		echo "not ok ${ntest} ${add_msg}"
72		echo "# ----- expected from: $*"
73		echo "${eorig}" | sed 's/^/# /'
74		echo "# ----- got:"
75		echo "${gorig}" | sed 's/^/# /'
76		echo "# ----- end"
77	fi
78	ntest=`expr $ntest + 1`
79}
80
81expect_ok()
82{
83	out=`$* 2>&1`
84	ec=$?
85	if [ $ec -eq 0 ]; then
86		echo "ok ${ntest} ${add_msg}"
87		echo "# ----- expected success from: $*"
88		if [ ! -z "${out}" ]; then
89			echo "# ----- output (exit code=${ec}):"
90			echo "${out}" | sed 's/^/# /'
91			echo "# ----- end"
92		fi
93	else
94		echo "not ok ${ntest} ${add_msg}"
95		echo "# ----- expected success from: $*"
96		echo "# ----- output (exit code=${ec}):"
97		echo "${out}" | sed 's/^/# /'
98		echo "# ----- end"
99	fi
100	ntest=`expr $ntest + 1`
101}
102
103expect_fl()
104{
105	out=`$* 2>&1`
106	ec=$?
107	if [ $ec -ne 0 ]; then
108		echo "ok ${ntest} ${add_msg}"
109		echo "# ----- expected failure from: $*"
110		if [ ! -z "${out}" ]; then
111			echo "# ----- output (exit code=${ec}):"
112			echo "${out}" | sed 's/^/# /'
113			echo "# ----- end"
114		fi
115	else
116		echo "not ok ${ntest} ${add_msg}"
117		echo "# ----- expected failure from: $*"
118		echo "# ----- output (exit code=${ec}):"
119		echo "${out}" | sed 's/^/# /'
120		echo "# ----- end"
121	fi
122	ntest=`expr $ntest + 1`
123}
124
125quick_exit()
126{
127	echo "1..1"
128	echo "ok 1"
129	exit 0
130}
131
132# Set up a scratch tmpfs directory (Linux only)
133setup_tmpfs()
134{
135	cmd="mktemp -d /tmp/zfs-regression.XXXXXXXXXX"
136	TMPDIR=`${cmd}` || die "failed: ${cmd}"
137	cmd="mount -t tmpfs none ${TMPDIR}"
138	${cmd} || die "failed: ${cmd}"
139}
140
141# Clean up the tmpfs directory (Linux only)
142cleanup_tmpfs()
143{
144	if [ -n "${TMPDIR}" ]; then
145		cmd="umount ${TMPDIR} && rmdir ${TMPDIR}"
146		eval "${cmd}" || die "failed: ${cmd}"
147	fi
148}
149
150# Truncate a file
151truncate_cmd()
152{
153	size="${1}"
154	file="${2}"
155
156	cmd="dd if=/dev/null of=${file} bs=1 count=0 seek=${size}"
157	${cmd} > /dev/null 2>&1 || die "failed: ${cmd}"
158}
159
160# Create a memory-backed block device
161create_memdisk()
162{
163	size="${1}"
164	devname="${2}"
165
166	if [ "${os}" = "FreeBSD" ]; then
167		if [ -n "${devname}" ]; then
168			devparam="-u ${devname}"
169		fi
170		cmd="mdconfig -a -t swap -s ${size} ${devparam}"
171		DISKNAME=`$cmd 2>/dev/null` || die "failed: ${cmd}"
172		if [ -n "${devname}" ]; then
173			DISKNAME="${devname}"
174		fi
175		FDISKNAME="/dev/${DISKNAME}"
176	elif [ "${os}" = "SunOS" ]; then
177		cmd="mktemp /tmp/zfstest.XXXXXXXXXX"
178		fname=`${cmd}` || die "failed: ${cmd}"
179
180		truncate_cmd "${size}" "${fname}"
181
182		if [ -n "${devname}" ]; then
183			cmd="lofiadm -a ${fname} ${devname}"
184			${cmd} || die "failed: ${cmd}"
185			DISKNAME="${devname}"
186		else
187			cmd="lofiadm -a ${fname}"
188			DISKNAME=`${cmd}` || die "failed: ${cmd}"
189		fi
190		FDISKNAME="${DISKNAME}"
191	elif [ "${os}" = "Linux" ]; then
192		if [ -z "${TMPDIR_DISKS}" ]; then
193			setup_tmpfs
194			TMPDIR_DISKS="${TMPDIR}"
195		fi
196
197		cmd="mktemp ${TMPDIR_DISKS}/disk.XXXXXXXXXX"
198		fname=`${cmd}` || die "failed: ${cmd}"
199
200		truncate_cmd "${size}" "${fname}"
201
202		if [ -n "${devname}" ]; then
203			devname=`echo ${devname} | cut -c 9-`
204			cmd="losetup /dev/${devname} ${fname} 2>&1"
205			eval ${cmd} || die "failed: ${cmd}"
206			DISKNAME="${devname}"
207		else
208			cmd="losetup -s -f ${fname} 2>&1"
209			diskname=`eval ${cmd}`
210
211			if [ "${diskname}" = "losetup: could not find any free loop device" ]; then
212				# If there are no free loopback devices, create one more
213				max=`echo /dev/loop* | awk 'BEGIN { RS=" "; FS="loop" } {if ($2 > max) max = $2} END {print max}'`
214				max=$((max + 1))
215				cmd="mknod /dev/loop${max} b 7 ${max}"
216				${cmd} || die "failed: ${cmd}"
217
218				cmd="losetup -s -f ${fname}"
219				diskname=`${cmd}` || die "failed: ${cmd}"
220			fi
221			DISKNAME=`eval echo ${diskname} | sed 's/^\/dev\///'`
222		fi
223		ln /dev/${DISKNAME} /dev/zfstest_${DISKNAME}
224		DISKNAME="zfstest_${DISKNAME}"
225		FDISKNAME="/dev/${DISKNAME}"
226	else
227		die "Sorry, your OS is not supported"
228	fi
229}
230
231# Destroy a memory-backed block device
232destroy_memdisk()
233{
234	disk="${1}"
235
236	if [ "${os}" = "FreeBSD" ]; then
237		cmd="mdconfig -d -u ${disk}"
238		${cmd} || die "failed: ${cmd}"
239	elif [ "${os}" = "SunOS" ]; then
240		cmd="lofiadm ${disk}"
241		fname=`${cmd}` || die "failed: ${cmd}"
242
243		cmd="lofiadm -d ${disk}"
244		${cmd} || die "failed: ${cmd}"
245
246		cmd="rm ${fname}"
247		${cmd} || die "failed: ${cmd}"
248	elif [ "${os}" = "Linux" ]; then
249		cmd="rm /dev/${disk}"
250		${cmd} || die "failed: ${cmd}"
251		disk=`echo ${disk} | cut -c 9-`
252
253		cmd="losetup /dev/${disk} | awk '{print substr(\$3, 2, length(\$3)-2)}'"
254		fname=`eval ${cmd}` || die "failed: ${cmd}"
255
256		cmd="losetup -d /dev/${disk}"
257		${cmd} || die "failed: ${cmd}"
258
259		cmd="rm ${fname}"
260		${cmd} || die "failed: ${cmd}"
261	else
262		die "Sorry, your OS is not supported"
263	fi
264}
265
266disks_create()
267{
268	if [ -z "${ndisks}" ]; then
269		start=0
270	else
271		start=${ndisks}
272	fi
273	ndisks=$((start+$1))
274	n=$((ndisks-$start))
275	if [ -z "${2}" ]; then
276		size="96M"
277	else
278		size="${2}"
279	fi
280	for i in `nums $n $start`; do
281		create_memdisk ${size}
282		eval disk${i}="${DISKNAME}"
283		eval fdisk${i}="${FDISKNAME}"
284	done
285}
286
287disks_destroy()
288{
289	for i in `nums $ndisks 0`; do
290		eval disk=\$disk${i}
291		if [ ! -z "${disk}" ]; then
292			destroy_memdisk ${disk}
293		fi
294	done
295	[ -n "${TMPDIR_DISKS}" ] && TMPDIR="${TMPDIR_DISKS}" cleanup_tmpfs
296	return 0
297}
298
299disk_create()
300{
301	diskno=${1}
302	eval disk=\$disk${diskno}
303	if [ ! -z ${disk} ]; then
304		die "disk${diskno} is already set"
305	fi
306	dname=${2}
307	if [ -z "${3}" ]; then
308		size="96M"
309	else
310		size="${3}"
311	fi
312	create_memdisk ${size} ${dname}
313	[ "${DISKNAME}" = "${dname}" ] || die "${DISKNAME} != ${dname}"
314	eval disk${diskno}="${DISKNAME}"
315	eval fdisk${diskno}="${FDISKNAME}"
316}
317
318disk_destroy()
319{
320	eval disk=\$disk${1}
321	destroy_memdisk ${disk}
322	eval disk${1}=""
323}
324
325files_create()
326{
327	if [ -z "${nfiles}" ]; then
328		start=0
329	else
330		start=${nfiles}
331	fi
332	nfiles=$((start+$1))
333	n=$((nfiles-$start))
334	if [ -z "${2}" ]; then
335		size="96M"
336	else
337		size="${2}"
338	fi
339	for i in `nums $n $start`; do
340		if [ "${os}" = "Linux" ]; then
341			if [ -z "${TMPDIR_FILES}" ]; then
342				setup_tmpfs
343				TMPDIR_FILES="${TMPDIR}"
344			fi
345			file=`mktemp ${TMPDIR_FILES}/zfstest.XXXXXXXX`
346		else
347			file=`mktemp /tmp/zfstest.XXXXXXXX`
348		fi
349		truncate_cmd ${size} ${file}
350		eval file${i}=${file}
351	done
352}
353
354files_destroy()
355{
356	for i in `nums $nfiles 0`; do
357		eval file=\$file${i}
358		rm -f ${file}
359	done
360	nfiles=0
361	[ -n "${TMPDIR_FILES}" ] && TMPDIR="${TMPDIR_FILES}" cleanup_tmpfs
362	return 0
363}
364
365name_create()
366{
367	echo "zfstest_`dd if=/dev/urandom bs=1k count=1 2>/dev/null | openssl md5 | awk '{ print $NF }'`"
368}
369
370names_create()
371{
372	nnames=$1
373	for i in `nums $nnames 0`; do
374		eval name${i}=`name_create`
375	done
376}
377
378is_mountpoint()
379{
380	dir="${1}"
381	if [ ! -d "${dir}" ]; then
382		return 1
383	fi
384	if [ -n "${GNU_STAT}" ]; then
385		statcmd="stat -c"
386	else
387		statcmd="stat -f"
388	fi
389	if [ "`${statcmd} '%d' ${dir} 2>/dev/null`" -eq "`${statcmd} '%d' ${dir}/.. 2>/dev/null`" ]; then
390		return 1
391	fi
392	return 0
393}
394
395nums()
396{
397	which jot >/dev/null 2>&1
398	if [ $? -eq 0 ]; then
399		jot ${1} ${2}
400		return $?
401	fi
402
403	start="${2}"
404	[ -z "${start}" ] && start="1";
405	end=$((${1}+${start}-1))
406
407	which seq >/dev/null 2>&1
408	if [ $? -eq 0 ]; then
409		seq ${start} ${end}
410		return $?
411	fi
412
413	i=1
414	while :; do
415		echo $i
416		if [ $i -eq ${1} ]; then
417			break
418		fi
419		i=$((i+1))
420	done
421}
422
423wait_for_resilver()
424{
425	for i in `nums 64`; do
426		${ZPOOL} status ${1} | grep replacing >/dev/null
427		if [ $? -ne 0 ]; then
428			break
429		fi
430		sleep 1
431	done
432}
433
434get_guid()
435{
436	${ZDB} -l ${1} | grep -B1 ${1} | grep guid | head -n1 | awk 'BEGIN {FS="="} {print $2}'
437}
438