Viewing: recovery-random-scale.sh
#!/usr/bin/bash
#
# client failure does not affect other clients
# Start load on clients (each client works on it's own directory).
# At defined (5-10 minutes) interval fail one random client and then fail mds.
# Reintegrate failed client after recovery completed,
# application errors are allowed for that client but not on other clients.
# 10 minute intervals and verify that no application errors occur.
# Test runs one of CLIENT_LOAD progs on remote clients.
set -e
ONLY=${ONLY:-"$*"}
LUSTRE=${LUSTRE:-$(dirname $0)/..}
. $LUSTRE/tests/test-framework.sh
init_test_env "$@"
init_logging
. $LUSTRE/tests/recovery-scale-lib.sh
# bug number for skipped test:
ALWAYS_EXCEPT="$RECOVERY_RANDOM_SCALE_EXCEPT "
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
build_test_filter
remote_mds_nodsh && skip_env "remote MDS with nodsh"
remote_ost_nodsh && skip_env "remote OST with nodsh"
if (( CLIENTCOUNT < 3 )); then
skip_env "need three or more clients"
fi
if [[ -z "$SHARED_DIRECTORY" ]] || ! check_shared_dir "$SHARED_DIRECTORY"; then
skip_env "SHARED_DIRECTORY should be specified with a shared directory \
which is accessible on all of the nodes"
fi
if [[ "$FAILURE_MODE" == "SOFT" ]]; then
log "WARNING: $0 is not functional with FAILURE_MODE = SOFT, bz22797"
fi
# Application failures are allowed for the failed client
# but not for other clients.
ERRORS_OK="yes"
init_stripe_dir_params RECOVERY_SCALE_ENABLE_REMOTE_DIRS \
RECOVERY_SCALE_ENABLE_STRIPED_DIRS
numfailovers () {
local facet
local var
for facet in ${MDTS//,/ } ${FAILED_CLIENTS//,/ }; do
var=$(node_var_name $facet)_nums
val=${!var}
if [ "$val" ] ; then
echo "$facet failed over $val times"
fi
done
}
check_and_setup_lustre
rm -rf $DIR/[Rdfs][0-9]*
insulate_clients
check_progs_installed $NODES_TO_USE "${CLIENT_LOADS[@]}"
MAX_RECOV_TIME=$(max_recovery_time)
MDTS=$(get_facets MDS)
OSTS=$(get_facets OST)
# Fail a random client and then failover a random MDS.
test_fail_client_mds() {
local fail_client
local serverfacet
local client_var
local var
stack_trap summary_and_cleanup EXIT INT
# start vmstat on OSS nodes
[[ -z "$VMSTAT" ]] || start_vmstat $(osts_nodes) $VMSTAT_PID_FILE
# start client loads
rm -f $END_RUN_FILE
start_client_loads $NODES_TO_USE
echo client loads pids:
do_nodesv $NODES_TO_USE "cat $LOAD_PID_FILE" || exit 3
ELAPSED=0
local it_time_start
local sleep=0
local reqfail=0
local start_ts=$(date +%s)
local current_ts=$start_ts
while [ $ELAPSED -lt $DURATION -a ! -e $END_RUN_FILE ]; do
# In order to perform the
# expected number of failovers, we need to account the
# following:
# 1) the time that has elapsed during the client load checking
# 2) time takes for failover
it_time_start=$(date +%s)
fail_client=$(get_random_entry $NODES_TO_USE)
client_var=$(node_var_name $fail_client)_nums
# store the list of failed clients
# lists are comma separated
FAILED_CLIENTS=$(expand_list $FAILED_CLIENTS $fail_client)
serverfacet=$(get_random_entry $MDTS)
var=$(node_var_name $serverfacet)_nums
# Check that our client loads are still running. If any have
# died, that means they have died outside of recovery, which
# is unacceptable.
log "==== Checking clients loads BEFORE failover -- failure NOT OK \
ELAPSED=$ELAPSED DURATION=$DURATION \
PERIOD=$SERVER_FAILOVER_PERIOD"
check_client_loads $NODES_TO_USE || exit 4
log "FAIL CLIENT $fail_client..."
shutdown_client $fail_client
log "Starting failover on $serverfacet"
facet_failover "$serverfacet" || exit 1
if ! wait_recovery_complete $serverfacet; then
echo "$serverfacet recovery is not completed!"
exit 7
fi
boot_node $fail_client
echo "Reintegrating $fail_client"
zconf_mount $fail_client $MOUNT || exit $?
client_up $fail_client || exit $?
# Increment the number of failovers
val=$((${!var} + 1))
eval $var=$val
val=$((${!client_var} + 1))
eval $client_var=$val
# load script on failed clients could create END_RUN_FILE
# We shuold remove it and ignore the failure if this
# file contains the failed client only.
# We can not use ERRORS_OK when start all loads at the start of
# this script because the application errors allowed for random
# failed client only, but not for all clients.
if [ -e $END_RUN_FILE ]; then
local end_run_node
read end_run_node < $END_RUN_FILE
if [[ $end_run_node = $fail_client ]]; then
rm -f $END_RUN_FILE
else
echo "failure is expected on FAIL CLIENT \
$fail_client, not on $end_run_node"
exit 13
fi
fi
restart_client_loads $fail_client $ERRORS_OK || exit $?
# Check that not failed clients loads are still running.
# No application failures should occur on clients that were
# not failed.
log "==== Checking clients loads AFTER failed client reintegrated \
-- failure NOT OK"
if ! ERRORS_OK= check_client_loads \
$(exclude_items_from_list $NODES_TO_USE $fail_client); then
log "Client load failed. Exiting..."
exit 5
fi
current_ts=$(date +%s)
ELAPSED=$((current_ts - start_ts))
sleep=$((SERVER_FAILOVER_PERIOD - (current_ts - it_time_start)))
# Keep counting the number of iterations when
# time spent to failover and two client loads check exceeded
# the value ( SERVER_FAILOVER_PERIOD - MINSLEEP ).
if [ $sleep -lt $MINSLEEP ]; then
reqfail=$((reqfail + 1))
log "WARNING: failover, client reintegration and \
check_client_loads time exceeded SERVER_FAILOVER_PERIOD - MINSLEEP!
Failed to load the filesystem with I/O for a minimum period of \
$MINSLEEP $reqfail times ( REQFAIL=$REQFAIL ).
This iteration, the load was only applied for sleep=$sleep seconds.
Estimated max recovery time : $MAX_RECOV_TIME
Probably the hardware is taking excessively long time to boot.
Try to increase SERVER_FAILOVER_PERIOD (current is $SERVER_FAILOVER_PERIOD), \
bug 20918"
[ $reqfail -gt $REQFAIL ] && exit 6
fi
log "Number of failovers:
$(numfailovers) and counting..."
[ $((ELAPSED + sleep)) -ge $DURATION ] && break
if [ $sleep -gt 0 ]; then
echo "sleeping $sleep seconds... "
sleep $sleep
fi
done
exit 0
}
run_test fail_client_mds "fail client, then failover MDS"
zconf_mount $HOSTNAME $MOUNT || error "mount $MOUNT on $HOSTNAME failed"
client_up || error "start client on $HOSTNAME failed"
complete_test $SECONDS
check_and_cleanup_lustre
exit_status