Whamcloud - gitweb
b=14657
[fs/lustre-release.git] / lustre / tests / test-framework.sh
1 #!/bin/bash
2 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
3
4 trap 'print_summary && echo "test-framework exiting on error"' ERR
5 set -e
6 #set -x
7
8
9 export REFORMAT=${REFORMAT:-""}
10 export VERBOSE=false
11 export GMNALNID=${GMNALNID:-/usr/sbin/gmlndnid}
12 export CATASTROPHE=${CATASTROPHE:-/proc/sys/lnet/catastrophe}
13 export GSS=false
14 export GSS_KRB5=false
15 export GSS_PIPEFS=false
16 #export PDSH="pdsh -S -Rssh -w"
17
18 # eg, assert_env LUSTRE MDSNODES OSTNODES CLIENTS
19 assert_env() {
20     local failed=""
21     for name in $@; do
22         if [ -z "${!name}" ]; then
23             echo "$0: $name must be set"
24             failed=1
25         fi
26     done
27     [ $failed ] && exit 1 || true
28 }
29
30 usage() {
31     echo "usage: $0 [-r] [-f cfgfile]"
32     echo "       -r: reformat"
33
34     exit
35 }
36
37 print_summary () {
38     [ "$TESTSUITE" == "lfscktest" ] && return 0
39     [ -n "$ONLY" ] && echo "WARNING: ONLY is set to ${ONLY}."
40     local form="%-13s %-17s %s\n"
41     printf "$form" "status" "script" "skipped tests E(xcluded) S(low)"
42     echo "------------------------------------------------------------------------------------"
43     for O in $TESTSUITE_LIST; do
44         local skipped=""
45         local slow=""
46         local o=$(echo $O | tr "[:upper:]" "[:lower:]")
47         o=${o//_/-}
48         o=${o//tyn/tyN}
49         local log=${TMP}/${o}.log 
50         [ -f $log ] && skipped=$(grep excluded $log | awk '{ printf " %s", $3 }' | sed 's/test_//g')
51         [ -f $log ] && slow=$(grep SLOW $log | awk '{ printf " %s", $3 }' | sed 's/test_//g')
52         [ "${!O}" = "done" ] && \
53             printf "$form" "Done" "$O" "E=$skipped" && \
54             [ -n "$slow" ] && printf "$form" "-" "-" "S=$slow"
55
56     done
57
58     for O in $TESTSUITE_LIST; do
59         [ "${!O}" = "no" ] && \
60             printf "$form" "Skipped" "$O" ""
61     done
62
63     for O in $TESTSUITE_LIST; do
64         [ "${!O}" = "done" -o "${!O}" = "no" ] || \
65             printf "$form" "UNFINISHED" "$O" ""
66     done
67 }
68
69 init_test_env() {
70     export LUSTRE=`absolute_path $LUSTRE`
71     export TESTSUITE=`basename $0 .sh`
72     export LTESTDIR=${LTESTDIR:-$LUSTRE/../ltest}
73
74     [ -d /r ] && export ROOT=${ROOT:-/r}
75     export TMP=${TMP:-$ROOT/tmp}
76     export TESTSUITELOG=${TMP}/${TESTSUITE}.log
77
78     export PATH=:$PATH:$LUSTRE/utils:$LUSTRE/utils/gss:$LUSTRE/tests
79     export LCTL=${LCTL:-"$LUSTRE/utils/lctl"}
80     export LFS=${LFS:-"$LUSTRE/utils/lfs"}
81     [ ! -f "$LCTL" ] && export LCTL=$(which lctl) 
82     export LFS=${LFS:-"$LUSTRE/utils/lfs"}
83     [ ! -f "$LFS" ] && export LFS=$(which lfs) 
84     export MKFS=${MKFS:-"$LUSTRE/utils/mkfs.lustre"}
85     [ ! -f "$MKFS" ] && export MKFS=$(which mkfs.lustre) 
86     export TUNEFS=${TUNEFS:-"$LUSTRE/utils/tunefs.lustre"}
87     [ ! -f "$TUNEFS" ] && export TUNEFS=$(which tunefs.lustre) 
88     export CHECKSTAT="${CHECKSTAT:-"checkstat -v"} "
89     export FSYTPE=${FSTYPE:-"ldiskfs"}
90     export NAME=${NAME:-local}
91     export LPROC=/proc/fs/lustre
92     export LGSSD=${LGSSD:-"$LUSTRE/utils/gss/lgssd"}
93     export LSVCGSSD=${LSVCGSSD:-"$LUSTRE/utils/gss/lsvcgssd"}
94     export KRB5DIR=${KRB5DIR:-"/usr/kerberos"}
95     export DIR2
96
97     if [ "$ACCEPTOR_PORT" ]; then
98         export PORT_OPT="--port $ACCEPTOR_PORT"
99     fi
100
101     case "x$SEC" in
102         xkrb5*)
103             echo "Using GSS/krb5 ptlrpc security flavor"
104             GSS=true
105             GSS_KRB5=true
106             ;;
107     esac
108
109     # Paths on remote nodes, if different 
110     export RLUSTRE=${RLUSTRE:-$LUSTRE}
111     export RPWD=${RPWD:-$PWD}
112     export I_MOUNTED=${I_MOUNTED:-"no"}
113
114     # command line
115     
116     while getopts "rvf:" opt $*; do 
117         case $opt in
118             f) CONFIG=$OPTARG;;
119             r) REFORMAT=--reformat;;
120             v) VERBOSE=true;;
121             \?) usage;;
122         esac
123     done
124
125     shift $((OPTIND - 1))
126     ONLY=${ONLY:-$*}
127
128     [ "$TESTSUITELOG" ] && rm -f $TESTSUITELOG || true
129
130 }
131
132 load_module() {
133     EXT=".ko"
134     module=$1
135     shift
136     BASE=`basename $module $EXT`
137     lsmod | grep -q ${BASE} || \
138       if [ -f ${LUSTRE}/${module}${EXT} ]; then
139         insmod ${LUSTRE}/${module}${EXT} $@
140     else
141         # must be testing a "make install" or "rpm" installation
142         # note failed to load ptlrpc_gss is considered not fatal
143         if [ "$BASE" == "ptlrpc_gss" ]; then
144             modprobe $BASE $@ 2>/dev/null || echo "gss/krb5 is not supported"
145         else
146             modprobe $BASE $@
147         fi
148     fi
149 }
150
151 load_modules() {
152     if [ -n "$MODPROBE" ]; then
153         # use modprobe
154     return 0
155     fi
156     if [ "$HAVE_MODULES" = true ]; then
157     # we already loaded
158         return 0
159     fi
160     HAVE_MODULES=true
161
162     echo Loading modules from $LUSTRE
163     load_module ../lnet/libcfs/libcfs
164     [ -f /etc/modprobe.conf ] && MODPROBECONF=/etc/modprobe.conf
165     [ -f /etc/modprobe.d/Lustre ] && MODPROBECONF=/etc/modprobe.d/Lustre
166     [ -z "$LNETOPTS" -a -n "$MODPROBECONF" ] && \
167         LNETOPTS=$(awk '/^options lnet/ { print $0}' $MODPROBECONF | sed 's/^options lnet //g')
168     echo "lnet options: '$LNETOPTS'"
169     # note that insmod will ignore anything in modprobe.conf
170     load_module ../lnet/lnet/lnet $LNETOPTS
171     LNETLND=${LNETLND:-"socklnd/ksocklnd"}
172     load_module ../lnet/klnds/$LNETLND
173     load_module lvfs/lvfs
174     load_module obdclass/obdclass
175     load_module ptlrpc/ptlrpc
176     load_module ptlrpc/gss/ptlrpc_gss
177     # Now, some modules depend on lquota without USE_QUOTA check,
178     # will fix later. Disable check "$USE_QUOTA" = "yes" temporary.
179     #[ "$USE_QUOTA" = "yes" ] && load_module quota/lquota
180     load_module quota/lquota
181     load_module fid/fid
182     load_module fld/fld
183     load_module lmv/lmv
184     load_module mdc/mdc
185     load_module osc/osc
186     load_module lov/lov
187     load_module mgc/mgc
188     if [ -z "$CLIENTONLY" ]; then
189         [ "$FSTYPE" = "ldiskfs" ] && load_module ../ldiskfs/ldiskfs/ldiskfs
190         load_module mgs/mgs
191         load_module mds/mds
192         load_module mdd/mdd
193         load_module mdt/mdt
194         load_module lvfs/fsfilt_$FSTYPE
195         load_module cmm/cmm
196         load_module osd/osd
197         load_module ost/ost
198         load_module obdfilter/obdfilter
199     fi
200
201     load_module llite/lustre
202     load_module llite/llite_lloop
203     rm -f $TMP/ogdb-`hostname`
204     $LCTL modules > $TMP/ogdb-`hostname`
205     # 'mount' doesn't look in $PATH, just sbin
206     [ -f $LUSTRE/utils/mount.lustre ] && cp $LUSTRE/utils/mount.lustre /sbin/. || true
207 }
208
209 RMMOD=rmmod
210 if [ `uname -r | cut -c 3` -eq 4 ]; then
211     RMMOD="modprobe -r"
212 fi
213
214 wait_for_lnet() {
215     local UNLOADED=0
216     local WAIT=0
217     local MAX=60
218     MODULES=$($LCTL modules | awk '{ print $2 }')
219     while [ -n "$MODULES" ]; do
220     sleep 5
221     $RMMOD $MODULES > /dev/null 2>&1 || true
222     MODULES=$($LCTL modules | awk '{ print $2 }')
223         if [ -z "$MODULES" ]; then
224         return 0
225         else
226             WAIT=$((WAIT + 5))
227             echo "waiting, $((MAX - WAIT)) secs left"
228         fi
229         if [ $WAIT -eq $MAX ]; then
230             echo "LNET modules $MODULES will not unload"
231         lsmod
232             return 3
233         fi
234     done
235 }
236
237 unload_modules() {
238     wait_exit_ST client # bug 12845
239
240     lsmod | grep lnet > /dev/null && $LCTL dl && $LCTL dk $TMP/debug
241     local MODULES=$($LCTL modules | awk '{ print $2 }')
242     $RMMOD $MODULES > /dev/null 2>&1 || true
243      # do it again, in case we tried to unload ksocklnd too early
244     MODULES=$($LCTL modules | awk '{ print $2 }')
245     [ -n "$MODULES" ] && $RMMOD $MODULES > /dev/null 2>&1 || true
246     MODULES=$($LCTL modules | awk '{ print $2 }')
247     if [ -n "$MODULES" ]; then
248     echo "Modules still loaded: "
249     echo $MODULES 
250     if [ -e $LPROC ]; then
251         echo "Lustre still loaded"
252         cat $LPROC/devices || true
253         lsmod
254         return 2
255     else
256         echo "Lustre stopped but LNET is still loaded, waiting..."
257         wait_for_lnet || return 3
258     fi
259     fi
260     HAVE_MODULES=false
261
262     LEAK_LUSTRE=$(dmesg | tail -n 30 | grep "obd mem.*leaked" || true)
263     LEAK_PORTALS=$(dmesg | tail -n 20 | grep "Portals memory leaked" || true)
264     if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
265         echo "$LEAK_LUSTRE" 1>&2
266         echo "$LEAK_PORTALS" 1>&2
267         mv $TMP/debug $TMP/debug-leak.`date +%s` || true
268         echo "Memory leaks detected"
269         [ -n "$IGNORE_LEAK" ] && echo "ignoring leaks" && return 0
270         return 254
271     fi
272     echo "modules unloaded."
273     return 0
274 }
275
276 check_gss_daemon_facet() {
277     facet=$1
278     dname=$2
279
280     num=`do_facet $facet ps -o cmd -C $dname | grep $dname | wc -l`
281     if [ $num -ne 1 ]; then
282         echo "$num instance of $dname on $facet"
283         return 1
284     fi
285     return 0
286 }
287
288 send_sigint() {
289     local facet=$1
290     shift
291     do_facet $facet "killall -2 $@ 2>/dev/null || true"
292 }
293
294 start_gss_daemons() {
295     # starting on MDT
296     for num in `seq $MDSCOUNT`; do
297         do_facet mds$num "$LSVCGSSD -v"
298         if $GSS_PIPEFS; then
299             do_facet mds$num "$LGSSD -v"
300         fi
301     done
302     # starting on OSTs
303     for num in `seq $OSTCOUNT`; do
304         do_facet ost$num "$LSVCGSSD -v"
305     done
306     # starting on client
307     # FIXME: is "client" the right facet name?
308     if $GSS_PIPEFS; then
309         do_facet client "$LGSSD -v"
310     fi
311
312     # wait daemons entering "stable" status
313     sleep 5
314
315     #
316     # check daemons are running
317     #
318     for num in `seq $MDSCOUNT`; do
319         check_gss_daemon_facet mds$num lsvcgssd
320         if $GSS_PIPEFS; then
321             check_gss_daemon_facet mds$num lgssd
322         fi
323     done
324     for num in `seq $OSTCOUNT`; do
325         check_gss_daemon_facet ost$num lsvcgssd
326     done
327     if $GSS_PIPEFS; then
328         check_gss_daemon_facet client lgssd
329     fi
330 }
331
332 stop_gss_daemons() {
333     for num in `seq $MDSCOUNT`; do
334         send_sigint mds$num lsvcgssd lgssd
335     done
336     for num in `seq $OSTCOUNT`; do
337         send_sigint ost$num lsvcgssd
338     done
339     send_sigint client lgssd
340 }
341
342 init_krb5_env() {
343     if [ ! -z $SEC ]; then
344         MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS,sec=$SEC
345         OST_MOUNT_OPTS=$OST_MOUNT_OPTS,sec=$SEC
346     fi
347
348     if $GSS; then
349         start_gss_daemons
350     fi
351 }
352
353 cleanup_krb5_env() {
354     if $GSS; then
355         stop_gss_daemons
356         # maybe cleanup credential cache?
357     fi
358 }
359
360 mdsdevlabel() {
361     local num=$1
362     local device=`mdsdevname $num`
363     local label=`do_facet mds$num "e2label ${device}" | grep -v "CMD: "`
364     echo -n $label
365 }
366
367 ostdevlabel() {
368     local num=$1
369     local device=`ostdevname $num`
370     local label=`do_facet ost$num "e2label ${device}" | grep -v "CMD: "`
371     echo -n $label
372 }
373
374 # Facet functions
375 # start facet device options 
376 start() {
377     facet=$1
378     shift
379     device=$1
380     shift
381     echo "Starting ${facet}: $@ ${device} ${MOUNT%/*}/${facet}"
382     do_facet ${facet} mkdir -p ${MOUNT%/*}/${facet}
383     do_facet ${facet} mount -t lustre $@ ${device} ${MOUNT%/*}/${facet} 
384     RC=${PIPESTATUS[0]}
385     if [ $RC -ne 0 ]; then
386         echo mount -t lustre $@ ${device} ${MOUNT%/*}/${facet} 
387         echo Start of ${device} on ${facet} failed ${RC}
388     else 
389         do_facet ${facet} "sysctl -w lnet.debug=$PTLDEBUG; \
390         sysctl -w lnet.subsystem_debug=${SUBSYSTEM# }; \
391         sysctl -w lnet.debug_mb=${DEBUG_SIZE}"
392
393         do_facet ${facet} sync
394         label=$(do_facet ${facet} "e2label ${device}")
395         [ -z "$label" ] && echo no label for ${device} && exit 1
396         eval export ${facet}_svc=${label}
397         eval export ${facet}_dev=${device}
398         eval export ${facet}_opt=\"$@\"
399         echo Started ${label}
400     fi
401     return $RC
402 }
403
404 stop() {
405     local running
406     facet=$1
407     shift
408     HOST=`facet_active_host $facet`
409     [ -z $HOST ] && echo stop: no host for $facet && return 0
410
411     running=$(do_facet ${facet} "grep -c ${MOUNT%/*}/${facet}' ' /proc/mounts") || true
412     if [ ${running} -ne 0 ]; then
413         echo "Stopping ${MOUNT%/*}/${facet} (opts:$@)"
414         do_facet ${facet} umount -d $@ ${MOUNT%/*}/${facet}
415     fi
416
417     # umount should block, but we should wait for unrelated obd's
418     # like the MGS or MGC to also stop.
419     wait_exit_ST ${facet}
420 }
421
422 zconf_mount() {
423     local OPTIONS
424     local client=$1
425     local mnt=$2
426     # Only supply -o to mount if we have options
427     if [ -n "$MOUNTOPT" ]; then
428         OPTIONS="-o $MOUNTOPT"
429     fi
430     local device=$MGSNID:/$FSNAME
431     if [ -z "$mnt" -o -z "$FSNAME" ]; then
432         echo Bad zconf mount command: opt=$OPTIONS dev=$device mnt=$mnt
433         exit 1
434     fi
435
436     echo "Starting client: $OPTIONS $device $mnt" 
437     do_node $client mkdir -p $mnt
438     do_node $client mount -t lustre $OPTIONS $device $mnt || return 1
439
440     do_node $client "sysctl -w lnet.debug=$PTLDEBUG;
441         sysctl -w lnet.subsystem_debug=${SUBSYSTEM# };
442         sysctl -w lnet.debug_mb=${DEBUG_SIZE}"
443     [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
444     return 0
445 }
446
447 zconf_umount() {
448     client=$1
449     mnt=$2
450     [ "$3" ] && force=-f
451     local running=$(do_node $client "grep -c $mnt' ' /proc/mounts") || true
452     if [ $running -ne 0 ]; then
453         echo "Stopping client $mnt (opts:$force)"
454         do_node $client umount $force $mnt
455     fi
456 }
457
458 shutdown_facet() {
459     facet=$1
460     if [ "$FAILURE_MODE" = HARD ]; then
461         $POWER_DOWN `facet_active_host $facet`
462         sleep 2 
463     elif [ "$FAILURE_MODE" = SOFT ]; then
464         stop $facet
465     fi
466 }
467
468 reboot_facet() {
469     facet=$1
470     if [ "$FAILURE_MODE" = HARD ]; then
471         $POWER_UP `facet_active_host $facet`
472     else
473         sleep 10
474     fi
475 }
476
477 # verify that lustre actually cleaned up properly
478 cleanup_check() {
479     [ -f $CATASTROPHE ] && [ `cat $CATASTROPHE` -ne 0 ] && \
480         error "LBUG/LASSERT detected"
481     BUSY=`dmesg | grep -i destruct || true`
482     if [ "$BUSY" ]; then
483         echo "$BUSY" 1>&2
484         [ -e $TMP/debug ] && mv $TMP/debug $TMP/debug-busy.`date +%s`
485         exit 205
486     fi
487     LEAK_LUSTRE=`dmesg | tail -n 30 | grep "obd mem.*leaked" || true`
488     LEAK_PORTALS=`dmesg | tail -n 20 | grep "Portals memory leaked" || true`
489     if [ "$LEAK_LUSTRE" -o "$LEAK_PORTALS" ]; then
490         echo "$0: $LEAK_LUSTRE" 1>&2
491         echo "$0: $LEAK_PORTALS" 1>&2
492         echo "$0: Memory leak(s) detected..." 1>&2
493         mv $TMP/debug $TMP/debug-leak.`date +%s`
494         exit 204
495     fi
496
497     [ "`lctl dl 2> /dev/null | wc -l`" -gt 0 ] && lctl dl && \
498         echo "$0: lustre didn't clean up..." 1>&2 && return 202 || true
499
500     if [ "`/sbin/lsmod 2>&1 | egrep 'lnet|libcfs'`" ]; then
501         echo "$0: modules still loaded..." 1>&2
502         /sbin/lsmod 1>&2
503         return 203
504     fi
505     return 0
506 }
507
508 wait_delete_completed () {
509     local TOTALPREV=`awk 'BEGIN{total=0}; {total+=$1}; END{print total}' \
510             $LPROC/osc/*/kbytesavail`
511
512     local WAIT=0
513     local MAX_WAIT=20
514     while [ "$WAIT" -ne "$MAX_WAIT" ]; do
515         sleep 1
516         TOTAL=`awk 'BEGIN{total=0}; {total+=$1}; END{print total}' \
517             $LPROC/osc/*/kbytesavail`
518         [ "$TOTAL" -eq "$TOTALPREV" ] && break
519         echo "Waiting delete completed ... prev: $TOTALPREV current: $TOTAL "
520         TOTALPREV=$TOTAL
521         WAIT=$(( WAIT + 1))
522     done
523     echo "Delete completed."
524 }
525
526 wait_for_host() {
527     HOST=$1
528     check_network "$HOST" 900
529     while ! do_node $HOST "ls -d $LUSTRE " > /dev/null; do sleep 5; done
530 }
531
532 wait_for() {
533     facet=$1
534     HOST=`facet_active_host $facet`
535     wait_for_host $HOST
536 }
537
538 wait_mds_recovery_done () {
539     local timeout=`do_facet mds cat /proc/sys/lustre/timeout`
540 #define OBD_RECOVERY_TIMEOUT (obd_timeout * 5 / 2)
541 # as we are in process of changing obd_timeout in different ways
542 # let's set MAX longer than that
543     MAX=$(( timeout * 4 ))
544     WAIT=0
545     while [ $WAIT -lt $MAX ]; do
546         STATUS=`do_facet mds grep status /proc/fs/lustre/mdt/*-MDT*/recovery_status`
547         echo $STATUS | grep COMPLETE && return 0
548         sleep 5
549         WAIT=$((WAIT + 5))
550         echo "Waiting $(($MAX - $WAIT)) secs for MDS recovery done"
551     done
552     echo "MDS recovery not done in $MAX sec"
553     return 1            
554 }
555
556 wait_exit_ST () {
557     local facet=$1
558
559     local WAIT=0
560     local INTERVAL=1
561     # conf-sanity 31 takes a long time cleanup
562     while [ $WAIT -lt 300 ]; do
563         running=$(do_facet ${facet} "[ -e $LPROC ] && grep ST' ' $LPROC/devices") || true
564         [ -z "${running}" ] && return 0
565         echo "waited $WAIT for${running}"
566         [ $INTERVAL -lt 64 ] && INTERVAL=$((INTERVAL + INTERVAL))
567         sleep $INTERVAL
568         WAIT=$((WAIT + INTERVAL))
569     done
570     echo "service didn't stop after $WAIT seconds.  Still running:"
571     echo ${running}
572     return 1
573 }
574
575 client_df() {
576     # not every config has many clients
577     if [ ! -z "$CLIENTS" ]; then
578         $PDSH $CLIENTS "df $MOUNT" > /dev/null
579     fi
580 }
581
582 client_reconnect() {
583     uname -n >> $MOUNT/recon
584     if [ ! -z "$CLIENTS" ]; then
585         $PDSH $CLIENTS "df $MOUNT; uname -n >> $MOUNT/recon" > /dev/null
586     fi
587     echo Connected clients:
588     cat $MOUNT/recon
589     ls -l $MOUNT/recon > /dev/null
590     rm $MOUNT/recon
591 }
592
593 facet_failover() {
594     facet=$1
595     echo "Failing $facet on node `facet_active_host $facet`"
596     shutdown_facet $facet
597     reboot_facet $facet
598     client_df &
599     DFPID=$!
600     echo "df pid is $DFPID"
601     change_active $facet
602     TO=`facet_active_host $facet`
603     echo "Failover $facet to $TO"
604     wait_for $facet
605     local dev=${facet}_dev
606     local opt=${facet}_opt
607     start $facet ${!dev} ${!opt} || error "Restart of $facet failed"
608 }
609
610 obd_name() {
611     local facet=$1
612 }
613
614 replay_barrier() {
615     local facet=$1
616     do_facet $facet sync
617     df $MOUNT
618     local svc=${facet}_svc
619     do_facet $facet $LCTL --device %${!svc} readonly
620     do_facet $facet $LCTL --device %${!svc} notransno
621     do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
622     $LCTL mark "local REPLAY BARRIER on ${!svc}"
623 }
624
625 replay_barrier_nodf() {
626     local facet=$1    echo running=${running}
627     do_facet $facet sync
628     local svc=${facet}_svc
629     echo Replay barrier on ${!svc}
630     do_facet $facet $LCTL --device %${!svc} readonly
631     do_facet $facet $LCTL --device %${!svc} notransno
632     do_facet $facet $LCTL mark "$facet REPLAY BARRIER on ${!svc}"
633     $LCTL mark "local REPLAY BARRIER on ${!svc}"
634 }
635
636 mds_evict_client() {
637     UUID=`cat /proc/fs/lustre/mdc/${mds1_svc}-mdc-*/uuid`
638     do_facet mds1 "echo $UUID > /proc/fs/lustre/mdt/${mds1_svc}/evict_client"
639 }
640
641 ost_evict_client() {
642     UUID=`grep ${ost1_svc}-osc- $LPROC/devices | egrep -v 'MDT' | awk '{print $5}'`
643     do_facet ost1 "echo $UUID > /proc/fs/lustre/obdfilter/${ost1_svc}/evict_client"
644 }
645
646 fail() {
647     facet_failover $* || error "failover: $?"
648     df $MOUNT || error "post-failover df: $?"
649 }
650
651 fail_abort() {
652     local facet=$1
653     stop $facet
654     change_active $facet
655     local svc=${facet}_svc
656     local dev=${facet}_dev
657     local opt=${facet}_opt
658     start $facet ${!dev} ${!opt}
659     do_facet $facet lctl --device %${!svc} abort_recovery
660     df $MOUNT || echo "first df failed: $?"
661     sleep 1
662     df $MOUNT || error "post-failover df: $?"
663 }
664
665 do_lmc() {
666     echo There is no lmc.  This is mountconf, baby.
667     exit 1
668 }
669
670 h2gm () {
671     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
672         ID=`$PDSH $1 $GMNALNID -l | cut -d\  -f2`
673         echo $ID"@gm"
674     fi
675 }
676
677 h2name_or_ip() {
678     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
679         echo $1"@$2" 
680     fi
681 }
682
683 h2ptl() {
684    if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
685        ID=`xtprocadmin -n $1 2>/dev/null | egrep -v 'NID' | awk '{print $1}'`
686        if [ -z "$ID" ]; then
687            echo "Could not get a ptl id for $1..."
688            exit 1
689        fi
690        echo $ID"@ptl"
691    fi
692 }
693 declare -fx h2ptl
694
695 h2tcp() {
696     h2name_or_ip "$1" "tcp"
697 }
698 declare -fx h2tcp
699
700 h2elan() {
701     if [ "$1" = "client" -o "$1" = "'*'" ]; then echo \'*\'; else
702         if type __h2elan >/dev/null 2>&1; then
703             ID=$(__h2elan $1)
704         else
705             ID=`echo $1 | sed 's/[^0-9]*//g'`
706         fi
707         echo $ID"@elan"
708     fi
709 }
710 declare -fx h2elan
711
712 h2openib() {
713     h2name_or_ip "$1" "openib"
714 }
715 declare -fx h2openib
716
717 h2o2ib() {
718     h2name_or_ip "$1" "o2ib"
719 }
720 declare -fx h2o2ib
721
722 facet_host() {
723     local facet=$1
724     varname=${facet}_HOST
725     if [ -z "${!varname}" ]; then
726         if [ "${facet:0:3}" == "ost" ]; then
727             eval ${facet}_HOST=${ost_HOST}
728         fi
729     fi
730     echo -n ${!varname}
731 }
732
733 facet_active() {
734     local facet=$1
735     local activevar=${facet}active
736
737     if [ -f ./${facet}active ] ; then
738         source ./${facet}active
739     fi
740
741     active=${!activevar}
742     if [ -z "$active" ] ; then 
743         echo -n ${facet}
744     else
745         echo -n ${active}
746     fi
747 }
748
749 facet_active_host() {
750     local facet=$1
751     local active=`facet_active $facet`
752     if [ "$facet" == client ]; then
753         hostname
754     else
755         echo `facet_host $active`
756     fi
757 }
758
759 change_active() {
760     local facet=$1
761     failover=${facet}failover 
762     host=`facet_host $failover`
763     [ -z "$host" ] && return
764     curactive=`facet_active $facet`
765     if [ -z "${curactive}" -o "$curactive" == "$failover" ] ; then
766         eval export ${facet}active=$facet
767     else
768         eval export ${facet}active=$failover
769     fi
770     # save the active host for this facet
771     activevar=${facet}active
772     echo "$activevar=${!activevar}" > ./$activevar
773 }
774
775 do_node() {
776     HOST=$1
777     shift
778     local myPDSH=$PDSH
779     if [ "$HOST" = "$(hostname)" ]; then
780         myPDSH="no_dsh"
781     fi
782     if $VERBOSE; then
783         echo "CMD: $HOST $@" >&2
784         $myPDSH $HOST $LCTL mark "$@" > /dev/null 2>&1 || :
785     fi
786     $myPDSH $HOST "(PATH=\$PATH:$RLUSTRE/utils:$RLUSTRE/tests:/sbin:/usr/sbin; cd $RPWD; sh -c \"$@\")" | sed "s/^${HOST}: //"
787     return ${PIPESTATUS[0]}
788 }
789
790 do_facet() {
791     facet=$1
792     shift
793     HOST=`facet_active_host $facet`
794     [ -z $HOST ] && echo No host defined for facet ${facet} && exit 1
795     do_node $HOST $@
796 }
797
798 add() {
799     local facet=$1
800     shift
801     # make sure its not already running
802     stop ${facet} -f
803     rm -f ${facet}active
804     do_facet ${facet} $MKFS $*
805 }
806
807 ostdevname() {
808     num=$1
809     DEVNAME=OSTDEV$num
810     #if $OSTDEVn isn't defined, default is $OSTDEVBASE + num
811     eval DEVPTR=${!DEVNAME:=${OSTDEVBASE}${num}}
812     echo -n $DEVPTR
813 }
814
815 mdsdevname() {
816     num=$1
817     DEVNAME=MDSDEV$num
818     #if $MDSDEVn isn't defined, default is $MDSDEVBASE + num
819     eval DEVPTR=${!DEVNAME:=${MDSDEVBASE}${num}}
820     echo -n $DEVPTR
821 }
822
823 ########
824 ## MountConf setup
825
826 stopall() {
827     # make sure we are using the primary server, so test-framework will
828     # be able to clean up properly.
829     activemds=`facet_active mds1`
830     if [ $activemds != "mds1" ]; then
831         fail mds1
832     fi
833     
834     # assume client mount is local 
835     grep " $MOUNT " /proc/mounts && zconf_umount `hostname` $MOUNT $*
836     grep " $MOUNT2 " /proc/mounts && zconf_umount `hostname` $MOUNT2 $*
837     [ "$CLIENTONLY" ] && return
838     for num in `seq $MDSCOUNT`; do
839         stop mds$num -f
840     done
841     for num in `seq $OSTCOUNT`; do
842         stop ost$num -f
843     done
844     return 0
845 }
846
847 cleanupall() {
848     stopall $*
849     unload_modules
850     cleanup_krb5_env
851 }
852
853 mdsmkfsopts()
854 {
855     local nr=$1
856     test $nr = 1 && echo -n $MDS_MKFS_OPTS || echo -n $MDSn_MKFS_OPTS
857 }
858
859 formatall() {
860     [ "$FSTYPE" ] && FSTYPE_OPT="--backfstype $FSTYPE"
861
862     stopall
863     # We need ldiskfs here, may as well load them all
864     load_modules
865     [ "$CLIENTONLY" ] && return
866     echo "Formatting mdts, osts"
867     for num in `seq $MDSCOUNT`; do
868         echo "Format mds$num: $(mdsdevname $num)"
869         if $VERBOSE; then
870             add mds$num `mdsmkfsopts $num` $FSTYPE_OPT --reformat `mdsdevname $num` || exit 9
871         else
872             add mds$num `mdsmkfsopts $num` $FSTYPE_OPT --reformat `mdsdevname $num` > /dev/null || exit 9
873         fi
874     done
875
876     for num in `seq $OSTCOUNT`; do
877         echo "Format ost$num: $(ostdevname $num)"
878         if $VERBOSE; then
879             add ost$num $OST_MKFS_OPTS --reformat `ostdevname $num` || exit 10
880         else
881             add ost$num $OST_MKFS_OPTS --reformat `ostdevname $num` > /dev/null || exit 10
882         fi
883     done
884 }
885
886 mount_client() {
887     grep " $1 " /proc/mounts || zconf_mount `hostname` $*
888 }
889
890 setupall() {
891     load_modules
892     init_krb5_env
893     if [ -z "$CLIENTONLY" ]; then
894         echo "Setup mdts, osts"
895         for num in `seq $MDSCOUNT`; do
896             DEVNAME=$(mdsdevname $num)
897             echo $REFORMAT | grep -q "reformat" \
898             || do_facet mds$num "$TUNEFS --writeconf $DEVNAME"
899             start mds$num $DEVNAME $MDS_MOUNT_OPTS
900         done
901         for num in `seq $OSTCOUNT`; do
902             DEVNAME=$(ostdevname $num)
903             start ost$num $DEVNAME $OST_MOUNT_OPTS
904         done
905     fi
906     [ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
907     mount_client $MOUNT
908     if [ "$MOUNT_2" ]; then
909         mount_client $MOUNT2
910     fi
911     sleep 5
912 }
913
914 mounted_lustre_filesystems() {
915         awk '($3 ~ "lustre" && $1 ~ ":") { print $2 }' /proc/mounts
916 }
917
918 check_and_setup_lustre() {
919     MOUNTED="`mounted_lustre_filesystems`"
920     if [ -z "$MOUNTED" ]; then
921         [ "$REFORMAT" ] && formatall
922         setupall
923         MOUNTED="`mounted_lustre_filesystems`"
924         [ -z "$MOUNTED" ] && error "NAME=$NAME not mounted"
925         export I_MOUNTED=yes
926     fi
927     if [ "$ONLY" == "setup" ]; then
928         exit 0
929     fi
930 }
931
932 cleanup_and_setup_lustre() {
933     if [ "$ONLY" == "cleanup" -o "`mount | grep $MOUNT`" ]; then
934         sysctl -w lnet.debug=0 || true
935         cleanupall
936         if [ "$ONLY" == "cleanup" ]; then 
937             exit 0
938         fi
939     fi
940     check_and_setup_lustre
941 }
942
943 check_and_cleanup_lustre() {
944     if [ "`mount | grep $MOUNT`" ]; then
945         rm -rf $DIR/[Rdfs][0-9]*
946         rm -f $DIR/${TESTSUITE}/[Rdfs][1-9]*
947     fi
948     if [ "$I_MOUNTED" = "yes" ]; then
949         cleanupall -f || error "cleanup failed"
950     fi
951     unset I_MOUNTED
952 }
953
954 ####### 
955 # General functions
956
957 check_network() {
958     local NETWORK=0
959     local WAIT=0
960     local MAX=$2
961     while [ $NETWORK -eq 0 ]; do
962         ping -c 1 -w 3 $1 > /dev/null
963         if [ $? -eq 0 ]; then
964             NETWORK=1
965         else
966             WAIT=$((WAIT + 5))
967             echo "waiting for $1, $((MAX - WAIT)) secs left"
968             sleep 5
969         fi
970         if [ $WAIT -gt $MAX ]; then
971             echo "Network not available"
972             exit 1
973         fi
974     done
975 }
976 check_port() {
977     while( !($DSH2 $1 "netstat -tna | grep -q $2") ) ; do
978         sleep 9
979     done
980 }
981
982 no_dsh() {
983     shift
984     eval $@
985 }
986
987 comma_list() {
988     # the sed converts spaces to commas, but leaves the last space
989     # alone, so the line doesn't end with a comma.
990     echo "$*" | tr -s " " "\n" | sort -b -u | tr "\n" " " | sed 's/ \([^$]\)/,\1/g'
991 }
992
993 absolute_path() {
994     (cd `dirname $1`; echo $PWD/`basename $1`)
995 }
996
997 ##################################
998 # OBD_FAIL funcs
999
1000 drop_request() {
1001 # OBD_FAIL_MDS_ALL_REQUEST_NET
1002     RC=0
1003     do_facet mds sysctl -w lustre.fail_loc=0x123
1004     do_facet client "$1" || RC=$?
1005     do_facet mds sysctl -w lustre.fail_loc=0
1006     return $RC
1007 }
1008
1009 drop_reply() {
1010 # OBD_FAIL_MDS_ALL_REPLY_NET
1011     RC=0
1012     do_facet mds sysctl -w lustre.fail_loc=0x122
1013     do_facet client "$@" || RC=$?
1014     do_facet mds sysctl -w lustre.fail_loc=0
1015     return $RC
1016 }
1017
1018 drop_reint_reply() {
1019 # OBD_FAIL_MDS_REINT_NET_REP
1020     RC=0
1021     do_facet mds sysctl -w lustre.fail_loc=0x119
1022     do_facet client "$@" || RC=$?
1023     do_facet mds sysctl -w lustre.fail_loc=0
1024     return $RC
1025 }
1026
1027 pause_bulk() {
1028 #define OBD_FAIL_OST_BRW_PAUSE_BULK      0x214
1029     RC=0
1030     do_facet ost1 sysctl -w lustre.fail_loc=0x214
1031     do_facet client "$1" || RC=$?
1032     do_facet client "sync"
1033     do_facet ost1 sysctl -w lustre.fail_loc=0
1034     return $RC
1035 }
1036
1037 drop_ldlm_cancel() {
1038 #define OBD_FAIL_LDLM_CANCEL             0x304
1039     RC=0
1040     do_facet client sysctl -w lustre.fail_loc=0x304
1041     do_facet client "$@" || RC=$?
1042     do_facet client sysctl -w lustre.fail_loc=0
1043     return $RC
1044 }
1045
1046 drop_bl_callback() {
1047 #define OBD_FAIL_LDLM_BL_CALLBACK        0x305
1048     RC=0
1049     do_facet client sysctl -w lustre.fail_loc=0x305
1050     do_facet client "$@" || RC=$?
1051     do_facet client sysctl -w lustre.fail_loc=0
1052     return $RC
1053 }
1054
1055 drop_ldlm_reply() {
1056 #define OBD_FAIL_LDLM_REPLY              0x30c
1057     RC=0
1058     do_facet mds sysctl -w lustre.fail_loc=0x30c
1059     do_facet client "$@" || RC=$?
1060     do_facet mds sysctl -w lustre.fail_loc=0
1061     return $RC
1062 }
1063
1064 clear_failloc() {
1065     facet=$1
1066     pause=$2
1067     sleep $pause
1068     echo "clearing fail_loc on $facet"
1069     do_facet $facet "sysctl -w lustre.fail_loc=0"
1070 }
1071
1072 cancel_lru_locks() {
1073     $LCTL mark "cancel_lru_locks $1 start"
1074     for d in `find $LPROC/ldlm/namespaces | egrep -i $1`; do
1075         [ -f $d/lru_size ] && echo clear > $d/lru_size
1076         [ -f $d/lock_unused_count ] && grep [1-9] $d/lock_unused_count /dev/null
1077     done
1078     $LCTL mark "cancel_lru_locks $1 stop"
1079 }
1080
1081
1082 pgcache_empty() {
1083     for a in /proc/fs/lustre/llite/*/dump_page_cache; do
1084         if [ `wc -l $a | awk '{print $1}'` -gt 1 ]; then
1085             echo there is still data in page cache $a ?
1086             cat $a;
1087             return 1;
1088         fi
1089     done
1090     return 0
1091 }
1092
1093 debugsave() {
1094     DEBUGSAVE="$(sysctl -n lnet.debug)"
1095 }
1096
1097 debugrestore() {
1098     [ -n "$DEBUGSAVE" ] && sysctl -w lnet.debug="${DEBUGSAVE}"
1099     DEBUGSAVE=""
1100 }
1101
1102 ##################################
1103 # Test interface 
1104 ##################################
1105
1106 error() {
1107     local FAIL_ON_ERROR=${FAIL_ON_ERROR:-true}
1108     local TYPE=${TYPE:-"FAIL"}
1109     local ERRLOG
1110     sysctl -w lustre.fail_loc=0 2> /dev/null || true
1111     log " ${TESTSUITE} ${TESTNAME}: @@@@@@ ${TYPE}: $@ "
1112     ERRLOG=$TMP/lustre_${TESTSUITE}_${TESTNAME}.$(date +%s)
1113     echo "Dumping lctl log to $ERRLOG"
1114     # We need to dump the logs on all nodes
1115     local NODES=$(nodes_list)
1116     for NODE in $NODES; do
1117         do_node $NODE $LCTL dk $ERRLOG
1118     done
1119     debugrestore
1120     [ "$TESTSUITELOG" ] && echo "$0: ${TYPE}: $TESTNAME $@" >> $TESTSUITELOG
1121     if $FAIL_ON_ERROR; then
1122         exit 1
1123     fi
1124 }
1125
1126 # use only if we are ignoring failures for this test, bugno required.
1127 # (like ALWAYS_EXCEPT, but run the test and ignore the results.)
1128 # e.g. error_ignore 5494 "your message"
1129 error_ignore() {
1130     FAIL_ON_ERROR=false TYPE="IGNORE (bz$1)" error $2
1131 }
1132
1133 skip () {
1134         log " SKIP: ${TESTSUITE} ${TESTNAME} $@"
1135         [ "$TESTSUITELOG" ] && echo "${TESTSUITE}: SKIP: $TESTNAME $@" >> $TESTSUITELOG
1136 }
1137
1138 build_test_filter() {
1139     [ "$ONLY" ] && log "only running test `echo $ONLY`"
1140     for O in $ONLY; do
1141         eval ONLY_${O}=true
1142     done
1143     [ "$EXCEPT$ALWAYS_EXCEPT" ] && \
1144         log "skipping tests: `echo $EXCEPT $ALWAYS_EXCEPT`"
1145     [ "$EXCEPT_SLOW" ] && \
1146         log "skipping tests SLOW=no: `echo $EXCEPT_SLOW`"
1147     for E in $EXCEPT $ALWAYS_EXCEPT; do
1148         eval EXCEPT_${E}=true
1149     done
1150     for E in $EXCEPT_SLOW; do
1151         eval EXCEPT_SLOW_${E}=true
1152     done
1153     for G in $GRANT_CHECK_LIST; do
1154         eval GCHECK_ONLY_${G}=true
1155         done
1156 }
1157
1158 _basetest() {
1159     echo $*
1160 }
1161
1162 basetest() {
1163     IFS=abcdefghijklmnopqrstuvwxyz _basetest $1
1164 }
1165
1166 run_test() {
1167     export base=`basetest $1`
1168     if [ ! -z "$ONLY" ]; then
1169         testname=ONLY_$1
1170         if [ ${!testname}x != x ]; then
1171             run_one $1 "$2"
1172             return $?
1173         fi
1174         testname=ONLY_$base
1175         if [ ${!testname}x != x ]; then
1176             run_one $1 "$2"
1177             return $?
1178         fi
1179         echo -n "."
1180         return 0
1181     fi
1182     testname=EXCEPT_$1
1183     if [ ${!testname}x != x ]; then
1184         TESTNAME=test_$1 skip "skipping excluded test $1"
1185         return 0
1186     fi
1187     testname=EXCEPT_$base
1188     if [ ${!testname}x != x ]; then
1189         TESTNAME=test_$1 skip "skipping excluded test $1 (base $base)"
1190         return 0
1191     fi
1192     testname=EXCEPT_SLOW_$1
1193     if [ ${!testname}x != x ]; then
1194         TESTNAME=test_$1 skip "skipping SLOW test $1"
1195         return 0
1196     fi
1197     testname=EXCEPT_SLOW_$base
1198     if [ ${!testname}x != x ]; then
1199         TESTNAME=test_$1 skip "skipping SLOW test $1 (base $base)"
1200         return 0
1201     fi
1202
1203     run_one $1 "$2"
1204     
1205     return $?
1206 }
1207
1208 EQUALS="======================================================================"
1209 equals_msg() {
1210     msg="$@"
1211
1212     local suffixlen=$((${#EQUALS} - ${#msg}))
1213     [ $suffixlen -lt 5 ] && suffixlen=5
1214     log `echo $(printf '===== %s %.*s\n' "$msg" $suffixlen $EQUALS)`
1215 }
1216
1217 log() {
1218     echo "$*"
1219     lsmod | grep lnet > /dev/null || load_modules
1220
1221     local MSG="$*"
1222     # Get rif of '
1223     MSG=${MSG//\'/\\\'}
1224     MSG=${MSG//\(/\\\(}
1225     MSG=${MSG//\)/\\\)}
1226     MSG=${MSG//\;/\\\;}
1227     MSG=${MSG//\|/\\\|}
1228     local NODES=$(nodes_list)
1229     for NODE in $NODES; do
1230         do_node $NODE $LCTL mark "$MSG" 2> /dev/null || true
1231     done
1232 }
1233
1234 trace() {
1235         log "STARTING: $*"
1236         strace -o $TMP/$1.strace -ttt $*
1237         RC=$?
1238         log "FINISHED: $*: rc $RC"
1239         return 1
1240 }
1241
1242 pass() {
1243     echo PASS $@
1244 }
1245
1246 check_mds() {
1247     FFREE=`cat /proc/fs/lustre/mds/*/filesfree`
1248     FTOTAL=`cat /proc/fs/lustre/mds/*/filestotal`
1249     [ $FFREE -ge $FTOTAL ] && error "files free $FFREE > total $FTOTAL" || true
1250 }
1251
1252 reset_fail_loc () {
1253     local myNODES=$(nodes_list)
1254     local NODE
1255
1256     for NODE in $myNODES; do
1257         do_node $NODE sysctl -w lustre.fail_loc=0 || true
1258     done
1259 }
1260
1261 run_one() {
1262     testnum=$1
1263     message=$2
1264     tfile=f${testnum}
1265     export tdir=d${TESTSUITE}/d${base}
1266     local SAVE_UMASK=`umask`
1267     umask 0022
1268     mkdir -p $DIR/$tdir
1269
1270     BEFORE=`date +%s`
1271     log "== test $testnum: $message ============ `date +%H:%M:%S` ($BEFORE)"
1272     #check_mds
1273     export TESTNAME=test_$testnum
1274     test_${testnum} || error "test_$testnum failed with $?"
1275     #check_mds
1276     reset_fail_loc
1277     check_grant ${testnum} || error "check_grant $testnum failed with $?"
1278     [ -f $CATASTROPHE ] && [ `cat $CATASTROPHE` -ne 0 ] && \
1279         error "LBUG/LASSERT detected"
1280     pass "($((`date +%s` - $BEFORE))s)"
1281     rmdir ${DIR}/$tdir >/dev/null 2>&1 || true
1282     unset TESTNAME
1283     unset tdir
1284     umask $SAVE_UMASK
1285     cd $SAVE_PWD
1286     $CLEANUP
1287 }
1288
1289 canonical_path() {
1290     (cd `dirname $1`; echo $PWD/`basename $1`)
1291 }
1292
1293 sync_clients() {
1294     [ -d $DIR1 ] && cd $DIR1 && sync; sleep 1; sync 
1295     [ -d $DIR2 ] && cd $DIR2 && sync; sleep 1; sync 
1296         cd $SAVE_PWD
1297 }
1298
1299 check_grant() {
1300     export base=`basetest $1`
1301     [ "$CHECK_GRANT" == "no" ] && return 0
1302
1303         testname=GCHECK_ONLY_${base}
1304         [ ${!testname}x == x ] && return 0
1305
1306         echo -n "checking grant......"
1307         cd $SAVE_PWD
1308         # write some data to sync client lost_grant
1309         rm -f $DIR1/${tfile}_check_grant_* 2>&1
1310         for i in `seq $OSTCOUNT`; do
1311                 $LFS setstripe $DIR1/${tfile}_check_grant_$i -i $(($i -1)) -c 1
1312                 dd if=/dev/zero of=$DIR1/${tfile}_check_grant_$i bs=4k \
1313                                               count=1 > /dev/null 2>&1 
1314         done
1315         # sync all the data and make sure no pending data on server
1316         sync_clients
1317         
1318         #get client grant and server grant 
1319         client_grant=0
1320     for d in ${LPROC}/osc/*/cur_grant_bytes; do 
1321                 client_grant=$((client_grant + `cat $d`))
1322         done
1323         server_grant=0
1324         for d in ${LPROC}/obdfilter/*/tot_granted; do
1325                 server_grant=$((server_grant + `cat $d`))
1326         done
1327
1328         # cleanup the check_grant file
1329         for i in `seq $OSTCOUNT`; do
1330                 rm $DIR1/${tfile}_check_grant_$i
1331         done
1332
1333         #check whether client grant == server grant 
1334         if [ $client_grant != $server_grant ]; then
1335                 echo "failed: client:${client_grant} server: ${server_grant}"
1336                 return 1
1337         else
1338                 echo "pass"
1339         fi
1340 }
1341
1342 ########################
1343 # helper functions
1344
1345 osc_to_ost()
1346 {
1347     osc=$1
1348     ost=`echo $1 | awk -F_ '{print $3}'`
1349     if [ -z $ost ]; then
1350         ost=`echo $1 | sed 's/-osc.*//'`
1351     fi
1352     echo $ost
1353 }
1354
1355 remote_mds ()
1356 {
1357     [ ! -e /proc/fs/lustre/mdt/*MDT* ]
1358 }
1359
1360 remote_ost ()
1361 {
1362     [ $(grep -c obdfilter $LPROC/devices) -eq 0 ]
1363 }
1364
1365 mdts_nodes () {
1366     local MDSNODES=$(facet_host $SINGLEMDS)
1367     local NODES_sort
1368
1369     # FIXME: Currenly we use only $SINGLEMDS,
1370     # should be fixed when we will start to test cmd.
1371     echo $MDSNODES
1372     return
1373
1374     for num in `seq $MDSCOUNT`; do
1375         local myMDS=$(facet_host mds$num)
1376         MDSNODES="$MDSNODES $myMDS"
1377     done
1378     NODES_sort=$(for i in $MDSNODES; do echo $i; done | sort -u)
1379
1380     echo $NODES_sort
1381 }
1382
1383 osts_nodes () {
1384     local OSTNODES=$(facet_host ost1)
1385     local NODES_sort
1386
1387     for num in `seq $OSTCOUNT`; do
1388         local myOST=$(facet_host ost$num)
1389         OSTNODES="$OSTNODES $myOST"
1390     done
1391     NODES_sort=$(for i in $OSTNODES; do echo $i; done | sort -u)
1392
1393     echo $NODES_sort
1394 }
1395
1396 nodes_list () {
1397     # FIXME. We need a list of clients
1398     local myNODES=`hostname`
1399     local myNODES_sort
1400     
1401     myNODES="$myNODES $(osts_nodes) $(mdts_nodes)"
1402     myNODES_sort=$(for i in $myNODES; do echo $i; done | sort -u)
1403
1404     echo $myNODES_sort
1405 }
1406
1407 is_patchless ()
1408 {
1409     grep -q patchless $LPROC/version
1410 }
1411
1412 check_runas_id() {
1413     local myRUNAS_ID=$1
1414     shift
1415     local myRUNAS=$@
1416     mkdir $DIR/d0_runas_test
1417     chmod 0755 $DIR
1418     chown $myRUNAS_ID:$myRUNAS_ID $DIR/d0_runas_test
1419     $myRUNAS touch $DIR/d0_runas_test/f$$ || \
1420         error "unable to write to $DIR/d0_runas_test as UID $myRUNAS_ID. 
1421         Please set RUNAS_ID to some UID which exists on MDS and client or 
1422         add user $myRUNAS_ID:$myRUNAS_ID on these nodes."
1423     rm -rf $DIR/d0_runas_test
1424 }