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