1*eda14cbcSMatt Macy#!/bin/sh 2*eda14cbcSMatt Macy# 3*eda14cbcSMatt Macy# CDDL HEADER START 4*eda14cbcSMatt Macy# 5*eda14cbcSMatt Macy# The contents of this file are subject to the terms of the 6*eda14cbcSMatt Macy# Common Development and Distribution License, Version 1.0 only 7*eda14cbcSMatt Macy# (the "License"). You may not use this file except in compliance 8*eda14cbcSMatt Macy# with the License. 9*eda14cbcSMatt Macy# 10*eda14cbcSMatt Macy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*eda14cbcSMatt Macy# or http://www.opensolaris.org/os/licensing. 12*eda14cbcSMatt Macy# See the License for the specific language governing permissions 13*eda14cbcSMatt Macy# and limitations under the License. 14*eda14cbcSMatt Macy# 15*eda14cbcSMatt Macy# When distributing Covered Code, include this CDDL HEADER in each 16*eda14cbcSMatt Macy# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*eda14cbcSMatt Macy# If applicable, add the following below this CDDL HEADER, with the 18*eda14cbcSMatt Macy# fields enclosed by brackets "[]" replaced with your own identifying 19*eda14cbcSMatt Macy# information: Portions Copyright [yyyy] [name of copyright owner] 20*eda14cbcSMatt Macy# 21*eda14cbcSMatt Macy# CDDL HEADER END 22*eda14cbcSMatt Macy# 23*eda14cbcSMatt Macy 24*eda14cbcSMatt MacyBASE_DIR=$(dirname "$0") 25*eda14cbcSMatt MacySCRIPT_COMMON=common.sh 26*eda14cbcSMatt Macyif [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then 27*eda14cbcSMatt Macy. "${BASE_DIR}/${SCRIPT_COMMON}" 28*eda14cbcSMatt Macyelse 29*eda14cbcSMatt Macyecho "Missing helper script ${SCRIPT_COMMON}" && exit 1 30*eda14cbcSMatt Macyfi 31*eda14cbcSMatt Macy 32*eda14cbcSMatt MacyPROG=zfs-tests.sh 33*eda14cbcSMatt MacyVERBOSE="no" 34*eda14cbcSMatt MacyQUIET="" 35*eda14cbcSMatt MacyCLEANUP="yes" 36*eda14cbcSMatt MacyCLEANUPALL="no" 37*eda14cbcSMatt MacyLOOPBACK="yes" 38*eda14cbcSMatt MacySTACK_TRACER="no" 39*eda14cbcSMatt MacyFILESIZE="4G" 40*eda14cbcSMatt MacyDEFAULT_RUNFILES="common.run,$(uname | tr '[:upper:]' '[:lower:]').run" 41*eda14cbcSMatt MacyRUNFILES=${RUNFILES:-$DEFAULT_RUNFILES} 42*eda14cbcSMatt MacyFILEDIR=${FILEDIR:-/var/tmp} 43*eda14cbcSMatt MacyDISKS=${DISKS:-""} 44*eda14cbcSMatt MacySINGLETEST="" 45*eda14cbcSMatt MacySINGLETESTUSER="root" 46*eda14cbcSMatt MacyTAGS="" 47*eda14cbcSMatt MacyITERATIONS=1 48*eda14cbcSMatt MacyZFS_DBGMSG="$STF_SUITE/callbacks/zfs_dbgmsg.ksh" 49*eda14cbcSMatt MacyZFS_DMESG="$STF_SUITE/callbacks/zfs_dmesg.ksh" 50*eda14cbcSMatt MacyUNAME=$(uname -s) 51*eda14cbcSMatt Macy 52*eda14cbcSMatt Macy# Override some defaults if on FreeBSD 53*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then 54*eda14cbcSMatt Macy TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"} 55*eda14cbcSMatt Macy LOSETUP=/sbin/mdconfig 56*eda14cbcSMatt Macy DMSETUP=/sbin/gpart 57*eda14cbcSMatt Macyelse 58*eda14cbcSMatt Macy ZFS_MMP="$STF_SUITE/callbacks/zfs_mmp.ksh" 59*eda14cbcSMatt Macy TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DBGMSG:$ZFS_DMESG:$ZFS_MMP"} 60*eda14cbcSMatt Macy LOSETUP=${LOSETUP:-/sbin/losetup} 61*eda14cbcSMatt Macy DMSETUP=${DMSETUP:-/sbin/dmsetup} 62*eda14cbcSMatt Macyfi 63*eda14cbcSMatt Macy 64*eda14cbcSMatt Macy# 65*eda14cbcSMatt Macy# Log an informational message when additional verbosity is enabled. 66*eda14cbcSMatt Macy# 67*eda14cbcSMatt Macymsg() { 68*eda14cbcSMatt Macy if [ "$VERBOSE" = "yes" ]; then 69*eda14cbcSMatt Macy echo "$@" 70*eda14cbcSMatt Macy fi 71*eda14cbcSMatt Macy} 72*eda14cbcSMatt Macy 73*eda14cbcSMatt Macy# 74*eda14cbcSMatt Macy# Log a failure message, cleanup, and return an error. 75*eda14cbcSMatt Macy# 76*eda14cbcSMatt Macyfail() { 77*eda14cbcSMatt Macy echo "$PROG: $1" >&2 78*eda14cbcSMatt Macy cleanup 79*eda14cbcSMatt Macy exit 1 80*eda14cbcSMatt Macy} 81*eda14cbcSMatt Macy 82*eda14cbcSMatt Macycleanup_freebsd_loopback() { 83*eda14cbcSMatt Macy for TEST_LOOPBACK in ${LOOPBACKS}; do 84*eda14cbcSMatt Macy if [ -c "/dev/${TEST_LOOPBACK}" ]; then 85*eda14cbcSMatt Macy sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}" || 86*eda14cbcSMatt Macy echo "Failed to destroy: ${TEST_LOOPBACK}" 87*eda14cbcSMatt Macy fi 88*eda14cbcSMatt Macy done 89*eda14cbcSMatt Macy} 90*eda14cbcSMatt Macy 91*eda14cbcSMatt Macycleanup_linux_loopback() { 92*eda14cbcSMatt Macy for TEST_LOOPBACK in ${LOOPBACKS}; do 93*eda14cbcSMatt Macy LOOP_DEV=$(basename "$TEST_LOOPBACK") 94*eda14cbcSMatt Macy DM_DEV=$(sudo "${DMSETUP}" ls 2>/dev/null | \ 95*eda14cbcSMatt Macy grep "${LOOP_DEV}" | cut -f1) 96*eda14cbcSMatt Macy 97*eda14cbcSMatt Macy if [ -n "$DM_DEV" ]; then 98*eda14cbcSMatt Macy sudo "${DMSETUP}" remove "${DM_DEV}" || 99*eda14cbcSMatt Macy echo "Failed to remove: ${DM_DEV}" 100*eda14cbcSMatt Macy fi 101*eda14cbcSMatt Macy 102*eda14cbcSMatt Macy if [ -n "${TEST_LOOPBACK}" ]; then 103*eda14cbcSMatt Macy sudo "${LOSETUP}" -d "${TEST_LOOPBACK}" || 104*eda14cbcSMatt Macy echo "Failed to remove: ${TEST_LOOPBACK}" 105*eda14cbcSMatt Macy fi 106*eda14cbcSMatt Macy done 107*eda14cbcSMatt Macy} 108*eda14cbcSMatt Macy 109*eda14cbcSMatt Macy# 110*eda14cbcSMatt Macy# Attempt to remove loopback devices and files which where created earlier 111*eda14cbcSMatt Macy# by this script to run the test framework. The '-k' option may be passed 112*eda14cbcSMatt Macy# to the script to suppress cleanup for debugging purposes. 113*eda14cbcSMatt Macy# 114*eda14cbcSMatt Macycleanup() { 115*eda14cbcSMatt Macy if [ "$CLEANUP" = "no" ]; then 116*eda14cbcSMatt Macy return 0 117*eda14cbcSMatt Macy fi 118*eda14cbcSMatt Macy 119*eda14cbcSMatt Macy 120*eda14cbcSMatt Macy if [ "$LOOPBACK" = "yes" ]; then 121*eda14cbcSMatt Macy if [ "$UNAME" = "FreeBSD" ] ; then 122*eda14cbcSMatt Macy cleanup_freebsd_loopback 123*eda14cbcSMatt Macy else 124*eda14cbcSMatt Macy cleanup_linux_loopback 125*eda14cbcSMatt Macy fi 126*eda14cbcSMatt Macy fi 127*eda14cbcSMatt Macy 128*eda14cbcSMatt Macy for TEST_FILE in ${FILES}; do 129*eda14cbcSMatt Macy rm -f "${TEST_FILE}" >/dev/null 2>&1 130*eda14cbcSMatt Macy done 131*eda14cbcSMatt Macy 132*eda14cbcSMatt Macy if [ "$STF_PATH_REMOVE" = "yes" ] && [ -d "$STF_PATH" ]; then 133*eda14cbcSMatt Macy rm -Rf "$STF_PATH" 134*eda14cbcSMatt Macy fi 135*eda14cbcSMatt Macy} 136*eda14cbcSMatt Macytrap cleanup EXIT 137*eda14cbcSMatt Macy 138*eda14cbcSMatt Macy# 139*eda14cbcSMatt Macy# Attempt to remove all testpools (testpool.XXX), unopened dm devices, 140*eda14cbcSMatt Macy# loopback devices, and files. This is a useful way to cleanup a previous 141*eda14cbcSMatt Macy# test run failure which has left the system in an unknown state. This can 142*eda14cbcSMatt Macy# be dangerous and should only be used in a dedicated test environment. 143*eda14cbcSMatt Macy# 144*eda14cbcSMatt Macycleanup_all() { 145*eda14cbcSMatt Macy TEST_POOLS=$(sudo "$ZPOOL" list -H -o name | grep testpool) 146*eda14cbcSMatt Macy if [ "$UNAME" = "FreeBSD" ] ; then 147*eda14cbcSMatt Macy TEST_LOOPBACKS=$(sudo "${LOSETUP}" -l) 148*eda14cbcSMatt Macy else 149*eda14cbcSMatt Macy TEST_LOOPBACKS=$(sudo "${LOSETUP}" -a|grep file-vdev|cut -f1 -d:) 150*eda14cbcSMatt Macy fi 151*eda14cbcSMatt Macy TEST_FILES=$(ls /var/tmp/file-vdev* 2>/dev/null) 152*eda14cbcSMatt Macy 153*eda14cbcSMatt Macy msg 154*eda14cbcSMatt Macy msg "--- Cleanup ---" 155*eda14cbcSMatt Macy msg "Removing pool(s): $(echo "${TEST_POOLS}" | tr '\n' ' ')" 156*eda14cbcSMatt Macy for TEST_POOL in $TEST_POOLS; do 157*eda14cbcSMatt Macy sudo "$ZPOOL" destroy "${TEST_POOL}" 158*eda14cbcSMatt Macy done 159*eda14cbcSMatt Macy 160*eda14cbcSMatt Macy if [ "$UNAME" != "FreeBSD" ] ; then 161*eda14cbcSMatt Macy msg "Removing dm(s): $(sudo "${DMSETUP}" ls | 162*eda14cbcSMatt Macy grep loop | tr '\n' ' ')" 163*eda14cbcSMatt Macy sudo "${DMSETUP}" remove_all 164*eda14cbcSMatt Macy fi 165*eda14cbcSMatt Macy 166*eda14cbcSMatt Macy msg "Removing loopback(s): $(echo "${TEST_LOOPBACKS}" | tr '\n' ' ')" 167*eda14cbcSMatt Macy for TEST_LOOPBACK in $TEST_LOOPBACKS; do 168*eda14cbcSMatt Macy if [ "$UNAME" = "FreeBSD" ] ; then 169*eda14cbcSMatt Macy sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}" 170*eda14cbcSMatt Macy else 171*eda14cbcSMatt Macy sudo "${LOSETUP}" -d "${TEST_LOOPBACK}" 172*eda14cbcSMatt Macy fi 173*eda14cbcSMatt Macy done 174*eda14cbcSMatt Macy 175*eda14cbcSMatt Macy msg "Removing files(s): $(echo "${TEST_FILES}" | tr '\n' ' ')" 176*eda14cbcSMatt Macy for TEST_FILE in $TEST_FILES; do 177*eda14cbcSMatt Macy sudo rm -f "${TEST_FILE}" 178*eda14cbcSMatt Macy done 179*eda14cbcSMatt Macy} 180*eda14cbcSMatt Macy 181*eda14cbcSMatt Macy# 182*eda14cbcSMatt Macy# Takes a name as the only arguments and looks for the following variations 183*eda14cbcSMatt Macy# on that name. If one is found it is returned. 184*eda14cbcSMatt Macy# 185*eda14cbcSMatt Macy# $RUNFILE_DIR/<name> 186*eda14cbcSMatt Macy# $RUNFILE_DIR/<name>.run 187*eda14cbcSMatt Macy# <name> 188*eda14cbcSMatt Macy# <name>.run 189*eda14cbcSMatt Macy# 190*eda14cbcSMatt Macyfind_runfile() { 191*eda14cbcSMatt Macy NAME=$1 192*eda14cbcSMatt Macy RESULT="" 193*eda14cbcSMatt Macy 194*eda14cbcSMatt Macy if [ -f "$RUNFILE_DIR/$NAME" ]; then 195*eda14cbcSMatt Macy RESULT="$RUNFILE_DIR/$NAME" 196*eda14cbcSMatt Macy elif [ -f "$RUNFILE_DIR/$NAME.run" ]; then 197*eda14cbcSMatt Macy RESULT="$RUNFILE_DIR/$NAME.run" 198*eda14cbcSMatt Macy elif [ -f "$NAME" ]; then 199*eda14cbcSMatt Macy RESULT="$NAME" 200*eda14cbcSMatt Macy elif [ -f "$NAME.run" ]; then 201*eda14cbcSMatt Macy RESULT="$NAME.run" 202*eda14cbcSMatt Macy fi 203*eda14cbcSMatt Macy 204*eda14cbcSMatt Macy echo "$RESULT" 205*eda14cbcSMatt Macy} 206*eda14cbcSMatt Macy 207*eda14cbcSMatt Macy# 208*eda14cbcSMatt Macy# Symlink file if it appears under any of the given paths. 209*eda14cbcSMatt Macy# 210*eda14cbcSMatt Macycreate_links() { 211*eda14cbcSMatt Macy dir_list="$1" 212*eda14cbcSMatt Macy file_list="$2" 213*eda14cbcSMatt Macy 214*eda14cbcSMatt Macy [ -n "$STF_PATH" ] || fail "STF_PATH wasn't correctly set" 215*eda14cbcSMatt Macy 216*eda14cbcSMatt Macy for i in $file_list; do 217*eda14cbcSMatt Macy for j in $dir_list; do 218*eda14cbcSMatt Macy [ ! -e "$STF_PATH/$i" ] || continue 219*eda14cbcSMatt Macy 220*eda14cbcSMatt Macy if [ ! -d "$j/$i" ] && [ -e "$j/$i" ]; then 221*eda14cbcSMatt Macy ln -sf "$j/$i" "$STF_PATH/$i" || \ 222*eda14cbcSMatt Macy fail "Couldn't link $i" 223*eda14cbcSMatt Macy break 224*eda14cbcSMatt Macy fi 225*eda14cbcSMatt Macy done 226*eda14cbcSMatt Macy 227*eda14cbcSMatt Macy [ ! -e "$STF_PATH/$i" ] && \ 228*eda14cbcSMatt Macy STF_MISSING_BIN="$STF_MISSING_BIN $i" 229*eda14cbcSMatt Macy done 230*eda14cbcSMatt Macy STF_MISSING_BIN=${STF_MISSING_BIN# } 231*eda14cbcSMatt Macy} 232*eda14cbcSMatt Macy 233*eda14cbcSMatt Macy# 234*eda14cbcSMatt Macy# Constrain the path to limit the available binaries to a known set. 235*eda14cbcSMatt Macy# When running in-tree a top level ./bin/ directory is created for 236*eda14cbcSMatt Macy# convenience, otherwise a temporary directory is used. 237*eda14cbcSMatt Macy# 238*eda14cbcSMatt Macyconstrain_path() { 239*eda14cbcSMatt Macy . "$STF_SUITE/include/commands.cfg" 240*eda14cbcSMatt Macy 241*eda14cbcSMatt Macy # On FreeBSD, base system zfs utils are in /sbin and OpenZFS utils 242*eda14cbcSMatt Macy # install to /usr/local/sbin. To avoid testing the wrong utils we 243*eda14cbcSMatt Macy # need /usr/local to come before / in the path search order. 244*eda14cbcSMatt Macy SYSTEM_DIRS="/usr/local/bin /usr/local/sbin" 245*eda14cbcSMatt Macy SYSTEM_DIRS="$SYSTEM_DIRS /usr/bin /usr/sbin /bin /sbin" 246*eda14cbcSMatt Macy 247*eda14cbcSMatt Macy if [ "$INTREE" = "yes" ]; then 248*eda14cbcSMatt Macy # Constrained path set to ./zfs/bin/ 249*eda14cbcSMatt Macy STF_PATH="$BIN_DIR" 250*eda14cbcSMatt Macy STF_PATH_REMOVE="no" 251*eda14cbcSMatt Macy STF_MISSING_BIN="" 252*eda14cbcSMatt Macy if [ ! -d "$STF_PATH" ]; then 253*eda14cbcSMatt Macy mkdir "$STF_PATH" 254*eda14cbcSMatt Macy chmod 755 "$STF_PATH" || fail "Couldn't chmod $STF_PATH" 255*eda14cbcSMatt Macy fi 256*eda14cbcSMatt Macy 257*eda14cbcSMatt Macy # Special case links for standard zfs utilities 258*eda14cbcSMatt Macy DIRS="$(find "$CMD_DIR" -type d \( ! -name .deps -a \ 259*eda14cbcSMatt Macy ! -name .libs \) -print | tr '\n' ' ')" 260*eda14cbcSMatt Macy create_links "$DIRS" "$ZFS_FILES" 261*eda14cbcSMatt Macy 262*eda14cbcSMatt Macy # Special case links for zfs test suite utilities 263*eda14cbcSMatt Macy DIRS="$(find "$STF_SUITE" -type d \( ! -name .deps -a \ 264*eda14cbcSMatt Macy ! -name .libs \) -print | tr '\n' ' ')" 265*eda14cbcSMatt Macy create_links "$DIRS" "$ZFSTEST_FILES" 266*eda14cbcSMatt Macy else 267*eda14cbcSMatt Macy # Constrained path set to /var/tmp/constrained_path.* 268*eda14cbcSMatt Macy SYSTEMDIR=${SYSTEMDIR:-/var/tmp/constrained_path.XXXX} 269*eda14cbcSMatt Macy STF_PATH=$(mktemp -d "$SYSTEMDIR") 270*eda14cbcSMatt Macy STF_PATH_REMOVE="yes" 271*eda14cbcSMatt Macy STF_MISSING_BIN="" 272*eda14cbcSMatt Macy 273*eda14cbcSMatt Macy chmod 755 "$STF_PATH" || fail "Couldn't chmod $STF_PATH" 274*eda14cbcSMatt Macy 275*eda14cbcSMatt Macy # Special case links for standard zfs utilities 276*eda14cbcSMatt Macy create_links "$SYSTEM_DIRS" "$ZFS_FILES" 277*eda14cbcSMatt Macy 278*eda14cbcSMatt Macy # Special case links for zfs test suite utilities 279*eda14cbcSMatt Macy create_links "$STF_SUITE/bin" "$ZFSTEST_FILES" 280*eda14cbcSMatt Macy fi 281*eda14cbcSMatt Macy 282*eda14cbcSMatt Macy # Standard system utilities 283*eda14cbcSMatt Macy SYSTEM_FILES="$SYSTEM_FILES_COMMON" 284*eda14cbcSMatt Macy if [ "$UNAME" = "FreeBSD" ] ; then 285*eda14cbcSMatt Macy SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_FREEBSD" 286*eda14cbcSMatt Macy else 287*eda14cbcSMatt Macy SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_LINUX" 288*eda14cbcSMatt Macy fi 289*eda14cbcSMatt Macy create_links "$SYSTEM_DIRS" "$SYSTEM_FILES" 290*eda14cbcSMatt Macy 291*eda14cbcSMatt Macy # Exceptions 292*eda14cbcSMatt Macy ln -fs "$STF_PATH/awk" "$STF_PATH/nawk" 293*eda14cbcSMatt Macy if [ "$UNAME" = "Linux" ] ; then 294*eda14cbcSMatt Macy ln -fs /sbin/fsck.ext4 "$STF_PATH/fsck" 295*eda14cbcSMatt Macy ln -fs /sbin/mkfs.ext4 "$STF_PATH/newfs" 296*eda14cbcSMatt Macy ln -fs "$STF_PATH/gzip" "$STF_PATH/compress" 297*eda14cbcSMatt Macy ln -fs "$STF_PATH/gunzip" "$STF_PATH/uncompress" 298*eda14cbcSMatt Macy ln -fs "$STF_PATH/exportfs" "$STF_PATH/share" 299*eda14cbcSMatt Macy ln -fs "$STF_PATH/exportfs" "$STF_PATH/unshare" 300*eda14cbcSMatt Macy elif [ "$UNAME" = "FreeBSD" ] ; then 301*eda14cbcSMatt Macy ln -fs /usr/local/bin/ksh93 "$STF_PATH/ksh" 302*eda14cbcSMatt Macy fi 303*eda14cbcSMatt Macy} 304*eda14cbcSMatt Macy 305*eda14cbcSMatt Macy# 306*eda14cbcSMatt Macy# Output a useful usage message. 307*eda14cbcSMatt Macy# 308*eda14cbcSMatt Macyusage() { 309*eda14cbcSMatt Macycat << EOF 310*eda14cbcSMatt MacyUSAGE: 311*eda14cbcSMatt Macy$0 [hvqxkfS] [-s SIZE] [-r RUNFILES] [-t PATH] [-u USER] 312*eda14cbcSMatt Macy 313*eda14cbcSMatt MacyDESCRIPTION: 314*eda14cbcSMatt Macy ZFS Test Suite launch script 315*eda14cbcSMatt Macy 316*eda14cbcSMatt MacyOPTIONS: 317*eda14cbcSMatt Macy -h Show this message 318*eda14cbcSMatt Macy -v Verbose zfs-tests.sh output 319*eda14cbcSMatt Macy -q Quiet test-runner output 320*eda14cbcSMatt Macy -x Remove all testpools, dm, lo, and files (unsafe) 321*eda14cbcSMatt Macy -k Disable cleanup after test failure 322*eda14cbcSMatt Macy -f Use files only, disables block device tests 323*eda14cbcSMatt Macy -S Enable stack tracer (negative performance impact) 324*eda14cbcSMatt Macy -c Only create and populate constrained path 325*eda14cbcSMatt Macy -n NFSFILE Use the nfsfile to determine the NFS configuration 326*eda14cbcSMatt Macy -I NUM Number of iterations 327*eda14cbcSMatt Macy -d DIR Use DIR for files and loopback devices 328*eda14cbcSMatt Macy -s SIZE Use vdevs of SIZE (default: 4G) 329*eda14cbcSMatt Macy -r RUNFILES Run tests in RUNFILES (default: ${DEFAULT_RUNFILES}) 330*eda14cbcSMatt Macy -t PATH Run single test at PATH relative to test suite 331*eda14cbcSMatt Macy -T TAGS Comma separated list of tags (default: 'functional') 332*eda14cbcSMatt Macy -u USER Run single test as USER (default: root) 333*eda14cbcSMatt Macy 334*eda14cbcSMatt MacyEXAMPLES: 335*eda14cbcSMatt Macy# Run the default (linux) suite of tests and output the configuration used. 336*eda14cbcSMatt Macy$0 -v 337*eda14cbcSMatt Macy 338*eda14cbcSMatt Macy# Run a smaller suite of tests designed to run more quickly. 339*eda14cbcSMatt Macy$0 -r linux-fast 340*eda14cbcSMatt Macy 341*eda14cbcSMatt Macy# Run a single test 342*eda14cbcSMatt Macy$0 -t tests/functional/cli_root/zfs_bookmark/zfs_bookmark_cliargs.ksh 343*eda14cbcSMatt Macy 344*eda14cbcSMatt Macy# Cleanup a previous run of the test suite prior to testing, run the 345*eda14cbcSMatt Macy# default (linux) suite of tests and perform no cleanup on exit. 346*eda14cbcSMatt Macy$0 -x 347*eda14cbcSMatt Macy 348*eda14cbcSMatt MacyEOF 349*eda14cbcSMatt Macy} 350*eda14cbcSMatt Macy 351*eda14cbcSMatt Macywhile getopts 'hvqxkfScn:d:s:r:?t:T:u:I:' OPTION; do 352*eda14cbcSMatt Macy case $OPTION in 353*eda14cbcSMatt Macy h) 354*eda14cbcSMatt Macy usage 355*eda14cbcSMatt Macy exit 1 356*eda14cbcSMatt Macy ;; 357*eda14cbcSMatt Macy v) 358*eda14cbcSMatt Macy # shellcheck disable=SC2034 359*eda14cbcSMatt Macy VERBOSE="yes" 360*eda14cbcSMatt Macy ;; 361*eda14cbcSMatt Macy q) 362*eda14cbcSMatt Macy QUIET="yes" 363*eda14cbcSMatt Macy ;; 364*eda14cbcSMatt Macy x) 365*eda14cbcSMatt Macy CLEANUPALL="yes" 366*eda14cbcSMatt Macy ;; 367*eda14cbcSMatt Macy k) 368*eda14cbcSMatt Macy CLEANUP="no" 369*eda14cbcSMatt Macy ;; 370*eda14cbcSMatt Macy f) 371*eda14cbcSMatt Macy LOOPBACK="no" 372*eda14cbcSMatt Macy ;; 373*eda14cbcSMatt Macy S) 374*eda14cbcSMatt Macy STACK_TRACER="yes" 375*eda14cbcSMatt Macy ;; 376*eda14cbcSMatt Macy c) 377*eda14cbcSMatt Macy constrain_path 378*eda14cbcSMatt Macy exit 379*eda14cbcSMatt Macy ;; 380*eda14cbcSMatt Macy n) 381*eda14cbcSMatt Macy nfsfile=$OPTARG 382*eda14cbcSMatt Macy [ -f "$nfsfile" ] || fail "Cannot read file: $nfsfile" 383*eda14cbcSMatt Macy export NFS=1 384*eda14cbcSMatt Macy . "$nfsfile" 385*eda14cbcSMatt Macy ;; 386*eda14cbcSMatt Macy d) 387*eda14cbcSMatt Macy FILEDIR="$OPTARG" 388*eda14cbcSMatt Macy ;; 389*eda14cbcSMatt Macy I) 390*eda14cbcSMatt Macy ITERATIONS="$OPTARG" 391*eda14cbcSMatt Macy if [ "$ITERATIONS" -le 0 ]; then 392*eda14cbcSMatt Macy fail "Iterations must be greater than 0." 393*eda14cbcSMatt Macy fi 394*eda14cbcSMatt Macy ;; 395*eda14cbcSMatt Macy s) 396*eda14cbcSMatt Macy FILESIZE="$OPTARG" 397*eda14cbcSMatt Macy ;; 398*eda14cbcSMatt Macy r) 399*eda14cbcSMatt Macy RUNFILES="$OPTARG" 400*eda14cbcSMatt Macy ;; 401*eda14cbcSMatt Macy t) 402*eda14cbcSMatt Macy if [ -n "$SINGLETEST" ]; then 403*eda14cbcSMatt Macy fail "-t can only be provided once." 404*eda14cbcSMatt Macy fi 405*eda14cbcSMatt Macy SINGLETEST="$OPTARG" 406*eda14cbcSMatt Macy ;; 407*eda14cbcSMatt Macy T) 408*eda14cbcSMatt Macy TAGS="$OPTARG" 409*eda14cbcSMatt Macy ;; 410*eda14cbcSMatt Macy u) 411*eda14cbcSMatt Macy SINGLETESTUSER="$OPTARG" 412*eda14cbcSMatt Macy ;; 413*eda14cbcSMatt Macy ?) 414*eda14cbcSMatt Macy usage 415*eda14cbcSMatt Macy exit 416*eda14cbcSMatt Macy ;; 417*eda14cbcSMatt Macy esac 418*eda14cbcSMatt Macydone 419*eda14cbcSMatt Macy 420*eda14cbcSMatt Macyshift $((OPTIND-1)) 421*eda14cbcSMatt Macy 422*eda14cbcSMatt MacyFILES=${FILES:-"$FILEDIR/file-vdev0 $FILEDIR/file-vdev1 $FILEDIR/file-vdev2"} 423*eda14cbcSMatt MacyLOOPBACKS=${LOOPBACKS:-""} 424*eda14cbcSMatt Macy 425*eda14cbcSMatt Macyif [ -n "$SINGLETEST" ]; then 426*eda14cbcSMatt Macy if [ -n "$TAGS" ]; then 427*eda14cbcSMatt Macy fail "-t and -T are mutually exclusive." 428*eda14cbcSMatt Macy fi 429*eda14cbcSMatt Macy RUNFILE_DIR="/var/tmp" 430*eda14cbcSMatt Macy RUNFILES="zfs-tests.$$.run" 431*eda14cbcSMatt Macy SINGLEQUIET="False" 432*eda14cbcSMatt Macy 433*eda14cbcSMatt Macy if [ -n "$QUIET" ]; then 434*eda14cbcSMatt Macy SINGLEQUIET="True" 435*eda14cbcSMatt Macy fi 436*eda14cbcSMatt Macy 437*eda14cbcSMatt Macy cat >$RUNFILE_DIR/$RUNFILES << EOF 438*eda14cbcSMatt Macy[DEFAULT] 439*eda14cbcSMatt Macypre = 440*eda14cbcSMatt Macyquiet = $SINGLEQUIET 441*eda14cbcSMatt Macypre_user = root 442*eda14cbcSMatt Macyuser = $SINGLETESTUSER 443*eda14cbcSMatt Macytimeout = 600 444*eda14cbcSMatt Macypost_user = root 445*eda14cbcSMatt Macypost = 446*eda14cbcSMatt Macyoutputdir = /var/tmp/test_results 447*eda14cbcSMatt MacyEOF 448*eda14cbcSMatt Macy SINGLETESTDIR=$(dirname "$SINGLETEST") 449*eda14cbcSMatt Macy SINGLETESTFILE=$(basename "$SINGLETEST") 450*eda14cbcSMatt Macy SETUPSCRIPT= 451*eda14cbcSMatt Macy CLEANUPSCRIPT= 452*eda14cbcSMatt Macy 453*eda14cbcSMatt Macy if [ -f "$STF_SUITE/$SINGLETESTDIR/setup.ksh" ]; then 454*eda14cbcSMatt Macy SETUPSCRIPT="setup" 455*eda14cbcSMatt Macy fi 456*eda14cbcSMatt Macy 457*eda14cbcSMatt Macy if [ -f "$STF_SUITE/$SINGLETESTDIR/cleanup.ksh" ]; then 458*eda14cbcSMatt Macy CLEANUPSCRIPT="cleanup" 459*eda14cbcSMatt Macy fi 460*eda14cbcSMatt Macy 461*eda14cbcSMatt Macy cat >>$RUNFILE_DIR/$RUNFILES << EOF 462*eda14cbcSMatt Macy 463*eda14cbcSMatt Macy[$SINGLETESTDIR] 464*eda14cbcSMatt Macytests = ['$SINGLETESTFILE'] 465*eda14cbcSMatt Macypre = $SETUPSCRIPT 466*eda14cbcSMatt Macypost = $CLEANUPSCRIPT 467*eda14cbcSMatt Macytags = ['functional'] 468*eda14cbcSMatt MacyEOF 469*eda14cbcSMatt Macyfi 470*eda14cbcSMatt Macy 471*eda14cbcSMatt Macy# 472*eda14cbcSMatt Macy# Use default tag if none was specified 473*eda14cbcSMatt Macy# 474*eda14cbcSMatt MacyTAGS=${TAGS:='functional'} 475*eda14cbcSMatt Macy 476*eda14cbcSMatt Macy# 477*eda14cbcSMatt Macy# Attempt to locate the runfiles describing the test workload. 478*eda14cbcSMatt Macy# 479*eda14cbcSMatt MacyR="" 480*eda14cbcSMatt MacyIFS=, 481*eda14cbcSMatt Macyfor RUNFILE in $RUNFILES; do 482*eda14cbcSMatt Macy if [ -n "$RUNFILE" ]; then 483*eda14cbcSMatt Macy SAVED_RUNFILE="$RUNFILE" 484*eda14cbcSMatt Macy RUNFILE=$(find_runfile "$RUNFILE") 485*eda14cbcSMatt Macy [ -z "$RUNFILE" ] && fail "Cannot find runfile: $SAVED_RUNFILE" 486*eda14cbcSMatt Macy R="$R,$RUNFILE" 487*eda14cbcSMatt Macy fi 488*eda14cbcSMatt Macy 489*eda14cbcSMatt Macy if [ ! -r "$RUNFILE" ]; then 490*eda14cbcSMatt Macy fail "Cannot read runfile: $RUNFILE" 491*eda14cbcSMatt Macy fi 492*eda14cbcSMatt Macydone 493*eda14cbcSMatt Macyunset IFS 494*eda14cbcSMatt MacyRUNFILES=${R#,} 495*eda14cbcSMatt Macy 496*eda14cbcSMatt Macy# 497*eda14cbcSMatt Macy# This script should not be run as root. Instead the test user, which may 498*eda14cbcSMatt Macy# be a normal user account, needs to be configured such that it can 499*eda14cbcSMatt Macy# run commands via sudo passwordlessly. 500*eda14cbcSMatt Macy# 501*eda14cbcSMatt Macyif [ "$(id -u)" = "0" ]; then 502*eda14cbcSMatt Macy fail "This script must not be run as root." 503*eda14cbcSMatt Macyfi 504*eda14cbcSMatt Macy 505*eda14cbcSMatt Macyif [ "$(sudo whoami)" != "root" ]; then 506*eda14cbcSMatt Macy fail "Passwordless sudo access required." 507*eda14cbcSMatt Macyfi 508*eda14cbcSMatt Macy 509*eda14cbcSMatt Macy# 510*eda14cbcSMatt Macy# Constrain the available binaries to a known set. 511*eda14cbcSMatt Macy# 512*eda14cbcSMatt Macyconstrain_path 513*eda14cbcSMatt Macy 514*eda14cbcSMatt Macy# 515*eda14cbcSMatt Macy# Check if ksh exists 516*eda14cbcSMatt Macy# 517*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ]; then 518*eda14cbcSMatt Macy sudo ln -fs /usr/local/bin/ksh93 /bin/ksh 519*eda14cbcSMatt Macyfi 520*eda14cbcSMatt Macy[ -e "$STF_PATH/ksh" ] || fail "This test suite requires ksh." 521*eda14cbcSMatt Macy[ -e "$STF_SUITE/include/default.cfg" ] || fail \ 522*eda14cbcSMatt Macy "Missing $STF_SUITE/include/default.cfg file." 523*eda14cbcSMatt Macy 524*eda14cbcSMatt Macy# 525*eda14cbcSMatt Macy# Verify the ZFS module stack is loaded. 526*eda14cbcSMatt Macy# 527*eda14cbcSMatt Macyif [ "$STACK_TRACER" = "yes" ]; then 528*eda14cbcSMatt Macy sudo "${ZFS_SH}" -S >/dev/null 2>&1 529*eda14cbcSMatt Macyelse 530*eda14cbcSMatt Macy sudo "${ZFS_SH}" >/dev/null 2>&1 531*eda14cbcSMatt Macyfi 532*eda14cbcSMatt Macy 533*eda14cbcSMatt Macy# 534*eda14cbcSMatt Macy# Attempt to cleanup all previous state for a new test run. 535*eda14cbcSMatt Macy# 536*eda14cbcSMatt Macyif [ "$CLEANUPALL" = "yes" ]; then 537*eda14cbcSMatt Macy cleanup_all 538*eda14cbcSMatt Macyfi 539*eda14cbcSMatt Macy 540*eda14cbcSMatt Macy# 541*eda14cbcSMatt Macy# By default preserve any existing pools 542*eda14cbcSMatt Macy# NOTE: Since 'zpool list' outputs a newline-delimited list convert $KEEP from 543*eda14cbcSMatt Macy# space-delimited to newline-delimited. 544*eda14cbcSMatt Macy# 545*eda14cbcSMatt Macyif [ -z "${KEEP}" ]; then 546*eda14cbcSMatt Macy KEEP="$(sudo "$ZPOOL" list -H -o name)" 547*eda14cbcSMatt Macy if [ -z "${KEEP}" ]; then 548*eda14cbcSMatt Macy KEEP="rpool" 549*eda14cbcSMatt Macy fi 550*eda14cbcSMatt Macyelse 551*eda14cbcSMatt Macy KEEP="$(echo "$KEEP" | tr '[:blank:]' '\n')" 552*eda14cbcSMatt Macyfi 553*eda14cbcSMatt Macy 554*eda14cbcSMatt Macy# 555*eda14cbcSMatt Macy# NOTE: The following environment variables are undocumented 556*eda14cbcSMatt Macy# and should be used for testing purposes only: 557*eda14cbcSMatt Macy# 558*eda14cbcSMatt Macy# __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists 559*eda14cbcSMatt Macy# __ZFS_POOL_RESTRICT - iterate only over the pools it lists 560*eda14cbcSMatt Macy# 561*eda14cbcSMatt Macy# See libzfs/libzfs_config.c for more information. 562*eda14cbcSMatt Macy# 563*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then 564*eda14cbcSMatt Macy __ZFS_POOL_EXCLUDE="$(echo "$KEEP" | tr -s '\n' ' ')" 565*eda14cbcSMatt Macyelse 566*eda14cbcSMatt Macy __ZFS_POOL_EXCLUDE="$(echo "$KEEP" | sed ':a;N;s/\n/ /g;ba')" 567*eda14cbcSMatt Macyfi 568*eda14cbcSMatt Macy 569*eda14cbcSMatt Macy. "$STF_SUITE/include/default.cfg" 570*eda14cbcSMatt Macy 571*eda14cbcSMatt Macymsg 572*eda14cbcSMatt Macymsg "--- Configuration ---" 573*eda14cbcSMatt Macymsg "Runfiles: $RUNFILES" 574*eda14cbcSMatt Macymsg "STF_TOOLS: $STF_TOOLS" 575*eda14cbcSMatt Macymsg "STF_SUITE: $STF_SUITE" 576*eda14cbcSMatt Macymsg "STF_PATH: $STF_PATH" 577*eda14cbcSMatt Macy 578*eda14cbcSMatt Macy# 579*eda14cbcSMatt Macy# No DISKS have been provided so a basic file or loopback based devices 580*eda14cbcSMatt Macy# must be created for the test suite to use. 581*eda14cbcSMatt Macy# 582*eda14cbcSMatt Macyif [ -z "${DISKS}" ]; then 583*eda14cbcSMatt Macy # 584*eda14cbcSMatt Macy # Create sparse files for the test suite. These may be used 585*eda14cbcSMatt Macy # directory or have loopback devices layered on them. 586*eda14cbcSMatt Macy # 587*eda14cbcSMatt Macy for TEST_FILE in ${FILES}; do 588*eda14cbcSMatt Macy [ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}" 589*eda14cbcSMatt Macy truncate -s "${FILESIZE}" "${TEST_FILE}" || 590*eda14cbcSMatt Macy fail "Failed creating: ${TEST_FILE} ($?)" 591*eda14cbcSMatt Macy done 592*eda14cbcSMatt Macy 593*eda14cbcSMatt Macy # 594*eda14cbcSMatt Macy # If requested setup loopback devices backed by the sparse files. 595*eda14cbcSMatt Macy # 596*eda14cbcSMatt Macy if [ "$LOOPBACK" = "yes" ]; then 597*eda14cbcSMatt Macy test -x "$LOSETUP" || fail "$LOSETUP utility must be installed" 598*eda14cbcSMatt Macy 599*eda14cbcSMatt Macy for TEST_FILE in ${FILES}; do 600*eda14cbcSMatt Macy if [ "$UNAME" = "FreeBSD" ] ; then 601*eda14cbcSMatt Macy MDDEVICE=$(sudo "${LOSETUP}" -a -t vnode -f "${TEST_FILE}") 602*eda14cbcSMatt Macy if [ -z "$MDDEVICE" ] ; then 603*eda14cbcSMatt Macy fail "Failed: ${TEST_FILE} -> loopback" 604*eda14cbcSMatt Macy fi 605*eda14cbcSMatt Macy DISKS="$DISKS $MDDEVICE" 606*eda14cbcSMatt Macy LOOPBACKS="$LOOPBACKS $MDDEVICE" 607*eda14cbcSMatt Macy else 608*eda14cbcSMatt Macy TEST_LOOPBACK=$(sudo "${LOSETUP}" -f) 609*eda14cbcSMatt Macy sudo "${LOSETUP}" "${TEST_LOOPBACK}" "${TEST_FILE}" || 610*eda14cbcSMatt Macy fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}" 611*eda14cbcSMatt Macy BASELOOPBACK=$(basename "$TEST_LOOPBACK") 612*eda14cbcSMatt Macy DISKS="$DISKS $BASELOOPBACK" 613*eda14cbcSMatt Macy LOOPBACKS="$LOOPBACKS $TEST_LOOPBACK" 614*eda14cbcSMatt Macy fi 615*eda14cbcSMatt Macy done 616*eda14cbcSMatt Macy DISKS=${DISKS# } 617*eda14cbcSMatt Macy LOOPBACKS=${LOOPBACKS# } 618*eda14cbcSMatt Macy else 619*eda14cbcSMatt Macy DISKS="$FILES" 620*eda14cbcSMatt Macy fi 621*eda14cbcSMatt Macyfi 622*eda14cbcSMatt Macy 623*eda14cbcSMatt MacyNUM_DISKS=$(echo "${DISKS}" | awk '{print NF}') 624*eda14cbcSMatt Macy[ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)" 625*eda14cbcSMatt Macy 626*eda14cbcSMatt Macy# 627*eda14cbcSMatt Macy# Disable SELinux until the ZFS Test Suite has been updated accordingly. 628*eda14cbcSMatt Macy# 629*eda14cbcSMatt Macyif [ -x "$STF_PATH/setenforce" ]; then 630*eda14cbcSMatt Macy sudo setenforce permissive >/dev/null 2>&1 631*eda14cbcSMatt Macyfi 632*eda14cbcSMatt Macy 633*eda14cbcSMatt Macy# 634*eda14cbcSMatt Macy# Enable internal ZFS debug log and clear it. 635*eda14cbcSMatt Macy# 636*eda14cbcSMatt Macyif [ -e /sys/module/zfs/parameters/zfs_dbgmsg_enable ]; then 637*eda14cbcSMatt Macy sudo /bin/sh -c "echo 1 >/sys/module/zfs/parameters/zfs_dbgmsg_enable" 638*eda14cbcSMatt Macy sudo /bin/sh -c "echo 0 >/proc/spl/kstat/zfs/dbgmsg" 639*eda14cbcSMatt Macyfi 640*eda14cbcSMatt Macy 641*eda14cbcSMatt Macymsg "FILEDIR: $FILEDIR" 642*eda14cbcSMatt Macymsg "FILES: $FILES" 643*eda14cbcSMatt Macymsg "LOOPBACKS: $LOOPBACKS" 644*eda14cbcSMatt Macymsg "DISKS: $DISKS" 645*eda14cbcSMatt Macymsg "NUM_DISKS: $NUM_DISKS" 646*eda14cbcSMatt Macymsg "FILESIZE: $FILESIZE" 647*eda14cbcSMatt Macymsg "ITERATIONS: $ITERATIONS" 648*eda14cbcSMatt Macymsg "TAGS: $TAGS" 649*eda14cbcSMatt Macymsg "STACK_TRACER: $STACK_TRACER" 650*eda14cbcSMatt Macymsg "Keep pool(s): $KEEP" 651*eda14cbcSMatt Macymsg "Missing util(s): $STF_MISSING_BIN" 652*eda14cbcSMatt Macymsg "" 653*eda14cbcSMatt Macy 654*eda14cbcSMatt Macyexport STF_TOOLS 655*eda14cbcSMatt Macyexport STF_SUITE 656*eda14cbcSMatt Macyexport STF_PATH 657*eda14cbcSMatt Macyexport DISKS 658*eda14cbcSMatt Macyexport FILEDIR 659*eda14cbcSMatt Macyexport KEEP 660*eda14cbcSMatt Macyexport __ZFS_POOL_EXCLUDE 661*eda14cbcSMatt Macyexport TESTFAIL_CALLBACKS 662*eda14cbcSMatt Macyexport PATH=$STF_PATH 663*eda14cbcSMatt Macy 664*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then 665*eda14cbcSMatt Macy mkdir -p "$FILEDIR" || true 666*eda14cbcSMatt Macy RESULTS_FILE=$(mktemp -u "${FILEDIR}/zts-results.XXXX") 667*eda14cbcSMatt Macy REPORT_FILE=$(mktemp -u "${FILEDIR}/zts-report.XXXX") 668*eda14cbcSMatt Macyelse 669*eda14cbcSMatt Macy RESULTS_FILE=$(mktemp -u -t zts-results.XXXX -p "$FILEDIR") 670*eda14cbcSMatt Macy REPORT_FILE=$(mktemp -u -t zts-report.XXXX -p "$FILEDIR") 671*eda14cbcSMatt Macyfi 672*eda14cbcSMatt Macy 673*eda14cbcSMatt Macy# 674*eda14cbcSMatt Macy# Run all the tests as specified. 675*eda14cbcSMatt Macy# 676*eda14cbcSMatt Macymsg "${TEST_RUNNER} ${QUIET:+-q}" \ 677*eda14cbcSMatt Macy "-c \"${RUNFILES}\"" \ 678*eda14cbcSMatt Macy "-T \"${TAGS}\"" \ 679*eda14cbcSMatt Macy "-i \"${STF_SUITE}\"" \ 680*eda14cbcSMatt Macy "-I \"${ITERATIONS}\"" 681*eda14cbcSMatt Macy${TEST_RUNNER} ${QUIET:+-q} \ 682*eda14cbcSMatt Macy -c "${RUNFILES}" \ 683*eda14cbcSMatt Macy -T "${TAGS}" \ 684*eda14cbcSMatt Macy -i "${STF_SUITE}" \ 685*eda14cbcSMatt Macy -I "${ITERATIONS}" \ 686*eda14cbcSMatt Macy 2>&1 | tee "$RESULTS_FILE" 687*eda14cbcSMatt Macy 688*eda14cbcSMatt Macy# 689*eda14cbcSMatt Macy# Analyze the results. 690*eda14cbcSMatt Macy# 691*eda14cbcSMatt Macy${ZTS_REPORT} "$RESULTS_FILE" >"$REPORT_FILE" 692*eda14cbcSMatt MacyRESULT=$? 693*eda14cbcSMatt Macycat "$REPORT_FILE" 694*eda14cbcSMatt Macy 695*eda14cbcSMatt MacyRESULTS_DIR=$(awk '/^Log directory/ { print $3 }' "$RESULTS_FILE") 696*eda14cbcSMatt Macyif [ -d "$RESULTS_DIR" ]; then 697*eda14cbcSMatt Macy cat "$RESULTS_FILE" "$REPORT_FILE" >"$RESULTS_DIR/results" 698*eda14cbcSMatt Macyfi 699*eda14cbcSMatt Macy 700*eda14cbcSMatt Macyrm -f "$RESULTS_FILE" "$REPORT_FILE" 701*eda14cbcSMatt Macy 702*eda14cbcSMatt Macyif [ -n "$SINGLETEST" ]; then 703*eda14cbcSMatt Macy rm -f "$RUNFILES" >/dev/null 2>&1 704*eda14cbcSMatt Macyfi 705*eda14cbcSMatt Macy 706*eda14cbcSMatt Macyexit ${RESULT} 707