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