diff options
| author | Brian Behlendorf <behlendorf1@llnl.gov> | 2010-08-26 18:44:39 +0000 |
|---|---|---|
| committer | Brian Behlendorf <behlendorf1@llnl.gov> | 2010-08-31 20:41:50 +0000 |
| commit | 325f023544bbec6a478882c442e15304ee379759 (patch) | |
| tree | e41ddbab7f373fc7fd43390c4ba05ea722729e68 /scripts | |
| parent | 47d0ed1e6f8a8ee67492ec63173a27df8e4ca059 (diff) | |
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/common.sh | 443 | ||||
| -rw-r--r-- | scripts/common.sh.in | 69 | ||||
| -rwxr-xr-x | scripts/zconfig.sh | 50 |
3 files changed, 531 insertions, 31 deletions
diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100644 index 000000000000..66097570d76e --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,443 @@ +#!/bin/bash +# +# Common support functions for testing scripts. If a .script-config +# files is available it will be sourced so in-tree kernel modules and +# utilities will be used. If no .script-config can be found then the +# installed kernel modules and utilities will be used. + +basedir="$(dirname $0)" + +SCRIPT_CONFIG=.script-config +if [ -f "${basedir}/../${SCRIPT_CONFIG}" ]; then +. "${basedir}/../${SCRIPT_CONFIG}" +else +MODULES=(zlib_deflate spl splat zavl znvpair zunicode zcommon zfs) +fi + +PROG="<define PROG>" +CLEANUP= +VERBOSE= +VERBOSE_FLAG= +FORCE= +FORCE_FLAG= +DUMP_LOG= +ERROR= +RAID0S=() +RAID10S=() +RAIDZS=() +RAIDZ2S=() +TESTS_RUN=${TESTS_RUN:-'*'} +TESTS_SKIP=${TESTS_SKIP:-} + +prefix=/usr/local +exec_prefix=${prefix} +libexecdir=${exec_prefix}/libexec +pkglibexecdir=${libexecdir}/zfs +bindir=${exec_prefix}/bin +sbindir=${exec_prefix}/sbin + +ETCDIR=${ETCDIR:-/etc} +DEVDIR=${DEVDIR:-/dev/disk/zpool} +ZPOOLDIR=${ZPOOLDIR:-${pkglibexecdir}/zpool-config} +ZPIOSDIR=${ZPIOSDIR:-${pkglibexecdir}/zpios-test} +ZPIOSPROFILEDIR=${ZPIOSPROFILEDIR:-${pkglibexecdir}/zpios-profile} + +ZDB=${ZDB:-${sbindir}/zdb} +ZFS=${ZFS:-${sbindir}/zfs} +ZINJECT=${ZINJECT:-${sbindir}/zinject} +ZPOOL=${ZPOOL:-${sbindir}/zpool} +ZPOOL_ID=${ZPOOL_ID:-${bindir}/zpool_id} +ZTEST=${ZTEST:-${sbindir}/ztest} +ZPIOS=${ZPIOS:-${sbindir}/zpios} + +COMMON_SH=${COMMON_SH:-${pkglibexecdir}/common.sh} +ZFS_SH=${ZFS_SH:-${pkglibexecdir}/zfs.sh} +ZPOOL_CREATE_SH=${ZPOOL_CREATE_SH:-${pkglibexecdir}/zpool-create.sh} +ZPIOS_SH=${ZPIOS_SH:-${pkglibexecdir}/zpios.sh} +ZPIOS_SURVEY_SH=${ZPIOS_SURVEY_SH:-${pkglibexecdir}/zpios-survey.sh} + +LDMOD=${LDMOD:-/sbin/modprobe} +LSMOD=${LSMOD:-/sbin/lsmod} +RMMOD=${RMMOD:-/sbin/rmmod} +INFOMOD=${INFOMOD:-/sbin/modinfo} +LOSETUP=${LOSETUP:-/sbin/losetup} +SYSCTL=${SYSCTL:-/sbin/sysctl} +UDEVADM=${UDEVADM:-/sbin/udevadm} +AWK=${AWK:-/usr/bin/awk} + +COLOR_BLACK="\033[0;30m" +COLOR_DK_GRAY="\033[1;30m" +COLOR_BLUE="\033[0;34m" +COLOR_LT_BLUE="\033[1;34m" +COLOR_GREEN="\033[0;32m" +COLOR_LT_GREEN="\033[1;32m" +COLOR_CYAN="\033[0;36m" +COLOR_LT_CYAN="\033[1;36m" +COLOR_RED="\033[0;31m" +COLOR_LT_RED="\033[1;31m" +COLOR_PURPLE="\033[0;35m" +COLOR_LT_PURPLE="\033[1;35m" +COLOR_BROWN="\033[0;33m" +COLOR_YELLOW="\033[1;33m" +COLOR_LT_GRAY="\033[0;37m" +COLOR_WHITE="\033[1;37m" +COLOR_RESET="\033[0m" + +die() { + echo -e "${PROG}: $1" >&2 + exit 1 +} + +msg() { + if [ ${VERBOSE} ]; then + echo "$@" + fi +} + +pass() { + echo -e "${COLOR_GREEN}Pass${COLOR_RESET}" +} + +fail() { + echo -e "${COLOR_RED}Fail${COLOR_RESET} ($1)" + exit $1 +} + +skip() { + echo -e "${COLOR_BROWN}Skip${COLOR_RESET}" +} + +spl_dump_log() { + ${SYSCTL} -w kernel.spl.debug.dump=1 &>/dev/null + local NAME=`dmesg | tail -n 1 | cut -f5 -d' '` + ${SPLBUILD}/cmd/spl ${NAME} >${NAME}.log + echo + echo "Dumped debug log: ${NAME}.log" + tail -n1 ${NAME}.log + echo + return 0 +} + +check_modules() { + local LOADED_MODULES=() + local MISSING_MODULES=() + + for MOD in ${MODULES[*]}; do + local NAME=`basename $MOD .ko` + + if ${LSMOD} | egrep -q "^${NAME}"; then + LOADED_MODULES=(${NAME} ${LOADED_MODULES[*]}) + fi + + if [ ${INFOMOD} ${MOD} 2>/dev/null ]; then + MISSING_MODULES=("\t${MOD}\n" ${MISSING_MODULES[*]}) + fi + done + + if [ ${#LOADED_MODULES[*]} -gt 0 ]; then + ERROR="Unload these modules with '${PROG} -u':\n" + ERROR="${ERROR}${LOADED_MODULES[*]}" + return 1 + fi + + if [ ${#MISSING_MODULES[*]} -gt 0 ]; then + ERROR="The following modules can not be found," + ERROR="${ERROR} ensure your source trees are built:\n" + ERROR="${ERROR}${MISSING_MODULES[*]}" + return 1 + fi + + return 0 +} + +load_module() { + local NAME=`basename $1 .ko` + + if [ ${VERBOSE} ]; then + echo "Loading ${NAME} ($@)" + fi + + ${LDMOD} $* || ERROR="Failed to load $1" return 1 + + return 0 +} + +load_modules() { + mkdir -p /etc/zfs + + for MOD in ${MODULES[*]}; do + local NAME=`basename ${MOD} .ko` + local VALUE= + + for OPT in "$@"; do + OPT_NAME=`echo ${OPT} | cut -f1 -d'='` + + if [ ${NAME} = "${OPT_NAME}" ]; then + VALUE=`echo ${OPT} | cut -f2- -d'='` + fi + done + + load_module ${MOD} ${VALUE} || return 1 + done + + if [ ${VERBOSE} ]; then + echo "Successfully loaded ZFS module stack" + fi + + return 0 +} + +unload_module() { + local NAME=`basename $1 .ko` + + if [ ${VERBOSE} ]; then + echo "Unloading ${NAME} ($@)" + fi + + ${RMMOD} ${NAME} || ERROR="Failed to unload ${NAME}" return 1 + + return 0 +} + +unload_modules() { + local MODULES_REVERSE=( $(echo ${MODULES[@]} | + ${AWK} '{for (i=NF;i>=1;i--) printf $i" "} END{print ""}') ) + + for MOD in ${MODULES_REVERSE[*]}; do + local NAME=`basename ${MOD} .ko` + local USE_COUNT=`${LSMOD} | + egrep "^${NAME} "| ${AWK} '{print $3}'` + + if [ "${USE_COUNT}" = 0 ] ; then + + if [ "${DUMP_LOG}" -a ${NAME} = "spl" ]; then + spl_dump_log + fi + + unload_module ${MOD} || return 1 + fi + done + + if [ ${VERBOSE} ]; then + echo "Successfully unloaded ZFS module stack" + fi + + return 0 +} + +unused_loop_device() { + for DEVICE in `ls -1 /dev/loop*`; do + ${LOSETUP} ${DEVICE} &>/dev/null + if [ $? -ne 0 ]; then + echo ${DEVICE} + return + fi + done + + die "Error: Unable to find unused loopback device" +} + +# +# This can be slightly dangerous because the loop devices we are +# cleanup up may not be ours. However, if the devices are currently +# in use we will not be able to remove them, and we only remove +# devices which include 'zpool' in the name. So any damage we might +# do should be limited to other zfs related testing. +# +cleanup_loop_devices() { + local TMP_FILE=`mktemp` + + ${LOSETUP} -a | tr -d '()' >${TMP_FILE} + ${AWK} -F":" -v losetup="$LOSETUP" \ + '/zpool/ { system("losetup -d "$1) }' ${TMP_FILE} + ${AWK} -F" " '/zpool/ { system("rm -f "$3) }' ${TMP_FILE} + + rm -f ${TMP_FILE} +} + +# +# The following udev helper functions assume that the provided +# udev rules file will create a /dev/disk/zpool/<CHANNEL><RANK> +# disk mapping. In this mapping each CHANNEL is represented by +# the letters a-z, and the RANK is represented by the numbers +# 1-n. A CHANNEL should identify a group of RANKS which are all +# attached to a single controller, each RANK represents a disk. +# This provides a simply mechanism to locate a specific drive +# given a known hardware configuration. +# +udev_setup() { + local SRC_PATH=$1 + + # When running in tree manually contruct symlinks in tree to + # the proper devices. Symlinks are installed for all entires + # in the config file regardless of if that device actually + # exists. When installed as a package udev can be relied on for + # this and it will only create links for devices which exist. + if [ ${INTREE} ]; then + PWD=`pwd` + mkdir -p ${DEVDIR}/ + cd ${DEVDIR}/ + ${AWK} '!/^#/ && /./ { system( \ + "ln -f -s /dev/disk/by-path/"$2" "$1";" \ + "ln -f -s /dev/disk/by-path/"$2"-part1 "$1"p1;" \ + "ln -f -s /dev/disk/by-path/"$2"-part9 "$1"p9;" \ + ) }' $SRC_PATH + cd ${PWD} + else + DST_FILE=`basename ${SRC_PATH} | cut -f1-2 -d'.'` + DST_PATH=/etc/zfs/${DST_FILE} + + if [ -e ${DST_PATH} ]; then + die "Error: Config ${DST_PATH} already exists" + fi + + cp ${SRC_PATH} ${DST_PATH} + + if [ -f ${UDEVADM} ]; then + ${UDEVADM} trigger + ${UDEVADM} settle + else + /sbin/udevtrigger + /sbin/udevsettle + fi + fi + + return 0 +} + +udev_cleanup() { + local SRC_PATH=$1 + + if [ ${INTREE} ]; then + PWD=`pwd` + cd ${DEVDIR}/ + ${AWK} '!/^#/ && /./ { system( \ + "rm -f "$1" "$1"p1 "$1"p9") }' $SRC_PATH + cd ${PWD} + fi + + return 0 +} + +udev_cr2d() { + local CHANNEL=`echo "obase=16; $1+96" | bc` + local RANK=$2 + + printf "\x${CHANNEL}${RANK}" +} + +udev_raid0_setup() { + local RANKS=$1 + local CHANNELS=$2 + local IDX=0 + + RAID0S=() + for RANK in `seq 1 ${RANKS}`; do + for CHANNEL in `seq 1 ${CHANNELS}`; do + DISK=`udev_cr2d ${CHANNEL} ${RANK}` + RAID0S[${IDX}]="${DEVDIR}/${DISK}" + let IDX=IDX+1 + done + done + + return 0 +} + +udev_raid10_setup() { + local RANKS=$1 + local CHANNELS=$2 + local IDX=0 + + RAID10S=() + for RANK in `seq 1 ${RANKS}`; do + for CHANNEL1 in `seq 1 2 ${CHANNELS}`; do + let CHANNEL2=CHANNEL1+1 + DISK1=`udev_cr2d ${CHANNEL1} ${RANK}` + DISK2=`udev_cr2d ${CHANNEL2} ${RANK}` + GROUP="${DEVDIR}/${DISK1} ${DEVDIR}/${DISK2}" + RAID10S[${IDX}]="mirror ${GROUP}" + let IDX=IDX+1 + done + done + + return 0 +} + +udev_raidz_setup() { + local RANKS=$1 + local CHANNELS=$2 + + RAIDZS=() + for RANK in `seq 1 ${RANKS}`; do + RAIDZ=("raidz") + + for CHANNEL in `seq 1 ${CHANNELS}`; do + DISK=`udev_cr2d ${CHANNEL} ${RANK}` + RAIDZ[${CHANNEL}]="${DEVDIR}/${DISK}" + done + + RAIDZS[${RANK}]="${RAIDZ[*]}" + done + + return 0 +} + +udev_raidz2_setup() { + local RANKS=$1 + local CHANNELS=$2 + + RAIDZ2S=() + for RANK in `seq 1 ${RANKS}`; do + RAIDZ2=("raidz2") + + for CHANNEL in `seq 1 ${CHANNELS}`; do + DISK=`udev_cr2d ${CHANNEL} ${RANK}` + RAIDZ2[${CHANNEL}]="${DEVDIR}/${DISK}" + done + + RAIDZ2S[${RANK}]="${RAIDZ2[*]}" + done + + return 0 +} + +run_one_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + printf "%-4d %-36s " ${TEST_NUM} "${TEST_NAME}" + test_${TEST_NUM} +} + +skip_one_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + printf "%-4d %-36s " ${TEST_NUM} "${TEST_NAME}" + skip +} + +run_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + for i in ${TESTS_SKIP[@]}; do + if [[ $i == ${TEST_NUM} ]] ; then + skip_one_test ${TEST_NUM} "${TEST_NAME}" + return 0 + fi + done + + if [ "${TESTS_RUN[0]}" = "*" ]; then + run_one_test ${TEST_NUM} "${TEST_NAME}" + else + for i in ${TESTS_RUN[@]}; do + if [[ $i == ${TEST_NUM} ]] ; then + run_one_test ${TEST_NUM} "${TEST_NAME}" + return 0 + fi + done + + skip_one_test ${TEST_NUM} "${TEST_NAME}" + fi +} diff --git a/scripts/common.sh.in b/scripts/common.sh.in index 00418696c8e4..0a8399f18412 100644 --- a/scripts/common.sh.in +++ b/scripts/common.sh.in @@ -26,6 +26,8 @@ RAID0S=() RAID10S=() RAIDZS=() RAIDZ2S=() +TESTS_RUN=${TESTS_RUN:-'*'} +TESTS_SKIP=${TESTS_SKIP:-} prefix=@prefix@ exec_prefix=@exec_prefix@ @@ -58,6 +60,24 @@ SYSCTL=${SYSCTL:-/sbin/sysctl} UDEVADM=${UDEVADM:-/sbin/udevadm} AWK=${AWK:-/usr/bin/awk} +COLOR_BLACK="\033[0;30m" +COLOR_DK_GRAY="\033[1;30m" +COLOR_BLUE="\033[0;34m" +COLOR_LT_BLUE="\033[1;34m" +COLOR_GREEN="\033[0;32m" +COLOR_LT_GREEN="\033[1;32m" +COLOR_CYAN="\033[0;36m" +COLOR_LT_CYAN="\033[1;36m" +COLOR_RED="\033[0;31m" +COLOR_LT_RED="\033[1;31m" +COLOR_PURPLE="\033[0;35m" +COLOR_LT_PURPLE="\033[1;35m" +COLOR_BROWN="\033[0;33m" +COLOR_YELLOW="\033[1;33m" +COLOR_LT_GRAY="\033[0;37m" +COLOR_WHITE="\033[1;37m" +COLOR_RESET="\033[0m" + die() { echo -e "${PROG}: $1" >&2 exit 1 @@ -70,14 +90,18 @@ msg() { } pass() { - echo "PASS" + echo -e "${COLOR_GREEN}Pass${COLOR_RESET}" } fail() { - echo "FAIL ($1)" + echo -e "${COLOR_RED}Fail${COLOR_RESET} ($1)" exit $1 } +skip() { + echo -e "${COLOR_BROWN}Skip${COLOR_RESET}" +} + spl_dump_log() { ${SYSCTL} -w kernel.spl.debug.dump=1 &>/dev/null local NAME=`dmesg | tail -n 1 | cut -f5 -d' '` @@ -371,3 +395,44 @@ udev_raidz2_setup() { return 0 } + +run_one_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + printf "%-4d %-36s " ${TEST_NUM} "${TEST_NAME}" + test_${TEST_NUM} +} + +skip_one_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + printf "%-4d %-36s " ${TEST_NUM} "${TEST_NAME}" + skip +} + +run_test() { + local TEST_NUM=$1 + local TEST_NAME=$2 + + for i in ${TESTS_SKIP[@]}; do + if [[ $i == ${TEST_NUM} ]] ; then + skip_one_test ${TEST_NUM} "${TEST_NAME}" + return 0 + fi + done + + if [ "${TESTS_RUN[0]}" = "*" ]; then + run_one_test ${TEST_NUM} "${TEST_NAME}" + else + for i in ${TESTS_RUN[@]}; do + if [[ $i == ${TEST_NUM} ]] ; then + run_one_test ${TEST_NUM} "${TEST_NAME}" + return 0 + fi + done + + skip_one_test ${TEST_NUM} "${TEST_NAME}" + fi +} diff --git a/scripts/zconfig.sh b/scripts/zconfig.sh index 98f00fa0edae..c2e5d9754007 100755 --- a/scripts/zconfig.sh +++ b/scripts/zconfig.sh @@ -29,7 +29,7 @@ OPTIONS: EOF } -while getopts 'hvc?' OPTION; do +while getopts 'hvct:s:?' OPTION; do case $OPTION in h) usage @@ -41,6 +41,12 @@ while getopts 'hvc?' OPTION; do c) CLEANUP=1 ;; + t) + TESTS_RUN=($OPTARG) + ;; + s) + TESTS_SKIP=($OPTARG) + ;; ?) usage exit @@ -75,14 +81,12 @@ EOF } # Validate persistent zpool.cache configuration. -zconfig_test1() { +test_1() { local POOL_NAME=test1 local TMP_FILE1=`mktemp` local TMP_FILE2=`mktemp` local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 1 - persistent zpool.cache: " - # Create a pool save its status for comparison. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -101,17 +105,15 @@ zconfig_test1() { pass } -zconfig_test1 +run_test 1 "persistent zpool.cache" # Validate ZFS disk scanning and import w/out zpool.cache configuration. -zconfig_test2() { +test_2() { local POOL_NAME=test2 local TMP_FILE1=`mktemp` local TMP_FILE2=`mktemp` local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 2 - scan disks for pools to import: " - # Create a pool save its status for comparison. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -135,7 +137,7 @@ zconfig_test2() { pass } -zconfig_test2 +run_test 2 "scan disks for pools to import" zconfig_zvol_device_stat() { local EXPECT=$1 @@ -175,7 +177,7 @@ zconfig_zvol_device_stat() { # zpool import/export device check # (1 volume, 2 partitions, 1 snapshot, 1 clone) -zconfig_test3() { +test_3() { local POOL_NAME=tank local ZVOL_NAME=volume local SNAP_NAME=snap @@ -185,8 +187,6 @@ zconfig_test3() { local FULL_CLONE_NAME=${POOL_NAME}/${CLONE_NAME} local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 3 - zpool import/export device: " - # Create a pool, volume, partition, snapshot, and clone. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -225,10 +225,10 @@ zconfig_test3() { pass } -zconfig_test3 +run_test 3 "zpool import/export device" # zpool insmod/rmmod device check (1 volume, 1 snapshot, 1 clone) -zconfig_test4() { +test_4() { POOL_NAME=tank ZVOL_NAME=volume SNAP_NAME=snap @@ -238,8 +238,6 @@ zconfig_test4() { FULL_CLONE_NAME=${POOL_NAME}/${CLONE_NAME} TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 4 - zpool insmod/rmmod device: " - # Create a pool, volume, snapshot, and clone ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -278,18 +276,16 @@ zconfig_test4() { pass } -zconfig_test4 +run_test 4 "zpool insmod/rmmod device" # ZVOL volume sanity check -zconfig_test5() { +test_5() { local POOL_NAME=tank local ZVOL_NAME=fish local FULL_NAME=${POOL_NAME}/${ZVOL_NAME} local SRC_DIR=/bin/ local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 5 - zvol+ext3 volume: " - # Create a pool and volume. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -323,10 +319,10 @@ zconfig_test5() { pass } -zconfig_test5 +run_test 5 "zvol+ext3 volume" # ZVOL snapshot sanity check -zconfig_test6() { +test_6() { local POOL_NAME=tank local ZVOL_NAME=fish local SNAP_NAME=pristine @@ -335,8 +331,6 @@ zconfig_test6() { local SRC_DIR=/bin/ local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 6 - zvol+ext2 snapshot: " - # Create a pool and volume. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -382,10 +376,10 @@ zconfig_test6() { pass } -zconfig_test6 +run_test 6 "zvol+ext2 snapshot" # ZVOL clone sanity check -zconfig_test7() { +test_7() { local POOL_NAME=tank local ZVOL_NAME=fish local SNAP_NAME=pristine @@ -396,8 +390,6 @@ zconfig_test7() { local SRC_DIR=/bin/ local TMP_CACHE=`mktemp -p /tmp zpool.cache.XXXXXXXX` - echo -n "test 7 - zvol+ext2 clone: " - # Create a pool and volume. ${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1 ${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2 @@ -464,7 +456,7 @@ zconfig_test7() { pass } -zconfig_test7 +run_test 7 "zvol+ext2 clone" # Send/Receive sanity check test_8() { |
