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