3 ######################################################################
6 # specify obd names (host:name if remote)
7 # these can either be the echo_client names (client_names)
8 # or the ost names (ost_names)
9 #client_names=(ns8:ECHO_ns8 ns9:ECHO_ns9)
10 ost_names=(ns9:ost{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16})
12 # result file prefix (date/time + hostname makes unique)
13 rslt=/home_nfs/eeb/obdfilter_survey_`date +%F@%R`_`uname -n`
15 # lustre root (if running with own source tree)
16 lustre_root=/home_nfs/eeb/lustre
18 # what to do (we always do an initial write)
19 #tests="rewrite read reread rewrite_again"
22 # total size (MBytes) per OST
23 # large enough to avoid cache effects
24 # and to make test startup/shutdown overhead insignificant
27 # record size (KBytes)
31 # number of objects per OST
35 # threads per OST (1024 max)
39 # restart from here iff all are defined
44 # machine's page size (K)
47 # max buffer_mem (total_threads * buffer size)
48 # (to avoid lctl ENOMEM problems)
49 max_buffer_mem=$((1024*1024))
51 # how to run commands on other nodes
52 custom_remote_shell () {
57 # Hop on to the remote node, chdir to 'here' and run the given
58 # commands. One of the following will probably work.
59 ssh $host "cd $here; $cmds"
60 #rsh $host "cd $here; $cmds"
61 # we have to remove the leading `uname -n`: from pdsh output lines
62 #pdsh -w $host "cd $here; $cmds" | sed 's/^[^:]*://'
65 #####################################################################
66 # leave the rest of this alone unless you know what you're doing...
69 modprobe="/sbin/modprobe"
76 rsltf="${rslt}.summary"
77 cmdsf="${rslt}.script"
78 workf="${rslt}.detail"
82 if [ -z "$lustre_root" ]; then
85 lctl=${lustre_root}/utils/lctl
92 if [ "$host" = "localhost" -o "$host" = `uname -n` ]; then
95 custom_remote_shell $host "$cmds"
101 remote_shell $host $lsmod | grep obdecho > /dev/null 2>&1
106 if [ -z "$lustre_root" ]; then
107 remote_shell $host $modprobe obdecho
108 elif [ -f ${lustre_root}/obdecho/obdecho.ko ]; then
109 remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.ko
111 remote_shell $host $insmod ${lustre_root}/obdecho/obdecho.o
117 remote_shell $host $rmmod obdecho
124 remote_shell $host $lctl device_list | \
125 awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\
131 local client_name="$2"
133 if [ -z "$client_name" ]; then
134 if [ -z "$ost_name" ]; then
135 echo "client and ost name both null" 1>&2
138 client_name=${ost_name}_echo_client
140 ec=`get_devno $host echo_client $client_name`
141 if [ -n "$ec" ]; then
142 echo $ec $client_name 0
145 if [ -z "$ost_name" ]; then
146 echo "no echo client and ost_name not set" 1>&2
149 ost=`get_devno $host obdfilter $ost_name`
150 if [ -z "$ost" ]; then
151 echo "OST $ost_name not setup" 1>&2
154 remote_shell $host "$lctl <<EOF
155 attach echo_client $client_name ${client_name}_UUID
158 ec=`get_devno $host echo_client $client_name`
159 if [ -z "$ec" ]; then
160 echo "Can't setup echo client" 1>&2
163 echo $ec $client_name 1
166 teardown_ec_devno () {
169 remote_shell $host "$lctl <<EOF
177 # create a set of objects, check there are 'n' contiguous ones and
178 # return the first or 'ERROR'
183 remote_shell $host $lctl --device $devno create $nobj > $rfile 2>&1
185 '/is object id/ {obj=strtonum($6);\
186 first=!not_first; not_first=1;\
187 if (first) first_obj=obj;
188 else if (obj != prev + 1) exit;\
190 END {printf "%d %d\n", first_obj, n}'`)
191 if ((n[1] != nobj)); then
204 remote_shell $host $lctl --device $devno destroy $obj0 $nobj > $rfile 2>&1
210 '/^Selected device [0-9]+$/ {n = 0; next}\
211 /error/ {n = -1; exit}\
212 /^[0-9]+\/[0-9]+ Total: [0-9]+\.[0-9]+\/second$/ {n++; v=strtonum($3); \
213 if (n == 1 || v < min) min = v;\
214 if (n == 1 || v > max) max = v;\
216 {if (n != 0) {n = -1; exit}}\
217 END {printf "%d %f %f\n", n, min, max}'
220 get_global_stats () {
222 awk < $rfile 'BEGIN {n = 0;}\
223 {n++; if (n == 1) {err = $1; min = $2; max = $3} else\
224 {if ($1 < err) err = $1;\
225 if ($2 < min) min = $2;\
226 if ($3 > max) max = $3}}\
227 END {if (n == 0) err = 0;\
228 printf "%d %f %f\n", err, min, max}'
232 # 'x' disables data check
239 *write*) echo "w$x";;
245 if [ "$1" = "-n" ]; then
250 echo $minusn "$*" >> $rsltf
255 echo "$@" | xargs -n1 echo | sort -u
261 *:*) host=`echo $name | sed 's/:.*$//'`
262 name=`echo $name | sed 's/[^:]*://'`
270 ndevs=${#client_names[@]}
271 if ((ndevs != 0)); then
272 if ((${#ost_names[@]} != 0)); then
273 echo "Please specify client_names or ost_names, but not both" 1>&2
276 for ((i=0; i<ndevs;i++)); do
277 str=(`split_hostname ${client_names[$i]}`)
278 host_names[$i]=${str[0]}
279 client_names[$i]=${str[1]}
282 ndevs=${#ost_names[@]}
283 if ((ndevs == 0)); then
284 echo "Please specify either client_names or ost_names" 1>&2
287 for ((i=0; i<ndevs;i++)); do
288 str=(`split_hostname ${ost_names[$i]}`)
289 host_names[$i]=${str[0]}
290 ost_names[$i]=${str[1]}
294 unique_hosts=(`unique ${host_names[@]}`)
296 for host in ${unique_hosts[@]}; do
297 remote_shell $host "echo 0 > /proc/sys/portals/debug"
298 do_unload_obdecho[$host]=0
299 if check_obdecho $host; then
303 if check_obdecho $host; then
304 do_unload_obdecho[$host]=1
307 echo "Can't load obdecho on $host" 1>&2
311 for ((i=0; i<ndevs; i++)); do
312 host=${host_names[$i]}
313 devno=(`get_ec_devno $host "${client_names[$i]}" "${ost_names[$i]}"`)
314 if ((${#devno[@]} != 3)); then
317 devnos[$i]=${devno[0]}
318 client_names[$i]=${devno[1]}
319 do_teardown_ec[$i]=${devno[2]}
322 for ((rsz=$rszlo;rsz<=$rszhi;rsz*=2)); do
323 for ((nobj=$nobjlo;nobj<=$nobjhi;nobj*=2)); do
324 for ((thr=$thrlo;thr<=$thrhi;thr*=2)); do
325 if ((thr < nobj)); then
329 if [ -n "$restart_rsz" -a\
330 -n "$restart_nobj" -a\
331 -n "$restart_thr" ]; then
332 if ((rsz < restart_rsz ||\
333 (rsz == restart_rsz &&\
334 (nobj < restart_nobj ||\
335 (nobj == restart_nobj &&\
336 thr < restart_thr))))); then
341 total_thr=$((ndevs*thr))
342 total_nobj=$((ndevs*nobj))
343 pages=$((rsz/PAGE_SIZE))
344 actual_rsz=$((pages*PAGE_SIZE))
345 count=$((size*1024/(actual_rsz*thr)))
346 actual_size=$((actual_rsz*count*thr))
347 total_size=$((actual_size*ndevs))
348 # show computed parameters
349 str=`printf 'ost %2d sz %8dK rsz %4d obj %4d thr %4d ' \
350 $ndevs $total_size $actual_rsz $total_nobj $total_thr`
351 echo "=======================> $str" >> $workf
352 print_summary -n "$str"
353 if ((total_thr * actual_rsz > max_buffer_mem)); then
354 print_summary "Too much buffer space"
359 for ((idx=0; idx < ndevs; idx++)); do
360 host=${host_names[$idx]}
361 devno=${devnos[$idx]}
362 client_name="${host}:${client_names[$idx]}"
363 echo "=============> Create $nobj on $client_name" >> $workf
364 first_obj=`create_objects $host $devno $nobj $tmpf`
367 if [ $first_obj = "ERROR" ]; then
368 print_summary "created object #s on $client_name not contiguous"
371 first_objs[$idx]=$first_obj
373 for test in write $tests; do
374 print_summary -n "$test "
375 for host in ${unique_hosts[@]}; do
376 echo -n > ${cmdsf}_${host}
378 for ((idx=0; idx < ndevs; idx++)); do
379 host=${host_names[$idx]}
380 devno=${devnos[$idx]}
382 first_obj=${first_objs[$idx]}
383 echo >> ${cmdsf}_${host} \
384 "$lctl > $tmpfi 2>&1 \\
385 --threads $thr -$snap $devno \\
386 test_brw $count `testname2type $test` q $pages ${thr}t${first_obj} &"
388 for host in ${unique_hosts[@]}; do
389 echo "wait" >> ${cmdsf}_${host}
392 for host in ${unique_hosts[@]}; do
393 remote_shell $host bash ${cmdsf}_${host}&
397 for host in ${unique_hosts[@]}; do
400 str=`awk "BEGIN {printf \"%7.2f \",\
401 $total_size / (( $t1 - $t0 ) * 1024)}"`
402 print_summary -n "$str"
404 for ((idx=0; idx < ndevs; idx++)); do
405 client_name="${host_names[$idx]}:${client_names[$idx]}"
407 echo "=============> $test $client_name" >> $workf
409 get_stats $tmpfi >> $tmpf
412 echo "=============> $test global" >> $workf
414 stats=(`get_global_stats $tmpf`)
416 if ((stats[0] <= 0)); then
417 if ((stats[0] < 0)); then
418 str=`printf "%17s " ERROR`
420 str=`printf "%17s " SHORT`
423 str=`awk "BEGIN {printf \"[%7.2f,%7.2f] \",\
424 (${stats[1]} * $actual_rsz)/1024,\
425 (${stats[2]} * $actual_rsz)/1024; exit}"`
427 print_summary -n "$str"
430 for ((idx=0; idx < ndevs; idx++)); do
431 host=${host_names[$idx]}
432 devno=${devnos[$idx]}
433 client_name="${host}:${client_names[$idx]}"
434 first_obj=${first_objs[$idx]}
435 echo "=============> Destroy $nobj on $client_name" >> $workf
436 destroy_objects $host $devno $first_obj $nobj $tmpf
444 for ((i=0; i<ndevs; i++)); do
445 host=${host_names[$i]}
446 if ((${do_teardown_ec[$i]})); then
447 teardown_ec_devno $host ${client_names[$i]}
451 for host in ${unique_hosts[@]}; do
452 if ((${do_unload_obdecho[$host]})); then