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"}
# function used by scripts run on remote nodes
LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
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)"
[ ! -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}
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//\./ })
module_loaded () {
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
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
-
- # '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=/sbin/mount.lustre
+ if grep -qe "$sbin_mount " /proc/mounts; then
+ cmp $mount_lustre $sbin_mount || umount $sbin_mount
+ fi
+ if ! grep -qe "$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=/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
}
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
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() {
rc=$?
do_nodes $(comma_list $(osts_nodes)) \
lctl get_param obdfilter.${fsname}-OST*.quota_type || rc=$?
- return $rc
+ return $rc
}
# XXX This function is kept for interoperability with old server (< 2.3.50),
zconf_mount() {
local client=$1
local mnt=$2
- local OPTIONS=${3:-$MOUNTOPT}
+ local opts=${3:-$MOUNT_OPTS}
+ opts=${opts:+-o $opts}
+ local flags=${4:-$MOUNT_FLAGS}
local device=$MGSNID:/$FSNAME
if [ -z "$mnt" -o -z "$FSNAME" ]; then
- echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
+ echo Bad zconf mount command: opt=$flags $opts dev=$device mnt=$mnt
exit 1
fi
- echo "Starting client: $client: $OPTIONS $device $mnt"
+ echo "Starting client: $client: $flags $opts $device $mnt"
do_node $client mkdir -p $mnt
- do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
+ do_node $client $MOUNT_CMD $flags $opts $device $mnt || return 1
set_default_debug_nodes $client
zconf_mount_clients() {
local clients=$1
local mnt=$2
- local OPTIONS=${3:-$MOUNTOPT}
+ local opts=${3:-$MOUNT_OPTS}
+ opts=${opts:+-o $opts}
+ local flags=${4:-$MOUNT_FLAGS}
local device=$MGSNID:/$FSNAME
if [ -z "$mnt" -o -z "$FSNAME" ]; then
- echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
+ echo Bad zconf 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"
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]}
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
wait_delete_completed_mds() {
local MAX_WAIT=${1:-20}
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"
return
fi
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
opts+=${L_GETIDENTITY:+" --param=mdt.identity_upcall=$L_GETIDENTITY"}
if [ $fstype == ldiskfs ]; then
+ # Check for wide striping
+ if [ $OSTCOUNT -gt 160 ]; then
+ MDSJOURNALSIZE=${MDSJOURNALSIZE:-4096}
+ fs_mkfs_opts+="-O large_xattr"
+ fi
+
fs_mkfs_opts+=${MDSJOURNALSIZE:+" -J size=$MDSJOURNALSIZE"}
if [ ! -z $EJOURNAL ]; then
fs_mkfs_opts+=${MDSJOURNALSIZE:+" device=$EJOURNAL"}
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
}
#
# Run e2fsck on MDT and OST(s) to generate databases used for lfsck.
generate_db() {
- local i
- local ostidx
- local dev
+ local i
+ local ostidx
+ local dev
+ local node
[[ $(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
+ check_shared_dir $SHARED_DIRECTORY ||
+ error "$SHARED_DIRECTORY isn't a shared directory"
- [ $MDSCOUNT -eq 1 ] || error "CMD is not supported"
+ export MDSDB=$SHARED_DIRECTORY/mdsdb
+ export OSTDB=$SHARED_DIRECTORY/ostdb
- run_e2fsck $(mdts_nodes) $MDTDEV "-n --mdsdb $MDSDB"
+ # DNE is not supported, so when running e2fsck on a DNE filesystem,
+ # we only pass master MDS parameters.
+ run_e2fsck $MDTNODE $MDTDEV "-n --mdsdb $MDSDB"
i=0
ostidx=0
fi
#Run lfsck
echo $cmd
- do_node $node $cmd || rc=$?
+ do_node $client $cmd || rc=$?
#Umount if necessary
if ! $mounted; then
zconf_umount $client $MOUNT ||
[ "$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() {
return $RC
}
-drop_bl_callback() {
+drop_bl_callback_once() {
+ 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 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 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
}
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'
+
+ if [ $1 != "MGC" ]; then
+ 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'
+ else
+ for d in $(find \
+ /{proc,sys}/fs/lustre/ldlm/namespaces/*$1*/lru_size \
+ 2> /dev/null); do
+ echo "clear" > $d
+ done
+
+ for d in $(find \
+ /{proc,sys}/fs/lustre/ldlm/namespaces/*$1*/lock_unused_count \
+ 2> /dev/null); do
+ if [ $(cat $d) != 0 ]; then
+ echo "ldlm.namespaces.$(echo "$d" |
+ cut -f 7 -d'/').lock_unused_count=$(cat $d)"
+ fi
+ done
+ fi
+
$LCTL mark "cancel_lru_locks $1 stop"
}
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
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() {
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.
}
}
#
-# 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
+
+ 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"
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
+ 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
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
$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
}
########################
}
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
+ VAR=$(lctl get_param -n catastrophe 2>&1)
+ if [ $? = 0 ] ; then
+ if [ $VAR != 0 ]; then
+ return 1
+ fi
+ fi
[ -z "$rnodes" ] && return 0
local data
- data=$(do_nodes "$rnodes" "rc=\\\$([ -f $C ] &&
- echo \\\$(< $C) || echo 0);
+ data=$(do_nodes "$rnodes" "rc=\\\$(lctl get_param -n catastrophe);
if [ \\\$rc -ne 0 ]; then echo \\\$(hostname): \\\$rc; fi
exit \\\$rc")
local rc=$?
}
_wait_osc_import_state() {
- local facet=$1
- local ost_facet=$2
- local expected=$3
- local ost=$(get_osc_import_name $facet $ost_facet)
-
+ 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 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
- fi
- sleep 1
- i=$((i + 1))
- params=$($LCTL list_param $param 2>/dev/null || true)
- done
-
+ 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; then
error "import is not in ${expected} state"
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" -a -d $parent/$child ]; then
- return $rc
+ if [ "$option" == "-p" -o "$option2" == "-p" ]; then
+ if [ -d $parent/$child ]; then
+ return $rc
+ fi
+ p_option="-p"
+ fi
+
+ if [ "${option:0:2}" == "-c" ]; then
+ stripe_count=$(echo $option | sed 's/^-c//')
+ fi
+
+ if [ "${option2:0:2}" == "-c" ]; then
+ stripe_count=$(echo $option2 | sed 's/^-c//')
fi
if [ ! -d ${parent} ]; then
- if [ "$option" == "-p" ]; then
+ if [ "$p_option" == "-p" ]; then
mkdir -p ${parent}
else
return 1
fi
if [ $MDSCOUNT -le 1 ]; then
- mkdir $option $parent/$child || rc=$?
+ mkdir $p_option $parent/$child || rc=$?
else
local mdt_idx=$($LFS getstripe -M $parent)
local test_num=$(echo $testnum | sed -e 's/[^0-9]*//g')
- if [ "$mdt_idx" -ne 0 ]; then
- mkdir $option $parent/$child || rc=$?
- else
- mdt_idx=$((test_num % MDSCOUNT))
- echo "mkdir $mdt_idx for $parent/$child"
- $LFS setdirstripe -i $mdt_idx $parent/$child || rc=$?
- fi
+ 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=$?
fi
return $rc
}
[ $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."
+}
+
+# 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} lctl get_param -n \
+ osp.$proc_path.prealloc_last_id)
+ local next_id=$(do_facet mds${mdt_idx} 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 $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
+}