X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Ftest-framework.sh;h=3d0398f19679e234da3ea0b21a290a9c71302659;hp=aa320f2ae25a0f2af01808cf712df0086139dd8e;hb=af666bef05;hpb=cf6ac632a18c3acb3534cd07b717673997a58515;ds=sidebyside diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index aa320f2..3d0398f 100755 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -293,10 +293,15 @@ init_test_env() { fi export RSYNC_RSH=${RSYNC_RSH:-rsh} + export LNETCTL=${LNETCTL:-"$LUSTRE/../lnet/utils/lnetctl"} + [ ! -f "$LNETCTL" ] && export LNETCTL=$(which lnetctl 2> /dev/null) export LCTL=${LCTL:-"$LUSTRE/utils/lctl"} [ ! -f "$LCTL" ] && export LCTL=$(which lctl) export LFS=${LFS:-"$LUSTRE/utils/lfs"} [ ! -f "$LFS" ] && export LFS=$(which lfs) + export KSOCKLND_CONFIG=${KSOCKLND_CONFIG:-"$LUSTRE/scripts/ksocklnd-config"} + [ ! -f "$KSOCKLND_CONFIG" ] && + export KSOCKLND_CONFIG=$(which ksocklnd-config 2> /dev/null) export PERM_CMD=${PERM_CMD:-"$LCTL conf_param"} @@ -426,14 +431,19 @@ init_test_env() { # Constants used in more than one test script export LOV_MAX_STRIPE_COUNT=2000 + export DELETE_OLD_POOLS=${DELETE_OLD_POOLS:-false} + export KEEP_POOLS=${KEEP_POOLS:-false} export MACHINEFILE=${MACHINEFILE:-$TMP/$(basename $0 .sh).machines} . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh} get_lustre_env # use localrecov to enable recovery for local clients, LU-12722 - [[ $MDS1_VERSION -lt $(version_code 2.13.52) ]] || + [[ $MDS1_VERSION -lt $(version_code 2.13.52) ]] || { export MDS_MOUNT_OPTS=${MDS_MOUNT_OPTS:-"-o localrecov"} + export MGS_MOUNT_OPTS=${MGS_MOUNT_OPTS:-"-o localrecov"} + } + [[ $OST1_VERSION -lt $(version_code 2.13.52) ]] || export OST_MOUNT_OPTS=${OST_MOUNT_OPTS:-"-o localrecov"} } @@ -455,10 +465,10 @@ check_cpt_number() { # 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", "3" + eval set -- $(tr "[:punct:][a-z]" " " <<< $*) - echo -n $(((${1:-0} << 16) | (${2:-0} << 8) | ${3:-0})) + echo -n $(((${1:-0}<<24) | (${2:-0}<<16) | (${3:-0}<<8) | (${4:-0}))) } export LINUX_VERSION=$(uname -r | sed -e "s/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/") @@ -531,6 +541,17 @@ module_loaded () { /sbin/lsmod | grep -q "^\<$1\>" } +check_lfs_df_ret_val() { + # Ignore only EOPNOTSUPP (which is 95; Operation not supported) error + # returned by 'lfs df' for valid dentry but not a lustrefs. + # + # 'lfs df' historically always returned success(0) instead of + # EOPNOTSUPP. This function for compatibility reason, ignores and + # masquerades EOPNOTSUPP as success. + [[ $1 -eq 95 ]] && return 0 + return $1 +} + PRLFS=false lustre_insmod() { local module=$1 @@ -675,9 +696,9 @@ load_modules_local() { # that obviously has nothing to do with this Lustre run # Disable automatic memory scanning to avoid perf hit. if [ -f /sys/kernel/debug/kmemleak ] ; then - echo scan=off > /sys/kernel/debug/kmemleak - echo scan > /sys/kernel/debug/kmemleak - echo clear > /sys/kernel/debug/kmemleak + echo scan=off > /sys/kernel/debug/kmemleak || true + echo scan > /sys/kernel/debug/kmemleak || true + echo clear > /sys/kernel/debug/kmemleak || true fi echo Loading modules from $LUSTRE @@ -809,21 +830,19 @@ load_modules () { } check_mem_leak () { - LEAK_LUSTRE=$(dmesg | tail -n 30 | grep "obd_memory.*leaked" || true) - LEAK_PORTALS=$(dmesg | tail -n 20 | grep "Portals memory leaked" || true) - if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then - echo "$LEAK_LUSTRE" 1>&2 - echo "$LEAK_PORTALS" 1>&2 - mv $TMP/debug $TMP/debug-leak.`date +%s` || true - echo "Memory leaks detected" - [ -n "$IGNORE_LEAK" ] && { echo "ignoring leaks" && return 0; } || true - return 1 - fi + LEAK_LUSTRE=$(dmesg | tail -n 30 | grep "obd_memory.*leaked" || true) + LEAK_PORTALS=$(dmesg | tail -n 20 | egrep -i "libcfs.*memory leaked" || true) + if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then + echo "$LEAK_LUSTRE" 1>&2 + echo "$LEAK_PORTALS" 1>&2 + mv $TMP/debug $TMP/debug-leak.`date +%s` || true + echo "Memory leaks detected" + [ -n "$IGNORE_LEAK" ] && { echo "ignoring leaks" && return 0; } || true + return 1 + fi } -unload_modules() { - wait_exit_ST client # bug 12845 - +unload_modules_local() { $LUSTRE_RMMOD ldiskfs || return 2 [ -f /etc/udev/rules.d/99-lustre-test.rules ] && @@ -831,15 +850,23 @@ unload_modules() { udevadm control --reload-rules udevadm trigger + check_mem_leak || return 254 + + return 0 +} + +unload_modules() { + local rc=0 + + wait_exit_ST client # bug 12845 + + unload_modules_local || rc=$? + if $LOAD_MODULES_REMOTE; then local list=$(comma_list $(remote_nodes_list)) if [ -n "$list" ]; then echo "unloading modules on: '$list'" - do_rpc_nodes "$list" $LUSTRE_RMMOD ldiskfs - do_rpc_nodes "$list" check_mem_leak - do_rpc_nodes "$list" "rm -f /etc/udev/rules.d/99-lustre-test.rules" - do_rpc_nodes "$list" "udevadm control --reload-rules" - do_rpc_nodes "$list" "udevadm trigger" + do_rpc_nodes "$list" unload_modules_local fi fi @@ -850,10 +877,9 @@ unload_modules() { rm -f $sbin_mount fi - check_mem_leak || return 254 + [[ $rc -eq 0 ]] && echo "modules unloaded." - echo "modules unloaded." - return 0 + return $rc } fs_log_size() { @@ -861,7 +887,7 @@ fs_log_size() { local size=0 case $(facet_fstype $facet) in - ldiskfs) size=50;; # largest seen is 44, leave some headroom + ldiskfs) size=72;; # largest seen is 64, leave some headroom # grant_block_size is in bytes, allow at least 2x max blocksize zfs) size=$(lctl get_param osc.$FSNAME*.import | awk '/grant_block_size:/ {print $2/512; exit;}') @@ -1033,6 +1059,16 @@ init_gss() { start_gss_daemons || error_exit "start gss daemon failed! rc=$?" fi + if $GSS_SK && ! $SK_NO_KEY; then + echo "Loading basic SSK keys on all servers" + do_nodes $(comma_list $(all_server_nodes)) \ + "lgss_sk -t server -l $SK_PATH/$FSNAME.key || true" + do_nodes $(comma_list $(all_server_nodes)) \ + "keyctl show | grep lustre | cut -c1-11 | + sed -e 's/ //g;' | + xargs -IX keyctl setperm X 0x3f3f3f3f" + fi + if $GSS_SK && $SK_NO_KEY; then local numclients=${1:-$CLIENTCOUNT} local clients=${CLIENTS:-$HOSTNAME} @@ -1301,20 +1337,6 @@ devicelabel() { echo -n $label } -mdsdevlabel() { - local num=$1 - local device=$(mdsdevname $num) - local label=$(devicelabel mds$num ${device} | grep -v "CMD: ") - echo -n $label -} - -ostdevlabel() { - local num=$1 - local device=$(ostdevname $num) - local label=$(devicelabel ost$num ${device} | grep -v "CMD: ") - echo -n $label -} - # # Get the device of a facet. # @@ -1547,8 +1569,7 @@ get_osd_param() { local device=${2:-$FSNAME-OST*} local name=$3 - do_nodes $nodes "$LCTL get_param -n obdfilter.$device.$name \ - osd-*.$device.$name 2>&1" | grep -v 'error:' + do_nodes $nodes "$LCTL get_param -n osd-*.$device.$name" } set_osd_param() { @@ -1557,8 +1578,7 @@ set_osd_param() { local name=$3 local value=$4 - do_nodes $nodes "$LCTL set_param -n obdfilter.$device.$name=$value \ - osd-*.$device.$name=$value 2>&1" | grep -v 'error:' + do_nodes $nodes "$LCTL set_param -n osd-*.$device.$name=$value" } set_debug_size () { @@ -1617,6 +1637,22 @@ set_default_debug_facet () { set_default_debug_nodes $node "$debug" "$subsys" $debug_size } +set_params_nodes () { + [[ $# -ge 2 ]] || return 0 + + local nodes=$1 + shift + do_nodes $nodes $LCTL set_param $@ +} + +set_params_clients () { + local clients=${1:-$CLIENTS} + local params=${2:-$CLIENT_LCTL_SETPARAM_PARAM} + + [[ -n $params ]] || return 0 + set_params_nodes $clients $params +} + set_hostid () { local hostid=${1:-$(hostid)} @@ -2170,7 +2206,7 @@ restore_quota() { if [ "$old_MDT_QUOTA_TYPE" ]; then if [[ $PERM_CMD == *"set_param -P"* ]]; then do_facet mgs $PERM_CMD \ - osd-*.$FSNAME-MDT*.quota_slave.enable = \ + osd-*.$FSNAME-MDT*.quota_slave.enabled = \ $old_MDT_QUOTA_TYPE else do_facet mgs $PERM_CMD \ @@ -2180,7 +2216,7 @@ restore_quota() { if [ "$old_OST_QUOTA_TYPE" ]; then if [[ $PERM_CMD == *"set_param -P"* ]]; then do_facet mgs $PERM_CMD \ - osd-*.$FSNAME-OST*.quota_slave.enable = \ + osd-*.$FSNAME-OST*.quota_slave.enabled = \ $old_OST_QUOTA_TYPE else do_facet mgs $LCTL conf_param \ @@ -2194,6 +2230,7 @@ restore_quota() { # This will allow fixing the "lfs df" summary line in the future. lfs_df() { $LFS df $* | sed -e 's/filesystem /filesystem_/' + check_lfs_df_ret_val $? } # Get free inodes on the MDT specified by mdt index, free indoes on @@ -2241,9 +2278,9 @@ setup_quota(){ if [[ $PERM_CMD == *"set_param -P"* ]]; then do_facet mgs $PERM_CMD \ - osd-*.$FSNAME-MDT*.quota_slave.enable=$QUOTA_TYPE + osd-*.$FSNAME-MDT*.quota_slave.enabled=$QUOTA_TYPE do_facet mgs $PERM_CMD \ - osd-*.$FSNAME-OST*.quota_slave.enable=$QUOTA_TYPE + osd-*.$FSNAME-OST*.quota_slave.enabled=$QUOTA_TYPE else do_facet mgs $PERM_CMD $FSNAME.quota.mdt=$QUOTA_TYPE || error "set mdt quota type failed" @@ -2329,6 +2366,7 @@ zconf_mount() { fi set_default_debug_nodes $client + set_params_clients $client return 0 } @@ -2555,6 +2593,7 @@ exit \\\$rc" || return ${PIPESTATUS[0]} do_nodes $clients "mount | grep $mnt' '" set_default_debug_nodes $clients + set_params_clients $clients return 0 } @@ -2688,19 +2727,27 @@ remount_facet() { reboot_facet() { local facet=$1 + local node=$(facet_active_host $facet) + local sleep_time=${2:-10} + if [ "$FAILURE_MODE" = HARD ]; then - reboot_node $(facet_active_host $facet) + boot_node $node else - sleep 10 + sleep $sleep_time fi } boot_node() { - local node=$1 - if [ "$FAILURE_MODE" = HARD ]; then - reboot_node $node - wait_for_host $node - fi + local node=$1 + + if [ "$FAILURE_MODE" = HARD ]; then + reboot_node $node + wait_for_host $node + if $LOAD_MODULES_REMOTE; then + echo "loading modules on $node: $facet" + do_rpc_nodes $node load_modules_local + fi + fi } facets_hosts () { @@ -2954,35 +3001,6 @@ stop_client_loads() { } # End recovery-scale functions -# verify that lustre actually cleaned up properly -cleanup_check() { - 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 - - [[ $($LCTL dl 2>/dev/null | wc -l) -gt 0 ]] && $LCTL dl && - echo "$TESTSUITE: lustre didn't clean up..." 1>&2 && - return 202 || true - - if module_loaded lnet || module_loaded libcfs; then - echo "$TESTSUITE: modules still loaded..." 1>&2 - /sbin/lsmod 1>&2 - return 203 - fi - return 0 -} - ## # wait for a command to return the expected result # @@ -2997,15 +3015,21 @@ cleanup_check() { # If --verbose is passed as the first argument, the result is printed on each # value change, otherwise it is only printed after every 10s interval. # +# If --quiet is passed as the first/second argument, the do_node() command +# will not print the remote command before executing it each time. +# # Using wait_update_cond() or related helper function is preferable to adding # a "long enough" wait for some state to change in the background, since # "long enough" may be too short due to tunables, system config, or running in # a VM, and must by necessity wait too long for most cases or risk failure. # -# usage: wait_update_cond [--verbose] node check cond expect [max_wait] +# usage: wait_update_cond [--verbose] [--quiet] node check cond expect [max_wait] wait_update_cond() { - local verbose=false - [[ "$1" == "--verbose" ]] && verbose=true && shift + local verbose + local quiet + + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift local node=$1 local check="$2" @@ -3020,7 +3044,7 @@ wait_update_cond() { local print=10 while (( $waited <= $max_wait )); do - result=$(do_node $node "$check") + result=$(do_node $quiet $node "$check") eval [[ "'$result'" $cond "'$expect'" ]] if [[ $? == 0 ]]; then @@ -3028,7 +3052,7 @@ wait_update_cond() { echo "Updated after ${waited}s: want '$expect' got '$result'" return 0 fi - if $verbose && [[ "$result" != "$prev_result" ]]; then + if [[ -n "$verbose" && "$result" != "$prev_result" ]]; then [[ -n "$prev_result" ]] && echo "Changed after ${waited}s: from '$prev_result' to '$result'" prev_result="$result" @@ -3042,23 +3066,29 @@ wait_update_cond() { return 3 } -# usage: wait_update [--verbose] node check expect [max_wait] +# usage: wait_update [--verbose] [--quiet] node check expect [max_wait] wait_update() { - local verbose= - [ "$1" = "--verbose" ] && verbose="$1" && shift + local verbose + local quiet + + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift local node="$1" local check="$2" local expect="$3" local max_wait=$4 - wait_update_cond $verbose $node "$check" "==" "$expect" $max_wait + wait_update_cond $verbose $quiet $node "$check" "==" "$expect" $max_wait } # usage: wait_update_facet_cond [--verbose] facet check cond expect [max_wait] wait_update_facet_cond() { - local verbose= - [ "$1" = "--verbose" ] && verbose="$1" && shift + local verbose + local quiet + + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift local node=$(facet_active_host $1) local check="$2" @@ -3066,20 +3096,23 @@ wait_update_facet_cond() { local expect="$4" local max_wait=$5 - wait_update_cond $verbose $node "$check" "$cond" "$expect" $max_wait + wait_update_cond $verbose $quiet $node "$check" "$cond" "$expect" $max_wait } # usage: wait_update_facet [--verbose] facet check expect [max_wait] wait_update_facet() { - local verbose= - [ "$1" = "--verbose" ] && verbose="$1" && shift + local verbose + local quiet + + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift local node=$(facet_active_host $1) local check="$2" local expect="$3" local max_wait=$4 - wait_update_cond $verbose $node "$check" "==" "$expect" $max_wait + wait_update_cond $verbose $quiet $node "$check" "==" "$expect" $max_wait } sync_all_data() { @@ -3415,14 +3448,15 @@ wait_osts_up() { } wait_destroy_complete () { - echo "Waiting for local destroys to complete" + echo "Waiting for MDT destroys to complete" # MAX value shouldn't be big as this mean server responsiveness # never increase this just to make test pass but investigate # why it takes so long time - local MAX=5 + local MAX=${1:-5} local WAIT=0 + local list=$(comma_list $(mdts_nodes)) while [ $WAIT -lt $MAX ]; do - local -a RPCs=($($LCTL get_param -n osc.*.destroys_in_flight)) + local -a RPCs=($(do_nodes $list $LCTL get_param -n osp.*.destroys_in_flight)) local con=1 local i @@ -3437,7 +3471,7 @@ wait_destroy_complete () { echo "Waiting ${WAIT}s for local destroys to complete" WAIT=$((WAIT + 1)) done - echo "Local destroys weren't done in $MAX sec." + echo "MDT destroys weren't done in $MAX sec." return 1 } @@ -3502,12 +3536,20 @@ wait_remote_prog () { lfs_df_check() { local clients=${1:-$CLIENTS} + local rc if [ -z "$clients" ]; then - $LFS df $MOUNT + $LFS df $MOUNT > /dev/null + rc=$? else $PDSH $clients "$LFS df $MOUNT" > /dev/null + rc=$? fi + + check_lfs_df_ret_val $rc + rc=$? + + return $rc } clients_up() { @@ -3516,6 +3558,19 @@ clients_up() { lfs_df_check } +all_mds_up() { + (( MDSCOUNT == 1 )) && return + + # wait so that statfs data on MDT expire + local delay=$(do_facet $SINGLEMDS lctl \ + get_param -n osp.*MDT0000*MDT0001.maxage) + sleep $delay + local nodes=$(comma_list $(mdts_nodes)) + # initiate statfs RPC, all to all MDTs + do_nodes $nodes $LCTL get_param -N osp.*MDT*MDT*.filesfree >&/dev/null + do_nodes $nodes $LCTL get_param -N osp.*MDT*MDT*.filesfree >&/dev/null +} + client_up() { # usually checked on particular client or locally sleep 1 @@ -3608,7 +3663,7 @@ facet_failover() { facet=$(echo ${affecteds[index]} | tr -s " " | cut -d"," -f 1) echo reboot facets: ${affecteds[index]} - reboot_facet $facet + reboot_facet $facet $sleep_time change_active ${affecteds[index]} @@ -3635,10 +3690,6 @@ facet_failover() { done } -obd_name() { - local facet=$1 -} - replay_barrier() { local facet=$1 do_facet $facet "sync; sync; sync" @@ -3738,18 +3789,22 @@ fail() { } fail_nodf() { - local facet=$1 - facet_failover $facet + local facet=$1 + + facet_failover $facet } fail_abort() { local facet=$1 + local abort_type=${2:-"abort_recovery"} + stop $facet change_active $facet wait_for_facet $facet - mount_facet $facet -o abort_recovery + mount_facet $facet -o $abort_type clients_up || echo "first stat failed: $?" clients_up || error "post-failover stat: $?" + all_mds_up } host_nids_address() { @@ -4006,26 +4061,27 @@ change_active() { } do_node() { - local verbose=false - # do not stripe off hostname if verbose, bug 19215 - if [ x$1 = x--verbose ]; then - shift - verbose=true - fi + local verbose + local quiet - local HOST=$1 - shift - local myPDSH=$PDSH - if [ "$HOST" = "$HOSTNAME" ]; then - myPDSH="no_dsh" - elif [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" ]; then - echo "cannot run remote command on $HOST with $myPDSH" - return 128 - fi - if $VERBOSE; then - echo "CMD: $HOST $@" >&2 - $myPDSH $HOST "$LCTL mark \"$@\"" > /dev/null 2>&1 || : - fi + # do not strip off hostname if verbose, b=19215 + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift + + local HOST=$1 + shift + local myPDSH=$PDSH + + if [ "$HOST" = "$HOSTNAME" ]; then + myPDSH="no_dsh" + elif [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" ]; then + echo "cannot run remote command on $HOST with $myPDSH" + return 128 + fi + if $VERBOSE && [[ -z "$quiet" ]]; then + echo "CMD: $HOST $@" >&2 + $myPDSH $HOST "$LCTL mark \"$@\"" > /dev/null 2>&1 || : + fi if [[ "$myPDSH" == "rsh" ]] || [[ "$myPDSH" == *pdsh* && "$myPDSH" != *-S* ]]; then @@ -4042,7 +4098,7 @@ do_node() { return 0 fi - if $verbose ; then + if [[ -n "$verbose" ]]; then # print HOSTNAME for myPDSH="no_dsh" if [[ $myPDSH = no_dsh ]]; then $myPDSH $HOST "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; LUSTRE=\"$RLUSTRE\" sh -c \"$@\")" | sed -e "s/^/${HOSTNAME}: /" @@ -4055,12 +4111,8 @@ do_node() { return ${PIPESTATUS[0]} } -do_nodev() { - do_node --verbose "$@" -} - single_local_node () { - [ "$1" = "$HOSTNAME" ] + [ "$1" = "$HOSTNAME" ] } # Outputs environment variable assignments that should be passed to remote nodes @@ -4106,45 +4158,42 @@ get_env_vars() { } do_nodes() { - local verbose=false - # do not stripe off hostname if verbose, bug 19215 - if [ x$1 = x--verbose ]; then - shift - verbose=true - fi + local verbose + local quiet - local rnodes=$1 - shift + # do not strip off hostname if verbose, b=19215 + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift - if single_local_node $rnodes; then - if $verbose; then - do_nodev $rnodes "$@" - else - do_node $rnodes "$@" - fi - return $? - fi + local rnodes=$1 + shift - # This is part from do_node - local myPDSH=$PDSH + if single_local_node $rnodes; then + do_node $verbose $quiet $rnodes "$@" + return $? + fi - [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" -o "$myPDSH" = "rsh" ] && \ - echo "cannot run remote command on $rnodes with $myPDSH" && return 128 + # This is part from do_node + local myPDSH=$PDSH - export FANOUT=$(get_node_count "${rnodes//,/ }") - if $VERBOSE; then - echo "CMD: $rnodes $@" >&2 - $myPDSH $rnodes "$LCTL mark \"$@\"" > /dev/null 2>&1 || : - fi + [ -z "$myPDSH" -o "$myPDSH" = "no_dsh" -o "$myPDSH" = "rsh" ] && + echo "cannot run remote command on $rnodes with $myPDSH" && + return 128 - # do not replace anything from pdsh output if -N is used - # -N Disable hostname: prefix on lines of output. - if $verbose || [[ $myPDSH = *-N* ]]; then - $myPDSH $rnodes "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; LUSTRE=\"$RLUSTRE\" $(get_env_vars) sh -c \"$@\")" - else - $myPDSH $rnodes "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; LUSTRE=\"$RLUSTRE\" $(get_env_vars) sh -c \"$@\")" | sed -re "s/^[^:]*: //g" - fi - return ${PIPESTATUS[0]} + export FANOUT=$(get_node_count "${rnodes//,/ }") + if $VERBOSE && [[ -z "$quiet" ]]; then + echo "CMD: $rnodes $@" >&2 + $myPDSH $rnodes "$LCTL mark \"$@\"" > /dev/null 2>&1 || : + fi + + # do not replace anything from pdsh output if -N is used + # -N Disable hostname: prefix on lines of output. + if [[ -n "$verbose" || $myPDSH = *-N* ]]; then + $myPDSH $rnodes "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; LUSTRE=\"$RLUSTRE\" $(get_env_vars) sh -c \"$@\")" + else + $myPDSH $rnodes "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; LUSTRE=\"$RLUSTRE\" $(get_env_vars) sh -c \"$@\")" | sed -re "s/^[^:]*: //g" + fi + return ${PIPESTATUS[0]} } ## @@ -4155,11 +4204,18 @@ do_nodes() { # # usage: do_facet $facet command [arg ...] do_facet() { + local verbose + local quiet + + [[ "$1" == "--verbose" ]] && verbose="$1" && shift + [[ "$1" == "--quiet" || "$1" == "-q" ]] && quiet="$1" && shift + 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 host=$(facet_active_host $facet) + + [ -z "$host" ] && echo "No host defined for facet ${facet}" && exit 1 + do_node $verbose $quiet $host "$@" } # Function: do_facet_random_file $FACET $FILE $SIZE @@ -4182,7 +4238,7 @@ do_facet_create_file() { } do_nodesv() { - do_nodes --verbose "$@" + do_nodes --verbose "$@" } add() { @@ -4192,6 +4248,12 @@ add() { stop ${facet} -f rm -f $TMP/${facet}active [[ $facet = mds1 ]] && combined_mgs_mds && rm -f $TMP/mgsactive + + # make sure in-tree ldiskfs is loaded before mkfs + if local_mode && [[ $(node_fstypes $HOSTNAME) == *ldiskfs* ]]; then + load_module ../ldiskfs/ldiskfs + fi + do_facet ${facet} $MKFS $* || return ${PIPESTATUS[0]} if [[ $(facet_fstype $facet) == zfs ]]; then @@ -5260,6 +5322,11 @@ init_param_vars () { TIMEOUT=$(do_facet $SINGLEMDS "lctl get_param -n timeout") log "Using TIMEOUT=$TIMEOUT" + # tune down to speed up testing on (usually) small setups + local mgc_timeout=/sys/module/mgc/parameters/mgc_requeue_timeout_min + do_nodes $(comma_list $(nodes_list)) \ + "[ -f $mgc_timeout ] && echo 1 > $mgc_timeout; exit 0" + osc_ensure_active $SINGLEMDS $TIMEOUT osc_ensure_active client $TIMEOUT $LCTL set_param osc.*.idle_timeout=debug @@ -5292,6 +5359,7 @@ init_param_vars () { (( MDS1_VERSION <= $(version_code 2.13.52) )) || do_nodes $(comma_list $(mdts_nodes)) \ "$LCTL set_param lod.*.mdt_hash=crush" + do_node $(mgs_node) "$LCTL set_param -P *.*.lbug_on_grant_miscount=1" return 0 } @@ -5379,25 +5447,103 @@ is_mounted () { echo $mounted' ' | grep -w -q $mntpt' ' } -is_empty_dir() { - [ $(find $1 -maxdepth 1 -print | wc -l) = 1 ] && return 0 - return 1 +create_pools () { + local pool=$1 + local ostsn=${2:-$OSTCOUNT} + local npools=${FS_NPOOLS:-$((OSTCOUNT / ostsn))} + local n + + echo ostsn=$ostsn npools=$npools + if [[ $ostsn -gt $OSTCOUNT ]]; then + echo "request to use $ostsn OSTs in the pool, \ + using max available OSTCOUNT=$OSTCOUNT" + ostsn=$OSTCOUNT + fi + for (( n=0; n < $npools; n++ )); do + p=${pool}$n + if ! $DELETE_OLD_POOLS; then + log "request to not delete old pools: $FSNAME.$p exist?" + if ! check_pool_not_exist $FSNAME.$p; then + echo "Using existing $FSNAME.$p" + $LCTL pool_list $FSNAME.$p + continue + fi + fi + create_pool $FSNAME.$p $KEEP_POOLS || + error "create_pool $FSNAME.$p failed" + + local first=$(( (n * ostsn) % OSTCOUNT )) + local last=$(( (first + ostsn - 1) % OSTCOUNT )) + if [[ $first -le $last ]]; then + pool_add_targets $p $first $last || + error "pool_add_targets $p $first $last failed" + else + pool_add_targets $p $first $(( OSTCOUNT - 1 )) || + error "pool_add_targets $p $first \ + $(( OSTCOUNT - 1 )) failed" + pool_add_targets $p 0 $last || + error "pool_add_targets $p 0 $last failed" + fi + done } -# empty lustre filesystem may have empty directories lost+found and .lustre -is_empty_fs() { - # exclude .lustre & lost+found - [ $(find $1 -maxdepth 1 -name lost+found -o -name .lustre -prune -o \ - -print | wc -l) = 1 ] || return 1 - [ ! -d $1/lost+found ] || is_empty_dir $1/lost+found || return 1 - if [ $(lustre_version_code $SINGLEMDS) -gt $(version_code 2.4.0) ]; then - # exclude .lustre/fid (LU-2780) - [ $(find $1/.lustre -maxdepth 1 -name fid -prune -o \ - -print | wc -l) = 1 ] || return 1 - else - [ ! -d $1/.lustre ] || is_empty_dir $1/.lustre || return 1 - fi - return 0 +set_pools_quota () { + local u + local o + local p + local i + local j + + [[ $ENABLE_QUOTA ]] || error "Required Pool Quotas: \ + $POOLS_QUOTA_USERS_SET, but ENABLE_QUOTA not set!" + + # POOLS_QUOTA_USERS_SET= + # "quota15_1:20M -- for all of the found pools + # quota15_2:1G:gpool0 + # quota15_3 -- for global limit only + # quota15_4:200M:gpool0 + # quota15_4:200M:gpool1" + + declare -a pq_userset=(${POOLS_QUOTA_USERS_SET="mpiuser"}) + declare -a pq_users + declare -A pq_limits + + for ((i=0; i<${#pq_userset[@]}; i++)); do + u=${pq_userset[i]%%:*} + o="" + # user gets no pool limits if + # POOLS_QUOTA_USERS_SET does not specify it + [[ ${pq_userset[i]} =~ : ]] && o=${pq_userset[i]##$u:} + pq_limits[$u]+=" $o" + done + pq_users=(${!pq_limits[@]}) + + declare -a opts + local pool + + for ((i=0; i<${#pq_users[@]}; i++)); do + u=${pq_users[i]} + # set to max limit (_u64) + $LFS setquota -u $u -B $((2**24 - 1))T $DIR + opts=(${pq_limits[$u]}) + for ((j=0; j<${#opts[@]}; j++)); do + p=${opts[j]##*:} + o=${opts[j]%%:*} + # Set limit for all existing pools if + # no pool specified + if [ $p == $o ]; then + p=$(list_pool $FSNAME | sed "s/$FSNAME.//") + echo "No pool specified for $u, + set limit $o for all existing pools" + fi + for pool in $p; do + $LFS setquota -u $u -B $o --pool $pool $DIR || + error "setquota -u $u -B $o \ + --pool $pool failed" + done + done + $LFS quota -uv $u --pool $DIR + done } check_and_setup_lustre() { @@ -5448,17 +5594,18 @@ check_and_setup_lustre() { export I_MOUNTED2=yes fi - if $do_check; then - # FIXME: what to do if check_config failed? - # i.e. if: - # 1) remote client has mounted other Lustre fs? - # 2) lustre is mounted on remote_clients atall ? - check_config_clients $MOUNT - init_facets_vars - init_param_vars + if $do_check; then + # FIXME: what to do if check_config failed? + # i.e. if: + # 1) remote client has mounted other Lustre fs? + # 2) lustre is mounted on remote_clients atall ? + check_config_clients $MOUNT + init_facets_vars + init_param_vars - set_default_debug_nodes $(comma_list $(nodes_list)) - fi + set_default_debug_nodes $(comma_list $(nodes_list)) + set_params_clients + fi if [ -z "$CLIENTONLY" -a $(lower $OSD_TRACK_DECLARES_LBUG) == 'yes' ]; then local facets="" @@ -5484,6 +5631,16 @@ check_and_setup_lustre() { set_flavor_all $SEC fi + if $DELETE_OLD_POOLS; then + destroy_all_pools + fi + if [[ -n "$FS_POOL" ]]; then + create_pools $FS_POOL $FS_POOL_NOSTS + fi + + if [[ -n "$POOLS_QUOTA_USERS_SET" ]]; then + set_pools_quota + fi if [ "$ONLY" == "setup" ]; then exit 0 fi @@ -5514,51 +5671,6 @@ cleanup_and_setup_lustre() { check_and_setup_lustre } -# Get all of the server target devices from a given server node and type. -get_mnt_devs() { - local node=$1 - local type=$2 - local devs - local dev - - if [ "$type" == ost ]; then - devs=$(get_osd_param $node "" mntdev) - else - devs=$(do_node $node $LCTL get_param -n osd-*.$FSNAME-M*.mntdev) - fi - for dev in $devs; do - case $dev in - *loop*) do_node $node "losetup $dev" | \ - sed -e "s/.*(//" -e "s/).*//" ;; - *) echo $dev ;; - esac - done -} - -# Get all of the server target devices. -get_svr_devs() { - local node - local i - - # Master MDS parameters used by lfsck - MDTNODE=$(facet_active_host $SINGLEMDS) - MDTDEV=$(echo $(get_mnt_devs $MDTNODE mdt) | awk '{print $1}') - - # 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 @@ -5568,6 +5680,8 @@ run_e2fsck() { local log=$TMP/e2fsck.log local rc=0 + # turn on pfsck if it is supported + do_node $node $E2FSCK -h 2>&1 | grep -qw -- -m && cmd+=" -m8" echo $cmd do_node $node $cmd 2>&1 | tee $log rc=${PIPESTATUS[0]} @@ -5728,30 +5842,30 @@ check_and_cleanup_lustre() { # General functions wait_for_function () { - local quiet="" - - # suppress fn both stderr and stdout - if [ "$1" = "--quiet" ]; then - shift - quiet=" > /dev/null 2>&1" + local quiet="" - fi + # suppress fn both stderr and stdout + if [ "$1" = "--quiet" ]; then + shift + quiet=" > /dev/null 2>&1" + fi - local fn=$1 - local max=${2:-900} - local sleep=${3:-5} + local fn=$1 + local max=${2:-900} + local sleep=${3:-5} - local wait=0 + local wait=0 - while true; do + while true; do - eval $fn $quiet && return 0 + eval $fn $quiet && return 0 - wait=$((wait + sleep)) - [ $wait -lt $max ] || return 1 - echo waiting $fn, $((max - wait)) secs left ... - sleep $sleep - done + [ $wait -lt $max ] || return 1 + echo waiting $fn, $((max - wait)) secs left ... + wait=$((wait + sleep)) + [ $wait -gt $max ] && ((sleep -= wait - max)) + sleep $sleep + done } check_network() { @@ -5882,10 +5996,6 @@ at_max_get() { at_get $1 at_max } -at_min_get() { - at_get $1 at_min -} - at_max_set() { local at_max=$1 shift @@ -6041,9 +6151,9 @@ cancel_lru_locks() { default_lru_size() { - NR_CPU=$(grep -c "processor" /proc/cpuinfo) - DEFAULT_LRU_SIZE=$((100 * NR_CPU)) - echo "$DEFAULT_LRU_SIZE" + local nr_cpu=$(grep -c "processor" /proc/cpuinfo) + + echo $((100 * nr_cpu)) } lru_resize_enable() @@ -6053,7 +6163,10 @@ lru_resize_enable() lru_resize_disable() { - lctl set_param ldlm.namespaces.*$1*.lru_size $(default_lru_size) + local dev=${1} + local lru_size=${2:-$(default_lru_size)} + + $LCTL set_param ldlm.namespaces.*$dev*.lru_size=$lru_size } flock_is_enabled() @@ -6208,9 +6321,14 @@ error_noexit() { exit_status () { local status=0 - local log=$TESTSUITELOG + local logs="$TESTSUITELOG $1" + + for log in $logs; do + if [ -f "$log" ]; then + grep -qw FAIL $log && status=1 + fi + done - [ -f "$log" ] && grep -qw FAIL $log && status=1 exit $status } @@ -6467,10 +6585,10 @@ 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 --quiet $(comma_list $(nodes_list)) \ + "lctl set_param -n fail_loc=0 fail_val=0 2>/dev/null" || true + #echo done. } @@ -6479,7 +6597,8 @@ reset_fail_loc () { # Also appends a timestamp and prepends the testsuite name. # -EQUALS="====================================================================================================" +# ======================================================== 15:06:12 (1624050372) +EQUALS="========================================================" banner() { msg="== ${TESTSUITE} $*" last=${msg: -1:1} @@ -6495,7 +6614,7 @@ check_dmesg_for_errors() { ldiskfs_check_descriptors: Checksum for group 0 failed\|\ group descriptors corrupted" - res=$(do_nodes $(comma_list $(nodes_list)) "dmesg" | grep "$errors") + res=$(do_nodes -q $(comma_list $(nodes_list)) "dmesg" | grep "$errors") [ -z "$res" ] && return 0 echo "Kernel error detected: $res" return 1 @@ -6563,7 +6682,7 @@ run_one_logged() { # remove temp files between repetitions to avoid test failures [ -n "$append" -a -n "$DIR" -a -n "$tdir" -a -n "$tfile" ] && - rm -rf $DIR/$tdir* $DIR/$tfile* + rm -rvf $DIR/$tdir* $DIR/$tfile* # loop around subshell so stack_trap EXIT triggers each time (run_one $testnum "$testmsg") 2>&1 | tee -i $append $test_log rc=${PIPESTATUS[0]} @@ -6618,10 +6737,6 @@ skip_logged(){ log_sub_test_end "SKIP" "0" "0" "$@" } -canonical_path() { - (cd $(dirname $1); echo $PWD/$(basename $1)) -} - grant_from_clients() { local nodes="$1" @@ -6660,7 +6775,7 @@ check_grant() { # sync all the data and make sure no pending data on server do_nodes $clients sync - clients_up # initiate all idling connections + do_nodes $clients $LFS df # initiate all idling connections # get client grant cli_grant=$(grant_from_clients $clients) @@ -6707,7 +6822,7 @@ ostuuid_from_index() } ostname_from_index() { - local uuid=$(ostuuid_from_index $1) + local uuid=$(ostuuid_from_index $1 $2) echo ${uuid/_UUID/} } @@ -6741,7 +6856,7 @@ host_id() { # Description: # Returns list of ip addresses for each interface local_addr_list() { - ip addr | awk '/inet\ / {print $2}' | awk -F\/ '{print $1}' + ip addr | awk '/inet / {print $2}' | awk -F/ '{print $1}' } is_local_addr() { @@ -6865,11 +6980,6 @@ osts_nodes () { echo -n $(facets_nodes $(get_facets OST)) } -# Get all of the active AGT (HSM agent) nodes. -agts_nodes () { - echo -n $(facets_nodes $(get_facets AGT)) -} - # Get all of the client nodes and active server nodes. nodes_list () { local nodes=$HOSTNAME @@ -7009,12 +7119,6 @@ get_node_count() { echo $nodes | wc -w || true } -mixed_ost_devs () { - local nodes=$(osts_nodes) - local osscount=$(get_node_count "$nodes") - [ ! "$OSTCOUNT" = "$osscount" ] -} - mixed_mdt_devs () { local nodes=$(mdts_nodes) local mdtcount=$(get_node_count "$nodes") @@ -7039,23 +7143,6 @@ get_stripe () { rm -f $file } -setstripe_nfsserver () { - local dir=$1 - local nfsexportdir=$2 - shift - shift - - local -a nfsexport=($(awk '"'$dir'" ~ $2 && $3 ~ "nfs" && $2 != "/" \ - { print $1 }' /proc/mounts | cut -f 1 -d :)) - - # check that only one nfs mounted - [[ -z $nfsexport ]] && echo "$dir is not nfs mounted" && return 1 - (( ${#nfsexport[@]} == 1 )) || - error "several nfs mounts found for $dir: ${nfsexport[@]} !" - - do_nodev ${nfsexport[0]} lfs setstripe $nfsexportdir "$@" -} - # Check and add a test group. add_group() { local group_id=$1 @@ -7114,35 +7201,46 @@ add_user() { } check_runas_id_ret() { - local myRC=0 - local myRUNAS_UID=$1 - local myRUNAS_GID=$2 - shift 2 - local myRUNAS=$@ - if [ -z "$myRUNAS" ]; then - error_exit "myRUNAS command must be specified for check_runas_id" - fi - if $GSS_KRB5; then - $myRUNAS krb5_login.sh || \ - error "Failed to refresh Kerberos V5 TGT for UID $myRUNAS_ID." - fi - mkdir $DIR/d0_runas_test - chmod 0755 $DIR - chown $myRUNAS_UID:$myRUNAS_GID $DIR/d0_runas_test - $myRUNAS touch $DIR/d0_runas_test/f$$ || myRC=$? - rm -rf $DIR/d0_runas_test - return $myRC + local myRC=0 + local myRUNAS_UID=$1 + local myRUNAS_GID=$2 + shift 2 + local myRUNAS=$@ + + if [ -z "$myRUNAS" ]; then + error_exit "check_runas_id_ret requires myRUNAS argument" + fi + + $myRUNAS true || + error "Unable to execute $myRUNAS" + + id $myRUNAS_UID > /dev/null || + error "Invalid RUNAS_ID $myRUNAS_UID. Please set RUNAS_ID to " \ + "some UID which exists on MDS and client or add user " \ + "$myRUNAS_UID:$myRUNAS_GID on these nodes." + + if $GSS_KRB5; then + $myRUNAS krb5_login.sh || + error "Failed to refresh krb5 TGT for UID $myRUNAS_ID." + fi + mkdir $DIR/d0_runas_test + chmod 0755 $DIR + chown $myRUNAS_UID:$myRUNAS_GID $DIR/d0_runas_test + $myRUNAS -u $myRUNAS_UID -g $myRUNAS_GID touch $DIR/d0_runas_test/f$$ || + myRC=$? + rm -rf $DIR/d0_runas_test + return $myRC } check_runas_id() { - local myRUNAS_UID=$1 - local myRUNAS_GID=$2 - shift 2 - local myRUNAS=$@ - check_runas_id_ret $myRUNAS_UID $myRUNAS_GID $myRUNAS || \ - error "unable to write to $DIR/d0_runas_test as UID $myRUNAS_UID. - Please set RUNAS_ID to some UID which exists on MDS and client or - add user $myRUNAS_UID:$myRUNAS_GID on these nodes." + local myRUNAS_UID=$1 + local myRUNAS_GID=$2 + shift 2 + local myRUNAS=$@ + + check_runas_id_ret $myRUNAS_UID $myRUNAS_GID $myRUNAS || \ + error "unable to write to $DIR/d0_runas_test as " \ + "UID $myRUNAS_UID." } # obtain the UID/GID for MPI_USER @@ -7282,15 +7380,18 @@ restore_lustre_params() { check_node_health() { local nodes=${1:-$(comma_list $(nodes_list))} - - for node in ${nodes//,/ }; do - check_network "$node" 5 - if [ $? -eq 0 ]; then - do_node $node "$LCTL get_param catastrophe 2>&1" | - grep -q "catastrophe=1" && - error "$node:LBUG/LASSERT detected" || true - fi - done + local health=$TMP/node_health.$$ + + do_nodes -q $nodes "$LCTL get_param catastrophe 2>&1" | tee $health | + grep "catastrophe=1" && error "LBUG/LASSERT detected" + # Only check/report network health if get_param isn't reported, since + # *clearly* the network is working if get_param returned something. + if (( $(grep -c catastro $health) != $(wc -w <<< ${nodes//,/ }) )); then + for node in ${nodes//,/}; do + check_network $node 5 + done + fi + rm -f $health } mdsrate_cleanup () { @@ -7301,11 +7402,6 @@ mdsrate_cleanup () { fi } -delayed_recovery_enabled () { - local var=${SINGLEMDS}_svc - do_facet $SINGLEMDS lctl get_param -n mdd.${!var}.stale_export_age > /dev/null 2>&1 -} - ######################## convert_facet2label() { @@ -7330,20 +7426,6 @@ get_clientosc_proc_path() { echo "${1}-osc-[-0-9a-f]*" } -# If the 2.0 MDS was mounted on 1.8 device, then the OSC and LOV names -# used by MDT would not be changed. -# mdt lov: fsname-mdtlov -# mdt osc: fsname-OSTXXXX-osc -mds_on_old_device() { - local mds=${1:-"$SINGLEMDS"} - - if [ $(lustre_version_code $mds) -gt $(version_code 1.9.0) ]; then - do_facet $mds "lctl list_param osc.$FSNAME-OST*-osc \ - > /dev/null 2>&1" && return 0 - fi - return 1 -} - get_mdtosc_proc_path() { local mds_facet=$1 local ost_label=${2:-"*OST*"} @@ -7374,48 +7456,49 @@ get_osc_import_name() { } _wait_import_state () { - 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 + local expected="$1" + local CONN_PROC="$2" + local maxtime=${3:-$(max_recovery_time)} + local err_on_fail=${4:-1} + local CONN_STATE + local i=0 CONN_STATE=$($LCTL get_param -n $CONN_PROC 2>/dev/null | cut -f2 | uniq) - while ! echo "${CONN_STATE}" | egrep -q "^${expected}\$" ; do - if [ "${expected}" == "DISCONN" ]; then - # for disconn we can check after proc entry is removed - [ "x${CONN_STATE}" == "x" ] && return 0 - # with AT enabled, we can have connect request timeout near of - # reconnect timeout and test can't see real disconnect - [ "${CONN_STATE}" == "CONNECTING" ] && return 0 - fi - 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) - i=$(($i + 1)) - done + while ! echo "${CONN_STATE}" | egrep -q "^${expected}\$" ; do + if [[ "${expected}" == "DISCONN" ]]; then + # for disconn we can check after proc entry is removed + [[ -z "${CONN_STATE}" ]] && return 0 + # with AT, we can have connect request timeout near + # reconnect timeout and test can't see real disconnect + [[ "${CONN_STATE}" == "CONNECTING" ]] && return 0 + fi + if (( $i >= $maxtime )); then + (( $err_on_fail != 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) + i=$((i + 1)) + done - log "$CONN_PROC in ${CONN_STATE} state after $i sec" - return 0 + log "$CONN_PROC in ${CONN_STATE} state after $i sec" + return 0 } wait_import_state() { - 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 $error_on_failure || return - done + local expected="$1" + local params="$2" + local maxtime=${3:-$(max_recovery_time)} + local err_on_fail=${4:-1} + local param + + for param in ${params//,/ }; do + _wait_import_state "$expected" "$param" $maxtime $err_on_fail || + return + done } wait_import_state_mount() { @@ -7423,7 +7506,7 @@ wait_import_state_mount() { return 0 fi - wait_import_state $* + wait_import_state "$@" } # One client request could be timed out because server was not ready @@ -7503,8 +7586,9 @@ _wait_osc_import_state() { params=$param fi + local plist=$(comma_list $params) if ! do_rpc_nodes "$(facet_active_host $facet)" \ - wait_import_state $expected "$params" $maxtime; then + wait_import_state $expected $plist $maxtime; then error "$facet: import is not in $expected state after $maxtime" return 1 fi @@ -7559,8 +7643,9 @@ _wait_mgc_import_state() { params=$($LCTL list_param $param 2>/dev/null || true) done fi + local plist=$(comma_list $params) if ! do_rpc_nodes "$(facet_active_host $facet)" \ - wait_import_state $expected "$params" $maxtime \ + wait_import_state $expected $plist $maxtime \ $error_on_failure; then if [ $error_on_failure -ne 0 ]; then error "import is not in ${expected} state" @@ -7620,11 +7705,10 @@ do_rpc_nodes () { } wait_clients_import_state () { - local list=$1 - local facet=$2 - local expected=$3 - - local facets=$facet + local list="$1" + local facet="$2" + local expected="$3" + local facets="$facet" if [ "$FAILURE_MODE" = HARD ]; then facets=$(facets_on_host $(facet_active_host $facet)) @@ -7635,11 +7719,11 @@ wait_clients_import_state () { local proc_path case $facet in ost* ) proc_path="osc.$(get_clientosc_proc_path \ - $label).ost_server_uuid" ;; + $label).ost_server_uuid" ;; mds* ) proc_path="mdc.$(get_clientmdc_proc_path \ - $label).mds_server_uuid" ;; + $label).mds_server_uuid" ;; mgs* ) proc_path="mgc.$(get_clientmgc_proc_path \ - $label).mgs_server_uuid" ;; + $label).mgs_server_uuid" ;; *) error "unknown facet!" ;; esac @@ -7737,6 +7821,7 @@ check_pool_not_exist() { create_pool() { local fsname=${1%%.*} local poolname=${1##$fsname.} + local keep_pools=${2:-false} stack_trap "destroy_test_pools $fsname" EXIT do_facet mgs lctl pool_new $1 @@ -7755,7 +7840,7 @@ create_pool() { 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 + $keep_pools || add_pool_to_list $1 return $RC } @@ -7773,10 +7858,18 @@ remove_pool_from_list () { local poolname=${1##$fsname.} local listvar=${fsname}_CREATED_POOLS - local temp=${listvar}=$(exclude_items_from_list ${!listvar} $poolname) + local temp=${listvar}=$(exclude_items_from_list "${!listvar}" $poolname) eval export $temp } +# cleanup all pools exist on $FSNAME +destroy_all_pools () { + local i + for i in $(list_pool $FSNAME); do + destroy_pool $i + done +} + destroy_pool_int() { local ost local OSTS=$(list_pool $1) @@ -7797,8 +7890,7 @@ destroy_pool() { local RC - check_pool_not_exist $fsname.$poolname - [[ $? -eq 0 ]] && return 0 + check_pool_not_exist $fsname.$poolname && return 0 || true destroy_pool_int $fsname.$poolname RC=$? @@ -7892,8 +7984,11 @@ gather_logs () { fi if [ ! -f $LOGDIR/shared ]; then - do_nodes $list rsync -az "${prefix}.*.${suffix}" \ - $HOSTNAME:$LOGDIR + local remote_nodes=$(exclude_items_from_list $list $HOSTNAME) + + for node in ${remote_nodes//,/ }; do + rsync -az -e ssh $node:${prefix}.'*'.${suffix} $LOGDIR & + done fi } @@ -8463,94 +8558,6 @@ run_llverfs() llverfs $partial_arg $llverfs_opts $dir } -#Remove objects from OST -remove_ost_objects() { - local facet=$1 - local ostdev=$2 - local group=$3 - shift 3 - local objids="$@" - local mntpt=$(facet_mntpt $facet) - local opts=$OST_MOUNT_OPTS - local i - local rc - - echo "removing objects from $ostdev on $facet: $objids" - if ! test -b $ostdev; then - opts=$(csa_add "$opts" -o loop) - fi - mount -t $(facet_fstype $facet) $opts $ostdev $mntpt || - return $? - rc=0 - for i in $objids; do - rm $mntpt/O/$group/d$((i % 32))/$i || { rc=$?; break; } - done - umount -f $mntpt || return $? - return $rc -} - -#Remove files from MDT -remove_mdt_files() { - local facet=$1 - local mdtdev=$2 - shift 2 - local files="$@" - local mntpt=$(facet_mntpt $facet) - local opts=$MDS_MOUNT_OPTS - - echo "removing files from $mdtdev on $facet: $files" - if [ $(facet_fstype $facet) == ldiskfs ] && - ! do_facet $facet test -b $mdtdev; then - opts=$(csa_add "$opts" -o loop) - fi - mount -t $(facet_fstype $facet) $opts $mdtdev $mntpt || - return $? - rc=0 - for f in $files; do - rm $mntpt/ROOT/$f || { rc=$?; break; } - done - umount -f $mntpt || return $? - return $rc -} - -duplicate_mdt_files() { - local facet=$1 - local mdtdev=$2 - shift 2 - local files="$@" - local mntpt=$(facet_mntpt $facet) - local opts=$MDS_MOUNT_OPTS - - echo "duplicating files on $mdtdev on $facet: $files" - mkdir -p $mntpt || return $? - if [ $(facet_fstype $facet) == ldiskfs ] && - ! do_facet $facet test -b $mdtdev; then - opts=$(csa_add "$opts" -o loop) - fi - mount -t $(facet_fstype $facet) $opts $mdtdev $mntpt || - return $? - - do_umount() { - trap 0 - popd > /dev/null - rm $tmp - umount -f $mntpt - } - trap do_umount EXIT - - tmp=$(mktemp $TMP/setfattr.XXXXXXXXXX) - pushd $mntpt/ROOT > /dev/null || return $? - rc=0 - for f in $files; do - touch $f.bad || return $? - getfattr -n trusted.lov $f | sed "s#$f#&.bad#" > $tmp - rc=${PIPESTATUS[0]} - [ $rc -eq 0 ] || return $rc - setfattr --restore $tmp || return $? - done - do_umount -} - run_sgpdd () { local devs=${1//,/ } shift @@ -8638,17 +8645,6 @@ get_block_count() { echo -n ${count:-0} } -# Get the block size of the filesystem. -get_block_size() { - local facet=$1 - local device=$2 - local size - - [ -z "$CLIENTONLY" ] && size=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" | - awk '/^Block size:/ {print $3}') - echo -n ${size:-0} -} - # Check whether the "ea_inode" feature is enabled or not, to allow # ldiskfs xattrs over one block in size. Allow both the historical # Lustre feature name (large_xattr) and the upstream name (ea_inode). @@ -8884,7 +8880,7 @@ 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." + mkdir_on_mdt0 $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/* @@ -8950,8 +8946,18 @@ pool_add_targets() { fi local t=$(for i in $list; do printf "$FSNAME-OST%04x_UUID " $i; done) + local tg=$(for i in $list; + do printf -- "-e $FSNAME-OST%04x_UUID " $i; done) + local firstx=$(printf "%04x" $first) + local lastx=$(printf "%04x" $last) + do_facet mgs $LCTL pool_add \ - $FSNAME.$pool $FSNAME-OST[$first-$last/$step] + $FSNAME.$pool $FSNAME-OST[$firstx-$lastx/$step] + # ignore EEXIST(17) + if (( $? != 0 && $? != 17 )); then + error_noexit "pool_add $FSNAME-OST[$firstx-$lastx/$step] failed" + return 3 + fi # wait for OSTs to be added to the pool for mds_id in $(seq $MDSCOUNT); do @@ -8959,23 +8965,16 @@ pool_add_targets() { 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" || { + grep $tg | sort -u | tr '\n' ' '" "$t" || { error_noexit "mds$mds_id: Add to pool failed" - return 3 + return 2 } done - wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool \ - | sort -u | tr '\n' ' ' " "$t" || { + wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$pool | + grep $tg | 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() { @@ -9498,14 +9497,17 @@ check_clients_evicted() { local rc=0 for osc in $oscs; do - ((rc++)) echo "Check state for $osc" local evicted=$(do_facet client $LCTL get_param osc.$osc.state | - tail -n 3 | awk -F"[ [,]" \ - '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }') + tail -n 5 | awk -F"[ ,]" \ + '/EVICTED/ { if (mx<$4) { mx=$4; } } END { print mx }') if (($? == 0)) && (($evicted > $before)); then echo "$osc is evicted at $evicted" - ((rc--)) + else + ((rc++)) + echo "$osc was not evicted after $before:" + do_facet client $LCTL get_param osc.$osc.state | + tail -n 8 fi done @@ -9562,8 +9564,8 @@ changelog_register() { error "$mdt: changelog_mask=+hsm failed: $?" local cl_user - cl_user=$(do_facet $facet \ - $LCTL --device $mdt changelog_register -n) || + cl_user=$(do_facet $facet $LCTL --device $mdt \ + changelog_register -n $@) || error "$mdt: register changelog user failed: $?" stack_trap "__changelog_deregister $facet $cl_user" EXIT @@ -9650,6 +9652,7 @@ changelog_clear() { # so reorder to get same order than in changelog_register() local cl_facets=$(echo "${!CL_USERS[@]}" | tr " " "\n" | sort | tr "\n" " ") + local cl_user for facet in $cl_facets; do for cl_user in ${CL_USERS[$facet]}; do @@ -10027,19 +10030,16 @@ init_agt_vars() { export SINGLEAGT=${SINGLEAGT:-agt1} export HSMTOOL=${HSMTOOL:-"lhsmtool_posix"} + export HSMTOOL_PID_FILE=${HSMTOOL_PID_FILE:-"/var/run/lhsmtool_posix.pid"} export HSMTOOL_VERBOSE=${HSMTOOL_VERBOSE:-""} export HSMTOOL_UPDATE_INTERVAL=${HSMTOOL_UPDATE_INTERVAL:=""} export HSMTOOL_EVENT_FIFO=${HSMTOOL_EVENT_FIFO:=""} export HSMTOOL_TESTDIR + export HSMTOOL_ARCHIVE_FORMAT=${HSMTOOL_ARCHIVE_FORMAT:-v2} - # Copytools invoked from within the source tree are executed through a - # libtool script and have a different process name - from_build_tree && LIBTOOL_PREFIX=lt- - - export HSMTOOL_KILL=${LIBTOOL_PREFIX}${HSMTOOL} - - # pgrep(1) and pkill(1) limit process name matching to 15 characters - export HSMTOOL_PKILL=${HSMTOOL_KILL:0:15} + if ! [[ $HSMTOOL =~ hsmtool ]]; then + echo "HSMTOOL = '$HSMTOOL' does not contain 'hsmtool', GLWT" >&2 + fi HSM_ARCHIVE_NUMBER=2 @@ -10073,10 +10073,17 @@ get_mdt_devices() { done } +pkill_copytools() { + local hosts="$1" + local signal="$2" + + do_nodes "$hosts" "pkill --pidfile=$HSMTOOL_PID_FILE --signal=$signal hsmtool" +} + copytool_continue() { local agents=${1:-$(facet_active_host $SINGLEAGT)} - do_nodesv $agents "pkill -CONT -x $HSMTOOL_PKILL" || return 0 + pkill_copytools "$agents" CONT || return 0 echo "Copytool is continued on $agents" } @@ -10084,7 +10091,7 @@ kill_copytools() { local hosts=${1:-$(facet_active_host $SINGLEAGT)} echo "Killing existing copytools on $hosts" - do_nodesv $hosts "killall -q $HSMTOOL_KILL" || true + pkill_copytools "$hosts" TERM || return 0 copytool_continue "$hosts" } @@ -10120,28 +10127,29 @@ copytool_logfile() __lhsmtool_rebind() { - do_facet $facet $HSMTOOL -p "$hsm_root" --rebind "$@" "$mountpoint" + do_facet $facet $HSMTOOL "${hsmtool_options[@]}" --rebind "$@" "$mountpoint" } __lhsmtool_import() { mkdir -p "$(dirname "$2")" || error "cannot create directory '$(dirname "$2")'" - do_facet $facet $HSMTOOL -p "$hsm_root" --import "$@" "$mountpoint" + do_facet $facet $HSMTOOL "${hsmtool_options[@]}" --import "$@" "$mountpoint" } __lhsmtool_setup() { - local cmd="$HSMTOOL $HSMTOOL_VERBOSE --daemon --hsm-root \"$hsm_root\"" + local host="$(facet_host "$facet")" + local cmd="$HSMTOOL ${hsmtool_options[@]} --daemon --pid-file=$HSMTOOL_PID_FILE" [ -n "$bandwidth" ] && cmd+=" --bandwidth $bandwidth" [ -n "$archive_id" ] && cmd+=" --archive $archive_id" - [ ${#misc_options[@]} -gt 0 ] && - cmd+=" $(IFS=" " echo "$@")" - cmd+=" \"$mountpoint\"" +# [ ${#misc_options[@]} -gt 0 ] && +# cmd+=" $(IFS=" " echo "$@")" + cmd+=" $@ \"$mountpoint\"" - echo "Starting copytool $facet on $(facet_host $facet)" - stack_trap "do_facet $facet pkill -x '$HSMTOOL_PKILL' || true" EXIT - do_facet $facet "$cmd < /dev/null > \"$(copytool_logfile $facet)\" 2>&1" + echo "Starting copytool '$facet' on '$host' with cmdline '$cmd'" + stack_trap "pkill_copytools $host TERM || true" EXIT + do_node "$host" "$cmd < /dev/null > \"$(copytool_logfile $facet)\" 2>&1" } hsm_root() { @@ -10174,7 +10182,17 @@ copytool() # Parse arguments local fail_on_error=true - local -a misc_options + local -a hsmtool_options=("--hsm-root=$hsm_root") + local -a action_options=() + + if [[ -n "$HSMTOOL_ARCHIVE_FORMAT" ]]; then + hsmtool_options+=("--archive-format=$HSMTOOL_ARCHIVE_FORMAT") + fi + + if [[ -n "$HSMTOOL_VERBOSE" ]]; then + hsmtool_options+=("$HSMTOOL_VERBOSE") + fi + while [ $# -gt 0 ]; do case "$1" in -f|--facet) @@ -10202,7 +10220,7 @@ copytool() ;; *) # Uncommon(/copytool dependent) option - misc_options+=("$1") + action_options+=("$1") ;; esac shift @@ -10218,7 +10236,7 @@ copytool() ;; esac - __${copytool}_${action} "${misc_options[@]}" + __${copytool}_${action} "${action_options[@]}" if [ $? -ne 0 ]; then local error_msg @@ -10228,8 +10246,8 @@ copytool() error_msg="Failed to start copytool $facet on '$host'" ;; import) - local src="${misc_options[0]}" - local dest="${misc_options[1]}" + local src="${action_options[0]}" + local dest="${action_options[1]}" error_msg="Failed to import '$src' to '$dest'" ;; rebind) @@ -10476,12 +10494,12 @@ function createmany() { local saved_debug=$($LCTL get_param -n debug) local list=$(comma_list $(all_nodes)) - do_nodes $list $LCTL set_param debug=0 + do_nodes $list $LCTL set_param -n debug=0 } $LUSTRE/tests/createmany $* local rc=$? (( count > 100 )) && - do_nodes $list "$LCTL set_param debug=\\\"$saved_debug\\\"" + do_nodes $list "$LCTL set_param -n debug=\\\"$saved_debug\\\"" return $rc } @@ -10492,11 +10510,227 @@ function unlinkmany() { local saved_debug=$($LCTL get_param -n debug) local list=$(comma_list $(all_nodes)) - do_nodes $list $LCTL set_param debug=0 + do_nodes $list $LCTL set_param -n debug=0 } $LUSTRE/tests/unlinkmany $* local rc=$? (( count > 100 )) && - do_nodes $list "$LCTL set_param debug=\\\"$saved_debug\\\"" + do_nodes $list "$LCTL set_param -n debug=\\\"$saved_debug\\\"" return $rc } + +# Check if fallocate supported on OSTs, enable if unset, default mode=0 +# Optionally pass the OST fallocate mode (0=unwritten extents, 1=zero extents) +function check_set_fallocate() +{ + local new_mode="$1" + local osts=$(comma_list $(osts_nodes)) + local fa_mode="osd-ldiskfs.*.fallocate_zero_blocks" + local old_mode=$(do_facet ost1 $LCTL get_param -n $fa_mode 2>/dev/null| + head -n 1) + + [[ -n "$old_mode" ]] || { echo "fallocate not supported"; return 1; } + [[ -z "$new_mode" && "$old_mode" != "-1" ]] && + { echo "keep default fallocate mode: $old_mode"; return 0; } + [[ "$new_mode" && "$old_mode" == "$new_mode" ]] && + { echo "keep current fallocate mode: $old_mode"; return 0; } + + stack_trap "do_nodes $osts $LCTL set_param $fa_mode=$old_mode" + do_nodes $osts $LCTL set_param $fa_mode=${new_mode:-0} || + error "set $fa_mode=$new_mode" +} + +# Check if fallocate supported on OSTs, enable if unset, skip if unavailable +function check_set_fallocate_or_skip() +{ + [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend" + check_set_fallocate || skip "need at least 2.13.57 for fallocate" +} + +function disable_opencache() +{ + local state=$($LCTL get_param -n "llite.*.opencache_threshold_count" | head -1) + + test -z "${saved_OPENCACHE_value}" && + export saved_OPENCACHE_value="$state" + + [[ "$state" = "off" ]] && return + + $LCTL set_param -n "llite.*.opencache_threshold_count"=off +} + +function set_opencache() +{ + local newvalue="$1" + local state=$($LCTL get_param -n "llite.*.opencache_threshold_count") + + [[ -n "$newvalue" ]] || return + + [[ -n "${saved_OPENCACHE_value}" ]] || + export saved_OPENCACHE_value="$state" + + $LCTL set_param -n "llite.*.opencache_threshold_count"=$newvalue +} + + + +function restore_opencache() +{ + [[ -z "${saved_OPENCACHE_value}" ]] || + $LCTL set_param -n "llite.*.opencache_threshold_count"=${saved_OPENCACHE_value} +} + +# LU-13417: XXX lots of tests assume the directory to be created under MDT0, +# created on MDT0, use this function to create directory on specific MDT +# explicitly, and set default LMV to create subdirs on the same MDT too. +mkdir_on_mdt() { + local mdt + local OPTIND=1 + + while getopts "i:" opt $*; do + case $opt in + i) mdt=$OPTARG;; + esac + done + + shift $((OPTIND - 1)) + + $LFS mkdir -i $mdt -c 1 $* + # setting default LMV in non-DNE system will cause sanity-quota 41 fail + ((MDSCOUNT < 2)) || $LFS setdirstripe -D -i $mdt -c 1 $* +} + +mkdir_on_mdt0() { + mkdir_on_mdt -i0 $* +} + +# Wait for nodemap synchronization +wait_nm_sync() { + local nodemap_name=$1 + local key=$2 + local value=$3 + local opt=$4 + local proc_param + local is_active=$(do_facet mgs $LCTL get_param -n nodemap.active) + local max_retries=20 + local is_sync + local out1="" + local out2 + local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1) + local i + + if [ "$nodemap_name" == "active" ]; then + proc_param="active" + elif [ -z "$key" ]; then + proc_param=${nodemap_name} + else + proc_param="${nodemap_name}.${key}" + fi + if [ "$opt" == "inactive" ]; then + # check nm sync even if nodemap is not activated + is_active=1 + opt="" + fi + (( is_active == 0 )) && [ "$proc_param" != "active" ] && return + + if [ -z "$value" ]; then + out1=$(do_facet mgs $LCTL get_param $opt \ + nodemap.${proc_param} 2>/dev/null) + echo "On MGS ${mgs_ip}, ${proc_param} = $out1" + else + out1=$value; + fi + + # if servers run on the same node, it is impossible to tell if they get + # synced with the mgs, so just wait an arbitrary 10 seconds + if [ $(facet_active_host mgs) == $(facet_active_host mds) ] && + [ $(facet_active_host mgs) == $(facet_active_host ost1) ]; then + echo "waiting 10 secs for sync" + sleep 10 + return + fi + + # wait up to 10 seconds for other servers to sync with mgs + for i in $(seq 1 10); do + for node in $(all_server_nodes); do + local node_ip=$(host_nids_address $node $NETTYPE | + cut -d' ' -f1) + + is_sync=true + if [ -z "$value" ]; then + [ $node_ip == $mgs_ip ] && continue + fi + + out2=$(do_node $node_ip $LCTL get_param $opt \ + nodemap.$proc_param 2>/dev/null) + echo "On $node ${node_ip}, ${proc_param} = $out2" + [ "$out1" != "$out2" ] && is_sync=false && break + done + $is_sync && break + sleep 1 + done + if ! $is_sync; then + echo MGS + echo $out1 + echo OTHER - IP: $node_ip + echo $out2 + error "mgs and $nodemap_name ${key} mismatch, $i attempts" + fi + echo "waited $((i - 1)) seconds for sync" +} + +consume_precreations() { + local dir=$1 + local mfacet=$2 + local OSTIDX=$3 + local extra=${4:-2} + local OST=$(ostname_from_index $OSTIDX $dir) + + test_mkdir -p $dir/${OST} + $LFS setstripe -i $OSTIDX -c 1 ${dir}/${OST} + + # on the mdt's osc + local mdtosc_proc=$(get_mdtosc_proc_path $mfacet $OST) + local last_id=$(do_facet $mfacet $LCTL get_param -n \ + osp.$mdtosc_proc.prealloc_last_id) + local next_id=$(do_facet $mfacet $LCTL get_param -n \ + osp.$mdtosc_proc.prealloc_next_id) + echo "Creating to objid $last_id on ost $OST..." + createmany -o $dir/${OST}/f $next_id $((last_id - next_id + extra)) +} + +__exhaust_precreations() { + local OSTIDX=$1 + local FAILLOC=$2 + local FAILIDX=${3:-$OSTIDX} + local ofacet=ost$((OSTIDX + 1)) + + mkdir_on_mdt0 $DIR/$tdir + local mdtidx=$($LFS getstripe -m $DIR/$tdir) + local mfacet=mds$((mdtidx + 1)) + echo OSTIDX=$OSTIDX MDTIDX=$mdtidx + + local mdtosc_proc=$(get_mdtosc_proc_path $mfacet) + do_facet $mfacet $LCTL get_param osp.$mdtosc_proc.prealloc* + +#define OBD_FAIL_OST_ENOSPC 0x215 + do_facet $ofacet $LCTL set_param fail_val=$FAILIDX fail_loc=0x215 + + consume_precreations $DIR/$tdir $mfacet $OSTIDX + + do_facet $mfacet $LCTL get_param osp.$mdtosc_proc.prealloc* + do_facet $ofacet $LCTL set_param fail_loc=$FAILLOC +} + +exhaust_precreations() { + __exhaust_precreations $1 $2 $3 + sleep_maxage +} + +exhaust_all_precreations() { + local i + for (( i=0; i < OSTCOUNT; i++ )) ; do + __exhaust_precreations $i $1 -1 + done + sleep_maxage +}