Whamcloud - gitweb
Branch: b_new_cmd
[fs/lustre-release.git] / lustre / tests / test-framework.sh
1 #!/bin/bash
2 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
3
4 set -e
5 trap 'echo "test-framework exiting on error"' ERR
6 #set -x
7
8
9 export REFORMAT=""
10 export VERBOSE=${VERBOSE:-false}
11 export GMNALNID=${GMNALNID:-/usr/sbin/gmlndnid}
12 export CATASTROPHE=${CATASTROPHE:-/proc/sys/lnet/catastrophe}
13
14 # eg, assert_env LUSTRE MDSNODES OSTNODES CLIENTS
15 assert_env() {
16     local failed=""
17     for name in $@; do
18         if [ -z "${!name}" ]; then
19             echo "$0: $name must be set"
20             failed=1
21         fi
22     done
23     [ $failed ] && exit 1 || true
24 }
25
26 usage() {
27     echo "usage: $0 [-r] [-f cfgfile]"
28     echo "       -r: reformat"
29
30     exit
31 }
32
33 init_test_env() {
34     export LUSTRE=`absolute_path $LUSTRE`
35     export TESTSUITE=`basename $0 .sh`
36     export LTESTDIR=${LTESTDIR:-$LUSTRE/../ltest}
37
38     [ -d /r ] && export ROOT=${ROOT:-/r}
39     export TMP=${TMP:-$ROOT/tmp}
40
41     export PATH=:$PATH:$LUSTRE/utils:$LUSTRE/utils/gss:$LUSTRE/tests
42     export LCTL=${LCTL:-"$LUSTRE/utils/lctl"}
43     export MKFS=${MKFS:-"$LUSTRE/utils/mkfs.lustre"}
44     export CHECKSTAT="${CHECKSTAT:-checkstat} "
45     export FSYTPE=${FSTYPE:-"ldiskfs"}
46     export LPROC=/proc/fs/lustre
47     export LGSSD=${LGSSD:-"$LUSTRE/utils/gss/lgssd"}
48     export LSVCGSSD=${LSVCGSSD:-"$LUSTRE/utils/gss/lsvcgssd"}
49     export KRB5DIR=${KRB5DIR:-"/usr/kerberos"}
50
51     if [ "$ACCEPTOR_PORT" ]; then
52         export PORT_OPT="--port $ACCEPTOR_PORT"
53     fi
54
55     case "x$SEC" in
56         xkrb5*)
57             echo "Using GSS/krb5 ptlrpc security flavor"
58             export USING_KRB5="y"
59             ;;
60     esac
61
62     # Paths on remote nodes, if different 
63     export RLUSTRE=${RLUSTRE:-$LUSTRE}
64     export RPWD=${RPWD:-$PWD}
65
66     # command line
67     
68     while getopts "rvf:" opt $*; do 
69         case $opt in
70             f) CONFIG=$OPTARG;;
71             r) REFORMAT=--reformat;;
72             v) VERBOSE=true;;
73             \?) usage;;
74         esac
75     done
76
77     shift $((OPTIND - 1))
78     ONLY=${ONLY:-$*}
79 }
80
81 load_module() {
82     EXT=".ko"
83     module=$1
84     shift
85     BASE=`basename $module $EXT`
86     lsmod | grep -q ${BASE} || \
87       if [ -f ${LUSTRE}/${module}${EXT} ]; then
88         insmod ${LUSTRE}/${module}${EXT} $@
89     else
90         # must be testing a "make install" or "rpm" installation
91         # note failed to load ptlrpc_gss is considered not fatal
92         if [ "$BASE" == "ptlrpc_gss" ]; then
93             modprobe $BASE $@ || echo "gss/krb5 is not supported"
94         else
95             modprobe $BASE $@
96         fi
97     fi
98 }
99
100 load_modules() {
101     if [ -n "$MODPROBE" ]; then
102         # use modprobe
103         return 0
104     fi
105     if [ "$HAVE_MODULES" = true ]; then
106         # we already loaded
107         return 0
108     fi
109     HAVE_MODULES=true
110
111     echo Loading modules from $LUSTRE
112     load_module ../lnet/libcfs/libcfs
113     # note that insmod will ignore anything in modprobe.conf
114     load_module ../lnet/lnet/lnet $LNETOPTS
115     LNETLND=${LNETLND:-"socklnd/ksocklnd"}
116     load_module ../lnet/klnds/$LNETLND
117     load_module lvfs/lvfs
118     load_module obdclass/obdclass
119     load_module ptlrpc/ptlrpc
120     load_module ptlrpc/gss/ptlrpc_gss
121     load_module fid/fid
122     load_module fld/fld
123     load_module lmv/lmv
124     load_module quota/lquota
125     load_module mdc/mdc
126     load_module osc/osc
127     load_module lov/lov
128     load_module mds/mds
129     load_module mdd/mdd
130     load_module mdt/mdt
131     load_module cmm/cmm
132     load_module ldiskfs/ldiskfs
133     load_module lvfs/fsfilt_ldiskfs
134     load_module osd/osd
135     load_module ost/ost
136     load_module obdfilter/obdfilter
137     load_module llite/lustre
138     load_module mgc/mgc
139     load_module mgs/mgs
140     load_module quota/lquota
141     load_module obdecho/obdecho
142
143
144     rm -f $TMP/ogdb-`hostname`
145     $LCTL modules > $TMP/ogdb-`hostname`
146     # 'mount' doesn't look in $PATH, just sbin
147     [ -f $LUSTRE/utils/mount.lustre ] && cp $LUSTRE/utils/mount.lustre /sbin/. || true
148 }
149
150 wait_for_lnet() {
151     local UNLOADED=0
152     local WAIT=0
153     local MAX=60
154     MODULES=$($LCTL modules | awk '{ print $2 }')
155     while [ -n "$MODULES" ]; do
156         sleep 5
157         rmmod $MODULES >/dev/null 2>&1 || true
158         MODULES=$($LCTL modules | awk '{ print $2 }')
159         if [ -z "$MODULES" ]; then
160             return 0
161         else
162             WAIT=$((WAIT + 5))
163             echo "waiting, $((MAX - WAIT)) secs left"
164         fi
165         if [ $WAIT -eq $MAX ]; then
166             echo "LNET modules $MODULES will not unload"
167             lsmod
168             return 3
169         fi
170     done
171 }
172
173 unload_modules() {
174     lsmod | grep lnet > /dev/null && $LCTL dl && $LCTL dk $TMP/debug
175     local MODULES=$($LCTL modules | awk '{ print $2 }')
176     rmmod ldiskfs/quotafmt_test obdclass/llog_test quota/quotactl_test quota/quotacheck_test 2>&1 || true
177     rmmod $MODULES >/dev/null 2>&1 || true
178      # do it again, in case we tried to unload ksocklnd too early
179     MODULES=$($LCTL modules | awk '{ print $2 }')
180     [ -n "$MODULES" ] && rmmod $MODULES >/dev/null || true
181     MODULES=$($LCTL modules | awk '{ print $2 }')
182     if [ -n "$MODULES" ]; then
183         echo "Modules still loaded: "
184         echo $MODULES 
185         if [ -e $LPROC ]; then
186             echo "Lustre still loaded"
187             cat $LPROC/devices || true
188             lsmod
189             return 2
190         else
191             echo "Lustre stopped, but LNET is still loaded"
192             wait_for_lnet || return 3
193         fi
194     fi
195     HAVE_MODULES=false
196
197     LEAK_LUSTRE=$(dmesg | tail -n 30 | grep "obd mem.*leaked" || true)
198     LEAK_PORTALS=$(dmesg | tail -n 20 | grep "Portals memory leaked" || true)
199     if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
200         echo "$LEAK_LUSTRE" 1>&2
201         echo "$LEAK_PORTALS" 1>&2
202         mv $TMP/debug $TMP/debug-leak.`date +%s`
203         echo "Memory leaks detected"
204         return 254
205     fi
206     echo "modules unloaded."
207     return 0
208 }
209
210 check_gss_daemon_facet() {
211     facet=$1
212     dname=$2
213
214     num=`do_facet $facet ps -o cmd -C $dname | grep $dname | wc -l`
215     if [ $num -ne 1 ]; then
216         echo "$num instance of $dname on $facet"
217         return 1
218     fi
219     return 0
220 }
221
222 send_sigint() {
223     local facet=$1
224     shift
225     do_facet $facet "killall -2 $@ 2>/dev/null || true"
226 }
227
228 start_gss_daemons() {
229     # starting on MDT
230     for num in `seq $MDSCOUNT`; do
231         do_facet mds$num "$LSVCGSSD -v"
232         do_facet mds$num "$LGSSD -v"
233     done
234     # starting on OSTs
235     for num in `seq $OSTCOUNT`; do
236         do_facet ost$num "$LSVCGSSD -v"
237     done
238     # starting on client
239     # FIXME: is "client" the right facet name?
240     do_facet client "$LGSSD -v"
241
242     # wait daemons entering "stable" status
243     sleep 5
244
245     #
246     # check daemons are running
247     #
248     for num in `seq $MDSCOUNT`; do
249         check_gss_daemon_facet mds$num lsvcgssd
250         check_gss_daemon_facet mds$num lgssd
251     done
252     for num in `seq $OSTCOUNT`; do
253         check_gss_daemon_facet ost$num lsvcgssd
254     done
255     check_gss_daemon_facet client lgssd
256 }
257
258 stop_gss_daemons() {
259     for num in `seq $MDSCOUNT`; do
260         send_sigint mds$num lsvcgssd lgssd
261     done
262     for num in `seq $OSTCOUNT`; do
263         send_sigint ost$num lsvcgssd
264     done
265     send_sigint client lgssd
266 }
267
268 init_krb5_env() {
269     if [ ! -z $SEC ]; then
270         MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS,sec=$SEC
271         OST_MOUNT_OPTS=$OST_MOUNT_OPTS,sec=$SEC
272     fi
273
274     if [ ! -z $USING_KRB5 ]; then
275         start_gss_daemons
276     fi
277 }
278
279 cleanup_krb5_env() {
280     if [ ! -z $USING_KRB5 ]; then
281         stop_gss_daemons
282         # maybe cleanup credential cache?
283     fi
284 }
285
286 mdsdevlabel() {
287     local num=$1
288     local device=`mdsdevname $num`
289     local label=`do_facet mds$num "e2label ${device}" | grep -v "CMD: "`
290     echo -n $label
291 }
292
293 ostdevlabel() {
294     local num=$1
295     local device=`ostdevname $num`
296     local label=`do_facet ost$num "e2label ${device}" | grep -v "CMD: "`
297     echo -n $label
298 }
299
300 # Facet functions
301 # start facet device options 
302 start() {
303     facet=$1
304     shift
305     device=$1
306     shift
307     echo "Starting ${facet}: $@ ${device} ${MOUNT%/*}/${facet}"
308     do_facet ${facet} mkdir -p ${MOUNT%/*}/${facet}
309     do_facet ${facet} mount -t lustre $@ ${device} ${MOUNT%/*}/${facet} 
310     RC=${PIPESTATUS[0]}
311     if [ $RC -ne 0 ]; then
312         echo mount -t lustre $@ ${device} ${MOUNT%/*}/${facet} 
313         echo Start of ${device} on ${facet} failed ${RC}
314     else 
315         do_facet ${facet} sync
316         label=`do_facet ${facet} "e2label ${device}" | grep -v "CMD: "`
317         [ -z "$label" ] && echo no label for ${device} && exit 1
318         eval export ${facet}_svc=${label}
319         eval export ${facet}_dev=${device}
320         eval export ${facet}_opt=\"$@\"
321         echo Started ${label}
322     fi
323     return $RC
324 }
325
326 stop() {
327     local running
328     facet=$1
329     shift
330     HOST=`facet_active_host $facet`
331     [ -z $HOST ] && echo stop: no host for $facet && return 0
332
333     running=`do_facet ${facet} "grep -c ${MOUNT%/*}/${facet}' ' /proc/mounts" | grep -v "CMD: "`
334     if [ ${running} -ne 0 ]; then
335         echo "Stopping ${MOUNT%/*}/${facet} (opts:$@)"
336         do_facet ${facet} umount -d $@ ${MOUNT%/*}/${facet}
337     fi
338
339     [ -e /proc/fs/lustre ] && grep "ST " $LPROC/devices && echo "service didn't stop" && exit 1
340     return 0
341
342 }
343
344 zconf_mount() {
345     local OPTIONS
346     local client=$1
347     local mnt=$2
348     # Only supply -o to mount if we have options
349     if [ -n "$MOUNTOPT" ]; then
350         OPTIONS="-o $MOUNTOPT"
351     fi
352     local device=$MGSNID:/$FSNAME
353     if [ -z "$mnt" -o -z "$FSNAME" ]; then
354         echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
355         exit 1
356     fi
357
358     echo "Starting client: $OPTIONS $device $mnt" 
359     do_node $client mkdir -p $mnt
360     do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
361
362     do_node $client "sysctl -w lnet.debug=$PTLDEBUG; sysctl -w lnet.subsystem_debug=${SUBSYSTEM# }"
363     [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
364     return 0
365 }
366
367 zconf_umount() {
368     client=$1
369     mnt=$2
370     [ "$3" ] && force=-f
371     local running=`do_node $client "grep -c $mnt' ' /proc/mounts" | grep -v "CMD: "`
372     if [ $running -ne 0 ]; then
373         echo "Stopping client $mnt (opts:$force)"
374         do_node $client umount $force $mnt
375     fi
376 }
377
378 shutdown_facet() {
379     facet=$1
380     if [ "$FAILURE_MODE" = HARD ]; then
381         $POWER_DOWN `facet_active_host $facet`
382         sleep 2 
383     elif [ "$FAILURE_MODE" = SOFT ]; then
384         stop $facet
385     fi
386 }
387
388 reboot_facet() {
389     facet=$1
390     if [ "$FAILURE_MODE" = HARD ]; then
391         $POWER_UP `facet_active_host $facet`
392     else
393         sleep 10
394     fi
395 }
396
397 # verify that lustre actually cleaned up properly
398 cleanup_check() {
399     [ -e $CATASTROPHE -a "`cat $CATASTROPHE`" = "1" ] && echo "LBUG" && exit 206
400     BUSY=`dmesg | grep -i destruct || true`
401     if [ "$BUSY" ]; then
402         echo "$BUSY" 1>&2
403         [ -e $TMP/debug ] && mv $TMP/debug $TMP/debug-busy.`date +%s`
404         exit 205
405     fi
406     LEAK_LUSTRE=`dmesg | tail -n 30 | grep "obd mem.*leaked" || true`
407     LEAK_PORTALS=`dmesg | tail -n 20 | grep "Portals memory leaked" || true`
408     if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
409         echo "$0: $LEAK_LUSTRE" 1>&2
410         echo "$0: $LEAK_PORTALS" 1>&2
411         echo "$0: Memory leak(s) detected..." 1>&2
412         mv $TMP/debug $TMP/debug-leak.`date +%s`
413         exit 204
414     fi
415
416     [ "`lctl dl 2> /dev/null | wc -l`" -gt 0 ] && lctl dl && \
417         echo "$0: lustre didn't clean up..." 1>&2 && return 202 || true
418
419     if [ "`/sbin/lsmod 2>&1 | egrep 'lnet|libcfs'`" ]; then
420         echo "$0: modules still loaded..." 1>&2
421         /sbin/lsmod 1>&2
422         return 203
423     fi
424     return 0
425 }
426
427 wait_for_host() {
428     HOST=$1
429     check_network "$HOST" 900
430     while ! do_node $HOST "ls -d $LUSTRE " > /dev/null; do sleep 5; done
431 }
432
433 wait_for() {
434     facet=$1
435     HOST=`facet_active_host $facet`
436     wait_for_host $HOST
437 }
438
439 client_df() {
440     # not every config has many clients
441     if [ ! -z "$CLIENTS" ]; then
442         $PDSH $CLIENTS "df $MOUNT" > /dev/null
443     fi
444 }
445
446 client_reconnect() {
447     uname -n >> $MOUNT/recon
448     if [ ! -z "$CLIENTS" ]; then
449         $PDSH $CLIENTS "df $MOUNT; uname -n >> $MOUNT/recon" > /dev/null
450     fi
451     echo Connected clients:
452     cat $MOUNT/recon
453     ls -l $MOUNT/recon > /dev/null
454     rm $MOUNT/recon
455 }
456
457 facet_failover() {
458     facet=$1
459     echo "Failing $facet on node `facet_active_host $facet`"
460     shutdown_facet $facet
461     reboot_facet $facet
462     client_df &
463     DFPID=$!
464     echo "df pid is $DFPID"
465     change_active $facet
466     TO=`facet_active_host $facet`
467     echo "Failover $facet to $TO"
468     wait_for $facet
469     local dev=${facet}_dev
470     local opt=${facet}_opt
471     start $facet ${!dev} ${!opt}
472 }
473
474 obd_name() {
475     local facet=$1
476 }
477
478 replay_barrier() {
479     local facet=$1
480     do_facet $facet sync
481     df $MOUNT
482     local svc=${facet}_svc
483     do_facet $facet $LCTL --device %${!svc} readonly
484     do_facet $facet $LCTL --device %${!svc} notransno
485     do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
486     $LCTL mark "local REPLAY BARRIER on ${!svc}"
487 }
488
489 replay_barrier_nodf() {
490     local facet=$1    echo running=${running}
491     do_facet $facet sync
492     local svc=${facet}_svc
493     echo Replay barrier on ${!svc}
494     do_facet $facet $LCTL --device %${!svc} readonly
495     do_facet $facet $LCTL --device %${!svc} notransno
496     do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
497     $LCTL mark "local REPLAY BARRIER on ${!svc}"
498 }
499
500 mds_evict_client() {
501     UUID=`cat /proc/fs/lustre/mdc/${mds1_svc}-mdc-*/uuid`
502     do_facet mds1 "echo $UUID > /proc/fs/lustre/mdd/${mds1_svc}/evict_client"
503 }
504
505 ost_evict_client() {
506     UUID=`grep ${ost1_svc}-osc- $LPROC/devices | egrep -v 'MDT' | awk '{print $5}'`
507     do_facet ost1 "echo $UUID > /proc/fs/lustre/obdfilter/${ost1_svc}/evict_client"
508 }
509
510 fail() {
511     facet_failover $*
512     df $MOUNT || error "post-failover df: $?"
513 }
514
515 fail_abort() {
516     local facet=$1
517     stop $facet
518     change_active $facet
519     local svc=${facet}_svc
520     local dev=${facet}_dev
521     local opt=${facet}_opt
522     start $facet ${!dev} ${!opt}
523     do_facet $facet lctl --device %${!svc} abort_recovery
524     df $MOUNT || echo "first df failed: $?"
525     sleep 1
526     df $MOUNT || error "post-failover df: $?"
527 }
528
529 do_lmc() {
530     echo There is no lmc.  This is mountconf, baby.
531     exit 1
532 }
533
534 h2gm () {
535     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
536         ID=`$PDSH $1 $GMNALNID -l | cut -d\  -f2`
537         echo $ID"@gm"
538     fi
539 }
540
541 h2tcp() {
542     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
543         echo $1"@tcp" 
544     fi
545 }
546 declare -fx h2tcp
547
548 h2elan() {
549     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
550         if type __h2elan >/dev/null 2>&1; then
551             ID=$(__h2elan $1)
552         else
553             ID=`echo $1 | sed 's/[^0-9]*//g'`
554         fi
555         echo $ID"@elan"
556     fi
557 }
558 declare -fx h2elan
559
560 h2openib() {
561     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
562         ID=`echo $1 | sed 's/[^0-9]*//g'`
563         echo $ID"@openib"
564     fi
565 }
566 declare -fx h2openib
567
568 facet_host() {
569     local facet=$1
570     varname=${facet}_HOST
571     if [ -z "${!varname}" ]; then
572         if [ "${facet:0:3}" == "ost" ]; then
573             eval ${facet}_HOST=${ost_HOST}
574         fi
575     fi
576     echo -n ${!varname}
577 }
578
579 facet_active() {
580     local facet=$1
581     local activevar=${facet}active
582
583     if [ -f ./${facet}active ] ; then
584         source ./${facet}active
585     fi
586
587     active=${!activevar}
588     if [ -z "$active" ] ; then 
589         echo -n ${facet}
590     else
591         echo -n ${active}
592     fi
593 }
594
595 facet_active_host() {
596     local facet=$1
597     local active=`facet_active $facet`
598     if [ "$facet" == client ]; then
599         hostname
600     else
601         echo `facet_host $active`
602     fi
603 }
604
605 change_active() {
606     local facet=$1
607     failover=${facet}failover 
608     host=`facet_host $failover`
609     [ -z "$host" ] && return
610     curactive=`facet_active $facet`
611     if [ -z "${curactive}" -o "$curactive" == "$failover" ] ; then
612         eval export ${facet}active=$facet
613     else
614         eval export ${facet}active=$failover
615     fi
616     # save the active host for this facet
617     activevar=${facet}active
618     echo "$activevar=${!activevar}" > ./$activevar
619 }
620
621 do_node() {
622     HOST=$1
623     shift
624     local myPDSH=$PDSH
625     if [ "$HOST" = "$(hostname)" ]; then
626         myPDSH="no_dsh"
627     fi
628     if $VERBOSE; then
629         echo "CMD: $HOST $@"
630         $myPDSH $HOST $LCTL mark "$@" > /dev/null 2>&1 || :
631     fi
632     $myPDSH $HOST "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; sh -c \"$@\")"
633 }
634
635 do_facet() {
636     facet=$1
637     shift
638     HOST=`facet_active_host $facet`
639     [ -z $HOST ] && echo No host defined for facet ${facet} && exit 1
640     do_node $HOST $@
641 }
642
643 add() {
644     local facet=$1
645     shift
646     # make sure its not already running
647     stop ${facet} -f
648     rm -f ${facet}active
649     do_facet ${facet} $MKFS $*
650 }
651
652 ostdevname() {
653     num=$1
654     DEVNAME=OSTDEV$num
655     #if $OSTDEVn isn't defined, default is $OSTDEVBASE + num
656     eval DEVPTR=${!DEVNAME:=${OSTDEVBASE}${num}}
657     echo -n $DEVPTR
658 }
659
660 mdsdevname() {
661     num=$1
662     DEVNAME=MDSDEV$num
663     #if $MDSDEVn isn't defined, default is $MDSDEVBASE + num
664     eval DEVPTR=${!DEVNAME:=${MDSDEVBASE}${num}}
665     echo -n $DEVPTR
666 }
667
668 ########
669 ## MountConf setup
670
671 stopall() {
672     # make sure we are using the primary server, so test-framework will
673     # be able to clean up properly.
674     activemds=`facet_active mds1`
675     if [ $activemds != "mds1" ]; then
676         fail mds1
677     fi
678     
679     # assume client mount is local 
680     grep " $MOUNT " /proc/mounts && zconf_umount `hostname` $MOUNT $*
681     grep " $MOUNT2 " /proc/mounts && zconf_umount `hostname` $MOUNT2 $*
682     for num in `seq $MDSCOUNT`; do
683         stop mds$num -f
684     done
685     for num in `seq $OSTCOUNT`; do
686         stop ost$num -f
687     done
688     return 0
689 }
690
691 cleanupall() {
692     stopall $*
693     unload_modules
694     cleanup_krb5_env
695 }
696
697 mdsmkfsopts()
698 {
699     local nr=$1
700     test $nr = 1 && echo -n $MDS_MKFS_OPTS || echo -n $MDSn_MKFS_OPTS
701 }
702
703 formatall() {
704     stopall
705
706     # We need ldiskfs here, may as well load them all
707     load_modules
708     echo "Formatting mdts, osts"
709     for num in `seq $MDSCOUNT`; do
710         echo "Format mds$num: $(mdsdevname $num)"
711         if $VERBOSE; then
712             add mds$num `mdsmkfsopts $num` --reformat `mdsdevname $num` || exit 9
713         else
714             add mds$num `mdsmkfsopts $num` --reformat `mdsdevname $num` > /dev/null || exit 9
715         fi
716     done
717
718     for num in `seq $OSTCOUNT`; do
719         echo "Format ost$num: $(ostdevname $num)"
720         if $VERBOSE; then
721             add ost$num $OST_MKFS_OPTS --reformat `ostdevname $num` || exit 10
722         else
723             add ost$num $OST_MKFS_OPTS --reformat `ostdevname $num` > /dev/null || exit 10
724         fi
725     done
726 }
727
728 mount_client() {
729     grep " $1 " /proc/mounts || zconf_mount `hostname` $*
730 }
731
732 setupall() {
733     load_modules
734     init_krb5_env
735     echo "Setup mdts, osts"
736     for num in `seq $MDSCOUNT`; do
737         DEVNAME=`mdsdevname $num`
738         start mds$num $DEVNAME $MDS_MOUNT_OPTS
739     done
740     for num in `seq $OSTCOUNT`; do
741         DEVNAME=`ostdevname $num`
742         start ost$num $DEVNAME $OST_MOUNT_OPTS
743     done
744     [ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
745     mount_client $MOUNT
746     sleep 5
747 }
748
749
750 ####### 
751 # General functions
752
753 check_network() {
754     local NETWORK=0
755     local WAIT=0
756     local MAX=$2
757     while [ $NETWORK -eq 0 ]; do
758         ping -c 1 -w 3 $1 > /dev/null
759         if [ $? -eq 0 ]; then
760             NETWORK=1
761         else
762             WAIT=$((WAIT + 5))
763             echo "waiting for $1, $((MAX - WAIT)) secs left"
764             sleep 5
765         fi
766         if [ $WAIT -gt $MAX ]; then
767             echo "Network not available"
768             exit 1
769         fi
770     done
771 }
772 check_port() {
773     while( !($DSH2 $1 "netstat -tna | grep -q $2") ) ; do
774         sleep 9
775     done
776 }
777
778 no_dsh() {
779     shift
780     eval $@
781 }
782
783 comma_list() {
784     # the sed converts spaces to commas, but leaves the last space
785     # alone, so the line doesn't end with a comma.
786     echo "$*" | tr -s " " "\n" | sort -b -u | tr "\n" " " | sed 's/ \([^$]\)/,\1/g'
787 }
788
789 absolute_path() {
790     (cd `dirname $1`; echo $PWD/`basename $1`)
791 }
792
793 ##################################
794 # OBD_FAIL funcs
795
796 drop_request() {
797 # OBD_FAIL_MDS_ALL_REQUEST_NET
798     RC=0
799     do_facet mds sysctl -w lustre.fail_loc=0x123
800     do_facet client "$1" || RC=$?
801     do_facet mds sysctl -w lustre.fail_loc=0
802     return $RC
803 }
804
805 drop_reply() {
806 # OBD_FAIL_MDS_ALL_REPLY_NET
807     RC=0
808     do_facet mds sysctl -w lustre.fail_loc=0x122
809     do_facet client "$@" || RC=$?
810     do_facet mds sysctl -w lustre.fail_loc=0
811     return $RC
812 }
813
814 drop_reint_reply() {
815 # OBD_FAIL_MDS_REINT_NET_REP
816     RC=0
817     do_facet mds sysctl -w lustre.fail_loc=0x119
818     do_facet client "$@" || RC=$?
819     do_facet mds sysctl -w lustre.fail_loc=0
820     return $RC
821 }
822
823 pause_bulk() {
824 #define OBD_FAIL_OST_BRW_PAUSE_BULK      0x214
825     RC=0
826     do_facet ost1 sysctl -w lustre.fail_loc=0x214
827     do_facet client "$1" || RC=$?
828     do_facet client "sync"
829     do_facet ost1 sysctl -w lustre.fail_loc=0
830     return $RC
831 }
832
833 drop_ldlm_cancel() {
834 #define OBD_FAIL_LDLM_CANCEL             0x304
835     RC=0
836     do_facet client sysctl -w lustre.fail_loc=0x304
837     do_facet client "$@" || RC=$?
838     do_facet client sysctl -w lustre.fail_loc=0
839     return $RC
840 }
841
842 drop_bl_callback() {
843 #define OBD_FAIL_LDLM_BL_CALLBACK        0x305
844     RC=0
845     do_facet client sysctl -w lustre.fail_loc=0x305
846     do_facet client "$@" || RC=$?
847     do_facet client sysctl -w lustre.fail_loc=0
848     return $RC
849 }
850
851 clear_failloc() {
852     facet=$1
853     pause=$2
854     sleep $pause
855     echo "clearing fail_loc on $facet"
856     do_facet $facet "sysctl -w lustre.fail_loc=0"
857 }
858
859 cancel_lru_locks() {
860     $LCTL mark "cancel_lru_locks start"
861     for d in $LPROC/ldlm/namespaces/*-$1-*; do
862         if [ -f $d/lru_size ]; then
863             echo clear >> $d/lru_size
864         fi
865     done
866     grep "[0-9]" $LPROC/ldlm/namespaces/*-$1-*/lock_unused_count /dev/null
867     $LCTL mark "cancel_lru_locks stop"
868 }
869
870
871 pgcache_empty() {
872     for a in /proc/fs/lustre/llite/*/dump_page_cache; do
873         if [ `wc -l $a | awk '{print $1}'` -gt 1 ]; then
874             echo there is still data in page cache $a ?
875             cat $a;
876             return 1;
877         fi
878     done
879     return 0
880 }
881
882 ##################################
883 # Test interface 
884 error() {
885     sysctl -w lustre.fail_loc=0 2> /dev/null || true
886     echo "${TESTSUITE}: **** FAIL:" $@
887     log "FAIL: $@"
888     exit 1
889 }
890
891 build_test_filter() {
892     [ "$ONLY" ] && log "only running test `echo $ONLY`"
893     for O in $ONLY; do
894         eval ONLY_${O}=true
895     done
896     [ "$EXCEPT$ALWAYS_EXCEPT" ] && \
897         log "skipping tests: `echo $EXCEPT $ALWAYS_EXCEPT`"
898     for E in $EXCEPT $ALWAYS_EXCEPT; do
899         eval EXCEPT_${E}=true
900     done
901 }
902
903 _basetest() {
904     echo $*
905 }
906
907 basetest() {
908     IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
909 }
910
911 run_test() {
912     export base=`basetest $1`
913     if [ ! -z "$ONLY" ]; then
914         testname=ONLY_$1
915         if [ ${!testname}x != x ]; then
916             run_one $1 "$2"
917             return $?
918         fi
919         testname=ONLY_$base
920         if [ ${!testname}x != x ]; then
921             run_one $1 "$2"
922             return $?
923         fi
924         echo -n "."
925         return 0
926     fi
927     testname=EXCEPT_$1
928     if [ ${!testname}x != x ]; then
929         echo "skipping excluded test $1"
930         return 0
931     fi
932     testname=EXCEPT_$base
933     if [ ${!testname}x != x ]; then
934         echo "skipping excluded test $1 (base $base)"
935         return 0
936     fi
937     run_one $1 "$2"
938     
939     return $?
940 }
941
942 EQUALS="======================================================================"
943 equals_msg() {
944     msg="$@"
945
946     local suffixlen=$((${#EQUALS} - ${#msg}))
947     [ $suffixlen -lt 5 ] && suffixlen=5
948     printf '===== %s %.*s\n' "$msg" $suffixlen $EQUALS
949 }
950
951 log() {
952     echo "$*"
953     lsmod | grep lnet > /dev/null || load_modules
954     $LCTL mark "$*" 2> /dev/null || true
955 }
956
957 pass() {
958     echo PASS $@
959 }
960
961 check_mds() {
962     FFREE=`cat /proc/fs/lustre/mds/*/filesfree`
963     FTOTAL=`cat /proc/fs/lustre/mds/*/filestotal`
964     [ $FFREE -ge $FTOTAL ] && error "files free $FFREE > total $FTOTAL" || true
965 }
966
967 run_one() {
968     testnum=$1
969     message=$2
970     tfile=f${testnum}
971     tdir=d${base}
972
973     # Pretty tests run faster.
974     equals_msg $testnum: $message
975
976     BEFORE=`date +%s`
977     log "== test $testnum: $message ============ `date +%H:%M:%S` ($BEFORE)"
978     #check_mds
979     test_${testnum} || error "test_$testnum failed with $?"
980     #check_mds
981     [ -f $CATASTROPHE ] && [ `cat $CATASTROPHE` -ne 0 ] && \
982         error "LBUG/LASSERT detected"
983     pass "($((`date +%s` - $BEFORE))s)"
984 }
985
986 canonical_path() {
987     (cd `dirname $1`; echo $PWD/`basename $1`)
988 }
989