Enable shellcheck to run for select scripts

Enable shellcheck to run on zed scripts,
paxcheck.sh, zfs-tests.sh, zfs.sh, and zloop.sh.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Closes #5812
This commit is contained in:
Giuseppe Di Natale 2017-03-09 10:20:15 -08:00 committed by Brian Behlendorf
parent 9b77d1c958
commit c552fbc5f0
9 changed files with 114 additions and 100 deletions

View File

@ -47,11 +47,14 @@ cstyle:
shellcheck: shellcheck:
@if type shellcheck > /dev/null 2>&1; then \ @if type shellcheck > /dev/null 2>&1; then \
(find ${top_srcdir} -type f -name '*.sh.in' -o -type f \ shellcheck --exclude=SC1090 --format gcc scripts/paxcheck.sh \
-name '*.sh'; find etc/init.d/zfs*.in -type f) | \ scripts/zloop.sh \
scripts/zfs-tests.sh \
scripts/zfs.sh; \
(find cmd/zed/zed.d/*.sh -type f) | \
grep -v 'zfs-script-config' | \ grep -v 'zfs-script-config' | \
while read file; do \ while read file; do \
shellcheck --format gcc "$$file"; \ shellcheck --exclude=SC1090 --format gcc "$$file"; \
done; \ done; \
fi fi

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
# #
# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes. # Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes.
# #
@ -24,6 +24,7 @@
# 2: enclosure leds administratively disabled # 2: enclosure leds administratively disabled
# 3: The led sysfs path passed from ZFS does not exist # 3: The led sysfs path passed from ZFS does not exist
# 4: $ZPOOL not set # 4: $ZPOOL not set
# 5: awk is not installed
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc" [ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
. "${ZED_ZEDLET_DIR}/zed-functions.sh" . "${ZED_ZEDLET_DIR}/zed-functions.sh"
@ -37,6 +38,7 @@ if [ "${ZED_USE_ENCLOSURE_LEDS}" != "1" ] ; then
fi fi
zed_check_cmd "$ZPOOL" || exit 4 zed_check_cmd "$ZPOOL" || exit 4
zed_check_cmd awk || exit 5
# Global used in set_led debug print # Global used in set_led debug print
vdev="" vdev=""
@ -52,7 +54,7 @@ vdev=""
# Return # Return
# 0 on success, 3 on missing sysfs path # 0 on success, 3 on missing sysfs path
# #
function check_and_set_led check_and_set_led()
{ {
file="$1" file="$1"
val="$2" val="$2"
@ -86,12 +88,13 @@ function check_and_set_led
done done
} }
function state_to_val { state_to_val()
{
state="$1" state="$1"
if [ "$state" == "FAULTED" ] || [ "$state" == "DEGRADED" ] || \ if [ "$state" = "FAULTED" ] || [ "$state" = "DEGRADED" ] || \
[ "$state" == "UNAVAIL" ] ; then [ "$state" = "UNAVAIL" ] ; then
echo 1 echo 1
elif [ "$state" == "ONLINE" ] ; then elif [ "$state" = "ONLINE" ] ; then
echo 0 echo 0
fi fi
} }
@ -107,19 +110,26 @@ function state_to_val {
# Return # Return
# 0 on success, 3 on missing sysfs path # 0 on success, 3 on missing sysfs path
# #
function process_pool process_pool()
{ {
pool="$1" pool="$1"
rc=0 rc=0
# Lookup all the current LED values and paths in parallel # 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",' cmd='echo led_token=$(cat "$VDEV_ENC_SYSFS_PATH/fault"),"$VDEV_ENC_SYSFS_PATH",'
out=$($ZPOOL status -vc "$cmd" "$pool" | grep 'led_token=') 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 # Read out current LED value and path
tmp=$(echo "$therest" | sed 's/^.*led_token=//g') 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 if [ -z "$vdev_enc_sysfs_path" ] ; then
# Skip anything with no sysfs LED entries # Skip anything with no sysfs LED entries
@ -127,6 +137,7 @@ function process_pool
fi fi
if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then
#shellcheck disable=SC2030
rc=1 rc=1
zed_log_msg "vdev $vdev '$file/fault' doesn't exist" zed_log_msg "vdev $vdev '$file/fault' doesn't exist"
continue; continue;
@ -134,17 +145,19 @@ function process_pool
val=$(state_to_val "$state") val=$(state_to_val "$state")
if [ "$current_val" == "$val" ] ; then if [ "$current_val" = "$val" ] ; then
# LED is already set correctly # LED is already set correctly
continue; continue;
fi fi
check_and_set_led "$vdev_enc_sysfs_path/fault" "$val" if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then
(( rc |= $? )) rc=1
fi
done <<< "$out" done
if [ "$rc" == "0" ] ; then #shellcheck disable=SC2031
if [ "$rc" = "0" ] ; then
return 0 return 0
else else
# We didn't see a sysfs entry that we wanted to set # 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 if [ ! -z "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ ! -z "$ZEVENT_VDEV_STATE_STR" ] ; then
# Got a statechange for an individual VDEV # Got a statechange for an individual VDEV
val=$(state_to_val "$ZEVENT_VDEV_STATE_STR") 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" check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val"
else else
# Process the entire pool # 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 fi

View File

@ -39,10 +39,10 @@ umask 077
note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)" note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)"
note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" 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 "The number of I/O errors associated with a ZFS device exceeded"
echo "acceptable levels. ZFS has marked the device as faulted." 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 "The number of checksum errors associated with a ZFS device"
echo "exceeded acceptable levels. ZFS has marked the device as" echo "exceeded acceptable levels. ZFS has marked the device as"
echo "degraded." echo "degraded."

View File

@ -1,3 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2039
# zed-functions.sh # zed-functions.sh
# #
# ZED helper functions for use in ZEDLETs # ZED helper functions for use in ZEDLETs
@ -126,6 +128,7 @@ zed_lock()
# #
eval "exec ${fd}> '${lockfile}'" eval "exec ${fd}> '${lockfile}'"
err="$(flock --exclusive "${fd}" 2>&1)" err="$(flock --exclusive "${fd}" 2>&1)"
# shellcheck disable=SC2181
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
zed_log_err "failed to lock \"${lockfile}\": ${err}" zed_log_err "failed to lock \"${lockfile}\": ${err}"
fi fi
@ -162,8 +165,8 @@ zed_unlock()
fi fi
# Release the lock and close the file descriptor. # Release the lock and close the file descriptor.
#
err="$(flock --unlock "${fd}" 2>&1)" err="$(flock --unlock "${fd}" 2>&1)"
# shellcheck disable=SC2181
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
zed_log_err "failed to unlock \"${lockfile}\": ${err}" zed_log_err "failed to unlock \"${lockfile}\": ${err}"
fi fi
@ -424,14 +427,14 @@ zed_rate_limit()
# Return # Return
# Pool name # Pool name
# #
function zed_guid_to_pool zed_guid_to_pool()
{ {
if [ -z "$1" ] ; then if [ -z "$1" ] ; then
return return
fi fi
guid=$(printf "%llu" $1) guid=$(printf "%llu" "$1")
if [ ! -z "$guid" ] ; then 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 fi
} }

View File

@ -21,7 +21,6 @@ VERBOSE=
VERBOSE_FLAG= VERBOSE_FLAG=
FORCE= FORCE=
FORCE_FLAG= FORCE_FLAG=
DUMP_LOG=
ERROR= ERROR=
RAID0S=() RAID0S=()
RAID10S=() RAID10S=()
@ -155,17 +154,6 @@ init() {
populate $SRC_DIR 10 100 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() { check_modules() {
local LOADED_MODULES=() local LOADED_MODULES=()
local MISSING_MODULES=() local MISSING_MODULES=()
@ -265,11 +253,6 @@ unload_modules() {
egrep "^${NAME} "| ${AWK} '{print $3}'` egrep "^${NAME} "| ${AWK} '{print $3}'`
if [ "${USE_COUNT}" = 0 ] ; then if [ "${USE_COUNT}" = 0 ] ; then
if [ "${DUMP_LOG}" -a ${NAME} = "spl" ]; then
spl_dump_log
fi
unload_module ${MOD} || return 1 unload_module ${MOD} || return 1
fi fi
done done

View File

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
# shellcheck disable=SC2039
if ! type scanelf > /dev/null 2>&1; then if ! type scanelf > /dev/null 2>&1; then
echo "scanelf (from pax-utils) is required for these checks." >&2 echo "scanelf (from pax-utils) is required for these checks." >&2
exit 3 exit 3
@ -8,7 +9,7 @@ fi
RET=0 RET=0
# check for exec stacks # check for exec stacks
OUT="$(scanelf -qyRAF '%e %p' $1)" OUT=$(scanelf -qyRAF '%e %p' "$1")
if [ x"${OUT}" != x ]; then if [ x"${OUT}" != x ]; then
RET=2 RET=2
@ -24,7 +25,7 @@ fi
# check for TEXTRELS # check for TEXTRELS
OUT="$(scanelf -qyRAF '%T %p' $1)" OUT=$(scanelf -qyRAF '%T %p' "$1")
if [ x"${OUT}" != x ]; then if [ x"${OUT}" != x ]; then
RET=2 RET=2

View File

@ -20,7 +20,7 @@
# #
# CDDL HEADER END # CDDL HEADER END
# #
basedir="$(dirname $0)" basedir=$(dirname "$0")
SCRIPT_COMMON=common.sh SCRIPT_COMMON=common.sh
if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
@ -29,7 +29,7 @@ else
echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
fi fi
. $STF_SUITE/include/default.cfg . "$STF_SUITE/include/default.cfg"
PROG=zfs-tests.sh PROG=zfs-tests.sh
SUDO=/usr/bin/sudo SUDO=/usr/bin/sudo
@ -58,24 +58,24 @@ cleanup() {
if [ $LOOPBACK -eq 1 ]; then if [ $LOOPBACK -eq 1 ]; then
for TEST_LOOPBACK in ${LOOPBACKS}; do for TEST_LOOPBACK in ${LOOPBACKS}; do
LOOP_DEV=$(basename $TEST_LOOPBACK) LOOP_DEV=$(basename "$TEST_LOOPBACK")
DM_DEV=$(${SUDO} ${DMSETUP} ls 2>/dev/null | \ DM_DEV=$(${SUDO} "${DMSETUP}" ls 2>/dev/null | \
grep ${LOOP_DEV} | cut -f1) grep "${LOOP_DEV}" | cut -f1)
if [ -n "$DM_DEV" ]; then if [ -n "$DM_DEV" ]; then
${SUDO} ${DMSETUP} remove ${DM_DEV} || ${SUDO} "${DMSETUP}" remove "${DM_DEV}" ||
echo "Failed to remove: ${DM_DEV}" echo "Failed to remove: ${DM_DEV}"
fi fi
if [ -n "${TEST_LOOPBACK}" ]; then if [ -n "${TEST_LOOPBACK}" ]; then
${SUDO} ${LOSETUP} -d ${TEST_LOOPBACK} || ${SUDO} "${LOSETUP}" -d "${TEST_LOOPBACK}" ||
echo "Failed to remove: ${TEST_LOOPBACK}" echo "Failed to remove: ${TEST_LOOPBACK}"
fi fi
done done
fi fi
for TEST_FILE in ${FILES}; do for TEST_FILE in ${FILES}; do
rm -f ${TEST_FILE} &>/dev/null rm -f "${TEST_FILE}" &>/dev/null
done done
} }
trap cleanup EXIT trap cleanup EXIT
@ -87,29 +87,32 @@ trap cleanup EXIT
# be dangerous and should only be used in a dedicated test environment. # be dangerous and should only be used in a dedicated test environment.
# #
cleanup_all() { cleanup_all() {
local TEST_POOLS=$(${SUDO} ${ZPOOL} list -H -o name | grep testpool) local TEST_POOLS
local TEST_LOOPBACKS=$(${SUDO} ${LOSETUP} -a|grep file-vdev|cut -f1 -d:) TEST_POOLS=$(${SUDO} "${ZPOOL}" list -H -o name | grep testpool)
local TEST_FILES=$(ls /var/tmp/file-vdev* 2>/dev/null) 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
msg "--- Cleanup ---" 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 for TEST_POOL in $TEST_POOLS; do
${SUDO} ${ZPOOL} destroy ${TEST_POOL} ${SUDO} "${ZPOOL}" destroy "${TEST_POOL}"
done done
msg "Removing dm(s): $(${SUDO} ${DMSETUP} ls | msg "Removing dm(s): $(${SUDO} "${DMSETUP}" ls |
grep loop | tr '\n' ' ')" 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 for TEST_LOOPBACK in $TEST_LOOPBACKS; do
${SUDO} ${LOSETUP} -d ${TEST_LOOPBACK} ${SUDO} "${LOSETUP}" -d "${TEST_LOOPBACK}"
done 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 for TEST_FILE in $TEST_FILES; do
${SUDO} rm -f ${TEST_FILE} ${SUDO} rm -f "${TEST_FILE}"
done done
} }
@ -193,6 +196,7 @@ while getopts 'hvqxkfd:s:r:?t:u:' OPTION; do
exit 1 exit 1
;; ;;
v) v)
# shellcheck disable=SC2034
VERBOSE=1 VERBOSE=1
;; ;;
q) q)
@ -300,11 +304,11 @@ fi
# be a normal user account, needs to be configured such that it can # be a normal user account, needs to be configured such that it can
# run commands via sudo passwordlessly. # run commands via sudo passwordlessly.
# #
if [ $(id -u) = "0" ]; then if [ "$(id -u)" = "0" ]; then
fail "This script must not be run as root." fail "This script must not be run as root."
fi fi
if [ $(sudo whoami) != "root" ]; then if [ "$(sudo whoami)" != "root" ]; then
fail "Passwordless sudo access required." fail "Passwordless sudo access required."
fi fi
@ -318,7 +322,7 @@ fi
# #
# Verify the ZFS module stack if loaded. # 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. # Attempt to cleanup all previous state for a new test run.
@ -331,7 +335,7 @@ fi
# By default preserve any existing pools # By default preserve any existing pools
# #
if [ -z "${KEEP}" ]; then if [ -z "${KEEP}" ]; then
KEEP=$(${SUDO} ${ZPOOL} list -H -o name) KEEP=$(${SUDO} "${ZPOOL}" list -H -o name)
if [ -z "${KEEP}" ]; then if [ -z "${KEEP}" ]; then
KEEP="rpool" KEEP="rpool"
fi fi
@ -356,7 +360,7 @@ if [ -z "${DISKS}" ]; then
# #
for TEST_FILE in ${FILES}; do for TEST_FILE in ${FILES}; do
[ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}" [ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}"
truncate -s ${FILESIZE} ${TEST_FILE} || truncate -s "${FILESIZE}" "${TEST_FILE}" ||
fail "Failed creating: ${TEST_FILE} ($?)" fail "Failed creating: ${TEST_FILE} ($?)"
DISKS="$DISKS$TEST_FILE " DISKS="$DISKS$TEST_FILE "
done done
@ -369,17 +373,18 @@ if [ -z "${DISKS}" ]; then
check_loop_utils check_loop_utils
for TEST_FILE in ${FILES}; do for TEST_FILE in ${FILES}; do
TEST_LOOPBACK=$(${SUDO} ${LOSETUP} -f) TEST_LOOPBACK=$(${SUDO} "${LOSETUP}" -f)
${SUDO} ${LOSETUP} ${TEST_LOOPBACK} ${TEST_FILE} || ${SUDO} "${LOSETUP}" "${TEST_LOOPBACK}" "${TEST_FILE}" ||
fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}" fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}"
LOOPBACKS="${LOOPBACKS}${TEST_LOOPBACK} " LOOPBACKS="${LOOPBACKS}${TEST_LOOPBACK} "
DISKS="$DISKS$(basename $TEST_LOOPBACK) " BASELOOPBACKS=$(basename "$TEST_LOOPBACK")
DISKS="$DISKS$BASELOOPBACKS "
done done
fi fi
fi fi
NUM_DISKS=$(echo ${DISKS} | $AWK '{print NF}') NUM_DISKS=$(echo "${DISKS}" | $AWK '{print NF}')
[ $NUM_DISKS -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" [ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)"
# #
# Disable SELinux until the ZFS Test Suite has been updated accordingly. # Disable SELinux until the ZFS Test Suite has been updated accordingly.
@ -404,7 +409,7 @@ export KEEP
export __ZFS_POOL_EXCLUDE export __ZFS_POOL_EXCLUDE
msg "${TEST_RUNNER} ${QUIET} -c ${RUNFILE} -i ${STF_SUITE}" 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=$? RESULT=$?
echo echo

View File

@ -2,7 +2,7 @@
# #
# A simple script to simply the loading/unloading the ZFS module stack. # A simple script to simply the loading/unloading the ZFS module stack.
basedir="$(dirname $0)" basedir=$(dirname "$0")
SCRIPT_COMMON=common.sh SCRIPT_COMMON=common.sh
if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
@ -11,6 +11,7 @@ else
echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
fi fi
# shellcheck disable=SC2034
PROG=zfs.sh PROG=zfs.sh
UNLOAD= UNLOAD=
@ -26,7 +27,6 @@ OPTIONS:
-h Show this message -h Show this message
-v Verbose -v Verbose
-u Unload modules -u Unload modules
-d Save debug log on unload
MODULE-OPTIONS: MODULE-OPTIONS:
Must be of the from module="options", for example: Must be of the from module="options", for example:
@ -37,21 +37,19 @@ $0 zfs="zfs_prefetch_disable=1 zfs_mdcomp_disable=1"
EOF EOF
} }
while getopts 'hvud' OPTION; do while getopts 'hvu' OPTION; do
case $OPTION in case $OPTION in
h) h)
usage usage
exit 1 exit 1
;; ;;
v) v)
# shellcheck disable=SC2034
VERBOSE=1 VERBOSE=1
;; ;;
u) u)
UNLOAD=1 UNLOAD=1
;; ;;
d)
DUMP_LOG=1
;;
?) ?)
usage usage
exit exit
@ -59,7 +57,7 @@ while getopts 'hvud' OPTION; do
esac esac
done done
if [ $(id -u) != 0 ]; then if [ "$(id -u)" != 0 ]; then
die "Must run as root" die "Must run as root"
fi fi

View File

@ -20,7 +20,7 @@
# Copyright (C) 2016 Lawrence Livermore National Security, LLC. # Copyright (C) 2016 Lawrence Livermore National Security, LLC.
# #
basedir="$(dirname $0)" basedir=$(dirname "$0")
SCRIPT_COMMON=common.sh SCRIPT_COMMON=common.sh
if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then if [ -f "${basedir}/${SCRIPT_COMMON}" ]; then
@ -29,6 +29,7 @@ else
echo "Missing helper script ${SCRIPT_COMMON}" && exit 1 echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
fi fi
# shellcheck disable=SC2034
PROG=zloop.sh PROG=zloop.sh
DEFAULTWORKDIR=/var/tmp DEFAULTWORKDIR=/var/tmp
@ -56,8 +57,11 @@ function usage
function or_die function or_die
{ {
# shellcheck disable=SC2068
$@ $@
# shellcheck disable=SC2181
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
# shellcheck disable=SC2145
echo "Command failed: $@" echo "Command failed: $@"
exit 1 exit 1
fi fi
@ -76,14 +80,16 @@ fi
function core_file function core_file
{ {
# shellcheck disable=SC2012 disable=2086
printf "%s" "$(ls -tr1 $coreglob 2> /dev/null | head -1)" printf "%s" "$(ls -tr1 $coreglob 2> /dev/null | head -1)"
} }
function core_prog function core_prog
{ {
prog=$ZTEST 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 \' ' ') tr \' ' ')
# shellcheck disable=SC2076
if [[ "$core_id" =~ "zdb " ]]; then if [[ "$core_id" =~ "zdb " ]]; then
prog=$ZDB prog=$ZDB
fi fi
@ -95,23 +101,23 @@ function store_core
core="$(core_file)" core="$(core_file)"
if [[ $ztrc -ne 0 ]] || [[ -f "$core" ]]; then if [[ $ztrc -ne 0 ]] || [[ -f "$core" ]]; then
coreid=$(date "+zloop-%y%m%d-%H%M%S") coreid=$(date "+zloop-%y%m%d-%H%M%S")
foundcrashes=$(($foundcrashes + 1)) foundcrashes=$((foundcrashes + 1))
dest=$coredir/$coreid dest=$coredir/$coreid
or_die mkdir -p $dest or_die mkdir -p "$dest"
or_die mkdir -p $dest/vdev or_die mkdir -p "$dest/vdev"
echo "*** ztest crash found - moving logs to $dest" echo "*** ztest crash found - moving logs to $dest"
or_die mv ztest.history $dest/ or_die mv ztest.history "$dest/"
or_die mv ztest.ddt $dest/ or_die mv ztest.ddt "$dest/"
or_die mv ztest.out $dest/ or_die mv ztest.out "$dest/"
or_die mv $workdir/ztest* $dest/vdev/ or_die mv "$workdir/ztest*" "$dest/vdev/"
or_die mv $workdir/zpool.cache $dest/vdev/ or_die mv "$workdir/zpool.cache" "$dest/vdev/"
# check for core # check for core
if [[ -f "$core" ]]; then if [[ -f "$core" ]]; then
coreprog=$(core_prog $core) coreprog=$(core_prog "$core")
corestatus=$($GDB --batch --quiet \ corestatus=$($GDB --batch --quiet \
-ex "set print thread-events off" \ -ex "set print thread-events off" \
-ex "printf \"*\n* Backtrace \n*\n\"" \ -ex "printf \"*\n* Backtrace \n*\n\"" \
@ -124,11 +130,11 @@ function store_core
-ex "thread apply all bt" \ -ex "thread apply all bt" \
-ex "printf \"*\n* Backtraces (full) \n*\n\"" \ -ex "printf \"*\n* Backtraces (full) \n*\n\"" \
-ex "thread apply all bt full" \ -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 # Dump core + logs to stored directory
echo "$corestatus" >>$dest/status echo "$corestatus" >>"$dest/status"
or_die mv "$core" $dest/ or_die mv "$core" "$dest/"
# Record info in cores logfile # Record info in cores logfile
echo "*** core @ $coredir/$coreid/$core:" | \ echo "*** core @ $coredir/$coreid/$core:" | \
@ -149,7 +155,7 @@ while getopts ":ht:c:f:" opt; do
case $opt in case $opt in
t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;; t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;;
c ) [[ $OPTARG ]] && coredir=$OPTARG ;; c ) [[ $OPTARG ]] && coredir=$OPTARG ;;
f ) [[ $OPTARG ]] && workdir=$(readlink -f $OPTARG) ;; f ) [[ $OPTARG ]] && workdir=$(readlink -f "$OPTARG") ;;
h ) usage h ) usage
exit 2 exit 2
;; ;;
@ -166,13 +172,13 @@ ulimit -c unlimited
if [[ -f "$(core_file)" ]]; then if [[ -f "$(core_file)" ]]; then
echo -n "There's a core dump here you might want to look at first... " echo -n "There's a core dump here you might want to look at first... "
echo "$(core_file)" core_file
exit 1 exit 1
fi fi
if [[ ! -d $coredir ]]; then if [[ ! -d $coredir ]]; then
echo "core dump directory ($coredir) does not exist, creating it." echo "core dump directory ($coredir) does not exist, creating it."
or_die mkdir -p $coredir or_die mkdir -p "$coredir"
fi fi
if [[ ! -w $coredir ]]; then if [[ ! -w $coredir ]]; then
@ -190,7 +196,7 @@ starttime=$(date +%s)
curtime=$starttime curtime=$starttime
# if no timeout was specified, loop forever. # 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" zopt="-VVVVV"
# switch between common arrangements & fully randomized # 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 -s $size"
zopt="$zopt -f $workdir" zopt="$zopt -f $workdir"
# shellcheck disable=SC2124
cmd="$ZTEST $zopt $@" cmd="$ZTEST $zopt $@"
desc="$(date '+%m/%d %T') $cmd" desc="$(date '+%m/%d %T') $cmd"
echo "$desc" | tee -a ztest.history echo "$desc" | tee -a ztest.history
@ -227,7 +234,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $(($starttime + $timeout)) ]]; do
$cmd >>ztest.out 2>&1 $cmd >>ztest.out 2>&1
ztrc=$? ztrc=$?
egrep '===|WARNING' ztest.out >>ztest.history 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 store_core