Whamcloud - gitweb
LU-8687 tests: list pool on mds when mgs is separate
[fs/lustre-release.git] / lustre / tests / test-framework.sh
index 7a9cb6b..ffc5253 100755 (executable)
@@ -17,10 +17,6 @@ export QUOTA_AUTO=1
 # specify environment variable containing batch job name for server statistics
 export JOBID_VAR=${JOBID_VAR:-"procname_uid"}  # or "existing" or "disable"
 
-# LOAD_LLOOP: LU-409: only load llite_lloop module if kernel < 2.6.32 or
-#             LOAD_LLOOP is true. LOAD_LLOOP is false by default.
-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"}
@@ -59,7 +55,7 @@ sanitize_parameters() {
        do
                local path=${!i}
                if [ -d "$path" ]; then
-                       eval export $i=$(echo $path | sed -E 's/\/+$//g')
+                       eval export $i=$(echo $path | sed -r 's/\/+$//g')
                fi
        done
 }
@@ -142,6 +138,7 @@ init_test_env() {
        export TEST_FAILED=false
        export FAIL_ON_SKIP_ENV=${FAIL_ON_SKIP_ENV:-false}
        export RPC_MODE=${RPC_MODE:-false}
+       export DO_CLEANUP=${DO_CLEANUP:-true}
 
     export MKE2FS=$MKE2FS
     if [ -z "$MKE2FS" ]; then
@@ -269,6 +266,8 @@ init_test_env() {
     fi
     export LL_DECODE_FILTER_FID=${LL_DECODE_FILTER_FID:-"$LUSTRE/utils/ll_decode_filter_fid"}
     [ ! -f "$LL_DECODE_FILTER_FID" ] && export LL_DECODE_FILTER_FID="ll_decode_filter_fid"
+    export LL_DECODE_LINKEA=${LL_DECODE_LINKEA:-"$LUSTRE/utils/ll_decode_linkea"}
+    [ ! -f "$LL_DECODE_LINKEA" ] && export LL_DECODE_LINKEA="ll_decode_linkea"
     export MKFS=${MKFS:-"$LUSTRE/utils/mkfs.lustre"}
     [ ! -f "$MKFS" ] && export MKFS="mkfs.lustre"
     export TUNEFS=${TUNEFS:-"$LUSTRE/utils/tunefs.lustre"}
@@ -293,6 +292,8 @@ init_test_env() {
     export DIR2
     export SAVE_PWD=${SAVE_PWD:-$LUSTRE/tests}
     export AT_MAX_PATH
+    export LDEV=${LDEV:-"$LUSTRE/scripts/ldev"}
+    [ ! -f "$LDEV" ] && export LDEV=$(which ldev 2> /dev/null)
 
     if [ "$ACCEPTOR_PORT" ]; then
         export PORT_OPT="--port $ACCEPTOR_PORT"
@@ -333,20 +334,20 @@ init_test_env() {
        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}
@@ -401,9 +402,7 @@ export LINUX_VERSION_CODE=$(version_code ${LINUX_VERSION//\./ })
 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
+       # lustre: 2.8.52
        local VER=$(do_facet $facet $LCTL get_param -n version 2> /dev/null |
                    awk '/lustre: / { print $2 }')
        # lctl 2.6.50
@@ -493,20 +492,6 @@ load_module() {
        fi
 }
 
-llite_lloop_enabled() {
-    local n1=$(uname -r | cut -d. -f1)
-    local n2=$(uname -r | cut -d. -f2)
-    local n3=$(uname -r | cut -d- -f1 | cut -d. -f3)
-
-    # load the llite_lloop module for < 2.6.32 kernels
-    if [[ $n1 -lt 2 ]] || [[ $n1 -eq 2 && $n2 -lt 6 ]] || \
-       [[ $n1 -eq 2 && $n2 -eq 6 && $n3 -lt 32 ]] || \
-        $LOAD_LLOOP; then
-        return 0
-    fi
-    return 1
-}
-
 load_modules_local() {
        if [ -n "$MODPROBE" ]; then
                # use modprobe
@@ -545,6 +530,9 @@ load_modules_local() {
        fi
 
        load_module ../libcfs/libcfs/libcfs
+       # Prevent local MODOPTS_LIBCFS being passed as part of environment
+       # variable to remote nodes
+       unset MODOPTS_LIBCFS
 
     [ "$PTLDEBUG" ] && lctl set_param debug="$PTLDEBUG"
     [ "$SUBSYSTEM" ] && lctl set_param subsystem_debug="${SUBSYSTEM# }"
@@ -569,13 +557,15 @@ load_modules_local() {
     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
@@ -583,6 +573,8 @@ load_modules_local() {
                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
@@ -594,10 +586,9 @@ load_modules_local() {
                load_module osp/osp
                load_module ofd/ofd
                load_module osp/osp
-    fi
+       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
@@ -695,6 +686,18 @@ fs_log_size() {
        echo -n $size
 }
 
+fs_inode_ksize() {
+       local facet=${1:-$SINGLEMDS}
+       local fstype=$(facet_fstype $facet)
+       local size=0
+       case $fstype in
+               ldiskfs) size=4;;  # ~4KB per inode
+               zfs)     size=11;; # 10 to 11KB per inode
+       esac
+
+       echo -n $size
+}
+
 check_gss_daemon_nodes() {
     local list=$1
     dname=$2
@@ -973,6 +976,20 @@ facet_vdevice() {
        echo -n $device
 }
 
+running_in_vm() {
+       local virt=$(virt-what 2> /dev/null)
+
+       [ $? -eq 0 ] && [ -n "$virt" ] && { echo $virt; return; }
+
+       virt=$(dmidecode -s system-product-name | awk '{print $1}')
+
+       case $virt in
+               VMware|KVM|VirtualBox|Parallels)
+                       echo $virt | tr '[A-Z]' '[a-z]' ;;
+               *) ;;
+       esac
+}
+
 #
 # Re-read the partition table on failover partner host.
 # After a ZFS storage pool is created on a shared device, the partition table
@@ -1020,7 +1037,8 @@ create_zpool() {
        shift 3
        local opts=${@:-"-o cachefile=none"}
 
-       do_facet $facet "$ZPOOL list -H $poolname >/dev/null 2>&1 ||
+       do_facet $facet "modprobe zfs;
+               $ZPOOL list -H $poolname >/dev/null 2>&1 ||
                $ZPOOL create -f $opts $poolname $vdev"
 }
 
@@ -1086,7 +1104,8 @@ import_zpool() {
 
        if [[ -n "$poolname" ]]; then
                opts+=" -d $(dirname $(facet_vdevice $facet))"
-               do_facet $facet "$ZPOOL list -H $poolname >/dev/null 2>&1 ||
+               do_facet $facet "modprobe zfs;
+                       $ZPOOL list -H $poolname >/dev/null 2>&1 ||
                        $ZPOOL import -f $opts $poolname"
        fi
 }
@@ -1144,7 +1163,7 @@ set_debug_size () {
     if [ -f /sys/devices/system/cpu/possible ]; then
         local cpus=$(($(cut -d "-" -f 2 /sys/devices/system/cpu/possible)+1))
     else
-        local cpus=$(getconf _NPROCESSORS_CONF)
+        local cpus=$(getconf _NPROCESSORS_CONF 2>/dev/null)
     fi
 
     # bug 19944, adjust size to be -gt num_possible_cpus()
@@ -1186,6 +1205,15 @@ set_default_debug_facet () {
     set_default_debug_nodes $node
 }
 
+set_hostid () {
+    local hostid=${1:-$(hostid)}
+
+    if [ ! -s /etc/hostid ]; then
+       printf $(echo -n $hostid |
+           sed 's/\(..\)\(..\)\(..\)\(..\)/\\x\4\\x\3\\x\2\\x\1/') >/etc/hostid
+    fi
+}
+
 # Facet functions
 mount_facets () {
        local facets=${1:-$(get_facets)}
@@ -1272,6 +1300,11 @@ mount_facet() {
                return $RC
        fi
 
+       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
@@ -1301,7 +1334,9 @@ mount_facet() {
 
        # commit the device label change to disk
        if [[ $devicelabel =~ (:[a-zA-Z]{3}[0-9]{4}) ]]; then
+               echo "Commit the device label on ${!dev}"
                do_facet $facet "sync; sync; sync"
+               sleep 5
        fi
 
 
@@ -1545,7 +1580,7 @@ zconf_umount() {
     local client=$1
     local mnt=$2
     local force
-    local busy 
+    local busy
     local need_kill
 
     [ "$3" ] && force=-f
@@ -1586,13 +1621,13 @@ if [ \\\$running -ne \\\$mpts ]; then
     echo \\\$(hostname) env are INSANE!;
     exit 1;
 fi"
-    [ $? -eq 0 ] || rc=1 
+    [ $? -eq 0 ] || rc=1
     done
     return $rc
 }
 
 sanity_mount_check_servers () {
-    [ "$CLIENTONLY" ] && 
+    [ -n "$CLIENTONLY" ] &&
         { echo "CLIENTONLY mode, skip mount_check_servers"; return 0; } || true
     echo Checking servers environments
 
@@ -1714,7 +1749,7 @@ shutdown_node_hard () {
         wait_for_function --quiet "! ping -w 3 -c 1 $host" 5 1 && return 0
         echo "waiting for $host to fail attempts=$attempts"
         [ $i -lt $attempts ] || \
-            { echo "$host still pingable after power down! attempts=$attempts" && return 1; } 
+            { echo "$host still pingable after power down! attempts=$attempts" && return 1; }
     done
 }
 
@@ -1885,55 +1920,59 @@ start_client_loads () {
 
 # only for remote client
 check_client_load () {
-    local client=$1
-    local var=$(node_var_name $client)_load
-    local TESTLOAD=run_${!var}.sh
-
-    ps auxww | grep -v grep | grep $client | grep -q "$TESTLOAD" || return 1
-
-    # bug 18914: try to connect several times not only when
-    # check ps, but  while check_catastrophe also
-    local tries=3
-    local RC=254
-    while [ $RC = 254 -a $tries -gt 0 ]; do
-        let tries=$tries-1
-        # assume success
-        RC=0
-        if ! check_catastrophe $client; then
-            RC=${PIPESTATUS[0]}
-            if [ $RC -eq 254 ]; then
-                # FIXME: not sure how long we shuold sleep here
-                sleep 10
-                continue
-            fi
-            echo "check catastrophe failed: RC=$RC "
-            return $RC
-        fi
-    done
-    # We can continue try to connect if RC=254
-    # Just print the warning about this
-    if [ $RC = 254 ]; then
-        echo "got a return status of $RC from do_node while checking catastrophe on $client"
-    fi
-
-    # see if the load is still on the client
-    tries=3
-    RC=254
-    while [ $RC = 254 -a $tries -gt 0 ]; do
-        let tries=$tries-1
-        # assume success
-        RC=0
-        if ! do_node $client "ps auxwww | grep -v grep | grep -q $TESTLOAD"; then
-            RC=${PIPESTATUS[0]}
-            sleep 30
-        fi
-    done
-    if [ $RC = 254 ]; then
-        echo "got a return status of $RC from do_node while checking (catastrophe and 'ps') the client load on $client"
-        # see if we can diagnose a bit why this is
-    fi
+       local client=$1
+       local var=$(node_var_name $client)_load
+       local testload=run_${!var}.sh
+
+       ps auxww | grep -v grep | grep $client | grep -q $testload || return 1
+
+       # bug 18914: try to connect several times not only when
+       # check ps, but  while check_node_health also
+
+       local tries=3
+       local RC=254
+       while [ $RC = 254 -a $tries -gt 0 ]; do
+               let tries=$tries-1
+               # assume success
+               RC=0
+               if ! check_node_health $client; then
+                       RC=${PIPESTATUS[0]}
+                       if [ $RC -eq 254 ]; then
+                               # FIXME: not sure how long we shuold sleep here
+                               sleep 10
+                               continue
+                       fi
+                       echo "check node health failed: RC=$RC "
+                       return $RC
+               fi
+       done
+       # We can continue try to connect if RC=254
+       # Just print the warning about this
+       if [ $RC = 254 ]; then
+               echo "got a return status of $RC from do_node while checking " \
+               "node health on $client"
+       fi
+
+       # see if the load is still on the client
+       tries=3
+       RC=254
+       while [ $RC = 254 -a $tries -gt 0 ]; do
+               let tries=$tries-1
+               # assume success
+               RC=0
+               if ! do_node $client \
+                       "ps auxwww | grep -v grep | grep -q $testload"; then
+                       RC=${PIPESTATUS[0]}
+                       sleep 30
+               fi
+       done
+       if [ $RC = 254 ]; then
+               echo "got a return status of $RC from do_node while checking " \
+               "(node health and 'ps') the client load on $client"
+               # see if we can diagnose a bit why this is
+       fi
 
-    return $RC
+       return $RC
 }
 check_client_loads () {
    local clients=${1//,/ }
@@ -2129,6 +2168,15 @@ sync_all_data() {
                grep -v 'Found no match'
 }
 
+wait_zfs_commit() {
+       # the occupied disk space will be released
+       # only after DMUs are committed
+       if [[ $(facet_fstype $1) == zfs ]]; then
+               echo "sleep $2 for ZFS OSD"
+               sleep $2
+       fi
+}
+
 wait_delete_completed_mds() {
        local MAX_WAIT=${1:-20}
        # for ZFS, waiting more time for DMUs to be committed
@@ -2149,6 +2197,7 @@ wait_delete_completed_mds() {
                mds2sync="$mds2sync $node"
        done
        if [ -z "$mds2sync" ]; then
+               wait_zfs_commit $SINGLEMDS $ZFS_WAIT
                return
        fi
        mds2sync=$(comma_list $mds2sync)
@@ -2166,16 +2215,7 @@ wait_delete_completed_mds() {
                        "$LCTL get_param -n osc.*MDT*.sync_*" | calc_sum)
                #echo "$node: $changes changes on all"
                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
-
+                       wait_zfs_commit $SINGLEMDS $ZFS_WAIT
                        return
                fi
                sleep 1
@@ -2382,25 +2422,27 @@ wait_remote_prog () {
     return $rc
 }
 
+lfs_df_check() {
+       local clients=${1:-$CLIENTS}
+
+       if [ -z "$clients" ]; then
+               $LFS df $MOUNT
+       else
+               $PDSH $clients "$LFS df $MOUNT" > /dev/null
+       fi
+}
+
+
 clients_up() {
-    # not every config has many clients
-    sleep 1
-    if [ ! -z "$CLIENTS" ]; then
-        $PDSH $CLIENTS "stat -f $MOUNT" > /dev/null
-    else
-        stat -f $MOUNT > /dev/null
-    fi
+       # not every config has many clients
+       sleep 1
+       lfs_df_check
 }
 
 client_up() {
-    local client=$1
-    # usually checked on particular client or locally
-    sleep 1
-    if [ ! -z "$client" ]; then
-        $PDSH $client "stat -f $MOUNT" > /dev/null
-    else
-        stat -f $MOUNT > /dev/null
-    fi
+       # usually checked on particular client or locally
+       sleep 1
+       lfs_df_check $1
 }
 
 client_evicted() {
@@ -2408,16 +2450,17 @@ client_evicted() {
 }
 
 client_reconnect_try() {
-    uname -n >> $MOUNT/recon
-    if [ -z "$CLIENTS" ]; then
-        df $MOUNT; uname -n >> $MOUNT/recon
-    else
-        do_nodes $CLIENTS "df $MOUNT; uname -n >> $MOUNT/recon" > /dev/null
-    fi
-    echo Connected clients:
-    cat $MOUNT/recon
-    ls -l $MOUNT/recon > /dev/null
-    rm $MOUNT/recon
+       local f=$MOUNT/recon
+
+       uname -n >> $f
+       if [ -z "$CLIENTS" ]; then
+               $LFS df $MOUNT; uname -n >> $f
+       else
+               do_nodes $CLIENTS "$LFS df $MOUNT; uname -n >> $f" > /dev/null
+       fi
+       echo "Connected clients: $(cat $f)"
+       ls -l $f > /dev/null
+       rm $f
 }
 
 client_reconnect() {
@@ -2512,7 +2555,7 @@ obd_name() {
 replay_barrier() {
        local facet=$1
        do_facet $facet "sync; sync; sync"
-       df $MOUNT
+       $LFS df $MOUNT
 
        # make sure there will be no seq change
        local clients=${CLIENTS:-$HOSTNAME}
@@ -2597,7 +2640,7 @@ fail() {
 
        facet_failover $* || error "failover: $?"
        wait_clients_import_state "$clients" "$facets" FULL
-       clients_up || error "post-failover df: $?"
+       clients_up || error "post-failover stat: $?"
 }
 
 fail_nodf() {
@@ -2611,8 +2654,8 @@ fail_abort() {
        change_active $facet
        wait_for_facet $facet
        mount_facet $facet -o abort_recovery
-       clients_up || echo "first df failed: $?"
-       clients_up || error "post-failover df: $?"
+       clients_up || echo "first stat failed: $?"
+       clients_up || error "post-failover stat: $?"
 }
 
 do_lmc() {
@@ -3219,7 +3262,7 @@ facet_mntpt () {
     [[ $facet = mgs ]] && combined_mgs_mds && facet="mds1"
 
     local var=${facet}_MOUNT
-    eval mntpt=${!var:-${MOUNT%/*}/$facet}
+    eval mntpt=${!var:-${MOUNT}-$facet}
 
     echo -n $mntpt
 }
@@ -3227,7 +3270,7 @@ facet_mntpt () {
 mount_ldiskfs() {
        local facet=$1
        local dev=$(facet_device $facet)
-       local mnt=$(facet_mntpt $facet)
+       local mnt=${2:-$(facet_mntpt $facet)}
        local opts
 
        if ! do_facet $facet test -b $dev; then
@@ -3239,7 +3282,7 @@ mount_ldiskfs() {
 unmount_ldiskfs() {
        local facet=$1
        local dev=$(facet_device $facet)
-       local mnt=$(facet_mntpt $facet)
+       local mnt=${2:-$(facet_mntpt $facet)}
 
        do_facet $facet $UMOUNT $mnt
 }
@@ -3251,7 +3294,7 @@ var_name() {
 mount_zfs() {
        local facet=$1
        local ds=$(facet_device $facet)
-       local mnt=$(facet_mntpt $facet)
+       local mnt=${2:-$(facet_mntpt $facet)}
        local canmnt
        local mntpt
 
@@ -3274,7 +3317,7 @@ mount_zfs() {
 unmount_zfs() {
        local facet=$1
        local ds=$(facet_device $facet)
-       local mnt=$(facet_mntpt $facet)
+       local mnt=${2:-$(facet_mntpt $facet)}
        local var_mntpt=mz_$(var_name ${facet}_$ds)_mountpoint
        local var_canmnt=mz_$(var_name ${facet}_$ds)_canmount
        local mntpt=${!var_mntpt}
@@ -3290,16 +3333,18 @@ unmount_zfs() {
 
 mount_fstype() {
        local facet=$1
+       local mnt=$2
        local fstype=$(facet_fstype $facet)
 
-       mount_$fstype $facet
+       mount_$fstype $facet $mnt
 }
 
 unmount_fstype() {
        local facet=$1
+       local mnt=$2
        local fstype=$(facet_fstype $facet)
 
-       unmount_$fstype $facet
+       unmount_$fstype $facet $mnt
 }
 
 ########
@@ -3319,7 +3364,8 @@ stopall() {
     zconf_umount_clients $clients $MOUNT "$*" || true
     [ -n "$MOUNT2" ] && zconf_umount_clients $clients $MOUNT2 "$*" || true
 
-    [ "$CLIENTONLY" ] && return
+    [ -n "$CLIENTONLY" ] && return
+
     # The add fn does rm ${facet}active file, this would be enough
     # if we use do_facet <facet> only after the facet added, but
     # currently we use do_facet mds in local.sh
@@ -3342,12 +3388,14 @@ stopall() {
 }
 
 cleanup_echo_devs () {
-    local devs=$($LCTL dl | grep echo | awk '{print $4}')
+       trap 0
+       local dev
+       local devs=$($LCTL dl | grep echo | awk '{print $4}')
 
-    for dev in $devs; do
-        $LCTL --device $dev cleanup
-        $LCTL --device $dev detach
-    done
+       for dev in $devs; do
+               $LCTL --device $dev cleanup
+               $LCTL --device $dev detach
+       done
 }
 
 cleanupall() {
@@ -3408,7 +3456,6 @@ mkfs_opts() {
        opts+=${LDLM_TIMEOUT:+" --param=sys.ldlm_timeout=$LDLM_TIMEOUT"}
 
        if [ $type == MDS ]; then
-               opts+=${SECLEVEL:+" --param=mdt.sec_level"}
                opts+=${MDSCAPA:+" --param-mdt.capa=$MDSCAPA"}
                opts+=${STRIPE_BYTES:+" --param=lov.stripesize=$STRIPE_BYTES"}
                opts+=${STRIPES_PER_OBJ:+" --param=lov.stripecount=$STRIPES_PER_OBJ"}
@@ -3432,7 +3479,6 @@ mkfs_opts() {
        fi
 
        if [ $type == OST ]; then
-               opts+=${SECLEVEL:+" --param=ost.sec_level"}
                opts+=${OSSCAPA:+" --param=ost.capa=$OSSCAPA"}
 
                if [ $fstype == ldiskfs ]; then
@@ -3527,9 +3573,16 @@ format_ost() {
 
 formatall() {
        stopall
+       # Set hostid for ZFS/SPL zpool import protection
+       # (Assumes MDS version is also OSS version)
+       if [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.8.54) ];
+       then
+           do_rpc_nodes "$(comma_list $(remote_nodes_list))" set_hostid
+       fi
+
        # We need ldiskfs here, may as well load them all
        load_modules
-       [ "$CLIENTONLY" ] && return
+       [ -n "$CLIENTONLY" ] && return
        echo Formatting mgs, mds, osts
        if ! combined_mgs_mds ; then
                format_mgs
@@ -3619,21 +3672,19 @@ writeconf_all () {
 }
 
 setupall() {
-    nfs_client_mode && return
+       nfs_client_mode && return
        cifs_client_mode && return
 
-    sanity_mount_check ||
-        error "environments are insane!"
+       sanity_mount_check || error "environments are insane!"
 
-    load_modules
+       load_modules
 
-    if [ -z "$CLIENTONLY" ]; then
-        echo Setup mgs, mdt, osts
-        echo $WRITECONF | grep -q "writeconf" && \
-            writeconf_all
-        if ! combined_mgs_mds ; then
+       if [ -z "$CLIENTONLY" ]; then
+               echo Setup mgs, mdt, osts
+               echo $WRITECONF | grep -q "writeconf" && writeconf_all
+               if ! combined_mgs_mds ; then
                        start mgs $(mgsdevname) $MGS_MOUNT_OPTS
-        fi
+               fi
 
         for num in `seq $MDSCOUNT`; do
             DEVNAME=$(mdsdevname $num)
@@ -3702,7 +3753,7 @@ mounted_lustre_filesystems() {
 }
 
 init_facet_vars () {
-       [ "$CLIENTONLY" ] && return 0
+       [ -n "$CLIENTONLY" ] && return 0
        local facet=$1
        shift
        local device=$1
@@ -3827,14 +3878,17 @@ set_conf_param_and_check() {
        do_facet mgs "$LCTL conf_param $PARAM='$FINAL'" ||
                error "conf_param $PARAM failed"
 
-       wait_update $(facet_host $myfacet) "$TEST" "$FINAL" ||
+       wait_update_facet $myfacet "$TEST" "$FINAL" ||
                error "check $PARAM failed!"
 }
 
 init_param_vars () {
-       remote_mds_nodsh ||
-               TIMEOUT=$(do_facet $SINGLEMDS "lctl get_param -n timeout")
+       TIMEOUT=$(lctl get_param -n timeout)
+       TIMEOUT=${TIMEOUT:-20}
+
+       remote_mds_nodsh && log "Using TIMEOUT=$TIMEOUT" && return 0
 
+       TIMEOUT=$(do_facet $SINGLEMDS "lctl get_param -n timeout")
        log "Using TIMEOUT=$TIMEOUT"
 
        osc_ensure_active $SINGLEMDS $TIMEOUT
@@ -3895,14 +3949,14 @@ check_config_client () {
     local mntpt=$1
 
     local mounted=$(mount | grep " $mntpt ")
-    if [ "$CLIENTONLY" ]; then
+    if [ -n "$CLIENTONLY" ]; then
         # bug 18021
         # CLIENTONLY should not depend on *_HOST settings
         local mgc=$($LCTL device_list | awk '/MGC/ {print $4}')
         # in theory someone could create a new,
         # client-only config file that assumed lustre was already
         # configured and didn't set the MGSNID. If MGSNID is not set,
-        # then we should use the mgs nid currently being used 
+        # then we should use the mgs nid currently being used
         # as the default value. bug 18021
         [[ x$MGSNID = x ]] &&
             MGSNID=${mgc//MGC/}
@@ -3917,9 +3971,9 @@ check_config_client () {
         return 0
     fi
 
-    local myMGS_host=$mgs_HOST   
+    local myMGS_host=$mgs_HOST
     if [ "$NETTYPE" = "ptl" ]; then
-        myMGS_host=$(h2ptl $mgs_HOST | sed -e s/@ptl//) 
+        myMGS_host=$(h2ptl $mgs_HOST | sed -e s/@ptl//)
     fi
 
     echo Checking config lustre mounted on $mntpt
@@ -3991,15 +4045,15 @@ check_and_setup_lustre() {
        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
+       # 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
@@ -4022,7 +4076,7 @@ check_and_setup_lustre() {
                     restore_mount $MOUNT2
                     export I_MOUNTED2=yes
                 fi
-            fi 
+            fi
 
     # 5.
     # MOUNT is mounted MOUNT2 is not mounted
@@ -4043,7 +4097,7 @@ check_and_setup_lustre() {
         set_default_debug_nodes $(comma_list $(nodes_list))
     fi
 
-       if [ $(lower $OSD_TRACK_DECLARES_LBUG) == 'yes' ] ; then
+       if [ -z "$CLIENTONLY" -a $(lower $OSD_TRACK_DECLARES_LBUG) == 'yes' ]; then
                local facets=""
                [ "$(facet_fstype ost1)" = "ldiskfs" ] &&
                        facets="$(get_facets OST)"
@@ -4063,12 +4117,14 @@ check_and_setup_lustre() {
                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 [ -z "$CLIENTONLY" ]; then
+               # 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
+       fi
 
        if [ "$ONLY" == "setup" ]; then
                exit 0
@@ -4287,8 +4343,12 @@ check_and_cleanup_lustre() {
        fi
 
        if is_mounted $MOUNT; then
-               [ -n "$DIR" ] && rm -rf $DIR/[Rdfs][0-9]* ||
-                       error "remove sub-test dirs failed"
+               if $DO_CLEANUP; then
+                       [ -n "$DIR" ] && rm -rf $DIR/[Rdfs][0-9]* ||
+                               error "remove sub-test dirs failed"
+               else
+                       echo "skip cleanup"
+               fi
                [ "$ENABLE_QUOTA" ] && restore_quota || true
        fi
 
@@ -4611,7 +4671,8 @@ clear_failloc() {
 }
 
 set_nodes_failloc () {
-       do_nodes $(comma_list $1)  lctl set_param fail_val=0 fail_loc=$2
+       local fv=${3:-0}
+       do_nodes $(comma_list $1)  lctl set_param fail_val=$fv fail_loc=$2
 }
 
 cancel_lru_locks() {
@@ -4658,13 +4719,21 @@ pgcache_empty() {
 }
 
 debugsave() {
-    DEBUGSAVE="$(lctl get_param -n debug)"
+       DEBUGSAVE="$(lctl get_param -n debug)"
+       DEBUGSAVE_SERVER=$(do_facet $SINGLEMDS "$LCTL get_param -n debug")
 }
 
 debugrestore() {
-    [ -n "$DEBUGSAVE" ] && \
-        do_nodes $(comma_list $(nodes_list)) "$LCTL set_param debug=\\\"${DEBUGSAVE}\\\";"
-    DEBUGSAVE=""
+       [ -n "$DEBUGSAVE" ] &&
+               do_nodes $CLIENTS "$LCTL set_param debug=\\\"${DEBUGSAVE}\\\""||
+               true
+       DEBUGSAVE=""
+
+       [ -n "$DEBUGSAVE_SERVER" ] &&
+               do_nodes $(comma_list $(all_server_nodes)) \
+                        "$LCTL set_param debug=\\\"${DEBUGSAVE_SERVER}\\\"" ||
+                        true
+       DEBUGSAVE_SERVER=""
 }
 
 debug_size_save() {
@@ -4782,6 +4851,18 @@ error_and_remount() {
        exit 1
 }
 
+# Throw an error if it's not running in vm - usually for performance
+# verification
+error_not_in_vm() {
+       local virt=$(running_in_vm)
+       if [[ -n "$virt" ]]; then
+               echo "running in VM '$virt', ignore error"
+               error_ignore env=$virt "$@"
+       else
+               error "$@"
+       fi
+}
+
 skip_env () {
        $FAIL_ON_SKIP_ENV && error false $@ || skip $@
 }
@@ -4967,17 +5048,17 @@ check_mds() {
 }
 
 reset_fail_loc () {
-    echo -n "Resetting fail_loc on all nodes..."
-    do_nodes $(comma_list $(nodes_list)) "lctl set_param -n fail_loc=0 \
-           fail_val=0 2>/dev/null || true"
-    echo done.
+       echo -n "Resetting fail_loc on all nodes..."
+       do_nodes $(comma_list $(nodes_list)) "lctl set_param -n fail_loc=0 \
+           fail_val=0 2>/dev/null" || true
+       echo done.
 }
 
 
 #
-# Log a message (on all nodes) padded with "=" before and after. 
+# Log a message (on all nodes) padded with "=" before and after.
 # Also appends a timestamp and prepends the testsuite name.
-# 
+#
 
 EQUALS="===================================================================================================="
 banner() {
@@ -5025,7 +5106,7 @@ run_one() {
        cd $SAVE_PWD
        reset_fail_loc
        check_grant ${testnum} || error "check_grant $testnum failed with $?"
-       check_catastrophe || error "LBUG/LASSERT detected"
+       check_node_health
        check_dmesg_for_errors || error "Error in dmesg detected"
        if [ "$PARALLEL" != "yes" ]; then
                ps auxww | grep -v grep | grep -q multiop &&
@@ -5228,15 +5309,15 @@ remote_mds ()
 
 remote_mds_nodsh()
 {
-    [ "$CLIENTONLY" ] && return 0 || true
-    remote_mds && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$mds_HOST" ]
+       [ -n "$CLIENTONLY" ] && return 0 || true
+       remote_mds && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$mds_HOST" ]
 }
 
 require_dsh_mds()
 {
-        remote_mds_nodsh && echo "SKIP: $TESTSUITE: remote MDS with nodsh" && \
-            MSKIPPED=1 && return 1
-        return 0
+       remote_mds_nodsh && echo "SKIP: $TESTSUITE: remote MDS with nodsh" &&
+               MSKIPPED=1 && return 1
+       return 0
 }
 
 remote_ost ()
@@ -5250,8 +5331,8 @@ remote_ost ()
 
 remote_ost_nodsh()
 {
-    [ "$CLIENTONLY" ] && return 0 || true 
-    remote_ost && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$ost_HOST" ]
+       [ -n "$CLIENTONLY" ] && return 0 || true
+       remote_ost && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$ost_HOST" ]
 }
 
 require_dsh_ost()
@@ -5263,10 +5344,10 @@ require_dsh_ost()
 
 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" ]
+       [ -n "$CLIENTONLY" ] && return 0 || true
+       local MGS
+       MGS=$(facet_host mgs)
+       remote_node $MGS && [ "$PDSH" = "no_dsh" -o -z "$PDSH" -o -z "$ost_HOST" ]
 }
 
 local_mode ()
@@ -5427,19 +5508,14 @@ get_random_entry () {
     rnodes=${rnodes//,/ }
 
     local -a nodes=($rnodes)
-    local num=${#nodes[@]} 
+    local num=${#nodes[@]}
     local i=$((RANDOM * num * 2 / 65536))
 
     echo ${nodes[i]}
 }
 
 client_only () {
-    [ "$CLIENTONLY" ] || [ "$CLIENTMODSONLY" = yes ]
-}
-
-is_patchless ()
-{
-    lctl get_param version | grep -q patchless
+       [ -n "$CLIENTONLY" ] || [ "x$CLIENTMODSONLY" = "xyes" ]
 }
 
 check_versions () {
@@ -5726,16 +5802,21 @@ restore_lustre_params() {
        done
 }
 
-check_catastrophe() {
+check_node_health() {
        local nodes=${1:-$(comma_list $(nodes_list))}
 
-       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"
+       for node in ${nodes//,/ }; do
+               check_network "$node" 5
+               if [ $? -eq 0 ]; then
+                       do_node $node "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" || error "$node:LBUG/LASSERT detected"
+               fi
+       done
 }
 
 mdsrate_cleanup () {
@@ -6124,27 +6205,41 @@ oos_full() {
        return $OSCFULL
 }
 
-pool_list () {
-   do_facet mgs lctl pool_list $1
+list_pool() {
+       echo -e "$(do_facet $SINGLEMDS $LCTL pool_list $1 | sed '1d')"
+}
+
+check_pool_not_exist() {
+       local fsname=${1%%.*}
+       local poolname=${1##$fsname.}
+       [[ $# -ne 1 ]] && return 0
+       [[ x$poolname = x ]] &&  return 0
+       list_pool $fsname | grep -w $1 && return 1
+       return 0
 }
 
 create_pool() {
-    local fsname=${1%%.*}
-    local poolname=${1##$fsname.}
-
-    do_facet mgs lctl pool_new $1
-    local RC=$?
-    # get param should return err unless pool is created
-    [[ $RC -ne 0 ]] && return $RC
-
-    wait_update $HOSTNAME "lctl get_param -n lov.$fsname-*.pools.$poolname \
-        2>/dev/null || echo foo" "" || RC=1
-    if [[ $RC -eq 0 ]]; then
-        add_pool_to_list $1
-    else
-        error "pool_new failed $1"
-    fi
-    return $RC
+       local fsname=${1%%.*}
+       local poolname=${1##$fsname.}
+
+       do_facet mgs lctl pool_new $1
+       local RC=$?
+       # get param should return err unless pool is created
+       [[ $RC -ne 0 ]] && return $RC
+
+       for mds_id in $(seq $MDSCOUNT); do
+               local mdt_id=$((mds_id-1))
+               local lodname=$fsname-MDT$(printf "%04x" $mdt_id)-mdtlov
+               wait_update_facet mds$mds_id \
+                       "lctl get_param -n lod.$lodname.pools.$poolname \
+                               2>/dev/null || echo foo" "" ||
+                       error "mds$mds_id: pool_new failed $1"
+       done
+       wait_update $HOSTNAME "lctl get_param -n lov.$fsname-*.pools.$poolname \
+               2>/dev/null || echo foo" "" || error "pool_new failed $1"
+
+       add_pool_to_list $1
+       return $RC
 }
 
 add_pool_to_list () {
@@ -6166,39 +6261,43 @@ remove_pool_from_list () {
 }
 
 destroy_pool_int() {
-    local ost
-    local OSTS=$(do_facet $SINGLEMDS lctl pool_list $1 | \
-        awk '$1 !~ /^Pool:/ {print $1}')
-    for ost in $OSTS; do
-        do_facet mgs lctl pool_remove $1 $ost
-    done
-    do_facet mgs lctl pool_destroy $1
+       local ost
+       local OSTS=$(list_pool $1)
+       for ost in $OSTS; do
+               do_facet mgs lctl pool_remove $1 $ost
+       done
+       do_facet mgs lctl pool_destroy $1
 }
 
 # <fsname>.<poolname> or <poolname>
 destroy_pool() {
-    local fsname=${1%%.*}
-    local poolname=${1##$fsname.}
+       local fsname=${1%%.*}
+       local poolname=${1##$fsname.}
 
-    [[ x$fsname = x$poolname ]] && fsname=$FSNAME
+       [[ x$fsname = x$poolname ]] && fsname=$FSNAME
 
-    local RC
+       local RC
 
-    pool_list $fsname.$poolname || return $?
+       check_pool_not_exist $fsname.$poolname
+       [[ $? -eq 0 ]] && return 0
 
-    destroy_pool_int $fsname.$poolname
-    RC=$?
-    [[ $RC -ne 0 ]] && return $RC
+       destroy_pool_int $fsname.$poolname
+       RC=$?
+       [[ $RC -ne 0 ]] && return $RC
+       for mds_id in $(seq $MDSCOUNT); do
+               local mdt_id=$((mds_id-1))
+               local lodname=$fsname-MDT$(printf "%04x" $mdt_id)-mdtlov
+               wait_update_facet mds$mds_id \
+                       "lctl get_param -n lod.$lodname.pools.$poolname \
+                               2>/dev/null || echo foo" "foo" ||
+                       error "mds$mds_id: destroy pool failed $1"
+       done
+       wait_update $HOSTNAME "lctl get_param -n lov.$fsname-*.pools.$poolname \
+               2>/dev/null || echo foo" "foo" || error "destroy pool failed $1"
 
-    wait_update $HOSTNAME "lctl get_param -n lov.$fsname-*.pools.$poolname \
-      2>/dev/null || echo foo" "foo" || RC=1
+       remove_pool_from_list $fsname.$poolname
 
-    if [[ $RC -eq 0 ]]; then
-        remove_pool_from_list $fsname.$poolname
-    else
-        error "destroy pool failed $1"
-    fi
-    return $RC
+       return $RC
 }
 
 destroy_pools () {
@@ -6206,8 +6305,6 @@ destroy_pools () {
     local poolname
     local listvar=${fsname}_CREATED_POOLS
 
-    pool_list $fsname
-
     [ x${!listvar} = x ] && return 0
 
     echo destroy the created pools: ${!listvar}
@@ -6242,7 +6339,7 @@ gather_logs () {
     suffix="$ts.log"
     echo "Dumping lctl log to ${prefix}.*.${suffix}"
 
-    if [ "$CLIENTONLY" -o "$PDSH" == "no_dsh" ]; then
+    if [ -n "$CLIENTONLY" -o "$PDSH" == "no_dsh" ]; then
         echo "Dumping logs only on local client."
         $LCTL dk > ${prefix}.debug_log.$(hostname -s).${suffix}
         dmesg > ${prefix}.dmesg.$(hostname -s).${suffix}
@@ -6648,29 +6745,36 @@ check_write_access() {
 }
 
 init_logging() {
-    if [[ -n $YAML_LOG ]]; then
-        return
-    fi
-    local SAVE_UMASK=`umask`
-    umask 0000
-
-    export YAML_LOG=${LOGDIR}/results.yml
-    mkdir -p $LOGDIR
-    init_clients_lists
-
-    if [ ! -f $YAML_LOG ]; then       # If the yaml log already exists then we will just append to it
-      if check_shared_dir $LOGDIR; then
-          touch $LOGDIR/shared
-          echo "Logging to shared log directory: $LOGDIR"
-      else
-          echo "Logging to local directory: $LOGDIR"
-      fi
+       [[ -n $YAML_LOG ]] && return
+       local save_umask=$(umask)
+       umask 0000
 
-      yml_nodes_file $LOGDIR >> $YAML_LOG
-      yml_results_file >> $YAML_LOG
-    fi
+       export YAML_LOG=${LOGDIR}/results.yml
+       mkdir -p $LOGDIR
+       init_clients_lists
 
-    umask $SAVE_UMASK
+       # If the yaml log already exists then we will just append to it
+       if [ ! -f $YAML_LOG ]; then
+               if check_shared_dir $LOGDIR; then
+                       touch $LOGDIR/shared
+                       echo "Logging to shared log directory: $LOGDIR"
+               else
+                       echo "Logging to local directory: $LOGDIR"
+               fi
+
+               yml_nodes_file $LOGDIR >> $YAML_LOG
+               yml_results_file >> $YAML_LOG
+       fi
+
+       umask $save_umask
+
+       # If modules are not yet loaded then older "lctl lustre_build_version"
+       # will fail.  Use lctl build version instead.
+       log "Client: $($LCTL lustre_build_version)"
+       log "MDS: $(do_facet $SINGLEMDS $LCTL lustre_build_version 2>/dev/null||
+                   do_facet $SINGLEMDS $LCTL --version)"
+       log "OSS: $(do_facet ost1 $LCTL lustre_build_version 2> /dev/null ||
+                   do_facet ost1 $LCTL --version)"
 }
 
 log_test() {
@@ -6872,11 +6976,10 @@ get_obd_size() {
 #
 get_page_size() {
        local facet=$1
-       local size
+       local size=$(getconf PAGE_SIZE 2>/dev/null)
 
-       size=$(do_facet $facet getconf PAGE_SIZE)
-       [[ ${PIPESTATUS[0]} = 0 && -n "$size" ]] || size=4096
-       echo -n $size
+       [ -z "$CLIENTONLY" ] && size=$(do_facet $facet getconf PAGE_SIZE)
+       echo -n ${size:-4096}
 }
 
 #
@@ -6887,20 +6990,20 @@ get_block_count() {
        local device=$2
        local count
 
-       count=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" |
+       [ -z "$CLIENTONLY" ] && count=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" |
                awk '/^Block count:/ {print $3}')
-       echo -n $count
+       echo -n ${count:-0}
 }
 
 # Get the block size of the filesystem.
 get_block_size() {
-    local facet=$1
-    local device=$2
-    local size
+       local facet=$1
+       local device=$2
+       local size
 
-    size=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" |
-           awk '/^Block size:/ {print $3}')
-    echo $size
+       [ -z "$CLIENTONLY" ] && size=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" |
+               awk '/^Block size:/ {print $3}')
+       echo -n ${size:-0}
 }
 
 # Check whether the "large_xattr" feature is enabled or not.
@@ -7190,6 +7293,18 @@ pool_add_targets() {
        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 for OSTs to be added to the pool
+       for mds_id in $(seq $MDSCOUNT); do
+               local mdt_id=$((mds_id-1))
+               local lodname=$FSNAME-MDT$(printf "%04x" $mdt_id)-mdtlov
+               wait_update_facet mds$mds_id \
+                       "lctl get_param -n lod.$lodname.pools.$pool |
+                               sort -u | tr '\n' ' ' " "$t" || {
+                       error_noexit "mds$mds_id: Add to pool failed"
+                       return 3
+               }
+       done
        wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool \
                        | sort -u | tr '\n' ' ' " "$t" || {
                error_noexit "Add to pool failed"
@@ -7326,6 +7441,17 @@ pool_remove_first_target() {
        local pname="lov.$FSNAME-*.pools.$pool"
        local t=$($LCTL get_param -n $pname | head -1)
        do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
+       for mds_id in $(seq $MDSCOUNT); do
+               local mdt_id=$((mds_id-1))
+               local lodname=$FSNAME-MDT$(printf "%04x" $mdt_id)-mdtlov
+               wait_update_facet mds$mds_id \
+                       "lctl get_param -n lod.$lodname.pools.$pool |
+                               grep $t" "" || {
+                       error_noexit "mds$mds_id: $t not removed from" \
+                       "$FSNAME.$pool"
+                       return 2
+               }
+       done
        wait_update $HOSTNAME "lctl get_param -n $pname | grep $t" "" || {
                error_noexit "$t not removed from $FSNAME.$pool"
                return 1
@@ -7341,6 +7467,15 @@ pool_remove_all_targets() {
        do
                do_facet mgs $LCTL pool_remove $FSNAME.$pool $t
        done
+       for mds_id in $(seq $MDSCOUNT); do
+               local mdt_id=$((mds_id-1))
+               local lodname=$FSNAME-MDT$(printf "%04x" $mdt_id)-mdtlov
+               wait_update_facet mds$mds_id "lctl get_param -n \
+                       lod.$lodname.pools.$pool" "" || {
+                       error_noexit "mds$mds_id: Pool $pool not drained"
+                       return 4
+               }
+       done
        wait_update $HOSTNAME "lctl get_param -n $pname" "" || {
                error_noexit "Pool $FSNAME.$pool cannot be drained"
                return 1