#set -x
export LANG=en_US
-export EJOURNAL=${EJOURNAL:-""}
export REFORMAT=${REFORMAT:-""}
export WRITECONF=${WRITECONF:-""}
export VERBOSE=${VERBOSE:-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)}
print_summary () {
trap 0
+ [ -z "$DEFAULT_SUITES"] && return 0
[ "$TESTSUITE" == "lfsck" ] && return 0
[ -n "$ONLY" ] && echo "WARNING: ONLY is set to $(echo $ONLY)"
local details
# 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" ] && \
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/\([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 ../ldiskfs/ldiskfs
load_module osd-ldiskfs/osd_ldiskfs
fi
- load_module nodemap/nodemap
load_module mgs/mgs
load_module mdd/mdd
load_module mdt/mdt
# 'mount' doesn't look in $PATH, just sbin
local mount_lustre=$LUSTRE/utils/mount.lustre
if [ -f $mount_lustre ]; then
- local sbin_mount=/sbin/mount.lustre
- if grep -qe "$sbin_mount " /proc/mounts; then
- cmp $mount_lustre $sbin_mount || umount $sbin_mount
+ 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 -qe "$sbin_mount " /proc/mounts; then
+ 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"
fi
fi
- local sbin_mount=/sbin/mount.lustre
+ 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 ||
${!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
+ 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
+ local fstype=$(facet_fstype $facet)
+
+ 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
+
+ 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
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
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 etime
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
}
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]}
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
}
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.
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 ${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 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
fs_mkfs_opts+="-O large_xattr"
fi
- fs_mkfs_opts+=${MDSJOURNALSIZE:+" -J size=$MDSJOURNALSIZE"}
- if [ ! -z $EJOURNAL ]; then
- fs_mkfs_opts+=${MDSJOURNALSIZE:+" device=$EJOURNAL"}
+ 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
done
}
-formatall() {
+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
}
+cifs_client_mode () {
+ [ x$CIFSCLIENT = xyes ] &&
+ echo "CIFSCLIENT=$CIFSCLIENT mode: setup, cleanup, check config skipped"
+}
+
check_config_client () {
local mntpt=$1
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
+ cifs_client_mode && return
local MOUNTED=$(mounted_lustre_filesystems)
return $rc
}
+dump_file_contents() {
+ local nodes=$1
+ local dir=$2
+ local logname=$3
+ local node
+
+ 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
+}
+
+dump_command_output() {
+ local nodes=$1
+ local cmd=$2
+ local logname=$3
+ local node
+
+ if [ -z "$nodes" -o -z "$cmd" -o -z "$logname" ]; then
+ error_noexit false \
+ "Invalid parameters for dump_command_output()"
+ return 1
+ fi
+
+ for node in ${nodes}; do
+ do_node $node "echo ====${cmd}=======================;
+ $cmd" >> ${logname}.${node}.log
+ done
+}
+
+log_zfs_info() {
+ local logname=$1
+
+ # 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
+
+ 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
}
drop_update_reply() {
-# OBD_FAIL_UPDATE_OBJ_NET_REP
+# OBD_FAIL_OUT_UPDATE_NET_REP
local index=$1
shift 1
RC=0
}
drop_bl_callback_once() {
- rc=0
+ local 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=0x80000305
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
}
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
}
}
# prints bash call stack
-log_trace_dump() {
+print_stack_trace() {
echo " Trace dump:"
for (( i=1; i < ${#BASH_LINENO[*]} ; i++ )) ; do
local s=${BASH_SOURCE[$i]}
log " ${TESTSUITE} ${TESTNAME}: @@@@@@ ${TYPE}: $@ "
- log_trace_dump
+ print_stack_trace >&2
mkdir -p $LOGDIR
# We need to dump the logs on all nodes
}
log() {
- echo "$*"
- module_loaded lnet || load_modules
+ echo "$*" >&2
+ load_module ../libcfs/libcfs/libcfs
local MSG="$*"
# Get rid of '
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
fi
if [ -f $LOGDIR/err ]; then
+ log_zfs_info "$zfs_debug_log"
$FAIL_ON_ERROR && exit $RC
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" ]
}
check_catastrophe() {
- local rnodes=${1:-$(comma_list $(remote_nodes_list))}
- VAR=$(lctl get_param -n catastrophe 2>&1)
- if [ $? = 0 ] ; then
- if [ $VAR != 0 ]; then
- return 1
- fi
- fi
+ local nodes=${1:-$(comma_list $(nodes_list))}
- [ -z "$rnodes" ] && return 0
-
- local data
- data=$(do_nodes "$rnodes" "rc=\\\$(lctl get_param -n catastrophe);
- 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 SEQ
-
- SEQ=$(lfs path2fid $dir | tr '[:]' ' '|cut -f2 -d ' ')
- if [ "$SEQ" == "" ]; then
- error "can't get sequence for $dir"
- return 1
- fi
- export SEQ
-
- do_facet mds1 "cat /proc/fs/lustre/fld/srv-*-MDT0000/fldb" | \
- tr '[)]:-' ' ' | \
- while read SS EE IDX TYP; do \
- if let "SEQ >= SS && SEQ < EE"; then \
- echo $IDX; \
- fi; \
- done
+ 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
}
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 target=$(get_osc_import_name $facet $ost_facet)
+ local param="osc.${target}.ost_server_uuid"
local params=$param
local i=0
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
+ param="osp.${target}.mdt_server_uuid"
+ params=$param
+ fi
+
if ! do_rpc_nodes "$(facet_active_host $facet)" \
wait_import_state $expected "$params" $maxtime; then
error "import is not in ${expected} state"
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
+
+ local params=$(expand_list $params $proc_path)
+ done
- if ! do_rpc_nodes "$list" wait_import_state_mount $expected $params; then
+ if ! do_rpc_nodes "$list" wait_import_state_mount $expected $params;
+ then
error "import is not in ${expected} state"
return 1
fi
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
}
get_clients_mount_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 p_option
- local option2
local stripe_count=2
- local rc=0
-
- case $# in
- 1) path=$1;;
- 2) option=$1
- path=$2;;
- 3) option=$1
- option2=$2
- path=$3;;
- *) error "Only creating single directory is supported";;
- esac
-
- child=$(basename $path)
- parent=$(dirname $path)
-
- if [ "$option" == "-p" -o "$option2" == "-p" ]; then
- if [ -d $parent/$child ]; then
- return $rc
- fi
- p_option="-p"
- fi
+ 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
- if [ "${option:0:2}" == "-c" ]; then
- stripe_count=$(echo $option | sed 's/^-c//')
- fi
+ shift $((OPTIND - 1))
+ [ $# -eq 1 ] || error "Only creating single directory is supported"
+ path="$*"
- if [ "${option2:0:2}" == "-c" ]; then
- stripe_count=$(echo $option2 | sed 's/^-c//')
- fi
+ if [ "$p_option" == "-p" ]; then
+ local parent=$(dirname $path)
- if [ ! -d ${parent} ]; then
- if [ "$p_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 $p_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
- mdt_idx=$((test_num % MDSCOUNT))
- echo "striped dir -i$mdt_idx -c$stripe_count $path"
- $LFS setdirstripe -i$mdt_idx -c$stripe_count $path || rc=$?
+ if [ $stripe_index -eq -1 ]; then
+ mdt_index=$((test_num % MDSCOUNT))
+ else
+ 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
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.
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} lctl get_param -n \
+ 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} lctl get_param -n \
+ 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))
}
create_pool $FSNAME.$pool ||
{ error_noexit "No pool created, result code $?"; return 1; }
- [ $($LFS pool_list $FSNAME | grep -c $pool) -eq 1 ] ||
+ [ $($LFS pool_list $FSNAME | grep -c "$FSNAME.${pool}\$") -eq 1 ] ||
{ error_noexit "$pool not in lfs pool_list"; return 2; }
}
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"
+}