Whamcloud - gitweb
LU-676 tests: machinefile option for mpirun via a variable
[fs/lustre-release.git] / lustre / tests / functions.sh
1 #!/bin/bash
2 # -*- mode: Bash; tab-width: 4; indent-tabs-mode: t; -*-
3 # vim:shiftwidth=4:softtabstop=4:tabstop=4:
4
5 # Simple function used by run_*.sh scripts
6
7 assert_env() {
8     local failed=""
9     for name in $@; do
10         if [ -z "${!name}" ]; then
11             echo "$0: $name must be set"
12             failed=1
13         fi
14     done
15     [ $failed ] && exit 1 || true
16 }
17
18 # lrepl - Lustre test Read-Eval-Print Loop.
19 #
20 # This function implements a REPL for the Lustre test framework.  It
21 # doesn't exec an actual shell because the user may want to inspect
22 # variables and use functions from the test framework.
23 lrepl() {
24     local line
25     local rawline
26     local prompt
27
28     cat <<EOF
29         This is an interactive read-eval-print loop interactive shell
30         simulation that you can use to debug failing tests.  You can
31         enter most bash command lines (see notes below).
32
33         Use this REPL to inspect variables, set them, call test
34         framework shell functions, etcetera.
35
36         'exit' or EOF to exit this shell.
37
38         set \$retcode to 0 to cause the assertion failure that
39         triggered this REPL to be ignored.
40
41         Examples:
42             do_facet ost1 lctl get_param ost.*.ost.threads_*
43             do_rpc_nodes \$OSTNODES unload_modules
44
45         NOTES:
46             All but the last line of multi-line statements or blocks
47             must end in a backslash.
48
49             "Here documents" are not supported.
50
51             History is not supported, but command-line editing is.
52
53 EOF
54
55     # Prompt escapes don't work in read -p, sadly.
56     prompt=":test_${testnum:-UNKNOWN}:$(uname -n):$(basename $PWD)% "
57
58     # We use read -r to get close to a shell experience
59     while read -e -r -p "$prompt" rawline; do
60         line=
61         case "$rawline" in
62         # Don't want to exit-exit, just exit the REPL
63         exit) break;;
64         # We need to handle continuations, and read -r doesn't do
65         # that for us.  Yet we need read -r.
66         #
67         # We also use case/esac to compare lines read to "*\\"
68         # because [ "$line" = *\\ ] and variants of that don't work.
69         *\\) line="$rawline"
70             while read -e -r -p '> ' rawline
71             do
72                 line="$line"$'\n'"$rawline"
73                 case "$rawline" in
74                 # We could check for here documents by matching
75                 # against *<<*, but who cares.
76                 *\\) continue;;
77                 *) break;;
78                 esac
79             done
80             ;;
81         *) line=$rawline
82         esac
83
84         case "$line" in
85         *\\) break;;
86         esac
87
88         # Finally!  Time to eval.
89         eval "$line"
90     done
91
92     echo $'\n\tExiting interactive shell...\n'
93     return 0
94 }
95
96 # lassert - Lustre test framework assert
97 #
98 # Arguments: failure code, failure message, expression/statement
99 #
100 # lassert evaluates the expression given, and, if false, calls
101 # error() to trigger test failure.  If REPL_ON_LASSERT is true then
102 # lassert will call lrepl() to give the user an interactive shell.
103 # If the REPL sets retcode=0 then the assertion failure will be
104 # ignored.
105 lassert() {
106     local retcode=$1
107     local msg=$2
108     shift 2
109
110     echo "checking $* ($(eval echo \""$*"\"))..."
111     eval "$@" && return 0;
112
113     if ${REPL_ON_LASSERT:-false}; then
114         echo "Assertion $retcode failed: $* (expanded: $(eval echo \""$*"\"))
115 $msg"
116         lrepl
117     fi
118
119     error "Assertion $retcode failed: $* (expanded: $(eval echo \""$*"\"))
120 $msg"
121     return $retcode
122 }
123
124 # setmodopts- set module options for subsequent calls to load_modules
125 #
126 # Usage: setmodopts module_name new_value [var_in_which_to_save_old_value]
127 #        setmodopts -a module_name new_value [var_in_which_to_save_old_value]
128 #
129 # In the second usage the new value is appended to the old.
130 setmodopts() {
131         local _append=false
132
133         if [ "$1" = -a ]; then
134             _append=true
135             shift
136         fi
137
138         local _var=MODOPTS_$1
139         local _newvalue=$2
140         local _savevar=$3
141         local _oldvalue
142
143         # Dynamic naming of variables is a pain in bash.  In ksh93 we could
144         # write "nameref opts_var=${modname}_MODOPTS" then assign directly
145         # to opts_var.  Associative arrays would also help, alternatively.
146         # Alas, we're stuck with eval until all distros move to a more recent
147         # version of bash.  Fortunately we don't need to eval unset and export.
148
149         if [ -z "$_newvalue" ]; then
150             unset $_var
151             return 0
152         fi
153
154         _oldvalue=${!var}
155         $_append && _newvalue="$_oldvalue $_newvalue"
156         export $_var="$_newvalue"
157         echo setmodopts: ${_var}=${_newvalue}
158
159         [ -n "$_savevar" ] && eval $_savevar=\""$_oldvalue"\"
160 }
161
162 echoerr () { echo "$@" 1>&2 ; }
163
164 signaled() {
165     echoerr "$(date +'%F %H:%M:%S'): client load was signaled to terminate"
166
167     local PGID=$(ps -eo "%c %p %r" | awk "/ $PPID / {print \$3}")
168     kill -TERM -$PGID
169     sleep 5
170     kill -KILL -$PGID
171 }
172
173 mpi_run () {
174     local mpirun="$MPIRUN $MPIRUN_OPTIONS"
175     local command="$mpirun $@"
176     local mpilog=$TMP/mpi.log
177     local rc
178
179     if [ -n "$MPI_USER" -a "$MPI_USER" != root -a -n "$mpirun" ]; then
180         echo "+ chmod 0777 $MOUNT"
181         chmod 0777 $MOUNT
182         command="su $MPI_USER sh -c \"$command \""
183     fi
184
185     ls -ald $MOUNT
186     echo "+ $command"
187     eval $command 2>&1 | tee $mpilog || true
188
189     rc=${PIPESTATUS[0]}
190     if [ $rc -eq 0 ] && grep -q "p4_error:" $mpilog ; then
191        rc=1
192     fi
193     return $rc
194 }
195
196 nids_list () {
197    local list
198    for i in ${1//,/ }; do
199        list="$list $i@$NETTYPE"
200    done
201    echo $list
202 }
203
204 # FIXME: all setup/cleanup can be done without rpc.sh
205 lst_end_session () {
206     local verbose=false
207     [ x$1 = x--verbose ] && verbose=true
208
209     export LST_SESSION=`$LST show_session 2>/dev/null | awk -F " " '{print $5}'`
210     [ "$LST_SESSION" == "" ] && return
211
212     if $verbose; then
213         $LST show_error c s
214     fi
215     $LST stop b
216     $LST end_session
217 }
218
219 lst_session_cleanup_all () {
220     local list=$(comma_list $(nodes_list))
221     do_rpc_nodes $list lst_end_session
222 }
223
224 lst_cleanup () {
225     lsmod | grep -q lnet_selftest && \
226         rmmod lnet_selftest > /dev/null 2>&1 || true
227 }
228
229 lst_cleanup_all () {
230    local list=$(comma_list $(nodes_list))
231
232    # lst end_session needs to be executed only locally
233    # i.e. on node where lst new_session was called
234    lst_end_session --verbose
235    do_rpc_nodes $list lst_cleanup
236 }
237
238 lst_setup () {
239     load_module lnet_selftest
240 }
241
242 lst_setup_all () {
243     local list=$(comma_list $(nodes_list))
244     do_rpc_nodes $list lst_setup
245 }
246
247 ###
248 # short_hostname
249 #
250 # Passed a single argument, strips everything off following
251 # and includes the first period.
252 # client-20.lab.whamcloud.com becomes client-20
253 short_hostname() {
254   echo $(sed 's/\..*//' <<< $1)
255 }
256
257 print_opts () {
258     local var
259
260     echo OPTIONS:
261
262     for i in $@; do
263         var=$i
264         echo "${var}=${!var}"
265     done
266     [ -e $MACHINEFILE ] && cat $MACHINEFILE
267 }
268
269 run_compilebench() {
270
271 # Takes:
272 # 5 min * cbench_RUNS
273 #        SLOW=no     10 mins
274 #        SLOW=yes    50 mins
275 # Space estimation:
276 #        compile dir kernel-1 680MB
277 #        required space       680MB * cbench_IDIRS = ~7 Gb
278
279     cbench_DIR=${cbench_DIR:-""}
280     cbench_IDIRS=${cbench_IDIRS:-4}
281     cbench_RUNS=${cbench_RUNS:-4}
282
283     print_opts cbench_DIR cbench_IDIRS cbench_RUNS
284
285     [ x$cbench_DIR = x ] &&
286         { skip_env "compilebench not found" && return; }
287
288     [ -e $cbench_DIR/compilebench ] || \
289         { skip_env "No compilebench build" && return; }
290
291     local space=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
292     if [ $space -le $((680 * 1024 * cbench_IDIRS)) ]; then
293         cbench_IDIRS=$(( space / 680 / 1024))
294         [ $cbench_IDIRS = 0 ] && \
295             skip_env "Need free space atleast 680 Mb, have $space" && return
296
297         log free space=$space, reducing initial dirs to $cbench_IDIRS
298     fi
299     # FIXME:
300     # t-f _base needs to be modifyed to set properly tdir
301     # for new "test_foo" functions names
302     # local testdir=$DIR/$tdir
303     local testdir=$DIR/d0.compilebench
304     mkdir -p $testdir
305
306     local savePWD=$PWD
307     cd $cbench_DIR
308     local cmd="./compilebench -D $testdir -i $cbench_IDIRS \
309         -r $cbench_RUNS --makej"
310
311     log "$cmd"
312
313     local rc=0
314     eval $cmd
315     rc=$?
316
317     cd $savePWD
318     [ $rc = 0 ] || error "compilebench failed: $rc"
319     rm -rf $testdir
320 }
321
322 run_metabench() {
323
324     METABENCH=${METABENCH:-$(which metabench 2> /dev/null || true)}
325     mbench_NFILES=${mbench_NFILES:-30400}
326     # threads per client
327     mbench_THREADS=${mbench_THREADS:-4}
328
329     [ x$METABENCH = x ] &&
330         { skip_env "metabench not found" && return; }
331
332     # FIXME
333     # Need space estimation here.
334
335     print_opts METABENCH clients mbench_NFILES mbench_THREADS
336
337     local testdir=$DIR/d0.metabench
338     mkdir -p $testdir
339     # mpi_run uses mpiuser
340     chmod 0777 $testdir
341
342     # -C             Run the file creation tests.
343     # -S             Run the file stat tests.
344     # -c nfile       Number of files to be used in each test.
345     # -k             Cleanup.  Remove the test directories.
346     local cmd="$METABENCH -w $testdir -c $mbench_NFILES -C -S -k"
347     echo "+ $cmd"
348
349         # find out if we need to use srun by checking $SRUN_PARTITION
350         if [ "$SRUN_PARTITION" ]; then
351                 $SRUN $SRUN_OPTIONS -D $testdir -w $clients -N $num_clients \
352                         -n $((num_clients * mbench_THREADS)) \
353                         -p $SRUN_PARTITION -- $cmd
354         else
355                 mpi_run -np $((num_clients * $mbench_THREADS)) \
356                         ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
357         fi
358
359     local rc=$?
360     if [ $rc != 0 ] ; then
361         error "metabench failed! $rc"
362     fi
363     rm -rf $testdir
364 }
365
366 run_simul() {
367
368     SIMUL=${SIMUL:=$(which simul 2> /dev/null || true)}
369     # threads per client
370     simul_THREADS=${simul_THREADS:-2}
371     simul_REP=${simul_REP:-20}
372
373     if [ "$NFSCLIENT" ]; then
374         skip "skipped for NFSCLIENT mode"
375         return
376     fi
377
378     [ x$SIMUL = x ] &&
379         { skip_env "simul not found" && return; }
380
381     # FIXME
382     # Need space estimation here.
383
384     print_opts SIMUL clients simul_REP simul_THREADS
385
386     local testdir=$DIR/d0.simul
387     mkdir -p $testdir
388     # mpi_run uses mpiuser
389     chmod 0777 $testdir
390
391     # -n # : repeat each test # times
392     # -N # : repeat the entire set of tests # times
393
394     local cmd="$SIMUL -d $testdir -n $simul_REP -N $simul_REP"
395
396         echo "+ $cmd"
397         # find out if we need to use srun by checking $SRUN_PARTITION
398         if [ "$SRUN_PARTITION" ]; then
399                 $SRUN $SRUN_OPTIONS -D $testdir -w $clients -N $num_clients \
400                         -n $((num_clients * simul_THREADS)) -p $SRUN_PARTITION \
401                         -- $cmd
402         else
403                 mpi_run -np $((num_clients * simul_THREADS)) \
404                         ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
405         fi
406
407     local rc=$?
408     if [ $rc != 0 ] ; then
409         error "simul failed! $rc"
410     fi
411     rm -rf $testdir
412 }
413
414 run_mdtest() {
415
416     MDTEST=${MDTEST:=$(which mdtest 2> /dev/null || true)}
417     # threads per client
418     mdtest_THREADS=${mdtest_THREADS:-2}
419     mdtest_nFiles=${mdtest_nFiles:-"100000"}
420     # We devide the files by number of core
421     mdtest_nFiles=$((mdtest_nFiles/mdtest_THREADS/num_clients))
422     mdtest_iteration=${mdtest_iteration:-1}
423
424     local type=${1:-"ssf"}
425
426     if [ "$NFSCLIENT" ]; then
427         skip "skipped for NFSCLIENT mode"
428         return
429     fi
430
431     [ x$MDTEST = x ] &&
432         { skip_env "mdtest not found" && return; }
433
434     # FIXME
435     # Need space estimation here.
436
437     print_opts MDTEST mdtest_iteration mdtest_THREADS mdtest_nFiles
438
439     local testdir=$DIR/d0.mdtest
440     mkdir -p $testdir
441     # mpi_run uses mpiuser
442     chmod 0777 $testdir
443
444     # -i # : repeat each test # times
445     # -d   : test dir
446     # -n # : number of file/dir to create/stat/remove
447     # -u   : each process create/stat/remove individually
448
449     local cmd="$MDTEST -d $testdir -i $mdtest_iteration -n $mdtest_nFiles"
450     [ $type = "fpp" ] && cmd="$cmd -u"
451
452         echo "+ $cmd"
453         # find out if we need to use srun by checking $SRUN_PARTITION
454         if [ "$SRUN_PARTITION" ]; then
455                 $SRUN $SRUN_OPTIONS -D $testdir -w $clients -N $num_clients \
456                         -n $((num_clients * mdtest_THREADS)) \
457                         -p $SRUN_PARTITION -- $cmd
458         else
459                 mpi_run -np $((num_clients * mdtest_THREADS)) \
460                         ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
461         fi
462
463     local rc=$?
464     if [ $rc != 0 ] ; then
465         error "mdtest failed! $rc"
466     fi
467     rm -rf $testdir
468 }
469
470 run_connectathon() {
471
472     cnt_DIR=${cnt_DIR:-""}
473     cnt_NRUN=${cnt_NRUN:-10}
474
475     print_opts cnt_DIR cnt_NRUN
476
477     [ x$cnt_DIR = x ] &&
478         { skip_env "connectathon dir not found" && return; }
479
480     [ -e $cnt_DIR/runtests ] || \
481         { skip_env "No connectathon runtests found" && return; }
482
483     local testdir=$DIR/d0.connectathon
484     mkdir -p $testdir
485
486     local savePWD=$PWD
487     cd $cnt_DIR
488
489     #
490     # cthon options (must be in this order)
491     #
492     # -N numpasses - will be passed to the runtests script.  This argument
493     #         is optional.  It specifies the number of times to run
494     #         through the tests.
495     #
496     # One of these test types
497     #    -b  basic
498     #    -g  general
499     #    -s  special
500     #    -l  lock
501     #    -a  all of the above
502     #
503     # -f      a quick functionality test
504     #
505
506     tests="-b -g -s"
507     # Include lock tests unless we're running on nfsv4
508     local fstype=$(df -TP $testdir | awk 'NR==2  {print $2}')
509     echo "$testdir: $fstype"
510     if [[ $fstype != "nfs4" ]]; then
511         tests="$tests -l"
512     fi
513     echo "tests: $tests"
514     for test in $tests; do
515         local cmd="./runtests -N $cnt_NRUN $test -f $testdir"
516         local rc=0
517
518         log "$cmd"
519         eval $cmd
520         rc=$?
521         [ $rc = 0 ] || error "connectathon failed: $rc"
522     done
523
524     cd $savePWD
525     rm -rf $testdir
526 }
527
528 run_ior() {
529     local type=${1:="ssf"}
530
531     IOR=${IOR:-$(which IOR 2> /dev/null || true)}
532     # threads per client
533     ior_THREADS=${ior_THREADS:-2}
534     ior_iteration=${ior_iteration:-1}
535     ior_blockSize=${ior_blockSize:-6}   # GB
536     ior_xferSize=${ior_xferSize:-2m}
537     ior_type=${ior_type:-POSIX}
538     ior_DURATION=${ior_DURATION:-30}    # minutes
539
540     [ x$IOR = x ] &&
541         { skip_env "IOR not found" && return; }
542
543     local space=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
544     local total_threads=$(( num_clients * ior_THREADS ))
545     echo "+ $ior_blockSize * 1024 * 1024 * $total_threads "
546     if [ $((space / 2)) -le \
547         $(( ior_blockSize * 1024 * 1024 * total_threads)) ]; then
548         echo "+ $space * 9/10 / 1024 / 1024 / $num_clients / $ior_THREADS"
549         ior_blockSize=$(( space /2 /1024 /1024 / num_clients / ior_THREADS ))
550         [ $ior_blockSize = 0 ] && \
551             skip_env "Need free space more than $((2 * total_threads))GB: \
552                 $((total_threads *1024 *1024*2)), have $space" && return
553
554         local reduced_size="$num_clients x $ior_THREADS x $ior_blockSize"
555         echo "free space=$space, Need: $reduced_size GB"
556         echo "(blockSize reduced to $ior_blockSize Gb)"
557     fi
558
559     print_opts IOR ior_THREADS ior_DURATION MACHINEFILE
560
561     local testdir=$DIR/d0.ior.$type
562     mkdir -p $testdir
563     # mpi_run uses mpiuser
564     chmod 0777 $testdir
565     if [ "$NFSCLIENT" ]; then
566         setstripe_nfsserver $testdir -c -1 ||
567             { error "setstripe on nfsserver failed" && return 1; }
568     else
569         $LFS setstripe $testdir -c -1 ||
570             { error "setstripe failed" && return 2; }
571     fi
572     #
573     # -b N  blockSize --
574     #       contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)"
575     # -o S  testFileName
576     # -t N  transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)"
577     # -w    writeFile -- write file"
578     # -r    readFile -- read existing file"
579     # -T    maxTimeDuration -- max time in minutes to run tests"
580     # -k    keepFile -- keep testFile(s) on program exit
581
582     local cmd="$IOR -a $ior_type -b ${ior_blockSize}g -o $testdir/iorData \
583          -t $ior_xferSize -v -w -r -i $ior_iteration -T $ior_DURATION -k"
584     [ $type = "fpp" ] && cmd="$cmd -F"
585
586         echo "+ $cmd"
587         # find out if we need to use srun by checking $SRUN_PARTITION
588         if [ "$SRUN_PARTITION" ]; then
589                 $SRUN $SRUN_OPTIONS -D $testdir -w $clients -N $num_clients \
590                         -n $((num_clients * ior_THREADS)) -p $SRUN_PARTITION \
591                         -- $cmd
592         else
593                 mpi_run -np $((num_clients * $ior_THREADS)) \
594                         ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
595         fi
596
597     local rc=$?
598     if [ $rc != 0 ] ; then
599         error "ior failed! $rc"
600     fi
601     rm -rf $testdir
602 }
603
604 run_mib() {
605
606     MIB=${MIB:=$(which mib 2> /dev/null || true)}
607     # threads per client
608     mib_THREADS=${mib_THREADS:-2}
609     mib_xferSize=${mib_xferSize:-1m}
610     mib_xferLimit=${mib_xferLimit:-5000}
611     mib_timeLimit=${mib_timeLimit:-300}
612
613     if [ "$NFSCLIENT" ]; then
614         skip "skipped for NFSCLIENT mode"
615         return
616     fi
617
618     [ x$MIB = x ] &&
619         { skip_env "MIB not found" && return; }
620
621     print_opts MIB mib_THREADS mib_xferSize mib_xferLimit mib_timeLimit \
622         MACHINEFILE
623
624     local testdir=$DIR/d0.mib
625     mkdir -p $testdir
626     # mpi_run uses mpiuser
627     chmod 0777 $testdir
628     $LFS setstripe $testdir -c -1 ||
629         { error "setstripe failed" && return 2; }
630     #
631     # -I    Show intermediate values in output
632     # -H    Show headers in output
633     # -L    Do not issue new system calls after this many seconds
634     # -s    Use system calls of this size
635     # -t    test dir
636     # -l    Issue no more than this many system calls
637     local cmd="$MIB -t $testdir -s $mib_xferSize -l $mib_xferLimit \
638         -L $mib_timeLimit -HI -p mib.$(date +%Y%m%d%H%M%S)"
639
640         echo "+ $cmd"
641         # find out if we need to use srun by checking $SRUN_PARTITION
642         if [ "$SRUN_PARTITION" ]; then
643                 $SRUN $SRUN_OPTIONS -D $testdir -w $clients -N $num_clients \
644                         -n $((num_clients * mib_THREADS)) -p $SRUN_PARTITION \
645                         -- $cmd
646         else
647                 mpi_run -np $((num_clients * mib_THREADS)) \
648                         ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
649         fi
650
651     local rc=$?
652     if [ $rc != 0 ] ; then
653         error "mib failed! $rc"
654     fi
655     rm -rf $testdir
656 }
657
658 run_cascading_rw() {
659
660     CASC_RW=${CASC_RW:-$(which cascading_rw 2> /dev/null || true)}
661     # threads per client
662     casc_THREADS=${casc_THREADS:-2}
663     casc_REP=${casc_REP:-300}
664
665     if [ "$NFSCLIENT" ]; then
666         skip "skipped for NFSCLIENT mode"
667         return
668     fi
669
670     [ x$CASC_RW = x ] &&
671         { skip_env "cascading_rw not found" && return; }
672
673     # FIXME
674     # Need space estimation here.
675
676     print_opts CASC_RW clients casc_THREADS casc_REP MACHINEFILE
677
678     local testdir=$DIR/d0.cascading_rw
679     mkdir -p $testdir
680     # mpi_run uses mpiuser
681     chmod 0777 $testdir
682
683     # -g: debug mode
684     # -n: repeat test # times
685
686     local cmd="$CASC_RW -g -d $testdir -n $casc_REP"
687
688         echo "+ $cmd"
689         mpi_run -np $((num_clients * $casc_THREADS)) ${MACHINEFILE_OPTION} \
690                 ${MACHINEFILE} $cmd
691
692     local rc=$?
693     if [ $rc != 0 ] ; then
694         error "cascading_rw failed! $rc"
695     fi
696     rm -rf $testdir
697 }
698
699 run_write_append_truncate() {
700
701     # threads per client
702     write_THREADS=${write_THREADS:-8}
703     write_REP=${write_REP:-10000}
704
705     if [ "$NFSCLIENT" ]; then
706         skip "skipped for NFSCLIENT mode"
707         return
708     fi
709
710     # location is lustre/tests dir
711     if ! which write_append_truncate > /dev/null 2>&1 ; then
712         skip_env "write_append_truncate not found"
713         return
714     fi
715
716     # FIXME
717     # Need space estimation here.
718
719     local testdir=$DIR/d0.write_append_truncate
720     local file=$testdir/f0.wat
721
722     print_opts clients write_REP write_THREADS MACHINEFILE
723
724     mkdir -p $testdir
725     # mpi_run uses mpiuser
726     chmod 0777 $testdir
727
728     local cmd="write_append_truncate -n $write_REP $file"
729
730         echo "+ $cmd"
731         mpi_run -np $((num_clients * $write_THREADS)) ${MACHINEFILE_OPTION} \
732                 ${MACHINEFILE} $cmd
733
734     local rc=$?
735     if [ $rc != 0 ] ; then
736         error "write_append_truncate failed! $rc"
737         return $rc
738     fi
739     rm -rf $testdir
740 }
741
742 run_write_disjoint() {
743
744     WRITE_DISJOINT=${WRITE_DISJOINT:-$(which write_disjoint \
745         2> /dev/null || true)}
746     # threads per client
747     wdisjoint_THREADS=${wdisjoint_THREADS:-4}
748     wdisjoint_REP=${wdisjoint_REP:-10000}
749
750     if [ "$NFSCLIENT" ]; then
751         skip "skipped for NFSCLIENT mode"
752         return
753     fi
754
755     [ x$WRITE_DISJOINT = x ] &&
756         { skip_env "write_disjoint not found" && return; }
757
758     # FIXME
759     # Need space estimation here.
760
761     print_opts WRITE_DISJOINT clients wdisjoint_THREADS wdisjoint_REP \
762         MACHINEFILE
763     local testdir=$DIR/d0.write_disjoint
764     mkdir -p $testdir
765     # mpi_run uses mpiuser
766     chmod 0777 $testdir
767
768     local cmd="$WRITE_DISJOINT -f $testdir/file -n $wdisjoint_REP"
769
770         echo "+ $cmd"
771         mpi_run -np $((num_clients * $wdisjoint_THREADS)) \
772                 ${MACHINEFILE_OPTION} ${MACHINEFILE} $cmd
773
774     local rc=$?
775     if [ $rc != 0 ] ; then
776         error "write_disjoint failed! $rc"
777     fi
778     rm -rf $testdir
779 }
780
781 run_parallel_grouplock() {
782
783     PARALLEL_GROUPLOCK=${PARALLEL_GROUPLOCK:-$(which parallel_grouplock \
784         2> /dev/null || true)}
785     parallel_grouplock_MINTASKS=${parallel_grouplock_MINTASKS:-5}
786
787     if [ "$NFSCLIENT" ]; then
788         skip "skipped for NFSCLIENT mode"
789         return
790     fi
791
792     [ x$PARALLEL_GROUPLOCK = x ] &&
793         { skip "PARALLEL_GROUPLOCK not found" && return; }
794
795     print_opts clients parallel_grouplock_MINTASKS MACHINEFILE
796
797     local testdir=$DIR/d0.parallel_grouplock
798     mkdir -p $testdir
799     # mpi_run uses mpiuser
800     chmod 0777 $testdir
801
802     do_nodes $clients "lctl set_param llite.*.max_rw_chunk=0" ||
803         error "set_param max_rw_chunk=0 failed "
804
805     local cmd
806     local status=0
807     local subtest
808         for i in $(seq 12); do
809                 subtest="-t $i"
810                 local cmd="$PARALLEL_GROUPLOCK -g -v -d $testdir $subtest"
811                 echo "+ $cmd"
812
813                 mpi_run -np $parallel_grouplock_MINTASKS ${MACHINEFILE_OPTION} \
814                         ${MACHINEFILE} $cmd
815                 local rc=$?
816                 if [ $rc != 0 ] ; then
817                         error_noexit "parallel_grouplock subtests $subtest " \
818                                      "failed! $rc"
819                 else
820                         echo "parallel_grouplock subtests $subtest PASS"
821                 fi
822                 let status=$((status + rc))
823                 # clear debug to collect one log per one test
824                 do_nodes $(comma_list $(nodes_list)) lctl clear
825         done
826         [ $status -eq 0 ] || error "parallel_grouplock status: $status"
827         rm -rf $testdir
828 }
829
830 cleanup_statahead () {
831     trap 0
832
833     local clients=$1
834     local mntpt_root=$2
835     local num_mntpts=$3
836
837     for i in $(seq 0 $num_mntpts);do
838         zconf_umount_clients $clients ${mntpt_root}$i ||
839             error_exit "Failed to umount lustre on ${mntpt_root}$i"
840     done
841 }
842
843 run_statahead () {
844
845     statahead_NUMMNTPTS=${statahead_NUMMNTPTS:-5}
846     statahead_NUMFILES=${statahead_NUMFILES:-500000}
847
848     if [[ -n $NFSCLIENT ]]; then
849         skip "Statahead testing is not supported on NFS clients."
850         return 0
851     fi
852
853     [ x$MDSRATE = x ] &&
854         { skip_env "mdsrate not found" && return; }
855
856     print_opts MDSRATE clients statahead_NUMMNTPTS statahead_NUMFILES
857
858     # create large dir
859
860     # do not use default "d[0-9]*" dir name
861     # to avoid of rm $statahead_NUMFILES (500k) files in t-f cleanup
862     local dir=dstatahead
863     local testdir=$DIR/$dir
864
865     # cleanup only if dir exists
866     # cleanup only $statahead_NUMFILES number of files
867     # ignore the other files created by someone else
868     [ -d $testdir ] &&
869         mdsrate_cleanup $((num_clients * 32)) $MACHINEFILE \
870             $statahead_NUMFILES $testdir 'f%%d' --ignore
871
872     mkdir -p $testdir
873     # mpi_run uses mpiuser
874     chmod 0777 $testdir
875
876     local num_files=$statahead_NUMFILES
877
878     local IFree=$(inodes_available)
879     if [ $IFree -lt $num_files ]; then
880       num_files=$IFree
881     fi
882
883     cancel_lru_locks mdc
884
885     local cmd1="${MDSRATE} ${MDSRATE_DEBUG} --mknod --dir $testdir"
886     local cmd2="--nfiles $num_files --filefmt 'f%%d'"
887     local cmd="$cmd1 $cmd2"
888     echo "+ $cmd"
889
890         mpi_run -np $((num_clients * 32)) ${MACHINEFILE_OPTION} ${MACHINEFILE} \
891                 $cmd
892
893     local rc=$?
894     if [ $rc != 0 ] ; then
895         error "mdsrate failed to create $rc"
896         return $rc
897     fi
898
899     local num_mntpts=$statahead_NUMMNTPTS
900     local mntpt_root=$TMP/mntpt/lustre
901     local mntopts=${MNTOPTSTATAHEAD:-$MOUNTOPT}
902
903     echo "Mounting $num_mntpts lustre clients starts on $clients"
904     trap "cleanup_statahead $clients $mntpt_root $num_mntpts" EXIT ERR
905     for i in $(seq 0 $num_mntpts); do
906         zconf_mount_clients $clients ${mntpt_root}$i "$mntopts" ||
907             error_exit "Failed to mount lustre on ${mntpt_root}$i on $clients"
908     done
909
910     do_rpc_nodes $clients cancel_lru_locks mdc
911
912     do_rpc_nodes $clients do_ls $mntpt_root $num_mntpts $dir
913
914     mdsrate_cleanup $((num_clients * 32)) $MACHINEFILE \
915         $num_files $testdir 'f%%d' --ignore
916
917     # use rm instead of rmdir because of
918     # testdir could contain the files created by someone else,
919     # or by previous run where is num_files prev > num_files current
920     rm -rf $testdir
921     cleanup_statahead $clients $mntpt_root $num_mntpts
922 }