]> granicus.if.org Git - zfs/blob - scripts/common.sh.in
Illumos Crypto Port module added to enable native encryption in zfs
[zfs] / scripts / common.sh.in
1 #!/bin/bash
2 #
3 # Common support functions for testing scripts.  If a script-config
4 # files is available it will be sourced so in-tree kernel modules and
5 # utilities will be used.  If no script-config can be found then the
6 # installed kernel modules and utilities will be used.
7
8 basedir="$(dirname $0)"
9
10 SCRIPT_CONFIG=zfs-script-config.sh
11 if [ -f "${basedir}/../${SCRIPT_CONFIG}" ]; then
12 . "${basedir}/../${SCRIPT_CONFIG}"
13 else
14 KERNEL_MODULES=(zlib_deflate zlib_inflate)
15 MODULES=(spl splat zavl znvpair zunicode zcommon icp zfs)
16 fi
17
18 PROG="<define PROG>"
19 CLEANUP=
20 VERBOSE=
21 VERBOSE_FLAG=
22 FORCE=
23 FORCE_FLAG=
24 DUMP_LOG=
25 ERROR=
26 RAID0S=()
27 RAID10S=()
28 RAIDZS=()
29 RAIDZ2S=()
30 TESTS_RUN=${TESTS_RUN:-'*'}
31 TESTS_SKIP=${TESTS_SKIP:-}
32
33 prefix=@prefix@
34 exec_prefix=@exec_prefix@
35 pkgdatadir=@datarootdir@/@PACKAGE@
36 bindir=@bindir@
37 sbindir=@sbindir@
38 udevdir=@udevdir@
39 udevruledir=@udevruledir@
40 mounthelperdir=@mounthelperdir@
41 sysconfdir=@sysconfdir@
42 localstatedir=@localstatedir@
43
44 ETCDIR=${ETCDIR:-/etc}
45 DEVDIR=${DEVDIR:-/dev/disk/by-vdev}
46 ZPOOLDIR=${ZPOOLDIR:-${pkgdatadir}/zpool-config}
47 ZPIOSDIR=${ZPIOSDIR:-${pkgdatadir}/zpios-test}
48 ZPIOSPROFILEDIR=${ZPIOSPROFILEDIR:-${pkgdatadir}/zpios-profile}
49 TESTSDIR=${TESTSDIR:-${pkgdatadir}/zfs-tests}
50 RUNFILEDIR=${RUNFILEDIR:-${pkgdatadir}/runfiles}
51
52 ZDB=${ZDB:-${sbindir}/zdb}
53 ZFS=${ZFS:-${sbindir}/zfs}
54 ZINJECT=${ZINJECT:-${sbindir}/zinject}
55 ZHACK=${ZHACK:-${sbindir}/zhack}
56 ZPOOL=${ZPOOL:-${sbindir}/zpool}
57 ZTEST=${ZTEST:-${sbindir}/ztest}
58 ZPIOS=${ZPIOS:-${sbindir}/zpios}
59
60 COMMON_SH=${COMMON_SH:-${pkgdatadir}/common.sh}
61 ZFS_SH=${ZFS_SH:-${pkgdatadir}/zfs.sh}
62 ZPOOL_CREATE_SH=${ZPOOL_CREATE_SH:-${pkgdatadir}/zpool-create.sh}
63 ZPIOS_SH=${ZPIOS_SH:-${pkgdatadir}/zpios.sh}
64 ZPIOS_SURVEY_SH=${ZPIOS_SURVEY_SH:-${pkgdatadir}/zpios-survey.sh}
65 TEST_RUNNER=${TEST_RUNNER:-${pkgdatadir}/test-runner/bin/test-runner.py}
66 STF_TOOLS=${STF_TOOLS:-${pkgdatadir}/test-runner}
67 STF_SUITE=${STF_SUITE:-${pkgdatadir}/zfs-tests}
68
69 LDMOD=${LDMOD:-/sbin/modprobe}
70 LSMOD=${LSMOD:-/sbin/lsmod}
71 RMMOD=${RMMOD:-/sbin/rmmod}
72 INFOMOD=${INFOMOD:-/sbin/modinfo}
73 LOSETUP=${LOSETUP:-/sbin/losetup}
74 MDADM=${MDADM:-/sbin/mdadm}
75 DMSETUP=${DMSETUP:-/sbin/dmsetup}
76 PARTED=${PARTED:-/sbin/parted}
77 BLOCKDEV=${BLOCKDEV:-/sbin/blockdev}
78 LSSCSI=${LSSCSI:-/usr/bin/lsscsi}
79 SCSIRESCAN=${SCSIRESCAN:-/usr/bin/scsi-rescan}
80 SYSCTL=${SYSCTL:-/sbin/sysctl}
81 UDEVADM=${UDEVADM:-/sbin/udevadm}
82 AWK=${AWK:-/usr/bin/awk}
83 GDB=${GDB:-/usr/bin/gdb}
84
85 ZED_PIDFILE=${ZED_PIDFILE:-${localstatedir}/run/zed.pid}
86
87 COLOR_BLACK="\033[0;30m"
88 COLOR_DK_GRAY="\033[1;30m"
89 COLOR_BLUE="\033[0;34m"
90 COLOR_LT_BLUE="\033[1;34m" 
91 COLOR_GREEN="\033[0;32m"
92 COLOR_LT_GREEN="\033[1;32m"
93 COLOR_CYAN="\033[0;36m"
94 COLOR_LT_CYAN="\033[1;36m"
95 COLOR_RED="\033[0;31m"
96 COLOR_LT_RED="\033[1;31m"
97 COLOR_PURPLE="\033[0;35m"
98 COLOR_LT_PURPLE="\033[1;35m"
99 COLOR_BROWN="\033[0;33m"
100 COLOR_YELLOW="\033[1;33m"
101 COLOR_LT_GRAY="\033[0;37m"
102 COLOR_WHITE="\033[1;37m"
103 COLOR_RESET="\033[0m"
104
105 die() {
106         echo -e "${PROG}: $1" >&2
107         exit 1
108 }
109
110 msg() {
111         if [ ${VERBOSE} ]; then
112                 echo "$@"
113         fi
114 }
115
116 pass() {
117         echo -e "${COLOR_GREEN}Pass${COLOR_RESET}"
118 }
119
120 fail() {
121         echo -e "${COLOR_RED}Fail${COLOR_RESET} ($1)"
122         exit $1
123 }
124
125 skip() {
126         echo -e "${COLOR_BROWN}Skip${COLOR_RESET}"
127 }
128
129 populate() {
130         local ROOT=$1
131         local MAX_DIR_SIZE=$2
132         local MAX_FILE_SIZE=$3
133
134         mkdir -p $ROOT/{a,b,c,d,e,f,g}/{h,i}
135         DIRS=`find $ROOT`
136
137         for DIR in $DIRS; do
138                 COUNT=$(($RANDOM % $MAX_DIR_SIZE))
139
140                 for i in `seq $COUNT`; do
141                         FILE=`mktemp -p ${DIR}`
142                         SIZE=$(($RANDOM % $MAX_FILE_SIZE))
143                         dd if=/dev/urandom of=$FILE bs=1k count=$SIZE &>/dev/null
144                 done
145         done
146
147         return 0
148 }
149
150 init() {
151         # Create a random directory tree of files and sub-directories to
152         # to act as a copy source for the various regression tests.
153         SRC_DIR=`mktemp -d -p /var/tmp/ zfs.src.XXXXXXXX`
154         trap "rm -Rf $SRC_DIR" INT TERM EXIT
155         populate $SRC_DIR 10 100
156 }
157
158 spl_dump_log() {
159         ${SYSCTL} -w kernel.spl.debug.dump=1 &>/dev/null
160         local NAME=`dmesg | tail -n 1 | cut -f5 -d' '`
161         ${SPLBUILD}/cmd/spl ${NAME} >${NAME}.log
162         echo
163         echo "Dumped debug log: ${NAME}.log"
164         tail -n1 ${NAME}.log
165         echo
166         return 0
167 }
168
169 check_modules() {
170         local LOADED_MODULES=()
171         local MISSING_MODULES=()
172
173         for MOD in ${MODULES[*]}; do
174                 local NAME=`basename $MOD .ko`
175
176                 if ${LSMOD} | egrep -q "^${NAME}"; then
177                         LOADED_MODULES=(${NAME} ${LOADED_MODULES[*]})
178                 fi
179
180                 if [ ${INFOMOD} ${MOD} 2>/dev/null ]; then
181                         MISSING_MODULES=("\t${MOD}\n" ${MISSING_MODULES[*]})
182                 fi
183         done
184
185         if [ ${#LOADED_MODULES[*]} -gt 0 ]; then
186                 ERROR="Unload these modules with '${PROG} -u':\n"
187                 ERROR="${ERROR}${LOADED_MODULES[*]}"
188                 return 1
189         fi
190
191         if [ ${#MISSING_MODULES[*]} -gt 0 ]; then
192                 ERROR="The following modules can not be found,"
193                 ERROR="${ERROR} ensure your source trees are built:\n"
194                 ERROR="${ERROR}${MISSING_MODULES[*]}"
195                 return 1
196         fi
197
198         return 0
199 }
200
201 load_module() {
202         local NAME=`basename $1 .ko`
203
204         if [ ${VERBOSE} ]; then
205                 echo "Loading ${NAME} ($@)"
206         fi
207
208         ${LDMOD} $* &>/dev/null
209         if [ $? -ne 0 ]; then
210                 echo "Failed to load ${NAME} ($@)"
211                 return 1
212         fi
213
214         return 0
215 }
216
217 load_modules() {
218         mkdir -p /etc/zfs
219
220         for MOD in ${KERNEL_MODULES[*]}; do
221                 load_module ${MOD} >/dev/null
222         done
223
224         for MOD in ${MODULES[*]}; do
225                 local NAME=`basename ${MOD} .ko`
226                 local VALUE=
227
228                 for OPT in "$@"; do
229                         OPT_NAME=`echo ${OPT} | cut -f1 -d'='`
230
231                         if [ ${NAME} = "${OPT_NAME}" ]; then
232                                 VALUE=`echo ${OPT} | cut -f2- -d'='`
233                         fi
234                 done
235
236                 load_module ${MOD} ${VALUE} || return 1
237         done
238
239         if [ ${VERBOSE} ]; then
240                 echo "Successfully loaded ZFS module stack"
241         fi
242
243         return 0
244 }
245
246 unload_module() {
247         local NAME=`basename $1 .ko`
248
249         if [ ${VERBOSE} ]; then
250                 echo "Unloading ${NAME} ($@)"
251         fi
252
253         ${RMMOD} ${NAME} || ERROR="Failed to unload ${NAME}" return 1
254
255         return 0
256 }
257
258 unload_modules() {
259         local MODULES_REVERSE=( $(echo ${MODULES[@]} |
260                 ${AWK} '{for (i=NF;i>=1;i--) printf $i" "} END{print ""}') )
261
262         for MOD in ${MODULES_REVERSE[*]}; do
263                 local NAME=`basename ${MOD} .ko`
264                 local USE_COUNT=`${LSMOD} |
265                                 egrep "^${NAME} "| ${AWK} '{print $3}'`
266
267                 if [ "${USE_COUNT}" = 0 ] ; then
268
269                         if [ "${DUMP_LOG}" -a ${NAME} = "spl" ]; then
270                                 spl_dump_log
271                         fi
272
273                         unload_module ${MOD} || return 1
274                 fi
275         done
276
277         if [ ${VERBOSE} ]; then
278                 echo "Successfully unloaded ZFS module stack"
279         fi
280
281         return 0
282 }
283
284 #
285 # Check that the mdadm utilities are installed.
286 #
287 check_loop_utils() {
288         test -f ${LOSETUP} || die "${LOSETUP} utility must be installed"
289 }
290
291
292 #
293 # Find and return an unused loop device.  A new /dev/loopN node will be
294 # created if required.  The kernel loop driver will automatically register
295 # the minor as long as it's less than /sys/module/loop/parameters/max_loop.
296 #
297 unused_loop_device() {
298         local DEVICE=$(${LOSETUP} -f)
299         local MAX_LOOP_PATH="/sys/module/loop/parameters/max_loop"
300         local MAX_LOOP;
301
302         # An existing /dev/loopN device was available.
303         if [ -n "${DEVICE}" ]; then
304                 echo "${DEVICE}"
305                 return 0
306         fi
307
308         # Create a new /dev/loopN provided we are not at MAX_LOOP.
309         if [ -f "${MAX_LOOP_PATH}" ]; then
310                 MAX_LOOP=`cat /sys/module/loop/parameters/max_loop`
311                 if [ ${MAX_LOOP} -eq 0 ]; then
312                         MAX_LOOP=255
313                 fi
314
315                 for (( i=0; i<=${MAX_LOOP}; i++ )); do
316                         DEVICE="/dev/loop$i"
317
318                         if [ -b "${DEVICE}" ]; then
319                                 continue
320                         else
321                                 mknod -m660 "${DEVICE}" b 7 $i
322                                 chown root.disk "${DEVICE}"
323                                 chmod 666 "${DEVICE}"
324
325                                 echo "${DEVICE}"
326                                 return 0
327                         fi
328                 done
329         fi
330
331         die "Error: Unable to create new loopback device"
332 }
333
334 #
335 # This can be slightly dangerous because the loop devices we are
336 # cleaning up may not be ours.  However, if the devices are currently
337 # in use we will not be able to remove them, and we only remove
338 # devices which include 'zpool' or 'deleted' in the name.  So any
339 # damage we might do should be limited to other zfs related testing.
340 #
341 cleanup_loop_devices() {
342         local TMP_FILE=`mktemp`
343
344         ${LOSETUP} -a | tr -d '()' >${TMP_FILE}
345         ${AWK} -F":" -v losetup="$LOSETUP" \
346             '/zpool/ || /deleted/ { system("losetup -d "$1) }' ${TMP_FILE}
347         ${AWK} -F" " '/zpool/ || /deleted/ { system("rm -f "$3) }' ${TMP_FILE}
348
349         rm -f ${TMP_FILE}
350 }
351
352 #
353 # Destroy the passed loopback devices, this is used when you know
354 # the names of the loopback devices.
355 #
356 destroy_loop_devices() {
357         local LODEVICES="$1"
358
359         msg "Destroying ${LODEVICES}"
360         ${LOSETUP} -d ${LODEVICES} || \
361                 die "Error $? destroying ${FILE} -> ${DEVICE} loopback"
362
363         rm -f ${FILES}
364         return 0
365 }
366
367 #
368 # Create a device label taking care to briefly wait if udev needs to settle.
369 #
370 label() {
371         local DEVICE=$1
372         local LABEL=$2
373
374         wait_udev ${DEVICE} 30 || return 1
375         ${PARTED} ${DEVICE} --script -- mklabel ${LABEL} || return 2
376
377         return 0
378 }
379
380 #
381 # Create a primary partition on a block device.
382 #
383 partition() {
384         local DEVICE=$1
385         local TYPE=$2
386         local START=$3
387         local END=$4
388
389         ${PARTED} --align optimal ${DEVICE} --script -- \
390             mkpart ${TYPE} ${START} ${END} || return 1
391         udev_trigger
392
393         return 0
394 }
395
396 #
397 # Create a filesystem on the block device
398 #
399 format() {
400         local DEVICE=$1
401         local FSTYPE=$2
402
403         # Force 4K blocksize, else mkfs.ext2 tries to use 8K, which
404         # won't mount
405         /sbin/mkfs.${FSTYPE} -b 4096 -F -q ${DEVICE} >/dev/null || return 1
406
407         return 0
408 }
409
410 #
411 # Check that the mdadm utilities are installed.
412 #
413 check_md_utils() {
414         test -f ${MDADM} || die "${MDADM} utility must be installed"
415         test -f ${PARTED} || die "${PARTED} utility must be installed"
416 }
417
418 check_md_partitionable() {
419         local LOFILE=`mktemp -p /tmp zpool-lo.XXXXXXXX`
420         local LODEVICE=`unused_loop_device`
421         local MDDEVICE=`unused_md_device`
422         local RESULT=1
423
424         check_md_utils
425
426         rm -f ${LOFILE}
427         dd if=/dev/zero of=${LOFILE} bs=1M count=0 seek=16 \
428                 &>/dev/null || return ${RESULT}
429
430         msg "Creating ${LODEVICE} using ${LOFILE}"
431         ${LOSETUP} ${LODEVICE} ${LOFILE}
432         if [ $? -ne 0 ]; then
433                 rm -f ${LOFILE}
434                 return ${RESULT}
435         fi
436
437         msg "Creating ${MDDEVICE} using ${LODEVICE}"
438         ${MDADM} --build ${MDDEVICE} --level=faulty \
439                 --raid-devices=1 ${LODEVICE} &>/dev/null
440         if [ $? -ne 0 ]; then
441                 destroy_loop_devices ${LODEVICE}
442                 rm -f ${LOFILE}
443                 return ${RESULT}
444         fi
445         wait_udev ${MDDEVICE} 30
446
447         ${BLOCKDEV} --rereadpt ${MDDEVICE} 2>/dev/null
448         RESULT=$?
449
450         destroy_md_devices ${MDDEVICE}
451         destroy_loop_devices ${LODEVICE}
452         rm -f ${LOFILE}
453
454         return ${RESULT}
455 }
456
457 #
458 # Find and return an unused md device.
459 #
460 unused_md_device() {
461         for (( i=0; i<32; i++ )); do
462                 MDDEVICE=md${i}
463
464                 # Skip active devicesudo in /proc/mdstat.
465                 grep -q "${MDDEVICE} " /proc/mdstat && continue
466
467                 # Device doesn't exist, use it.
468                 if [ ! -e $/dev/{MDDEVICE} ]; then
469                         echo /dev/${MDDEVICE}
470                         return
471                 fi
472
473                 # Device exists but may not be in use.
474                 if [ -b /dev/${MDDEVICE} ]; then
475                         ${MDADM} --detail /dev/${MDDEVICE} &>/dev/null
476                         if [ $? -eq 1 ]; then
477                                 echo /dev/${MDDEVICE}
478                                 return
479                         fi
480                 fi
481         done
482
483         die "Error: Unable to find unused md device"
484 }
485
486 #
487 # This can be slightly dangerous because it is possible the md devices
488 # we are cleaning up may not be ours.  However, if the devices are
489 # currently in use we will not be able to remove them, and even if
490 # we remove devices which were not out we do not zero the super block
491 # so you should be able to reconstruct them.
492 #
493 cleanup_md_devices() {
494         destroy_md_devices "`ls /dev/md* 2>/dev/null | grep -v p`"
495         udev_trigger
496 }
497
498 #
499 # Destroy the passed md devices, this is used when you know
500 # the names of the md devices.
501 #
502 destroy_md_devices() {
503         local MDDEVICES="$1"
504
505         msg "Destroying ${MDDEVICES}"
506         for MDDEVICE in ${MDDEVICES}; do
507                 ${MDADM} --stop ${MDDEVICE} &>/dev/null
508                 ${MDADM} --remove ${MDDEVICE} &>/dev/null
509                 ${MDADM} --detail ${MDDEVICE} &>/dev/null
510         done
511
512         return 0
513 }
514
515 #
516 # Check that the scsi utilities are installed.
517 #
518 check_sd_utils() {
519         ${INFOMOD} scsi_debug &>/dev/null || die "scsi_debug module required"
520         test -f ${LSSCSI} || die "${LSSCSI} utility must be installed"
521 }
522
523 #
524 # Rescan the scsi bus for scsi_debug devices.  It is preferable to use the
525 # scsi-rescan tool if it is installed, but if it's not we can fall back to
526 # removing and readding the device manually.  This rescan will only effect
527 # the first scsi_debug device if scsi-rescan is missing.
528 #
529 scsi_rescan() {
530         local AWK_SCRIPT="/scsi_debug/ { print \$1; exit }"
531
532         if [ -f ${SCSIRESCAN} ]; then
533                 ${SCSIRESCAN} --forcerescan --remove &>/dev/null
534         else
535                 local SCSIID=`${LSSCSI} | ${AWK} "${AWK_SCRIPT}" | tr -d '[]'`
536                 local SCSIHOST=`echo ${SCSIID} | cut -f1 -d':'`
537                 echo 1 >"/sys/class/scsi_device/${SCSIID}/device/delete"
538                 udev_trigger
539                 echo "- - -" >/sys/class/scsi_host/host${SCSIHOST}/scan
540                 udev_trigger
541         fi
542 }
543
544 #
545 # Trigger udev and wait for it to settle.
546 #
547 udev_trigger() {
548         if [ -f ${UDEVADM} ]; then
549                 ${UDEVADM} trigger --action=change --subsystem-match=block
550                 ${UDEVADM} settle
551         else
552                 /sbin/udevtrigger
553                 /sbin/udevsettle
554         fi
555 }
556
557 #
558 # The following udev helper functions assume that the provided
559 # udev rules file will create a /dev/disk/by-vdev/<CHANNEL><RANK>
560 # disk mapping.  In this mapping each CHANNEL is represented by
561 # the letters a-z, and the RANK is represented by the numbers
562 # 1-n.  A CHANNEL should identify a group of RANKS which are all
563 # attached to a single controller, each RANK represents a disk.
564 # This provides a simply mechanism to locate a specific drive
565 # given a known hardware configuration.
566 #
567 udev_setup() {
568         local SRC_PATH=$1
569
570         # When running in tree manually contruct symlinks in tree to
571         # the proper devices.  Symlinks are installed for all entires
572         # in the config file regardless of if that device actually
573         # exists.  When installed as a package udev can be relied on for
574         # this and it will only create links for devices which exist.
575         if [ ${INTREE} ]; then
576                 PWD=`pwd`
577                 mkdir -p ${DEVDIR}/
578                 cd ${DEVDIR}/
579                 ${AWK} '!/^#/ && /./ { system( \
580                         "ln -f -s /dev/disk/by-path/"$2" "$1";" \
581                         "ln -f -s /dev/disk/by-path/"$2"-part1 "$1"p1;" \
582                         "ln -f -s /dev/disk/by-path/"$2"-part9 "$1"p9;" \
583                         ) }' $SRC_PATH
584                 cd ${PWD}
585         else
586                 DST_FILE=`basename ${SRC_PATH} | cut -f1-2 -d'.'`
587                 DST_PATH=/etc/zfs/${DST_FILE}
588
589                 if [ -e ${DST_PATH} ]; then
590                         die "Error: Config ${DST_PATH} already exists"
591                 fi
592
593                 cp ${SRC_PATH} ${DST_PATH}
594                 udev_trigger
595         fi
596
597         return 0
598 }
599
600 udev_cleanup() {
601         local SRC_PATH=$1
602
603         if [ ${INTREE} ]; then
604                 PWD=`pwd`
605                 cd ${DEVDIR}/
606                 ${AWK} '!/^#/ && /./ { system( \
607                         "rm -f "$1" "$1"p1 "$1"p9") }' $SRC_PATH
608                 cd ${PWD}
609         fi
610
611         return 0
612 }
613
614 udev_cr2d() {
615         local CHANNEL=`echo "obase=16; $1+96" | bc`
616         local RANK=$2
617
618         printf "\x${CHANNEL}${RANK}"
619 }
620
621 udev_raid0_setup() {
622         local RANKS=$1
623         local CHANNELS=$2
624         local IDX=0
625
626         RAID0S=()
627         for RANK in `seq 1 ${RANKS}`; do
628                 for CHANNEL in `seq 1 ${CHANNELS}`; do
629                         DISK=`udev_cr2d ${CHANNEL} ${RANK}`
630                         RAID0S[${IDX}]="${DEVDIR}/${DISK}"
631                         let IDX=IDX+1
632                 done
633         done
634
635         return 0
636 }
637
638 udev_raid10_setup() {
639         local RANKS=$1
640         local CHANNELS=$2
641         local IDX=0
642
643         RAID10S=()
644         for RANK in `seq 1 ${RANKS}`; do
645                 for CHANNEL1 in `seq 1 2 ${CHANNELS}`; do
646                         let CHANNEL2=CHANNEL1+1
647                         DISK1=`udev_cr2d ${CHANNEL1} ${RANK}`
648                         DISK2=`udev_cr2d ${CHANNEL2} ${RANK}`
649                         GROUP="${DEVDIR}/${DISK1} ${DEVDIR}/${DISK2}"
650                         RAID10S[${IDX}]="mirror ${GROUP}"
651                         let IDX=IDX+1
652                 done
653         done
654
655         return 0
656 }
657
658 udev_raidz_setup() {
659         local RANKS=$1
660         local CHANNELS=$2
661
662         RAIDZS=()
663         for RANK in `seq 1 ${RANKS}`; do
664                 RAIDZ=("raidz")
665
666                 for CHANNEL in `seq 1 ${CHANNELS}`; do
667                         DISK=`udev_cr2d ${CHANNEL} ${RANK}`
668                         RAIDZ[${CHANNEL}]="${DEVDIR}/${DISK}"
669                 done
670
671                 RAIDZS[${RANK}]="${RAIDZ[*]}"
672         done
673
674         return 0
675 }
676
677 udev_raidz2_setup() {
678         local RANKS=$1
679         local CHANNELS=$2
680
681         RAIDZ2S=()
682         for RANK in `seq 1 ${RANKS}`; do
683                 RAIDZ2=("raidz2")
684
685                 for CHANNEL in `seq 1 ${CHANNELS}`; do
686                         DISK=`udev_cr2d ${CHANNEL} ${RANK}`
687                         RAIDZ2[${CHANNEL}]="${DEVDIR}/${DISK}"
688                 done
689
690                 RAIDZ2S[${RANK}]="${RAIDZ2[*]}"
691         done
692
693         return 0
694 }
695
696 run_one_test() {
697         local TEST_NUM=$1
698         local TEST_NAME=$2
699
700         printf "%-4d %-34s " ${TEST_NUM} "${TEST_NAME}"
701         test_${TEST_NUM}
702 }
703
704 skip_one_test() {
705         local TEST_NUM=$1
706         local TEST_NAME=$2
707
708         printf "%-4d %-34s " ${TEST_NUM} "${TEST_NAME}"
709         skip
710 }
711
712 run_test() {
713         local TEST_NUM=$1
714         local TEST_NAME=$2
715
716         for i in ${TESTS_SKIP[@]}; do
717                 if [[ $i == ${TEST_NUM} ]] ; then
718                         skip_one_test ${TEST_NUM} "${TEST_NAME}"
719                         return 0
720                 fi
721         done
722
723         if [ "${TESTS_RUN[0]}" = "*" ]; then
724                 run_one_test ${TEST_NUM} "${TEST_NAME}"
725         else
726                 for i in ${TESTS_RUN[@]}; do
727                         if [[ $i == ${TEST_NUM} ]] ; then
728                                 run_one_test ${TEST_NUM} "${TEST_NAME}"
729                                 return 0
730                         fi
731                 done
732
733                 skip_one_test ${TEST_NUM} "${TEST_NAME}"
734         fi
735 }
736
737 wait_udev() {
738         local DEVICE=$1
739         local DELAY=$2
740         local COUNT=0
741
742         udev_trigger
743         while [ ! -e ${DEVICE} ]; do
744                 if [ ${COUNT} -gt ${DELAY} ]; then
745                         return 1
746                 fi
747
748                 let COUNT=${COUNT}+1
749                 sleep 1
750         done
751
752         return 0
753 }
754
755 stack_clear() {
756         local STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
757         local STACK_TRACER_ENABLED=/proc/sys/kernel/stack_tracer_enabled
758
759         if [ -e $STACK_MAX_SIZE ]; then
760                 echo 1 >$STACK_TRACER_ENABLED
761                 echo 0 >$STACK_MAX_SIZE
762         fi
763 }
764
765 stack_check() {
766         local STACK_MAX_SIZE=/sys/kernel/debug/tracing/stack_max_size
767         local STACK_TRACE=/sys/kernel/debug/tracing/stack_trace
768         local STACK_LIMIT=7000
769
770         if [ -e $STACK_MAX_SIZE ]; then
771                 STACK_SIZE=`cat $STACK_MAX_SIZE`
772
773                 if [ $STACK_SIZE -ge $STACK_LIMIT ]; then
774                         echo
775                         echo "Warning: max stack size $STACK_SIZE bytes"
776                         cat $STACK_TRACE
777                 fi
778         fi
779 }
780
781 kill_zed() {
782         if [ -f $ZED_PIDFILE ]; then
783                 kill $(cat $ZED_PIDFILE)
784         fi
785 }