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