X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre-iokit%2Fobdfilter-survey%2Fobdfilter-survey;h=6a762928b44fefa0c0fa7b593af7a1edf7eb2284;hp=f700a8810f6f39b56270dd1b9be43107bf65350e;hb=15470766199cbaf796375a93f341c084c7179981;hpb=d03c475e63cac8beeb20613d2e42881ae417eeb2 diff --git a/lustre-iokit/obdfilter-survey/obdfilter-survey b/lustre-iokit/obdfilter-survey/obdfilter-survey index f700a88..6a76292 100755 --- a/lustre-iokit/obdfilter-survey/obdfilter-survey +++ b/lustre-iokit/obdfilter-survey/obdfilter-survey @@ -3,23 +3,30 @@ ###################################################################### # customize per survey -# specify either the obdecho client names or the obdfilter names -client_names=() -ost_names=(ost{1,2,3,4,5,6,7,8}) - -# result file prefix -rslt=/tmp/obdfilter_survey - -# lustre root (leave blank unless running with own source) -lustre_root= - -# what to do (we always do an initial write) -#tests="rewrite read reread rewrite_again" -tests="rewrite read" - -# total size (MBytes) -# large enough to avoid cache effects -size=8192 +# specify obd instances to exercise +# these can be either... +# obdfilter instances (set 'ost_names') +# ...or... +# echo_client instances (set 'client_names') +# ... use 'host:name' for obd instances on other nodes. +ost_names=(ost{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}) +#client_names=(ns8:ECHO_ns8 ns9:ECHO_ns9) + +# result file prefix (date/time + hostname makes unique) +# NB ensure path to it exists +rslt=/home_nfs/eeb/obdfilter_survey_`date +%F@%R`_`uname -n` + +# lustre root (if running with own source tree) +lustre_root=/home_nfs/eeb/lustre + +# what tests to run (first must be write) +#tests=(write rewrite read reread rewrite_again) +tests=(write rewrite read) + +# total size (MBytes) per obd instance +# large enough to avoid cache effects +# and to make test startup/shutdown overhead insignificant +size=16384 # record size (KBytes) rszlo=1024 @@ -27,65 +34,116 @@ rszhi=1024 # number of objects per OST nobjlo=1 -nobjhi=32 +nobjhi=512 # threads per OST (1024 max) thrlo=1 -thrhi=128 +thrhi=64 # restart from here iff all are defined restart_rsz= restart_thr=1 restart_nobj=1 -# machine's page size +# machine's page size (K) PAGE_SIZE=64 # max buffer_mem (total_threads * buffer size) # (to avoid lctl ENOMEM problems) -max_buffer_mem=$((256*1024)) +max_buffer_mem=$((1024*1024)) + +# how to run commands on other nodes +# You need to make this work on your cluster if you have specified +# non-local obd instances above +custom_remote_shell () { + host=$1 + shift + cmds="$*" + here=`pwd` + # Hop on to the remote node, chdir to 'here' and run the given + # commands. One of the following will probably work. + ssh $host "cd $here; $cmds" + #rsh $host "cd $here; $cmds" + # we have to remove the leading `uname -n`: from pdsh output lines + #pdsh -w $host "cd $here; $cmds" | sed 's/^[^:]*://' +} ##################################################################### +# leave the rest of this alone unless you know what you're doing... + +# binaries +lsmod="/sbin/lsmod" +modprobe="/sbin/modprobe" +insmod="/sbin/insmod" +rmmod="/sbin/rmmod" +# lctl::test_brw bandwidth snapshot interval (seconds) snap=1 +# check file contents? verify=1 -check_obdecho() { - lsmod | grep obdecho > /dev/null 2>&1 -} +if [ ${#tests[@]} -eq 0 -o "${tests[0]}" != "write" ]; then + echo "First test must be 'write'" 1>&2 + exit 1 +fi -check_obdecho -load_obdecho=$(($? != 0)) +rsltf="${rslt}.summary" +workf="${rslt}.detail" +cmdsf="${rslt}.script" +echo -n > $rsltf +echo -n > $workf if [ -z "$lustre_root" ]; then lctl=lctl - if ((load_obdecho)); then - modprobe obdecho - fi else - lctl=${lustre_root}/lctl - if ((load_obdecho)); then - if [ -f ${lustre_root}/obdecho/obdecho.ko ]; then - insmod ${lustre_root}/obdecho/obdecho.ko - else - insmod ${lustre_root}/obdecho/obdecho.o - fi - fi + lctl=${lustre_root}/utils/lctl fi -check_obdecho || (echo "Can't load obdecho"; exit 1) +remote_shell () { + host=$1 + shift + cmds="$*" + if [ "$host" = "localhost" -o "$host" = `uname -n` ]; then + eval "$cmds" + else + custom_remote_shell $host "$cmds" + fi +} + +obdecho_loaded() { + local host=$1 + remote_shell $host $lsmod | grep obdecho > /dev/null 2>&1 +} + +load_obdecho () { + local host=$1 + if [ -z "$lustre_root" ]; then + remote_shell $host $modprobe obdecho + elif [ -f ${lustre_root}/obdecho/obdecho.ko ]; then + remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.ko + else + remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.o + fi +} + +unload_obdecho () { + local host=$1 + remote_shell $host $rmmod obdecho +} get_devno () { - local type=$1 - local name=$2 - $lctl device_list | awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\ - print \$1; exit}}" + local host=$1 + local type=$2 + local name=$3 + remote_shell $host $lctl device_list | \ + awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\ + print \$1; exit}}" } get_ec_devno () { - local idx=$1 - local client_name=${client_names[idx]} - local ost_name=${ost_names[idx]} + local host=$1 + local client_name="$2" + local ost_name="$3" if [ -z "$client_name" ]; then if [ -z "$ost_name" ]; then echo "client and ost name both null" 1>&2 @@ -93,25 +151,25 @@ get_ec_devno () { fi client_name=${ost_name}_echo_client fi - ec=`get_devno echo_client $client_name` + ec=`get_devno $host echo_client $client_name` if [ -n "$ec" ]; then - echo $ec $client_name + echo $ec $client_name 0 return fi if [ -z "$ost_name" ]; then echo "no echo client and ost_name not set" 1>&2 return fi - ost=`get_devno obdfilter $ost_name` + ost=`get_devno $host obdfilter $ost_name` if [ -z "$ost" ]; then echo "OST $ost_name not setup" 1>&2 return fi - $lctl <&2 return @@ -120,24 +178,23 @@ EOF } teardown_ec_devno () { - local idx=$1 - local client_name=${client_names[$idx]} - if ((do_teardown_ec[$idx])); then - $lctl < $rfile 2>&1 + local host=$1 + local devno=$2 + local nobj=$3 + local rfile=$4 + remote_shell $host $lctl --device $devno create $nobj > $rfile 2>&1 n=(`awk < $rfile \ '/is object id/ {obj=strtonum($6);\ first=!not_first; not_first=1;\ @@ -153,11 +210,12 @@ create_objects () { } destroy_objects () { - local devno=$1 - local obj0=$2 - local nobj=$3 - local rfile=$4 - $lctl --device $devno destroy $obj0 $nobj > $rfile 2>&1 + local host=$1 + local devno=$2 + local obj0=$3 + local nobj=$4 + local rfile=$5 + remote_shell $host $lctl --device $devno destroy $obj0 $nobj > $rfile 2>&1 } get_stats () { @@ -197,12 +255,6 @@ testname2type () { esac } -start=`date +%F@%R` -rsltf="${rslt}_${start}.summary" -echo -n > $rsltf -workf="${rslt}_${start}.detail" -echo -n > $workf - print_summary () { if [ "$1" = "-n" ]; then minusn=$1; shift @@ -213,22 +265,75 @@ print_summary () { echo $minusn "$*" } +unique () { + echo "$@" | xargs -n1 echo | sort -u +} + +split_hostname () { + local name=$1 + case $name in + *:*) host=`echo $name | sed 's/:.*$//'` + name=`echo $name | sed 's/[^:]*://'` + ;; + *) host=localhost + ;; + esac + echo "$host $name" +} + +# split out hostnames from client/ost names ndevs=${#client_names[@]} -if ((ndevs < ${#ost_names[@]} )); then +if ((ndevs != 0)); then + if ((${#ost_names[@]} != 0)); then + echo "Please specify client_names or ost_names, but not both" 1>&2 + exit 1 + fi + for ((i=0; i&2 + exit 1 + fi + for ((i=0; i /proc/sys/portals/debug" + do_unload_obdecho[$host]=0 + if obdecho_loaded $host; then + continue + fi + load_obdecho $host + if obdecho_loaded $host; then + do_unload_obdecho[$host]=1 + continue fi - devnos[$idx]=${devno[0]} - client_names[$idx]=${devno[1]} - do_teardown_ec[$idx]=$((${#devno[@]} > 2)) + echo "Can't load obdecho on $host" 1>&2 + exit 1 done -echo 0 > /proc/sys/portals/debug +# get all the echo_client device numbers and names +for ((i=0; i Create [$idx]" >> $workf + client_name="${host}:${client_names[$idx]}" + echo "=============> Create $nobj on $client_name" >> $workf + first_obj=`create_objects $host $devno $nobj $tmpf` cat $tmpf >> $workf rm $tmpf if [ $first_obj = "ERROR" ]; then - print_summary "created object #s [$idx] not contiguous" + print_summary "created object #s on $client_name not contiguous" exit 1 fi first_objs[$idx]=$first_obj done - for test in write $tests; do + # run tests + for test in ${tests[@]}; do print_summary -n "$test " - t0=`date +%s.%N` + # create per-host script files + for host in ${unique_hosts[@]}; do + echo -n > ${cmdsf}_${host} + done for ((idx=0; idx < ndevs; idx++)); do + host=${host_names[$idx]} devno=${devnos[$idx]} tmpfi="${tmpf}_$idx" first_obj=${first_objs[$idx]} - $lctl > $tmpfi 2>&1 \ - --threads $thr -$snap $devno \ - test_brw $count `testname2type $test` q $pages ${thr}t${first_obj} & + echo >> ${cmdsf}_${host} \ + "$lctl > $tmpfi 2>&1 \\ + --threads $thr -$snap $devno \\ + test_brw $count `testname2type $test` q $pages ${thr}t${first_obj} &" + done + for host in ${unique_hosts[@]}; do + echo "wait" >> ${cmdsf}_${host} + done + # timed run of all the per-host script files + t0=`date +%s.%N` + for host in ${unique_hosts[@]}; do + remote_shell $host bash ${cmdsf}_${host}& done wait t1=`date +%s.%N` + # clean up per-host script files + for host in ${unique_hosts[@]}; do + rm ${cmdsf}_${host} + done + # compute bandwidth from total data / elapsed time str=`awk "BEGIN {printf \"%7.2f \",\ $total_size / (( $t1 - $t0 ) * 1024)}"` print_summary -n "$str" + # collect/check individual OST stats echo -n > $tmpf for ((idx=0; idx < ndevs; idx++)); do + client_name="${host_names[$idx]}:${client_names[$idx]}" tmpfi="${tmpf}_$idx" - echo "========> $test [$idx]" >> $workf + echo "=============> $test $client_name" >> $workf cat $tmpfi >> $workf get_stats $tmpfi >> $tmpf rm $tmpfi done - echo "========> $test [$idx] global" >> $workf + # compute/display global min/max stats + echo "=============> $test global" >> $workf cat $tmpf >> $workf stats=(`get_global_stats $tmpf`) rm $tmpf if ((stats[0] <= 0)); then if ((stats[0] < 0)); then - str=`printf "%15s " ERROR` + str=`printf "%17s " ERROR` else - str=`printf "%15s " SHORT` + str=`printf "%17s " SHORT` fi else - str=`awk "BEGIN {printf \"[%6.2f,%6.2f] \",\ + str=`awk "BEGIN {printf \"[%7.2f,%7.2f] \",\ (${stats[1]} * $actual_rsz)/1024,\ (${stats[2]} * $actual_rsz)/1024; exit}"` fi print_summary -n "$str" done print_summary "" + # destroy objects we created for ((idx=0; idx < ndevs; idx++)); do + host=${host_names[$idx]} devno=${devnos[$idx]} + client_name="${host}:${client_names[$idx]}" first_obj=${first_objs[$idx]} - destroy_objects $devno $first_obj $nobj $tmpf - echo "========> Destroy [$idx]" >> $workf + echo "=============> Destroy $nobj on $client_name" >> $workf + destroy_objects $host $devno $first_obj $nobj $tmpf cat $tmpf >> $workf rm $tmpf done @@ -333,10 +465,17 @@ for ((rsz=$rszlo;rsz<=$rszhi;rsz*=2)); do done done -for ((idx=0; idx < ndevs; idx++)); do - teardown_ec_devno $idx +# tear down any echo clients we created +for ((i=0; i