Update QA tests and host configs.
[xfstests-dev.git] / common.rc
1 ##/bin/sh
2 #-----------------------------------------------------------------------
3 #  Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
4 #  This program is free software; you can redistribute it and/or modify
5 #  it under the terms of the GNU General Public License as published by
6 #  the Free Software Foundation; either version 2 of the License, or
7 #  (at your option) any later version.
8 #
9 #  This program is distributed in the hope that it will be useful,
10 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #  GNU General Public License for more details.
13 #
14 #  You should have received a copy of the GNU General Public License
15 #  along with this program; if not, write to the Free Software
16 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
17 #  USA
18 #
19 #  Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
20 #  Mountain View, CA 94043, USA, or: http://www.sgi.com
21 #-----------------------------------------------------------------------
22
23 _mount_opts()
24 {
25     case $FSTYP in
26     xfs)
27         export MOUNT_OPTIONS=$XFS_MOUNT_OPTIONS
28         ;;
29     udf)
30         export MOUNT_OPTIONS=$UDF_MOUNT_OPTIONS
31         ;;
32     nfs)
33         export MOUNT_OPTIONS=$NFS_MOUNT_OPTIONS
34         ;;
35     *)
36         ;;
37     esac
38 }
39
40 _mkfs_opts()
41 {
42     case $FSTYP in
43     xfs)
44         export MKFS_OPTIONS=$XFS_MKFS_OPTIONS
45         ;;
46     udf)
47         [ ! -z "$udf_fsize" ] && \
48             UDF_MKFS_OPTIONS="$UDF_MKFS_OPTIONS -s $udf_fsize"
49         export MKFS_OPTIONS=$UDF_MKFS_OPTIONS
50         ;;
51     nfs)
52         export MKFS_OPTIONS=$NFS_MKFS_OPTIONS
53         ;;
54     *)
55         ;;
56     esac
57 }
58
59 [ -z "$FSTYP" ] && FSTYP=xfs
60 [ -z "$MOUNT_OPTIONS" ] && _mount_opts
61 [ -z "$MKFS_OPTIONS" ] && _mkfs_opts
62
63
64 # we need common.config
65 if ! . ./common.config
66 then
67     echo "$iam: failed to source common.config"
68     exit 1
69 fi
70
71 # make sure we have a standard umask
72 umask 022
73
74 _mount()
75 {
76     $MOUNT_PROG $*
77 }
78
79 _scratch_options()
80 {
81     type=$1
82     SCRATCH_OPTIONS=""
83
84     if [ $FSTYP != "xfs" ]; then
85         return
86     fi
87
88     case $type in
89     mkfs)
90         [ "$HOSTOS" != "IRIX" ] && SCRATCH_OPTIONS="$SCRATCH_OPTIONS -f"
91         rt_opt="-r"
92         log_opt="-l"
93         ;;
94     mount)
95         rt_opt="-o"
96         log_opt="-o"
97         ;;
98     esac
99     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
100         SCRATCH_OPTIONS="$SCRATCH_OPTIONS ${rt_opt}rtdev=$SCRATCH_RTDEV"
101     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
102         SCRATCH_OPTIONS="$SCRATCH_OPTIONS ${log_opt}logdev=$SCRATCH_LOGDEV"
103 }
104
105 _test_options()
106 {
107     type=$1
108     TEST_OPTIONS=""
109
110     if [ $FSTYP != "xfs" ]; then
111         return
112     fi
113
114     case $type in
115     mkfs)
116         rt_opt="-r"
117         log_opt="-l"
118         ;;
119     mount)
120         rt_opt="-o"
121         log_opt="-o"
122         ;;
123     esac
124     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
125         TEST_OPTIONS="$TEST_OPTIONS ${rt_opt}rtdev=$TEST_RTDEV"
126     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
127         TEST_OPTIONS="$TEST_OPTIONS ${log_opt}logdev=$TEST_LOGDEV"
128 }
129
130 _scratch_mount_options()
131 {
132     _scratch_options mount
133     echo $SCRATCH_OPTIONS $MOUNT_OPTIONS $* $SCRATCH_DEV $SCRATCH_MNT
134 }
135
136 _scratch_mount()
137 {
138     _mount -t $FSTYP `_scratch_mount_options $*`
139 }
140
141 _test_mount()
142 {
143     _test_options mount 
144     _mount -t $FSTYP $TEST_OPTIONS $MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
145 }
146
147 _scratch_mkfs_options()
148 {
149     _scratch_options mkfs 
150     echo $SCRATCH_OPTIONS $MKFS_OPTIONS $* $SCRATCH_DEV
151 }
152
153 _scratch_mkfs_xfs()
154 {
155     _scratch_options mkfs 
156
157     $MKFS_XFS_PROG $SCRATCH_OPTIONS $MKFS_OPTIONS $* $SCRATCH_DEV
158     mkfs_status=$?
159
160     if [ "$USE_BIG_LOOPFS" = yes ]; then
161         [ -z "$RETAIN_AG_BYTES" ] && RETAIN_AG_BYTES=0
162         ./tools/ag-wipe -q -r $RETAIN_AG_BYTES $SCRATCH_DEV
163     fi
164
165     return $mkfs_status
166 }
167
168 _scratch_mkfs()
169 {
170     case $FSTYP in
171     xfs)
172         _scratch_mkfs_xfs $*
173         ;;
174     nfs*)
175         # do nothing for nfs
176         ;;
177     udf)
178         $MKFS_UDF_PROG $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
179         ;;
180     *)
181         /sbin/mkfs -t $FSTYP $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
182         ;;
183     esac
184 }
185
186 _scratch_xfs_db_options()
187 {
188     SCRATCH_OPTIONS=""
189     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
190         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
191     echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
192 }
193
194 _scratch_xfs_logprint()
195 {
196     SCRATCH_OPTIONS=""
197     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
198         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
199     $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
200 }
201
202 _scratch_xfs_repair()
203 {
204     SCRATCH_OPTIONS=""
205     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
206         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
207     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
208         SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
209     [ "$USE_BIG_LOOPFS" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
210     $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
211 }
212
213 _get_pids_by_name()
214 {
215     if [ $# -ne 1 ]
216     then
217         echo "Usage: _get_pids_by_name process-name" 1>&2
218         exit 1
219     fi
220
221     # Algorithm ... all ps(1) variants have a time of the form MM:SS or
222     # HH:MM:SS before the psargs field, use this as the search anchor.
223     #
224     # Matches with $1 (process-name) occur if the first psarg is $1
225     # or ends in /$1 ... the matching uses sed's regular expressions,
226     # so passing a regex into $1 will work.
227
228     ps $PS_ALL_FLAGS \
229     | sed -n \
230         -e 's/$/ /' \
231         -e 's/[         ][      ]*/ /g' \
232         -e 's/^ //' \
233         -e 's/^[^ ]* //' \
234         -e "/[0-9]:[0-9][0-9]  *[^ ]*\/$1 /s/ .*//p" \
235         -e "/[0-9]:[0-9][0-9]  *$1 /s/ .*//p"
236 }
237
238 # fqdn for localhost
239 #
240 _get_fqdn()
241 {
242     host=`hostname`
243     $NSLOOKUP_PROG $host | $AWK_PROG '{ if ($1 == "Name:") print $2 }'
244 }
245
246 # fix malloc libs output
247 #
248 _fix_malloc()
249 {
250     # filter out the Electric Fence notice
251     $PERL_PROG -e '
252         while (<>) {
253             if (defined $o && /^\s+Electric Fence/) {
254                 chomp($o);
255                 print "$o";
256                 undef $o;
257                 next;
258             }
259             print $o if (defined $o);
260
261             $o=$_;
262         }
263         print $o if (defined $o);
264     '
265 }
266
267 # check if run as root
268 #
269 _need_to_be_root()
270 {
271     id=`id | $SED_PROG -e 's/(.*//' -e 's/.*=//'`
272     if [ "$id" -ne 0 ]
273     then
274         echo "Arrgh ... you need to be root (not uid=$id) to run this test"
275         exit 1
276     fi
277 }
278
279
280 #
281 # _df_device : get an IRIX style df line for a given device 
282 #
283 #       - returns "" if not mounted
284 #       - returns fs type in field two (ala IRIX)
285 #       - joins line together if split by fancy df formatting
286 #       - strips header etc
287 #
288
289 _df_device()
290 {
291     if [ $# -ne 1 ]
292     then
293         echo "Usage: _df_device device" 1>&2
294         exit 1
295     fi
296     
297     $DF_PROG 2>/dev/null | $AWK_PROG -v what=$1 '
298         match($1,what) && NF==1 { 
299             v=$1
300             getline
301             print v, $0
302             exit
303         }
304         match($1,what) {
305             print
306             exit
307         }
308     '
309 }
310
311 #
312 # _df_dir : get an IRIX style df line for device where a directory resides
313 #
314 #       - returns fs type in field two (ala IRIX)
315 #       - joins line together if split by fancy df formatting
316 #       - strips header etc
317 #
318
319 _df_dir()
320 {
321     if [ $# -ne 1 ]
322     then
323         echo "Usage: _df_dir device" 1>&2
324         exit 1
325     fi
326     
327     $DF_PROG $1 2>/dev/null | $AWK_PROG -v what=$1 '
328         NR == 2 && NF==1 { 
329             v=$1
330             getline 
331             print v, $0;
332             exit 0
333         }
334         NR == 2 {
335             print;
336             exit 0
337         }
338         {}
339     '
340     # otherwise, nada
341 }
342
343 # return percentage used disk space for mounted device
344
345 _used()
346 {
347     if [ $# -ne 1 ]
348     then
349         echo "Usage: _used device" 1>&2
350         exit 1
351     fi
352     
353     _df_device $1 | $AWK_PROG '{ sub("%", "") ; print $6 }'
354 }
355
356 # return the FS type of a mounted device
357 #
358 _fs_type()
359 {
360     if [ $# -ne 1 ]
361     then
362         echo "Usage: _fs_type device" 1>&2
363         exit 1
364     fi
365     
366     _df_device $1 | $AWK_PROG '{ print $2 }'
367 }
368
369 # return the FS mount options of a mounted device
370 #
371 # should write a version which just parses the output of mount for IRIX
372 # compatibility, but since this isn't used at all, at the moment I'll leave
373 # this for now
374 #
375 _fs_options()
376 {
377     if [ $# -ne 1 ]
378     then
379         echo "Usage: _fs_options device" 1>&2
380         exit 1
381     fi
382     
383     $AWK_PROG -v dev=$1 '
384         match($1,dev) { print $4 }
385     ' </proc/mounts
386     
387 }
388
389 # returns device number if a file is a block device
390 #
391 _is_block_dev()
392 {
393     if [ $# -ne 1 ]
394     then
395         echo "Usage: _is_block_dev dev" 1>&2
396         exit 1
397     fi
398     
399     [ -b $1 ] && src/lstat64 $1 | $AWK_PROG '/Device type:/ { print $9 }'
400 }
401
402 # Do a command, log it to $seq.full, optionally test return status
403 # and die if command fails. If called with one argument _do executes the
404 # command, logs it, and returns its exit status. With two arguments _do
405 # first prints the message passed in the first argument, and then "done"
406 # or "fail" depending on the return status of the command passed in the
407 # second argument. If the command fails and the variable _do_die_on_error
408 # is set to "always" or the two argument form is used and _do_die_on_error
409 # is set to "message_only" _do will print an error message to
410 # $seq.out and exit.
411
412 _do()
413 {
414     if [ $# -eq 1 ]; then
415         _cmd=$1
416     elif [ $# -eq 2 ]; then
417         _note=$1
418         _cmd=$2
419         echo -n "$_note... "
420     else
421         echo "Usage: _do [note] cmd" 1>&2
422         status=1; exit
423     fi
424
425     (eval "echo '---' \"$_cmd\"") >>$here/$seq.full
426     (eval "$_cmd") >$tmp._out 2>&1; ret=$?
427     cat $tmp._out | _fix_malloc >>$here/$seq.full
428     if [ $# -eq 2 ]; then
429         if [ $ret -eq 0 ]; then
430             echo "done"
431         else
432             echo "fail"
433         fi
434     fi
435     if [ $ret -ne 0  ] \
436         && [ "$_do_die_on_error" = "always" \
437             -o \( $# -eq 2 -a "$_do_die_on_error" = "message_only" \) ]
438     then
439         [ $# -ne 2 ] && echo
440         eval "echo \"$_cmd\" failed \(returned $ret\): see $seq.full"
441         status=1; exit
442     fi
443
444     return $ret
445 }
446
447 # bail out, setting up .notrun file
448
449 _notrun()
450 {
451     echo "$*" >$seq.notrun
452     echo "$seq not run: $*"
453     status=0
454     exit
455 }
456
457 # just plain bail out
458
459 _fail()
460 {
461     echo "$*" | tee -a $here/$seq.full
462     echo "(see $seq.full for details)"
463     status=1
464     exit 1
465 }
466
467 # tests whether $FSTYP is one of the supported filesystems for a test
468 #
469 _supported_fs()
470 {
471     for f
472     do
473         if [ "$f" = "$FSTYP" ]
474         then
475             return
476         fi
477     done
478
479     _notrun "not suitable for this filesystem type: $FSTYP"
480 }
481
482 # tests whether $FSTYP is one of the supported OSes for a test
483 #
484 _supported_os()
485 {
486     for h
487     do
488         if [ "$h" = "$HOSTOS" ]
489         then
490             return
491         fi
492     done
493
494     _notrun "not suitable for this OS: $HOSTOS"
495 }
496
497 # this test needs a scratch partition - check we're ok & unmount it
498
499 _require_scratch()
500 {
501     case "$FSTYP" in
502         xfs|udf)
503                  if [ -z "$SCRATCH_DEV" -o "`_is_block_dev $SCRATCH_DEV`" = "" ]
504                  then
505                      _notrun "this test requires a valid \$SCRATCH_DEV"
506                  fi
507                  
508                  if [ "`_is_block_dev $SCRATCH_DEV`" = "`_is_block_dev $TEST_DEV`" ]
509                  then
510                      _notrun "this test requires a valid \$SCRATCH_DEV"
511                  fi
512                  ;;
513         nfs*|ext2|ext3|reiserfs)
514                  echo $SCRATCH_DEV | grep -q ":" > /dev/null 2>&1
515                  if [ ! -z "$SCRATCH_DEV" -a ! -b "$SCRATCH_DEV" -a "$?" != "0" ]
516                  then
517                      _notrun "this test requires a valid \$SCRATCH_DEV"
518                  fi
519                  ;;
520         *)
521                  _notrun "\$FSTYP ($FSTYP) unknown or not specified"
522                  ;;
523     esac
524
525     
526     # mounted?
527     if _mount | grep -q $SCRATCH_DEV
528     then 
529         # if it's mounted, make sure its on $SCRATCH_MNT
530         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
531         then 
532             echo "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
533             exit 1
534         fi
535         # and then unmount it
536         if ! $UMOUNT_PROG $SCRATCH_DEV
537         then
538             echo "failed to unmount $SCRATCH_DEV"
539             exit 1
540         fi
541     fi
542 }
543
544 # this test needs a logdev 
545
546 _require_logdev()
547 {
548     [ -z "$SCRATCH_LOGDEV" -o ! -b "$SCRATCH_LOGDEV" ] && \
549         _notrun "This test requires a valid \$SCRATCH_LOGDEV" 
550     [ "$USE_EXTERNAL" != yes ] && \
551         _notrun "This test requires USE_EXTERNAL to be enabled"
552
553     # ensure its not mounted
554     $UMOUNT_PROG $SCRATCH_LOGDEV 2>/dev/null
555 }
556
557 # this test requires loopback device support
558
559 _require_loop()
560 {
561     if [ "$HOSTOS" != "Linux" ]
562     then
563         _notrun "This test requires linux for loopback device support"
564     fi
565
566     modprobe loop >/dev/null 2>&1
567     if grep loop /proc/devices >/dev/null 2>&1
568     then
569         :
570     else
571         _notrun "This test requires loopback device support"
572     fi
573 }
574
575 # this test requires that (large) loopback device files are not in use
576
577 _require_nobigloopfs()
578 {
579     [ "$USE_BIG_LOOPFS" = yes ] && \
580         _notrun "Large filesystem testing in progress, skipped this test"
581 }
582
583 # this test requires that a realtime subvolume is in use, and
584 # that the kernel supports realtime as well.
585
586 _require_realtime()
587 {
588     [ "$USE_EXTERNAL" = yes ] || \
589         _notrun "External volumes not in use, skipped this test"
590     [ "$SCRATCH_RTDEV" = "" ] && \
591         _notrun "Realtime device required, skipped this test"
592 }
593
594 # this test requires that a specified command (executable) exists
595
596 _require_command()
597 {
598     [ -x "$1" ] || _notrun "$1 utility required, skipped this test"
599 }
600
601 # this test requires that external log/realtime devices are not in use
602
603 _require_nonexternal()
604 {
605     [ "$USE_EXTERNAL" = yes ] && \
606         _notrun "External device testing in progress, skipped this test"
607 }
608
609 # check that a FS is mounted as XFS. if so, return mount point
610 #
611 _xfs_mounted()
612 {
613     if [ $# -ne 1 ]
614     then
615         echo "Usage: _xfs_mounted device" 1>&2
616         exit 1
617     fi
618     
619     device=$1
620     
621     if _mount | grep $device | $AWK_PROG '
622         /type xfs/  { print $3 ; exit 0 }
623         END         { exit 1 }
624     '
625     then
626         echo "_xfs_mounted: $device is not a mounted XFS FS"
627         exit 1
628     fi
629 }
630
631
632 # remount a FS to a new mode (ro or rw)
633 #
634 _remount()
635 {
636     if [ $# -ne 2 ]
637     then
638         echo "Usage: _remount device ro/rw" 1>&2
639         exit 1
640     fi
641     device=$1
642     mode=$2
643     
644     if ! mount -o remount,$mode $device
645     then
646         echo "_remount: failed to remount filesystem on $device as $mode"
647         exit 1
648     fi
649 }
650
651 # run xfs_check and friends on a FS. 
652 #
653 # if the filesystem is mounted, it's either remounted ro before being
654 # checked or it's unmounted and then remounted
655 #
656
657 USE_REMOUNT=0
658
659 _check_xfs_filesystem()
660 {
661     if [ $# -ne 3 ]
662     then
663         echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
664         exit 1
665     fi
666
667     device=$1
668     if [ "$2" != "none" ]; then
669         extra_log_options="-l$2"
670         extra_mount_options="-ologdev=$2"
671     fi
672
673     if [ "$3" != "none" ]; then
674         extra_rt_options="-r$3"
675         extra_mount_options=$extra_mount_options" -ortdev=$3"
676     fi
677
678     [ "$FSTYP" != xfs ] && return 0
679     testoption=""
680     [ "$USE_BIG_LOOPFS" = yes ] && testoption=-t
681
682     type=`_fs_type $device`
683     ok=1
684     
685     if [ "$type" = "xfs" ]
686     then
687         # mounted... 
688         
689         if [ $USE_REMOUNT -eq 0 ]
690         then
691             mountpoint=`_xfs_mounted $device`
692             $UMOUNT_PROG $device
693         else
694             _remount $device ro
695         fi
696     fi
697
698     $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
699                 | tee $tmp.logprint | grep -q "<CLEAN>"
700     if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
701     then
702         echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seq.full)"
703         
704         echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$here/$seq.full
705         echo "*** xfs_logprint -t output ***"                   >>$here/$seq.full
706         cat $tmp.logprint                                       >>$here/$seq.full
707         echo "*** end xfs_logprint output"                      >>$here/$seq.full
708         
709         ok=0
710     fi
711
712     $XFS_CHECK_PROG $testoption $extra_log_options $device 2>&1 |\
713          _fix_malloc >$tmp.fs_check 
714     if [ -s $tmp.fs_check ]
715     then
716         echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seq.full)"
717         
718         echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$here/$seq.full
719         echo "*** xfs_check output ***"                         >>$here/$seq.full
720         cat $tmp.fs_check                                       >>$here/$seq.full
721         echo "*** end xfs_check output"                         >>$here/$seq.full
722         
723         ok=0
724     fi
725     # repair doesn't scale massively at this stage, optionally skip it for now
726     [ "$USE_BIG_LOOPFS" = yes ] || \
727     $XFS_REPAIR_PROG -n $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
728     if [ $? -ne 0 ]
729     then
730         echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seq.full)"
731         
732         echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$here/$seq.full
733         echo "*** xfs_repair -n output ***"                     >>$here/$seq.full
734         cat $tmp.repair | _fix_malloc                           >>$here/$seq.full
735         echo "*** end xfs_repair output"                        >>$here/$seq.full
736         
737         ok=0
738     fi
739     rm -f $tmp.fs_check $tmp.logprint $tmp.repair
740  
741     if [ $ok -eq 0 ]
742     then
743         echo "*** mount output ***"                             >>$here/$seq.full
744         _mount                                                  >>$here/$seq.full
745         echo "*** end mount output"                             >>$here/$seq.full
746     elif [ "$type" = "xfs" ]
747     then
748         # mounted... 
749         if [ $USE_REMOUNT -eq 0 ]
750         then
751             if ! _mount -t xfs $extra_mount_options $device $mountpoint
752             then
753                 echo "!!! failed to remount $device on $mountpoint"
754                 ok=0
755             fi
756         else
757             _remount $device rw
758         fi
759     fi
760     
761     [ $ok -eq 0 ] && exit 1
762     return 0    
763 }
764
765 # Filter the knowen errors the UDF Verifier reports. 
766 _udf_test_known_error_filter() 
767 {
768         egrep -v "PVD  60  Error: Interchange Level: 1, Maximum Interchange Level: 0|FSD  28  Error: Interchange Level: 1, Maximum Interchange Level: 1,|PVD  72  Warning: Volume Set Identifier: \"\*IRIX UDF\",|Warning: [0-9]+ unused blocks NOT marked as unallocated."
769
770 }
771
772 _check_udf_filesystem()
773 {
774     [ "$DISABLE_UDF_TEST" == "1" ] && return
775
776     if [ $# -ne 1 -a $# -ne 2 ]
777     then
778         echo "Usage: _check_udf_filesystem device [last_block]" 1>&2
779         exit 1
780     fi
781
782     if [ ! -x $here/src/udf_test ]
783     then
784         echo "udf_test not installed, please download and build the Philips" 
785         echo "UDF Verification Software from http://www.extra.research.philips.com/udf/."
786         echo "Then copy the udf_test binary to $here/src/."
787         echo "If you do not wish to run udf_test then set environment variable DISABLE_UDF_TEST"
788         echo "to 1."
789         return
790     fi
791         
792     device=$1
793     if [ $# -eq 2 ];
794     then
795         LAST_BLOCK=`expr \( $2 - 1 \)`
796         OPT_ARG="-lastvalidblock $LAST_BLOCK"
797     fi
798
799     rm -f $seq.checkfs
800     sleep 1 # Due to a problem with time stamps in udf_test
801     $here/src/udf_test $OPT_ARG $device | tee $here/$seq.checkfs | egrep "Error|Warning" | \
802         _udf_test_known_error_filter | \
803         egrep -iv "Error count:.*[0-9]+.*total occurrences:.*[0-9]+|Warning count:.*[0-9]+.*total occurrences:.*[0-9]+" | \
804         sed "s/^.*$/Warning UDF Verifier reported errors see $seq.checkfs./g"
805
806 }
807
808 _check_test_fs()
809 {
810     TEST_LOG="none"
811     TEST_RT="none"
812     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
813         TEST_LOG="$TEST_LOGDEV"
814
815     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
816         TEST_RT="$TEST_RTDEV"
817
818     _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
819 }
820
821 _check_scratch_fs()
822 {
823     case $FSTYP in
824     xfs)
825         SCRATCH_LOG="none"
826         SCRATCH_RT="none"
827         [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
828             SCRATCH_LOG="$SCRATCH_LOGDEV"
829
830         [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
831             SCRATCH_RT="$SCRATCH_RTDEV"
832
833         _check_xfs_filesystem $SCRATCH_DEV $SCRATCH_LOG $SCRATCH_RT
834         ;;
835     udf)
836         _check_udf_filesystem $SCRATCH_DEV $udf_fsize
837         ;;
838     nfs*)
839         # Don't know how to check an NFS filesystem, yet.
840         ;;
841     *)
842         ;;
843     esac
844 }
845
846 _full_fstyp_details()
847 {
848      [ -z "$FSTYP" ] && FSTYP=xfs
849      if [ $FSTYP = xfs ]; then
850         if [ -d /proc/fs/xfs ]; then
851             if grep -q 'debug 0' /proc/fs/xfs/stat; then
852                 FSTYP="$FSTYP (non-debug)"
853             elif grep -q 'debug 1' /proc/fs/xfs/stat; then
854                 FSTYP="$FSTYP (debug)"
855             fi
856         else
857             if uname -a | grep -qi 'debug'; then
858                 FSTYP="$FSTYP (debug)"
859             else
860                 FSTYP="$FSTYP (non-debug)"
861             fi
862         fi
863      fi
864      echo $FSTYP
865 }
866
867 _full_platform_details()
868 {
869      os=`uname -s`
870      host=`hostname -s`
871      kernel=`uname -r`
872      platform=`uname -m`
873      echo "$os/$platform $host $kernel"
874 }
875
876 _check_testdir()
877 {
878     case $FSTYP in
879     xfs)
880         _check_test_fs
881         ;;
882     udf)
883         _cleanup_testdir
884         _check_scratch_fs
885         _scratch_mount
886         ;;
887     nfs*)
888         # Don't know how to check an NFS filesystem, yet.
889         ;;
890     *)
891         ;;
892     esac
893 }
894
895
896 _setup_xfs_testdir()
897 {
898     [ "$FSTYP" != "xfs" ] \
899         && _fail "setup_xfs_testdir: \$FSTYP ($FSTYP) is not xfs"
900     
901     testdir=$TEST_DIR
902 }
903
904 _setup_udf_scratchdir()
905 {
906     [ "$FSTYP" != "udf" ] \
907         && _fail "setup_udf_testdir: \$FSTYP is not udf"
908     [ -z "$SCRATCH_DEV" -o ! -b "$SCRATCH_DEV" ] \
909         && _notrun "this test requires a valid \$SCRATCH_DEV"
910     [ -z "$SCRATCH_MNT" ] \
911         && _notrun "this test requires a valid \$SCRATCH_MNT"
912     
913     # mounted?
914     if _mount | grep -q $SCRATCH_DEV
915     then 
916         # if it's mounted, make sure its on $TEST_RW_DIR
917         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
918         then 
919             _fail "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
920         fi
921         $UMOUNT_PROG $SCRATCH_DEV
922     fi 
923
924     _scratch_mkfs
925     _scratch_mount
926
927     testdir=$SCRATCH_MNT
928 }
929
930 _setup_nfs_scratchdir()
931 {
932     [ "$FSTYP" != "nfs" ] \
933         && _fail "setup_nfs_testdir: \$FSTYP is not nfs"
934     [ -z "$SCRATCH_DEV" ] \
935         && _notrun "this test requires a valid host fs for \$SCRATCH_DEV"
936     [ -z "$SCRATCH_MNT" ] \
937         && _notrun "this test requires a valid \$SCRATCH_MNT"
938     
939     # mounted?
940     if _mount | grep -q $SCRATCH_DEV
941     then 
942         # if it's mounted, make sure its on $SCRATCH_MNT
943         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
944         then 
945             _fail "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
946         fi
947         $UMOUNT_PROG $SCRATCH_DEV
948     fi 
949
950     _scratch_mkfs
951     _scratch_mount
952
953     testdir=$SCRATCH_MNT
954 }
955
956 #
957 # Warning for UDF and NFS this function calls _setup_udf_scratchdir and 
958 # _setup_udf_scratchdir. This is done because testdir is a persistent 
959 # XFS only partition. 
960 #
961 _setup_testdir()
962 {
963     case $FSTYP in
964     xfs)
965         _setup_xfs_testdir
966         ;;
967     udf)
968         _setup_udf_scratchdir
969         ;;
970     nfs*)
971         _setup_nfs_scratchdir
972         ;;
973     *)
974         _fail "\$FSTYP is not xfs, udf or nfs"
975         ;;
976     esac    
977 }
978
979 _cleanup_testdir()
980 {
981     case $FSTYP in
982     xfs)
983         # do nothing, testdir is $TEST_DIR
984         :
985         ;;
986     udf)
987         # umount testdir as it is $SCRATCH_MNT which could be used by xfs next
988         [ -n "$testdir" ] && $UMOUNT_PROG $testdir
989         ;;
990     nfs*)
991         # umount testdir as it is $SCRATCH_MNT which could be used by xfs next
992         [ -n "$testdir" ] && $UMOUNT_PROG $testdir
993         ;;
994     *)
995         _fail "\$FSTYP is not xfs, udf or nfs"
996         ;;
997     esac    
998 }
999
1000 ################################################################################
1001
1002 if [ "$iam" != new -a "$iam" != bench ]
1003 then
1004     # make some further configuration checks here
1005
1006     if [ "$TEST_DEV" = ""  ]
1007     then
1008         echo "common.rc: Error: \$TEST_DEV is not set"
1009         exit 1
1010     fi
1011     
1012     # if $TEST_DEV is not mounted, mount it now as XFS
1013     if [ -z "`_fs_type $TEST_DEV`" ]
1014     then
1015         # $TEST_DEV is not mounted
1016         if ! _test_mount
1017         then
1018             echo "common.rc: retrying test device mount with external set"
1019             [ "$USE_EXTERNAL" != "yes" ] && export USE_EXTERNAL=yes
1020             if ! _test_mount
1021             then
1022                 echo "common.rc: could not mount $TEST_DEV on $TEST_DIR"
1023                 exit 1
1024             fi
1025         fi
1026     fi
1027     
1028     if [ "`_fs_type $TEST_DEV`" != "xfs" ]
1029     then
1030         echo "common.rc: Error: \$TEST_DEV ($TEST_DEV) is not a MOUNTED XFS filesystem"
1031         $DF_PROG $TEST_DEV
1032         exit 1
1033     fi
1034
1035 fi
1036
1037 _link_out_file()
1038 {
1039    if [ -z "$1" ]; then
1040       echo Error must pass \$seq.
1041       exit      
1042    fi
1043    rm -f $1
1044    if [ "`uname`" == "IRIX64" ] || [ "`uname`" == "IRIX" ]; then
1045       ln -s $1.irix $1
1046    elif [ "`uname`" == "Linux" ]; then
1047       ln -s $1.linux $1
1048    else
1049       echo Error test $seq does not run on the operating system: `uname`
1050       exit
1051    fi
1052 }
1053
1054 # Populate a filesystem with inodes for performance experiments
1055
1056 # usage: populate [-v] [-n ndirs] [-f nfiles] [-d depth] [-r root] [-s size]
1057
1058
1059 _die()
1060 {
1061         echo $@
1062         exit 1
1063 }
1064
1065 _nfiles()
1066 {
1067         f=0
1068         while [ $f -lt $1 ]
1069         do
1070                 file=f$f
1071                 touch $file
1072                 if [ $size -gt 0 ]; then
1073                     dd if=/dev/zero of=$file bs=1024 count=$size 
1074                 fi
1075                 f=`expr $f + 1`
1076         done
1077 }
1078
1079 # takes dirname, depth
1080 _descend()
1081 {
1082         dirname=$1; depth=$2
1083         mkdir $dirname  || die "mkdir $dirname failed"
1084         cd $dirname
1085
1086         _nfiles $files           # files for this dir
1087
1088         [ $depth -eq 0 ] && return
1089         deep=`expr $depth - 1`  # go 1 down
1090
1091         [ $verbose = true ] && echo "descending, depth from leaves = $deep"
1092
1093         d=0
1094         while [ $d -lt $dirs ]
1095         do
1096                 _descend d$d $deep &
1097                 d=`expr $d + 1`
1098                 wait
1099         done
1100 }
1101
1102
1103 _populate_fs()
1104 {
1105
1106     here=`pwd`
1107     dirs=5          # ndirs in each subdir till leaves
1108     size=0          # sizeof files in K
1109     files=100       # num files in _each_ subdir
1110     depth=2         # depth of tree from root to leaves
1111     verbose=false
1112     root=root       # path of initial root of directory tree
1113
1114     while getopts "d:f:n:r:s:v" c
1115     do
1116         case $c in
1117         d)      depth=$OPTARG;;
1118         n)      dirs=$OPTARG;;
1119         f)      files=$OPTARG;;
1120         s)      size=$OPTARG;;
1121         v)      verbose=true;;
1122         r)      root=$OPTARG;;
1123         esac
1124     done
1125
1126
1127     _descend $root $depth
1128     wait
1129
1130     cd $here
1131
1132     [ $verbose = true ] && echo done
1133
1134 }
1135
1136 # make sure this script returns success
1137 /bin/true