diff --git a/Makefile.am b/Makefile.am index e009212f45..2cd2aabc5a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,11 +47,14 @@ cstyle: shellcheck: @if type shellcheck > /dev/null 2>&1; then \ - (find ${top_srcdir} -type f -name '*.sh.in' -o -type f \ - -name '*.sh'; find etc/init.d/zfs*.in -type f) | \ + shellcheck --exclude=SC1090 --format gcc scripts/paxcheck.sh \ + scripts/zloop.sh \ + scripts/zfs-tests.sh \ + scripts/zfs.sh; \ + (find cmd/zed/zed.d/*.sh -type f) | \ grep -v 'zfs-script-config' | \ while read file; do \ - shellcheck --format gcc "$$file"; \ + shellcheck --exclude=SC1090 --format gcc "$$file"; \ done; \ fi diff --git a/cmd/zed/zed.d/statechange-led.sh b/cmd/zed/zed.d/statechange-led.sh index 7a8c1fde97..c1a1bd92d5 100755 --- a/cmd/zed/zed.d/statechange-led.sh +++ b/cmd/zed/zed.d/statechange-led.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # # Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes. # @@ -24,6 +24,7 @@ # 2: enclosure leds administratively disabled # 3: The led sysfs path passed from ZFS does not exist # 4: $ZPOOL not set +# 5: awk is not installed [ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc" . "${ZED_ZEDLET_DIR}/zed-functions.sh" @@ -37,6 +38,7 @@ if [ "${ZED_USE_ENCLOSURE_LEDS}" != "1" ] ; then fi zed_check_cmd "$ZPOOL" || exit 4 +zed_check_cmd awk || exit 5 # Global used in set_led debug print vdev="" @@ -52,7 +54,7 @@ vdev="" # Return # 0 on success, 3 on missing sysfs path # -function check_and_set_led +check_and_set_led() { file="$1" val="$2" @@ -86,12 +88,13 @@ function check_and_set_led done } -function state_to_val { +state_to_val() +{ state="$1" - if [ "$state" == "FAULTED" ] || [ "$state" == "DEGRADED" ] || \ - [ "$state" == "UNAVAIL" ] ; then + if [ "$state" = "FAULTED" ] || [ "$state" = "DEGRADED" ] || \ + [ "$state" = "UNAVAIL" ] ; then echo 1 - elif [ "$state" == "ONLINE" ] ; then + elif [ "$state" = "ONLINE" ] ; then echo 0 fi } @@ -107,19 +110,26 @@ function state_to_val { # Return # 0 on success, 3 on missing sysfs path # -function process_pool +process_pool() { pool="$1" rc=0 # Lookup all the current LED values and paths in parallel + #shellcheck disable=SC2016 cmd='echo led_token=$(cat "$VDEV_ENC_SYSFS_PATH/fault"),"$VDEV_ENC_SYSFS_PATH",' out=$($ZPOOL status -vc "$cmd" "$pool" | grep 'led_token=') - while read -r vdev state read write chksum therest ; do + #shellcheck disable=SC2034 + echo "$out" | while read -r vdev state read write chksum therest; do # Read out current LED value and path tmp=$(echo "$therest" | sed 's/^.*led_token=//g') - IFS="," read -r current_val vdev_enc_sysfs_path <<< "$tmp" + vdev_enc_sysfs_path=$(echo "$tmp" | awk -F ',' '{print $2}') + current_val=$(echo "$tmp" | awk -F ',' '{print $1}') + + if [ "$current_val" != "0" ] ; then + current_val=1 + fi if [ -z "$vdev_enc_sysfs_path" ] ; then # Skip anything with no sysfs LED entries @@ -127,6 +137,7 @@ function process_pool fi if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then + #shellcheck disable=SC2030 rc=1 zed_log_msg "vdev $vdev '$file/fault' doesn't exist" continue; @@ -134,17 +145,19 @@ function process_pool val=$(state_to_val "$state") - if [ "$current_val" == "$val" ] ; then + if [ "$current_val" = "$val" ] ; then # LED is already set correctly continue; fi - check_and_set_led "$vdev_enc_sysfs_path/fault" "$val" - (( rc |= $? )) + if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then + rc=1 + fi - done <<< "$out" + done - if [ "$rc" == "0" ] ; then + #shellcheck disable=SC2031 + if [ "$rc" = "0" ] ; then return 0 else # We didn't see a sysfs entry that we wanted to set @@ -155,9 +168,10 @@ function process_pool if [ ! -z "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ ! -z "$ZEVENT_VDEV_STATE_STR" ] ; then # Got a statechange for an individual VDEV val=$(state_to_val "$ZEVENT_VDEV_STATE_STR") - vdev="$(basename $ZEVENT_VDEV_PATH)" + vdev=$(basename "$ZEVENT_VDEV_PATH") check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val" else # Process the entire pool - process_pool "$(zed_guid_to_pool $ZEVENT_POOL_GUID)" + poolname=$(zed_guid_to_pool "$ZEVENT_POOL_GUID") + process_pool "$poolname" fi diff --git a/cmd/zed/zed.d/statechange-notify.sh b/cmd/zed/zed.d/statechange-notify.sh index eba4ef9d8f..f46080a032 100755 --- a/cmd/zed/zed.d/statechange-notify.sh +++ b/cmd/zed/zed.d/statechange-notify.sh @@ -39,10 +39,10 @@ umask 077 note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)" note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" { - if [ "${ZEVENT_VDEV_STATE_STR}" == "FAULTED" ] ; then + if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then echo "The number of I/O errors associated with a ZFS device exceeded" echo "acceptable levels. ZFS has marked the device as faulted." - elif [ "${ZEVENT_VDEV_STATE_STR}" == "DEGRADED" ] ; then + elif [ "${ZEVENT_VDEV_STATE_STR}" = "DEGRADED" ] ; then echo "The number of checksum errors associated with a ZFS device" echo "exceeded acceptable levels. ZFS has marked the device as" echo "degraded." diff --git a/cmd/zed/zed.d/zed-functions.sh b/cmd/zed/zed.d/zed-functions.sh index d234fb48a0..b7de5104f0 100644 --- a/cmd/zed/zed.d/zed-functions.sh +++ b/cmd/zed/zed.d/zed-functions.sh @@ -1,3 +1,5 @@ +#!/bin/sh +# shellcheck disable=SC2039 # zed-functions.sh # # ZED helper functions for use in ZEDLETs @@ -126,6 +128,7 @@ zed_lock() # eval "exec ${fd}> '${lockfile}'" err="$(flock --exclusive "${fd}" 2>&1)" + # shellcheck disable=SC2181 if [ $? -ne 0 ]; then zed_log_err "failed to lock \"${lockfile}\": ${err}" fi @@ -162,8 +165,8 @@ zed_unlock() fi # Release the lock and close the file descriptor. - # err="$(flock --unlock "${fd}" 2>&1)" + # shellcheck disable=SC2181 if [ $? -ne 0 ]; then zed_log_err "failed to unlock \"${lockfile}\": ${err}" fi @@ -424,14 +427,14 @@ zed_rate_limit() # Return # Pool name # -function zed_guid_to_pool +zed_guid_to_pool() { if [ -z "$1" ] ; then return fi - guid=$(printf "%llu" $1) + guid=$(printf "%llu" "$1") if [ ! -z "$guid" ] ; then - $ZPOOL get -H -ovalue,name guid | awk '$1=='$guid' {print $2}' + $ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}' fi } diff --git a/scripts/common.sh.in b/scripts/common.sh.in index 38fc6985ad..e1a9b82d29 100644 --- a/scripts/common.sh.in +++ b/scripts/common.sh.in @@ -21,7 +21,6 @@ VERBOSE= VERBOSE_FLAG= FORCE= FORCE_FLAG= -DUMP_LOG= ERROR= RAID0S=() RAID10S=() @@ -155,17 +154,6 @@ init() { populate $SRC_DIR 10 100 } -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=() @@ -265,11 +253,6 @@ unload_modules() { 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 diff --git a/scripts/paxcheck.sh b/scripts/paxcheck.sh index 1d85f9d01e..87e817500b 100755 --- a/scripts/paxcheck.sh +++ b/scripts/paxcheck.sh @@ -1,5 +1,6 @@ #!/bin/sh +# shellcheck disable=SC2039 if ! type scanelf > /dev/null 2>&1; then echo "scanelf (from pax-utils) is required for these checks." >&2 exit 3 @@ -8,7 +9,7 @@ fi RET=0 # check for exec stacks -OUT="$(scanelf -qyRAF '%e %p' $1)" +OUT=$(scanelf -qyRAF '%e %p' "$1") if [ x"${OUT}" != x ]; then RET=2 @@ -24,7 +25,7 @@ fi # check for TEXTRELS -OUT="$(scanelf -qyRAF '%T %p' $1)" +OUT=$(scanelf -qyRAF '%T %p' "$1") if [ x"${OUT}" != x ]; then RET=2 diff --git a/scripts/zfs-tests.sh b/scripts/zfs-tests.sh index f06d6a1ab8..72876a65b2 100755 --- a/scripts/zfs-tests.sh +++ b/scripts/zfs-tests.sh @@ -20,7 +20,7 @@ # # CDDL HEADER END # -basedir="$(dirname $0)" +basedir=$(dirname "$0") SCRIPT_COMMON=common.sh if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then @@ -29,7 +29,7 @@ else echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 fi -. $STF_SUITE/include/default.cfg +. "$STF_SUITE/include/default.cfg" PROG=zfs-tests.sh SUDO=/usr/bin/sudo @@ -58,24 +58,24 @@ cleanup() { if [ $LOOPBACK -eq 1 ]; then for TEST_LOOPBACK in ${LOOPBACKS}; do - LOOP_DEV=$(basename $TEST_LOOPBACK) - DM_DEV=$(${SUDO} ${DMSETUP} ls 2>/dev/null | \ - grep ${LOOP_DEV} | cut -f1) + LOOP_DEV=$(basename "$TEST_LOOPBACK") + DM_DEV=$(${SUDO} "${DMSETUP}" ls 2>/dev/null | \ + grep "${LOOP_DEV}" | cut -f1) if [ -n "$DM_DEV" ]; then - ${SUDO} ${DMSETUP} remove ${DM_DEV} || + ${SUDO} "${DMSETUP}" remove "${DM_DEV}" || echo "Failed to remove: ${DM_DEV}" fi if [ -n "${TEST_LOOPBACK}" ]; then - ${SUDO} ${LOSETUP} -d ${TEST_LOOPBACK} || + ${SUDO} "${LOSETUP}" -d "${TEST_LOOPBACK}" || echo "Failed to remove: ${TEST_LOOPBACK}" fi done fi for TEST_FILE in ${FILES}; do - rm -f ${TEST_FILE} &>/dev/null + rm -f "${TEST_FILE}" &>/dev/null done } trap cleanup EXIT @@ -87,29 +87,32 @@ trap cleanup EXIT # be dangerous and should only be used in a dedicated test environment. # cleanup_all() { - local TEST_POOLS=$(${SUDO} ${ZPOOL} list -H -o name | grep testpool) - local TEST_LOOPBACKS=$(${SUDO} ${LOSETUP} -a|grep file-vdev|cut -f1 -d:) - local TEST_FILES=$(ls /var/tmp/file-vdev* 2>/dev/null) + local TEST_POOLS + TEST_POOLS=$(${SUDO} "${ZPOOL}" list -H -o name | grep testpool) + local TEST_LOOPBACKS + TEST_LOOPBACKS=$(${SUDO} "${LOSETUP}" -a|grep file-vdev|cut -f1 -d:) + local TEST_FILES + TEST_FILES=$(ls /var/tmp/file-vdev* 2>/dev/null) msg msg "--- Cleanup ---" - msg "Removing pool(s): $(echo ${TEST_POOLS} | tr '\n' ' ')" + msg "Removing pool(s): $(echo "${TEST_POOLS}" | tr '\n' ' ')" for TEST_POOL in $TEST_POOLS; do - ${SUDO} ${ZPOOL} destroy ${TEST_POOL} + ${SUDO} "${ZPOOL}" destroy "${TEST_POOL}" done - msg "Removing dm(s): $(${SUDO} ${DMSETUP} ls | + msg "Removing dm(s): $(${SUDO} "${DMSETUP}" ls | grep loop | tr '\n' ' ')" - ${SUDO} ${DMSETUP} remove_all + ${SUDO} "${DMSETUP}" remove_all - msg "Removing loopback(s): $(echo ${TEST_LOOPBACKS} | tr '\n' ' ')" + msg "Removing loopback(s): $(echo "${TEST_LOOPBACKS}" | tr '\n' ' ')" for TEST_LOOPBACK in $TEST_LOOPBACKS; do - ${SUDO} ${LOSETUP} -d ${TEST_LOOPBACK} + ${SUDO} "${LOSETUP}" -d "${TEST_LOOPBACK}" done - msg "Removing files(s): $(echo ${TEST_FILES} | tr '\n' ' ')" + msg "Removing files(s): $(echo "${TEST_FILES}" | tr '\n' ' ')" for TEST_FILE in $TEST_FILES; do - ${SUDO} rm -f ${TEST_FILE} + ${SUDO} rm -f "${TEST_FILE}" done } @@ -193,6 +196,7 @@ while getopts 'hvqxkfd:s:r:?t:u:' OPTION; do exit 1 ;; v) + # shellcheck disable=SC2034 VERBOSE=1 ;; q) @@ -300,11 +304,11 @@ fi # be a normal user account, needs to be configured such that it can # run commands via sudo passwordlessly. # -if [ $(id -u) = "0" ]; then +if [ "$(id -u)" = "0" ]; then fail "This script must not be run as root." fi -if [ $(sudo whoami) != "root" ]; then +if [ "$(sudo whoami)" != "root" ]; then fail "Passwordless sudo access required." fi @@ -318,7 +322,7 @@ fi # # Verify the ZFS module stack if loaded. # -${SUDO} ${ZFS_SH} &>/dev/null +${SUDO} "${ZFS_SH}" &>/dev/null # # Attempt to cleanup all previous state for a new test run. @@ -331,7 +335,7 @@ fi # By default preserve any existing pools # if [ -z "${KEEP}" ]; then - KEEP=$(${SUDO} ${ZPOOL} list -H -o name) + KEEP=$(${SUDO} "${ZPOOL}" list -H -o name) if [ -z "${KEEP}" ]; then KEEP="rpool" fi @@ -356,7 +360,7 @@ if [ -z "${DISKS}" ]; then # for TEST_FILE in ${FILES}; do [ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}" - truncate -s ${FILESIZE} ${TEST_FILE} || + truncate -s "${FILESIZE}" "${TEST_FILE}" || fail "Failed creating: ${TEST_FILE} ($?)" DISKS="$DISKS$TEST_FILE " done @@ -369,17 +373,18 @@ if [ -z "${DISKS}" ]; then check_loop_utils for TEST_FILE in ${FILES}; do - TEST_LOOPBACK=$(${SUDO} ${LOSETUP} -f) - ${SUDO} ${LOSETUP} ${TEST_LOOPBACK} ${TEST_FILE} || + TEST_LOOPBACK=$(${SUDO} "${LOSETUP}" -f) + ${SUDO} "${LOSETUP}" "${TEST_LOOPBACK}" "${TEST_FILE}" || fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}" LOOPBACKS="${LOOPBACKS}${TEST_LOOPBACK} " - DISKS="$DISKS$(basename $TEST_LOOPBACK) " + BASELOOPBACKS=$(basename "$TEST_LOOPBACK") + DISKS="$DISKS$BASELOOPBACKS " done fi fi -NUM_DISKS=$(echo ${DISKS} | $AWK '{print NF}') -[ $NUM_DISKS -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" +NUM_DISKS=$(echo "${DISKS}" | $AWK '{print NF}') +[ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" # # Disable SELinux until the ZFS Test Suite has been updated accordingly. @@ -404,7 +409,7 @@ export KEEP export __ZFS_POOL_EXCLUDE msg "${TEST_RUNNER} ${QUIET} -c ${RUNFILE} -i ${STF_SUITE}" -${TEST_RUNNER} ${QUIET} -c ${RUNFILE} -i ${STF_SUITE} +${TEST_RUNNER} ${QUIET} -c "${RUNFILE}" -i "${STF_SUITE}" RESULT=$? echo diff --git a/scripts/zfs.sh b/scripts/zfs.sh index 55584ddd1f..2ffcf40da5 100755 --- a/scripts/zfs.sh +++ b/scripts/zfs.sh @@ -2,7 +2,7 @@ # # A simple script to simply the loading/unloading the ZFS module stack. -basedir="$(dirname $0)" +basedir=$(dirname "$0") SCRIPT_COMMON=common.sh if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then @@ -11,6 +11,7 @@ else echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 fi +# shellcheck disable=SC2034 PROG=zfs.sh UNLOAD= @@ -26,7 +27,6 @@ OPTIONS: -h Show this message -v Verbose -u Unload modules - -d Save debug log on unload MODULE-OPTIONS: Must be of the from module="options", for example: @@ -37,21 +37,19 @@ $0 zfs="zfs_prefetch_disable=1 zfs_mdcomp_disable=1" EOF } -while getopts 'hvud' OPTION; do +while getopts 'hvu' OPTION; do case $OPTION in h) usage exit 1 ;; v) + # shellcheck disable=SC2034 VERBOSE=1 ;; u) UNLOAD=1 ;; - d) - DUMP_LOG=1 - ;; ?) usage exit @@ -59,7 +57,7 @@ while getopts 'hvud' OPTION; do esac done -if [ $(id -u) != 0 ]; then +if [ "$(id -u)" != 0 ]; then die "Must run as root" fi diff --git a/scripts/zloop.sh b/scripts/zloop.sh index 580fcfe40a..3a6db40cf0 100755 --- a/scripts/zloop.sh +++ b/scripts/zloop.sh @@ -20,7 +20,7 @@ # Copyright (C) 2016 Lawrence Livermore National Security, LLC. # -basedir="$(dirname $0)" +basedir=$(dirname "$0") SCRIPT_COMMON=common.sh if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then @@ -29,6 +29,7 @@ else echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 fi +# shellcheck disable=SC2034 PROG=zloop.sh DEFAULTWORKDIR=/var/tmp @@ -56,8 +57,11 @@ function usage function or_die { + # shellcheck disable=SC2068 $@ + # shellcheck disable=SC2181 if [[ $? -ne 0 ]]; then + # shellcheck disable=SC2145 echo "Command failed: $@" exit 1 fi @@ -76,14 +80,16 @@ fi function core_file { + # shellcheck disable=SC2012 disable=2086 printf "%s" "$(ls -tr1 $coreglob 2> /dev/null | head -1)" } function core_prog { prog=$ZTEST - core_id=$($GDB --batch -c $1 | grep "Core was generated by" | \ + core_id=$($GDB --batch -c "$1" | grep "Core was generated by" | \ tr \' ' ') + # shellcheck disable=SC2076 if [[ "$core_id" =~ "zdb " ]]; then prog=$ZDB fi @@ -95,23 +101,23 @@ function store_core core="$(core_file)" if [[ $ztrc -ne 0 ]] || [[ -f "$core" ]]; then coreid=$(date "+zloop-%y%m%d-%H%M%S") - foundcrashes=$(($foundcrashes + 1)) + foundcrashes=$((foundcrashes + 1)) dest=$coredir/$coreid - or_die mkdir -p $dest - or_die mkdir -p $dest/vdev + or_die mkdir -p "$dest" + or_die mkdir -p "$dest/vdev" echo "*** ztest crash found - moving logs to $dest" - or_die mv ztest.history $dest/ - or_die mv ztest.ddt $dest/ - or_die mv ztest.out $dest/ - or_die mv $workdir/ztest* $dest/vdev/ - or_die mv $workdir/zpool.cache $dest/vdev/ + or_die mv ztest.history "$dest/" + or_die mv ztest.ddt "$dest/" + or_die mv ztest.out "$dest/" + or_die mv "$workdir/ztest*" "$dest/vdev/" + or_die mv "$workdir/zpool.cache" "$dest/vdev/" # check for core if [[ -f "$core" ]]; then - coreprog=$(core_prog $core) + coreprog=$(core_prog "$core") corestatus=$($GDB --batch --quiet \ -ex "set print thread-events off" \ -ex "printf \"*\n* Backtrace \n*\n\"" \ @@ -124,11 +130,11 @@ function store_core -ex "thread apply all bt" \ -ex "printf \"*\n* Backtraces (full) \n*\n\"" \ -ex "thread apply all bt full" \ - -ex "quit" $coreprog "$core" | grep -v "New LWP") + -ex "quit" "$coreprog" "$core" | grep -v "New LWP") # Dump core + logs to stored directory - echo "$corestatus" >>$dest/status - or_die mv "$core" $dest/ + echo "$corestatus" >>"$dest/status" + or_die mv "$core" "$dest/" # Record info in cores logfile echo "*** core @ $coredir/$coreid/$core:" | \ @@ -149,7 +155,7 @@ while getopts ":ht:c:f:" opt; do case $opt in t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;; c ) [[ $OPTARG ]] && coredir=$OPTARG ;; - f ) [[ $OPTARG ]] && workdir=$(readlink -f $OPTARG) ;; + f ) [[ $OPTARG ]] && workdir=$(readlink -f "$OPTARG") ;; h ) usage exit 2 ;; @@ -166,13 +172,13 @@ ulimit -c unlimited if [[ -f "$(core_file)" ]]; then echo -n "There's a core dump here you might want to look at first... " - echo "$(core_file)" + core_file exit 1 fi if [[ ! -d $coredir ]]; then echo "core dump directory ($coredir) does not exist, creating it." - or_die mkdir -p $coredir + or_die mkdir -p "$coredir" fi if [[ ! -w $coredir ]]; then @@ -190,7 +196,7 @@ starttime=$(date +%s) curtime=$starttime # if no timeout was specified, loop forever. -while [[ $timeout -eq 0 ]] || [[ $curtime -le $(($starttime + $timeout)) ]]; do +while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do zopt="-VVVVV" # switch between common arrangements & fully randomized @@ -220,6 +226,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $(($starttime + $timeout)) ]]; do zopt="$zopt -s $size" zopt="$zopt -f $workdir" + # shellcheck disable=SC2124 cmd="$ZTEST $zopt $@" desc="$(date '+%m/%d %T') $cmd" echo "$desc" | tee -a ztest.history @@ -227,7 +234,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $(($starttime + $timeout)) ]]; do $cmd >>ztest.out 2>&1 ztrc=$? egrep '===|WARNING' ztest.out >>ztest.history - $ZDB -U $workdir/zpool.cache -DD ztest >>ztest.ddt + $ZDB -U "$workdir/zpool.cache" -DD ztest >>ztest.ddt store_core