2 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
4 ######################################################################
7 # Prerequisite: For "stripe_count > 0" you need to have ost setup and mounted.
10 # case 1 (stripe_count=0 default):
11 # $ thrhi=8 dir_count=4 sh mds-survey
12 # one can also run test with user defined targets as follows,
13 # $ thrhi=8 dir_count=4 file_count=50000 targets="lustre-MDT0000" sh mds-survey
14 # case 2 (stripe_count > 0, must have ost mounted):
15 # $ thrhi=8 dir_count=4 file_count=50000 stripe_count=2
16 # targets="lustre-MDT0000" sh mds-survey
17 # [ NOTE: It is advised to have automated login (passwordless entry) on server ]
22 # Customisation variables
23 #####################################################################
24 # One can change variable values in this section as per requirements
25 # The following variables can be set in the environment, or on the
27 # result file prefix (date/time + hostname makes unique)
28 # NB ensure path to it exists
29 rslt_loc=${rslt_loc:-"/tmp"}
30 rslt=${rslt:-"$rslt_loc/mds_survey_`date +%F@%R`_`uname -n`"}
32 # min and max thread count
36 # number of directories to test
37 dir_count=${dir_count:-$thrlo}
38 # number of files per thread
39 file_count=${file_count:-100000}
41 targets=${targets:-""}
42 stripe_count=${stripe_count:-0}
43 # what tests to run (first must be create, and last must be destroy)
44 # default=(create lookup md_getattr setxattr destroy)
45 tests_str=${tests_str:-"create lookup md_getattr setxattr destroy"}
47 # start number for each thread
48 start_number=${start_number:-2}
52 # Customisation variables ends here.
53 #####################################################################
54 # leave the rest of this alone unless you know what you're doing...
59 create_directories () {
66 for ((idx = 0; idx < $ndir; idx++)); do
67 if (( idx == 0 )); then
70 dirname=${basedir}${idx}
72 remote_shell $host $lctl --device $devno test_mkdir /$dirname > $rfile 2>&1
74 echo "$line" | grep -q 'error: test_mkdir'
77 echo "ERROR: fail test_mkdir" >&2
86 destroy_directories () {
93 for ((idx = 0; idx < $ndir; idx++)); do
94 if (( idx == 0 )); then
97 dirname=${basedir}${idx}
99 remote_shell $host $lctl --device $devno test_rmdir /$dirname > $rfile 2>&1
106 '/start at/ { n=0; next } \
107 /error at/ {n = -1; exit} \
109 /^[0-9]+\/[0-9]+ Total: [0-9]+\.[0-9]+\/second$/ \
110 { n++; v=strtonum($3); \
111 if (n == 1 || v < min) min = v; \
112 if (n == 1 || v > max) max = v; \
115 { if (n != 0) {n = -1; exit } } \
116 END {printf "%d %f %f\n", n, min, max}'
119 get_global_stats () {
124 if (n == 1) { err = $1; min = $2; max = $3}\
126 { if ($1 < err) err = $1; \
127 if ($2 < min) min = $2; \
128 if ($3 > max) max = $3; \
131 END { if (n == 0) err = 0; \
132 printf "%d %f %f\n", err, min, max}'
136 if [ "$1" = "-n" ]; then
141 echo $minusn "$*" >> $rsltf
147 for name in $tests_str; do
152 # hide a little trick to unset this from the command line
153 if [ "$lustre_root" == " " ]; then
157 if [ -z "$lustre_root" ]; then
160 lctl=${lustre_root}/utils/lctl
163 declare -a client_names
164 declare -a host_names
165 if [ -z "$targets" ]; then
166 targets=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
167 \$3 == \"mdt\") {print \$4} }")
168 if [ -z "$targets" ]; then
169 echo "Can't find any MDT to test. Please set targets=..."
175 if (( $stripe_count > 0 )); then
176 obd=$($lctl device_list | awk "{if (\$2 == \"UP\" && \
177 \$3 == \"obdfilter\") {print \$4} }")
178 if [ -z "$obd" ]; then
179 echo "Need obdfilter to test stripe_count"
184 # split out hostnames from mdt names
186 for trgt in $targets; do
187 str=(`split_hostname $trgt`)
188 host_names[$ndevs]=${str[0]}
189 client_names[$ndevs]=${str[1]}
193 # check and insert obdecho module
194 if ! lsmod | grep obdecho > /dev/null; then
198 if [ $count -eq 0 -o "${tests[0]}" != "create" -o "${tests[(($count - 1))]}" != "destroy" ]; then
199 echo "tests: ${tests[@]}"
200 echo "First test must be 'create', and last test must be 'destroy'" 1>&2
204 rsltf="${rslt}.summary"
205 workf="${rslt}.detail"
206 cmdsf="${rslt}.script"
207 vmstatf="${rslt}.vmstat"
212 # disable portals debug and get obdecho loaded on all relevant hosts
213 unique_hosts=(`unique ${host_names[@]}`)
216 for host in ${unique_hosts[@]}; do
217 host_vmstatf=${vmstatf}_${host}
218 echo -n > $host_vmstatf
219 remote_shell $host "vmstat 5 >> $host_vmstatf" &> /dev/null &
221 vmstatpids[$pidcount]=$pid
222 pidcount=$((pidcount+1))
224 # get all the echo_client device numbers and names
225 for ((i=0; i < $ndevs; i++)); do
226 host=${host_names[$i]}
227 devno=(`get_ec_devno $host "${client_names[$i]}" "${client_names[$i]}" "mdt" $layer`)
228 if ((${#devno[@]} != 3)); then
231 devnos[$i]=${devno[0]}
232 client_names[$i]=${devno[1]}
233 do_teardown_ec[$i]=${devno[2]}
235 if (($ndevs <= 0 || ${#host_names[@]} <= 0)); then
236 echo "no devices or hosts specified"
239 print_summary "$(date) $0 from $(hostname)"
242 for ((idx = 0; idx < $ndevs; idx++)); do
243 host=${host_names[$idx]}
244 devno=${devnos[$idx]}
245 client_name="${host}:${client_names[$idx]}"
246 echo "=============> Create $dir_count directories on $client_name" >> $workf
247 destroy_directories $host $devno $dir_count $tmpf
248 ret=`create_directories $host $devno $dir_count $tmpf`
251 if [ $ret = "ERROR" ]; then
252 print_summary "created directories on $client_name failed"
258 for ((thr = $thrlo; thr <= $thrhi; thr*=2)); do
259 thr_per_dir=$((${thr}/${dir_count}))
260 # skip if no enough thread
261 if (( thr_per_dir <= 0 )); then
264 str=`printf 'mdt %1d file %7d dir %4d thr %4d ' \
265 $ndevs $file_count $dir_count $thr`
266 echo "=======================> $str" >> $workf
267 print_summary -n "$str"
269 for test in ${tests[@]}; do
271 for host in ${unique_hosts[@]}; do
272 echo "starting run for config: $config test: $test file: \
273 $file_count threads: $thr directories: $dir_count" >> ${vmstatf}_${host}
275 print_summary -n "$test "
276 # create per-host script files
277 for host in ${unique_hosts[@]}; do
278 echo -n > ${cmdsf}_${host}
280 for ((idx = 0; idx < $ndevs; idx++)); do
281 host=${host_names[$idx]}
282 devno=${devnos[$idx]}
284 [ $test = "create" ] && test="create -c $stripe_count"
285 echo >> ${cmdsf}_${host} \
286 "$lctl > $tmpfi 2>&1 \
287 --threads $thr -$snap $devno test_$test -d /$basedir -D $dir_count \
288 -b $start_number -n $file_count"
291 for host in ${unique_hosts[@]}; do
292 echo "wait" >> ${cmdsf}_${host}
293 pidarray[$pidcount]=0
294 pidcount=$((pidcount+1))
296 # timed run of all the per-host script files
299 for host in ${unique_hosts[@]}; do
300 remote_shell $host bash < ${cmdsf}_${host} &
301 pidarray[$pidcount]=$!
302 pidcount=$((pidcount+1))
305 for host in ${unique_hosts[@]}; do
306 wait ${pidarray[$pidcount]}
307 pidcount=$((pidcount+1))
311 # clean up per-host script files
312 for host in ${unique_hosts[@]}; do
316 # compute bandwidth from total data / elapsed time
317 str=`awk "BEGIN {printf \"%7.2f \", \
318 ( $file_count * $thr_per_dir ) / ( $t1 - $t0 )}"`
319 print_summary -n "$str"
320 # collect/check individual MDT stats
322 for ((idx = 0; idx < $ndevs; idx++)); do
323 client_name="${host_names[$idx]}:${client_names[$idx]}"
325 echo "=============> $test $client_name" >> $workf
326 host="${host_names[$idx]}"
327 remote_shell $host cat $tmpfi > ${tmpfi}_local
328 cat ${tmpfi}_local >> $workf
329 get_stats ${tmpfi}_local >> $tmpf
330 rm -f $tmpfi ${tmpfi}_local
332 # compute/display global min/max stats
333 echo "=============> $test global" >> $workf
335 stats=(`get_global_stats $tmpf`)
337 if ((stats[0] <= 0)); then
338 if ((stats[0] < 0)); then
339 str=`printf "%17s " ERROR`
341 str=`printf "%17s " SHORT`
344 str=`awk "BEGIN {printf \"[%7.2f,%7.2f] \", \
345 ${stats[1]}, ${stats[2]}; exit}"`
347 print_summary -n "$str"
351 # destroy directories
353 for ((idx = 0; idx < $ndevs; idx++)); do
354 host=${host_names[$idx]}
355 devno=${devnos[$idx]}
356 client_name="${host}:${client_names[$idx]}"
357 echo "=============> Destroy $dir_count directories on $client_name" >> $workf
358 destroy_directories $host $devno $dir_count $tmpf