#set -x
export LANG=en_US
-export EJOURNAL=${EJOURNAL:-""}
export REFORMAT=${REFORMAT:-""}
export WRITECONF=${WRITECONF:-""}
export VERBOSE=${VERBOSE:-false}
-export CATASTROPHE=${CATASTROPHE:-/proc/sys/lnet/catastrophe}
export GSS=false
export GSS_KRB5=false
export GSS_PIPEFS=false
export LOAD_LLOOP=${LOAD_LLOOP:-false}
#export PDSH="pdsh -S -Rssh -w"
+export MOUNT_CMD=${MOUNT_CMD:-"mount -t lustre"}
+export UMOUNT=${UMOUNT:-"umount -d"}
+# sles12 umount has a issue with -d option
+[ -e /etc/SuSE-release ] && grep -w VERSION /etc/SuSE-release | grep -wq 12 && {
+ export UMOUNT="umount"
+}
# function used by scripts run on remote nodes
LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
[ -z "$MODPROBECONF" -a -f /etc/modprobe.conf ] &&
MODPROBECONF=/etc/modprobe.conf
+sanitize_parameters() {
+ for i in DIR DIR1 DIR2 MOUNT MOUNT1 MOUNT2
+ do
+ local path=${!i}
+ if [ -d "$path" ]; then
+ eval export $i=$(echo $path | sed -r 's/\/+$//g')
+ fi
+ done
+}
assert_DIR () {
- local failed=""
- [[ $DIR/ = $MOUNT/* ]] || \
- { failed=1 && echo "DIR=$DIR not in $MOUNT. Aborting."; }
- [[ $DIR1/ = $MOUNT1/* ]] || \
- { failed=1 && echo "DIR1=$DIR1 not in $MOUNT1. Aborting."; }
- [[ $DIR2/ = $MOUNT2/* ]] || \
- { failed=1 && echo "DIR2=$DIR2 not in $MOUNT2. Aborting"; }
+ local failed=""
+ [[ $DIR/ = $MOUNT/* ]] ||
+ { failed=1 && echo "DIR=$DIR not in $MOUNT. Aborting."; }
+ [[ $DIR1/ = $MOUNT1/* ]] ||
+ { failed=1 && echo "DIR1=$DIR1 not in $MOUNT1. Aborting."; }
+ [[ $DIR2/ = $MOUNT2/* ]] ||
+ { failed=1 && echo "DIR2=$DIR2 not in $MOUNT2. Aborting"; }
- [ -n "$failed" ] && exit 99 || true
+ [ -n "$failed" ] && exit 99 || true
}
usage() {
print_summary () {
trap 0
- [ "$TESTSUITE" == "lfsck" ] && return 0
+ [ -z "$DEFAULT_SUITES"] && return 0
[ -n "$ONLY" ] && echo "WARNING: ONLY is set to $(echo $ONLY)"
local details
local form="%-13s %-17s %-9s %s %s\n"
local total=
local status=Unfinished
if [ -f $log ]; then
- skipped=$(grep excluded $log | awk '{ printf " %s", $3 }' | sed 's/test_//g')
- slow=$(egrep "^PASS|^FAIL" $log | tr -d "("| sed s/s\)$//g | sort -nr -k 3 | head -5 | awk '{ print $2":"$3"s" }')
- total=$(grep duration $log | awk '{ print $2}')
- if [ "${!O}" = "done" ]; then
- status=Done
- fi
- if $DDETAILS; then
- local durations=$(egrep "^PASS|^FAIL" $log | tr -d "("| sed s/s\)$//g | awk '{ print $2":"$3"|" }')
- details=$(printf "%s\n%s %s %s\n" "$details" "DDETAILS" "$O" "$(echo $durations)")
- fi
+ skipped=$(grep excluded $log | awk '{ printf " %s", $3 }' |
+ sed 's/test_//g')
+ slow=$(egrep "^PASS|^FAIL" $log | tr -d "("| sed s/s\)$//g |
+ sort -nr -k 3 | head -n5 | awk '{ print $2":"$3"s" }')
+ total=$(grep duration $log | awk '{ print $2 }')
+ if [ "${!O}" = "done" ]; then
+ status=Done
+ fi
+ if $DDETAILS; then
+ local durations=$(egrep "^PASS|^FAIL" $log |
+ tr -d "("| sed s/s\)$//g |
+ awk '{ print $2":"$3"|" }')
+ details=$(printf "%s\n%s %s %s\n" "$details" \
+ "DDETAILS" "$O" "$(echo $durations)")
+ fi
fi
printf "$form" $status "$O" "${total}" "E=$skipped"
printf "$form" "-" "-" "-" "S=$(echo $slow)"
fi
fi
- export LFSCK_BIN=${LFSCK_BIN:-lfsck}
- export LFSCK_ALWAYS=${LFSCK_ALWAYS:-"no"} # check fs after each test suite
- export FSCK_MAX_ERR=4 # File system errors left uncorrected
+ export LFSCK_ALWAYS=${LFSCK_ALWAYS:-"no"} # check fs after test suite
+ export FSCK_MAX_ERR=4 # File system errors left uncorrected
export ZFS=${ZFS:-zfs}
export ZPOOL=${ZPOOL:-zpool}
[ ! -f "$LST" ] && export LST=$(which lst)
export SGPDDSURVEY=${SGPDDSURVEY:-"$LUSTRE/../lustre-iokit/sgpdd-survey/sgpdd-survey")}
[ ! -f "$SGPDDSURVEY" ] && export SGPDDSURVEY=$(which sgpdd-survey)
+ export MCREATE=${MCREATE:-mcreate}
# Ubuntu, at least, has a truncate command in /usr/bin
# so fully path our truncate command.
export TRUNCATE=${TRUNCATE:-$LUSTRE/tests/truncate}
+ export FSX=${FSX:-$LUSTRE/tests/fsx}
export MDSRATE=${MDSRATE:-"$LUSTRE/tests/mpi/mdsrate"}
[ ! -f "$MDSRATE" ] && export MDSRATE=$(which mdsrate 2> /dev/null)
if ! echo $PATH | grep -q $LUSTRE/tests/racer; then
export LFS_MIGRATE=${LFS_MIGRATE:-$LUSTRE/scripts/lfs_migrate}
[ ! -f "$LFS_MIGRATE" ] &&
export LFS_MIGRATE=$(which lfs_migrate 2> /dev/null)
+ export LR_READER=${LR_READER:-"$LUSTRE/utils/lr_reader"}
+ [ ! -f "$LR_READER" ] && export LR_READER=$(which lr_reader 2> /dev/null)
+ [ -z "$LR_READER" ] && export LR_READER="/usr/sbin/lr_reader"
export NAME=${NAME:-local}
export LGSSD=${LGSSD:-"$LUSTRE/utils/gss/lgssd"}
[ "$GSS_PIPEFS" = "true" ] && [ ! -f "$LGSSD" ] && \
export SHUTDOWN_ATTEMPTS=${SHUTDOWN_ATTEMPTS:-3}
export OSD_TRACK_DECLARES_LBUG=${OSD_TRACK_DECLARES_LBUG:-"yes"}
- # command line
+ # command line
- while getopts "rvwf:" opt $*; do
- case $opt in
- f) CONFIG=$OPTARG;;
- r) REFORMAT=--reformat;;
- v) VERBOSE=true;;
- w) WRITECONF=writeconf;;
- \?) usage;;
- esac
- done
+ while getopts "rvwf:" opt $*; do
+ case $opt in
+ f) CONFIG=$OPTARG;;
+ r) REFORMAT=yes;;
+ v) VERBOSE=true;;
+ w) WRITECONF=writeconf;;
+ \?) usage;;
+ esac
+ done
- shift $((OPTIND - 1))
- ONLY=${ONLY:-$*}
+ shift $((OPTIND - 1))
+ ONLY=${ONLY:-$*}
# print the durations of each test if "true"
DDETAILS=${DDETAILS:-false}
if ! $RPC_MODE; then
rm -f $TMP/*active
fi
+
+ export TF_FAIL=${TF_FAIL:-$TMP/tf.fail}
}
check_cpt_number() {
fi
}
+# Return a numeric version code based on a version string. The version
+# code is useful for comparison two version strings to see which is newer.
version_code() {
- # split arguments like "1.8.6-wc3" into "1", "8", "6", "wc3"
- eval set -- $(tr "[:punct:]" " " <<< $*)
+ # split arguments like "1.8.6-wc3" into "1", "8", "6", "wc3"
+ eval set -- $(tr "[:punct:]" " " <<< $*)
- echo -n "$((($1 << 16) | ($2 << 8) | $3))"
+ echo -n "$((($1 << 16) | ($2 << 8) | $3))"
}
-export LINUX_VERSION=$(uname -r | sed -e "s/[-.]/ /3" -e "s/ .*//")
+export LINUX_VERSION=$(uname -r | sed -e "s/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/")
export LINUX_VERSION_CODE=$(version_code ${LINUX_VERSION//\./ })
+# Report the Lustre build version string (e.g. 1.8.7.3 or 2.4.1).
+#
+# usage: lustre_build_version
+#
+# All Lustre versions support "lctl get_param" to report the version of the
+# code running in the kernel (what our tests are interested in), but it
+# doesn't work without modules loaded. If that fails, use "lctl version"
+# instead, which is easy to parse and works without the kernel modules,
+# but was only added in 2.6.50. If that also fails, fall back to calling
+# "lctl lustre_build_version" which prints either (or both) the userspace
+# and kernel build versions, but is deprecated and should eventually be
+# removed.
+#
+# output: prints version string to stdout in dotted-decimal format
+lustre_build_version() {
+ local facet=${1:-client}
+
+ # lustre: 2.6.52
+ # kernel: patchless_client
+ # build: v2_6_92_0-gadb3ee4-2.6.32-431.29.2.el6_lustre.x86_64
+ local VER=$(do_facet $facet $LCTL get_param -n version 2> /dev/null |
+ awk '/lustre: / { print $2 }')
+ # lctl 2.6.50
+ [ -z "$VER" ] && VER=$(do_facet $facet $LCTL --version 2>/dev/null |
+ awk '{ print $2 }')
+ # Lustre version: 2.5.3-gfcfd782-CHANGED-2.6.32.26-175.fc12.x86_64
+ # lctl version: 2.5.3-gfcfd782-CHANGED-2.6.32.26-175.fc12.x86_64
+ [ -z "$VER" ] && VER=$(do_facet $facet $LCTL lustre_build_version |
+ awk '/version:/ { print $3; exit; }')
+ sed -e 's/^v//' -e 's/-.*//' -e 's/_/./g' <<<$VER
+}
+
+# Report the Lustre numeric build version code for the supplied facet.
+lustre_version_code() {
+ version_code $(lustre_build_version $1)
+}
+
module_loaded () {
- /sbin/lsmod | grep -q "^\<$1\>"
+ /sbin/lsmod | grep -q "^\<$1\>"
}
# Load a module on the system where this is running.
#
-# Synopsis: load_module module_name [module arguments for insmod/modprobe]
+# usage: load_module module_name [module arguments for insmod/modprobe]
#
# If module arguments are not given but MODOPTS_<MODULE> is set, then its value
# will be used as the arguments. Otherwise arguments will be obtained from
EXT=".ko"
module=$1
shift
- BASE=`basename $module $EXT`
+ BASE=$(basename $module $EXT)
module_loaded ${BASE} && return
- # If no module arguments were passed, get them from $MODOPTS_<MODULE>, else from
- # modprobe.conf
+ # If no module arguments were passed, get them from $MODOPTS_<MODULE>,
+ # else from modprobe.conf
if [ $# -eq 0 ]; then
# $MODOPTS_<MODULE>; we could use associative arrays, but that's not in
# Bash until 4.x, so we resort to eval.
[ $# -gt 0 ] && echo "${module} options: '$*'"
- # Note that insmod will ignore anything in modprobe.conf, which is why we're
- # passing options on the command-line.
- if [ "$BASE" == "lnet_selftest" ] && \
- [ -f ${LUSTRE}/../lnet/selftest/${module}${EXT} ]; then
- insmod ${LUSTRE}/../lnet/selftest/${module}${EXT}
- elif [ -f ${LUSTRE}/${module}${EXT} ]; then
- insmod ${LUSTRE}/${module}${EXT} "$@"
- else
- # must be testing a "make install" or "rpm" installation
- # note failed to load ptlrpc_gss is considered not fatal
- if [ "$BASE" == "ptlrpc_gss" ]; then
- modprobe $BASE "$@" 2>/dev/null || echo "gss/krb5 is not supported"
- else
- modprobe $BASE "$@"
- fi
- fi
+ # Note that insmod will ignore anything in modprobe.conf, which is why
+ # we're passing options on the command-line.
+ if [[ "$BASE" == "lnet_selftest" ]] &&
+ [[ -f ${LUSTRE}/../lnet/selftest/${module}${EXT} ]]; then
+ insmod ${LUSTRE}/../lnet/selftest/${module}${EXT}
+ elif [[ -f ${LUSTRE}/${module}${EXT} ]]; then
+ [[ "$BASE" != "ptlrpc_gss" ]] || modprobe sunrpc
+ insmod ${LUSTRE}/${module}${EXT} "$@"
+ else
+ # must be testing a "make install" or "rpm" installation
+ # note failed to load ptlrpc_gss is considered not fatal
+ if [[ "$BASE" == "ptlrpc_gss" ]]; then
+ modprobe $BASE "$@" 2>/dev/null ||
+ echo "gss/krb5 is not supported"
+ else
+ modprobe $BASE "$@"
+ fi
+ fi
}
llite_lloop_enabled() {
[ "$PTLDEBUG" ] && lctl set_param debug="$PTLDEBUG"
[ "$SUBSYSTEM" ] && lctl set_param subsystem_debug="${SUBSYSTEM# }"
load_module ../lnet/lnet/lnet
+ case $NETTYPE in
+ o2ib)
+ LNETLND="o2iblnd/ko2iblnd"
+ ;;
+ *)
+ ;;
+ esac
LNETLND=${LNETLND:-"socklnd/ksocklnd"}
load_module ../lnet/klnds/$LNETLND
load_module obdclass/obdclass
load_module lov/lov
load_module mgc/mgc
load_module obdecho/obdecho
- if ! client_only; then
- SYMLIST=/proc/kallsyms
- grep -q crc16 $SYMLIST || { modprobe crc16 2>/dev/null || true; }
- grep -q -w jbd $SYMLIST || { modprobe jbd 2>/dev/null || true; }
- grep -q -w jbd2 $SYMLIST || { modprobe jbd2 2>/dev/null || true; }
+ if ! client_only; then
+ SYMLIST=/proc/kallsyms
+ grep -q crc16 $SYMLIST ||
+ { modprobe crc16 2>/dev/null || true; }
+ grep -q -w jbd2 $SYMLIST ||
+ { modprobe jbd2 2>/dev/null || true; }
load_module lfsck/lfsck
- [ "$LQUOTA" != "no" ] && load_module quota/lquota $LQUOTAOPTS
+ [ "$LQUOTA" != "no" ] &&
+ load_module quota/lquota $LQUOTAOPTS
if [[ $(node_fstypes $HOSTNAME) == *zfs* ]]; then
modprobe zfs
load_module osd-zfs/osd_zfs
if [[ $(node_fstypes $HOSTNAME) == *ldiskfs* ]]; then
grep -q exportfs_decode_fh $SYMLIST ||
{ modprobe exportfs 2> /dev/null || true; }
+ grep -q -w mbcache $SYMLIST ||
+ { modprobe mbcache 2>/dev/null || true; }
load_module ../ldiskfs/ldiskfs
load_module osd-ldiskfs/osd_ldiskfs
fi
load_module osp/osp
load_module ofd/ofd
load_module osp/osp
- fi
-
-
- load_module llite/lustre
- llite_lloop_enabled && load_module llite/llite_lloop
- [ -d /r ] && OGDB=${OGDB:-"/r/tmp"}
- OGDB=${OGDB:-$TMP}
- rm -f $OGDB/ogdb-$HOSTNAME
- $LCTL modules > $OGDB/ogdb-$HOSTNAME
+ fi
- # 'mount' doesn't look in $PATH, just sbin
- if [ -f $LUSTRE/utils/mount.lustre ] && \
- ! grep -qe "/sbin/mount\.lustre " /proc/mounts; then
- [ ! -f /sbin/mount.lustre ] && touch /sbin/mount.lustre
- mount --bind $LUSTRE/utils/mount.lustre /sbin/mount.lustre || true
- fi
+ load_module llite/lustre
+ llite_lloop_enabled && load_module llite/llite_lloop
+ [ -d /r ] && OGDB=${OGDB:-"/r/tmp"}
+ OGDB=${OGDB:-$TMP}
+ rm -f $OGDB/ogdb-$HOSTNAME
+ $LCTL modules > $OGDB/ogdb-$HOSTNAME
+
+ # 'mount' doesn't look in $PATH, just sbin
+ local mount_lustre=$LUSTRE/utils/mount.lustre
+ if [ -f $mount_lustre ]; then
+ local sbin_mount=$(readlink -f /sbin)/mount.lustre
+ if grep -qw "$sbin_mount" /proc/mounts; then
+ cmp -s $mount_lustre $sbin_mount || umount $sbin_mount
+ fi
+ if ! grep -qw "$sbin_mount" /proc/mounts; then
+ [ ! -f "$sbin_mount" ] && touch "$sbin_mount"
+ if [ ! -s "$sbin_mount" -a -w "$sbin_mount" ]; then
+ cat <<- EOF > "$sbin_mount"
+ #!/bin/sh
+ #STUB MARK
+ echo "This $sbin_mount just a mountpoint." 1>&2
+ echo "It is never supposed to be run." 1>&2
+ logger -p emerg -- "using stub $sbin_mount $@"
+ exit 1
+ EOF
+ chmod a+x $sbin_mount
+ fi
+ mount --bind $mount_lustre $sbin_mount ||
+ error "can't bind $mount_lustre to $sbin_mount"
+ fi
+ fi
}
load_modules () {
fi
fi
- if grep -qe "/sbin/mount\.lustre" /proc/mounts; then
- umount /sbin/mount.lustre || true
- [ -w /sbin/mount.lustre -a ! -s /sbin/mount.lustre ] && \
- rm -f /sbin/mount.lustre || true
- fi
+ local sbin_mount=$(readlink -f /sbin)/mount.lustre
+ if grep -qe "$sbin_mount " /proc/mounts; then
+ umount $sbin_mount || true
+ [ -s $sbin_mount ] && ! grep -q "STUB MARK" $sbin_mount ||
+ rm -f $sbin_mount
+ fi
- check_mem_leak || return 254
+ check_mem_leak || return 254
- echo "modules unloaded."
- return 0
+ echo "modules unloaded."
+ return 0
}
fs_log_size() {
fi
local list=$(comma_list $(mdts_nodes))
-
echo "Starting gss daemon on mds: $list"
do_nodes $list "$LSVCGSSD -v" || return 1
if $GSS_PIPEFS; then
stop_gss_daemons() {
local list=$(comma_list $(mdts_nodes))
-
+
send_sigint $list lsvcgssd lgssd
list=$(comma_list $(osts_nodes))
module_loaded ptlrpc_gss ||
error_exit "init_gss : GSS=$GSS, but gss/krb5 is not supported!"
fi
- start_gss_daemons || error_exit "start gss daemon failed! rc=$?"
+ if $GSS_KRB5; then
+ start_gss_daemons || error_exit "start gss daemon failed! rc=$?"
+ fi
if [ -n "$LGSS_KEYRING_DEBUG" ]; then
- echo $LGSS_KEYRING_DEBUG > /proc/fs/lustre/sptlrpc/gss/lgss_keyring/debug_level
+ lctl set_param -n \
+ sptlrpc.gss.lgss_keyring.debug_level=$LGSS_KEYRING_DEBUG
fi
fi
}
facet_number() {
local facet=$1
- if [ $facet == mgs ]; then
+ if [ $facet == mgs ] || [ $facet == client ]; then
return 1
fi
echo -n $fstypes
}
+facet_index() {
+ local facet=$1
+ local num=$(facet_number $facet)
+ local index
+
+ if [[ $(facet_type $facet) = OST ]]; then
+ index=OSTINDEX${num}
+ if [[ -n "${!index}" ]]; then
+ echo -n ${!index}
+ return
+ fi
+
+ index=${OST_INDICES[num - 1]}
+ fi
+
+ [[ -n "$index" ]] || index=$((num - 1))
+ echo -n $index
+}
+
devicelabel() {
local facet=$1
local dev=$2
local name=$3
do_nodes $nodes "$LCTL get_param -n obdfilter.$device.$name \
- osd-*.$device.$name 2>&1" | grep -v 'Found no match'
+ osd-*.$device.$name 2>&1" | grep -v 'error:'
}
set_osd_param() {
local value=$4
do_nodes $nodes "$LCTL set_param -n obdfilter.$device.$name=$value \
- osd-*.$device.$name=$value 2>&1" | grep -v 'Found no match'
+ osd-*.$device.$name=$value 2>&1" | grep -v 'error:'
}
set_debug_size () {
local opt=${facet}_opt
local mntpt=$(facet_mntpt $facet)
local opts="${!opt} $@"
+ local fstype=$(facet_fstype $facet)
+ local devicelabel
+
+ module_loaded lustre || load_modules
if [ $(facet_fstype $facet) == ldiskfs ] &&
! do_facet $facet test -b ${!dev}; then
import_zpool $facet || return ${PIPESTATUS[0]}
fi
+ case $fstype in
+ ldiskfs)
+ devicelabel=$(do_facet ${facet} "$E2LABEL ${!dev}");;
+ zfs)
+ devicelabel=$(do_facet ${facet} "$ZFS get -H -o value \
+ lustre:svname ${!dev}");;
+ *)
+ error "unknown fstype!";;
+ esac
+
echo "Starting ${facet}: $opts ${!dev} $mntpt"
# for testing LU-482 error handling in mount_facets() and test_0a()
if [ -f $TMP/test-lu482-trigger ]; then
RC=2
else
- do_facet ${facet} "mkdir -p $mntpt; mount -t lustre $opts \
+ do_facet ${facet} "mkdir -p $mntpt; $MOUNT_CMD $opts \
${!dev} $mntpt"
RC=${PIPESTATUS[0]}
fi
+
if [ $RC -ne 0 ]; then
echo "Start of ${!dev} on ${facet} failed ${RC}"
- else
- set_default_debug_facet $facet
+ return $RC
+ fi
- label=$(devicelabel ${facet} ${!dev})
- [ -z "$label" ] && echo no label for ${!dev} && exit 1
- eval export ${facet}_svc=${label}
- echo Started ${label}
- fi
- return $RC
+ health=$(do_facet ${facet} "$LCTL get_param -n health_check")
+ if [[ "$health" != "healthy" ]]; then
+ error "$facet is in a unhealthy state"
+ fi
+
+ set_default_debug_facet $facet
+
+ if [[ $facet == mds* ]]; then
+ do_facet $facet \
+ lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 2>/dev/null
+ fi
+
+ if [[ $opts =~ .*nosvc.* ]]; then
+ echo "Start ${!dev} without service"
+ else
+
+ case $fstype in
+ ldiskfs)
+ wait_update_facet ${facet} "$E2LABEL ${!dev} \
+ 2>/dev/null | grep -E ':[a-zA-Z]{3}[0-9]{4}'" \
+ "" || error "${!dev} failed to initialize!";;
+ zfs)
+ wait_update_facet ${facet} "$ZFS get -H -o value \
+ lustre:svname ${!dev} 2>/dev/null | \
+ grep -E ':[a-zA-Z]{3}[0-9]{4}'" "" ||
+ error "${!dev} failed to initialize!";;
+
+ *)
+ error "unknown fstype!";;
+ esac
+ fi
+
+ # commit the device label change to disk
+ if [[ $devicelabel =~ (:[a-zA-Z]{3}[0-9]{4}) ]]; then
+ do_facet $facet "sync; sync; sync"
+ fi
+
+
+ label=$(devicelabel ${facet} ${!dev})
+ [ -z "$label" ] && echo no label for ${!dev} && exit 1
+ eval export ${facet}_svc=${label}
+ echo Started ${label}
+
+ return $RC
}
# start facet device options
start() {
- local facet=$1
- shift
- local device=$1
- shift
- eval export ${facet}_dev=${device}
- eval export ${facet}_opt=\"$@\"
+ local facet=$1
+ shift
+ local device=$1
+ shift
+ eval export ${facet}_dev=${device}
+ eval export ${facet}_opt=\"$@\"
- local varname=${facet}failover_dev
- if [ -n "${!varname}" ] ; then
- eval export ${facet}failover_dev=${!varname}
- else
- eval export ${facet}failover_dev=$device
- fi
+ local varname=${facet}failover_dev
+ if [ -n "${!varname}" ] ; then
+ eval export ${facet}failover_dev=${!varname}
+ else
+ eval export ${facet}failover_dev=$device
+ fi
- local mntpt=$(facet_mntpt $facet)
- do_facet ${facet} mkdir -p $mntpt
- eval export ${facet}_MOUNT=$mntpt
- mount_facet ${facet}
- RC=$?
- return $RC
+ local mntpt=$(facet_mntpt $facet)
+ do_facet ${facet} mkdir -p $mntpt
+ eval export ${facet}_MOUNT=$mntpt
+ mount_facet ${facet}
+ RC=$?
+
+ if [[ $facet == mds* ]]; then
+ do_facet $facet \
+ lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 \
+ 2>/dev/null
+ fi
+
+ return $RC
}
stop() {
running=$(do_facet ${facet} "grep -c $mntpt' ' /proc/mounts") || true
if [ ${running} -ne 0 ]; then
echo "Stopping $mntpt (opts:$@) on $HOST"
- do_facet ${facet} umount -d $@ $mntpt
+ do_facet ${facet} $UMOUNT $@ $mntpt
fi
# umount should block, but we should wait for unrelated obd's
rc=$?
do_nodes $(comma_list $(osts_nodes)) \
lctl get_param obdfilter.${fsname}-OST*.quota_type || rc=$?
- return $rc
-}
-
-# XXX This function is kept for interoperability with old server (< 2.3.50),
-# it should be removed whenever we drop the interoperability for such
-# server.
-restore_quota_old() {
- local mntpt=${1:-$MOUNT}
- local quota_type=$(quota_type $FSNAME | grep MDT | cut -d "=" -f2)
- if [ ! "$old_QUOTA_TYPE" ] ||
- [ "$quota_type" = "$old_QUOTA_TYPE" ]; then
- return
- fi
- quota_save_version $old_QUOTA_TYPE
-}
-
-# XXX This function is kept for interoperability with old server (< 2.3.50),
-# it should be removed whenever we drop the interoperability for such
-# server.
-setup_quota_old(){
- local mntpt=$1
-
- # no quota enforcement for now and accounting works out of the box
- return
-
- # We need save the original quota_type params, and restore them after testing
-
- # Suppose that quota type the same on mds and ost
- local quota_type=$(quota_type | grep MDT | cut -d "=" -f2)
- [ ${PIPESTATUS[0]} -eq 0 ] || error "quota_type failed!"
- echo "[HOST:$HOSTNAME] [old_quota_type:$quota_type] [new_quota_type:$QUOTA_TYPE]"
- if [ "$quota_type" != "$QUOTA_TYPE" ]; then
- export old_QUOTA_TYPE=$quota_type
- quota_save_version $QUOTA_TYPE
- else
- qtype=$(tr -c -d "ug" <<< $QUOTA_TYPE)
- $LFS quotacheck -$qtype $mntpt || error "quotacheck has failed for $type"
- fi
-
- local quota_usrs=$QUOTA_USERS
-
- # get_filesystem_size
- local disksz=$(lfs_df $mntpt | grep "summary" | awk '{print $2}')
- local blk_soft=$((disksz + 1024))
- local blk_hard=$((blk_soft + blk_soft / 20)) # Go 5% over
-
- local Inodes=$(lfs_df -i $mntpt | grep "summary" | awk '{print $2}')
- local i_soft=$Inodes
- local i_hard=$((i_soft + i_soft / 20))
-
- echo "Total disk size: $disksz block-softlimit: $blk_soft block-hardlimit:
- $blk_hard inode-softlimit: $i_soft inode-hardlimit: $i_hard"
-
- local cmd
- for usr in $quota_usrs; do
- echo "Setting up quota on $HOSTNAME:$mntpt for $usr..."
- for type in u g; do
- cmd="$LFS setquota -$type $usr -b $blk_soft -B $blk_hard -i $i_soft -I $i_hard $mntpt"
- echo "+ $cmd"
- eval $cmd || error "$cmd FAILED!"
- done
- # display the quota status
- echo "Quota settings for $usr : "
- $LFS quota -v -u $usr $mntpt || true
- done
+ return $rc
}
# get mdt quota type
# restore old quota type settings
restore_quota() {
- if [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.50) ]; then
- restore_quota_old
- return
- fi
-
if [ "$old_MDT_QUOTA_TYPE" ]; then
do_facet mgs $LCTL conf_param \
$FSNAME.quota.mdt=$old_MDT_QUOTA_TYPE
}
setup_quota(){
- if [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.50) ]; then
- setup_quota_old $1
- return
- fi
-
local mntpt=$1
# save old quota type & set new quota type
}
zconf_mount() {
- local client=$1
- local mnt=$2
- local OPTIONS=${3:-$MOUNTOPT}
-
- local device=$MGSNID:/$FSNAME
- if [ -z "$mnt" -o -z "$FSNAME" ]; then
- echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
- exit 1
- fi
+ local client=$1
+ local mnt=$2
+ local opts=${3:-$MOUNT_OPTS}
+ opts=${opts:+-o $opts}
+ local flags=${4:-$MOUNT_FLAGS}
+
+ local device=$MGSNID:/$FSNAME$FILESET
+ if [ -z "$mnt" -o -z "$FSNAME" ]; then
+ echo "Bad mount command: opt=$flags $opts dev=$device " \
+ "mnt=$mnt"
+ exit 1
+ fi
- echo "Starting client: $client: $OPTIONS $device $mnt"
- do_node $client mkdir -p $mnt
- do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
+ echo "Starting client: $client: $flags $opts $device $mnt"
+ do_node $client mkdir -p $mnt
+ if [ -n "$FILESET" -a -z "$SKIP_FILESET" ];then
+ do_node $client $MOUNT_CMD $flags $opts $MGSNID:/$FSNAME \
+ $mnt || return 1
+ #disable FILESET if not supported
+ do_nodes $client lctl get_param -n \
+ mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
+ device=$MGSNID:/$FSNAME
+ do_node $client mkdir -p $mnt/$FILESET
+ do_node $client "! grep -q $mnt' ' /proc/mounts ||
+ umount $mnt"
+ fi
+ do_node $client $MOUNT_CMD $flags $opts $device $mnt || return 1
- set_default_debug_nodes $client
+ set_default_debug_nodes $client
- return 0
+ return 0
}
zconf_umount() {
# mount clients if not mouted
zconf_mount_clients() {
- local clients=$1
- local mnt=$2
- local OPTIONS=${3:-$MOUNTOPT}
-
- local device=$MGSNID:/$FSNAME
- if [ -z "$mnt" -o -z "$FSNAME" ]; then
- echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
- exit 1
- fi
+ local clients=$1
+ local mnt=$2
+ local opts=${3:-$MOUNT_OPTS}
+ opts=${opts:+-o $opts}
+ local flags=${4:-$MOUNT_FLAGS}
+
+ local device=$MGSNID:/$FSNAME$FILESET
+ if [ -z "$mnt" -o -z "$FSNAME" ]; then
+ echo "Bad conf mount command: opt=$flags $opts dev=$device " \
+ "mnt=$mnt"
+ exit 1
+ fi
- echo "Starting client $clients: $OPTIONS $device $mnt"
+ echo "Starting client $clients: $flags $opts $device $mnt"
+ if [ -n "$FILESET" -a ! -n "$SKIP_FILESET" ]; then
+ do_nodes $clients "! grep -q $mnt' ' /proc/mounts ||
+ umount $mnt"
+ do_nodes $clients $MOUNT_CMD $flags $opts $MGSNID:/$FSNAME \
+ $mnt || return 1
+ #disable FILESET if not supported
+ do_nodes $clients lctl get_param -n \
+ mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
+ device=$MGSNID:/$FSNAME
+ do_nodes $clients mkdir -p $mnt/$FILESET
+ do_nodes $clients "! grep -q $mnt' ' /proc/mounts ||
+ umount $mnt"
+ fi
- do_nodes $clients "
+ do_nodes $clients "
running=\\\$(mount | grep -c $mnt' ');
rc=0;
if [ \\\$running -eq 0 ] ; then
mkdir -p $mnt;
- mount -t lustre $OPTIONS $device $mnt;
+ $MOUNT_CMD $flags $opts $device $mnt;
rc=\\\$?;
fi;
exit \\\$rc" || return ${PIPESTATUS[0]}
- echo "Started clients $clients: "
- do_nodes $clients "mount | grep $mnt' '"
+ echo "Started clients $clients: "
+ do_nodes $clients "mount | grep $mnt' '"
- set_default_debug_nodes $clients
+ set_default_debug_nodes $clients
- return 0
+ return 0
}
zconf_umount_clients() {
local host=${2:-$(facet_host $facet)}
local label=$(convert_facet2label $facet)
- do_node $host $LCTL dl | awk '{print $4}' | grep -q -x $label
+ do_node $host $LCTL dl | awk '{ print $4 }' | grep -q "^$label\$"
}
facets_up_on_host () {
# verify that lustre actually cleaned up properly
cleanup_check() {
- [ -f $CATASTROPHE ] && [ `cat $CATASTROPHE` -ne 0 ] && \
- error "LBUG/LASSERT detected"
- BUSY=`dmesg | grep -i destruct || true`
- if [ "$BUSY" ]; then
- echo "$BUSY" 1>&2
- [ -e $TMP/debug ] && mv $TMP/debug $TMP/debug-busy.`date +%s`
- exit 205
- fi
+ VAR=$(lctl get_param -n catastrophe 2>&1)
+ if [ $? = 0 ] ; then
+ if [ $VAR != 0 ]; then
+ error "LBUG/LASSERT detected"
+ fi
+ fi
+ BUSY=$(dmesg | grep -i destruct || true)
+ if [ -n "$BUSY" ]; then
+ echo "$BUSY" 1>&2
+ [ -e $TMP/debug ] && mv $TMP/debug $TMP/debug-busy.$(date +%s)
+ exit 205
+ fi
- check_mem_leak || exit 204
+ check_mem_leak || exit 204
- [ "`lctl dl 2> /dev/null | wc -l`" -gt 0 ] && lctl dl &&
+ [[ $($LCTL dl 2>/dev/null | wc -l) -gt 0 ]] && $LCTL dl &&
echo "$TESTSUITE: lustre didn't clean up..." 1>&2 &&
return 202 || true
local sleep=1
local print=10
+ PREV_RESULT=$(do_node $node "$TEST")
while [ true ]; do
RESULT=$(do_node $node "$TEST")
if [[ "$RESULT" == "$FINAL" ]]; then
}
wait_update_facet() {
+ local verbose=
+ [ "$1" = "--verbose" ] && verbose="$1" && shift
+
local facet=$1
shift
- wait_update $(facet_active_host $facet) "$@"
+ wait_update $verbose $(facet_active_host $facet) "$@"
}
sync_all_data() {
do_nodes $(comma_list $(mdts_nodes)) \
- "lctl set_param -n osd*.*MDT*.force_sync 1"
+ "lctl set_param -n osd*.*MDT*.force_sync=1"
do_nodes $(comma_list $(osts_nodes)) \
- "lctl set_param -n osd*.*OS*.force_sync 1" 2>&1 |
+ "lctl set_param -n osd*.*OS*.force_sync=1" 2>&1 |
grep -v 'Found no match'
}
wait_delete_completed_mds() {
local MAX_WAIT=${1:-20}
+ # for ZFS, waiting more time for DMUs to be committed
+ local ZFS_WAIT=${2:-5}
local mds2sync=""
- local stime=`date +%s`
+ local stime=$(date +%s)
local etime
local node
local changes
# find MDS with pending deletions
for node in $(mdts_nodes); do
- changes=$(do_node $node "lctl get_param -n osc.*MDT*.sync_*" \
+ changes=$(do_node $node "$LCTL get_param -n osc.*MDT*.sync_*" \
2>/dev/null | calc_sum)
- if [ -z "$changes" ] || [ $changes -eq 0 ]; then
+ if [[ $changes -eq 0 ]]; then
continue
fi
mds2sync="$mds2sync $node"
done
- if [ "$mds2sync" == "" ]; then
+ if [ -z "$mds2sync" ]; then
return
fi
mds2sync=$(comma_list $mds2sync)
# sync MDS transactions
- do_nodes $mds2sync "lctl set_param -n osd*.*MD*.force_sync 1"
+ do_nodes $mds2sync "$LCTL set_param -n osd*.*MD*.force_sync 1"
# wait till all changes are sent and commmitted by OSTs
# for ldiskfs space is released upon execution, but DMU
# do this upon commit
local WAIT=0
- while [ "$WAIT" -ne "$MAX_WAIT" ]; do
- changes=$(do_nodes $mds2sync "lctl get_param -n osc.*MDT*.sync_*" \
- | calc_sum)
+ while [[ $WAIT -ne $MAX_WAIT ]]; do
+ changes=$(do_nodes $mds2sync \
+ "$LCTL get_param -n osc.*MDT*.sync_*" | calc_sum)
#echo "$node: $changes changes on all"
- if [ "$changes" -eq "0" ]; then
- etime=`date +%s`
+ if [[ $changes -eq 0 ]]; then
+ etime=$(date +%s)
#echo "delete took $((etime - stime)) seconds"
+
+ # the occupied disk space will be released
+ # only after DMUs are committed
+ if [[ $(facet_fstype $SINGLEMDS) == zfs ]]; then
+ echo "sleep $ZFS_WAIT for ZFS OSD"
+ sleep $ZFS_WAIT
+ fi
+
return
fi
sleep 1
WAIT=$(( WAIT + 1))
done
- etime=`date +%s`
+ etime=$(date +%s)
echo "Delete is not completed in $((etime - stime)) seconds"
- do_nodes $mds2sync "lctl get_param osc.*MDT*.sync_*"
+ do_nodes $mds2sync "$LCTL get_param osc.*MDT*.sync_*"
}
wait_for_host() {
! client_up $1
}
-client_reconnect() {
+client_reconnect_try() {
uname -n >> $MOUNT/recon
if [ -z "$CLIENTS" ]; then
df $MOUNT; uname -n >> $MOUNT/recon
rm $MOUNT/recon
}
+client_reconnect() {
+ # one client_reconnect_try call does not always do the job...
+ while true ; do
+ client_reconnect_try && break
+ sleep 1
+ done
+}
+
affected_facets () {
local facet=$1
}
facet_failover() {
+ local E2FSCK_ON_MDT0=false
+ if [ "$1" == "--fsck" ]; then
+ shift
+ [ $(facet_fstype $SINGLEMDS) == ldiskfs ] &&
+ E2FSCK_ON_MDT0=true
+ fi
+
local facets=$1
local sleep_time=$2
local -a affecteds
shutdown_facet $facet
done
+ $E2FSCK_ON_MDT0 && (run_e2fsck $(facet_active_host $SINGLEMDS) \
+ $(mdsdevname 1) "-n" || error "Running e2fsck")
+
for ((index=0; index<$total; index++)); do
facet=$(echo ${affecteds[index]} | tr -s " " | cut -d"," -f 1)
echo reboot facets: ${affecteds[index]}
# inside fail() and fail_abort().
#
do_facet $facet $LCTL --device ${!svc} readonly
- do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
- $LCTL mark "local REPLAY BARRIER on ${!svc}"
+ do_facet $facet $LCTL mark "$HOSTNAME: $facet REPLAY BARRIER on ${!svc}"
+ $LCTL mark "$HOSTNAME: local REPLAY BARRIER on ${!svc}"
}
replay_barrier_nodf() {
echo Replay barrier on ${!svc}
do_facet $facet $LCTL --device ${!svc} notransno
do_facet $facet $LCTL --device ${!svc} readonly
- do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
- $LCTL mark "local REPLAY BARRIER on ${!svc}"
+ do_facet $facet $LCTL mark "$HOSTNAME: $facet REPLAY BARRIER on ${!svc}"
+ $LCTL mark "$HOSTNAME: local REPLAY BARRIER on ${!svc}"
}
replay_barrier_nosync() {
echo Replay barrier on ${!svc}
do_facet $facet $LCTL --device ${!svc} notransno
do_facet $facet $LCTL --device ${!svc} readonly
- do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
- $LCTL mark "local REPLAY BARRIER on ${!svc}"
+ do_facet $facet $LCTL mark "$HOSTNAME: $facet REPLAY BARRIER on ${!svc}"
+ $LCTL mark "$HOSTNAME: local REPLAY BARRIER on ${!svc}"
}
#
done
myList="${myList%* }";
- # We can select an object at a offset in the list
+ # We can select an object at an offset in the list
[ $# -eq 2 ] && {
cnt=0
for item in $myList; do
varname=${facet}_HOST
if [ -z "${!varname}" ]; then
if [ "${facet:0:3}" == "ost" ]; then
- eval export ${facet}_HOST=${ost_HOST}
+ local fh=${facet%failover}_HOST
+ eval export ${facet}_HOST=${!fh}
+ if [ -z "${!varname}" ]; then
+ eval export ${facet}_HOST=${ost_HOST}
+ fi
elif [ "${facet:0:3}" == "mdt" -o \
"${facet:0:3}" == "mds" -o \
"${facet:0:3}" == "mgs" ]; then
}
facet_active_host() {
- local facet=$1
- local active=`facet_active $facet`
- if [ "$facet" == client ]; then
- echo $HOSTNAME
- else
- echo `facet_host $active`
- fi
+ facet_host $(facet_active $1)
}
# Get the passive failover partner host of facet.
}
do_node() {
- local verbose=false
- # do not stripe off hostname if verbose, bug 19215
- if [ x$1 = x--verbose ]; then
- shift
- verbose=true
- fi
+ local verbose=false
+ # do not stripe off hostname if verbose, bug 19215
+ if [ x$1 = x--verbose ]; then
+ shift
+ verbose=true
+ fi
- local HOST=$1
- shift
- local myPDSH=$PDSH
- if [ "$HOST" = "$HOSTNAME" ]; then
- myPDSH="no_dsh"
- elif [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" ]; then
- echo "cannot run remote command on $HOST with $myPDSH"
- return 128
- fi
- if $VERBOSE; then
- echo "CMD: $HOST $@" >&2
- $myPDSH $HOST "$LCTL mark \"$@\"" > /dev/null 2>&1 || :
- fi
+ local HOST=$1
+ shift
+ local myPDSH=$PDSH
+ if [ "$HOST" = "$HOSTNAME" ]; then
+ myPDSH="no_dsh"
+ elif [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" ]; then
+ echo "cannot run remote command on $HOST with $myPDSH"
+ return 128
+ fi
+ if $VERBOSE; then
+ echo "CMD: $HOST $@" >&2
+ $myPDSH $HOST "$LCTL mark \"$HOSTNAME: $@\"" &>/dev/null || :
+ fi
if [ "$myPDSH" = "rsh" ]; then
# we need this because rsh does not return exit code of an executed command
local facet
for var in ${!MODOPTS_*}; do
- value=${!var}
+ value=${!var//\"/\\\"}
echo -n " ${var}=\"$value\""
done
fi
done
+ for var in VERBOSE; do
+ if [ -n "${!var}" ]; then
+ echo -n " $var=${!var}"
+ fi
+ done
+
if [ -n "$FSTYPE" ]; then
echo -n " FSTYPE=$FSTYPE"
fi
+
+ for var in LNETLND NETTYPE; do
+ if [ -n "${!var}" ]; then
+ echo -n " $var=${!var}"
+ fi
+ done
}
do_nodes() {
return $?
fi
- # This is part from do_node
- local myPDSH=$PDSH
+ # This is part from do_node
+ local myPDSH=$PDSH
- [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" -o "$myPDSH" = "rsh" ] && \
- echo "cannot run remote command on $rnodes with $myPDSH" && return 128
+ [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" -o "$myPDSH" = "rsh" ] &&
+ echo "cannot run remote command on $rnodes with $myPDSH" &&
+ return 128
- export FANOUT=$(get_node_count "${rnodes//,/ }")
- if $VERBOSE; then
- echo "CMD: $rnodes $@" >&2
- $myPDSH $rnodes "$LCTL mark \"$@\"" > /dev/null 2>&1 || :
- fi
+ export FANOUT=$(get_node_count "${rnodes//,/ }")
+ if $VERBOSE; then
+ echo "CMD: $rnodes $@" >&2
+ $myPDSH $rnodes "$LCTL mark \"$HOSTNAME: $@\"" &>/dev/null || :
+ fi
# do not replace anything from pdsh output if -N is used
# -N Disable hostname: prefix on lines of output.
return ${PIPESTATUS[0]}
}
+##
+# Execute commands on a single service's host
+#
+# The \a facet (service) may be on a local or remote node, which is
+# determined at the time the command is run.
+#
+# usage: do_facet $facet command [arg ...]
do_facet() {
- local facet=$1
- shift
- local HOST=`facet_active_host $facet`
- [ -z $HOST ] && echo No host defined for facet ${facet} && exit 1
- do_node $HOST "$@"
+ local facet=$1
+ shift
+ local HOST=$(facet_active_host $facet)
+ [ -z $HOST ] && echo "No host defined for facet ${facet}" && exit 1
+ do_node $HOST "$@"
}
# Function: do_facet_random_file $FACET $FILE $SIZE
eval VDEVPTR="";;
zfs )
#if $OSTDEVn isn't defined, default is $OSTDEVBASE{n}
- # Device formated by zfs
+ # Device formatted by zfs
DEVNAME=OSTDEV$num
eval VDEVPTR=${!DEVNAME:=${OSTDEVBASE}${num}};;
* )
echo -n $VDEVPTR
}
-# Logical device formated for lustre
+# Logical device formatted for lustre
mdsdevname() {
local num=$1
local DEVNAME=MDSDEV$num
eval VDEVPTR="";;
zfs )
# if $MDSDEVn isn't defined, default is $MDSDEVBASE{n}
- # Device formated by ZFS
+ # Device formatted by ZFS
local DEVNAME=MDSDEV$num
eval VDEVPTR=${!DEVNAME:=${MDSDEVBASE}${num}};;
* )
local dev=$(facet_device $facet)
local mnt=$(facet_mntpt $facet)
- do_facet $facet umount -d $mnt
+ do_facet $facet $UMOUNT $mnt
}
var_name() {
cleanupall() {
nfs_client_mode && return
+ cifs_client_mode && return
stopall $*
cleanup_echo_devs
local dev=$2
local fsname=${3:-"$FSNAME"}
local type=$(facet_type $facet)
- local index=$(($(facet_number $facet) - 1))
+ local index=$(facet_index $facet)
local fstype=$(facet_fstype $facet)
local host=$(facet_host $facet)
local opts
local fs_mkfs_opts
local var
- if [ $type == MGS ] && combined_mgs_mds; then
- return 1
- fi
-
if [ $type == MGS ] || ( [ $type == MDS ] &&
[ "$dev" == $(mgsdevname) ] &&
[ "$host" == "$(facet_host mgs)" ] ); then
opts+=${L_GETIDENTITY:+" --param=mdt.identity_upcall=$L_GETIDENTITY"}
if [ $fstype == ldiskfs ]; then
- fs_mkfs_opts+=${MDSJOURNALSIZE:+" -J size=$MDSJOURNALSIZE"}
- if [ ! -z $EJOURNAL ]; then
- fs_mkfs_opts+=${MDSJOURNALSIZE:+" device=$EJOURNAL"}
+ # Check for wide striping
+ if [ $OSTCOUNT -gt 160 ]; then
+ MDSJOURNALSIZE=${MDSJOURNALSIZE:-4096}
+ fs_mkfs_opts+="-O large_xattr"
+ fi
+
+ var=${facet}_JRN
+ if [ -n "${!var}" ]; then
+ fs_mkfs_opts+=" -J device=${!var}"
+ else
+ fs_mkfs_opts+=${MDSJOURNALSIZE:+" -J size=$MDSJOURNALSIZE"}
fi
fs_mkfs_opts+=${MDSISIZE:+" -i $MDSISIZE"}
fi
opts+=${OSSCAPA:+" --param=ost.capa=$OSSCAPA"}
if [ $fstype == ldiskfs ]; then
- fs_mkfs_opts+=${OSTJOURNALSIZE:+" -J size=$OSTJOURNALSIZE"}
+ var=${facet}_JRN
+ if [ -n "${!var}" ]; then
+ fs_mkfs_opts+=" -J device=${!var}"
+ else
+ fs_mkfs_opts+=${OSTJOURNALSIZE:+" -J size=$OSTJOURNALSIZE"}
+ fi
fi
fi
echo -n "$opts"
}
-formatall() {
+check_ost_indices() {
+ local index_count=${#OST_INDICES[@]}
+ [[ $index_count -eq 0 || $OSTCOUNT -le $index_count ]] && return 0
+
+ # OST count is greater than the index count in $OST_INDEX_LIST.
+ # We need check whether there are duplicate indices.
+ local i
+ local j
+ local index
+ for i in $(seq $((index_count + 1)) $OSTCOUNT); do
+ index=$(facet_index ost$i)
+ for j in $(seq 0 $((index_count - 1))); do
+ [[ $index -ne ${OST_INDICES[j]} ]] ||
+ error "ost$i has the same index $index as ost$((j+1))"
+ done
+ done
+}
+
+format_mgs() {
+ local quiet
+
+ if ! $VERBOSE; then
+ quiet=yes
+ fi
+ echo "Format mgs: $(mgsdevname)"
+ reformat_external_journal mgs
+ add mgs $(mkfs_opts mgs $(mgsdevname)) --reformat \
+ $(mgsdevname) $(mgsvdevname) ${quiet:+>/dev/null} || exit 10
+}
+
+format_mdt() {
+ local num=$1
local quiet
if ! $VERBOSE; then
quiet=yes
fi
+ echo "Format mds$num: $(mdsdevname $num)"
+ reformat_external_journal mds$num
+ add mds$num $(mkfs_opts mds$num $(mdsdevname ${num})) \
+ --reformat $(mdsdevname $num) $(mdsvdevname $num) \
+ ${quiet:+>/dev/null} || exit 10
+}
+
+format_ost() {
+ local num=$1
+
+ if ! $VERBOSE; then
+ quiet=yes
+ fi
+ echo "Format ost$num: $(ostdevname $num)"
+ reformat_external_journal ost$num
+ add ost$num $(mkfs_opts ost$num $(ostdevname ${num})) \
+ --reformat $(ostdevname $num) $(ostvdevname ${num}) \
+ ${quiet:+>/dev/null} || exit 10
+}
+formatall() {
stopall
# We need ldiskfs here, may as well load them all
load_modules
[ "$CLIENTONLY" ] && return
echo Formatting mgs, mds, osts
if ! combined_mgs_mds ; then
- echo "Format mgs: $(mgsdevname)"
- add mgs $(mkfs_opts mgs $(mgsdevname)) --reformat \
- $(mgsdevname) $(mgsvdevname) ${quiet:+>/dev/null} ||
- exit 10
+ format_mgs
fi
for num in $(seq $MDSCOUNT); do
- echo "Format mds$num: $(mdsdevname $num)"
- add mds$num $(mkfs_opts mds$num $(mdsdevname ${num})) \
- --reformat $(mdsdevname $num) $(mdsvdevname $num) \
- ${quiet:+>/dev/null} || exit 10
+ format_mdt $num
done
+ export OST_INDICES=($(hostlist_expand "$OST_INDEX_LIST"))
+ check_ost_indices
for num in $(seq $OSTCOUNT); do
- echo "Format ost$num: $(ostdevname $num)"
- add ost$num $(mkfs_opts ost$num $(ostdevname ${num})) \
- --reformat $(ostdevname $num) $(ostvdevname ${num}) \
- ${quiet:+>/dev/null} || exit 10
+ format_ost $num
done
}
setupall() {
nfs_client_mode && return
+ cifs_client_mode && return
sanity_mount_check ||
error "environments are insane!"
return 1
}
-check_config_client () {
+cifs_client_mode () {
+ [ x$CIFSCLIENT = xyes ] &&
+ echo "CIFSCLIENT=$CIFSCLIENT mode: setup, cleanup, check config skipped"
+}
+
+check_config_client () {
local mntpt=$1
local mounted=$(mount | grep " $mntpt ")
local mntpt=$1
nfs_client_mode && return
+ cifs_client_mode && return
do_rpc_nodes "$clients" check_config_client $mntpt
}
check_and_setup_lustre() {
- nfs_client_mode && return
+ sanitize_parameters
+ nfs_client_mode && return
+ cifs_client_mode && return
+
+ local MOUNTED=$(mounted_lustre_filesystems)
- local MOUNTED=$(mounted_lustre_filesystems)
-
- local do_check=true
- # 1.
- # both MOUNT and MOUNT2 are not mounted
- if ! is_mounted $MOUNT && ! is_mounted $MOUNT2; then
- [ "$REFORMAT" ] && formatall
- # setupall mounts both MOUNT and MOUNT2 (if MOUNT_2 is set)
- setupall
- is_mounted $MOUNT || error "NAME=$NAME not mounted"
- export I_MOUNTED=yes
- do_check=false
+ local do_check=true
+ # 1.
+ # both MOUNT and MOUNT2 are not mounted
+ if ! is_mounted $MOUNT && ! is_mounted $MOUNT2; then
+ [ "$REFORMAT" = "yes" ] && formatall
+ # setupall mounts both MOUNT and MOUNT2 (if MOUNT_2 is set)
+ setupall
+ is_mounted $MOUNT || error "NAME=$NAME not mounted"
+ export I_MOUNTED=yes
+ do_check=false
# 2.
# MOUNT2 is mounted
elif is_mounted $MOUNT2; then
set_flavor_all $SEC
fi
+ #Enable remote MDT create for testing
+ for num in $(seq $MDSCOUNT); do
+ do_facet mds$num \
+ lctl set_param -n mdt.${FSNAME}*.enable_remote_dir=1 \
+ 2>/dev/null
+ done
+
if [ "$ONLY" == "setup" ]; then
exit 0
fi
}
cleanup_mount () {
- local clients=${CLIENTS:-$HOSTNAME}
- local mntpt=$1
+ local clients=${CLIENTS:-$HOSTNAME}
+ local mntpt=$1
- zconf_umount_clients $clients $mntpt
+ zconf_umount_clients $clients $mntpt
}
cleanup_and_setup_lustre() {
if [ "$type" == ost ]; then
devs=$(get_osd_param $node "" mntdev)
else
- devs=$(do_node $node \
- "lctl get_param -n osd-*.$FSNAME-M*.mntdev")
+ devs=$(do_node $node $LCTL get_param -n osd-*.$FSNAME-M*.mntdev)
fi
for dev in $devs; do
case $dev in
# Get all of the server target devices.
get_svr_devs() {
- local i
+ local node
+ local i
- # MDT device
- MDTDEV=$(get_mnt_devs $(mdts_nodes) mdt)
+ # Master MDS parameters used by lfsck
+ MDTNODE=$(facet_active_host $SINGLEMDS)
+ MDTDEV=$(echo $(get_mnt_devs $MDTNODE mdt) | awk '{print $1}')
- # OST devices
- i=0
- for node in $(osts_nodes); do
- OSTDEVS[i]=$(get_mnt_devs $node ost)
- i=$((i + 1))
- done
+ # MDT devices
+ i=0
+ for node in $(mdts_nodes); do
+ MDTDEVS[i]=$(get_mnt_devs $node mdt)
+ i=$((i + 1))
+ done
+
+ # OST devices
+ i=0
+ for node in $(osts_nodes); do
+ OSTDEVS[i]=$(get_mnt_devs $node ost)
+ i=$((i + 1))
+ done
}
# Run e2fsck on MDT or OST device.
run_e2fsck() {
- local node=$1
- local target_dev=$2
- local extra_opts=$3
+ local node=$1
+ local target_dev=$2
+ local extra_opts=$3
+ local cmd="$E2FSCK -d -v -t -t -f $extra_opts $target_dev"
+ local log=$TMP/e2fsck.log
+ local rc=0
- df > /dev/null # update statfs data on disk
- local cmd="$E2FSCK -d -v -t -t -f $extra_opts $target_dev"
- echo $cmd
- local rc=0
- do_node $node $cmd || rc=$?
- [ $rc -le $FSCK_MAX_ERR ] || \
- error "$cmd returned $rc, should be <= $FSCK_MAX_ERR"
- return 0
+ echo $cmd
+ do_node $node $cmd 2>&1 | tee $log
+ rc=${PIPESTATUS[0]}
+ if [ -n "$(grep "DNE mode isn't supported" $log)" ]; then
+ rm -f $log
+ if [ $MDSCOUNT -gt 1 ]; then
+ skip "DNE mode isn't supported!"
+ cleanupall
+ exit_status
+ else
+ error "It's not DNE mode."
+ fi
+ fi
+ rm -f $log
+
+ [ $rc -le $FSCK_MAX_ERR ] ||
+ error "$cmd returned $rc, should be <= $FSCK_MAX_ERR"
+
+ return 0
}
#
return 0
}
-# Run e2fsck on MDT and OST(s) to generate databases used for lfsck.
-generate_db() {
- local i
- local ostidx
- local dev
-
- [[ $(lustre_version_code $SINGLEMDS) -ne $(version_code 2.2.0) ]] ||
- { skip "Lustre 2.2.0 lacks the patch for LU-1255"; exit 0; }
-
- check_shared_dir $SHARED_DIRECTORY ||
- error "$SHARED_DIRECTORY isn't a shared directory"
-
- export MDSDB=$SHARED_DIRECTORY/mdsdb
- export OSTDB=$SHARED_DIRECTORY/ostdb
-
- [ $MDSCOUNT -eq 1 ] || error "CMD is not supported"
-
- run_e2fsck $(mdts_nodes) $MDTDEV "-n --mdsdb $MDSDB"
+run_lfsck() {
+ do_nodes $(comma_list $(mdts_nodes) $(osts_nodes)) \
+ $LCTL set_param printk=+lfsck
+ do_facet $SINGLEMDS "$LCTL lfsck_start -M $FSNAME-MDT0000 -r -A -t all"
+
+ for k in $(seq $MDSCOUNT); do
+ # wait up to 10+1 minutes for LFSCK to complete
+ wait_update_facet --verbose mds${k} "$LCTL get_param -n \
+ mdd.$(facet_svc mds${k}).lfsck_layout |
+ awk '/^status/ { print \\\$2 }'" "completed" 600 ||
+ error "MDS${k} layout isn't the expected 'completed'"
+ wait_update_facet --verbose mds${k} "$LCTL get_param -n \
+ mdd.$(facet_svc mds${k}).lfsck_namespace |
+ awk '/^status/ { print \\\$2 }'" "completed" 60 ||
+ error "MDS${k} namespace isn't the expected 'completed'"
+ done
+ local rep_mdt=$(do_nodes $(comma_list $(mdts_nodes)) \
+ $LCTL get_param -n mdd.$FSNAME-*.lfsck_* |
+ awk '/repaired/ { print $2 }' | calc_sum)
+ local rep_ost=$(do_nodes $(comma_list $(osts_nodes)) \
+ $LCTL get_param -n obdfilter.$FSNAME-*.lfsck_* |
+ awk '/repaired/ { print $2 }' | calc_sum)
+ local repaired=$((rep_mdt + rep_ost))
+ [ $repaired -eq 0 ] ||
+ error "lfsck repaired $rep_mdt MDT and $rep_ost OST errors"
+}
+
+dump_file_contents() {
+ local nodes=$1
+ local dir=$2
+ local logname=$3
+ local node
- i=0
- ostidx=0
- OSTDB_LIST=""
- for node in $(osts_nodes); do
- for dev in ${OSTDEVS[i]}; do
- run_e2fsck $node $dev "-n --mdsdb $MDSDB --ostdb $OSTDB-$ostidx"
- OSTDB_LIST="$OSTDB_LIST $OSTDB-$ostidx"
- ostidx=$((ostidx + 1))
- done
- i=$((i + 1))
- done
+ if [ -z "$nodes" -o -z "$dir" -o -z "$logname" ]; then
+ error_noexit false \
+ "Invalid parameters for dump_file_contents()"
+ return 1
+ fi
+ for node in ${nodes}; do
+ do_node $node "for i in \\\$(find $dir -type f); do
+ echo ====\\\${i}=======================;
+ cat \\\${i};
+ done" >> ${logname}.${node}.log
+ done
}
-# Run lfsck on server node if lfsck can't be found on client (LU-2571)
-run_lfsck_remote() {
- local cmd="$LFSCK_BIN -c -l --mdsdb $MDSDB --ostdb $OSTDB_LIST $MOUNT"
- local client=$1
- local mounted=true
- local rc=0
+dump_command_output() {
+ local nodes=$1
+ local cmd=$2
+ local logname=$3
+ local node
- #Check if lustre is already mounted
- do_rpc_nodes $client is_mounted $MOUNT || mounted=false
- if ! $mounted; then
- zconf_mount $client $MOUNT ||
- error "failed to mount Lustre on $client"
- fi
- #Run lfsck
- echo $cmd
- do_node $node $cmd || rc=$?
- #Umount if necessary
- if ! $mounted; then
- zconf_umount $client $MOUNT ||
- error "failed to unmount Lustre on $client"
+ if [ -z "$nodes" -o -z "$cmd" -o -z "$logname" ]; then
+ error_noexit false \
+ "Invalid parameters for dump_command_output()"
+ return 1
fi
- [ $rc -le $FSCK_MAX_ERR ] ||
- error "$cmd returned $rc, should be <= $FSCK_MAX_ERR"
- echo "lfsck finished with rc=$rc"
-
- return $rc
+ for node in ${nodes}; do
+ do_node $node "echo ====${cmd}=======================;
+ $cmd" >> ${logname}.${node}.log
+ done
}
-run_lfsck() {
- local facets="client $SINGLEMDS"
- local found=false
- local facet
- local node
- local rc=0
-
- for facet in $facets; do
- node=$(facet_active_host $facet)
- if check_progs_installed $node $LFSCK_BIN; then
- found=true
- break
- fi
- done
- ! $found && error "None of \"$facets\" supports lfsck"
+log_zfs_info() {
+ local logname=$1
- run_lfsck_remote $node || rc=$?
+ # dump file contents from /proc/spl in case of zfs test
+ if [ "$(facet_fstype ost1)" = "zfs" ]; then
+ dump_file_contents "$(osts_nodes)" "/proc/spl" "${logname}"
+ dump_command_output \
+ "$(osts_nodes)" "zpool events -v" "${logname}"
+ fi
- rm -rvf $MDSDB* $OSTDB* || true
- return $rc
+ if [ "$(facet_fstype $SINGLEMDS)" = "zfs" ]; then
+ dump_file_contents "$(mdts_nodes)" "/proc/spl" "${logname}"
+ dump_command_output \
+ "$(mdts_nodes)" "zpool events -v" "${logname}"
+ fi
}
check_and_cleanup_lustre() {
- if [ "$LFSCK_ALWAYS" = "yes" -a "$TESTSUITE" != "lfsck" ]; then
- get_svr_devs
- generate_db
- run_lfsck
- fi
+ if [ "$LFSCK_ALWAYS" = "yes" -a "$TESTSUITE" != "sanity-lfsck" -a \
+ "$TESTSUITE" != "sanity-scrub" ]; then
+ run_lfsck
+ fi
if is_mounted $MOUNT; then
[ -n "$DIR" ] && rm -rf $DIR/[Rdfs][0-9]* ||
[ "$ENABLE_QUOTA" ] && restore_quota || true
fi
- if [ "$I_UMOUNTED2" = "yes" ]; then
- restore_mount $MOUNT2 || error "restore $MOUNT2 failed"
- fi
+ if [ "$I_UMOUNTED2" = "yes" ]; then
+ restore_mount $MOUNT2 || error "restore $MOUNT2 failed"
+ fi
- if [ "$I_MOUNTED2" = "yes" ]; then
- cleanup_mount $MOUNT2
- fi
+ if [ "$I_MOUNTED2" = "yes" ]; then
+ cleanup_mount $MOUNT2
+ fi
- if [ "$I_MOUNTED" = "yes" ]; then
- cleanupall -f || error "cleanup failed"
- unset I_MOUNTED
- fi
+ if [ "$I_MOUNTED" = "yes" ]; then
+ cleanupall -f || error "cleanup failed"
+ unset I_MOUNTED
+ fi
}
#######
drop_reply() {
# OBD_FAIL_MDS_ALL_REPLY_NET
- RC=0
- do_facet $SINGLEMDS lctl set_param fail_loc=0x122
- do_facet client "$@" || RC=$?
- do_facet $SINGLEMDS lctl set_param fail_loc=0
- return $RC
+ RC=0
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0x122
+ eval "$@" || RC=$?
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0
+ return $RC
}
drop_reint_reply() {
# OBD_FAIL_MDS_REINT_NET_REP
- RC=0
- do_facet $SINGLEMDS lctl set_param fail_loc=0x119
- do_facet client "$@" || RC=$?
- do_facet $SINGLEMDS lctl set_param fail_loc=0
- return $RC
+ RC=0
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0x119
+ eval "$@" || RC=$?
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0
+ return $RC
}
drop_update_reply() {
-# OBD_FAIL_UPDATE_OBJ_NET_REP
+# OBD_FAIL_OUT_UPDATE_NET_REP
local index=$1
shift 1
RC=0
pause_bulk() {
#define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
- RC=0
- do_facet ost1 lctl set_param fail_loc=0x214
- do_facet client "$1" || RC=$?
- do_facet client "sync"
- do_facet ost1 lctl set_param fail_loc=0
- return $RC
+ RC=0
+
+ local timeout=${2:-0}
+ # default is (obd_timeout / 4) if unspecified
+ echo "timeout is $timeout/$2"
+ do_facet ost1 lctl set_param fail_val=$timeout fail_loc=0x80000214
+ do_facet client "$1" || RC=$?
+ do_facet client "sync"
+ do_facet ost1 lctl set_param fail_loc=0
+ return $RC
}
drop_ldlm_cancel() {
return $RC
}
-drop_bl_callback() {
+drop_bl_callback_once() {
+ local rc=0
+ do_facet client lctl set_param ldlm.namespaces.*.early_lock_cancel=0
#define OBD_FAIL_LDLM_BL_CALLBACK_NET 0x305
- RC=0
do_facet client lctl set_param fail_loc=0x80000305
- do_facet client "$@" || RC=$?
+ do_facet client "$@" || rc=$?
do_facet client lctl set_param fail_loc=0
- return $RC
+ do_facet client lctl set_param fail_val=0
+ do_facet client lctl set_param ldlm.namespaces.*.early_lock_cancel=1
+ return $rc
+}
+
+drop_bl_callback() {
+ rc=0
+ do_facet client lctl set_param ldlm.namespaces.*.early_lock_cancel=0
+#define OBD_FAIL_LDLM_BL_CALLBACK_NET 0x305
+ do_facet client lctl set_param fail_loc=0x305
+ do_facet client "$@" || rc=$?
+ do_facet client lctl set_param fail_loc=0
+ do_facet client lctl set_param fail_val=0
+ do_facet client lctl set_param ldlm.namespaces.*.early_lock_cancel=1
+ return $rc
}
drop_ldlm_reply() {
#define OBD_FAIL_LDLM_REPLY 0x30c
RC=0
- do_facet $SINGLEMDS lctl set_param fail_loc=0x30c
+ local list=$(comma_list $(mdts_nodes) $(osts_nodes))
+ do_nodes $list lctl set_param fail_loc=0x30c
+
do_facet client "$@" || RC=$?
- do_facet $SINGLEMDS lctl set_param fail_loc=0
+
+ do_nodes $list lctl set_param fail_loc=0
+ return $RC
+}
+
+drop_ldlm_reply_once() {
+#define OBD_FAIL_LDLM_REPLY 0x30c
+ RC=0
+ local list=$(comma_list $(mdts_nodes) $(osts_nodes))
+ do_nodes $list lctl set_param fail_loc=0x8000030c
+
+ do_facet client "$@" || RC=$?
+
+ do_nodes $list lctl set_param fail_loc=0
return $RC
}
}
set_nodes_failloc () {
- do_nodes $(comma_list $1) lctl set_param fail_loc=$2
+ do_nodes $(comma_list $1) lctl set_param fail_val=0 fail_loc=$2
}
cancel_lru_locks() {
- $LCTL mark "cancel_lru_locks $1 start"
- for d in `lctl get_param -N ldlm.namespaces.*.lru_size | egrep -i $1`; do
- $LCTL set_param -n $d=clear
- done
- $LCTL get_param ldlm.namespaces.*.lock_unused_count | egrep -i $1 | grep -v '=0'
- $LCTL mark "cancel_lru_locks $1 stop"
+ #$LCTL mark "$HOSTNAME: cancel_lru_locks $1 start"
+ $LCTL set_param -n ldlm.namespaces.*$1*.lru_size=clear
+ $LCTL get_param ldlm.namespaces.*$1*.lock_unused_count | grep -v '=0'
+ #$LCTL mark "$HOSTNAME: cancel_lru_locks $1 stop"
}
default_lru_size()
lctl set_param ldlm.namespaces.*$1*.lru_size $(default_lru_size)
}
+flock_is_enabled()
+{
+ local RC=0
+ [ -z "$(mount | grep "$MOUNT.*flock" | grep -v noflock)" ] && RC=1
+ return $RC
+}
+
pgcache_empty() {
local FILE
for FILE in `lctl get_param -N "llite.*.dump_page_cache"`; do
}
# prints bash call stack
-log_trace_dump() {
+print_stack_trace() {
+ local skip=${1:-1}
echo " Trace dump:"
- for (( i=1; i < ${#BASH_LINENO[*]} ; i++ )) ; do
- local s=${BASH_SOURCE[$i]}
- local l=${BASH_LINENO[$i-1]}
- local f=${FUNCNAME[$i]}
- echo " = $s:$l:$f()"
+ for (( i=$skip; i < ${#BASH_LINENO[*]} ; i++ )) ; do
+ local src=${BASH_SOURCE[$i]}
+ local lineno=${BASH_LINENO[$i-1]}
+ local funcname=${FUNCNAME[$i]}
+ echo " = $src:$lineno:$funcname()"
done
}
-##################################
-# Test interface
-##################################
-
-error_noexit() {
+report_error() {
local TYPE=${TYPE:-"FAIL"}
local dump=true
dump=false
fi
-
log " ${TESTSUITE} ${TESTNAME}: @@@@@@ ${TYPE}: $@ "
- log_trace_dump
-
+ (print_stack_trace 2) >&2
mkdir -p $LOGDIR
# We need to dump the logs on all nodes
if $dump; then
echo "$@" > $LOGDIR/err
fi
fi
+
+ # cleanup the env for failed tests
+ reset_fail_loc
+}
+
+##################################
+# Test interface
+##################################
+
+error_noexit() {
+ report_error "$@"
}
exit_status () {
}
error() {
- error_noexit "$@"
+ report_error "$@"
exit 1
}
error_exit() {
- error "$@"
+ report_error "$@"
+ exit 1
}
# use only if we are ignoring failures for this test, bugno required.
error_ignore() {
local TYPE="IGNORE ($1)"
shift
- error_noexit "$@"
+ report_error "$@"
}
error_and_remount() {
- error_noexit "$@"
+ report_error "$@"
remount_client $MOUNT
exit 1
}
build_test_filter() {
EXCEPT="$EXCEPT $(testslist_filter)"
- [ "$ONLY" ] && log "only running test `echo $ONLY`"
- for O in $ONLY; do
- eval ONLY_${O}=true
- done
+ for O in $ONLY; do
+ if [[ $O = [0-9]*-[0-9]* ]]; then
+ for num in $(seq $(echo $O | tr '-' ' ')); do
+ eval ONLY_$num=true
+ done
+ else
+ eval ONLY_${O}=true
+ fi
+ done
+
[ "$EXCEPT$ALWAYS_EXCEPT" ] && \
log "excepting tests: `echo $EXCEPT $ALWAYS_EXCEPT`"
[ "$EXCEPT_SLOW" ] && \
# run or not run. These need to be documented...
#
run_test() {
- assert_DIR
-
- export base=`basetest $1`
- if [ ! -z "$ONLY" ]; then
- testname=ONLY_$1
- if [ ${!testname}x != x ]; then
- [ "$LAST_SKIPPED" ] && echo "" && LAST_SKIPPED=
- run_one_logged $1 "$2"
- return $?
- fi
- testname=ONLY_$base
- if [ ${!testname}x != x ]; then
- [ "$LAST_SKIPPED" ] && echo "" && LAST_SKIPPED=
- run_one_logged $1 "$2"
- return $?
- fi
- LAST_SKIPPED="y"
- return 0
- fi
+ assert_DIR
+
+ export base=$(basetest $1)
+ if [ -n "$ONLY" ]; then
+ testname=ONLY_$1
+ if [ ${!testname}x != x ]; then
+ [ -n "$LAST_SKIPPED" ] && echo "" && LAST_SKIPPED=
+ run_one_logged $1 "$2"
+ return $?
+ fi
+ testname=ONLY_$base
+ if [ ${!testname}x != x ]; then
+ [ -n "$LAST_SKIPPED" ] && echo "" && LAST_SKIPPED=
+ run_one_logged $1 "$2"
+ return $?
+ fi
+ LAST_SKIPPED="y"
+ return 0
+ fi
LAST_SKIPPED="y"
ALWAYS_SKIPPED="y"
- testname=EXCEPT_$1
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping excluded test $1"
- return 0
- fi
- testname=EXCEPT_$base
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping excluded test $1 (base $base)"
- return 0
- fi
- testname=EXCEPT_ALWAYS_$1
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping ALWAYS excluded test $1"
- return 0
- fi
- testname=EXCEPT_ALWAYS_$base
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping ALWAYS excluded test $1 (base $base)"
- return 0
- fi
- testname=EXCEPT_SLOW_$1
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping SLOW test $1"
- return 0
- fi
- testname=EXCEPT_SLOW_$base
- if [ ${!testname}x != x ]; then
- TESTNAME=test_$1 skip "skipping SLOW test $1 (base $base)"
- return 0
- fi
+ testname=EXCEPT_$1
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping excluded test $1"
+ return 0
+ fi
+ testname=EXCEPT_$base
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping excluded test $1 (base $base)"
+ return 0
+ fi
+ testname=EXCEPT_ALWAYS_$1
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping ALWAYS excluded test $1"
+ return 0
+ fi
+ testname=EXCEPT_ALWAYS_$base
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping ALWAYS excluded test $1 (base $base)"
+ return 0
+ fi
+ testname=EXCEPT_SLOW_$1
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping SLOW test $1"
+ return 0
+ fi
+ testname=EXCEPT_SLOW_$base
+ if [ ${!testname}x != x ]; then
+ TESTNAME=test_$1 skip "skipping SLOW test $1 (base $base)"
+ return 0
+ fi
- LAST_SKIPPED=
- ALWAYS_SKIPPED=
- run_one_logged $1 "$2"
+ LAST_SKIPPED=
+ ALWAYS_SKIPPED=
+ run_one_logged $1 "$2"
- return $?
+ return $?
}
log() {
- echo "$*"
- module_loaded lnet || load_modules
-
- local MSG="$*"
- # Get rid of '
- MSG=${MSG//\'/\\\'}
- MSG=${MSG//\(/\\\(}
- MSG=${MSG//\)/\\\)}
- MSG=${MSG//\;/\\\;}
- MSG=${MSG//\|/\\\|}
- MSG=${MSG//\>/\\\>}
- MSG=${MSG//\</\\\<}
- MSG=${MSG//\//\\\/}
- do_nodes $(comma_list $(nodes_list)) $LCTL mark "$MSG" 2> /dev/null || true
+ echo "$*" >&2
+ load_module ../libcfs/libcfs/libcfs
+
+ local MSG="$HOSTNAME: $*"
+ # Get rid of '
+ MSG=${MSG//\'/\\\'}
+ MSG=${MSG//\(/\\\(}
+ MSG=${MSG//\)/\\\)}
+ MSG=${MSG//\;/\\\;}
+ MSG=${MSG//\|/\\\|}
+ MSG=${MSG//\>/\\\>}
+ MSG=${MSG//\</\\\<}
+ MSG=${MSG//\//\\\/}
+ do_nodes $(comma_list $(nodes_list)) $LCTL mark "$MSG" 2> /dev/null ||
+ true
}
trace() {
reset_fail_loc () {
echo -n "Resetting fail_loc on all nodes..."
- do_nodes $(comma_list $(nodes_list)) "lctl set_param -n fail_loc=0 2>/dev/null || true"
+ do_nodes $(comma_list $(nodes_list)) "lctl set_param -n fail_loc=0 \
+ fail_val=0 2>/dev/null || true"
echo done.
}
log "$msg== $(date +"%H:%M:%S (%s)")"
}
+check_dmesg_for_errors() {
+ local res
+ local errors="VFS: Busy inodes after unmount of\|\
+ldiskfs_check_descriptors: Checksum for group 0 failed\|\
+group descriptors corrupted"
+
+ res=$(do_nodes $(comma_list $(nodes_list)) "dmesg" | grep "$errors")
+ [ -z "$res" ] && return 0
+ echo "Kernel error detected: $res"
+ return 1
+}
+
#
-# Run a single test function and cleanup after it.
+# Run a single test function and cleanup after it.
#
# This function should be run in a subshell so the test func can
# exit() without stopping the whole script.
#
run_one() {
- local testnum=$1
- local message=$2
- tfile=f.${TESTSUITE}.${testnum}
- export tdir=d0.${TESTSUITE}/d${base}
- export TESTNAME=test_$testnum
- local SAVE_UMASK=`umask`
- umask 0022
-
- banner "test $testnum: $message"
- test_${testnum} || error "test_$testnum failed with $?"
- cd $SAVE_PWD
- reset_fail_loc
- check_grant ${testnum} || error "check_grant $testnum failed with $?"
- check_catastrophe || error "LBUG/LASSERT detected"
+ local testnum=$1
+ local message=$2
+ export tfile=f${testnum}.${TESTSUITE}
+ export tdir=d${testnum}.${TESTSUITE}
+ export TESTNAME=test_$testnum
+ local SAVE_UMASK=`umask`
+ umask 0022
+
+ if ! grep -q $DIR /proc/mounts; then
+ $SETUP
+ fi
+
+ banner "test $testnum: $message"
+ test_${testnum} || error "test_$testnum failed with $?"
+ cd $SAVE_PWD
+ reset_fail_loc
+ check_grant ${testnum} || error "check_grant $testnum failed with $?"
+ check_catastrophe || error "LBUG/LASSERT detected"
+ check_dmesg_for_errors || error "Error in dmesg detected"
if [ "$PARALLEL" != "yes" ]; then
ps auxww | grep -v grep | grep -q multiop &&
error "multiop still running"
fi
- unset TESTNAME
- unset tdir
- umask $SAVE_UMASK
- return 0
+ unset TESTNAME
+ unset tdir
+ unset tfile
+ umask $SAVE_UMASK
+ $CLEANUP
+ return 0
}
#
# - test result is saved to data file
#
run_one_logged() {
- local BEFORE=`date +%s`
+ local BEFORE=$(date +%s)
local TEST_ERROR
local name=${TESTSUITE}.test_${1}.test_log.$(hostname -s).log
local test_log=$LOGDIR/$name
+ local zfs_log_name=${TESTSUITE}.test_${1}.zfs_log
+ local zfs_debug_log=$LOGDIR/$zfs_log_name
rm -rf $LOGDIR/err
rm -rf $LOGDIR/ignore
rm -rf $LOGDIR/skip
- local SAVE_UMASK=`umask`
+ local SAVE_UMASK=$(umask)
umask 0022
echo
[ $RC -ne 0 ] && [ ! -f $LOGDIR/err ] &&
echo "test_$1 returned $RC" | tee $LOGDIR/err
- duration=$((`date +%s` - $BEFORE))
+ duration=$(($(date +%s) - $BEFORE))
pass "$1" "(${duration}s)"
if [[ -f $LOGDIR/err ]]; then
fi
log_sub_test_end $TEST_STATUS $duration "$RC" "$TEST_ERROR"
+ if [[ "$TEST_STATUS" != "SKIP" ]] && [[ -f $TF_SKIP ]]; then
+ rm -f $TF_SKIP
+ fi
+
if [ -f $LOGDIR/err ]; then
+ log_zfs_info "$zfs_debug_log"
$FAIL_ON_ERROR && exit $RC
fi
}
canonical_path() {
- (cd `dirname $1`; echo $PWD/`basename $1`)
+ (cd $(dirname $1); echo $PWD/$(basename $1))
}
check_grant() {
- export base=`basetest $1`
- [ "$CHECK_GRANT" == "no" ] && return 0
+ export base=$(basetest $1)
+ [ "$CHECK_GRANT" == "no" ] && return 0
- testname=GCHECK_ONLY_${base}
- [ ${!testname}x == x ] && return 0
+ testname=GCHECK_ONLY_${base}
+ [ ${!testname}x == x ] && return 0
- echo -n "checking grant......"
+ echo -n "checking grant......"
- local clients=$CLIENTS
- [ -z $clients ] && clients=$(hostname)
+ local clients=$CLIENTS
+ [ -z "$clients" ] && clients=$(hostname)
- # sync all the data and make sure no pending data on server
- do_nodes $clients sync
-
- # get client grant
- client_grant=`do_nodes $clients \
- "$LCTL get_param -n osc.${FSNAME}-*.cur_*grant_bytes" | \
- awk '{total += $1} END{print total}'`
-
- # get server grant
- server_grant=`do_nodes $(comma_list $(osts_nodes)) \
- "$LCTL get_param -n obdfilter.${FSNAME}-OST*.tot_granted" |
- awk '{total += $1} END{print total}'`
-
- # check whether client grant == server grant
- if [ $client_grant -ne $server_grant ]; then
- echo "failed: client:${client_grant} server: ${server_grant}."
- do_nodes $(comma_list $(osts_nodes)) \
- "$LCTL get_param obdfilter.${FSNAME}-OST*.tot*"
- do_nodes $clients "$LCTL get_param osc.${FSNAME}-*.cur_*_bytes"
- return 1
- else
- echo "pass: client:${client_grant} server: ${server_grant}"
- fi
+ # sync all the data and make sure no pending data on server
+ do_nodes $clients sync
+
+ # get client grant
+ client_grant=$(do_nodes $clients \
+ "$LCTL get_param -n osc.${FSNAME}-*.cur_*grant_bytes" |
+ awk '{ total += $1 } END { printf("%0.0f", total) }')
+ # get server grant
+ server_grant=$(do_nodes $(comma_list $(osts_nodes)) \
+ "$LCTL get_param -n obdfilter.${FSNAME}-OST*.tot_granted" |
+ awk '{ total += $1 } END { printf("%0.0f", total) }')
+
+ # check whether client grant == server grant
+ if [[ $client_grant -ne $server_grant ]]; then
+ echo "failed: client:${client_grant} server: ${server_grant}."
+ do_nodes $(comma_list $(osts_nodes)) \
+ "$LCTL get_param obdfilter.${FSNAME}-OST*.tot*"
+ do_nodes $clients "$LCTL get_param osc.${FSNAME}-*.cur_*_bytes"
+ return 1
+ else
+ echo "pass: client:${client_grant} server: ${server_grant}"
+ fi
}
########################
remote_mgs_nodsh()
{
+ [ "$CLIENTONLY" ] && return 0 || true
local MGS
MGS=$(facet_host mgs)
remote_node $MGS && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$ost_HOST" ]
}
client_only () {
- [ "$CLIENTONLY" ] || [ "$CLIENTMODSONLY" = yes ]
-}
-
-is_patchless ()
-{
- lctl get_param version | grep -q patchless
+ [ "$CLIENTONLY" ] || [ "$CLIENTMODSONLY" = yes ]
}
check_versions () {
}
setstripe_nfsserver () {
- local dir=$1
+ local dir=$1
- local nfsserver=$(awk '"'$dir'" ~ $2 && $3 ~ "nfs" && $2 != "/" \
- { print $1 }' /proc/mounts | cut -f 1 -d : | head -1)
+ local nfsserver=$(awk '"'$dir'" ~ $2 && $3 ~ "nfs" && $2 != "/" \
+ { print $1 }' /proc/mounts | cut -f 1 -d : | head -n1)
- [ -z $nfsserver ] && echo "$dir is not nfs mounted" && return 1
+ [ -z $nfsserver ] && echo "$dir is not nfs mounted" && return 1
- do_nodev $nfsserver lfs setstripe "$@"
+ do_nodev $nfsserver lfs setstripe "$@"
}
# Check and add a test group.
SECONDS=0
eval '$cmd'
-
+
[ ${PIPESTATUS[0]} -eq 0 ] || rc=1
echo $SECONDS
}
inodes_available () {
- local IFree=$($LFS df -i $MOUNT | grep ^$FSNAME | awk '{print $4}' | sort -un | head -1) || return 1
- echo $IFree
+ local IFree=$($LFS df -i $MOUNT | grep ^$FSNAME | awk '{ print $4 }' |
+ sort -un | head -n1) || return 1
+ echo $((IFree))
}
mdsrate_inodes_available () {
# sum llite stat items
calc_llite_stats() {
- local res=$(lctl get_param -n llite.*.stats |
- awk 'BEGIN {s = 0} END {print s} /^'"$1"'/ {s += $2}')
- echo $res
+ local res=$(lctl get_param -n llite.*.stats |
+ awk '/^'"$1"'/ {sum += $2} END { printf("%0.0f", sum) }')
+ echo $((res))
}
# reset osc stat counters
clear_osc_stats(){
- lctl set_param -n osc.*.osc_stats 0
+ lctl set_param -n osc.*.osc_stats 0
}
# sum osc stat items
calc_osc_stats() {
- local res=$(lctl get_param -n osc.*.osc_stats |
- awk 'BEGIN {s = 0} END {print s} /^'"$1"'/ {s += $2}')
- echo $res
+ local res=$(lctl get_param -n osc.*.osc_stats |
+ awk '/^'"$1"'/ {sum += $2} END { printf("%0.0f", sum) }')
+ echo $((res))
}
calc_sum () {
- awk 'BEGIN {s = 0}; {s += $1}; END {print s}'
+ awk '{sum += $1} END { printf("%0.0f", sum) }'
}
calc_osc_kbytes () {
}
check_catastrophe() {
- local rnodes=${1:-$(comma_list $(remote_nodes_list))}
- local C=$CATASTROPHE
- [ -f $C ] && [ $(cat $C) -ne 0 ] && return 1
-
- [ -z "$rnodes" ] && return 0
-
- local data
- data=$(do_nodes "$rnodes" "rc=\\\$([ -f $C ] &&
- echo \\\$(< $C) || echo 0);
- if [ \\\$rc -ne 0 ]; then echo \\\$(hostname): \\\$rc; fi
- exit \\\$rc")
- local rc=$?
- if [ -n "$data" ]; then
- echo $data
- return $rc
- fi
- return 0
-}
-
-# CMD: determine mds index where directory inode presents
-get_mds_dir () {
- local dir=$1
- local file=$dir/f0.get_mds_dir_tmpfile
+ local nodes=${1:-$(comma_list $(nodes_list))}
- mkdir -p $dir
- rm -f $file
- sleep 1
- local iused=$(lfs df -i $dir | grep MDT | awk '{print $3}')
- local -a oldused=($iused)
-
- openfile -f O_CREAT:O_LOV_DELAY_CREATE -m 0644 $file > /dev/null
- sleep 1
- iused=$(lfs df -i $dir | grep MDT | awk '{print $3}')
- local -a newused=($iused)
-
- local num=0
- for ((i=0; i<${#newused[@]}; i++)); do
- if [ ${oldused[$i]} -lt ${newused[$i]} ]; then
- echo $(( i + 1 ))
- rm -f $file
- return 0
- fi
- done
- error "mdt-s : inodes count OLD ${oldused[@]} NEW ${newused[@]}"
+ do_nodes $nodes "rc=0;
+val=\\\$($LCTL get_param -n catastrophe 2>&1);
+if [[ \\\$? -eq 0 && \\\$val -ne 0 ]]; then
+ echo \\\$(hostname -s): \\\$val;
+ rc=\\\$val;
+fi;
+exit \\\$rc"
}
mdsrate_cleanup () {
}
get_clientosc_proc_path() {
- echo "${1}-osc-*"
-}
-
-get_lustre_version () {
- local facet=${1:-"$SINGLEMDS"}
- do_facet $facet $LCTL get_param -n version | awk '/^lustre:/ {print $2}'
-}
-
-lustre_version_code() {
- local facet=${1:-"$SINGLEMDS"}
- version_code $(get_lustre_version $1)
+ echo "${1}-osc-*"
}
# If the 2.0 MDS was mounted on 1.8 device, then the OSC and LOV names
}
get_mdtosc_proc_path() {
- local mds_facet=$1
- local ost_label=${2:-"*OST*"}
-
- [ "$mds_facet" = "mds" ] && mds_facet=$SINGLEMDS
- local mdt_label=$(convert_facet2label $mds_facet)
- local mdt_index=$(echo $mdt_label | sed -e 's/^.*-//')
-
- if [ $(lustre_version_code $mds_facet) -le $(version_code 1.8.0) ] ||
- mds_on_old_device $mds_facet; then
- echo "${ost_label}-osc"
- else
- echo "${ost_label}-osc-${mdt_index}"
- fi
+ local mds_facet=$1
+ local ost_label=${2:-"*OST*"}
+
+ [ "$mds_facet" = "mds" ] && mds_facet=$SINGLEMDS
+ local mdt_label=$(convert_facet2label $mds_facet)
+ local mdt_index=$(echo $mdt_label | sed -e 's/^.*-//')
+
+ if [ $(lustre_version_code $mds_facet) -le $(version_code 1.8.0) ] ||
+ mds_on_old_device $mds_facet; then
+ echo "${ost_label}-osc"
+ elif [[ $ost_label = *OST* ]]; then
+ echo "${ost_label}-osc-${mdt_index}"
+ else
+ echo "${ost_label}-osp-${mdt_index}"
+ fi
}
get_osc_import_name() {
local expected=$1
local CONN_PROC=$2
local maxtime=${3:-$(max_recovery_time)}
+ local error_on_failure=${4:-1}
local CONN_STATE
local i=0
# reconnect timeout and test can't see real disconnect
[ "${CONN_STATE}" == "CONNECTING" ] && return 0
fi
- [ $i -ge $maxtime ] && \
- error "can't put import for $CONN_PROC into ${expected} state after $i sec, have ${CONN_STATE}" && \
+ if [ $i -ge $maxtime ]; then
+ [ $error_on_failure -ne 0 ] && \
+ error "can't put import for $CONN_PROC into ${expected}" \
+ "state after $i sec, have ${CONN_STATE}"
return 1
+ fi
sleep 1
# Add uniq for multi-mount case
CONN_STATE=$($LCTL get_param -n $CONN_PROC 2>/dev/null | cut -f2 | uniq)
local state=$1
local params=$2
local maxtime=${3:-$(max_recovery_time)}
+ local error_on_failure=${4:-1}
local param
for param in ${params//,/ }; do
- _wait_import_state $state $param $maxtime || return
+ _wait_import_state $state $param $maxtime $error_on_failure || return
done
}
}
_wait_osc_import_state() {
- local facet=$1
- local ost_facet=$2
- local expected=$3
- local ost=$(get_osc_import_name $facet $ost_facet)
-
- local param="osc.${ost}.ost_server_uuid"
+ local facet=$1
+ local ost_facet=$2
+ local expected=$3
+ local target=$(get_osc_import_name $facet $ost_facet)
+ local param="osc.${target}.ost_server_uuid"
+ local params=$param
local i=0
- # 1. wait the deadline of client 1st request (it could be skipped)
- # 2. wait the deadline of client 2nd request
- local maxtime=$(( 2 * $(request_timeout $facet)))
-
- #During setup time, the osc might not be setup, it need wait
- #until list_param can return valid value. And also if there
- #are mulitple osc entries we should list all of them before
- #go to wait.
- local params=$($LCTL list_param $param 2>/dev/null || true)
- while [ -z "$params" ]; do
- if [ $i -ge $maxtime ]; then
- echo "can't get $param by list_param in $maxtime secs"
- if [[ $facet != client* ]]; then
- echo "Go with $param directly"
- params=$param
- break
- else
+ # 1. wait the deadline of client 1st request (it could be skipped)
+ # 2. wait the deadline of client 2nd request
+ local maxtime=$(( 2 * $(request_timeout $facet)))
+
+ if [[ $facet == client* ]]; then
+ # During setup time, the osc might not be setup, it need wait
+ # until list_param can return valid value. And also if there
+ # are mulitple osc entries we should list all of them before
+ # go to wait.
+ params=$($LCTL list_param $param 2>/dev/null || true)
+ while [ -z "$params" ]; do
+ if [ $i -ge $maxtime ]; then
+ echo "can't get $param in $maxtime secs"
return 1
fi
+ sleep 1
+ i=$((i + 1))
+ params=$($LCTL list_param $param 2>/dev/null || true)
+ done
+ fi
+
+ if [[ $ost_facet = mds* ]]; then
+ # no OSP connection to itself
+ if [[ $facet = $ost_facet ]]; then
+ return 0
fi
- sleep 1
- i=$((i + 1))
- params=$($LCTL list_param $param 2>/dev/null || true)
- done
+ param="osp.${target}.mdt_server_uuid"
+ params=$param
+ fi
if ! do_rpc_nodes "$(facet_active_host $facet)" \
wait_import_state $expected "$params" $maxtime; then
fi
}
+_wait_mgc_import_state() {
+ local facet=$1
+ local expected=$2
+ local error_on_failure=${3:-1}
+ local param="mgc.*.mgs_server_uuid"
+ local params=$param
+ local i=0
+
+ # 1. wait the deadline of client 1st request (it could be skipped)
+ # 2. wait the deadline of client 2nd request
+ local maxtime=$(( 2 * $(request_timeout $facet)))
+
+ if [[ $facet == client* ]]; then
+ # During setup time, the osc might not be setup, it need wait
+ # until list_param can return valid value. And also if there
+ # are mulitple osc entries we should list all of them before
+ # go to wait.
+ params=$($LCTL list_param $param 2>/dev/null || true)
+ while [ -z "$params" ]; do
+ if [ $i -ge $maxtime ]; then
+ echo "can't get $param in $maxtime secs"
+ return 1
+ fi
+ sleep 1
+ i=$((i + 1))
+ params=$($LCTL list_param $param 2>/dev/null || true)
+ done
+ fi
+ if ! do_rpc_nodes "$(facet_active_host $facet)" \
+ wait_import_state $expected "$params" $maxtime \
+ $error_on_failure; then
+ if [ $error_on_failure -ne 0 ]; then
+ error "import is not in ${expected} state"
+ fi
+ return 1
+ fi
+
+ return 0
+}
+
+wait_mgc_import_state() {
+ local facet=$1
+ local expected=$2
+ local error_on_failure=${3:-1}
+ local num
+
+ if [[ $facet = mds ]]; then
+ for num in $(seq $MDSCOUNT); do
+ _wait_mgc_import_state mds$num "$expected" \
+ $error_on_failure || return
+ done
+ else
+ _wait_mgc_import_state "$facet" "$expected"
+ $error_on_failure || return
+ fi
+}
+
+wait_dne_interconnect() {
+ local num
+
+ if [ $MDSCOUNT -gt 1 ]; then
+ for num in $(seq $MDSCOUNT); do
+ wait_osc_import_state mds mds$num FULL
+ done
+ fi
+}
+
get_clientmdc_proc_path() {
echo "${1}-mdc-*"
}
+get_clientmgc_proc_path() {
+ echo "*"
+}
+
do_rpc_nodes () {
local list=$1
shift
}
wait_clients_import_state () {
- local list=$1
- local facet=$2
- local expected=$3
+ local list=$1
+ local facet=$2
+ local expected=$3
- local facets=$facet
+ local facets=$facet
- if [ "$FAILURE_MODE" = HARD ]; then
- facets=$(facets_on_host $(facet_active_host $facet))
- fi
+ if [ "$FAILURE_MODE" = HARD ]; then
+ facets=$(facets_on_host $(facet_active_host $facet))
+ fi
- for facet in ${facets//,/ }; do
- local label=$(convert_facet2label $facet)
- local proc_path
- case $facet in
- ost* ) proc_path="osc.$(get_clientosc_proc_path $label).ost_server_uuid" ;;
- mds* ) proc_path="mdc.$(get_clientmdc_proc_path $label).mds_server_uuid" ;;
- *) error "unknown facet!" ;;
- esac
- local params=$(expand_list $params $proc_path)
- done
+ for facet in ${facets//,/ }; do
+ local label=$(convert_facet2label $facet)
+ local proc_path
+ case $facet in
+ ost* ) proc_path="osc.$(get_clientosc_proc_path \
+ $label).ost_server_uuid" ;;
+ mds* ) proc_path="mdc.$(get_clientmdc_proc_path \
+ $label).mds_server_uuid" ;;
+ mgs* ) proc_path="mgc.$(get_clientmgc_proc_path \
+ $label).mgs_server_uuid" ;;
+ *) error "unknown facet!" ;;
+ esac
- if ! do_rpc_nodes "$list" wait_import_state_mount $expected $params; then
+ local params=$(expand_list $params $proc_path)
+ done
+
+ if ! do_rpc_nodes "$list" wait_import_state_mount $expected $params;
+ then
error "import is not in ${expected} state"
return 1
fi
}
add_pool_to_list () {
- local fsname=${1%%.*}
- local poolname=${1##$fsname.}
+ local fsname=${1%%.*}
+ local poolname=${1##$fsname.}
- local listvar=${fsname}_CREATED_POOLS
- eval export ${listvar}=$(expand_list ${!listvar} $poolname)
+ local listvar=${fsname}_CREATED_POOLS
+ local temp=${listvar}=$(expand_list ${!listvar} $poolname)
+ eval export $temp
}
remove_pool_from_list () {
- local fsname=${1%%.*}
- local poolname=${1##$fsname.}
+ local fsname=${1%%.*}
+ local poolname=${1##$fsname.}
- local listvar=${fsname}_CREATED_POOLS
- eval export ${listvar}=$(exclude_items_from_list ${!listvar} $poolname)
+ local listvar=${fsname}_CREATED_POOLS
+ local temp=${listvar}=$(exclude_items_from_list ${!listvar} $poolname)
+ eval export $temp
}
destroy_pool_int() {
return $rc
}
-# target_start_and_reset_recovery_timer()
-# service_time = at_est2timeout(service_time);
-# service_time += 2 * (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC +
-# INITIAL_CONNECT_TIMEOUT);
-# CONNECTION_SWITCH_MAX : min(25U, max(CONNECTION_SWITCH_MIN,obd_timeout))
-#define CONNECTION_SWITCH_INC 1
-#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN,obd_timeout/20)
-#define CONNECTION_SWITCH_MIN 5U
+# check_and_start_recovery_timer()
+# service_time = at_est2timeout(service_time);
+# service_time += 2 * INITIAL_CONNECT_TIMEOUT;
+# service_time += 2 * (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC);
-max_recovery_time () {
- local init_connect_timeout=$(( TIMEOUT / 20 ))
- [[ $init_connect_timeout -ge 5 ]] || init_connect_timeout=5
+#define INITIAL_CONNECT_TIMEOUT max(CONNECTION_SWITCH_MIN, obd_timeout/20)
+#define CONNECTION_SWITCH_MAX min(50, max(CONNECTION_SWITCH_MIN, obd_timeout))
+#define CONNECTION_SWITCH_MIN 5
+#define CONNECTION_SWITCH_INC 5
+max_recovery_time() {
+ local init_connect_timeout=$((TIMEOUT / 20))
+ ((init_connect_timeout >= 5)) || init_connect_timeout=5
- local service_time=$(( $(at_max_get client) + $(( 2 * $(( 25 + 1 + init_connect_timeout)) )) ))
+ local service_time=$(($(at_max_get client) * 9 / 4 + 5))
+ service_time=$((service_time + 2 * (init_connect_timeout + 50 + 5)))
- echo $service_time
+ echo -n $service_time
+}
+
+recovery_time_min() {
+ local connection_switch_min=5
+ local connection_switch_inc=5
+ local connection_switch_max
+ local reconnect_delay_max
+ local initial_connect_timeout
+ local max
+ local timout_20
+
+ #connection_switch_max=min(50, max($connection_switch_min,$TIMEOUT)
+ (($connection_switch_min > $TIMEOUT)) &&
+ max=$connection_switch_min || max=$TIMEOUT
+ (($max < 50)) && connection_switch_max=$max || connection_switch_max=50
+
+ #initial_connect_timeout = max(connection_switch_min, obd_timeout/20)
+ timeout_20=$((TIMEOUT/20))
+ (($connection_switch_min > $timeout_20)) &&
+ initial_connect_timeout=$connection_switch_min ||
+ initial_connect_timeout=$timeout_20
+
+ reconnect_delay_max=$((connection_switch_max + connection_switch_inc + \
+ initial_connect_timeout))
+ echo $((2 * reconnect_delay_max))
}
get_clients_mount_count () {
}
#
+# Get the available size (KB) of a given obd target.
+#
+get_obd_size() {
+ local facet=$1
+ local obd=$2
+ local size
+
+ [[ $facet != client ]] || return 0
+
+ size=$(do_facet $facet $LCTL get_param -n *.$obd.kbytesavail | head -n1)
+ echo -n $size
+}
+
+#
+# Get the page size (bytes) on a given facet node.
+#
+get_page_size() {
+ local facet=$1
+ local size
+
+ size=$(do_facet $facet getconf PAGE_SIZE)
+ [[ ${PIPESTATUS[0]} = 0 && -n "$size" ]] || size=4096
+ echo -n $size
+}
+
+#
# Get the block count of the filesystem.
#
get_block_count() {
reformat_external_journal() {
local facet=$1
+ local var
- if [ ! -z ${EJOURNAL} ]; then
+ var=${facet}_JRN
+ if [ -n "${!var}" ]; then
local rcmd="do_facet $facet"
- echo "reformat external journal on $facet:${EJOURNAL}"
- ${rcmd} mke2fs -O journal_dev ${EJOURNAL} || return 1
+ echo "reformat external journal on $facet:${!var}"
+ ${rcmd} mke2fs -O journal_dev ${!var} || return 1
fi
}
echo "backup data"
${rcmd} tar zcf $metadata -C $mntpt/ . > /dev/null 2>&1 || return 3
# step 6: umount
- ${rcmd} umount -d $mntpt || return 4
- # step 7: reformat external journal if needed
- reformat_external_journal $facet || return 5
+ ${rcmd} $UMOUNT $mntpt || return 4
# step 8: reformat dev
echo "reformat new device"
- add $facet $(mkfs_opts $facet ${devname}) --backfstype ldiskfs \
- --reformat ${devname} $(mdsvdevname $(facet_number $facet)) \
- > /dev/null || exit 6
+ format_mdt $(facet_number $facet)
# step 9: mount dev
${rcmd} mount -t ldiskfs $opts $devname $mntpt || return 7
# step 10: restore metadata
echo "remove recovery logs"
${rcmd} rm -fv $mntpt/OBJECTS/* $mntpt/CATALOGS
# step 13: umount dev
- ${rcmd} umount -d $mntpt || return 10
+ ${rcmd} $UMOUNT $mntpt || return 10
# step 14: cleanup tmp backup
${rcmd} rm -f $metaea $metadata
# step 15: reset device label - it's not virgin on
done
fi
# step 4: umount
- ${rcmd} umount -d $mntpt || return 2
+ ${rcmd} $UMOUNT $mntpt || return 2
# OI files will be recreated when mounted as lustre next time.
}
# make directory on different MDTs
test_mkdir() {
- local option
- local parent
- local child
local path
- local rc=0
-
- case $# in
- 1) path=$1;;
- 2) option=$1
- path=$2;;
- *) error "Only creating single directory is supported";;
- esac
+ local p_option
+ local stripe_count=2
+ local stripe_index=-1
+ local OPTIND=1
+
+ while getopts "c:i:p" opt; do
+ case $opt in
+ c) stripe_count=$OPTARG;;
+ i) stripe_index=$OPTARG;;
+ p) p_option="-p";;
+ \?) error "only support -i -c -p";;
+ esac
+ done
- child=$(basename $path)
- parent=$(dirname $path)
+ shift $((OPTIND - 1))
+ [ $# -eq 1 ] || error "Only creating single directory is supported"
+ path="$*"
- if [ "$option" == "-p" -a -d $parent/$child ]; then
- return $rc
- fi
+ if [ "$p_option" == "-p" ]; then
+ local parent=$(dirname $path)
- if [ ! -d ${parent} ]; then
- if [ "$option" == "-p" ]; then
- mkdir -p ${parent}
- else
- return 1
- fi
+ [ -d $path ] && return 0
+ [ ! -d ${parent} ] && mkdir -p ${parent}
fi
if [ $MDSCOUNT -le 1 ]; then
- mkdir $option $parent/$child || rc=$?
+ mkdir $path
else
- local mdt_idx=$($LFS getstripe -M $parent)
local test_num=$(echo $testnum | sed -e 's/[^0-9]*//g')
+ local mdt_index
- if [ "$mdt_idx" -ne 0 ]; then
- mkdir $option $parent/$child || rc=$?
+ if [ $stripe_index -eq -1 ]; then
+ mdt_index=$((test_num % MDSCOUNT))
else
- mdt_idx=$((test_num % MDSCOUNT))
- echo "mkdir $mdt_idx for $parent/$child"
- $LFS setdirstripe -i $mdt_idx $parent/$child || rc=$?
+ mdt_index=$stripe_index
fi
+ echo "striped dir -i$mdt_index -c$stripe_count $path"
+ $LFS setdirstripe -i$mdt_index -c$stripe_count $path
fi
- return $rc
}
# find the smallest and not in use file descriptor
[ $fd -lt $max_fd ] || error "finding free file descriptor failed"
echo $fd
}
+
+check_mount_and_prep()
+{
+ is_mounted $MOUNT || setupall
+
+ rm -rf $DIR/[df][0-9]* || error "Fail to cleanup the env!"
+ mkdir $DIR/$tdir || error "Fail to mkdir $DIR/$tdir."
+ for idx in $(seq $MDSCOUNT); do
+ local name="MDT$(printf '%04x' $((idx - 1)))"
+ rm -rf $MOUNT/.lustre/lost+found/$name/*
+ done
+}
+
+# calcule how many ost-objects to be created.
+precreated_ost_obj_count()
+{
+ local mdt_idx=$1
+ local ost_idx=$2
+ local mdt_name="MDT$(printf '%04x' $mdt_idx)"
+ local ost_name="OST$(printf '%04x' $ost_idx)"
+ local proc_path="${FSNAME}-${ost_name}-osc-${mdt_name}"
+ local last_id=$(do_facet mds$((mdt_idx + 1)) lctl get_param -n \
+ osp.$proc_path.prealloc_last_id)
+ local next_id=$(do_facet mds$((mdt_idx + 1)) lctl get_param -n \
+ osp.$proc_path.prealloc_next_id)
+ echo $((last_id - next_id + 1))
+}
+
+check_file_in_pool()
+{
+ local file=$1
+ local pool=$2
+ local tlist="$3"
+ local res=$($GETSTRIPE $file | grep 0x | cut -f2)
+ for i in $res
+ do
+ for t in $tlist ; do
+ [ "$i" -eq "$t" ] && continue 2
+ done
+
+ echo "pool list: $tlist"
+ echo "striping: $res"
+ error_noexit "$file not allocated in $pool"
+ return 1
+ done
+ return 0
+}
+
+pool_add() {
+ echo "Creating new pool"
+ local pool=$1
+
+ create_pool $FSNAME.$pool ||
+ { error_noexit "No pool created, result code $?"; return 1; }
+ [ $($LFS pool_list $FSNAME | grep -c "$FSNAME.${pool}\$") -eq 1 ] ||
+ { error_noexit "$pool not in lfs pool_list"; return 2; }
+}
+
+pool_add_targets() {
+ echo "Adding targets to pool"
+ local pool=$1
+ local first=$2
+ local last=$3
+ local step=${4:-1}
+
+ local list=$(seq $first $step $last)
+
+ local t=$(for i in $list; do printf "$FSNAME-OST%04x_UUID " $i; done)
+ do_facet mgs $LCTL pool_add \
+ $FSNAME.$pool $FSNAME-OST[$first-$last/$step]
+ wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool \
+ | sort -u | tr '\n' ' ' " "$t" || {
+ error_noexit "Add to pool failed"
+ return 1
+ }
+ local lfscount=$($LFS pool_list $FSNAME.$pool | grep -c "\-OST")
+ local addcount=$(((last - first) / step + 1))
+ [ $lfscount -eq $addcount ] || {
+ error_noexit "lfs pool_list bad ost count" \
+ "$lfscount != $addcount"
+ return 2
+ }
+}
+
+pool_set_dir() {
+ local pool=$1
+ local tdir=$2
+ echo "Setting pool on directory $tdir"
+
+ $SETSTRIPE -c 2 -p $pool $tdir && return 0
+
+ error_noexit "Cannot set pool $pool to $tdir"
+ return 1
+}
+
+pool_check_dir() {
+ local pool=$1
+ local tdir=$2
+ echo "Checking pool on directory $tdir"
+
+ local res=$($GETSTRIPE --pool $tdir | sed "s/\s*$//")
+ [ "$res" = "$pool" ] && return 0
+
+ error_noexit "Pool on '$tdir' is '$res', not '$pool'"
+ return 1
+}
+
+pool_dir_rel_path() {
+ echo "Testing relative path works well"
+ local pool=$1
+ local tdir=$2
+ local root=$3
+
+ mkdir -p $root/$tdir/$tdir
+ cd $root/$tdir
+ pool_set_dir $pool $tdir || return 1
+ pool_set_dir $pool ./$tdir || return 2
+ pool_set_dir $pool ../$tdir || return 3
+ pool_set_dir $pool ../$tdir/$tdir || return 4
+ rm -rf $tdir; cd - > /dev/null
+}
+
+pool_alloc_files() {
+ echo "Checking files allocation from directory pool"
+ local pool=$1
+ local tdir=$2
+ local count=$3
+ local tlist="$4"
+
+ local failed=0
+ for i in $(seq -w 1 $count)
+ do
+ local file=$tdir/file-$i
+ touch $file
+ check_file_in_pool $file $pool "$tlist" || \
+ failed=$((failed + 1))
+ done
+ [ "$failed" = 0 ] && return 0
+
+ error_noexit "$failed files not allocated in $pool"
+ return 1
+}
+
+pool_create_files() {
+ echo "Creating files in pool"
+ local pool=$1
+ local tdir=$2
+ local count=$3
+ local tlist="$4"
+
+ mkdir -p $tdir
+ local failed=0
+ for i in $(seq -w 1 $count)
+ do
+ local file=$tdir/spoo-$i
+ $SETSTRIPE -p $pool $file
+ check_file_in_pool $file $pool "$tlist" || \
+ failed=$((failed + 1))
+ done
+ [ "$failed" = 0 ] && return 0
+
+ error_noexit "$failed files not allocated in $pool"
+ return 1
+}
+
+pool_lfs_df() {
+ echo "Checking 'lfs df' output"
+ local pool=$1
+
+ local t=$($LCTL get_param -n lov.$FSNAME-clilov-*.pools.$pool |
+ tr '\n' ' ')
+ local res=$($LFS df --pool $FSNAME.$pool |
+ awk '{print $1}' |
+ grep "$FSNAME-OST" |
+ tr '\n' ' ')
+ [ "$res" = "$t" ] && return 0
+
+ error_noexit "Pools OSTs '$t' is not '$res' that lfs df reports"
+ return 1
+}
+
+pool_file_rel_path() {
+ echo "Creating files in a pool with relative pathname"
+ local pool=$1
+ local tdir=$2
+
+ mkdir -p $tdir ||
+ { error_noexit "unable to create $tdir"; return 1 ; }
+ local file="/..$tdir/$tfile-1"
+ $SETSTRIPE -p $pool $file ||
+ { error_noexit "unable to create $file" ; return 2 ; }
+
+ cd $tdir
+ $SETSTRIPE -p $pool $tfile-2 || {
+ error_noexit "unable to create $tfile-2 in $tdir"
+ return 3
+ }
+}
+
+pool_remove_first_target() {
+ echo "Removing first target from a pool"
+ local pool=$1
+
+ local pname="lov.$FSNAME-*.pools.$pool"
+ local t=$($LCTL get_param -n $pname | head -1)
+ do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
+ wait_update $HOSTNAME "lctl get_param -n $pname | grep $t" "" || {
+ error_noexit "$t not removed from $FSNAME.$pool"
+ return 1
+ }
+}
+
+pool_remove_all_targets() {
+ echo "Removing all targets from pool"
+ local pool=$1
+ local file=$2
+ local pname="lov.$FSNAME-*.pools.$pool"
+ for t in $($LCTL get_param -n $pname | sort -u)
+ do
+ do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
+ done
+ wait_update $HOSTNAME "lctl get_param -n $pname" "" || {
+ error_noexit "Pool $FSNAME.$pool cannot be drained"
+ return 1
+ }
+ # striping on an empty/nonexistant pool should fall back
+ # to "pool of everything"
+ touch $file || {
+ error_noexit "failed to use fallback striping for empty pool"
+ return 2
+ }
+ # setstripe on an empty pool should fail
+ $SETSTRIPE -p $pool $file 2>/dev/null && {
+ error_noexit "expected failure when creating file" \
+ "with empty pool"
+ return 3
+ }
+ return 0
+}
+
+pool_remove() {
+ echo "Destroying pool"
+ local pool=$1
+ local file=$2
+
+ do_facet mgs $LCTL pool_destroy $FSNAME.$pool
+
+ sleep 2
+ # striping on an empty/nonexistant pool should fall back
+ # to "pool of everything"
+ touch $file || {
+ error_noexit "failed to use fallback striping for missing pool"
+ return 1
+ }
+ # setstripe on an empty pool should fail
+ $SETSTRIPE -p $pool $file 2>/dev/null && {
+ error_noexit "expected failure when creating file" \
+ "with missing pool"
+ return 2
+ }
+
+ # get param should return err once pool is gone
+ if wait_update $HOSTNAME "lctl get_param -n \
+ lov.$FSNAME-*.pools.$pool 2>/dev/null || echo foo" "foo"
+ then
+ remove_pool_from_list $FSNAME.$pool
+ return 0
+ fi
+ error_noexit "Pool $FSNAME.$pool is not destroyed"
+ return 3
+}
+
+# Get and check the actual stripe count of one file.
+# Usage: check_stripe_count <file> <expected_stripe_count>
+check_stripe_count() {
+ local file=$1
+ local expected=$2
+ local actual
+
+ [[ -z "$file" || -z "$expected" ]] &&
+ error "check_stripe_count: invalid argument"
+
+ local cmd="$GETSTRIPE -c $file"
+ actual=$($cmd) || error "$cmd failed"
+ actual=${actual%% *}
+
+ if [[ $actual -ne $expected ]]; then
+ [[ $expected -eq -1 ]] ||
+ error "$cmd wrong: found $actual, expected $expected"
+ [[ $actual -eq $OSTCOUNT ]] ||
+ error "$cmd wrong: found $actual, expected $OSTCOUNT"
+ fi
+}
+
+# Get and check the actual list of OST indices on one file.
+# Usage: check_obdidx <file> <expected_comma_separated_list_of_ost_indices>
+check_obdidx() {
+ local file=$1
+ local expected=$2
+ local obdidx
+
+ [[ -z "$file" || -z "$expected" ]] &&
+ error "check_obdidx: invalid argument!"
+
+ obdidx=$(comma_list $($GETSTRIPE $file | grep -A $OSTCOUNT obdidx |
+ grep -v obdidx | awk '{print $1}' | xargs))
+
+ [[ $obdidx = $expected ]] ||
+ error "list of OST indices on $file is $obdidx," \
+ "should be $expected"
+}
+
+# Get and check the actual OST index of the first stripe on one file.
+# Usage: check_start_ost_idx <file> <expected_start_ost_idx>
+check_start_ost_idx() {
+ local file=$1
+ local expected=$2
+ local start_ost_idx
+
+ [[ -z "$file" || -z "$expected" ]] &&
+ error "check_start_ost_idx: invalid argument!"
+
+ start_ost_idx=$($GETSTRIPE $file | grep -A 1 obdidx | grep -v obdidx |
+ awk '{print $1}')
+
+ [[ $start_ost_idx = $expected ]] ||
+ error "OST index of the first stripe on $file is" \
+ "$start_ost_idx, should be $expected"
+}
+
+killall_process () {
+ local clients=${1:-$(hostname)}
+ local name=$2
+ local signal=$3
+ local rc=0
+
+ do_nodes $clients "killall $signal $name"
+}