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.
8 basedir
="$(dirname $0)"
10 SCRIPT_CONFIG
=.script-config
11 if [ -f "${basedir}/../${SCRIPT_CONFIG}" ]; then
12 .
"${basedir}/../${SCRIPT_CONFIG}"
14 MODULES
=(zlib_deflate spl splat zavl znvpair zunicode zcommon zfs
)
31 exec_prefix
=@exec_prefix@
32 libexecdir
=@libexecdir@
33 pkglibexecdir
=${libexecdir}/@PACKAGE@
37 ETCDIR
=${ETCDIR:-/etc}
38 DEVDIR
=${DEVDIR:-/dev/disk/zpool}
39 ZPOOLDIR
=${ZPOOLDIR:-${pkglibexecdir}/zpool-config}
41 ZDB
=${ZDB:-${sbindir}/zdb}
42 ZFS
=${ZFS:-${sbindir}/zfs}
43 ZINJECT
=${ZINJECT:-${sbindir}/zinject}
44 ZPOOL
=${ZPOOL:-${sbindir}/zpool}
45 ZPOOL_ID
=${ZPOOL_ID:-${bindir}/zpool_id}
46 ZTEST
=${ZTEST:-${sbindir}/ztest}
48 COMMON_SH
=${COMMON_SH:-${pkglibexecdir}/common.sh}
49 ZFS_SH
=${ZFS_SH:-${pkglibexecdir}/zfs.sh}
50 ZPOOL_CREATE_SH
=${ZPOOL_CREATE_SH:-${pkglibexecdir}/zpool-create.sh}
52 LDMOD
=${LDMOD:-/sbin/modprobe}
53 LSMOD
=${LSMOD:-/sbin/lsmod}
54 RMMOD
=${RMMOD:-/sbin/rmmod}
55 INFOMOD
=${INFOMOD:-/sbin/modinfo}
56 LOSETUP
=${LOSETUP:-/sbin/losetup}
57 SYSCTL
=${SYSCTL:-/sbin/sysctl}
58 UDEVADM
=${UDEVADM:-/sbin/udevadm}
59 AWK
=${AWK:-/usr/bin/awk}
62 echo -e "${PROG}: $1" >&2
67 if [ ${VERBOSE} ]; then
82 ${SYSCTL} -w kernel.spl.debug.dump
=1 &>/dev
/null
83 local NAME
=`dmesg | tail -n 1 | cut -f5 -d' '`
84 ${SPLBUILD}/cmd/spl ${NAME} >${NAME}.log
86 echo "Dumped debug log: ${NAME}.log"
93 local LOADED_MODULES
=()
94 local MISSING_MODULES
=()
96 for MOD
in ${MODULES[*]}; do
97 local NAME
=`basename $MOD .ko`
99 if ${LSMOD} |
egrep -q "^${NAME}"; then
100 LOADED_MODULES
=(${NAME} ${LOADED_MODULES[*]})
103 if [ ${INFOMOD} ${MOD} 2>/dev
/null
]; then
104 MISSING_MODULES
=("\t${MOD}\n" ${MISSING_MODULES[*]})
108 if [ ${#LOADED_MODULES[*]} -gt 0 ]; then
109 ERROR
="Unload these modules with '${PROG} -u':\n"
110 ERROR
="${ERROR}${LOADED_MODULES[*]}"
114 if [ ${#MISSING_MODULES[*]} -gt 0 ]; then
115 ERROR
="The following modules can not be found,"
116 ERROR
="${ERROR} ensure your source trees are built:\n"
117 ERROR
="${ERROR}${MISSING_MODULES[*]}"
125 local NAME
=`basename $1 .ko`
127 if [ ${VERBOSE} ]; then
128 echo "Loading ${NAME} ($@)"
131 ${LDMOD} $
* || ERROR
="Failed to load $1" return 1
139 for MOD
in ${MODULES[*]}; do
140 local NAME
=`basename ${MOD} .ko`
144 OPT_NAME
=`echo ${OPT} | cut -f1 -d'='`
146 if [ ${NAME} = "${OPT_NAME}" ]; then
147 VALUE
=`echo ${OPT} | cut -f2- -d'='`
151 load_module
${MOD} ${VALUE} ||
return 1
154 if [ ${VERBOSE} ]; then
155 echo "Successfully loaded ZFS module stack"
162 local NAME
=`basename $1 .ko`
164 if [ ${VERBOSE} ]; then
165 echo "Unloading ${NAME} ($@)"
168 ${RMMOD} ${NAME} || ERROR="Failed to unload ${NAME}" return 1
174 local MODULES_REVERSE=( $(echo ${MODULES[@]} |
175 ${AWK} '{for (i=NF;i>=1;i--) printf $i" "} END{print ""}') )
177 for MOD in ${MODULES_REVERSE[*]}; do
178 local NAME=`basename ${MOD} .ko`
179 local USE_COUNT=`${LSMOD} |
180 egrep "^
${NAME} "| ${AWK} '{print $3}'`
182 if [ "${USE_COUNT}" = 0 ] ; then
184 if [ "${DUMP_LOG}" -a ${NAME} = "spl" ]; then
188 unload_module ${MOD} || return 1
192 if [ ${VERBOSE} ]; then
193 echo "Successfully unloaded ZFS module stack"
199 unused_loop_device() {
200 for DEVICE in `ls -1 /dev/loop*`; do
201 ${LOSETUP} ${DEVICE} &>/dev/null
202 if [ $? -ne 0 ]; then
208 die "Error: Unable to find unused loopback device"
212 # This can be slightly dangerous because the loop devices we are
213 # cleanup up may not be ours. However, if the devices are currently
214 # in use we will not be able to remove them, and we only remove
215 # devices which include 'zpool
' in the name. So any damage we might
216 # do should be limited to other zfs related testing.
218 cleanup_loop_devices() {
219 local TMP_FILE=`mktemp`
221 ${LOSETUP} -a | tr -d '()' >${TMP_FILE}
222 ${AWK} -F":" -v losetup="$LOSETUP" \
223 '/zpool
/ { system
("losetup -d "$1) }' ${TMP_FILE}
224 ${AWK} -F" " '/zpool
/ { system
("rm -f "$3) }' ${TMP_FILE}
230 # The following udev helper functions assume that the provided
231 # udev rules file will create a /dev/disk/zpool/<CHANNEL><RANK>
232 # disk mapping. In this mapping each CHANNEL is represented by
233 # the letters a-z, and the RANK is represented by the numbers
234 # 1-n. A CHANNEL should identify a group of RANKS which are all
235 # attached to a single controller, each RANK represents a disk.
236 # This provides a simply mechanism to locate a specific drive
237 # given a known hardware configuration.
242 # When running in tree manually contruct symlinks in tree to
243 # the proper devices. Symlinks are installed for all entires
244 # in the config file regardless of if that device actually
245 # exists. When installed as a package udev can be relied on for
246 # this and it will only create links for devices which exist.
247 if [ ${INTREE} ]; then
251 ${AWK} '!/^
#/ && /./ { system( \
252 "ln -f -s /dev/disk/by-path/"$2" "$1";" \
253 "ln -f -s /dev/disk/by-path/"$2"-part1 "$1"p1;" \
254 "ln -f -s /dev/disk/by-path/"$2"-part9 "$1"p9;" \
258 DST_FILE=`basename ${SRC_PATH} | cut -f1-2 -d'.
'`
259 DST_PATH=/etc/zfs/${DST_FILE}
261 if [ -e ${DST_PATH} ]; then
262 die "Error: Config ${DST_PATH} already exists"
265 cp ${SRC_PATH} ${DST_PATH}
267 if [ -f ${UDEVADM} ]; then
282 if [ ${INTREE} ]; then
285 ${AWK} '!/^
#/ && /./ { system( \
286 "rm -f "$1" "$1"p1 "$1"p9") }' $SRC_PATH
294 local CHANNEL=`echo "obase=16; $1+96" | bc`
297 printf "\x${CHANNEL}${RANK}"
306 for RANK in `seq 1 ${RANKS}`; do
307 for CHANNEL in `seq 1 ${CHANNELS}`; do
308 DISK=`udev_cr2d ${CHANNEL} ${RANK}`
309 RAID0S[${IDX}]="${DEVDIR}/${DISK}"
317 udev_raid10_setup() {
323 for RANK in `seq 1 ${RANKS}`; do
324 for CHANNEL1 in `seq 1 2 ${CHANNELS}`; do
325 let CHANNEL2=CHANNEL1+1
326 DISK1=`udev_cr2d ${CHANNEL1} ${RANK}`
327 DISK2=`udev_cr2d ${CHANNEL2} ${RANK}`
328 GROUP="${DEVDIR}/${DISK1} ${DEVDIR}/${DISK2}"
329 RAID10S[${IDX}]="mirror ${GROUP}"
342 for RANK in `seq 1 ${RANKS}`; do
345 for CHANNEL in `seq 1 ${CHANNELS}`; do
346 DISK=`udev_cr2d ${CHANNEL} ${RANK}`
347 RAIDZ[${CHANNEL}]="${DEVDIR}/${DISK}"
350 RAIDZS[${RANK}]="${RAIDZ[*]}"
356 udev_raidz2_setup() {
361 for RANK in `seq 1 ${RANKS}`; do
364 for CHANNEL in `seq 1 ${CHANNELS}`; do
365 DISK=`udev_cr2d ${CHANNEL} ${RANK}`
366 RAIDZ2[${CHANNEL}]="${DEVDIR}/${DISK}"
369 RAIDZ2S[${RANK}]="${RAIDZ2[*]}"