3 ######################################################################
6 # specify either the obdecho client names or the obdfilter names
8 ost_names=(ost{1,2,3,4,5,6,7,8})
11 rslt=/tmp/obdfilter_survey
13 # lustre root (leave blank unless running with own source)
16 # what to do (we always do an initial write)
17 #tests="rewrite read reread rewrite_again"
21 # large enough to avoid cache effects
24 # record size (KBytes)
28 # number of objects per OST
32 # threads per OST (1024 max)
36 # restart from here iff all are defined
44 # max buffer_mem (total_threads * buffer size)
45 # (to avoid lctl ENOMEM problems)
46 max_buffer_mem=$((256*1024))
48 #####################################################################
54 lsmod | grep obdecho > /dev/null 2>&1
58 load_obdecho=$(($? != 0))
60 if [ -z "$lustre_root" ]; then
62 if ((load_obdecho)); then
66 lctl=${lustre_root}/lctl
67 if ((load_obdecho)); then
68 if [ -f ${lustre_root}/obdecho/obdecho.ko ]; then
69 insmod ${lustre_root}/obdecho/obdecho.ko
71 insmod ${lustre_root}/obdecho/obdecho.o
76 check_obdecho || (echo "Can't load obdecho"; exit 1)
81 $lctl device_list | awk "{if (\$2 == \"UP\" && \$3 == \"$type\" && \$4 == \"$name\") {\
87 local client_name=${client_names[idx]}
88 local ost_name=${ost_names[idx]}
89 if [ -z "$client_name" ]; then
90 if [ -z "$ost_name" ]; then
91 echo "client and ost name both null" 1>&2
94 client_name=${ost_name}_echo_client
96 ec=`get_devno echo_client $client_name`
101 if [ -z "$ost_name" ]; then
102 echo "no echo client and ost_name not set" 1>&2
105 ost=`get_devno obdfilter $ost_name`
106 if [ -z "$ost" ]; then
107 echo "OST $ost_name not setup" 1>&2
111 attach echo_client $client_name ${client_name}_UUID
114 ec=`get_devno echo_client $client_name`
115 if [ -z "$ec" ]; then
116 echo "Can't setup echo client" 1>&2
119 echo $ec $client_name 1
122 teardown_ec_devno () {
124 local client_name=${client_names[$idx]}
125 if ((do_teardown_ec[$idx])); then
135 # create a set of objects, check there are 'n' contiguous ones and
136 # return the first or 'ERROR'
140 $lctl --device $devno create $nobj > $rfile 2>&1
142 '/is object id/ {obj=strtonum($6);\
143 first=!not_first; not_first=1;\
144 if (first) first_obj=obj;
145 else if (obj != prev + 1) exit;\
147 END {printf "%d %d\n", first_obj, n}'`)
148 if ((n[1] != nobj)); then
160 $lctl --device $devno destroy $obj0 $nobj > $rfile 2>&1
166 '/^Selected device [0-9]+$/ {n = 0; next}\
167 /error/ {n = -1; exit}\
168 /^[0-9]+\/[0-9]+ Total: [0-9]+\.[0-9]+\/second$/ {n++; v=strtonum($3); \
169 if (n == 1 || v < min) min = v;\
170 if (n == 1 || v > max) max = v;\
172 {if (n != 0) {n = -1; exit}}\
173 END {printf "%d %f %f\n", n, min, max}'
176 get_global_stats () {
178 awk < $rfile 'BEGIN {n = 0;}\
179 {n++; if (n == 1) {err = $1; min = $2; max = $3} else\
180 {if ($1 < err) err = $1;\
181 if ($2 < min) min = $2;\
182 if ($3 > max) max = $3}}\
183 END {if (n == 0) err = 0;\
184 printf "%d %f %f\n", err, min, max}'
188 # 'x' disables data check
195 *write*) echo "w$x";;
201 rsltf="${rslt}_${start}.summary"
203 workf="${rslt}_${start}.detail"
207 if [ "$1" = "-n" ]; then
212 echo $minusn "$*" >> $rsltf
216 ndevs=${#client_names[@]}
217 if ((ndevs < ${#ost_names[@]} )); then
218 ndevs=${#ost_names[@]}
221 for ((idx = 0; idx < ndevs; idx++)); do
222 devno=(`get_ec_devno $idx`)
223 if ((${#devno[@]} < 2)); then
226 devnos[$idx]=${devno[0]}
227 client_names[$idx]=${devno[1]}
228 do_teardown_ec[$idx]=$((${#devno[@]} > 2))
231 echo 0 > /proc/sys/portals/debug
233 for ((rsz=$rszlo;rsz<=$rszhi;rsz*=2)); do
234 for ((nobj=$nobjlo;nobj<=$nobjhi;nobj*=2)); do
235 for ((thr=$thrlo;thr<=$thrhi;thr*=2)); do
236 if ((thr < nobj)); then
240 if [ -n "$restart_rsz" -a\
241 -n "$restart_nobj" -a\
242 -n "$restart_thr" ]; then
243 if ((rsz < restart_rsz ||\
244 (rsz == restart_rsz &&\
245 (nobj < restart_nobj ||\
246 (nobj == restart_nobj &&\
247 thr < restart_thr))))); then
252 total_thr=$((ndevs*thr))
253 total_nobj=$((ndevs*nobj))
254 pages=$((rsz/PAGE_SIZE))
255 actual_rsz=$((pages*PAGE_SIZE))
256 count=$((size*1024/(actual_rsz*thr)))
257 actual_size=$((actual_rsz*count*thr))
258 total_size=$((actual_size*ndevs))
259 # show computed parameters
260 str=`printf 'ost %2d sz %8dK rsz %4d obj %4d thr %4d ' \
261 $ndevs $total_size $actual_rsz $total_nobj $total_thr`
262 echo "=======================> $str" >> $workf
263 print_summary -n "$str"
264 if ((total_thr * actual_rsz > max_buffer_mem)); then
265 print_summary "Too much buffer space"
270 for ((idx=0; idx < ndevs; idx++)); do
271 devno=${devnos[$idx]}
272 first_obj=`create_objects $devno $nobj $tmpf`
273 echo "========> Create [$idx]" >> $workf
276 if [ $first_obj = "ERROR" ]; then
277 print_summary "created object #s [$idx] not contiguous"
280 first_objs[$idx]=$first_obj
282 for test in write $tests; do
283 print_summary -n "$test "
285 for ((idx=0; idx < ndevs; idx++)); do
286 devno=${devnos[$idx]}
288 first_obj=${first_objs[$idx]}
289 $lctl > $tmpfi 2>&1 \
290 --threads $thr -$snap $devno \
291 test_brw $count `testname2type $test` q $pages ${thr}t${first_obj} &
295 str=`awk "BEGIN {printf \"%7.2f \",\
296 $total_size / (( $t1 - $t0 ) * 1024)}"`
297 print_summary -n "$str"
299 for ((idx=0; idx < ndevs; idx++)); do
301 echo "========> $test [$idx]" >> $workf
303 get_stats $tmpfi >> $tmpf
306 echo "========> $test [$idx] global" >> $workf
308 stats=(`get_global_stats $tmpf`)
310 if ((stats[0] <= 0)); then
311 if ((stats[0] < 0)); then
312 str=`printf "%15s " ERROR`
314 str=`printf "%15s " SHORT`
317 str=`awk "BEGIN {printf \"[%6.2f,%6.2f] \",\
318 (${stats[1]} * $actual_rsz)/1024,\
319 (${stats[2]} * $actual_rsz)/1024; exit}"`
321 print_summary -n "$str"
324 for ((idx=0; idx < ndevs; idx++)); do
325 devno=${devnos[$idx]}
326 first_obj=${first_objs[$idx]}
327 destroy_objects $devno $first_obj $nobj $tmpf
328 echo "========> Destroy [$idx]" >> $workf
336 for ((idx=0; idx < ndevs; idx++)); do
337 teardown_ec_devno $idx
340 if ((load_obdecho)); then