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