xfstests: automatically add -F to xfs_io on non-xfs
[xfstests-dev.git] / common / rc
1 ##/bin/bash
2 #-----------------------------------------------------------------------
3 #  Copyright (c) 2000-2006 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 BC=$(which bc 2> /dev/null) || BC=
24
25 _require_math()
26 {
27         if [ -z "$BC" ]; then
28                 _notrun "this test requires 'bc' tool for doing math operations"
29         fi
30 }
31
32 _math()
33 {
34         [ $# -le 0 ] && return
35         if [ "$BC" ]; then
36                 result=$(LANG=C echo "scale=0; $@" | "$BC" -q 2> /dev/null)
37         else
38                 _notrun "this test requires 'bc' tool for doing math operations"
39         fi
40         echo "$result"
41 }
42
43 dd()
44 {
45    if [ "$HOSTOS" == "Linux" ]
46    then 
47         command dd --help | grep noxfer > /dev/null 2>&1
48         
49         if [ "$?" -eq 0 ]
50             then
51                 command dd status=noxfer $@
52             else
53                 command dd $@
54         fi
55    else
56         command dd $@
57    fi
58 }
59
60 # Prints the md5 checksum of a given file
61 _md5_checksum()
62 {
63         md5sum $1 | cut -d ' ' -f1
64 }
65
66
67 # ls -l w/ selinux sometimes puts a dot at the end:
68 # -rwxrw-r--. id1 id2 file1
69
70 _ls_l()
71 {
72         ls -l $* | sed "s/\(^[-rwxdlbcpsStT]*\)\. /\1 /"
73 }
74
75 _mount_opts()
76 {
77     # SELinux adds extra xattrs which can mess up our expected output.
78     # So, mount with a context, and they won't be created
79     # nfs_t is a "liberal" context so we can use it.
80     if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
81         SELINUX_MOUNT_OPTIONS="-o context=system_u:object_r:nfs_t:s0"
82         export SELINUX_MOUNT_OPTIONS
83     fi
84
85     case $FSTYP in
86     xfs)
87         export MOUNT_OPTIONS=$XFS_MOUNT_OPTIONS
88         ;;
89     udf)
90         export MOUNT_OPTIONS=$UDF_MOUNT_OPTIONS
91         ;;
92     nfs)
93         export MOUNT_OPTIONS=$NFS_MOUNT_OPTIONS
94         ;;
95     ext2|ext3|ext4|ext4dev)
96         # acls & xattrs aren't turned on by default on ext$FOO
97         export MOUNT_OPTIONS="-o acl,user_xattr $EXT_MOUNT_OPTIONS"
98         ;;
99     reiserfs)
100         # acls & xattrs aren't turned on by default on reiserfs
101         export MOUNT_OPTIONS="-o acl,user_xattr $REISERFS_MOUNT_OPTIONS"
102         ;;
103     gfs2)
104         # acls aren't turned on by default on gfs2
105         export MOUNT_OPTIONS="-o acl $GFS2_MOUNT_OPTIONS"
106         ;;
107     *)
108         ;;
109     esac
110 }
111
112 _mkfs_opts()
113 {
114     case $FSTYP in
115     xfs)
116         export MKFS_OPTIONS=$XFS_MKFS_OPTIONS
117         ;;
118     udf)
119         [ ! -z "$udf_fsize" ] && \
120             UDF_MKFS_OPTIONS="$UDF_MKFS_OPTIONS -s $udf_fsize"
121         export MKFS_OPTIONS=$UDF_MKFS_OPTIONS
122         ;;
123     nfs)
124         export MKFS_OPTIONS=$NFS_MKFS_OPTIONS
125         ;;
126     reiserfs)
127         export MKFS_OPTIONS="$REISERFS_MKFS_OPTIONS -q"
128         ;;
129     gfs2)
130         export MKFS_OPTIONS="$GFS2_MKFS_OPTIONS -O -p lock_nolock"
131         ;;
132     jfs)
133         export MKFS_OPTIONS="$JFS_MKFS_OPTIONS -q"
134         ;;
135     *)
136         ;;
137     esac
138 }
139
140 _fsck_opts()
141 {
142     case $FSTYP in
143     ext2|ext3|ext4|ext4dev)
144         export FSCK_OPTIONS="-nf"
145         ;;
146     reiserfs)
147         export FSCK_OPTIONS="--yes"
148         ;;
149     *)
150         export FSCK_OPTIONS="-n"
151         ;;
152     esac
153 }
154
155 [ -z "$FSTYP" ] && FSTYP=xfs
156 [ -z "$MOUNT_OPTIONS" ] && _mount_opts
157 [ -z "$MKFS_OPTIONS" ] && _mkfs_opts
158 [ -z "$FSCK_OPTIONS" ] && _fsck_opts
159
160
161 # we need common/config
162 if [ "$iam" != "check" ]
163 then
164     if ! . ./common/config
165         then
166         echo "$iam: failed to source common/config"
167         exit 1
168     fi
169 fi
170
171 # check for correct setup
172 case "$FSTYP" in
173     xfs)
174          [ "$XFS_LOGPRINT_PROG" = "" ] && _fatal "xfs_logprint not found"
175          [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
176          [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
177          [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
178          ;;
179     udf)
180          [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
181          ;;
182     btrfs)
183          [ "$MKFS_BTRFS_PROG" = "" ] && _fatal "mkfs.btrfs not found"
184          ;;
185     nfs)
186          ;;
187 esac
188
189 # make sure we have a standard umask
190 umask 022
191
192 _mount()
193 {
194     $MOUNT_PROG `_mount_ops_filter $*`
195 }
196
197 _scratch_options()
198 {
199     type=$1
200     SCRATCH_OPTIONS=""
201
202     if [ "$FSTYP" != "xfs" ]; then
203         return
204     fi
205
206     case $type in
207     mkfs)
208         [ "$HOSTOS" != "IRIX" ] && SCRATCH_OPTIONS="$SCRATCH_OPTIONS -f"
209         rt_opt="-r"
210         log_opt="-l"
211         ;;
212     mount)
213         rt_opt="-o"
214         log_opt="-o"
215         ;;
216     esac
217     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
218         SCRATCH_OPTIONS="$SCRATCH_OPTIONS ${rt_opt}rtdev=$SCRATCH_RTDEV"
219     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
220         SCRATCH_OPTIONS="$SCRATCH_OPTIONS ${log_opt}logdev=$SCRATCH_LOGDEV"
221 }
222
223 _test_options()
224 {
225     type=$1
226     TEST_OPTIONS=""
227
228     if [ "$FSTYP" != "xfs" ]; then
229         return
230     fi
231
232     case $type in
233     mkfs)
234         rt_opt="-r"
235         log_opt="-l"
236         ;;
237     mount)
238         rt_opt="-o"
239         log_opt="-o"
240         ;;
241     esac
242     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
243         TEST_OPTIONS="$TEST_OPTIONS ${rt_opt}rtdev=$TEST_RTDEV"
244     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
245         TEST_OPTIONS="$TEST_OPTIONS ${log_opt}logdev=$TEST_LOGDEV"
246 }
247
248 _mount_ops_filter()
249 {
250     params="$*"
251     
252     #get mount point to handle dmapi mtpt option correctly
253     let last_index=$#-1
254     [ $last_index -gt 0 ] && shift $last_index
255     FS_ESCAPED=$1
256     
257     # irix is fussy about how it is fed its mount options
258     # - multiple -o's are not allowed
259     # - no spaces between comma delimitered options
260     # the sed script replaces all -o's (except the first) with a comma
261     # not required for linux, but won't hurt
262     
263     echo $params | sed -e 's/[[:space:]]*-o[[:space:]]*/UnIqUe/1; s/[[:space:]]*-o[[:space:]]*/,/g; s/UnIqUe/ -o /1' \
264         | sed -e 's/dmapi/dmi/' \
265         | $PERL_PROG -ne "s#mtpt=[^,|^\n|^\s]*#mtpt=$FS_ESCAPED\1\2#; print;"
266
267 }
268
269 _scratch_mount_options()
270 {
271     _scratch_options mount
272
273     echo $SCRATCH_OPTIONS $MOUNT_OPTIONS $SELINUX_MOUNT_OPTIONS $* $SCRATCH_DEV $SCRATCH_MNT
274 }
275
276 _scratch_mount()
277 {
278     _mount -t $FSTYP `_scratch_mount_options $*`
279 }
280
281 _scratch_unmount()
282 {
283     $UMOUNT_PROG $SCRATCH_DEV
284 }
285
286 _scratch_remount()
287 {
288     _scratch_unmount
289     _scratch_mount
290 }
291
292 _test_mount()
293 {
294     _test_options mount
295     _mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
296 }
297
298 _scratch_mkfs_options()
299 {
300     _scratch_options mkfs
301     echo $SCRATCH_OPTIONS $MKFS_OPTIONS $* $SCRATCH_DEV
302 }
303
304
305 _setup_large_xfs_fs()
306 {
307         fs_size=$1
308         local tmp_dir=/tmp/
309
310         [ "$LARGE_SCRATCH_DEV" != yes ] && return 0
311         [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0
312         [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0
313
314         # calculate the size of the file we need to allocate.
315         # Default free space in the FS is 50GB, but you can specify more via
316         # SCRATCH_DEV_EMPTY_SPACE
317         file_size=$(($fs_size - 50*1024*1024*1024))
318         file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE))
319
320         # mount the filesystem, create the file, unmount it
321         _scratch_mount 2>&1 >$tmp_dir/mnt.err
322         local status=$?
323         if [ $status -ne 0 ]; then
324                 echo "mount failed"
325                 cat $tmp_dir/mnt.err >&2
326                 rm -f $tmp_dir/mnt.err
327                 return $status
328         fi
329         rm -f $tmp_dir/mnt.err
330
331         xfs_io -F -f \
332                 -c "truncate $file_size" \
333                 -c "falloc -k 0 $file_size" \
334                 -c "chattr +d" \
335                 $SCRATCH_MNT/.use_space 2>&1 > /dev/null
336         export NUM_SPACE_FILES=1
337         status=$?
338         umount $SCRATCH_MNT
339         if [ $status -ne 0 ]; then
340                 echo "large file prealloc failed"
341                 cat $tmp_dir/mnt.err >&2
342                 return $status
343         fi
344         return 0
345 }
346
347 _scratch_mkfs_xfs()
348 {
349     # extra mkfs options can be added by tests
350     local extra_mkfs_options=$*
351
352     local tmp_dir=/tmp/
353
354     _scratch_options mkfs
355
356     # save mkfs output in case conflict means we need to run again.
357     # only the output for the mkfs that applies should be shown
358     $MKFS_XFS_PROG $SCRATCH_OPTIONS $MKFS_OPTIONS $extra_mkfs_options $SCRATCH_DEV \
359         2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
360     local mkfs_status=$?
361
362     # a mkfs failure may be caused by conflicts between
363     # $MKFS_OPTIONS and $extra_mkfs_options
364
365     if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then
366         echo "** mkfs failed with extra mkfs options added to \"$MKFS_OPTIONS\" by test $seq **" \
367             >>$seqres.full
368         echo "** attempting to mkfs using only test $seq options: $extra_mkfs_options **" \
369             >>$seqres.full
370         # running mkfs again. overwrite previous mkfs output files
371         $MKFS_XFS_PROG $SCRATCH_OPTIONS $extra_mkfs_options $SCRATCH_DEV \
372             2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
373         mkfs_status=$?
374     fi
375
376     if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then
377         # manually parse the mkfs output to get the fs size in bytes
378         local fs_size
379         fs_size=`cat $tmp_dir.mkfsstd | perl -ne '
380             if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) {
381                 my $size = $1 * $2;
382                 print STDOUT "$size\n";
383             }'`
384         _setup_large_xfs_fs $fs_size
385         mkfs_status=$?
386     fi
387
388     # output stored mkfs output
389     cat $tmp_dir.mkfserr >&2
390     cat $tmp_dir.mkfsstd
391     rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
392
393     return $mkfs_status
394 }
395
396 # xfs_check script is planned to be deprecated. But, we want to
397 # be able to invoke "xfs_check" behavior in xfstests in order to
398 # maintain the current verification levels.
399 _xfs_check()
400 {
401     OPTS=" "
402     DBOPTS=" "
403     USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
404
405     while getopts "b:fi:l:stvV" c
406     do
407         case $c in
408             s) OPTS=$OPTS"-s ";;
409             t) OPTS=$OPTS"-t ";;
410             v) OPTS=$OPTS"-v ";;
411             i) OPTS=$OPTS"-i "$OPTARG" ";;
412             b) OPTS=$OPTS"-b "$OPTARG" ";;
413             f) DBOPTS=$DBOPTS" -f";;
414             l) DBOPTS=$DBOPTS" -l "$OPTARG" ";;
415             V) $XFS_DB_PROG -p xfs_check -V
416                 return $?
417                 ;;
418         esac
419     done
420     set -- extra $@
421     shift $OPTIND
422     case $# in
423         1)    ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1
424                status=$?
425                ;;
426         2)    echo $USAGE 1>&1
427               status=2
428               ;;
429     esac
430     return $status
431 }
432
433 _setup_large_ext4_fs()
434 {
435         fs_size=$1
436         local tmp_dir=/tmp/
437
438         [ "$LARGE_SCRATCH_DEV" != yes ] && return 0
439         [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0
440         [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0
441
442         # Default free space in the FS is 50GB, but you can specify more via
443         # SCRATCH_DEV_EMPTY_SPACE
444         space_to_consume=$(($fs_size - 50*1024*1024*1024 - $SCRATCH_DEV_EMPTY_SPACE))
445
446         # mount the filesystem and create 16TB - 4KB files until we consume
447         # all the necessary space.
448         _scratch_mount 2>&1 >$tmp_dir/mnt.err
449         local status=$?
450         if [ $status -ne 0 ]; then
451                 echo "mount failed"
452                 cat $tmp_dir/mnt.err >&2
453                 rm -f $tmp_dir/mnt.err
454                 return $status
455         fi
456         rm -f $tmp_dir/mnt.err
457
458         file_size=$((16*1024*1024*1024*1024 - 4096))
459         nfiles=0
460         while [ $space_to_consume -gt $file_size ]; do
461
462                 xfs_io -F -f \
463                         -c "truncate $file_size" \
464                         -c "falloc -k 0 $file_size" \
465                         $SCRATCH_MNT/.use_space.$nfiles 2>&1
466                 status=$?
467                 if [ $status -ne 0 ]; then
468                         break;
469                 fi
470
471                 space_to_consume=$(( $space_to_consume - $file_size ))
472                 nfiles=$(($nfiles + 1))
473         done
474
475         # consume the remaining space.
476         if [ $space_to_consume -gt 0 ]; then
477                 xfs_io -F -f \
478                         -c "truncate $space_to_consume" \
479                         -c "falloc -k 0 $space_to_consume" \
480                         $SCRATCH_MNT/.use_space.$nfiles 2>&1
481                 status=$?
482         fi
483         export NUM_SPACE_FILES=$nfiles
484
485         umount $SCRATCH_MNT
486         if [ $status -ne 0 ]; then
487                 echo "large file prealloc failed"
488                 cat $tmp_dir/mnt.err >&2
489                 return $status
490         fi
491         return 0
492 }
493 _scratch_mkfs_ext4()
494 {
495         local tmp_dir=/tmp/
496
497         /sbin/mkfs -t $FSTYP -- -F $MKFS_OPTIONS $* $SCRATCH_DEV \
498                         2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd
499         local mkfs_status=$?
500
501         if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then
502                 # manually parse the mkfs output to get the fs size in bytes
503                 fs_size=`cat $tmp_dir.mkfsstd | awk ' \
504                         /^Block size/ { split($2, a, "="); bs = a[2] ; } \
505                         / inodes, / { blks = $3 } \
506                         /reserved for the super user/ { resv = $1 } \
507                         END { fssize = bs * blks - resv; print fssize }'`
508
509                 _setup_large_ext4_fs $fs_size
510                 mkfs_status=$?
511         fi
512
513         # output stored mkfs output
514         cat $tmp_dir.mkfserr >&2
515         cat $tmp_dir.mkfsstd
516         rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd
517
518         return $mkfs_status
519 }
520
521 _scratch_mkfs()
522 {
523     case $FSTYP in
524     xfs)
525         _scratch_mkfs_xfs $*
526         ;;
527     nfs*)
528         # do nothing for nfs
529         ;;
530     udf)
531         $MKFS_UDF_PROG $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
532         ;;
533     btrfs)
534         $MKFS_BTRFS_PROG $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
535         ;;
536     ext4)
537         _scratch_mkfs_ext4 $*
538         ;;
539     *)
540         yes | $MKFS_PROG -t $FSTYP -- $MKFS_OPTIONS $* $SCRATCH_DEV
541         ;;
542     esac
543 }
544
545 # Create fs of certain size on scratch device
546 # _scratch_mkfs_sized <size in bytes> [optional blocksize]
547 _scratch_mkfs_sized()
548 {
549     fssize=$1
550     blocksize=$2
551     [ -z "$blocksize" ] && blocksize=4096
552     blocks=`expr $fssize / $blocksize`
553
554     if [ "$HOSTOS" == "Linux" ]; then
555         devsize=`blockdev --getsize64 $SCRATCH_DEV`
556         [ "$fssize" -gt "$devsize" ] && _notrun "Scratch device too small"
557     fi
558
559     case $FSTYP in
560     xfs)
561         _scratch_mkfs_xfs -d size=$fssize -b size=$blocksize
562         ;;
563     ext2|ext3|ext4|ext4dev)
564         yes | ${MKFS_PROG}.$FSTYP $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
565         ;;
566     btrfs)
567         $MKFS_BTRFS_PROG $MKFS_OPTIONS -b $fssize $SCRATCH_DEV
568         ;;
569     *)
570         _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
571         ;;
572     esac
573 }
574
575 # Emulate an N-data-disk stripe w/ various stripe units
576 # _scratch_mkfs_geom <sunit bytes> <swidth multiplier> [optional blocksize]
577 _scratch_mkfs_geom()
578 {
579     sunit_bytes=$1
580     swidth_mult=$2
581     blocksize=$3
582     [ -z "$blocksize" ] && blocksize=4096
583
584     let sunit_blocks=$sunit_bytes/$blocksize
585     let swidth_blocks=$sunit_blocks*$swidth_mult
586
587     case $FSTYP in
588     xfs)
589         MKFS_OPTIONS+=" -b size=$blocksize, -d su=$sunit_bytes,sw=$swidth_mult"
590         ;;
591     ext4|ext4dev)
592         MKFS_OPTIONS+=" -b $blocksize -E stride=$sunit_blocks,stripe_width=$swidth_blocks"
593         ;;
594     *)
595         _notrun "can't mkfs $FSTYP with geometry"
596         ;;
597     esac
598     _scratch_mkfs
599 }
600
601 _scratch_resvblks()
602 {
603         case $FSTYP in
604         xfs)
605                 xfs_io -x -c "resblks $1" $SCRATCH_MNT
606                 ;;
607         *)
608                 ;;
609         esac
610 }
611
612 _scratch_xfs_db_options()
613 {
614     SCRATCH_OPTIONS=""
615     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
616         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
617     echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
618 }
619
620 _scratch_xfs_logprint()
621 {
622     SCRATCH_OPTIONS=""
623     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
624         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
625     $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
626 }
627
628 _scratch_xfs_check()
629 {
630     SCRATCH_OPTIONS=""
631     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
632         SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
633     [ "$LARGE_SCRATCH_DEV" = yes ] && \
634         SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
635     _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
636 }
637
638 _scratch_xfs_repair()
639 {
640     SCRATCH_OPTIONS=""
641     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
642         SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
643     [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
644         SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV"
645     [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
646     $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV
647 }
648
649 _get_pids_by_name()
650 {
651     if [ $# -ne 1 ]
652     then
653         echo "Usage: _get_pids_by_name process-name" 1>&2
654         exit 1
655     fi
656
657     # Algorithm ... all ps(1) variants have a time of the form MM:SS or
658     # HH:MM:SS before the psargs field, use this as the search anchor.
659     #
660     # Matches with $1 (process-name) occur if the first psarg is $1
661     # or ends in /$1 ... the matching uses sed's regular expressions,
662     # so passing a regex into $1 will work.
663
664     ps $PS_ALL_FLAGS \
665     | sed -n \
666         -e 's/$/ /' \
667         -e 's/[         ][      ]*/ /g' \
668         -e 's/^ //' \
669         -e 's/^[^ ]* //' \
670         -e "/[0-9]:[0-9][0-9]  *[^ ]*\/$1 /s/ .*//p" \
671         -e "/[0-9]:[0-9][0-9]  *$1 /s/ .*//p"
672 }
673
674 # fix malloc libs output
675 #
676 _fix_malloc()
677 {
678     # filter out the Electric Fence notice
679     $PERL_PROG -e '
680         while (<>) {
681             if (defined $o && /^\s+Electric Fence/) {
682                 chomp($o);
683                 print "$o";
684                 undef $o;
685                 next;
686             }
687             print $o if (defined $o);
688
689             $o=$_;
690         }
691         print $o if (defined $o);
692     '
693 }
694
695 # check if run as root
696 #
697 _need_to_be_root()
698 {
699     id=`id | $SED_PROG -e 's/(.*//' -e 's/.*=//'`
700     if [ "$id" -ne 0 ]
701     then
702         echo "Arrgh ... you need to be root (not uid=$id) to run this test"
703         exit 1
704     fi
705 }
706
707
708 #
709 # _df_device : get an IRIX style df line for a given device
710 #
711 #       - returns "" if not mounted
712 #       - returns fs type in field two (ala IRIX)
713 #       - joins line together if split by fancy df formatting
714 #       - strips header etc
715 #
716
717 _df_device()
718 {
719     if [ $# -ne 1 ]
720     then
721         echo "Usage: _df_device device" 1>&2
722         exit 1
723     fi
724
725     $DF_PROG 2>/dev/null | $AWK_PROG -v what=$1 '
726         match($1,what) && NF==1 {
727             v=$1
728             getline
729             print v, $0
730             exit
731         }
732         match($1,what) {
733             print
734             exit
735         }
736     '
737 }
738
739 #
740 # _df_dir : get an IRIX style df line for device where a directory resides
741 #
742 #       - returns fs type in field two (ala IRIX)
743 #       - joins line together if split by fancy df formatting
744 #       - strips header etc
745 #
746
747 _df_dir()
748 {
749     if [ $# -ne 1 ]
750     then
751         echo "Usage: _df_dir device" 1>&2
752         exit 1
753     fi
754
755     $DF_PROG $1 2>/dev/null | $AWK_PROG -v what=$1 '
756         NR == 2 && NF==1 {
757             v=$1
758             getline
759             print v, $0;
760             exit 0
761         }
762         NR == 2 {
763             print;
764             exit 0
765         }
766         {}
767     '
768     # otherwise, nada
769 }
770
771 # return percentage used disk space for mounted device
772
773 _used()
774 {
775     if [ $# -ne 1 ]
776     then
777         echo "Usage: _used device" 1>&2
778         exit 1
779     fi
780
781     _df_device $1 | $AWK_PROG '{ sub("%", "") ; print $6 }'
782 }
783
784 # return the FS type of a mounted device
785 #
786 _fs_type()
787 {
788     if [ $# -ne 1 ]
789     then
790         echo "Usage: _fs_type device" 1>&2
791         exit 1
792     fi
793
794     #
795     # The Linux kernel shows NFSv4 filesystems in df output as
796     # filesystem type nfs4, although we mounted it as nfs earlier.
797     # Fix the filesystem type up here so that the callers don't
798     # have to bother with this quirk.
799     #
800     _df_device $1 | $AWK_PROG '{ print $2 }' | sed -e 's/nfs4/nfs/'
801 }
802
803 # return the FS mount options of a mounted device
804 #
805 # should write a version which just parses the output of mount for IRIX
806 # compatibility, but since this isn't used at all, at the moment I'll leave
807 # this for now
808 #
809 _fs_options()
810 {
811     if [ $# -ne 1 ]
812     then
813         echo "Usage: _fs_options device" 1>&2
814         exit 1
815     fi
816
817     $AWK_PROG -v dev=$1 '
818         match($1,dev) { print $4 }
819     ' </proc/mounts
820 }
821
822 # returns device number if a file is a block device
823 #
824 _is_block_dev()
825 {
826     if [ $# -ne 1 ]
827     then
828         echo "Usage: _is_block_dev dev" 1>&2
829         exit 1
830     fi
831
832     _dev=$1
833     if [ -L "${_dev}" ]; then
834         _dev=`readlink -f ${_dev}`
835     fi
836
837     if [ -b "${_dev}" ]; then
838         src/lstat64 ${_dev} | $AWK_PROG '/Device type:/ { print $9 }'
839     fi
840 }
841
842 # Do a command, log it to $seqres.full, optionally test return status
843 # and die if command fails. If called with one argument _do executes the
844 # command, logs it, and returns its exit status. With two arguments _do
845 # first prints the message passed in the first argument, and then "done"
846 # or "fail" depending on the return status of the command passed in the
847 # second argument. If the command fails and the variable _do_die_on_error
848 # is set to "always" or the two argument form is used and _do_die_on_error
849 # is set to "message_only" _do will print an error message to
850 # $seqres.out and exit.
851
852 _do()
853 {
854     if [ $# -eq 1 ]; then
855         _cmd=$1
856     elif [ $# -eq 2 ]; then
857         _note=$1
858         _cmd=$2
859         echo -n "$_note... "
860     else
861         echo "Usage: _do [note] cmd" 1>&2
862         status=1; exit
863     fi
864
865     (eval "echo '---' \"$_cmd\"") >>$seqres.full
866     (eval "$_cmd") >$tmp._out 2>&1; ret=$?
867     cat $tmp._out | _fix_malloc >>$seqres.full
868     if [ $# -eq 2 ]; then
869         if [ $ret -eq 0 ]; then
870             echo "done"
871         else
872             echo "fail"
873         fi
874     fi
875     if [ $ret -ne 0  ] \
876         && [ "$_do_die_on_error" = "always" \
877             -o \( $# -eq 2 -a "$_do_die_on_error" = "message_only" \) ]
878     then
879         [ $# -ne 2 ] && echo
880         eval "echo \"$_cmd\" failed \(returned $ret\): see $seqres.full"
881         status=1; exit
882     fi
883
884     return $ret
885 }
886
887 # bail out, setting up .notrun file
888 #
889 _notrun()
890 {
891     echo "$*" > $seqres.notrun
892     echo "$seq not run: $*"
893     status=0
894     exit
895 }
896
897 # just plain bail out
898 #
899 _fail()
900 {
901     echo "$*" | tee -a $seqres.full
902     echo "(see $seqres.full for details)"
903     status=1
904     exit 1
905 }
906
907 # tests whether $FSTYP is one of the supported filesystems for a test
908 #
909 _supported_fs()
910 {
911     for f
912     do
913         if [ "$f" = "$FSTYP" -o "$f" = "generic" ]
914         then
915             return
916         fi
917     done
918
919     _notrun "not suitable for this filesystem type: $FSTYP"
920 }
921
922 # tests whether $FSTYP is one of the supported OSes for a test
923 #
924 _supported_os()
925 {
926     for h
927     do
928         if [ "$h" = "$HOSTOS" ]
929         then
930             return
931         fi
932     done
933
934     _notrun "not suitable for this OS: $HOSTOS"
935 }
936
937 # this test needs a scratch partition - check we're ok & unmount it
938 #
939 _require_scratch()
940 {
941     case "$FSTYP" in
942         nfs*)
943                  echo $SCRATCH_DEV | grep -q ":" > /dev/null 2>&1
944                  if [ -z "$SCRATCH_DEV" -o "$?" != "0" ]
945                  then
946                      _notrun "this test requires a valid \$SCRATCH_DEV"
947                  fi
948                  ;;
949         *)
950                  if [ -z "$SCRATCH_DEV" -o "`_is_block_dev $SCRATCH_DEV`" = "" ]
951                  then
952                      _notrun "this test requires a valid \$SCRATCH_DEV"
953                  fi
954                  if [ "`_is_block_dev $SCRATCH_DEV`" = "`_is_block_dev $TEST_DEV`" ]
955                  then
956                      _notrun "this test requires a valid \$SCRATCH_DEV"
957                  fi
958                 if [ ! -d "$SCRATCH_MNT" ]
959                 then
960                      _notrun "this test requires a valid \$SCRATCH_MNT"
961                 fi
962                  ;;
963     esac
964
965     # mounted?
966     if _mount | grep -q $SCRATCH_DEV
967     then
968         # if it's mounted, make sure its on $SCRATCH_MNT
969         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
970         then
971             echo "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
972             exit 1
973         fi
974         # and then unmount it
975         if ! $UMOUNT_PROG $SCRATCH_DEV
976         then
977             echo "failed to unmount $SCRATCH_DEV"
978             exit 1
979         fi
980     fi
981 }
982
983 # this test needs a logdev
984 #
985 _require_logdev()
986 {
987     [ -z "$SCRATCH_LOGDEV" -o ! -b "$SCRATCH_LOGDEV" ] && \
988         _notrun "This test requires a valid \$SCRATCH_LOGDEV"
989     [ "$USE_EXTERNAL" != yes ] && \
990         _notrun "This test requires USE_EXTERNAL to be enabled"
991
992     # ensure its not mounted
993     $UMOUNT_PROG $SCRATCH_LOGDEV 2>/dev/null
994 }
995
996 # this test requires loopback device support
997 #
998 _require_loop()
999 {
1000     if [ "$HOSTOS" != "Linux" ]
1001     then
1002         _notrun "This test requires linux for loopback device support"
1003     fi
1004
1005     modprobe loop >/dev/null 2>&1
1006     if grep loop /proc/devices >/dev/null 2>&1
1007     then
1008         :
1009     else
1010         _notrun "This test requires loopback device support"
1011     fi
1012 }
1013
1014 # this test requires ext2 filesystem support
1015 #
1016 _require_ext2()
1017 {
1018     if [ "$HOSTOS" != "Linux" ]
1019     then
1020         _notrun "This test requires linux for ext2 filesystem support"
1021     fi
1022
1023     modprobe ext2 >/dev/null 2>&1
1024     if grep ext2 /proc/filesystems >/dev/null 2>&1
1025     then
1026         :
1027     else
1028         _notrun "This test requires ext2 filesystem support"
1029     fi
1030 }
1031
1032 # this test requires that (large) loopback device files are not in use
1033 #
1034 _require_no_large_scratch_dev()
1035 {
1036     [ "$LARGE_SCRATCH_DEV" = yes ] && \
1037         _notrun "Large filesystem testing in progress, skipped this test"
1038 }
1039
1040 # this test requires that a realtime subvolume is in use, and
1041 # that the kernel supports realtime as well.
1042 #
1043 _require_realtime()
1044 {
1045     [ "$USE_EXTERNAL" = yes ] || \
1046         _notrun "External volumes not in use, skipped this test"
1047     [ "$SCRATCH_RTDEV" = "" ] && \
1048         _notrun "Realtime device required, skipped this test"
1049 }
1050
1051 # this test requires that a specified command (executable) exists
1052 # $1 - command, $2 - name for error message
1053 #
1054 _require_command()
1055 {
1056     [ -n "$1" ] && _cmd="$1" || _cmd="$2"
1057     [ -n "$1" -a -x "$1" ] || _notrun "$_cmd utility required, skipped this test"
1058 }
1059
1060 # this test requires the device mapper flakey target
1061 #
1062 _require_dm_flakey()
1063 {
1064     _require_command $DMSETUP_PROG
1065
1066     modprobe dm-flakey >/dev/null 2>&1
1067     $DMSETUP_PROG targets | grep flakey >/dev/null 2>&1
1068     if [ $? -eq 0 ]
1069     then
1070         :
1071     else
1072         _notrun "This test requires dm flakey support"
1073     fi
1074 }
1075
1076 # this test requires the projid32bit feature to be available in
1077 # mkfs.xfs
1078 #
1079 _require_projid32bit()
1080 {
1081         _scratch_mkfs_xfs -f -i projid32bit=0 2>&1 >/dev/null \
1082            || _notrun "mkfs.xfs doesn't have projid32bit feature"
1083 }
1084
1085 # this test requires that external log/realtime devices are not in use
1086 #
1087 _require_nonexternal()
1088 {
1089     [ "$USE_EXTERNAL" = yes ] && \
1090         _notrun "External device testing in progress, skipped this test"
1091 }
1092
1093 # this test requires that a (specified) aio-dio executable exists
1094 # $1 - command (optional)
1095 #
1096 _require_aiodio()
1097 {
1098     if [ -z "$1" ]
1099     then
1100         AIO_TEST=src/aio-dio-regress/aiodio_sparse2
1101         [ -x $AIO_TEST ] || _notrun "aio-dio utilities required"
1102     else
1103         AIO_TEST=src/aio-dio-regress/$1
1104         [ -x $AIO_TEST ] || _notrun "$AIO_TEST not built"
1105     fi
1106 }
1107
1108 # run an aio-dio program
1109 # $1 - command
1110 _run_aiodio()
1111 {
1112     if [ -z "$1" ]
1113     then
1114         echo "usage: _run_aiodio command_name" 2>&1
1115         status=1; exit 1
1116     fi
1117
1118     _require_aiodio $1
1119
1120     local testtemp=$TEST_DIR/aio-testfile
1121     rm -f $testtemp
1122     $AIO_TEST $testtemp 2>&1
1123     status=$?
1124     rm -f $testtemp
1125
1126     return $status
1127 }
1128
1129 # indicate whether YP/NIS is active or not
1130 #
1131 _yp_active()
1132 {
1133         local dn
1134         dn=$(domainname 2>/dev/null)
1135         test -n "${dn}" -a "${dn}" != "(none)"
1136         echo $?
1137 }
1138
1139 # cat the password file
1140 #
1141 _cat_passwd()
1142 {
1143         [ $(_yp_active) -eq 0 ] && ypcat passwd
1144         cat /etc/passwd
1145 }
1146
1147 # cat the group file
1148 #
1149 _cat_group()
1150 {
1151         [ $(_yp_active) -eq 0 ] && ypcat group
1152         cat /etc/group
1153 }
1154
1155 # check for the fsgqa user on the machine
1156 #
1157 _require_user()
1158 {
1159     qa_user=fsgqa
1160     _cat_passwd | grep -q $qa_user
1161     [ "$?" == "0" ] || _notrun "$qa_user user not defined."
1162     echo /bin/true | su $qa_user
1163     [ "$?" == "0" ] || _notrun "$qa_user cannot execute commands."
1164 }
1165
1166 # check for the fsgqa group on the machine
1167 #
1168 _require_group()
1169 {
1170     qa_group=fsgqa
1171     _cat_group | grep -q $qa_group
1172     [ "$?" == "0" ] || _notrun "$qa_group user not defined."
1173 }
1174
1175 _filter_user_do()
1176 {
1177         perl -ne "
1178 s,.*Permission\sdenied.*,Permission denied,;
1179 s,.*no\saccess\sto\stty.*,,;
1180 s,.*no\sjob\scontrol\sin\sthis\sshell.*,,;
1181 s,^\s*$,,;
1182         print;"
1183 }
1184
1185 _user_do()
1186 {
1187     if [ "$HOSTOS" == "IRIX" ]
1188         then
1189         echo $1 | /bin/bash "su $qa_user 2>&1" | _filter_user_do
1190     else
1191         echo $1 | su $qa_user 2>&1 | _filter_user_do
1192     fi
1193 }
1194
1195 # check that xfs_io, kernel, and filesystem all support zero
1196 _require_xfs_io_zero()
1197 {
1198         testio=`$XFS_IO_PROG -c "zero help" 2>&1`
1199         echo $testio | grep -q 'command "zero" not found' && \
1200                 _notrun "zero command not supported"
1201 }
1202
1203 # check that xfs_io, glibc, kernel, and filesystem all (!) support
1204 # fallocate
1205 #
1206 _require_xfs_io_falloc()
1207 {
1208         testfile=$TEST_DIR/$$.falloc
1209         testio=`$XFS_IO_PROG -F -f -c "falloc 0 1m" $testfile 2>&1`
1210         rm -f $testfile 2>&1 > /dev/null
1211         echo $testio | grep -q "not found" && \
1212                 _notrun "xfs_io fallocate support is missing"
1213         echo $testio | grep -q "Operation not supported" && \
1214                 _notrun "xfs_io fallocate command failed (old kernel/wrong fs?)"
1215 }
1216
1217 # check that xfs_io, kernel and filesystem all support fallocate with hole
1218 # punching
1219 _require_xfs_io_falloc_punch()
1220 {
1221         testfile=$TEST_DIR/$$.falloc
1222         testio=`$XFS_IO_PROG -F -f -c "pwrite 0 20k" -c "fsync" \
1223                 -c "fpunch 4k 8k" $testfile 2>&1`
1224         rm -f $testfile 2>&1 > /dev/null
1225         echo $testio | grep -q "not found" && \
1226                 _notrun "xfs_io fallocate punch support is missing"
1227         echo $testio | grep -q "Operation not supported" && \
1228                 _notrun "xfs_io fallocate punch command failed (no fs support?)"
1229 }
1230
1231 # check that xfs_io, kernel and filesystem support fiemap
1232 _require_xfs_io_fiemap()
1233 {
1234         testfile=$TEST_DIR/$$.fiemap
1235         testio=`$XFS_IO_PROG -F -f -c "pwrite 0 20k" -c "fsync" \
1236                 -c "fiemap -v" $testfile 2>&1`
1237         rm -f $testfile 2>&1 > /dev/null
1238         echo $testio | grep -q "not found" && \
1239                 _notrun "xfs_io fiemap support is missing"
1240         echo $testio | grep -q "Operation not supported" && \
1241                 _notrun "xfs_io fiemap command failed (no fs support?)"
1242 }
1243
1244 # Check that a fs has enough free space (in 1024b blocks)
1245 #
1246 _require_fs_space()
1247 {
1248         MNT=$1
1249         BLOCKS=$2       # in units of 1024
1250         let GB=$BLOCKS/1024/1024
1251
1252         FREE_BLOCKS=`df -klP $MNT | grep -v Filesystem | awk '{print $4}'`
1253         [ $FREE_BLOCKS -lt $BLOCKS ] && \
1254                 _notrun "This test requires at least ${GB}GB free on $MNT to run"
1255 }
1256
1257 #
1258 # Check if the filesystem supports sparse files.
1259 #
1260 # Unfortunately there is no better way to do this than a manual black list.
1261 #
1262 _require_sparse_files()
1263 {
1264     case $FSTYP in
1265     hfsplus)
1266         _notrun "Sparse files not supported by this filesystem type: $FSTYP"
1267         ;;
1268     *)
1269         ;;
1270     esac
1271 }
1272
1273 _require_debugfs()
1274 {
1275     #boot_params always present in debugfs
1276     [ -d "$DEBUGFS_MNT/boot_params" ] || _notrun "Debugfs not mounted"
1277 }
1278
1279 _require_fail_make_request()
1280 {
1281     [ -f "$DEBUGFS_MNT/fail_make_request/probability" ] \
1282         || _notrun "$DEBUGFS_MNT/fail_make_request \
1283  not found. Seems that CONFIG_FAIL_MAKE_REQUEST kernel config option not enabled"
1284 }
1285
1286 # check that a FS on a device is mounted
1287 # if so, return mount point
1288 #
1289 _is_mounted()
1290 {
1291     if [ $# -ne 1 ]
1292     then
1293         echo "Usage: _is_mounted device" 1>&2
1294         exit 1
1295     fi
1296
1297     device=$1
1298
1299     if _mount | grep "$device " | $AWK_PROG -v pattern="type $FSTYP" '
1300         pattern        { print $3 ; exit 0 }
1301         END            { exit 1 }
1302     '
1303     then
1304         echo "_is_mounted: $device is not a mounted $FSTYP FS"
1305         exit 1
1306     fi
1307 }
1308
1309 # remount a FS to a new mode (ro or rw)
1310 #
1311 _remount()
1312 {
1313     if [ $# -ne 2 ]
1314     then
1315         echo "Usage: _remount device ro/rw" 1>&2
1316         exit 1
1317     fi
1318     device=$1
1319     mode=$2
1320
1321     if ! mount -o remount,$mode $device
1322     then
1323         echo "_remount: failed to remount filesystem on $device as $mode"
1324         exit 1
1325     fi
1326 }
1327
1328 # Run the appropriate repair/check on a filesystem
1329 #
1330 # if the filesystem is mounted, it's either remounted ro before being
1331 # checked or it's unmounted and then remounted
1332 #
1333
1334 # If set, we remount ro instead of unmounting for fsck
1335 USE_REMOUNT=0
1336
1337 _umount_or_remount_ro()
1338 {
1339     if [ $# -ne 1 ]
1340     then
1341         echo "Usage: _umount_or_remount_ro <device>" 1>&2
1342         exit 1
1343     fi
1344
1345     device=$1
1346     mountpoint=`_is_mounted $device`
1347
1348     if [ $USE_REMOUNT -eq 0 ]; then
1349         $UMOUNT_PROG $device
1350     else
1351         _remount $device ro
1352     fi
1353     echo "$mountpoint"
1354 }
1355
1356 _mount_or_remount_rw()
1357 {
1358     if [ $# -ne 3 ]
1359     then
1360         echo "Usage: _mount_or_remount_rw <opts> <device> <mountpoint>" 1>&2
1361         exit 1
1362     fi
1363     mount_opts=$1
1364     device=$2
1365     mountpoint=$3
1366
1367     if [ $USE_REMOUNT -eq 0 ]
1368     then
1369         if ! _mount -t $FSTYP $mount_opts $device $mountpoint
1370         then
1371             echo "!!! failed to remount $device on $mountpoint"
1372             return 0 # ok=0
1373         fi
1374     else
1375         _remount $device rw
1376     fi
1377
1378     return 1 # ok=1
1379 }
1380
1381 # Check a generic filesystem in no-op mode; this assumes that the
1382 # underlying fsck program accepts "-n" for a no-op (check-only) run,
1383 # and that it will still return an errno for corruption in this mode.
1384 #
1385 # Filesystems which don't support this will need to define their
1386 # own check routine.
1387 #
1388 _check_generic_filesystem()
1389 {
1390     device=$1
1391
1392     # If type is set, we're mounted
1393     type=`_fs_type $device`
1394     ok=1
1395
1396     if [ "$type" = "$FSTYP" ]
1397     then
1398         # mounted ...
1399         mountpoint=`_umount_or_remount_ro $device`
1400     fi
1401
1402     fsck -t $FSTYP $FSCK_OPTIONS $device >$tmp.fsck 2>&1
1403     if [ $? -ne 0 ]
1404     then
1405         echo "_check_generic_filesystem: filesystem on $device is inconsistent (see $seqres.full)"
1406
1407         echo "_check_generic filesystem: filesystem on $device is inconsistent" >>$seqres.full
1408         echo "*** fsck.$FSTYP output ***"       >>$seqres.full
1409         cat $tmp.fsck                           >>$seqres.full
1410         echo "*** end fsck.$FSTYP output"       >>$seqres.full
1411
1412         ok=0
1413     fi
1414     rm -f $tmp.fsck
1415
1416     if [ $ok -eq 0 ]
1417     then
1418         echo "*** mount output ***"             >>$seqres.full
1419         _mount                                  >>$seqres.full
1420         echo "*** end mount output"             >>$seqres.full
1421     elif [ "$type" = "$FSTYP" ]
1422     then
1423         # was mounted ...
1424         _mount_or_remount_rw "$MOUNT_OPTIONS" $device $mountpoint
1425         ok=$?
1426     fi
1427
1428     if [ $ok -eq 0 ]; then
1429         status=1
1430         exit 1
1431     fi
1432
1433     return 0
1434 }
1435
1436 # run xfs_check and friends on a FS.
1437
1438 _check_xfs_filesystem()
1439 {
1440     if [ $# -ne 3 ]
1441     then
1442         echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2
1443         exit 1
1444     fi
1445
1446     extra_mount_options=""
1447     device=$1
1448     if [ "$2" != "none" ]; then
1449         extra_log_options="-l$2"
1450         extra_mount_options="-ologdev=$2"
1451     fi
1452
1453     if [ "$3" != "none" ]; then
1454         extra_rt_options="-r$3"
1455         extra_mount_options=$extra_mount_options" -ortdev=$3"
1456     fi
1457     extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
1458
1459     [ "$FSTYP" != xfs ] && return 0
1460
1461     type=`_fs_type $device`
1462     ok=1
1463
1464     if [ "$type" = "xfs" ]
1465     then
1466         # mounted ...
1467         mountpoint=`_umount_or_remount_ro $device`
1468     fi
1469
1470     $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \
1471                 | tee $tmp.logprint | grep -q "<CLEAN>"
1472     if [ $? -ne 0 -a "$HOSTOS" = "Linux" ]
1473     then
1474         echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)"
1475
1476         echo "_check_xfs_filesystem: filesystem on $device has dirty log"   >>$seqres.full
1477         echo "*** xfs_logprint -t output ***"   >>$seqres.full
1478         cat $tmp.logprint                       >>$seqres.full
1479         echo "*** end xfs_logprint output"      >>$seqres.full
1480
1481         ok=0
1482     fi
1483
1484     # xfs_check runs out of memory on large files, so even providing the test
1485     # option (-t) to avoid indexing the free space trees doesn't make it pass on
1486     # large filesystems. Avoid it.
1487     if [ "$LARGE_SCRATCH_DEV" != yes ]; then
1488             _xfs_check $extra_log_options $device 2>&1 |\
1489                  _fix_malloc >$tmp.fs_check
1490     fi
1491     if [ -s $tmp.fs_check ]
1492     then
1493         echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)"
1494
1495         echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
1496         echo "*** xfs_check output ***"         >>$seqres.full
1497         cat $tmp.fs_check                       >>$seqres.full
1498         echo "*** end xfs_check output"         >>$seqres.full
1499
1500         ok=0
1501     fi
1502
1503     $XFS_REPAIR_PROG -n $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
1504     if [ $? -ne 0 ]
1505     then
1506         echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)"
1507
1508         echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
1509         echo "*** xfs_repair -n output ***"     >>$seqres.full
1510         cat $tmp.repair | _fix_malloc           >>$seqres.full
1511         echo "*** end xfs_repair output"        >>$seqres.full
1512
1513         ok=0
1514     fi
1515     rm -f $tmp.fs_check $tmp.logprint $tmp.repair
1516
1517     if [ $ok -eq 0 ]
1518     then
1519         echo "*** mount output ***"             >>$seqres.full
1520         _mount                                  >>$seqres.full
1521         echo "*** end mount output"             >>$seqres.full
1522     elif [ "$type" = "xfs" ]
1523     then
1524         _mount_or_remount_rw "$extra_mount_options" $device $mountpoint
1525     fi
1526
1527     if [ $ok -eq 0 ]; then
1528         status=1
1529         exit 1
1530     fi
1531
1532     return 0
1533 }
1534
1535 # Filter the knowen errors the UDF Verifier reports.
1536 _udf_test_known_error_filter()
1537 {
1538         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."
1539
1540 }
1541
1542 _check_udf_filesystem()
1543 {
1544     [ "$DISABLE_UDF_TEST" == "1" ] && return
1545
1546     if [ $# -ne 1 -a $# -ne 2 ]
1547     then
1548         echo "Usage: _check_udf_filesystem device [last_block]" 1>&2
1549         exit 1
1550     fi
1551
1552     if [ ! -x $here/src/udf_test ]
1553     then
1554         echo "udf_test not installed, please download and build the Philips"
1555         echo "UDF Verification Software from http://www.extra.research.philips.com/udf/."
1556         echo "Then copy the udf_test binary to $here/src/."
1557         echo "If you do not wish to run udf_test then set environment variable DISABLE_UDF_TEST"
1558         echo "to 1."
1559         return
1560     fi
1561
1562     device=$1
1563     if [ $# -eq 2 ];
1564     then
1565         LAST_BLOCK=`expr \( $2 - 1 \)`
1566         OPT_ARG="-lastvalidblock $LAST_BLOCK"
1567     fi
1568
1569     rm -f $seqres.checkfs
1570     sleep 1 # Due to a problem with time stamps in udf_test
1571     $here/src/udf_test $OPT_ARG $device | tee $seqres.checkfs | egrep "Error|Warning" | \
1572         _udf_test_known_error_filter | \
1573         egrep -iv "Error count:.*[0-9]+.*total occurrences:.*[0-9]+|Warning count:.*[0-9]+.*total occurrences:.*[0-9]+" | \
1574         sed "s/^.*$/Warning UDF Verifier reported errors see $seqres.checkfs./g"
1575
1576 }
1577
1578 _check_xfs_test_fs()
1579 {
1580     TEST_LOG="none"
1581     TEST_RT="none"
1582     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
1583         TEST_LOG="$TEST_LOGDEV"
1584
1585     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
1586         TEST_RT="$TEST_RTDEV"
1587
1588     _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT
1589
1590     # check for ipath consistency
1591     if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then
1592         # errors go to stderr
1593         xfs_check_ipaths $TEST_DIR >/dev/null
1594         xfs_repair_ipaths -n $TEST_DIR >/dev/null
1595     fi
1596 }
1597
1598 _check_btrfs_filesystem()
1599 {
1600     device=$1
1601
1602     # If type is set, we're mounted
1603     type=`_fs_type $device`
1604     ok=1
1605
1606     if [ "$type" = "$FSTYP" ]
1607     then
1608         # mounted ...
1609         mountpoint=`_umount_or_remount_ro $device`
1610     fi
1611
1612     btrfsck $device >$tmp.fsck 2>&1
1613     if [ $? -ne 0 ]
1614     then
1615         echo "_check_btrfs_filesystem: filesystem on $device is inconsistent (see $seqres.full)"
1616
1617         echo "_check_btrfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full
1618         echo "*** fsck.$FSTYP output ***"       >>$seqres.full
1619         cat $tmp.fsck                           >>$seqres.full
1620         echo "*** end fsck.$FSTYP output"       >>$seqres.full
1621
1622         ok=0
1623     fi
1624     rm -f $tmp.fsck
1625
1626     if [ $ok -eq 0 ]
1627     then
1628         echo "*** mount output ***"             >>$seqres.full
1629         _mount                                  >>$seqres.full
1630         echo "*** end mount output"             >>$seqres.full
1631     elif [ "$type" = "$FSTYP" ]
1632     then
1633         # was mounted ...
1634         _mount_or_remount_rw "$MOUNT_OPTIONS" $device $mountpoint
1635         ok=$?
1636     fi
1637
1638     if [ $ok -eq 0 ]; then
1639         status=1
1640         exit 1
1641     fi
1642
1643     return 0
1644 }
1645
1646 _check_test_fs()
1647 {
1648     case $FSTYP in
1649     xfs)
1650         _check_xfs_test_fs
1651         ;;
1652     nfs)
1653         # no way to check consistency for nfs
1654         ;;
1655     udf)
1656         # do nothing for now
1657         ;;
1658     btrfs)
1659         _check_btrfs_filesystem $TEST_DEV
1660         ;;
1661     *)
1662         _check_generic_filesystem $TEST_DEV
1663         ;;
1664     esac
1665 }
1666
1667 _check_scratch_fs()
1668 {
1669     case $FSTYP in
1670     xfs)
1671         SCRATCH_LOG="none"
1672         SCRATCH_RT="none"
1673         [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
1674             SCRATCH_LOG="$SCRATCH_LOGDEV"
1675
1676         [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
1677             SCRATCH_RT="$SCRATCH_RTDEV"
1678
1679         _check_xfs_filesystem $SCRATCH_DEV $SCRATCH_LOG $SCRATCH_RT
1680         ;;
1681     udf)
1682         _check_udf_filesystem $SCRATCH_DEV $udf_fsize
1683         ;;
1684     nfs*)
1685         # Don't know how to check an NFS filesystem, yet.
1686         ;;
1687     btrfs)
1688         _check_btrfs_filesystem $SCRATCH_DEV
1689         ;;
1690     *)
1691         _check_generic_filesystem $SCRATCH_DEV
1692         ;;
1693     esac
1694 }
1695
1696 _full_fstyp_details()
1697 {
1698      [ -z "$FSTYP" ] && FSTYP=xfs
1699      if [ $FSTYP = xfs ]; then
1700         if [ -d /proc/fs/xfs ]; then
1701             if grep -q 'debug 0' /proc/fs/xfs/stat; then
1702                 FSTYP="$FSTYP (non-debug)"
1703             elif grep -q 'debug 1' /proc/fs/xfs/stat; then
1704                 FSTYP="$FSTYP (debug)"
1705             fi
1706         else
1707             if uname -a | grep -qi 'debug'; then
1708                 FSTYP="$FSTYP (debug)"
1709             else
1710                 FSTYP="$FSTYP (non-debug)"
1711             fi
1712         fi
1713      fi
1714      echo $FSTYP
1715 }
1716
1717 _full_platform_details()
1718 {
1719      os=`uname -s`
1720      host=`hostname -s`
1721      kernel=`uname -r`
1722      platform=`uname -m`
1723      echo "$os/$platform $host $kernel"
1724 }
1725
1726 _setup_udf_scratchdir()
1727 {
1728     [ "$FSTYP" != "udf" ] \
1729         && _fail "setup_udf_testdir: \$FSTYP is not udf"
1730     [ -z "$SCRATCH_DEV" -o ! -b "$SCRATCH_DEV" ] \
1731         && _notrun "this test requires a valid \$SCRATCH_DEV"
1732     [ -z "$SCRATCH_MNT" ] \
1733         && _notrun "this test requires a valid \$SCRATCH_MNT"
1734
1735     # mounted?
1736     if _mount | grep -q $SCRATCH_DEV
1737     then
1738         # if it's mounted, make sure its on $TEST_RW_DIR
1739         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
1740         then
1741             _fail "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
1742         fi
1743         $UMOUNT_PROG $SCRATCH_DEV
1744     fi
1745
1746     _scratch_mkfs
1747     _scratch_mount
1748
1749     testdir=$SCRATCH_MNT
1750 }
1751
1752 _setup_nfs_scratchdir()
1753 {
1754     [ "$FSTYP" != "nfs" ] \
1755         && _fail "setup_nfs_testdir: \$FSTYP is not nfs"
1756     [ -z "$SCRATCH_DEV" ] \
1757         && _notrun "this test requires a valid host fs for \$SCRATCH_DEV"
1758     [ -z "$SCRATCH_MNT" ] \
1759         && _notrun "this test requires a valid \$SCRATCH_MNT"
1760
1761     # mounted?
1762     if _mount | grep -q $SCRATCH_DEV
1763     then
1764         # if it's mounted, make sure its on $SCRATCH_MNT
1765         if ! _mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
1766         then
1767             _fail "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
1768         fi
1769         $UMOUNT_PROG $SCRATCH_DEV
1770     fi
1771
1772     _scratch_mkfs
1773     _scratch_mount
1774
1775     testdir=$SCRATCH_MNT
1776 }
1777
1778 #
1779 # Warning for UDF and NFS:
1780 # this function calls _setup_udf_scratchdir and _setup_udf_scratchdir
1781 # which actually uses the scratch dir for the test dir.
1782 #
1783 # This was done because testdir was intended to be a persistent
1784 # XFS only partition.  This should eventually change, and treat
1785 # at least local filesystems all the same.
1786 #
1787 _setup_testdir()
1788 {
1789     case $FSTYP in
1790     udf)
1791         _setup_udf_scratchdir
1792         ;;
1793     nfs*)
1794         _setup_nfs_scratchdir
1795         ;;
1796     *)
1797         testdir=$TEST_DIR
1798         ;;
1799     esac
1800 }
1801
1802 _cleanup_testdir()
1803 {
1804     case $FSTYP in
1805     udf)
1806         # umount testdir as it is $SCRATCH_MNT which could be used by xfs next
1807         [ -n "$testdir" ] && $UMOUNT_PROG $testdir
1808         ;;
1809     nfs*)
1810         # umount testdir as it is $SCRATCH_MNT which could be used by xfs next
1811         [ -n "$testdir" ] && $UMOUNT_PROG $testdir
1812         ;;
1813     *)
1814         # do nothing, testdir is $TEST_DIR
1815         :
1816         ;;
1817     esac
1818 }
1819
1820 _link_out_file()
1821 {
1822         if [ -z "$1" -o -z "$2" ]; then
1823                 echo Error must pass src and dst.
1824                 exit
1825         fi
1826         rm -f $2
1827         if [ "`uname`" == "IRIX64" ] || [ "`uname`" == "IRIX" ]; then
1828                 ln -s $1.irix $2
1829         elif [ "`uname`" == "Linux" ]; then
1830                 ln -s $1.linux $2
1831         else
1832                 echo Error test $seq does not run on the operating system: `uname`
1833                 exit
1834         fi
1835 }
1836
1837 _die()
1838 {
1839         echo $@
1840         exit 1
1841 }
1842
1843 #takes files, randomdata
1844 _nfiles()
1845 {
1846         f=0
1847         while [ $f -lt $1 ]
1848         do
1849                 file=f$f
1850                 echo > $file
1851                 if [ $size -gt 0 ]; then
1852                     if [ "$2" == "false" ]; then
1853                         dd if=/dev/zero of=$file bs=1024 count=$size 2>&1 | _filter_dd
1854                     else
1855                         dd if=/dev/urandom of=$file bs=1024 count=$size 2>&1 | _filter_dd
1856                     fi
1857                 fi
1858                 let f=$f+1
1859         done
1860 }
1861
1862 # takes dirname, depth, randomdata
1863 _descend()
1864 {
1865         dirname=$1; depth=$2; randomdata=$3
1866         mkdir $dirname  || die "mkdir $dirname failed"
1867         cd $dirname
1868
1869         _nfiles $files $randomdata          # files for this dir and data type
1870
1871         [ $depth -eq 0 ] && return
1872         let deep=$depth-1 # go 1 down
1873
1874         [ $verbose = true ] && echo "descending, depth from leaves = $deep"
1875
1876         d=0
1877         while [ $d -lt $dirs ]
1878         do
1879                 _descend d$d $deep &
1880                 let d=$d+1
1881                 wait
1882         done
1883 }
1884
1885 # Populate a filesystem with inodes for performance experiments
1886 #
1887 # usage: populate [-v] [-n ndirs] [-f nfiles] [-d depth] [-r root] [-s size] [-x]
1888 #
1889 _populate_fs()
1890 {
1891     here=`pwd`
1892     dirs=5          # ndirs in each subdir till leaves
1893     size=0          # sizeof files in K
1894     files=100       # num files in _each_ subdir
1895     depth=2         # depth of tree from root to leaves
1896     verbose=false
1897     root=root       # path of initial root of directory tree
1898     randomdata=false # -x data type urandom or zero
1899
1900     OPTIND=1
1901     while getopts "d:f:n:r:s:v:x" c
1902     do
1903         case $c in
1904         d)      depth=$OPTARG;;
1905         n)      dirs=$OPTARG;;
1906         f)      files=$OPTARG;;
1907         s)      size=$OPTARG;;
1908         v)      verbose=true;;
1909         r)      root=$OPTARG;;
1910         x)      randomdata=true;;
1911         esac
1912     done
1913
1914     _descend $root $depth $randomdata
1915     wait
1916
1917     cd $here
1918
1919     [ $verbose = true ] && echo done
1920 }
1921
1922 # query whether the given file has the given inode flag set
1923 #
1924 _test_inode_flag()
1925 {
1926     flag=$1
1927     file=$2
1928
1929     if which $XFS_IO_PROG >/dev/null; then
1930         if $XFS_IO_PROG -r -c 'lsattr -v' "$file" | grep -q "$flag" ; then
1931             return 0
1932         fi
1933     fi
1934     return 1
1935 }
1936
1937 # query the given files extsize allocator hint in bytes (if any)
1938 #
1939 _test_inode_extsz()
1940 {
1941     file=$1
1942     blocks=""
1943
1944     if which $XFS_IO_PROG >/dev/null; then
1945         blocks=`$XFS_IO_PROG -r -c 'stat' "$file" | \
1946                 awk '/^xattr.extsize =/ { print $3 }'`
1947     fi
1948     [ -z "$blocks" ] && blocks="0"
1949     echo $blocks
1950 }
1951
1952 # scratch_dev_pool should contain the disks pool for the btrfs raid
1953 _require_scratch_dev_pool()
1954 {
1955         local i
1956         if [ -z "$SCRATCH_DEV_POOL" ]; then
1957                 _notrun "this test requires a valid \$SCRATCH_DEV_POOL"
1958         fi
1959
1960         # btrfs test case needs 2 or more scratch_dev_pool; other FS not sure
1961         # so fail it
1962         case $FSTYP in
1963         btrfs)
1964                 if [ "`echo $SCRATCH_DEV_POOL|wc -w`" -lt 2 ]; then
1965                         _notrun "btrfs and this test needs 2 or more disks in SCRATCH_DEV_POOL"
1966                 fi
1967         ;;
1968         *)
1969                 _notrun "dev_pool is not supported by fstype \"$FSTYP\""
1970         ;;
1971         esac
1972
1973         for i in $SCRATCH_DEV_POOL; do
1974                 if [ "`_is_block_dev $i`" = "" ]; then
1975                         _notrun "this test requires valid block disk $i"
1976                 fi
1977                 if [ "`_is_block_dev $i`" = "`_is_block_dev $TEST_DEV`" ]; then
1978                         _notrun "$i is part of TEST_DEV, this test requires unique disks"
1979                 fi
1980                 if _mount | grep -q $i; then
1981                         if ! $UMOUNT_PROG $i; then
1982                             echo "failed to unmount $i - aborting"
1983                             exit 1
1984                         fi
1985                 fi
1986                 # to help better debug when something fails, we remove
1987                 # traces of previous btrfs FS on the dev.
1988                 dd if=/dev/zero of=$i bs=4096 count=100 > /dev/null 2>&1
1989         done
1990 }
1991
1992 # We will check if the device is virtual (eg: loop device) since it does not
1993 # have the delete entry-point. Otherwise SCSI and USB devices are fine. 
1994 _require_deletable_scratch_dev_pool()
1995 {
1996         local i
1997         local x
1998         for i in $SCRATCH_DEV_POOL; do
1999                 x=`echo $i | cut -d"/" -f 3`
2000                 ls -l /sys/class/block/${x} | grep -q "virtual" 
2001                 if [ $? == "0" ]; then
2002                         _notrun "$i is a virtual device which is not deletable"
2003                 fi
2004         done
2005 }
2006
2007 # We check for btrfs and (optionally) features of the btrfs command
2008 _require_btrfs()
2009 {
2010         cmd=$1
2011         _require_command $BTRFS_UTIL_PROG btrfs
2012         if [ -z "$1" ]; then
2013                 return 1;
2014         fi
2015         $BTRFS_UTIL_PROG $cmd --help >/dev/null 2>&1
2016         [ $? -eq 0 ] || _notrun "$BTRFS_UTIL_PROG too old (must support $cmd)"
2017 }
2018
2019 # Check that fio is present, and it is able to execute given jobfile
2020 _require_fio()
2021 {
2022         job=$1
2023
2024         _require_command $FIO_PROG
2025         if [ -z "$1" ]; then
2026                 return 1;
2027         fi
2028
2029         $FIO_PROG --warnings-fatal --showcmd $job >> $seqres.full 2>&1
2030         [ $? -eq 0 ] || _notrun "$FIO_PROG too old, see $seqres.full"
2031 }
2032
2033 # Does freeze work on this fs?
2034 _require_freeze()
2035 {
2036         xfs_freeze -f "$TEST_DIR" >/dev/null 2>&1
2037         result=$? 
2038         xfs_freeze -u "$TEST_DIR" >/dev/null 2>&1
2039         [ $result -eq 0 ] || _notrun "$FSTYP does not support freezing"
2040 }
2041
2042 # arg 1 is dev to remove and is output of the below eg.
2043 # ls -l /sys/class/block/sdd | rev | cut -d "/" -f 3 | rev
2044 _devmgt_remove()
2045 {
2046         echo 1 > /sys/class/scsi_device/${1}/device/delete || _fail "Remove disk failed"
2047 }
2048
2049 # arg 1 is dev to add and is output of the below eg.
2050 # ls -l /sys/class/block/sdd | rev | cut -d "/" -f 3 | rev
2051 _devmgt_add()
2052 {
2053         local h
2054         local tdl
2055         # arg 1 will be in h:t:d:l format now in the h and "t d l" format
2056         h=`echo ${1} | cut -d":" -f 1`
2057         tdl=`echo ${1} | cut -d":" -f 2-|sed 's/:/ /g'`
2058
2059         echo ${tdl} >  /sys/class/scsi_host/host${h}/scan || _fail "Add disk failed"
2060 }
2061
2062 _require_fstrim()
2063 {
2064         if [ -z "$FSTRIM_PROG" ]; then
2065                 _notrun "This test requires fstrim utility."
2066         fi
2067 }
2068
2069 _test_batched_discard()
2070 {
2071         if [ $# -ne 1 ]; then
2072                 echo "Usage: _test_batched_discard mnt_point" 1>&2
2073                 exit 1
2074         fi
2075         _require_fstrim
2076         $FSTRIM_PROG ${1} &>/dev/null
2077 }
2078
2079 _require_dumpe2fs()
2080 {
2081         if [ -z "$DUMPE2FS_PROG" ]; then
2082                 _notrun "This test requires dumpe2fs utility."
2083         fi
2084 }
2085
2086 _create_loop_device()
2087 {
2088         file=$1
2089         dev=`losetup -f --show $file` || _fail "Cannot assign $file to a loop device"
2090         echo $dev
2091 }
2092
2093 _destroy_loop_device()
2094 {
2095         dev=$1
2096         losetup -d $dev || _fail "Cannot destroy loop device $dev"
2097 }
2098
2099 _scale_fsstress_args()
2100 {
2101     args=""
2102     while [ $# -gt 0 ]; do
2103         case "$1" in
2104             -n) args="$args $1 $(($2 * $TIME_FACTOR))"; shift ;;
2105             -p) args="$args $1 $(($2 * $LOAD_FACTOR))"; shift ;;
2106             *) args="$args $1" ;;
2107         esac
2108         shift
2109     done
2110     echo $args
2111 }
2112
2113 run_check()
2114 {
2115         echo "# $@" >> $seqres.full 2>&1
2116         "$@" >> $seqres.full 2>&1 || _fail "failed: '$@'"
2117 }
2118
2119 ################################################################################
2120
2121 if [ "$iam" != new ]
2122 then
2123     # make some further configuration checks here
2124
2125     if [ "$TEST_DEV" = ""  ]
2126     then
2127         echo "common/rc: Error: \$TEST_DEV is not set"
2128         exit 1
2129     fi
2130
2131     # if $TEST_DEV is not mounted, mount it now as XFS
2132     if [ -z "`_fs_type $TEST_DEV`" ]
2133     then
2134         # $TEST_DEV is not mounted
2135         if ! _test_mount
2136         then
2137             echo "common/rc: retrying test device mount with external set"
2138             [ "$USE_EXTERNAL" != "yes" ] && export USE_EXTERNAL=yes
2139             if ! _test_mount
2140             then
2141                 echo "common/rc: could not mount $TEST_DEV on $TEST_DIR"
2142                 exit 1
2143             fi
2144         fi
2145     fi
2146
2147     if [ "`_fs_type $TEST_DEV`" != "$FSTYP" ]
2148     then
2149         echo "common/rc: Error: \$TEST_DEV ($TEST_DEV) is not a MOUNTED $FSTYP filesystem"
2150         $DF_PROG $TEST_DEV
2151         exit 1
2152     fi
2153
2154     # Figure out if we need to add -F ("foreign", deprecated) option to xfs_io
2155     xfs_io -c stat $TEST_DIR 2>&1 | grep -q "is not on an XFS filesystem" && \
2156         export XFS_IO_PROG="$XFS_IO_PROG -F"
2157
2158 fi
2159
2160 # make sure this script returns success
2161 /bin/true