--- /dev/null
+#! /bin/sh
+#
+# XFS QA Test No. 001
+# $Id: 1.1 $
+#
+# Random file copier to produce chains of identical files so the head
+# and the tail cna be diff'd at then end of each iteration.
+#
+# Exercises creat, write and unlink for a variety of directory sizes, and
+# checks for data corruption.
+#
+# run [config]
+#
+# config has one line per file with filename and byte size, else use
+# the default one below.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=kenmcd@bruce.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+tmp=/tmp/$$
+here=`pwd`
+status=1
+done_cleanup=false
+trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# real QA test starts here
+
+verbose=true
+
+if [ $# -eq 0 ]
+then
+ # use the default config
+ #
+ cat <<End-of-File >$tmp.config
+# pathname size in bytes
+#
+small 10
+big 102400
+sub/small 10
+sub/big 102400
+#
+sub/a 1
+sub/b 2
+sub/c 4
+sub/d 8
+sub/e 16
+sub/f 32
+sub/g 64
+sub/h 128
+sub/i 256
+sub/j 512
+sub/k 1024
+sub/l 2048
+sub/m 4096
+sub/n 8192
+#
+sub/a00 100
+sub/b00 200
+sub/c00 400
+sub/d00 800
+sub/e00 1600
+sub/f00 3200
+sub/g00 6400
+sub/h00 12800
+sub/i00 25600
+sub/j00 51200
+sub/k00 102400
+sub/l00 204800
+sub/m00 409600
+sub/n00 819200
+#
+sub/a000 1000
+sub/e000 16000
+sub/h000 128000
+sub/k000 1024000
+End-of-File
+elif [ $# -eq 1 ]
+then
+ if [ -f $1 ]
+ then
+ cp $1 $tmp.config
+ else
+ echo "Error: cannot open config \"$1\""
+ exit 1
+ fi
+else
+ echo "Usage: run [config]"
+ exit 1
+fi
+
+ncopy=200 # number of file copies in the chain step
+
+_setup()
+{
+ if mkdir -p $TEST_DIR/$$
+ then
+ :
+ else
+ echo "Error: cannot mkdir \"$TEST_DIR/$$\""
+ exit 1
+ fi
+ cd $TEST_DIR/$$
+
+ $verbose && echo -n "setup "
+ sed -e '/^#/d' $tmp.config \
+ | while read file nbytes
+ do
+ dir=`dirname $file`
+ if [ "$dir" != "." ]
+ then
+ if [ ! -d $dir ]
+ then
+ if mkdir $dir
+ then
+ :
+ else
+ $verbose && echo
+ echo "Error: cannot mkdir \"$dir\""
+ exit 1
+ fi
+ fi
+ fi
+ rm -f $file
+ if $here/src/fill $file $file $nbytes
+ then
+ :
+ else
+ $verbose && echo
+ echo "Error: cannot create \"$file\""
+ exit 1
+ fi
+ $verbose && echo -n "."
+ done
+ $verbose && echo
+}
+
+_mark_iteration()
+{
+ $verbose && echo -n "mark_iteration "
+ sed -e '/^#/d' $tmp.config \
+ | while read file nbytes
+ do
+ if [ ! -f $file ]
+ then
+ $verbose && echo
+ echo "Error: $file vanished!"
+ touch $tmp.bad
+ continue
+ fi
+ sed -e "s/ [0-9][0-9]* / $1 /" <$file >$file.tmp
+ mv $file.tmp $file
+ $verbose && echo -n "."
+ done
+ $verbose && echo
+}
+
+# for each file, make a number of copies forming a chain like foo.0,
+# foo.1, foo.2, ... foo.N
+#
+# files are chosen at random, so the lengths of the chains are different
+#
+# then rename foo.N to foo.last and remove all of the other files in
+# the chain
+#
+_chain()
+{
+ $AWK_PROG <$tmp.config '
+BEGIN { nfile = 0 }
+/^\#/ { next }
+ { file[nfile] = $1
+ link[nfile] = 0
+ nfile++
+ }
+END { srand('$iter')
+ for (i=0; i < '$ncopy'; i++) {
+ # choose a file at random, and add one copy to that chain
+ j = -1
+ while (j < 0 || j >= nfile)
+ j = int(rand() * nfile)
+ if (link[j] == 0) {
+ printf "if [ ! -f %s ]; then echo \"%s missing!\"; exit; fi\n",file[j],file[j]
+ printf "if [ -f %s.0 ]; then echo \"%s.0 already present!\"; exit; fi\n",file[j],file[j]
+ printf "cp %s %s.0\n",file[j],file[j]
+ }
+ else {
+ printf "if [ ! -f %s.%d ]; then echo \"%s.%d missing!\"; exit; fi\n",file[j],link[j]-1,file[j],link[j]-1
+ printf "if [ -f %s.%d ]; then echo \"%s.%d already present!\"; exit; fi\n",file[j],link[j],file[j],link[j]
+ printf "cp %s.%d %s.%d\n",file[j],link[j]-1,file[j],link[j]
+ }
+ link[j]++
+ }
+ # close all the chains, and remove all of the files except
+ # the head of the chain
+ for (j=0; j<nfile; j++) {
+ if (link[j] > 0)
+ printf "mv %s.%d %s.last\n",file[j],link[j]-1,file[j]
+ for (i=0; i<link[j]-1; i++) {
+ printf "rm -f %s.%d\n",file[j],i
+ }
+ }
+ }' \
+ | sh
+}
+
+_check()
+{
+ rm -f $tmp.bad
+ $verbose && echo -n "check "
+ sed -e '/^#/d' $tmp.config \
+ | while read file nbytes
+ do
+ if [ ! -f $file ]
+ then
+ $verbose && echo
+ echo "Error: $file vanished!"
+ touch $tmp.bad
+ continue
+ fi
+ if [ -f $file.last ]
+ then
+ if cmp $file $file.last >/dev/null 2>&1
+ then
+ $verbose && echo -n "."
+ else
+ $verbose && echo
+ echo "Error: corruption for $file ..."
+ diff -c $file $file.last
+ touch $tmp.bad
+ fi
+ else
+ $verbose && echo -n "."
+ fi
+ done
+ $verbose && echo
+}
+
+_cleanup()
+{
+ # cleanup
+ #
+ if $done_cleanup
+ then
+ :
+ elif [ $status -eq 0 ]
+ then
+ $verbose && echo "cleanup"
+ cd /
+ rm -rf $TEST_DIR/$$
+ done_cleanup=true
+ fi
+}
+
+status=0
+_cleanup
+status=1
+done_cleanup=false
+
+_setup
+
+# do the test
+#
+for iter in 1 2 3 4 5
+do
+ echo -n "iter $iter chain ... "
+ _chain
+ _check
+ if [ -f $tmp.bad ]
+ then
+ echo "Fatal error: test abandoned without changes"
+ exit 1
+ fi
+done
+
+status=0
+exit
--- /dev/null
+QA output created by 001
+cleanup
+setup ....................................
+iter 1 chain ... check ....................................
+iter 2 chain ... check ....................................
+iter 3 chain ... check ....................................
+iter 4 chain ... check ....................................
+iter 5 chain ... check ....................................
+cleanup
--- /dev/null
+#! /bin/sh
+#
+# XFS QA Test No. 002
+# $Id: 1.1 $
+#
+# simple inode link count test for a regular file
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=kenmcd@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+tmp=/tmp/$$
+here=`pwd`
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# real QA test starts here
+
+echo "Silence is goodness ..."
+
+# ensure target directory exists
+mkdir `dirname $TEST_DIR/$tmp` 2>/dev/null
+
+touch $TEST_DIR/$tmp.1
+for l in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+do
+ ln $TEST_DIR/$tmp.1 $TEST_DIR/$tmp.$l
+ x=`src/lstat64 $TEST_DIR/$tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
+ if [ "$l" -ne $x ]
+ then
+ echo "Arrgh, created link #$l and lstat64 looks like ..."
+ src/lstat64 $TEST_DIR/$tmp.1
+ status=1
+ fi
+done
+
+for l in 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
+do
+ x=`src/lstat64 $TEST_DIR/$tmp.1 | sed -n -e '/ Links: /s/.*Links: *//p'`
+ if [ "$l" -ne $x ]
+ then
+ echo "Arrgh, about to remove link #$l and lstat64 looks like ..."
+ src/lstat64 $TEST_DIR/$tmp.1
+ status=1
+ fi
+ rm -f $TEST_DIR/$tmp.$l
+done
+
+# success, all done
+exit
--- /dev/null
+QA output created by 002
+Silence is goodness ...
--- /dev/null
+#! /bin/sh
+#
+# XFS QA Test No. 003
+# $Id: 1.1 $
+#
+# exercise xfs_db bug #784078
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+tmp=/tmp/$$
+here=`pwd`
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+_need_to_be_root
+
+# real QA test starts here
+
+PATH=".:$PATH"
+
+[ -f core ] && rm -f core
+[ -f core ] && echo "Warning: can't nuke existing core file!"
+
+test_done()
+{
+ sts=$?
+ [ -f core ] && echo "FAILED - core file"
+ [ ! -f core -a $sts != 0 ] && echo "FAILED - non-zero exit status"
+ rm -f core
+}
+
+# real QA test starts here
+
+echo "=== TEST 1 ==="
+xfs_db -r -c 'pop' -c 'type sb' $TEST_DEV
+test_done
+
+echo "=== TEST 2 ==="
+xfs_db -r -c 'push sb' $TEST_DEV
+test_done
+
+echo "=== TEST 3 ==="
+xfs_db -r -c 'pop' -c 'push sb' $TEST_DEV
+test_done
+
+echo "=== TEST 4 ==="
+xfs_db -r -c 'type sb' -c 'print' $TEST_DEV
+test_done
+
+echo "=== TEST 5 ==="
+xfs_db -r -c 'inode 128' -c 'push' -c 'type' $TEST_DEV >$tmp.out 2>&1
+test_done
+if ! grep -q "current type is \"inode\"" $tmp.out
+then
+ cat $tmp.out
+fi
+
+echo "=== TEST 6 ==="
+xfs_db -r -c 'sb' -c 'a' $TEST_DEV >$tmp.out 2>&1 # don't care about output
+test_done
+
+echo "=== TEST 7 ==="
+xfs_db -r -c 'ring' $TEST_DEV
+test_done
--- /dev/null
+QA output created by 003
+=== TEST 1 ===
+no current object
+=== TEST 2 ===
+=== TEST 3 ===
+=== TEST 4 ===
+no current object
+no current type
+=== TEST 5 ===
+=== TEST 6 ===
+=== TEST 7 ===
+no entries in location ring.
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 004
+# $Id: 1.1 $
+#
+# exercise xfs_db bug #789674 and other freesp functionality
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0
+
+_cleanup()
+{
+ umount $SCRATCH_MNT
+ rm -f $tmp.*
+ exit $status
+}
+trap "_cleanup" 0 1 2 3 15
+
+_populate_scratch()
+{
+ mkfs -t xfs -f $SCRATCH_DEV >/dev/null 2>&1
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT
+ dd if=/dev/zero of=$SCRATCH_MNT/foo count=200 bs=4096 >/dev/null 2>&1 &
+ dd if=/dev/zero of=$SCRATCH_MNT/goo count=400 bs=4096 >/dev/null 2>&1 &
+ dd if=/dev/zero of=$SCRATCH_MNT/moo count=800 bs=4096 >/dev/null 2>&1 &
+ wait
+ umount $SCRATCH_MNT # flush everything
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT # and then remount
+}
+
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_need_to_be_root
+_require_scratch
+
+# real QA test starts here
+rm -f $seq.full
+
+_populate_scratch
+
+eval `df -P -T --block-size=512 $SCRATCH_MNT 2>&1 \
+ | $AWK_PROG 'END { printf "blocks=%u used=%u avail=%u\n", $3, $4, $5 }'`
+echo "df gave: blocks=$blocks used=$used avail=$avail" >>$seq.full
+
+blksize=`xfs_db -r -c sb -c p $SCRATCH_DEV |grep blocksize |sed -e 's/.*= *//'`
+if [ -z "$blksize" ]
+then
+ echo "Arrgh ... cannot determine blocksize for $fs, xfs_db reports"
+ xfs_db -r -c sb -c p $SCRATCH_DEV
+ status=1
+ continue
+fi
+echo "blocksize from xfs_db is '$blksize'" >>$seq.full
+
+xfs_db -r -c "freesp -s" $SCRATCH_DEV >$tmp.xfs_db
+echo "xfs_db for $SCRATCH_DEV" >>$seq.full
+cat $tmp.xfs_db >>$seq.full
+
+# check the 'blocks' field from freesp command is OK
+perl -ne '
+ BEGIN { $avail ='$avail' * 512;
+ $answer="(no xfs_db free blocks line?)" }
+ /free blocks (\d+)$/ || next;
+ $freesp = $1 * '$blksize';
+ if ($freesp == $avail) { $answer = "yes"; }
+ else { $answer = "no ($freesp != $avail)"; }
+ END { print "$answer\n" }
+ ' <$tmp.xfs_db >$tmp.ans
+ans="`cat $tmp.ans`"
+echo "Checking blocks column same as df: $ans"
+if [ "$ans" != yes ]
+then
+ echo "Error: $SCRATCH_DEV: freesp mismatch: $ans"
+ echo "xfs_db output ..."
+ cat $tmp.xfs_db
+ status=1
+fi
+
+# check the 'pct' field from freesp command is good
+perl -ne '
+ BEGIN { $percent = 0; }
+ /free/ && next; # skip over free extent size number
+ if (/\s+(\d+\.\d+)$/) {
+ $percent += $1;
+ }
+ END { $percent += 0.5; print int($percent), "\n" } # round up
+' <$tmp.xfs_db >$tmp.ans
+ans="`cat $tmp.ans`"
+echo "Checking percent column yields 100: $ans"
+if [ "$ans" != 100 ]
+then
+ echo "Error: $SCRATCH_DEV: pct mismatch: $ans (expected 100)"
+ echo "xfs_db output ..."
+ cat $tmp.xfs_db
+ status=1
+fi
+
+exit
--- /dev/null
+QA output created by 004
+Checking blocks column same as df: yes
+Checking percent column yields 100: 100
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 005
+# $Id: 1.1 $
+#
+# Test symlinks & ELOOP
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+#
+# note ELOOP limit used to be 32 but changed to 8. Who know what
+# it might be next.
+#
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ cd $TEST_DIR
+ rm -f symlink_{0,1,2,3}{0,1,2,3,4,5,6,7,8,9} symlink_self empty_file
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+cd $TEST_DIR
+
+o=empty_file
+touch $o
+for f in symlink_{0,1,2,3}{0,1,2,3,4,5,6,7,8,9}
+do
+ ln -s $o $f
+ o=$f
+done
+
+ln -s symlink_self symlink_self
+
+echo "*** touch deep symlinks"
+echo ""
+touch symlink_{0,1,2,3}{0,1,2,3,4,5,6,7,8,9}
+echo ""
+echo "*** touch recusive symlinks"
+echo ""
+touch symlink_self
+
+exit
--- /dev/null
+QA output created by 005
+*** touch deep symlinks
+
+touch: symlink_08: Too many levels of symbolic links
+touch: symlink_09: Too many levels of symbolic links
+touch: symlink_10: Too many levels of symbolic links
+touch: symlink_11: Too many levels of symbolic links
+touch: symlink_12: Too many levels of symbolic links
+touch: symlink_13: Too many levels of symbolic links
+touch: symlink_14: Too many levels of symbolic links
+touch: symlink_15: Too many levels of symbolic links
+touch: symlink_16: Too many levels of symbolic links
+touch: symlink_17: Too many levels of symbolic links
+touch: symlink_18: Too many levels of symbolic links
+touch: symlink_19: Too many levels of symbolic links
+touch: symlink_20: Too many levels of symbolic links
+touch: symlink_21: Too many levels of symbolic links
+touch: symlink_22: Too many levels of symbolic links
+touch: symlink_23: Too many levels of symbolic links
+touch: symlink_24: Too many levels of symbolic links
+touch: symlink_25: Too many levels of symbolic links
+touch: symlink_26: Too many levels of symbolic links
+touch: symlink_27: Too many levels of symbolic links
+touch: symlink_28: Too many levels of symbolic links
+touch: symlink_29: Too many levels of symbolic links
+touch: symlink_30: Too many levels of symbolic links
+touch: symlink_31: Too many levels of symbolic links
+touch: symlink_32: Too many levels of symbolic links
+touch: symlink_33: Too many levels of symbolic links
+touch: symlink_34: Too many levels of symbolic links
+touch: symlink_35: Too many levels of symbolic links
+touch: symlink_36: Too many levels of symbolic links
+touch: symlink_37: Too many levels of symbolic links
+touch: symlink_38: Too many levels of symbolic links
+touch: symlink_39: Too many levels of symbolic links
+
+*** touch recusive symlinks
+
+touch: symlink_self: Too many levels of symbolic links
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 006
+# $Id: 1.1 $
+#
+# permname
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -rf $TEST_DIR/permname.$$
+}
+
+_count()
+{
+ $AWK_PROG '
+ BEGIN { count = 0 }
+ { count ++ }
+ END { print count " files created" }
+ '
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+
+mkdir $TEST_DIR/permname.$$
+
+echo ""
+echo "single thread permname"
+echo "----------------------"
+mkdir $TEST_DIR/permname.$$/a
+cd $TEST_DIR/permname.$$/a
+$here/src/permname -c 4 -l 6 -p 1 || echo "permname returned $?"
+find . | _count
+
+echo ""
+echo "multi thread permname"
+echo "----------------------"
+mkdir $TEST_DIR/permname.$$/b
+cd $TEST_DIR/permname.$$/b
+$here/src/permname -c 4 -l 6 -p 4 || echo "permname returned $?"
+find . | _count
+
+exit
--- /dev/null
+QA output created by 006
+
+single thread permname
+----------------------
+alpha size = 4, name length = 6, total files = 4096, nproc=1
+4097 files created
+
+multi thread permname
+----------------------
+alpha size = 4, name length = 6, total files = 4096, nproc=4
+4097 files created
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 007
+# $Id: 1.1 $
+#
+# drive the src/nametest program
+# which does a heap of open(create)/unlink/stat
+# and checks that error codes make sense with its
+# memory of the files created.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -f $tmp.*
+ rm -rf $TEST_DIR/$seq
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+status=1 # default failure
+sourcefile=$tmp.nametest
+seed=1
+iterations=100000
+num_filenames=100
+
+# need to create an input file with a list of
+# filenames on each line
+i=1
+while [ $i -le $num_filenames ]; do
+ echo "nametest.$i" >>$sourcefile
+ i=`expr $i + 1`
+done
+
+mkdir $TEST_DIR/$seq
+cd $TEST_DIR/$seq
+$here/src/nametest -l $sourcefile -s $seed -i $iterations -z
+
+
+#optional stuff if your test has verbose output to help resolve problems
+#echo
+#echo "If failure, check $seq.full (this) and $seq.full.ok (reference)"
+
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 007
+.Seed = 1 (use "-s 1" to re-execute this test)
+.......................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+.........................................................................
+....................................................
+creates: 18736 OK, 18802 EEXIST ( 37538 total, 50% EEXIST)
+removes: 18675 OK, 19927 ENOENT ( 38602 total, 51% ENOENT)
+lookups: 12000 OK, 11860 ENOENT ( 23860 total, 49% ENOENT)
+total : 49411 OK, 50589 w/error (100000 total, 50% w/error)
+
+cleanup: 61 removes
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 008
+# $Id: 1.1 $
+#
+# randholes test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; _cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -rf $TEST_DIR/randholes.$$.*
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_do_test()
+{
+ _n="$1"
+ _holes="$2"
+ _param="$3"
+
+ out=$TEST_DIR/randholes.$$.$_n
+ echo ""
+ echo "randholes.$_n : $_param"
+ echo "------------------------------------------"
+ if $here/src/randholes $_param $out >$tmp.out
+ then
+ # quick check - how many holes did we get?
+ count=`xfs_bmap $out | egrep -c ': hole'`
+ # blocks can end up adjacent, therefore number of holes varies
+ _within_tolerance "holes" $count $_holes 10% -v
+ else
+ echo " randholes returned $? - see $seq.out.full"
+ echo "--------------------------------------" >>$here/$seq.out.full
+ echo "$_n - output from randholes:" >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ cat $tmp.out >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ echo "$_n - output from bmap:" >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ xfs_bmap -vvv $out >>$here/$seq.out.full
+ status=1
+ fi
+}
+
+# real QA test starts here
+
+rm -f $here/$seq.out.full
+
+_do_test 1 50 "-l 5000000 -c 50 -b 4096"
+_do_test 2 100 "-l 10000000 -c 100 -b 4096"
+_do_test 3 100 "-l 10000000 -c 100 -b 512" # test partial pages
+
+# success, all done
+exit
--- /dev/null
+QA output created by 008
+
+randholes.1 : -l 5000000 -c 50 -b 4096
+------------------------------------------
+holes is in range
+
+randholes.2 : -l 10000000 -c 100 -b 4096
+------------------------------------------
+holes is in range
+
+randholes.3 : -l 10000000 -c 100 -b 512
+------------------------------------------
+holes is in range
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 009
+# $Id: 1.1 $
+#
+# alloc test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT
+}
+
+_block_filter()
+{
+ sed -e 's/[0-9][0-9]*\.\.[0-9][0-9]*/BLOCKRANGE/g'
+}
+
+_init()
+{
+ echo "*** mkfs"
+ if ! mkfs -t xfs -f $SCRATCH_DEV >$tmp.out 2>&1
+ then
+ cat $tmp.out
+ echo "failed to mkfs $SCRATCH_DEV"
+ exit 1
+ fi
+
+ echo "*** mount"
+ if ! mount $SCRATCH_DEV $SCRATCH_MNT -t xfs
+ then
+ echo "failed to mount $SCRATCH_DEV"
+ exit 1
+ fi
+}
+
+_filesize()
+{
+ ls -l $1 | $AWK_PROG '{print "filesize = " $5}'
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_scratch
+
+_init
+out=$SCRATCH_MNT/$$.tmp
+
+# since we're using a clean FS here, we make some assumptions
+# about availability of contiguous blocks
+
+# also interesting to note is that ALLOC == FREE. seriously.
+# the _length is ignored_ in irix. the file is allocated up
+# to the specified offset, and zero filled if previously
+# unallocated. the file is truncated at the specified point.
+
+echo "*** test 1 - reservations cleared on O_TRUNC"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+r 0 1000b
+m
+EOF
+_filesize $out
+
+cat <<EOF | src/alloc -n -b 4096 -f $out -t | _block_filter
+m
+EOF
+_filesize $out
+
+echo "*** test 2 - reserve & filesize"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+r 0 1000b
+EOF
+
+_filesize $out
+
+echo "*** test 3 - alloc & filesize"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+a 1000b
+EOF
+
+_filesize $out
+
+echo "*** test 4 - allocations cleared on O_TRUNC"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+a 1000b
+EOF
+_filesize $out
+
+cat <<EOF | src/alloc -n -b 4096 -f $out -t | _block_filter
+m
+EOF
+_filesize $out
+
+echo "*** test 5 - reserve / unreserve"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+r 0 100b
+u 100b 500b
+m
+u 900b 200b
+m
+EOF
+
+echo "*** test 6 - reserve adjacent"
+rm -f $out
+cat <<EOF | src/alloc -t -n -b 4096 -f $out | _block_filter
+r 0 100b
+r 100b 100b
+m
+EOF
+
+echo "*** test 7 - alloc"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+a 1000b
+m
+a 2000b
+m
+EOF
+
+_filesize $out
+
+echo "*** test 8 - alloc & truncate"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+a 1000b
+m
+t 500b
+m
+EOF
+
+_filesize $out
+
+echo "*** test 9 - reserve & truncate"
+rm -f $out
+cat <<EOF | src/alloc -n -b 4096 -f $out | _block_filter
+r 0 1000b
+m
+t 500b
+m
+EOF
+
+_filesize $out
+
+
+status=0
+exit
--- /dev/null
+QA output created by 009
+*** mkfs
+*** mount
+*** test 1 - reservations cleared on O_TRUNC
+ blocksize 4096
+ CMD resvsp, off=0, len=4096000
+ MAP off=0, len=4096000 [0,1000]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+filesize = 0
+ blocksize 4096
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+filesize = 0
+*** test 2 - reserve & filesize
+ blocksize 4096
+ CMD resvsp, off=0, len=4096000
+ MAP off=0, len=4096000 [0,1000]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+filesize = 0
+*** test 3 - alloc & filesize
+ blocksize 4096
+ CMD allocsp, off=4096000, len=-1
+ MAP off=4096000, len=-1 [1000-]
+ [ofs,count]: start..end
+filesize = 4096000
+*** test 4 - allocations cleared on O_TRUNC
+ blocksize 4096
+ CMD allocsp, off=4096000, len=-1
+ MAP off=4096000, len=-1 [1000-]
+ [ofs,count]: start..end
+filesize = 4096000
+ blocksize 4096
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+filesize = 0
+*** test 5 - reserve / unreserve
+ blocksize 4096
+ CMD resvsp, off=0, len=409600
+ MAP off=0, len=409600 [0,100]
+ [ofs,count]: start..end
+ [0,100]: BLOCKRANGE
+ CMD unresvsp, off=409600, len=2048000
+ MAP off=409600, len=2048000 [100,500]
+ [ofs,count]: start..end
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,100]: BLOCKRANGE
+ CMD unresvsp, off=3686400, len=819200
+ MAP off=3686400, len=819200 [900,200]
+ [ofs,count]: start..end
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,100]: BLOCKRANGE
+*** test 6 - reserve adjacent
+ blocksize 4096
+ CMD resvsp, off=0, len=409600
+ MAP off=0, len=409600 [0,100]
+ [ofs,count]: start..end
+ [0,100]: BLOCKRANGE
+ CMD resvsp, off=409600, len=409600
+ MAP off=409600, len=409600 [100,100]
+ [ofs,count]: start..end
+ [100,100]: BLOCKRANGE
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,200]: BLOCKRANGE
+*** test 7 - alloc
+ blocksize 4096
+ CMD allocsp, off=4096000, len=-1
+ MAP off=4096000, len=-1 [1000-]
+ [ofs,count]: start..end
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+ CMD allocsp, off=8192000, len=-1
+ MAP off=8192000, len=-1 [2000-]
+ [ofs,count]: start..end
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,2000]: BLOCKRANGE
+filesize = 8192000
+*** test 8 - alloc & truncate
+ blocksize 4096
+ CMD allocsp, off=4096000, len=-1
+ MAP off=4096000, len=-1 [1000-]
+ [ofs,count]: start..end
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+ TRUNCATE off=2048000
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,500]: BLOCKRANGE
+filesize = 2048000
+*** test 9 - reserve & truncate
+ blocksize 4096
+ CMD resvsp, off=0, len=4096000
+ MAP off=0, len=4096000 [0,1000]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+ TRUNCATE off=2048000
+ MAP off=0, len=-1 [0-]
+ [ofs,count]: start..end
+ [0,1000]: BLOCKRANGE
+filesize = 2048000
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 010
+# $Id: 1.1 $
+#
+# dbtest
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=ivanr@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+
+_cleanup()
+{
+ rm -f $TEST_DIR/DBtest*.{pag,dir}
+}
+trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# filter random number output from dbtest
+#
+_filter_dbtest()
+{
+ sed \
+ -e '/were [0-9][0-9]* duplicate/s//were BLEEP duplicate/' \
+ -e '/using [0-9][0-9]* as seed/s//using BLEEP as seed/'
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+cd $TEST_DIR
+$here/src/dbtest -l 5 -n 3000 | _filter_dbtest
+
+# success, all done
+exit
--- /dev/null
+QA output created by 010
+dbtest v1.0
+
+Creating database containing 3000 records...
+ performing lookups for 5 iterations...
+ using BLEEP as seed for srandom()...
+
+
+There were BLEEP duplicate checksums generated
+
+Performing lookups on database...
+
+ Sequential lookups...
+
+
+ Random lookups...
+
+Lookups succeeded...
+
+Performing lookups on database...
+
+ Sequential lookups...
+
+
+ Random lookups...
+
+Lookups succeeded...
+
+Performing lookups on database...
+
+ Sequential lookups...
+
+
+ Random lookups...
+
+Lookups succeeded...
+
+Performing lookups on database...
+
+ Sequential lookups...
+
+
+ Random lookups...
+
+Lookups succeeded...
+
+Performing lookups on database...
+
+ Sequential lookups...
+
+
+ Random lookups...
+
+Lookups succeeded...
+
+Cleaning up database...
+
+There were BLEEP duplicate checksums generated
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 011
+# $Id: 1.1 $
+#
+# dirstress
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+out=$TEST_DIR/dirstress.$$
+trap "rm -f $tmp.*; _cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -rf $out
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+count=1000
+if ! mkdir $out
+then
+ echo "!! couldn't mkdir $out"
+ status=1
+ exit
+fi
+
+rm -f $seq.out.full
+
+_test()
+{
+ test="$1"
+ args="$2"
+ count="$3"
+
+ echo "*** TEST $test $args -f <count>"
+ if ! $here/src/dirstress -d $out -f $count $args >$tmp.out 2>&1
+ then
+ echo " dirstress failed"
+ echo "*** TEST $test -d $out -f $count $args" >>$seq.out.full
+ cat $tmp.out >>$seq.out.full
+ status=1
+ fi
+}
+
+# dirstress doesn't check returns - this is a crash & burn test.
+
+count=1000
+_test 1 "-p 1 -n 1" $count
+_test 2 "-p 5 -n 1" $count
+_test 3 "-p 5 -n 5" $count
+
+# if error
+exit
--- /dev/null
+QA output created by 011
+*** TEST 1 -p 1 -n 1 -f <count>
+*** TEST 2 -p 5 -n 1 -f <count>
+*** TEST 3 -p 5 -n 5 -f <count>
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 012
+# $Id: 1.1 $
+#
+# holes
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; _cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -rf $TEST_DIR/holes.$$.*
+}
+
+_filesize()
+{
+ ls -l $1 | $AWK_PROG '{print " filesize = " $5}'
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_do_test()
+{
+ _n="$1"
+ _param="$2"
+ _count="$3"
+
+ failed=0
+
+ out=$TEST_DIR/holes.$$.$_n
+ echo ""
+ echo "holes.$_n : $_param"
+ echo "-----------------------------------------------"
+ if ! $here/src/holes $_param $out >$tmp.out
+ then
+ echo " holes returned $? - see $seq.out.full"
+ failed=1
+ status=1
+ fi
+
+
+ if [ $failed -eq 0 ]
+ then
+ # quick check - how many holes did we get?
+ count=`xfs_bmap $out | egrep -c ': hole'`
+ echo " $count hole(s) detected"
+ # and how big was the file?
+ _filesize $out
+
+ if [ $count -ne $_count ]
+ then
+ echo " unexpected number of holes - see $seq.out.full"
+ status=1
+ failed=1
+ fi
+ fi
+
+ if [ $failed -eq 1 ]
+ then
+ echo "--------------------------------------" >>$here/$seq.out.full
+ echo "$_n - output from holes:" >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ cat $tmp.out >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ echo "$_n - output from bmap:" >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ xfs_bmap -vvv $out >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ echo "$_n - output from ls -li:" >>$here/$seq.out.full
+ echo "--------------------------------------" >>$here/$seq.out.full
+ ls -li $out >>$here/$seq.out.full
+ status=1
+ fi
+}
+
+# real QA test starts here
+
+rm -f $here/$seq.out.full
+
+# small & fairly dense
+_do_test 1 "-l 40960000 -b 40960 -i 10 -c 1" 100
+
+# big & sparse
+_do_test 2 "-l 409600000 -b 40960 -i 1000 -c 1" 10
+
+# no holes, but a very nasty way to write a file (lots of extents)
+_do_test 3 "-l 40960000 -b 40960 -i 10 -c 10" 0
+
+exit
--- /dev/null
+QA output created by 012
+
+holes.1 : -l 40960000 -b 40960 -i 10 -c 1
+-----------------------------------------------
+ 100 hole(s) detected
+ filesize = 40960000
+
+holes.2 : -l 409600000 -b 40960 -i 1000 -c 1
+-----------------------------------------------
+ 10 hole(s) detected
+ filesize = 409600000
+
+holes.3 : -l 40960000 -b 40960 -i 10 -c 10
+-----------------------------------------------
+ 0 hole(s) detected
+ filesize = 40960000
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 013
+# $Id: 1.1 $
+#
+# fsstress
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ # we might get here with a RO FS
+ mount -o remount,rw $TEST_DEV >/dev/null 2>&1
+ # now kill!
+ rm -rf $TEST_DIR/fsstress.$$.*
+}
+
+_filesize()
+{
+ ls -l $1 | $AWK_PROG '{print " filesize = " $5}'
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_do_test()
+{
+ _n="$1"
+ _param="$2"
+ _count="$3"
+
+ failed=0
+
+ out=$TEST_DIR/fsstress.$$.$_n
+ rm -rf $out
+ if ! mkdir $out
+ then
+ echo " failed to mkdir $out"
+ status=1
+ exit
+ fi
+
+ echo ""
+ echo "-----------------------------------------------"
+ echo "fsstress.$_n : $_param"
+ echo "-----------------------------------------------"
+ # -v >$tmp.out
+ if ! $here/src/fsstress $_param $FSSTRESS_AVOID -n $_count -d $out >/dev/null 2>&1
+ then
+ echo " fsstress (count=$_count) returned $? - see $seq.full"
+
+ echo "--------------------------------------" >>$here/$seq.full
+ echo "$_n - output from fsstress:" >>$here/$seq.full
+ echo "--------------------------------------" >>$here/$seq.full
+ echo "<NOT LOGGED>" >>$here/$seq.full
+ #cat $tmp.out >>$here/$seq.full
+ status=1
+ fi
+
+ _check_fs $TEST_DEV
+}
+
+
+# real QA test starts here
+
+rm -f $here/$seq.full
+echo "berevity is wit..."
+
+count=1000
+
+_check_fs $TEST_DEV
+
+# the default
+
+_do_test 1 "-r" $count
+
+# and the default with multiprocess
+
+_do_test 2 "-p 5 -r" $count
+
+# from Glen's notes
+
+_do_test 3 "-p 4 -z -f rmdir=10 -f link=10 -f creat=10 -f mkdir=10 -f rename=30 -f stat=30 -f unlink=30 -f truncate=20" $count
+
+exit
+
+# Test with error injection:
+#
+# (error injection)
+# fsstress -n 1000 -d $scratch -p 4 -z -f rmdir=10 -f link=10 -f creat=10 \
+# -f mkdir=10 -f rename=30 -f stat=30 -f unlink=30 -f truncate=20 \
+# -e 1
+#
+# Error values 1 - 6 test IFLUSH
+# 1 - corrupt buffer being flushed to di_core.di_magic
+# 2 - corrupt inode being flushed i_d.di_magic
+# 3 - corrupt IFREG format check
+# 4 - corrupt IFDIR format check
+# 5 - corrupt i_d.di_nextents
+# 6 - corrupt i_d.di_forkoff > sb_inodesize
--- /dev/null
+QA output created by 013
+berevity is wit...
+
+-----------------------------------------------
+fsstress.1 : -r
+-----------------------------------------------
+
+-----------------------------------------------
+fsstress.2 : -p 5 -r
+-----------------------------------------------
+
+-----------------------------------------------
+fsstress.3 : -p 4 -z -f rmdir=10 -f link=10 -f creat=10 -f mkdir=10 -f rename=30 -f stat=30 -f unlink=30 -f truncate=20
+-----------------------------------------------
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 014
+# $Id: 1.1 $
+#
+# truncfile
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; _cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ rm -rf $TEST_DIR/truncfile.$$.*
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+
+echo "berevity is wit..."
+
+echo "------"
+echo "test 1"
+echo "------"
+if ! src/truncfile -c 10000 $TEST_DIR/truncfile.$$.0 >$tmp.out 2>&1
+then
+ out=`cat $tmp.out`
+ echo "truncfile returned $? : \"$out\""
+else
+ echo "OK"
+fi
+
+exit
--- /dev/null
+QA output created by 014
+berevity is wit...
+------
+test 1
+------
+OK
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 015
+# $Id: 1.1 $
+#
+# check out-of-space behaviour
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # success is the default!
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_cleanup()
+{
+ umount $SCRATCH_MNT
+}
+
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_free()
+{
+ _df_dir $TEST_DIR | $AWK_PROG '{ print $5 }'
+}
+
+_filter_dd()
+{
+ $AWK_PROG '
+ /records in/ { next }
+ /records out/ { next }
+ /No space left on device/ { print " !!! disk full (expected)"
+ next }
+ { print " *** " $0 }
+ '
+}
+
+# real QA test starts here
+_require_scratch
+
+mkfs -t xfs -f -d size=50m $SCRATCH_DEV >/dev/null
+mount -t xfs $SCRATCH_DEV $SCRATCH_MNT
+out=$SCRATCH_MNT/fillup.$$
+
+free0=`_free`
+if [ -z "$free0" ]
+then
+ echo " *** failed to get free space (0)"
+ exit 1
+fi
+
+echo "fill disk:" # well, filesystem really - not disk
+
+dd if=/dev/zero of=$out bs=1024k 2>&1 | _filter_dd
+
+if [ ! -e $out ]
+then
+ echo " *** file not created"
+ exit 1
+fi
+
+if [ ! -s $out ]
+then
+ echo " *** file created with zero length"
+ ls -l $out
+ exit 1
+fi
+
+echo "delete fill:"
+
+if ! rm $out
+then
+ echo " *** file not deleted"
+ exit 1
+fi
+
+if [ -e $out ]
+then
+ echo " *** file still exists"
+ ls -l $out
+ exit 1
+fi
+
+echo "check free space:"
+
+free1=`_free`
+if [ -z "$free1" ]
+then
+ echo " *** failed to get free space (1)"
+ exit 1
+fi
+
+echo -n " !!! "
+_within_tolerance "free space" $free1 $free0 1% -v
+
+status=0
+exit
--- /dev/null
+QA output created by 015
+fill disk:
+ !!! disk full (expected)
+delete fill:
+check free space:
+ !!! free space is in range
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 016
+# $Id: 1.1 $
+#
+# test end of log overwrite bug #796141
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+#
+# pv 796141
+#
+# create a new FS, mostly fill the log. Then wrap the log back to the
+# start bit by bit to force wiping of stale blocks near the end of the
+# log. Check the block after the log ends to check for corruption
+#
+# assumptions :
+# - given we're only touching a single inode, the block after the
+# log which is in the middle ag should never be touched.
+# if it changes, we assume the log is writing over it
+#
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1
+
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+}
+
+_block_filter()
+{
+ sed -e 's/[0-9][0-9]*\.\.[0-9][0-9]*/BLOCKRANGE/g'
+}
+
+_init()
+{
+ echo "*** reset partition"
+ $here/src/devzero -b 2048 -n 50 -v 198 $SCRATCH_DEV
+ echo "*** mkfs"
+ if ! mkfs -t xfs -f -d size=50m -l size=512b $SCRATCH_DEV >$tmp.out 2>&1
+ then
+ cat $tmp.out
+ echo "failed to mkfs $SCRATCH_DEV"
+ exit 1
+ fi
+}
+
+_log_traffic()
+{
+ count=$1
+ echo "*** generate log traffic"
+
+ out=$SCRATCH_MNT/$$.tmp
+
+ echo " *** mount"
+ if ! mount $SCRATCH_DEV $SCRATCH_MNT -t xfs
+ then
+ echo "failed to mount $SCRATCH_DEV"
+ exit 1
+ fi
+
+ # having quota enabled means extra log traffic - evil!
+ $here/src/feature -u $SCRATCH_DEV && _notrun "User quota are enabled"
+ $here/src/feature -g $SCRATCH_DEV && _notrun "Group quota are enabled"
+
+ echo " *** fiddle"
+ while [ $count -ge 0 ]
+ do
+ touch $out
+ rm $out
+ let "count = count - 1"
+ done
+
+ echo " *** unmount"
+ if ! umount $SCRATCH_DEV
+ then
+ echo "failed to unmount $SCRATCH_DEV"
+ exit 1
+ fi
+}
+
+_log_size()
+{
+ xfs_logprint -tb $SCRATCH_DEV | $AWK_PROG '
+ /log device/ { print $7}
+ '
+}
+
+_log_head()
+{
+ xfs_logprint -tb $SCRATCH_DEV | $AWK_PROG '
+ /head:/ { print $5 }
+ '
+}
+
+_after_log()
+{
+ xfs_db -r $1 -c "sb" -c "print" | $AWK_PROG '
+ /logstart/ { logstart = $3 }
+ /logblocks/ { logblocks = $3 }
+ END {
+ print logstart + logblocks
+ }
+ '
+}
+
+_check_corrupt()
+{
+ f="c6c6c6c6"
+ echo "*** check for corruption"
+ echo "expect $f..." >>$seq.full
+ xfs_db -r $1 -c "fsblock $2" -c "print" | head | tee -a $seq.full | \
+ grep -q -v "$f $f $f $f $f $f $f $f" && \
+ _fail "!!! block $2 corrupted!"
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+rm -f $seq.full
+
+_require_scratch
+_init
+
+block=`_after_log $SCRATCH_DEV`
+echo "fsblock after log = $block" >>$seq.full
+_check_corrupt $SCRATCH_DEV $block
+
+size=`_log_size`
+echo "log size = $size BB" >>$seq.full
+head=`_log_head`
+echo "log position = $head" >>$seq.full
+
+[ $size -eq 4096 ] || \
+ _fail "!!! unexpected log size $size"
+[ $head -eq 2 ] || \
+ _fail "!!! unexpected initial log position $head"
+
+echo " lots of traffic" >>$seq.full
+_log_traffic 850
+head=`_log_head`
+echo "log position = $head" >>$seq.full
+
+[ $head -gt 3850 -a $head -lt 4050 ] || \
+ _fail "!!! unexpected log position $head"
+
+for c in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+do
+ echo " little traffic" >>$seq.full
+ _log_traffic 2
+ head=`_log_head`
+ echo "log position = $head" >>$seq.full
+ _check_corrupt $SCRATCH_DEV $block
+done
+
+[ $head -lt 1000 ] || \
+ _fail "!!! unexpected log position $head"
+
+
+# happy exit
+rm $seq.full
+status=0
+exit 0
--- /dev/null
+QA output created by 016
+*** reset partition
+Wrote 51200.00Kb (value 0xc6)
+*** mkfs
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** generate log traffic
+ *** mount
+ *** fiddle
+ *** unmount
+*** check for corruption
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 017
+# $Id: 1.1 $
+#
+# test remount ro - pv 795642
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+}
+trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+_clean_log()
+{
+ echo "" >>$seq.full
+ echo "*** xfs_logprint ***" >>$seq.full
+ echo "" >>$seq.full
+ xfs_logprint -tb $1 | tee -a $seq.full \
+ | head | grep -q "<CLEAN>" || _fail "DIRTY LOG"
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_scratch
+
+echo "*** init FS"
+
+rm -f $seq.full
+umount $SCRATCH_DEV >/dev/null 2>&1
+echo "*** MKFS ***" >>$seq.full
+echo "" >>$seq.full
+mkfs -t xfs -f $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "mkfs failed"
+mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >>$seq.full 2>&1 \
+ || _fail "mount failed"
+
+echo "*** test"
+
+for l in 0 1 2 3 4
+do
+ echo " *** test $l"
+ src/fsstress -d $SCRATCH_MNT -n 1000 $FSSTRESS_AVOID >>$seq.full
+
+ mount -o remount,ro $SCRATCH_DEV \
+ || _fail "remount ro failed"
+
+ _clean_log $SCRATCH_DEV
+
+ echo "" >>$seq.full
+ echo "*** XFS_CHECK ***" >>$seq.full
+ echo "" >>$seq.full
+ xfs_check $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "xfs_check failed"
+ mount -o remount,rw $SCRATCH_DEV \
+ || _fail "remount rw failed"
+done
+
+echo "*** done"
+# happy exit
+rm -f $seq.full
+status=0
+exit 0
--- /dev/null
+QA output created by 017
+*** init FS
+*** test
+ *** test 0
+ *** test 1
+ *** test 2
+ *** test 3
+ *** test 4
+*** done
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 018
+# $Id: 1.1 $
+#
+# xfs_logprint test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_full()
+{
+ echo "" >>$seq.full
+ echo "*** $* ***" >>$seq.full
+ echo "" >>$seq.full
+}
+
+_clean_log()
+{
+ _full "clean_log : xfs_logprint"
+ xfs_logprint -t $1 | tee -a $seq.full \
+ | head | grep -q "<CLEAN>" || _fail "DIRTY LOG"
+}
+
+_filter_logprint()
+{
+ sed '
+ s/data device: 0x[0-9a-f][0-9a-f]*/data device: <DEVICE>/;
+ s/log device: 0x[0-9a-f][0-9a-f]*/log device: <DEVICE>/;
+ s/daddr: [0-9][0-9]*/daddr: <DADDR>/;
+ s/length: [0-9][0-9]*/length: <LENGTH>/;
+ s/length: [0-9][0-9]*/length: <LENGTH>/;
+ s/^cycle num overwrites: .*$/cycle num overwrites: <TIDS>/;
+ s/tid: [0-9a-f][0-9a-f]*/tid: <TID>/;
+ s/tid:0x[0-9a-f][0-9a-f]*/tid:<TID>/;
+ s/q:0x[0-9a-f][0-9a-f]*/q:<Q>/;
+ s/a:0x[0-9a-f][0-9a-f]*/a:<A>/g;
+ s/blkno:0x[0-9a-f][0-9a-f]*/blkno:<BLKNO>/g;
+ s/blkno: [0-9][0-9]* (0x[0-9a-f]*)/blkno: <BLKNO> (<BLKNO>)/g;
+ s/blkno: [0-9][0-9]*/blkno: <BLKNO>/g;
+ s/boff: [0-9][0-9]*/boff: <BOFF>/g;
+ s/len: *[0-9][0-9]*/len:<LEN>/g;
+ s/skipped [0-9][0-9]* zeroed blocks/skipped <COUNT> zeroed blocks/;
+ s/atime:[0-9a-fx]* *mtime:[0-9a-fx]* *ctime:[0-9a-fx]*/atime:<TIME> mtime:<TIME> ctime:<TIME>/;
+ s/atime 0x[0-9a-f]* mtime 0x[0-9a-f]* ctime 0x[0-9a-f]*/atime <TIME> mtime <TIME> ctime <TIME>/;
+ s/block [0-9][0-9]*/block <BLOCK>/;
+ s/icount: *[0-9][0-9]* *ifree: *[0-9][0-9]* *fdblks: *[0-9][0-9]* *frext: *[0-9][0-9]*/icount:<COUNT> ifree:<FREE> fdblks:<BLOCKS> frext:<COUNT>/;
+ s/1st: *[0-9][0-9]* *last: *[0-9][0-9]* *cnt: *[0-9][0-9]* *freeblks: *[0-9][0-9]* *longest: *[0-9][0-9]*/1st:<NUM> last:<NUM> cnt:<COUNT> freeblks:<COUNT> longest:<NUM>/;
+ s/^uuid: *[0-9a-f-][0-9a-f-]* *format: *.*$/uuid: <UUID> format: <FORMAT>/;
+ '
+
+}
+
+_check_log()
+{
+ _clean_log $SCRATCH_DEV
+ echo "### xfs_logprint output ###"
+ xfs_logprint $SCRATCH_DEV 2>&1 | _filter_logprint
+ echo "### xfs_logprint -t -i -s 0 output ###"
+ xfs_logprint -t -i -s 0 $SCRATCH_DEV 2>&1 | _filter_logprint
+ echo "### xfs_logprint -t -b -s 0 output ###"
+ xfs_logprint -t -b -s 0 $SCRATCH_DEV 2>&1 | _filter_logprint
+}
+
+# real QA test starts here
+
+_require_scratch
+
+echo "*** init FS"
+
+rm -f $seq.full
+umount $SCRATCH_DEV >/dev/null 2>&1
+
+_full "mkfs"
+mkfs -t xfs -f $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "mkfs failed"
+_full " mount"
+mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >>$seq.full 2>&1 \
+ || _fail "mount failed"
+
+# generate some log traffic - but not too much - life gets a little
+# more complicated if the log wraps around. This traffic is
+# pretty much arbitary, but could probably be made better than this.
+
+touch $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
+
+_full "umount"
+umount $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "umount failed"
+
+_check_log
+
+rm $seq.full
+exit
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 019
+# $Id: 1.1 $
+#
+# mkfs protofile test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+seqfull="$seq.full"
+status=1 # failure is the default!
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+ rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_full()
+{
+ echo "" >>$seqfull
+ echo "*** $* ***" >>$seqfull
+ echo "" >>$seqfull
+}
+
+_filter_stat()
+{
+ sed '
+ /^Access:/d;
+ /^Modify:/d;
+ /^Change:/d;
+ s/Device: *[0-9][0-9]*,[0-9][0-9]*/Device: <DEVICE>/;
+ s/Inode: *[0-9][0-9]*/Inode: <INODE>/;
+ ' | tr -s ' '
+}
+
+# real QA test starts here
+
+_require_scratch
+
+protofile=$tmp.proto
+tempfile=$tmp.file
+
+echo fish >$tempfile
+$here/src/devzero -b 2048 -n 2 $tempfile.2 -c -v 44
+
+cat >$protofile <<EOF
+DUMMY1
+0 0
+: root directory
+d--777 3 1
+: a directory
+directory d--755 3 1
+file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_0 ---755 3 1 $tempfile
+file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1 ---755 3 1 $tempfile
+file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_2 ---755 3 1 $tempfile
+file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_3 ---755 3 1 $tempfile
+file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_4 ---755 3 1 $tempfile
+$
+: back in the root
+setuid -u-666 0 0 $tempfile
+setgid --g666 0 0 $tempfile
+setugid -ug666 0 0 $tempfile
+block_device b--012 3 1 161 162
+char_device c--345 3 1 177 178
+pipe p--670 0 0
+symlink l--123 0 0 bigfile
+: a file we actually read
+bigfile ---666 3 0 $tempfile.2
+: done
+$
+EOF
+
+if [ $? -ne 0 ]
+then
+ _fail "failed to create test protofile"
+fi
+
+_verify_fs()
+{
+ echo "*** create FS version $1"
+ VERSION="-n version=$1"
+
+ rm -f $seqfull
+ umount $SCRATCH_DEV >/dev/null 2>&1
+
+ _full "mkfs"
+ mkfs -t xfs -f $VERSION -p $protofile $SCRATCH_DEV >>$seqfull 2>&1 \
+ || _fail "mkfs failed"
+
+ echo "*** check FS"
+ _check_fs $SCRATCH_DEV
+
+ echo "*** mount FS"
+ _full " mount"
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >>$seqfull 2>&1 \
+ || _fail "mount failed"
+
+ echo "*** verify FS"
+ (cd $SCRATCH_MNT ; find . | sort \
+ | xargs $here/src/lstat64 | _filter_stat)
+ diff -q $SCRATCH_MNT/bigfile $tempfile.2 \
+ || _fail "bigfile corrupted"
+
+ echo "*** unmount FS"
+ _full "umount"
+ umount $SCRATCH_DEV >>$seqfull 2>&1 \
+ || _fail "umount failed"
+
+ echo "*** check FS"
+ _check_fs $SCRATCH_DEV
+}
+
+_verify_fs 1
+_verify_fs 2
+
+echo "*** done"
+rm $seqfull
+status=0
+exit
--- /dev/null
+QA output created by 019
+Wrote 2048.00Kb (value 0x2c)
+*** create FS version 1
+*** check FS
+*** mount FS
+*** verify FS
+ File: "."
+ Size: 4096 Filetype: Directory
+ Mode: (0777/drwxrwxrwx) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 3
+
+ File: "./bigfile"
+ Size: 2097152 Filetype: Regular File
+ Mode: (0666/-rw-rw-rw-) Uid: (3) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./block_device"
+ Size: 0 Filetype: Block Device
+ Mode: (0012/b-----x-w-) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1 Device type: 161,162
+
+ File: "./char_device"
+ Size: 0 Filetype: Character Device
+ Mode: (0345/c-wxr--r-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1 Device type: 177,178
+
+ File: "./directory"
+ Size: 4096 Filetype: Directory
+ Mode: (0755/drwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 2
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_0"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_2"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_3"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_4"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./pipe"
+ Size: 0 Filetype: Fifo File
+ Mode: (0670/frw-rwx---) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setgid"
+ Size: 5 Filetype: Regular File
+ Mode: (2666/-rw-rwsrw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setugid"
+ Size: 5 Filetype: Regular File
+ Mode: (6666/-rwsrwsrw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setuid"
+ Size: 5 Filetype: Regular File
+ Mode: (4666/-rwsrw-rw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./symlink"
+ Size: 7 Filetype: Symbolic Link
+ Mode: (0123/l--x-w--wx) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+*** unmount FS
+*** check FS
+*** create FS version 2
+*** check FS
+*** mount FS
+*** verify FS
+ File: "."
+ Size: 138 Filetype: Directory
+ Mode: (0777/drwxrwxrwx) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 3
+
+ File: "./bigfile"
+ Size: 2097152 Filetype: Regular File
+ Mode: (0666/-rw-rw-rw-) Uid: (3) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./block_device"
+ Size: 0 Filetype: Block Device
+ Mode: (0012/b-----x-w-) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1 Device type: 161,162
+
+ File: "./char_device"
+ Size: 0 Filetype: Character Device
+ Mode: (0345/c-wxr--r-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1 Device type: 177,178
+
+ File: "./directory"
+ Size: 4096 Filetype: Directory
+ Mode: (0755/drwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 2
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_0"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_1"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_2"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_3"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./directory/file_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_4"
+ Size: 5 Filetype: Regular File
+ Mode: (0755/-rwxr-xr-x) Uid: (3) Gid: (1)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./pipe"
+ Size: 0 Filetype: Fifo File
+ Mode: (0670/frw-rwx---) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setgid"
+ Size: 5 Filetype: Regular File
+ Mode: (2666/-rw-rwsrw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setugid"
+ Size: 5 Filetype: Regular File
+ Mode: (6666/-rwsrwsrw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./setuid"
+ Size: 5 Filetype: Regular File
+ Mode: (4666/-rwsrw-rw-) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+
+ File: "./symlink"
+ Size: 7 Filetype: Symbolic Link
+ Mode: (0123/l--x-w--wx) Uid: (0) Gid: (0)
+Device: <DEVICE> Inode: <INODE> Links: 1
+*** unmount FS
+*** check FS
+*** done
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 020
+# $Id: 1.1 $
+#
+# extended attributes
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.* $testfile; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_filter()
+{
+ sed "s#$TEST_DIR[^ :]*#<TESTFILE>#g;
+ s#$tmp[^ :]*#<TMPFILE>#g;
+ s#/proc[^ :]*#<PROCFILE>#g" $1
+}
+
+_attr()
+{
+ xfs_attr $* 2>$tmp.err >$tmp.out
+ exit=$?
+ _filter $tmp.out
+ _filter $tmp.err 1>&2
+ return $exit
+}
+
+_attr_list()
+{
+ file=$1
+
+ echo " *** print attributes"
+ if ! _attr -l $file >$tmp.raw
+ then
+ echo " !!! error return"
+ return 1
+ fi
+
+ $AWK_PROG -v file=$file '
+ {
+ print substr($2,2,length($2)-2)
+ count++
+ }
+ END {
+ exit count
+ }
+ ' <$tmp.raw >$tmp.list
+
+ echo " *** $? attribute(s)"
+ for l in `cat $tmp.list`
+ do
+ if ! _attr -g $l $file >$tmp.raw
+ then
+ echo " *** $l"
+ echo " !!! error return"
+ return 1
+ fi
+ $AWK_PROG '
+ NR==1 {
+ print " *** field: " substr($2,2,length($2)-2) \
+ " length: " $5
+ next
+ }
+ {
+ print " ::: " $0
+ }
+ ' <$tmp.raw
+
+ done
+}
+
+
+# real QA test starts here
+
+testfile=$TEST_DIR/attribute_$$
+
+echo "*** list non-existant file"
+_attr_list $testfile
+
+echo "*** list non-xfs file (in /proc)"
+_attr_list /proc/devices
+
+echo "*** list empty file"
+touch $testfile
+_attr_list $testfile
+
+echo "*** query non-existant attribute"
+_attr -g "nonexistant" $testfile 2>&1
+
+echo "*** one attribute"
+echo "fish" | _attr -s fish $testfile
+_attr_list $testfile
+
+echo "*** replace attribute"
+echo "fish3" | _attr -s fish $testfile
+_attr_list $testfile
+
+echo "*** add attribute"
+echo "fish2" | _attr -s snrub $testfile
+_attr_list $testfile
+
+echo "*** remove attribute"
+_attr -r fish $testfile
+_attr_list $testfile
+
+echo "*** add lots of attributes"
+v=0
+while [ $v -lt 1000 ]
+do
+ echo "value_$v" | xfs_attr -s "attribute_$v" $testfile >/dev/null
+ if [ $? -ne 0 ]
+ then
+ echo "!!! failed to add \"attribute_$v\""
+ exit 1
+ fi
+
+ let "v = v + 1"
+done
+
+echo "*** check"
+# don't print it all out...
+xfs_attr -l $testfile \
+ | $AWK_PROG '{ l++ } END {print " *** " l " attribute(s)" }'
+
+echo "*** remove lots of attributes"
+v=0
+while [ $v -lt 1000 ]
+do
+ if ! xfs_attr -r "attribute_$v" $testfile >/dev/null
+ then
+ echo "!!! failed to add \"attribute_$v\""
+ exit 1
+ fi
+
+ let "v = v + 1"
+done
+
+_attr_list $testfile
+
+echo "*** really long value"
+dd if=/dev/zero bs=1024 count=100 2>/dev/null \
+ | _attr -s "long_attr" $testfile >/dev/null
+
+_attr -g "long_attr" $testfile | tail -n +2 | od -t x1
+_attr -r "long_attr" $testfile >/dev/null
+
+
+echo "*** set/get/remove really long names (expect failure)"
+short="XXXXXXXXXX"
+long="$short$short$short$short$short$short$short$short$short$short"
+vlong="$long$long$long"
+
+_attr -s $vlong -V fish $testfile 2>&1 >/dev/null
+_attr -g $vlong $testfile 2>&1 >/dev/null
+_attr -r $vlong $testfile 2>&1 >/dev/null
+
+echo "*** check final"
+
+_attr_list $testfile
+
+echo "*** delete"
+rm -f $testfile
+
+exit
--- /dev/null
+QA output created by 020
+*** list non-existant file
+ *** print attributes
+attr_list: No such file or directory
+Could not list attributes for <TESTFILE>
+ !!! error return
+*** list non-xfs file (in /proc)
+ *** print attributes
+attr_list: Invalid argument
+Could not list attributes for <PROCFILE>
+ !!! error return
+*** list empty file
+ *** print attributes
+ *** 0 attribute(s)
+*** query non-existant attribute
+attr_get: No data available
+Could not get "nonexistant" for <TESTFILE>
+*** one attribute
+Attribute "fish" set to a 5 byte value for <TESTFILE>:
+fish
+
+ *** print attributes
+ *** 1 attribute(s)
+ *** field: fish length: 5
+ ::: fish
+ :::
+*** replace attribute
+Attribute "fish" set to a 6 byte value for <TESTFILE>:
+fish3
+
+ *** print attributes
+ *** 1 attribute(s)
+ *** field: fish length: 6
+ ::: fish3
+ :::
+*** add attribute
+Attribute "snrub" set to a 6 byte value for <TESTFILE>:
+fish2
+
+ *** print attributes
+ *** 2 attribute(s)
+ *** field: fish length: 6
+ ::: fish3
+ :::
+ *** field: snrub length: 6
+ ::: fish2
+ :::
+*** remove attribute
+ *** print attributes
+ *** 1 attribute(s)
+ *** field: snrub length: 6
+ ::: fish2
+ :::
+*** add lots of attributes
+*** check
+ *** 1001 attribute(s)
+*** remove lots of attributes
+ *** print attributes
+ *** 1 attribute(s)
+ *** field: snrub length: 6
+ ::: fish2
+ :::
+*** really long value
+0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+*
+0200000 0a
+0200001
+*** set/get/remove really long names (expect failure)
+attr_set: Bad address
+Could not set "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" for <TESTFILE>
+attr_get: Bad address
+Could not get "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" for <TESTFILE>
+attr_remove: Bad address
+Could not remove "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" for <TESTFILE>
+*** check final
+ *** print attributes
+ *** 1 attribute(s)
+ *** field: snrub length: 6
+ ::: fish2
+ :::
+*** delete
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 021
+# $Id: 1.1 $
+#
+# xfs_db type attr test (pv 797508 linux-xfs & IRIX)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+ rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_s()
+{
+ echo $2 | xfs_attr -s $1 $testfile >/dev/null
+}
+
+_attr()
+{
+ xfs_attr $* 2>$tmp.err >$tmp.out
+ exit=$?
+ sed "s#$SCRATCH_MNT[^ .:]*#<TESTFILE>#g; s#$tmp[^ :]*#<TMPFILE>#g;" $tmp.out
+ sed "s#$SCRATCH_MNT[^ .:]*#<TESTFILE>#g; s#$tmp[^ :]*#<TMPFILE>#g;" $tmp.err 1>&2
+ return $exit
+}
+
+# real QA test starts here
+
+_require_scratch
+
+
+echo "*** mkfs"
+
+rm -f $seq.full
+umount $SCRATCH_DEV >/dev/null 2>&1
+
+mkfs -t xfs -f $SCRATCH_DEV >/dev/null \
+ || _fail "mkfs failed"
+
+echo "*** mount FS"
+mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >/dev/null \
+ || _fail "mount failed"
+
+testfile=$SCRATCH_MNT/testfile
+echo "*** make test file 1"
+
+touch $testfile.1
+echo "v1" | _attr -s "a1" $testfile.1 >/dev/null
+echo "v2--" | _attr -s "a2--" $testfile.1 >/dev/null
+_attr -l $testfile.1
+inum_1=`ls -li $testfile.1 | $AWK_PROG '{ print $1 }'`
+
+echo "*** make test file 2"
+
+touch $testfile.2
+echo "value_1" | _attr -s "a1" $testfile.2 >/dev/null
+echo "value_2" | _attr -s "a2-----" $testfile.2 >/dev/null
+
+(echo start ; dd if=/dev/zero bs=65525 count=1 ; echo end ) \
+ | _attr -s "a3" $testfile.2 >/dev/null
+
+_attr -l $testfile.2
+inum_2=`ls -li $testfile.2 | $AWK_PROG '{ print $1 }'`
+
+echo "*** unmount FS"
+umount $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "umount failed"
+
+echo "*** dump attributes (1)"
+
+xfs_db -r -c "inode $inum_1" -c "print a.sfattr" $SCRATCH_DEV
+
+echo "*** dump attributes (2)"
+
+xfs_db -r -c "inode $inum_2" -c "a a.bmx[0].startblock" -c "print" $SCRATCH_DEV
+
+echo "*** done"
+rm $seq.full
+exit
--- /dev/null
+QA output created by 021
+*** mkfs
+*** mount FS
+*** make test file 1
+Attribute "a1" has a 3 byte value for <TESTFILE>.1
+Attribute "a2--" has a 5 byte value for <TESTFILE>.1
+*** make test file 2
+1+0 records in
+1+0 records out
+Attribute "a1" has a 8 byte value for <TESTFILE>.2
+Attribute "a3" has a 65535 byte value for <TESTFILE>.2
+Attribute "a2-----" has a 8 byte value for <TESTFILE>.2
+*** unmount FS
+*** dump attributes (1)
+a.sfattr.hdr.totsize = 24
+a.sfattr.hdr.count = 2
+a.sfattr.list[0].namelen = 2
+a.sfattr.list[0].valuelen = 3
+a.sfattr.list[0].root = 0
+a.sfattr.list[0].name = "a1"
+a.sfattr.list[0].value = "v1\d"
+a.sfattr.list[1].namelen = 4
+a.sfattr.list[1].valuelen = 5
+a.sfattr.list[1].root = 0
+a.sfattr.list[1].name = "a2--"
+a.sfattr.list[1].value = "v2--\d"
+*** dump attributes (2)
+hdr.info.forw = 0
+hdr.info.back = 0
+hdr.info.magic = 0xfbee
+hdr.count = 3
+hdr.usedbytes = 52
+hdr.firstused = 4044
+hdr.holes = 0
+hdr.freemap[0-2] = [base,size] 0:[56,3988] 1:[0,0] 2:[0,0]
+entries[0-2] = [hashval,nameidx,incomplete,root,local] 0:[0x30b1,4080,0,0,1] 1:[0x30b3,4044,0,0,0] 2:[0xd5aad33f,4060,0,0,1]
+nvlist[0].valuelen = 8
+nvlist[0].namelen = 2
+nvlist[0].name = "a1"
+nvlist[0].value = "value_1\d"
+nvlist[1].valueblk = 0x1
+nvlist[1].valuelen = 65535
+nvlist[1].namelen = 2
+nvlist[1].name = "a3"
+nvlist[2].valuelen = 8
+nvlist[2].namelen = 7
+nvlist[2].name = "a2-----"
+nvlist[2].value = "value_2\d"
+*** done
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 022
+# $Id: 1.1 $
+#
+# Test out a level 0 dump/restore to a tape of a subdir
+# i.e. it is testing out drive_scsitape.c
+#
+# Use src/fsstress to create a directory structure with a mix of files
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -rf $tmp.*; exit \$status" 0 1 2 3 15
+
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_stress
+_erase_hard
+_do_dump_sub
+_do_restore
+_ls_compare_sub
+
+# success, all done
+exit
--- /dev/null
+QA output created by 022
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fsstress.
+
+-----------------------------------------------
+fsstress : -f link=10 -f creat=10 -f mkdir=10 -f truncate=5 -f symlink=10
+-----------------------------------------------
+Erasing tape
+Dumping to tape...
+xfsdump -s DUMP_SUBDIR -f TAPE_DEV -M stress_tape_media -L stress_022 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_022"
+xfsdump: ino map phase 1: parsing subtree selections
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: pruning unneeded subtrees
+xfsdump: ino map phase 4: estimating dump size
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_022 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing listing of dump directory with restore directory
+Files TMP.dump_dir and TMP.restore_dir are identical
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 023
+# $Id: 1.1 $
+#
+# To test xfsdump/restore to tape using a directory with
+# files with data created by src/fill.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@bruce.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -rf $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_fill
+_erase_hard
+_do_dump_sub
+_do_restore
+_diff_compare_sub
+_ls_compare_sub
+
+# success, all done
+exit
--- /dev/null
+QA output created by 023
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -s DUMP_SUBDIR -f TAPE_DEV -M stress_tape_media -L stress_023 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_023"
+xfsdump: ino map phase 1: parsing subtree selections
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: pruning unneeded subtrees
+xfsdump: ino map phase 4: estimating dump size
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_023 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Comparing listing of dump directory with restore directory
+Files TMP.dump_dir and TMP.restore_dir are identical
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 024
+# $Id: 1.1 $
+#
+# Test out incremental dumps
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@bruce.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_fill
+_erase_hard
+_do_dump
+_append_dumpdir_fill
+_erase_hard
+_do_dump_incremental
+_do_restore
+_diff_compare
+
+# success, all done
+exit
--- /dev/null
+QA output created by 024
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -l0 -f TAPE_DEV -M stress_tape_media -L stress_024 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_024"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Erasing tape
+Dumping incrementally to tape...
+xfsdump -l1 -f TAPE_DEV -M stress_tape_media -L stress_024 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 1 incremental dump of HOSTNAME:SCRATCH_MNT based on level 0 dump begun DATE
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_024"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: pruning unneeded subtrees
+xfsdump: ino map phase 4: estimating dump size
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_024 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Only in DUMP_DIR: big
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Only in DUMP_DIR/sub: a00
+Only in DUMP_DIR/sub: a000
+Only in DUMP_DIR/sub: b
+Only in DUMP_DIR/sub: b00
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Only in DUMP_DIR/sub: c00
+Only in DUMP_DIR/sub: d
+Only in DUMP_DIR/sub: d00
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Only in DUMP_DIR/sub: e00
+Only in DUMP_DIR/sub: e000
+Only in DUMP_DIR/sub: f
+Only in DUMP_DIR/sub: f00
+Only in DUMP_DIR/sub: g
+Only in DUMP_DIR/sub: g00
+Only in DUMP_DIR/sub: h
+Only in DUMP_DIR/sub: h00
+Only in DUMP_DIR/sub: h000
+Only in DUMP_DIR/sub: i
+Only in DUMP_DIR/sub: i00
+Only in DUMP_DIR/sub: j
+Only in DUMP_DIR/sub: j00
+Only in DUMP_DIR/sub: k
+Only in DUMP_DIR/sub: k00
+Only in DUMP_DIR/sub: k000
+Only in DUMP_DIR/sub: l
+Only in DUMP_DIR/sub: l00
+Only in DUMP_DIR/sub: m
+Only in DUMP_DIR/sub: m00
+Only in DUMP_DIR/sub: n
+Only in DUMP_DIR/sub: n00
+Only in DUMP_DIR/sub: small
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 025
+# $Id: 1.1 $
+#
+# Test dump/restore using -m option (min strategy)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@bruce.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_fill
+_erase_hard
+_do_dump_min
+_do_restore_min
+_diff_compare
+
+# success, all done
+exit
--- /dev/null
+QA output created by 025
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -m -b 1048576 -l0 -f TAPE_DEV -M stress_tape_media -L stress_025 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_025"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -m -b 1048576 -f TAPE_DEV -L stress_025 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 026
+# $Id: 1.1 $
+#
+# Test xfsdump/xfsrestore to a dump file (as opposed to a tape)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@bruce.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_create_dumpdir_fill
+_do_dump_file
+_do_restore_file
+_diff_compare
+
+# success, all done
+exit
--- /dev/null
+QA output created by 026
+Creating directory system to dump using src/fill.
+Setup ....................................
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L stress_026 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_026"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Restoring from file...
+xfsrestore -f DUMP_FILE -L stress_026 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 027
+# $Id: 1.1 $
+#
+# Test out "xfsdump | xfsrestore"
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_create_dumpdir_fill
+_do_dump_restore
+_diff_compare_sub
+
+# success, all done
+exit
--- /dev/null
+QA output created by 027
+Creating directory system to dump using src/fill.
+Setup ....................................
+xfsdump|xfsrestore ...
+xfsdump -s DUMP_SUBDIR - SCRATCH_MNT | xfsrestore - RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: searching media for dump
+xfsrestore: examining media file 0
+xfsrestore: dump description:
+xfsrestore: hostname: HOSTNAME
+xfsrestore: mount point: SCRATCH_MNT
+xfsrestore: volume: SCRATCH_DEV
+xfsrestore: session time: TIME
+xfsrestore: level: 0
+xfsrestore: session label: ""
+xfsrestore: media label: ""
+xfsrestore: file system id: ID
+xfsrestore: session id: ID
+xfsrestore: media id: ID
+xfsrestore: searching media for directory dump
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: ""
+xfsdump: ino map phase 1: parsing subtree selections
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: pruning unneeded subtrees
+xfsdump: ino map phase 4: estimating dump size
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 028
+# $Id: 1.1 $
+#
+# To test out xfsinvutil
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=0 # success is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+# wipe test dir clean first
+# so dump can be real quick
+_wipe_fs
+
+#
+# Create 5 dumps
+# and on the 3rd dump note the date
+# which we'll use to prune against using xfsinvutil
+#
+i=0
+while [ $i -lt 5 ]; do
+ _do_dump_file -L "session.$i"
+ if [ $i -eq 2 ]; then
+ sleep 1
+ middate=`date '+%m/%d/%Y %T'`
+ fi
+ rm $dump_file
+ sleep 2
+ i=`expr $i + 1`
+done
+
+echo "middate = $middate" >>$seq.full
+
+#
+# Now do the xfsinvutil and
+# look and the inventory before and after
+# to see if it did the job
+#
+_dump_inventory
+_do_invutil -n
+_dump_inventory
+
+
+# success, all done
+exit
--- /dev/null
+QA output created by 028
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.0 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.0"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.1 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.1"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.2 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.2"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.3 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.3"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.4 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.4"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+file system 0:
+ fs id: ID
+ session 0:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.0"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 1:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.1"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 2:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.2"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 3:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.3"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 4:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.4"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+Processing file /var/xfsdump/inventory/UUIDstab
+ Found entry for HOSTNAME:SCRATCH_MNT
+ processing index file
+ /var/xfsdump/inventory/UUID.InvIndex
+ Checking access for
+ /var/xfsdump/inventory/UUID.StObj
+ Mount point match
+ Session 0: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+Pruning this matching entry:
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+LABEL : session.0
+TIME OF DUMP : TIME
+-------------------------------------------------
+
+ Session 1: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+Pruning this matching entry:
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+LABEL : session.1
+TIME OF DUMP : TIME
+-------------------------------------------------
+
+ Session 2: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+Pruning this matching entry:
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+LABEL : session.2
+TIME OF DUMP : TIME
+-------------------------------------------------
+
+ Session 3: HOSTNAME:SCRATCH_MNT
+ Session 4: HOSTNAME:SCRATCH_MNT
+file system 0:
+ fs id: ID
+ session 0:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.3"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 1:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.4"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 029
+# $Id: 1.1 $
+#
+# exercise mkfs log (internal/external) zeroing
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+mkfs_args=""
+logp_args=""
+if [ ! -z "$SCRATCH_LOGDEV" ] # test external log if possible
+then
+ mkfs_args="-l logdev=$SCRATCH_LOGDEV,size=1200b"
+ logp_args="-l $SCRATCH_LOGDEV"
+fi
+
+_filter_logprint()
+{
+ perl -ne '
+ s/data device: ([\w|\/]+)/data device: DDEV/;
+ s/log device: ([\w|\/]+) daddr: (\d+) length: (\d+)/log device: LDEV daddr: XXX length: XXX/;
+ s/log file: "([\w|\/]+)" daddr: (\d+) length: (\d+)/log device: LDEV daddr: XXX length: XXX/;
+ s/skipped (\w+) zeroed blocks/skipped XXX zeroed blocks/;
+ s/^uuid: *[0-9a-f-][0-9a-f-]* *format: *.*$/uuid: <UUID> format: <FORMAT>/;
+ print;
+ '
+}
+
+# real QA test starts here
+#
+_require_scratch
+
+echo
+mkfs -t xfs -f $mkfs_args $SCRATCH_DEV | _filter_mkfs 2>/dev/null
+
+echo
+xfs_logprint $logp_args $SCRATCH_DEV | _filter_logprint
+
+status=0
+exit
--- /dev/null
+QA output created by 029
+
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+xfs_logprint:
+ data device: DDEV
+ log device: LDEV daddr: XXX length: XXX
+
+cycle: 1 version: 1 lsn: 1,0 tail_lsn: 1,0
+length of Log Record: 20 prev offset: -1 num ops: 1
+uuid: <UUID> format: <FORMAT>
+----------------------------------------------------------------------------
+Oper (0): tid: b0c0d0d0 len: 8 clientid: LOG flags: UNMOUNT
+Unmount filesystem
+
+============================================================================
+xfs_logprint: skipped XXX zeroed blocks
+xfs_logprint: physical end of log
+============================================================================
+xfs_logprint: logical end of log
+============================================================================
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 030
+# $Id: 1.3 $
+#
+# exercise xfs_repair repairing broken filesystems
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.repair
+
+# nuke the superblock, AGI, AGF, AGFL; then try repair the damage
+#
+_check_ag()
+{
+ for structure in 'sb 0' 'agf 0' 'agi 0' 'agfl 0'
+ do
+ echo "Corrupting $structure - setting bits to $1"
+ _check_repair $1 "$structure"
+ done
+}
+
+# real QA test starts here
+_require_scratch
+
+# first we need to ensure there are no bogus secondary
+# superblocks between the primary and first secondary
+# superblock (hanging around from earlier tests)...
+#
+size="-d size=100m"
+mkfs -t xfs -f $size $SCRATCH_DEV >/dev/null 2>&1
+if [ $? -ne 0 ] # probably don't have a big enough scratch
+then
+ size=""
+ src/devzero -v -1 $SCRATCH_DEV >/dev/null
+else
+ clear=""
+ eval `xfs_db -r -c "sb 1" -c stack $SCRATCH_DEV | perl -ne '
+ if (/byte offset (\d+), length (\d+)/) {
+ print "clear=", $1 / 512, "\n"; exit
+ }'`
+ [ -z "$clear" ] && echo "Cannot calculate length to clear"
+ src/devzero -v -1 -n "$clear" $SCRATCH_DEV >/dev/null
+fi
+
+# now kick off the real repair test...
+#
+mkfs -t xfs -f $size $SCRATCH_DEV | _filter_mkfs 2>$tmp.mkfs
+source $tmp.mkfs
+_check_ag 0
+_check_ag -1
+
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 030
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+Corrupting sb 0 - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+bad primary superblock - bad magic number !!!
+
+attempting to find secondary superblock...
+found candidate secondary superblock...
+verified secondary superblock...
+writing modified primary superblock
+sb root inode value INO inconsistent with calculated value INO
+resetting superblock root inode pointer to INO
+sb realtime bitmap inode INO inconsistent with calculated value INO
+resetting superblock realtime bitmap ino pointer to INO
+sb realtime summary inode INO inconsistent with calculated value INO
+resetting superblock realtime summary ino pointer to INO
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+Note - stripe unit (0) and width (0) fields have been reset.
+Please set with mount -o sunit=<value>,swidth=<value>
+done
+Corrupting agf 0 - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+bad magic # 0x0 for agf 0
+bad version # 0 for agf 0
+bad length 0 for agf 0, should be LENGTH
+reset bad agf for ag 0
+bad agbno AGBNO for btbno root, agno 0
+bad agbno AGBNO for btbcnt root, agno 0
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting agi 0 - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+bad magic # 0x0 for agi 0
+bad version # 0 for agi 0
+bad length # 0 for agi 0, should be LENGTH
+reset bad agi for ag 0
+bad agbno AGBNO for inobt root, agno 0
+root inode chunk not found
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+error following ag 0 unlinked list
+ - process known inodes and perform inode discovery...
+imap claims in-use inode 131 is free, correcting imap
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting agfl 0 - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting sb 0 - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+bad primary superblock - bad magic number !!!
+
+attempting to find secondary superblock...
+found candidate secondary superblock...
+verified secondary superblock...
+writing modified primary superblock
+sb root inode value INO inconsistent with calculated value INO
+resetting superblock root inode pointer to INO
+sb realtime bitmap inode INO inconsistent with calculated value INO
+resetting superblock realtime bitmap ino pointer to INO
+sb realtime summary inode INO inconsistent with calculated value INO
+resetting superblock realtime summary ino pointer to INO
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+Note - stripe unit (0) and width (0) fields have been reset.
+Please set with mount -o sunit=<value>,swidth=<value>
+done
+Corrupting agf 0 - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+bad magic # 0xffffffff for agf 0
+bad version # -1 for agf 0
+bad sequence # -1 for agf 0
+bad length -1 for agf 0, should be LENGTH
+flfirst -1 in agf 0 too large (max = MAX)
+fllast -1 in agf 0 too large (max = MAX)
+reset bad agf for ag 0
+freeblk count 1 != flcount -1 in ag 0
+bad agbno AGBNO for btbno root, agno 0
+bad agbno AGBNO for btbcnt root, agno 0
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting agi 0 - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+bad magic # 0xffffffff for agi 0
+bad version # -1 for agi 0
+bad sequence # -1 for agi 0
+bad length # -1 for agi 0, should be LENGTH
+reset bad agi for ag 0
+bad agbno AGBNO for inobt root, agno 0
+root inode chunk not found
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+imap claims in-use inode 131 is free, correcting imap
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting agfl 0 - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 031
+# $Id: 1.1 $
+#
+# exercise xfs_repair - ensure repeated use doesn't corrupt
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+rm -f $seq.full
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_check_repair()
+{
+ xfs_repair $SCRATCH_DEV >$tmp.0 2>&1
+ for i in 1 2 3 4
+ do
+ echo "Repairing, iteration $i" | tee -a $seq.full
+ xfs_repair $SCRATCH_DEV 2>&1 | tee -a $seq.full >$tmp.$i
+ diff $tmp.0 $tmp.$i
+ # echo all interesting stuff...
+ perl -ne '
+ s/(rebuilding directory inode) (\d+)/\1 INO/g;
+ /^\S+/ && print;
+ ' $tmp.$i
+ done
+ echo
+}
+
+# prototype file to create various directory forms
+_create_proto()
+{
+ total=$1
+ count=0
+
+ cat >$tmp.proto <<EOF
+DUMMY1
+0 0
+: root directory
+d--777 3 1
+lost+found d--755 3 1
+$
+EOF
+
+ while [ $count -lt $total ]
+ do
+ count=`expr $count + 1`
+ cat >>$tmp.proto <<EOF
+${count}_of_${total}_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ---755 3 1 /bin/true
+EOF
+ done
+ echo '$' >>$tmp.proto
+}
+
+# real QA test starts here
+#
+_require_scratch
+
+MKFSV1="-t xfs -f -p $tmp.proto -n version=1 $SCRATCH_DEV"
+MKFSV2="-t xfs -f -p $tmp.proto -n version=2 $SCRATCH_DEV"
+
+# sanity test - default + one root directory entry
+_create_proto 0
+echo "=== version 1, one entry"
+mkfs $MKFSV1 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+echo "=== version 2, one entry (shortform)"
+mkfs $MKFSV2 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+
+# block-form root directory & repeat
+_create_proto 20
+echo "=== version 1, twenty entries"
+mkfs $MKFSV1 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+echo "=== version 2, twenty entries (block form)"
+mkfs $MKFSV2 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+
+# leaf-form root directory & repeat
+_create_proto 1000
+echo "=== version 1, thousand entries"
+mkfs $MKFSV1 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+echo "=== version 2, thousand entries (leaf form)"
+mkfs $MKFSV2 | _filter_mkfs >/dev/null 2>&1
+_check_repair
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 031
+=== version 1, one entry
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+
+=== version 2, one entry (shortform)
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+
+=== version 1, twenty entries
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+
+=== version 2, twenty entries (block form)
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+
+=== version 1, thousand entries
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+Phase 7 - verify and correct link counts...
+done
+
+=== version 2, thousand entries (leaf form)
+Repairing, iteration 1
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 2
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 3
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+Repairing, iteration 4
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+Phase 3 - for each AG...
+Phase 4 - check for duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+Phase 6 - check inode connectivity...
+rebuilding directory inode INO
+Phase 7 - verify and correct link counts...
+done
+
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 032
+# $Id: 1.1 $
+#
+# cross check mkfs detection of foreign filesystems
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+rm -f $seq.full
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+#
+_require_scratch
+
+echo "Silence is golden."
+for fs in `echo /sbin/mkfs.* | sed -e 's/.sbin.mkfs.//g'`
+do
+ preop="" # for special input needs
+ preargs="" # for any special pre-device options
+ postargs="" # for any special post-device options
+
+ # minix mkfs fails for large devices, restrict to 2000 blocks
+ [ $fs = "minix" ] && postargs=2000
+ # these folk prompt before writing
+ [ $fs = "jfs" ] && preop="echo Y |"
+ [ $fs = "reiserfs" ] && preop="echo y |"
+
+ # overwite the first few Kb - should blow away superblocks
+ src/devzero -n 20 $SCRATCH_DEV >/dev/null
+
+ # create a filesystem of this type
+ echo "=== Creating $fs filesystem..." >>$seq.full
+ echo " ( mkfs -t $fs $SCRATCH_DEV )" >>$seq.full
+ eval $preop mkfs -t $fs $preargs $SCRATCH_DEV $postargs >>$seq.full 2>&1
+
+ # next, ensure we don't overwrite it
+ echo "=== Attempting XFS overwrite of $fs..." >>$seq.full
+ mkfs -t xfs $SCRATCH_DEV >>$seq.full 2>&1
+
+ [ $? -eq 0 ] && echo "Failed - overwrote fs type ${fs}!"
+done
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 032
+Silence is golden.
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 033
+# $Id: 1.1 $
+#
+# exercise xfs_repair repairing broken filesystems (root inodes)
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.repair
+
+# nuke the root, rt bitmap, and rt summary inodes
+#
+_check_root_inos()
+{
+ echo "Corrupting root inode - setting bits to $1"
+ _check_repair $1 "inode $rootino"
+ echo "Corrupting rt bitmap inode - setting bits to $1"
+ _check_repair $1 "inode $rbmino"
+ echo "Corrupting rt summary inode - setting bits to $1"
+ _check_repair $1 "inode $rsumino"
+}
+
+# real QA test starts here
+_require_scratch
+
+# devzero blows away 512byte blocks, so make 512byte inodes
+mkfs -t xfs -f -i size=512 $SCRATCH_DEV | _filter_mkfs 2>/dev/null
+`xfs_db -r -c sb -c p $SCRATCH_DEV | grep 'ino = ' | \
+ sed -e 's/ //g' -e 's/^/export /'`
+# rootino, rbmino, and rsumino are now set (lets blow em away!)
+_check_root_inos 0
+_check_root_inos -1
+
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 033
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+Corrupting root inode - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0x0 on inode INO
+bad version number 0x0 on inode INO
+bad magic number 0x0 on inode INO, resetting magic number
+bad version number 0x0 on inode INO, resetting version number
+imap claims a free inode INO is in use, correcting imap and clearing inode
+cleared root inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+root inode lost
+ - clear lost+found (if it exists) ...
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing root directory
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+resetting inode INO nlinks from 2 to 3
+done
+Corrupting rt bitmap inode - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0x0 on inode INO
+bad version number 0x0 on inode INO
+bad magic number 0x0 on inode INO, resetting magic number
+bad version number 0x0 on inode INO, resetting version number
+imap claims a free inode INO is in use, correcting imap and clearing inode
+cleared realtime bitmap inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing realtime bitmap inode
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting rt summary inode - setting bits to 0
+Wrote 0.50Kb (value 0x0)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0x0 on inode INO
+bad version number 0x0 on inode INO
+bad magic number 0x0 on inode INO, resetting magic number
+bad version number 0x0 on inode INO, resetting version number
+imap claims a free inode INO is in use, correcting imap and clearing inode
+cleared realtime summary inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing realtime summary inode
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+Phase 7 - verify and correct link counts...
+done
+Corrupting root inode - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0xffff on inode INO
+bad version number 0xffffffff on inode INO
+bad (negative) size -1 on inode INO
+bad magic number 0xffff on inode INO, resetting magic number
+bad version number 0xffffffff on inode INO, resetting version number
+bad (negative) size -1 on inode INO
+cleared root inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+root inode lost
+ - clear lost+found (if it exists) ...
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing root directory
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+disconnected dir inode INO, moving to lost+found
+Phase 7 - verify and correct link counts...
+resetting inode INO nlinks from 2 to 3
+done
+Corrupting rt bitmap inode - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0xffff on inode INO
+bad version number 0xffffffff on inode INO
+bad (negative) size -1 on inode INO
+bad magic number 0xffff on inode INO, resetting magic number
+bad version number 0xffffffff on inode INO, resetting version number
+bad (negative) size -1 on inode INO
+cleared realtime bitmap inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing realtime bitmap inode
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+disconnected dir inode INO, moving to lost+found
+Phase 7 - verify and correct link counts...
+done
+Corrupting rt summary inode - setting bits to -1
+Wrote 0.50Kb (value 0xffffffff)
+Phase 1 - find and verify superblock...
+Phase 2 - using internal log
+ - zero log...
+ - scan filesystem freespace and inode maps...
+ - found root inode chunk
+Phase 3 - for each AG...
+ - scan and clear agi unlinked lists...
+ - process known inodes and perform inode discovery...
+bad magic number 0xffff on inode INO
+bad version number 0xffffffff on inode INO
+bad (negative) size -1 on inode INO
+bad magic number 0xffff on inode INO, resetting magic number
+bad version number 0xffffffff on inode INO, resetting version number
+bad (negative) size -1 on inode INO
+cleared realtime summary inode INO
+ - process newly discovered inodes...
+Phase 4 - check for duplicate blocks...
+ - setting up duplicate extent list...
+ - clear lost+found (if it exists) ...
+ - clearing existing "lost+found" inode
+ - deleting existing "lost+found" entry
+ - check for inodes claiming duplicate blocks...
+Phase 5 - rebuild AG headers and trees...
+ - reset superblock...
+Phase 6 - check inode connectivity...
+reinitializing realtime summary inode
+ - resetting contents of realtime bitmap and summary inodes
+ - ensuring existence of lost+found directory
+ - traversing filesystem starting at / ...
+ - traversal finished ...
+ - traversing all unattached subtrees ...
+ - traversals finished ...
+ - moving disconnected inodes to lost+found ...
+disconnected dir inode INO, moving to lost+found
+Phase 7 - verify and correct link counts...
+done
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 034
+# $Id: 1.1 $
+#
+# pv 801241 - check for reference leaks from the *handle ioctls
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=root@leesa.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+}
+trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_scratch
+
+echo "*** init FS"
+
+rm -f $seq.full
+umount $SCRATCH_DEV >/dev/null 2>&1
+echo "*** MKFS ***" >>$seq.full
+echo "" >>$seq.full
+mkfs -t xfs -f $SCRATCH_DEV >>$seq.full 2>&1 \
+ || _fail "mkfs failed"
+mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >>$seq.full 2>&1 \
+ || _fail "mount failed"
+
+echo "*** test"
+
+_check_fs $SCRATCH_DEV
+
+if ! touch $SCRATCH_MNT/fish
+then
+ echo "!!! failed to touch fish"
+ exit
+fi
+
+if ! src/ioctl $SCRATCH_MNT $SCRATCH_MNT/fish >/dev/null 2>&1
+then
+ echo "!!! failed to run ioctl test program"
+ exit
+fi
+
+if ! rm $SCRATCH_MNT/fish
+then
+ echo "!!! failed to remove fish"
+ exit
+fi
+
+# pv 801241 causes corruption here (inode left in agi_unlinked list)
+_check_fs $SCRATCH_DEV
+
+echo "*** done"
+# happy exit
+rm -f $seq.full
+status=0
+exit 0
--- /dev/null
+QA output created by 034
+*** init FS
+*** test
+*** done
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 035
+# $Id: 1.1 $
+#
+# Test doing multiple dumps to tape and restoring the 2nd one
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sagan.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_fill
+_erase_hard
+_do_dump -L $seq.1
+_rewind
+_create_dumpdir_fill2
+_do_dump -L $seq.2
+_do_restore -L $seq.2
+_diff_compare
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 035
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -l0 -f TAPE_DEV -M stress_tape_media -L 035.1 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "035.1"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Creating directory system to dump using src/fill.
+Setup ....
+Dumping to tape...
+xfsdump -l0 -f TAPE_DEV -M stress_tape_media -L 035.2 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "035.2"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: preparing drive
+xfsdump: positioned at media file 0: dump 0, stream 0
+xfsdump: positioned at media file 1: dump 0, stream 0
+xfsdump: positioned at media file 2: dump 0, stream 0
+xfsdump: stream terminator found
+xfsdump: creating dump session media file 0 (media 0, file 2)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 3)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 4)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L 035.2 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: examining media file 1
+xfsrestore: examining media file 2
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/biggg and RESTORE_DIR/DUMP_SUBDIR/biggg are identical
+Files DUMP_DIR/smalll and RESTORE_DIR/DUMP_SUBDIR/smalll are identical
+Files DUMP_DIR/sub/biggg and RESTORE_DIR/DUMP_SUBDIR/sub/biggg are identical
+Files DUMP_DIR/sub/smalll and RESTORE_DIR/DUMP_SUBDIR/sub/smalll are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 036
+# $Id: 1.1 $
+#
+# Test xfsdump/restore minrmt to a remote IRIX tape
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape $RMT_IRIXTAPE_DEV
+_create_dumpdir_fill
+_erase_soft
+_do_dump_min -o -F
+_do_restore_min
+_diff_compare
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 036
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -o -F -m -b 1048576 -l0 -f TAPE_DEV -M stress_tape_media -L stress_036 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_036"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: WARNING: media may contain data. Overwrite option specified
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -m -b 1048576 -f TAPE_DEV -L stress_036 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 037
+# $Id: 1.1 $
+#
+# Test xfsdump/restore minrmt to a remote linux tape
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape $RMT_TAPE_DEV
+_create_dumpdir_fill
+_erase_soft
+_do_dump_min -o -F
+_do_restore_min
+_diff_compare
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 037
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -o -F -m -b 1048576 -l0 -f TAPE_DEV -M stress_tape_media -L stress_037 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_037"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: WARNING: media may contain data. Overwrite option specified
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -m -b 1048576 -f TAPE_DEV -L stress_037 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 038
+# $Id: 1.1 $
+#
+# Test xfsdump/restore to a remote linux tape
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape $RMT_TAPE_DEV
+_create_dumpdir_fill
+_erase_hard
+_do_dump
+_do_restore
+_diff_compare
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 038
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -l0 -f TAPE_DEV -M stress_tape_media -L stress_038 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_038"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 245760 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_038 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 039
+# $Id: 1.1 $
+#
+# Test xfsdump/restore to a remote IRIX tape
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape $RMT_IRIXTAPE_DEV
+_create_dumpdir_fill
+_erase_soft
+_do_dump -o -F
+_do_restore
+_diff_compare
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 039
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -o -F -l0 -f TAPE_DEV -M stress_tape_media -L stress_039 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_039"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: WARNING: media may contain data. Overwrite option specified
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 245760 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_039 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Only in SCRATCH_MNT: RESTORE_SUBDIR
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 040
+# $Id: 1.1 $
+#
+# srcdiff test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+cd `pwd`
+
+if [ -z "$WORKAREA" ]
+then
+ export WORKAREA=../../..
+fi
+
+if [ ! -f $WORKAREA/cmd/xfs/tools/srcdiff ]
+then
+ _notrun "Can't find srcdiff tool under \"$WORKAREA\""
+fi
+
+if [ ! -d $WORKAREA/linux/fs/xfs ]
+then
+ _notrun "Can't find XFS source under \"$WORKAREA\""
+fi
+
+if [ ! -d $WORKAREA/cmd/xfs/include ]
+then
+ _notrun "Can't find XFS command headers under \"$WORKAREA\""
+fi
+
+cd $WORKAREA/cmd/xfs/tools
+perl ./srcdiff -q
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 040
+
+=== Checking headers ===
+
+=== Checking libxfs code ===
+
+=== Checking logprint code ===
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 041
+# $Id: 041,v 1.3 2000/09/27 00:24:17 ajag Exp ajag $
+#
+# growfs QA tests - repeatedly fill/grow the filesystem
+# check the filesystem contents after each operation
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+set +x
+# creator
+owner=ajag@melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ umount $SCRATCH_MNT
+ rm -f $tmp.*
+}
+trap "_cleanup ; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_scratch
+
+_do()
+{
+ if [ $# -ne 1 ]; then echo "Usage: _do \"cmd\"" 1>&2 ; exit 1; fi
+ echo "*** $1" >>$seq.full
+ eval "$1 >>$seq.full 2>&1"
+}
+
+_fill()
+{
+ if [ $# -ne 1 ]; then echo "Usage: _fill \"path\"" 1>&2 ; exit 1; fi
+ echo -n "Fill filesystem... "
+ _do "(src/fill2fs --verbose --dir=$1 --seed=0 --filesize=65536 --stddev=32768 --list=- >>$tmp.manifest)"
+ echo "done"
+}
+
+rm -f $seq.full
+#agsize=16
+agsize=32
+echo -n "Make $agsize megabyte filesystem on SCRATCH_DEV and mount... "
+_do "mkfs -t xfs -d size=${agsize}m,agcount=1 -l internal -f $SCRATCH_DEV"
+_do "mount -t xfs $SCRATCH_DEV $SCRATCH_MNT"
+echo "done"
+
+# full allocation group -> partial; partial -> expand partial + new partial;
+# partial -> expand partial; partial -> full
+# 17 -> 33 -> 35 -> 48 megabytes, converted to fs blocks below
+#for size in 4352 8448 8960 12288
+# 33 -> 67 -> 75 -> 96 converted to fs blocks:
+for size in 8448 17512 19200 24576
+do
+ _fill $SCRATCH_MNT/fill_$size
+ echo -n "Grow filesystem to $size blocks... "
+ _do "xfs_growfs -D ${size} $SCRATCH_MNT"
+ echo "done"
+ echo -n "Flush filesystem... "
+ _do "umount $SCRATCH_MNT"
+ _do "mount -t xfs $SCRATCH_DEV $SCRATCH_MNT"
+ echo "done"
+ echo -n "Check files... "
+ if ! _do "src/fill2fs_check $tmp.manifest"; then
+ echo "fail"
+ echo "Files corrupt/missing after growfs. Test failed see $seq.full"
+ status=1; exit
+ fi
+ echo "done"
+# echo -n "Checking filesystem... "
+# _check_fs $SCRATCH_DEV
+# echo "done"
+done
+
+# success, all done
+echo "Growfs tests passed."
+status=0 ; exit
--- /dev/null
+QA output created by 041
+Make 32 megabyte filesystem on SCRATCH_DEV and mount... done
+Fill filesystem... done
+Grow filesystem to 8448 blocks... done
+Flush filesystem... done
+Check files... done
+Fill filesystem... done
+Grow filesystem to 17512 blocks... done
+Flush filesystem... done
+Check files... done
+Fill filesystem... done
+Grow filesystem to 19200 blocks... done
+Flush filesystem... done
+Check files... done
+Fill filesystem... done
+Grow filesystem to 24576 blocks... done
+Flush filesystem... done
+Check files... done
+Growfs tests passed.
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 042
+# $Id: 042,v 1.2 2000/09/27 00:24:22 ajag Exp ajag $
+#
+# fsr.xfs QA tests
+# create a large fragmented file and check that fsr.xfs doesn't corrupt
+# it or the other contents of the filesystem
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+set +x
+# creator
+owner=ajag@melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ umount $SCRATCH_MNT
+ rm -f $tmp.*
+}
+trap "_cleanup ; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_scratch
+
+_cull_files()
+{
+ perl -e "\$manifest=\"$tmp.manifest\";" -e '
+ open MANIFEST, $manifest;
+ @in = <MANIFEST>;
+ close MANIFEST;
+ open MANIFEST, ">$manifest";
+ for ($i = 0; $i < @in; $i++) {
+ if (($i+1) % 2 == 0) {
+ # remove every second file
+ chomp($s = $in[$i]);
+ if (unlink($s) != 1) {
+ print "_cull_files: could not delete \"$s\"\n";
+ exit(1);
+ }
+ }
+ else {
+ print MANIFEST $in[$i];
+ }
+ }
+ close MANIFEST;'
+}
+
+_do()
+{
+ if [ $# -ne 1 ]; then echo "Usage: _do \"cmd\"" 1>&2 ; exit 1; fi
+ echo "*** $1" >>$seq.full
+ eval "$1 >>$seq.full 2>&1"
+}
+
+
+# create a large contiguous file using dd
+# use fill2fs to fill the filesystem up with 4k sized files
+# fill any remaining space using dd
+# delete every second 4k file - remaining free space should be fragmented
+# use fill2 to generate a very large file - run it until it fails producing a truncated file
+# delete the dd-generated file
+# run fsr.xfs on the filesystem
+# check checksums for remaining files
+
+# create 3 minimum sized (16Mb) allocation groups
+# xfs_repair is going to need three to verify the superblock
+rm -f $seq.full
+echo -n "Make a 48 megabyte filesystem on SCRATCH_DEV and mount... "
+_do "mkfs -t xfs -d size=48m,agcount=3 -l internal -f $SCRATCH_DEV"
+_do "mount -t xfs $SCRATCH_DEV $SCRATCH_MNT"
+echo "done"
+echo -n "Reserve 16 1Mb unfragmented regions... "
+for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+do
+ _do "dd if=/dev/zero of=$SCRATCH_MNT/hole$i bs=4096 count=256"
+ _do "dd if=/dev/zero of=$SCRATCH_MNT/space$i bs=4096 count=1"
+ _do "xfs_bmap $SCRATCH_MNT/hole$i"
+done
+echo "done"
+echo -n "Fill filesystem with 4k files, generate manifest... "
+_do "(src/fill2fs --verbose --dir=$SCRATCH_MNT/fill --seed=0 --filesize=4096 --stddev=0 --list=$tmp.manifest)"
+echo "done"
+echo -n "Use up any further available space using dd... "
+_do "dd if=/dev/zero of=$SCRATCH_MNT/pad bs=4096"
+echo "done"
+echo -n "Delete every second file... "
+if ! _do "_cull_files"; then
+ echo "fail"
+ echo "Could not cull files. Test failed see $seq.full"
+ status=1; exit
+fi
+echo "done"
+echo -n "Create one very large file... "
+_do "src/fill2 -d nbytes=16000000,file=$SCRATCH_MNT/fragmented"
+echo "done"
+_do "xfs_bmap $SCRATCH_MNT/fragmented"
+_do "(sum $SCRATCH_MNT/fragmented >$tmp.sum1)"
+echo -n "Remove other files... "
+_do "rm -rf $SCRATCH_MNT/{pad,hole*}"
+echo "done"
+
+# flush everything
+_do "umount $SCRATCH_MNT"
+_do "mount -t xfs $SCRATCH_DEV $SCRATCH_MNT"
+
+echo -n "Run fsr.xfs on filesystem... "
+_do "fsr.xfs -v $SCRATCH_DEV"
+echo "done"
+_do "xfs_bmap $SCRATCH_MNT/fragmented"
+
+echo -n "Check 4k files... "
+if ! _do "src/fill2fs_check $tmp.manifest"; then
+ echo "fail"
+ echo "4k file is corrupt/missing after fsr. Test failed see $seq.full"
+ status=1; exit
+fi
+echo "done"
+echo -n "Check large file... "
+_do "(sum $SCRATCH_MNT/fragmented >$tmp.sum2)"
+if ! diff $tmp.sum1 $tmp.sum2; then
+ echo "fail"
+ echo "File is corrupt/missing after fsr. Test failed see $seq.full"
+ status=1; exit
+fi
+echo "done"
+
+echo -n "Checking filesystem... "
+_check_fs $SCRATCH_DEV
+echo "done"
+# success, all done
+echo "fsr.xfs tests passed."
+status=0 ; exit
--- /dev/null
+QA output created by 042
+Make a 48 megabyte filesystem on SCRATCH_DEV and mount... done
+Reserve 16 1Mb unfragmented regions... done
+Fill filesystem with 4k files, generate manifest... done
+Use up any further available space using dd... done
+Delete every second file... done
+Create one very large file... done
+Remove other files... done
+Run fsr.xfs on filesystem... done
+Check 4k files... done
+Check large file... done
+Checking filesystem... done
+fsr.xfs tests passed.
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 043
+# $Id: 1.1 $
+#
+# Test out xfsdump/restore but rmv inventory prior to restore.
+# This checks that the on-disk inventory can be successfully
+# rebuilt from the on-tape inventory.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_require_tape
+_create_dumpdir_fill
+_erase_hard
+_do_dump_sub
+rm -rf /var/xfsdump/inventory # delete it - let cleanup fix it
+_do_restore
+_diff_compare_sub
+_ls_compare_sub
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 043
+Put scsi tape driver into variable block size mode
+Creating directory system to dump using src/fill.
+Setup ....................................
+Erasing tape
+Dumping to tape...
+xfsdump -s DUMP_SUBDIR -f TAPE_DEV -M stress_tape_media -L stress_043 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_043"
+xfsdump: ino map phase 1: parsing subtree selections
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: pruning unneeded subtrees
+xfsdump: ino map phase 4: estimating dump size
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: preparing drive
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dumping session inventory
+xfsdump: beginning inventory media file
+xfsdump: media file 1 (media 0, file 1)
+xfsdump: ending inventory media file
+xfsdump: inventory media file size NUM bytes
+xfsdump: writing stream terminator
+xfsdump: beginning media stream terminator
+xfsdump: media file 2 (media 0, file 2)
+xfsdump: ending media stream terminator
+xfsdump: media stream terminator size 1048576 bytes
+xfsdump: dump size (non-dir files) : NUM bytes
+xfsdump: dump complete: SECS seconds elapsed
+Rewinding tape
+Restoring from tape...
+xfsrestore -f TAPE_DEV -L stress_043 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: searching media for dump
+xfsrestore: preparing drive
+xfsrestore: examining media file 0
+xfsrestore: found dump matching specified label:
+xfsrestore: hostname: HOSTNAME
+xfsrestore: mount point: SCRATCH_MNT
+xfsrestore: volume: SCRATCH_DEV
+xfsrestore: session time: TIME
+xfsrestore: level: 0
+xfsrestore: session label: "stress_043"
+xfsrestore: media label: "stress_tape_media"
+xfsrestore: file system id: ID
+xfsrestore: session id: ID
+xfsrestore: media id: ID
+xfsrestore: searching media for directory dump
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: examining media file 1
+xfsrestore: incorporating on-media session inventory into online inventory
+xfsrestore: /var/xfsdump/inventory created
+xfsrestore: using on-media session inventory
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing dump directory with restore directory
+Files DUMP_DIR/big and RESTORE_DIR/DUMP_SUBDIR/big are identical
+Files DUMP_DIR/small and RESTORE_DIR/DUMP_SUBDIR/small are identical
+Files DUMP_DIR/sub/a and RESTORE_DIR/DUMP_SUBDIR/sub/a are identical
+Files DUMP_DIR/sub/a00 and RESTORE_DIR/DUMP_SUBDIR/sub/a00 are identical
+Files DUMP_DIR/sub/a000 and RESTORE_DIR/DUMP_SUBDIR/sub/a000 are identical
+Files DUMP_DIR/sub/b and RESTORE_DIR/DUMP_SUBDIR/sub/b are identical
+Files DUMP_DIR/sub/b00 and RESTORE_DIR/DUMP_SUBDIR/sub/b00 are identical
+Files DUMP_DIR/sub/big and RESTORE_DIR/DUMP_SUBDIR/sub/big are identical
+Files DUMP_DIR/sub/c and RESTORE_DIR/DUMP_SUBDIR/sub/c are identical
+Files DUMP_DIR/sub/c00 and RESTORE_DIR/DUMP_SUBDIR/sub/c00 are identical
+Files DUMP_DIR/sub/d and RESTORE_DIR/DUMP_SUBDIR/sub/d are identical
+Files DUMP_DIR/sub/d00 and RESTORE_DIR/DUMP_SUBDIR/sub/d00 are identical
+Files DUMP_DIR/sub/e and RESTORE_DIR/DUMP_SUBDIR/sub/e are identical
+Files DUMP_DIR/sub/e00 and RESTORE_DIR/DUMP_SUBDIR/sub/e00 are identical
+Files DUMP_DIR/sub/e000 and RESTORE_DIR/DUMP_SUBDIR/sub/e000 are identical
+Files DUMP_DIR/sub/f and RESTORE_DIR/DUMP_SUBDIR/sub/f are identical
+Files DUMP_DIR/sub/f00 and RESTORE_DIR/DUMP_SUBDIR/sub/f00 are identical
+Files DUMP_DIR/sub/g and RESTORE_DIR/DUMP_SUBDIR/sub/g are identical
+Files DUMP_DIR/sub/g00 and RESTORE_DIR/DUMP_SUBDIR/sub/g00 are identical
+Files DUMP_DIR/sub/h and RESTORE_DIR/DUMP_SUBDIR/sub/h are identical
+Files DUMP_DIR/sub/h00 and RESTORE_DIR/DUMP_SUBDIR/sub/h00 are identical
+Files DUMP_DIR/sub/h000 and RESTORE_DIR/DUMP_SUBDIR/sub/h000 are identical
+Files DUMP_DIR/sub/i and RESTORE_DIR/DUMP_SUBDIR/sub/i are identical
+Files DUMP_DIR/sub/i00 and RESTORE_DIR/DUMP_SUBDIR/sub/i00 are identical
+Files DUMP_DIR/sub/j and RESTORE_DIR/DUMP_SUBDIR/sub/j are identical
+Files DUMP_DIR/sub/j00 and RESTORE_DIR/DUMP_SUBDIR/sub/j00 are identical
+Files DUMP_DIR/sub/k and RESTORE_DIR/DUMP_SUBDIR/sub/k are identical
+Files DUMP_DIR/sub/k00 and RESTORE_DIR/DUMP_SUBDIR/sub/k00 are identical
+Files DUMP_DIR/sub/k000 and RESTORE_DIR/DUMP_SUBDIR/sub/k000 are identical
+Files DUMP_DIR/sub/l and RESTORE_DIR/DUMP_SUBDIR/sub/l are identical
+Files DUMP_DIR/sub/l00 and RESTORE_DIR/DUMP_SUBDIR/sub/l00 are identical
+Files DUMP_DIR/sub/m and RESTORE_DIR/DUMP_SUBDIR/sub/m are identical
+Files DUMP_DIR/sub/m00 and RESTORE_DIR/DUMP_SUBDIR/sub/m00 are identical
+Files DUMP_DIR/sub/n and RESTORE_DIR/DUMP_SUBDIR/sub/n are identical
+Files DUMP_DIR/sub/n00 and RESTORE_DIR/DUMP_SUBDIR/sub/n00 are identical
+Files DUMP_DIR/sub/small and RESTORE_DIR/DUMP_SUBDIR/sub/small are identical
+Comparing listing of dump directory with restore directory
+Files TMP.dump_dir and TMP.restore_dir are identical
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 041
+# $Id: 1.1 $
+#
+# external log uuid/format tests
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+_require_logdev
+
+_filter_logprint()
+{
+ perl -ne '
+ s/data device: ([\w|\/]+)/data device: DDEV/;
+ s/log device: ([\w|\/]+) daddr: (\d+) length: (\d+)/log device: LDEV daddr: XXX length: XXX/;
+ s/log file: "([\w|\/]+)" daddr: (\d+) length: (\d+)/log device: LDEV daddr: XXX length: XXX/;
+ s/uuid: ([abcdef\d-]+)\s+format: (.+)/uuid: UUID format: FORMAT/;
+ s/skipped (\w+) zeroed blocks/skipped XXX zeroed blocks/;
+ print;
+ '
+}
+
+_check_mount()
+{
+ echo " *** mount (expect success)"
+ if ! mount -t xfs -o logdev=$SCRATCH_LOGDEV $SCRATCH_DEV $SCRATCH_MNT
+ then
+ echo " !!! mount failed (expecting success)"
+ status=1
+ exit
+ fi
+
+ echo " *** umount"
+ if ! umount $SCRATCH_DEV
+ then
+ echo " !!! umount failed (expecting success)"
+ status=1
+ exit
+ fi
+}
+
+_check_no_mount()
+{
+ echo " *** mount (expect failure)"
+ if mount -t xfs -o logdev=$SCRATCH_LOGDEV $SCRATCH_DEV $SCRATCH_MNT >$tmp.err 2>&1
+ then
+ cat $tmp.err
+ echo " !!! mount succeeded (expecting failure)"
+ status=1
+ exit
+ fi
+}
+
+_check_require_logdev()
+{
+ echo " *** mount without logdev (expect failure)"
+ if mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >$tmp.err 2>&1
+ then
+ cat $tmp.err
+ echo " !!! mount succeeded (expecting failure)"
+ status=1
+ exit
+ fi
+}
+
+
+
+# real QA test starts here
+#
+_require_scratch
+
+echo -e -n "\n\r*** XFS QA 044 - expect mount failure messages\n\r\n\r" >/dev/console
+
+echo "*** mkfs"
+mkfs -t xfs -f -l logdev=$SCRATCH_LOGDEV,size=4096b $SCRATCH_DEV | _filter_mkfs 2>/dev/null
+_check_mount
+_check_require_logdev
+
+echo "*** set uuid"
+xfs_db -x $SCRATCH_DEV -l $SCRATCH_LOGDEV -c "uuid 02020202-0202-0202-0202-020202020202" \
+ || _unexpected
+_check_mount
+
+echo "*** zero log"
+$here/src/loggen -z 100 >$SCRATCH_LOGDEV
+_check_mount
+
+echo "*** write clean log"
+$here/src/loggen -u 2 -f 1 -m 1 -z 100 >$SCRATCH_LOGDEV
+_check_mount
+
+echo "*** write clean log (different format)"
+$here/src/loggen -u 2 -f 99 -m 1 -z 100 >$SCRATCH_LOGDEV
+_check_mount
+
+echo "*** write clean log (different uuid)"
+$here/src/loggen -u 7 -m 1 -z 100 >$SCRATCH_LOGDEV
+_check_no_mount
+
+echo "*** write clean log (different uuid & format)"
+$here/src/loggen -u 7 -f 99 -m 1 -z 100 >$SCRATCH_LOGDEV
+_check_no_mount
+
+echo "*** write dirty log"
+$here/src/loggen -u 2 -e 1 -z 100 >$SCRATCH_LOGDEV
+_check_mount
+
+echo "*** write dirty log (different format)"
+$here/src/loggen -u 2 -f 99 -e 1 -z 100 >$SCRATCH_LOGDEV
+_check_no_mount
+
+echo "*** write dirty log (irix style)"
+$here/src/loggen -u 0 -f 0 -e 1 -z 100 >$SCRATCH_LOGDEV
+_check_no_mount
+
+echo "*** write large dirty log"
+$here/src/loggen -u 2 -e 16000 -z 100 >$SCRATCH_LOGDEV
+_check_mount
+
+echo -e -n "\n\r*** XFS QA 044 - done\n\r\n\r" >/dev/console
+
+status=0
+# if error
+exit
--- /dev/null
+QA output created by 044
+*** mkfs
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+ *** mount (expect success)
+ *** umount
+ *** mount without logdev (expect failure)
+*** set uuid
+clearing log and setting uuid
+writing all SBs
+new uuid = 02020202-0202-0202-0202-020202020202
+ *** mount (expect success)
+ *** umount
+*** zero log
+*** loggen
+ *** zero block (1BB) x 100
+ *** mount (expect success)
+ *** umount
+*** write clean log
+*** loggen
+ *** unmount record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect success)
+ *** umount
+*** write clean log (different format)
+*** loggen
+ *** unmount record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect success)
+ *** umount
+*** write clean log (different uuid)
+*** loggen
+ *** unmount record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect failure)
+*** write clean log (different uuid & format)
+*** loggen
+ *** unmount record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect failure)
+*** write dirty log
+*** loggen
+ *** empty record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect success)
+ *** umount
+*** write dirty log (different format)
+*** loggen
+ *** empty record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect failure)
+*** write dirty log (irix style)
+*** loggen
+ *** empty record (2BB) x 1
+ *** zero block (1BB) x 100
+ *** mount (expect failure)
+*** write large dirty log
+*** loggen
+ *** empty record (2BB) x 16000
+ *** zero block (1BB) x 100
+ *** mount (expect success)
+ *** umount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 045
+# $Id: 1.1 $
+#
+# test mount of two FSes with identical UUID and mount with unknown option
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_get_uuid()
+{
+ xfs_db -r $1 -c "uuid" | $AWK_PROG '
+ /^uuid/ { print $3 }
+ '
+}
+
+# real QA test starts here
+
+_require_scratch
+
+echo "*** get uuid"
+uuid=`_get_uuid $TEST_DEV`
+echo "*** mkfs"
+if ! mkfs -t xfs -f $SCRATCH_DEV >$tmp.out 2>&1
+then
+ cat $tmp.out
+ echo "!!! failed to mkfs on $SCRATCH_DEV"
+ exit
+fi
+
+echo "*** mount fs with bad mount option (expect failure)"
+if mount -t xfs $SCRATCH_DEV $SCRATCH_MNT -o foobar >$tmp.out 2>&1
+then
+ cat $tmp.out
+ echo "!!! mount succeeded (expecting failure)"
+ exit
+fi
+
+echo "*** duplicate uuid"
+xfs_db -x $SCRATCH_DEV -c "uuid $uuid" >/dev/null
+
+echo "*** mount fs with duplicate uuid (expect failure)"
+if mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >$tmp.out 2>&1
+then
+ cat $tmp.out
+ echo "!!! mount succeeded (expecting failure)"
+ exit
+fi
+
+echo "*** ok!"
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 045
+*** get uuid
+*** mkfs
+*** mount fs with bad mount option (expect failure)
+*** duplicate uuid
+*** mount fs with duplicate uuid (expect failure)
+*** ok!
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 046
+# $Id: 1.1 $
+#
+# check on symlinks permissions
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+_create_dumpdir_symlinks
+_do_dump_file
+_do_restore_file
+_ls_compare_sub
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 046
+Creating directory system of symlinks to dump.
+Setup ....
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L stress_046 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "stress_046"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Restoring from file...
+xfsrestore -f DUMP_FILE -L stress_046 RESTORE_DIR
+xfsrestore: version 3.0 - Running single-threaded
+xfsrestore: using online session inventory
+xfsrestore: searching media for directory dump
+xfsrestore: examining media file 0
+xfsrestore: reading directories
+xfsrestore: directory post-processing
+xfsrestore: restoring non-directory files
+xfsrestore: restore complete: SECS seconds elapsed
+Comparing listing of dump directory with restore directory
+Files TMP.dump_dir and TMP.restore_dir are identical
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 047
+# $Id: 1.1 $
+#
+# invutil with interactive responses
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sherman.melbourne.sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.dump
+
+# real QA test starts here
+
+# wipe test dir clean first
+# so dump can be real quick
+_wipe_fs
+
+#
+# Create 5 dumps
+# and on the 3rd dump note the date
+# which we'll use to prune against using xfsinvutil
+#
+i=0
+while [ $i -lt 5 ]; do
+ _do_dump_file -L "session.$i"
+ if [ $i -eq 2 ]; then
+ sleep 1
+ middate=`date '+%m/%d/%Y %T'`
+ fi
+ rm $dump_file
+ sleep 2
+ i=`expr $i + 1`
+done
+
+echo "middate = $middate" >>$seq.full
+
+# Only say No to 1st question to prune
+cat >$tmp.input <<EOF
+N
+Y
+Y
+Y
+Y
+EOF
+
+#
+# Now do the xfsinvutil and
+# look and the inventory before and after
+# to see if it did the job
+#
+_dump_inventory
+_do_invutil <$tmp.input
+_dump_inventory
+
+status=0
+exit
--- /dev/null
+QA output created by 047
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.0 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.0"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: /var/xfsdump/inventory created
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.1 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.1"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.2 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.2"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.3 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.3"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+Dumping to file...
+xfsdump -f DUMP_FILE -M stress_tape_media -L session.4 SCRATCH_MNT
+xfsdump: version 3.0 - Running single-threaded
+xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
+xfsdump: dump date: DATE
+xfsdump: session id: ID
+xfsdump: session label: "session.4"
+xfsdump: ino map phase 1: skipping (no subtrees specified)
+xfsdump: ino map phase 2: constructing initial dump list
+xfsdump: ino map phase 3: skipping (no pruning necessary)
+xfsdump: ino map phase 4: skipping (size estimated in phase 2)
+xfsdump: ino map phase 5: skipping (only one dump stream)
+xfsdump: ino map construction complete
+xfsdump: estimated dump size: NUM bytes
+xfsdump: creating dump session media file 0 (media 0, file 0)
+xfsdump: dumping ino map
+xfsdump: dumping directories
+xfsdump: dumping non-directory files
+xfsdump: ending media file
+xfsdump: media file size NUM bytes
+xfsdump: dump size (non-dir files) : 0 bytes
+xfsdump: dump complete: SECS seconds elapsed
+file system 0:
+ fs id: ID
+ session 0:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.0"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 1:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.1"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 2:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.2"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 3:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.3"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 4:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.4"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+Processing file /var/xfsdump/inventory/UUIDstab
+ Found entry for HOSTNAME:SCRATCH_MNT
+ processing index file
+ /var/xfsdump/inventory/UUID.InvIndex
+ Checking access for
+ /var/xfsdump/inventory/UUID.StObj
+ Mount point match
+ Session 0: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+An entry matching the mount point/time is :
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+TIME OF DUMP : TIME
+
+Do you want to prune this entry: [y/n] -------------------------------------------------
+
+ Session 1: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+An entry matching the mount point/time is :
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+TIME OF DUMP : TIME
+
+Do you want to prune this entry: [y/n] -------------------------------------------------
+
+ Session 2: HOSTNAME:SCRATCH_MNT
+-------------------------------------------------
+An entry matching the mount point/time is :
+UUID : ID
+MOUNT POINT : HOSTNAME:SCRATCH_MNT
+DEV PATH : HOSTNAME:SCRATCH_DEV
+TIME OF DUMP : TIME
+
+Do you want to prune this entry: [y/n] -------------------------------------------------
+
+ Session 3: HOSTNAME:SCRATCH_MNT
+ Session 4: HOSTNAME:SCRATCH_MNT
+file system 0:
+ fs id: ID
+ session 0:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.0"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 1:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.3"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
+ session 2:
+ mount point: HOSTNAME:SCRATCH_MNT
+ device: HOSTNAME:SCRATCH_DEV
+ time: TIME
+ session label: "session.4"
+ session id: ID
+ level: 0
+ resumed: NO
+ subtree: NO
+ streams: 1
+ stream 0:
+ pathname: DUMP_FILE
+ start: ino 0 offset 0
+ end: ino 1 offset 0
+ interrupted: NO
+ media files: 1
+ media file 0:
+ mfile index: 0
+ mfile type: data
+ mfile size: 21016
+ mfile start: ino 0 offset 0
+ mfile end: ino 1 offset 0
+ media label: "stress_tape_media"
+ media id: ID
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 048
+# $Id: 1.1 $
+#
+# test return codes from ioctl on bad userspace address
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+src/fault $TEST_DIR || exit
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 048
+--- ioctl with bad output address
+ --- got error 14 as expected
+--- ioctl with bad input address
+ --- got error 14 as expected
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 049
+# $Id: 1.1 $
+#
+# XFS on loop test
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightfullclaim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+_cleanup()
+{
+ umount $SCRATCH_MNT/test2 > /dev/null 2>&1
+ umount $SCRATCH_MNT/test > /dev/null 2>&1
+ rm -f $tmp.*
+
+ if [ -w $seq.full ]
+ then
+ echo "--- mounts at end (after cleanup)" >> $seq.full
+ mount >> $seq.full
+ fi
+}
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "_cleanup ; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_log()
+{
+ echo "--- $*"
+ echo "--- $*" >> $seq.full
+}
+
+# real QA test starts here
+
+_require_scratch
+_require_loop
+
+rm -f $seq.full
+
+echo "(dev=$SCRATCH_DEV, mount=$SCRATCH_MNT)" >> $seq.full
+echo "" >> $seq.full
+
+echo "--- mounts" >> $seq.full
+mount >> $seq.full
+
+_log "Create ext2 fs on scratch"
+mkfs -t ext2 $SCRATCH_DEV >> $seq.full 2>&1 \
+ || _fail "!!! failed to mkfs ext2"
+
+_log "Mount ext2 fs on scratch"
+mount -t ext2 $SCRATCH_DEV $SCRATCH_MNT >> $seq.full 2>&1 \
+ || _fail "!!! failed to mount"
+
+_log "Create xfs fs in file on scratch"
+mkfs -t xfs -d file,name=$SCRATCH_MNT/test.xfs,size=20m >> $seq.full 2>&1 \
+ || _fail "!!! failed to mkfs xfs"
+
+_log "Make mount points"
+mkdir $SCRATCH_MNT/test $SCRATCH_MNT/test2 >> $seq.full 2>&1 \
+ || _fail "!!! failed to make mount points"
+
+_log "Mount xfs via loop"
+mount -t xfs -o loop $SCRATCH_MNT/test.xfs $SCRATCH_MNT/test >> $seq.full 2>&1 \
+ || _fail "!!! failed to loop mount xfs"
+
+_log "stress"
+src/fsstress -d $SCRATCH_MNT/test -n 1000 $FSSTRESS_AVOID >> $seq.full 2>&1 \
+ || _fail "!!! stress failed"
+
+_log "clean"
+rm -rf $SCRATCH_MNT/test/* >> $seq.full 2>&1 \
+ || _fail "!!! clean failed"
+
+_log "create file for ext2 fs"
+dd if=/dev/zero of=$SCRATCH_MNT/test/test.ext2 bs=1024 count=10240 >> $seq.full 2>&1 \
+ || _fail "!!! create file failed"
+
+_log "Create ext2 fs in file on looped xfs"
+echo y | mkfs -t ext2 $SCRATCH_MNT/test/test.ext2 >> $seq.full 2>&1 \
+ || _fail "!!! failed to mkfs ext2 on xfs"
+
+_log "Mount ext2 on xfs via loop"
+mount -t ext2 -o loop $SCRATCH_MNT/test/test.ext2 $SCRATCH_MNT/test2 >> $seq.full 2>&1 \
+ || _fail "!!! failed to loop mount xfs"
+
+_log "stress ext2 on xfs via loop"
+src/fsstress -d $SCRATCH_MNT/test2 -n 1000 $FSSTRESS_AVOID >> $seq.full 2>&1 \
+ || _fail "!!! stress ext2 failed"
+
+_log "clean"
+rm -rf $SCRATCH_MNT/test/* >> $seq.full 2>&1 \
+ || _fail "!!! clean failed"
+
+_log "umount ext2 on xfs"
+umount $SCRATCH_MNT/test2 >> $seq.full 2>&1 \
+ || _fail "!!! umount ext2 failed"
+
+_log "umount xfs"
+umount $SCRATCH_MNT/test >> $seq.full 2>&1 \
+ || _fail "!!! umount xfs failed"
+
+echo "--- mounts at end (before cleanup)" >> $seq.full
+mount >> $seq.full
+
+rm -f $seq.full
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 049
+--- Create ext2 fs on scratch
+--- Mount ext2 fs on scratch
+--- Create xfs fs in file on scratch
+--- Make mount points
+--- Mount xfs via loop
+--- stress
+--- clean
+--- create file for ext2 fs
+--- Create ext2 fs in file on looped xfs
+--- Mount ext2 on xfs via loop
+--- stress ext2 on xfs via loop
+--- clean
+--- umount ext2 on xfs
+--- umount xfs
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 050
+# $Id: 1.1 $
+#
+# Exercises basic XFS quota functionality
+# MOUNT_OPTIONS env var switches the test type (uid/gid/acct/enfd)
+# options are: (-o) usrquota, grpquota, uqnoenforce, gqnoenforce
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=nathans@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.quota
+. ./common.filter
+
+_cleanup()
+{
+ echo; echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+ rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+rm -f $seq.full $seq.out
+
+_require_quota
+_require_scratch
+
+_mymount()
+{
+ umount $SCRATCH_DEV >/dev/null 2>&1
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT || _fail "mount failed"
+ chmod ugo+rwx $SCRATCH_MNT
+ quot.xfs $SCRATCH_DEV >>$seq.full 2>&1
+}
+
+# real QA test starts here
+mkfs -t xfs -f $SCRATCH_DEV | _filter_mkfs 2>$tmp.mkfs
+cat $tmp.mkfs >>$seq.full
+chmod a+w $seq.full # arbitrary users will write here
+
+# keep the blocksize and data size for dd later
+. $tmp.mkfs
+
+_mymount
+
+# setup exactly what it is we'll be testing
+if ! src/feature -q $SCRATCH_DEV
+then
+ _notrun "XFS quota not enabled"
+elif src/feature -u $SCRATCH_DEV
+then
+ type=u ; id=`_choose_uid`; ln -s $seq.usrquota $seq.out
+elif src/feature -g $SCRATCH_DEV
+then
+ type=g ; id=`_choose_gid`; ln -s $seq.grpquota $seq.out
+elif src/feature -U $SCRATCH_DEV
+then
+ type=u ; id=`_choose_uid`; ln -s $seq.uqnoenforce $seq.out
+elif src/feature -G $SCRATCH_DEV
+then
+ type=g ; id=`_choose_gid`; ln -s $seq.gqnoenforce $seq.out
+else
+ _notrun "No quota support at mount time"
+fi
+
+echo "Using output from '" `ls -l $seq.out` "'" >>$seq.full
+echo "and using type=$type id=$id" >>$seq.full
+
+echo
+echo "*** report no quota settings" | tee -a $seq.full
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+echo
+echo "*** report initial settings" | tee -a $seq.full
+setquota -n -$type $id $SCRATCH_DEV 100 500 4 10
+_file_as_id $SCRATCH_MNT/initme $id $type $dbsize 0
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+echo
+echo "*** push past the soft inode limit" | tee -a $seq.full
+_file_as_id $SCRATCH_MNT/softie1 $id $type $dbsize 0
+_file_as_id $SCRATCH_MNT/softie2 $id $type $dbsize 0
+_mymount
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+echo
+echo "*** push past the soft block limit" | tee -a $seq.full
+_file_as_id $SCRATCH_MNT/softie $id $type $dbsize 140
+_mymount
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+echo
+echo "*** push past the hard inode limit (expect EDQUOT)" | tee -a $seq.full
+for i in 1 2 3 4 5 6 7 8 9 10 11 12
+do
+ _file_as_id $SCRATCH_MNT/hard$i $id $type $dbsize 0
+done
+_mymount
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+echo
+echo "*** push past the hard block limit (expect EDQUOT)" | tee -a $seq.full
+_file_as_id $SCRATCH_MNT/softie $id $type $dbsize 540
+_mymount
+repquota -m -$type $SCRATCH_DEV | _filter_repquota
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 050
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+
+*** report initial settings
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] -- 0 100 500 1 4 10
+
+*** push past the soft inode limit
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] -- 0 100 500 3 4 10
+
+*** push past the soft block limit
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] ++ 140 100 500 none 4 4 10 none
+
+*** push past the hard inode limit (expect EDQUOT)
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 1 0 0 3 0 0
+[NAME] ++ 140 100 500 none 16 4 10 none
+
+*** push past the hard block limit (expect EDQUOT)
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 1 0 0 3 0 0
+[NAME] ++ 540 100 500 none 16 4 10 none
+
+*** unmount
--- /dev/null
+QA output created by 050
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data = bsize=XXX blocks=XXX, imaxpct=PCT
+ = sunit=XXX swidth=XXX, unwritten=X
+naming =VERN bsize=XXX
+log =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+
+*** report initial settings
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] -- 0 100 500 1 4 10
+
+*** push past the soft inode limit
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] -- 0 100 500 3 4 10
+
+*** push past the soft block limit
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] ++ 140 100 500 7 days 4 4 10 7 days
+
+*** push past the hard inode limit (expect EDQUOT)
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] ++ 140 100 500 7 days 10 4 10 7 days
+
+*** push past the hard block limit (expect EDQUOT)
+ Block limits File limits
+user used soft hard grace used soft hard grace
+[NAME] -- 0 0 0 3 0 0
+[NAME] ++ 496 100 500 7 days 10 4 10 7 days
+
+*** unmount
--- /dev/null
+#! /bin/sh
+# XFS QA Test No. 051
+# $Id: 1.1 $
+#
+# Test out ACLs.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=tes@sgi.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+runas=$here/src/runas
+status=1 # FAILure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_cleanup()
+{
+ rm -f $tmp.*
+ rm -rf $TEST_DIR/$seq.dir1
+}
+
+_ls()
+{
+ ls -ln $* | awk '{ print $1, $3, $4, $NF }'
+}
+
+# -----
+# minimal access ACL has ACEs: USER_OBJ, GROUP_OBJ, OTHER_OBJ
+# This is set with chacl(1) and can be changed by chmod(1).
+#
+# Test that this is being set for ACL and for std unix permissions
+# Test that we can get back the same ACL.
+# Test std permissions for rwx.
+# -----
+#
+# Test out default ACLs and that the ACL is being PASSed
+# onto the children of the dir.
+#
+# -----
+# Test out access check for extended ACLs.
+# -> 3 extra ACEs: MASK, GROUP, USER
+# -> the GROUP compares with egid of process _and_ the supplementary
+# groups (as found in /etc/group)
+#
+# Test that mask works for USER, GROUP, GROUP_OBJ
+# Test that the ACE type priority is working
+# -> this would be done by simultaneously matching on ACEs
+# -> interesting if it allows user to specify ACEs in any order
+#
+
+acl1=1001;acl2=1002;acl3=1003
+
+[ -x /bin/chacl ] || _notrun "chacl command not found"
+[ -x $runas ] || _notrun "$runas executable not found"
+
+# get dir
+cd $TEST_DIR
+rm -rf $seq.dir1
+mkdir $seq.dir1
+cd $seq.dir1
+
+#-------------------------------------------------------
+# real QA test starts here
+
+echo ""
+echo "=== Test minimal ACE ==="
+
+echo "Setup file"
+touch file1
+cat <<EOF >file1
+#!/bin/sh
+echo "Test was executed"
+EOF
+chmod u=rwx file1
+chmod g=rw- file1
+chmod o=r-- file1
+chown $acl1.$acl2 file1
+_ls file1
+
+echo ""
+echo "--- Test get and set of ACL ---"
+chacl -l file1
+echo "Expect to FAIL"
+chacl u::r--,g::rwx,o:rw- file1 2>&1
+echo "Expect to PASS"
+chacl u::r--,g::rwx,o::rw- file1 2>&1
+chacl -l file1
+
+echo ""
+echo "--- Test sync of ACL with std permissions ---"
+_ls file1
+chmod u+w file1
+_ls file1
+chacl -l file1
+
+echo ""
+echo "--- Test owner permissions ---"
+chacl u::r-x,g::---,o::--- file1 2>&1
+chacl -l file1
+# change to owner
+echo "Expect to PASS"
+$runas -u $acl1 -g $acl1 ./file1 2>&1
+echo "Expect to FAIL"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+
+echo ""
+echo "--- Test group permissions ---"
+chacl u::---,g::r-x,o::--- file1 2>&1
+chacl -l file1
+echo "Expect to FAIL - acl1 is owner"
+$runas -u $acl1 -g $acl1 ./file1 2>&1
+echo "Expect to PASS - acl2 matches group"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+echo "Expect to PASS - acl2 matches sup group"
+$runas -u $acl2 -g $acl3 -s $acl2 ./file1 2>&1
+echo "Expect to FAIL - acl3 is not in group"
+$runas -u $acl3 -g $acl3 ./file1 2>&1
+
+echo ""
+echo "--- Test other permissions ---"
+chacl u::---,g::---,o::r-x file1 2>&1
+chacl -l file1
+echo "Expect to FAIL - acl1 is owner"
+$runas -u $acl1 -g $acl1 ./file1 2>&1
+echo "Expect to FAIL - acl2 is in group"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+echo "Expect to FAIL - acl2 is in sup. group"
+$runas -u $acl2 -g $acl3 -s $acl2 ./file1 2>&1
+echo "Expect to PASS - acl3 is not owner or in group"
+$runas -u $acl3 -g $acl3 ./file1 2>&1
+
+#-------------------------------------------------------
+
+echo ""
+echo "=== Test Extended ACLs ==="
+
+echo ""
+echo "--- Test adding a USER ACE ---"
+echo "Expect to FAIL as no MASK provided"
+chacl u::---,g::---,o::---,u:$acl2:r-x file1 2>&1
+echo "Ensure that ACL has not been changed"
+chacl -l file1
+echo "Expect to PASS - USER ACE matches user"
+chacl u::---,g::---,o::---,u:$acl2:r-x,m::rwx file1 2>&1
+chacl -l file1
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+echo "Expect to FAIL - USER ACE does not match user"
+$runas -u $acl3 -g $acl3 ./file1 2>&1
+
+echo ""
+echo "--- Test adding a GROUP ACE ---"
+echo "Expect to FAIL as no MASK provided"
+chacl u::---,g::---,o::---,g:$acl2:r-x file1 2>&1
+echo "Ensure that ACL has not been changed"
+chacl -l file1
+chacl u::---,g::---,o::---,g:$acl2:r-x,m::rwx file1 2>&1
+chacl -l file1
+echo "Expect to PASS - GROUP ACE matches group"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+echo "Expect to PASS - GROUP ACE matches sup group"
+$runas -u $acl2 -g $acl1 -s $acl2 ./file1 2>&1
+echo "Expect to FAIL - GROUP ACE does not match group"
+$runas -u $acl3 -g $acl3 ./file1 2>&1
+
+#-------------------------------------------------------
+
+echo ""
+echo "--- Test MASK ---"
+chacl u::---,g::---,o::---,g:$acl2:r-x,m::-wx file1 2>&1
+chacl -l file1
+echo "Expect to FAIL as MASK prohibits execution"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+chacl u::---,g::---,o::---,u:$acl2:r-x,m::-wx file1 2>&1
+echo "Expect to FAIL as MASK prohibits execution"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+
+chacl u::---,g::---,o::---,u:$acl2:r-x,m::r-x file1 2>&1
+echo "Expect to PASS as MASK allows execution"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+
+#-------------------------------------------------------
+
+echo ""
+echo "--- Test ACE priority ---"
+
+chacl o::rwx,g::rwx,u:$acl1:rwx,u::---,m::rwx file1 2>&1
+echo "Expect to FAIL as should match on owner"
+$runas -u $acl1 -g $acl2 ./file1 2>&1
+
+chacl o::---,g::---,u:$acl2:rwx,u::---,m::rwx file1 2>&1
+echo "Expect to PASS as should match on user"
+$runas -u $acl2 -g $acl2 ./file1 2>&1
+
+
+#-------------------------------------------------------
+
+echo ""
+echo "=== Test can read ACLs without access permissions ==="
+# This was a bug in kernel code where syscred wasn't being used
+# to override the capabilities
+chacl o::---,g::---,u::--- file1 2>&1
+chacl -l ./file1
+
+
+#-------------------------------------------------------
+
+echo ""
+echo "=== Test Default ACLs ==="
+mkdir acldir
+chacl -b "u::rwx,g::rwx,o::rwx" "u::r-x,g::r--,o::---" ./acldir 2>&1
+chacl -l ./acldir
+
+cd acldir
+touch file2
+_ls file2
+chacl -l ./file2
+cd ..
+
+#-------------------------------------------------------
+
+# success, all done
+status=0
+exit
--- /dev/null
+QA output created by 051
+
+=== Test minimal ACE ===
+Setup file
+-rwxrw-r-- 1001 1002 file1
+
+--- Test get and set of ACL ---
+file1 []
+Expect to FAIL
+chacl: "u::r--,g::rwx,o:rw-" is an invalid ACL specification.
+Expect to PASS
+file1 [u::r--,g::rwx,o::rw-]
+
+--- Test sync of ACL with std permissions ---
+-r--rwxrw- 1001 1002 file1
+-rw-rwxrw- 1001 1002 file1
+file1 [u::rw-,g::rwx,o::rw-]
+
+--- Test owner permissions ---
+file1 [u::r-x,g::---,o::---]
+Expect to PASS
+Test was executed
+Expect to FAIL
+sh: ./file1: Permission denied
+
+--- Test group permissions ---
+file1 [u::---,g::r-x,o::---]
+Expect to FAIL - acl1 is owner
+sh: ./file1: Permission denied
+Expect to PASS - acl2 matches group
+Test was executed
+Expect to PASS - acl2 matches sup group
+Test was executed
+Expect to FAIL - acl3 is not in group
+sh: ./file1: Permission denied
+
+--- Test other permissions ---
+file1 [u::---,g::---,o::r-x]
+Expect to FAIL - acl1 is owner
+sh: ./file1: Permission denied
+Expect to FAIL - acl2 is in group
+sh: ./file1: Permission denied
+Expect to FAIL - acl2 is in sup. group
+sh: ./file1: Permission denied
+Expect to PASS - acl3 is not owner or in group
+Test was executed
+
+=== Test Extended ACLs ===
+
+--- Test adding a USER ACE ---
+Expect to FAIL as no MASK provided
+chacl: error setting access acl on "file1": Invalid argument
+Ensure that ACL has not been changed
+file1 [u::---,g::---,o::r-x]
+Expect to PASS - USER ACE matches user
+file1 [u::---,g::---,o::---,u:1002:r-x,m::rwx]
+Test was executed
+Expect to FAIL - USER ACE does not match user
+sh: ./file1: Permission denied
+
+--- Test adding a GROUP ACE ---
+Expect to FAIL as no MASK provided
+chacl: error setting access acl on "file1": Invalid argument
+Ensure that ACL has not been changed
+file1 [u::---,g::---,o::---,u:1002:r-x,m::rwx]
+file1 [u::---,g::---,o::---,g:1002:r-x,m::rwx]
+Expect to PASS - GROUP ACE matches group
+Test was executed
+Expect to PASS - GROUP ACE matches sup group
+Test was executed
+Expect to FAIL - GROUP ACE does not match group
+sh: ./file1: Permission denied
+
+--- Test MASK ---
+file1 [u::---,g::---,o::---,g:1002:r-x,m::-wx]
+Expect to FAIL as MASK prohibits execution
+./file1: ./file1: Permission denied
+Expect to FAIL as MASK prohibits execution
+./file1: ./file1: Permission denied
+Expect to PASS as MASK allows execution
+Test was executed
+
+--- Test ACE priority ---
+Expect to FAIL as should match on owner
+sh: ./file1: Permission denied
+Expect to PASS as should match on user
+Test was executed
+
+=== Test can read ACLs without access permissions ===
+./file1 [o::---,g::---,u::---]
+
+=== Test Default ACLs ===
+./acldir [u::rwx,g::rwx,o::rwx/u::r-x,g::r--,o::---]
+-r--r----- 0 0 file2
+./file2 [u::r--,g::r--,o::---]
--- /dev/null
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+# $Id: Makefile,v 2.195 1999/10/19 02:07:28 kenmcd Exp $
+#
+
+TOPDIR = ..
+include $(TOPDIR)/include/builddefs
+
+TESTS = $(shell sed -n -e '/^[0-9][0-9][0-9]*/s/ .*//p' group)
+LDIRT = *.bad *.new *.core *.full *.raw core a.out *.bak check.log check.time
+SUBDIRS = src
+
+default: new remake check $(TESTS) $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+
+install:
+
+include $(BUILDRULES)
--- /dev/null
+______________________
+USING THE XFS QA SUITE
+______________________
+
+Preparing system for tests:
+
+ - compile XFS into your kernel or load XFS modules
+ - install user tools including mkfs.xfs, xfs_db & xfs_bmap
+
+ - create two partitions to use for testing
+ - one TEST partition
+ - format as XFS, mount & optionally populate with
+ NON-IMPORTANT stuff
+ - one SCRATCH partition
+ - leave empty and expect this partition to be clobbered
+ by some tests.
+
+ (these must be two DIFFERENT partitions)
+
+ - setup your environment
+ - setenv TEST_DEV "device containing TEST PARTITION"
+ - setenv TEST_DIR "mount point of TEST PARTITION"
+ - setenv SCRATCH_DEV "device containing SCRATCH PARTITION"
+ - setenv SCRATCH_MNT "mount point for SCRATCH PARTITION"
+ - setenv TAPE_DEV "tape device for testing xfsdump"
+ - setenv RMT_TAPE_DEV "remote tape device for testing xfsdump"
+ - setenv RMT_IRIXTAPE_DEV "remote IRIX tape device for testing xfsdump"
+ - optionally:
+ - setenv SCRATCH_LOGDEV "device for external log"
+ - setenv SCRATCH_RTDEV "device for realtime data"
+ - or add a case to the switch in common.config assigning
+ these variables based on the hostname of your test
+ machine
+
+ - if testing xfsdump, make sure the tape devices have a
+ tape which can be overwritten.
+
+ - make sure $TEST_DEV is a mounted XFS partition
+ - make sure that $SCRATCH_DEV contains nothing useful
+
+Running tests:
+
+ - cd cmd/xfs/stress
+ - ./check 001 002 003 ...
+
+ The check script tests the return value of each script, and
+ compares the output against the expected output. If the output
+ is not as expected, a diff will be output and an .out.bad file
+ will be produced for the failing test.
+
+ Unexpected console messages, crashes and hangs may be considered
+ to be failures but are not necesarily detected by the QA system.
+
+__________________________
+ADDING TO THE XFS QA SUITE
+__________________________
+
+
+Creating new tests scripts:
+
+ Use the "new" script.
+
+Test script environment:
+
+ When developing a new test script keep the following things in
+ mind. All of the environment variables and shell procedures are
+ available to the script once the "common.rc" file has been
+ sourced.
+
+ 1. The tests are run from an arbitrary directory. If you want to
+ do operations on an XFS filesystem (good idea, eh?), then do
+ one of the following:
+
+ (a) Create directories and files at will in the directory
+ $TEST_DIR ... this is within an XFS filesystem and world
+ writeable. You should cleanup when your test is done,
+ e.g. use a _cleanup shell procedure in the trap ... see
+ 001 for an example. If you need to know, the $TEST_DIR
+ direcotry is within the filesystem on the block device
+ $TEST_DEV.
+
+ (b) mkfs a new XFS filesystem on $SCRATCH_DEV, and mount this
+ on $SCRATCH_MNT. Call the the _require_scratch function
+ on startup if you require use of the scratch partition.
+ _require_scratch does some checks on $SCRATCH_DEV &
+ $SCRATCH_MNT and makes sure they're unmounted. You should
+ cleanup when your test is done, and in particular unmount
+ $SCRATCH_MNT.
+ Tests can make use of $SCRATCH_LOGDEV and $SCRATCH_RTDEV
+ for testing external log and realtime volumes - however,
+ these tests need to simply "pass" (e.g. cat $seq.out; exit
+ - or default to an internal log) in the common case where
+ these variables are not set.
+
+ 2. You can safely create temporary files that are not part of the
+ filesystem tests (e.g. to catch output, prepare lists of things
+ to do, etc.) in files named $tmp.<anything>. The standard test
+ script framework created by "new" will initialize $tmp and
+ cleanup on exit.
+
+ 3. By default, tests are run as the same uid as the person
+ executing the control script "check" that runs the test scripts.
+
+ If you need to be root, add a call to the shell procedure
+ _need_to_be_root ... this will do nothing or exit with an
+ error message depending on your current uid.
+
+ 4. Some other useful shell procedures:
+
+ _get_fqdn - echo the host's fully qualified
+ domain name
+
+ _get_pids_by_name - one argument is a process name, and
+ return all of the matching pids on
+ standard output
+
+ _within_tolerance - fancy numerical "close enough is good
+ enough" filter for deterministic
+ output ... see comments in
+ common.filter for an explanation
+
+ _filter_date - turn ctime(3) format dates into the
+ string DATE for deterministic
+ output
+
+Verified output:
+
+ Each test script has a numerical name, e.g. 007, and an associated
+ verified output, e.g. 007.out.
+
+ It is important that the verified output is deterministic, and
+ part of the job of the test script is to filter the output to
+ make this so. Examples of the sort of things that need filtering:
+
+ - dates
+ - pids
+ - hostnames
+ - filesystem names
+ - timezones
+ - variable directory contents
+ - imprecise numbers, especially sizes and times
+
+ Use the "remake" script to recreate the verified output for one
+ or more tests.
+
+Pass/failure:
+
+ The script "check" may be used to run one or more tests.
+
+ Test number $seq is deemed to "pass" when:
+ (a) no "core" file is created,
+ (b) the file $seq.notrun is not created,
+ (c) the exit status is 0, and
+ (d) the output matches the verified output.
+
+ In the "not run" case (b), the $seq.notrun file should contain a
+ short one-line summary of why the test was not run. The standard
+ output is not checked, so this can be used for a more verbose
+ explanation and to provide feedback when the QA test is run
+ interactively.
+
+
+ To force a non-zero exit status use:
+ status=1
+ exit
+
+ Note that:
+ exit 1
+ won't have the desired effect becuase of the way the exit trap
+ works.
+
+ The recent pass/fail history is maintained in the file "check.log".
+ The elapsed time for the most recent pass for each test is kept
+ in "check.time".
--- /dev/null
+#!/bin/sh
+
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+# Control script for QA
+#
+# $Header: /build2/depot/linux/pcp/dev/qa/RCS/check,v 2.32 1999/10/18 06:58:20 kenmcd Exp $
+#
+
+tmp=/tmp/$$
+status=0
+needwrap=true
+try=0
+n_bad=0
+bad=""
+notrun=""
+interrupt=true
+
+# generic initialization
+iam=check
+if ! . ./common.rc
+then
+ echo "check: failed to source common.rc"
+ exit 1
+fi
+
+if [ $UID -ne 0 ]
+then
+ echo "check: QA must be run as root"
+ exit 1
+fi
+
+_wallclock()
+{
+ date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
+}
+
+_timestamp()
+{
+ now=`date "+%D-%T"`
+ echo -n " [$now]"
+}
+
+_wrapup()
+{
+ # for hangcheck ...
+ # remove files that were used by hangcheck
+ #
+ [ -f /tmp/check.pid ] && rm -rf /tmp/check.pid
+ [ -f /tmp/check.sts ] && rm -rf /tmp/check.sts
+
+ if $showme
+ then
+ :
+ elif $needwrap
+ then
+ if [ -f check.time -a -f $tmp.time ]
+ then
+ cat check.time $tmp.time \
+ | $AWK_PROG '
+ { t[$1] = $2 }
+END { if (NR > 0) {
+ for (i in t) print i " " t[i]
+ }
+ }' \
+ | sort -n >$tmp.out
+ mv $tmp.out check.time
+ fi
+
+ if [ -f $tmp.expunged ]
+ then
+ notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'`
+ try=`expr $try - $notrun`
+ list=`echo "$list" | sed -f $tmp.expunged`
+ fi
+
+ echo "" >>check.log
+ date >>check.log
+ echo $list | fmt | sed -e 's/^/ /' >>check.log
+ $interrupt && echo "Interrupted!" >>check.log
+
+ if [ ! -z "$notrun" ]
+ then
+ echo "Not run:$notrun"
+ echo "Not run:$notrun" >>check.log
+ fi
+ if [ ! -z "$n_bad" -a $n_bad != 0 ]
+ then
+ echo "Failures:$bad"
+ echo "Failed $n_bad of $try tests"
+ echo "Failures:$bad" | fmt >>check.log
+ echo "Failed $n_bad of $try tests" >>check.log
+ else
+ echo "Passed all $try tests"
+ echo "Passed all $try tests" >>check.log
+ fi
+ needwrap=false
+ fi
+
+ rm -f $tmp.*
+}
+
+trap "_wrapup; exit \$status" 0 1 2 3 15
+
+# for hangcheck ...
+# Save pid of check in a well known place, so that hangcheck can be sure it
+# has the right pid (getting the pid from ps output is not reliable enough).
+#
+rm -rf /tmp/check.pid
+echo $$ >/tmp/check.pid
+
+# for hangcheck ...
+# Save the status of check in a well known place, so that hangcheck can be
+# sure to know where check is up to (getting test number from ps output is
+# not reliable enough since the trace stuff has been introduced).
+#
+rm -rf /tmp/check.sts
+echo "preamble" >/tmp/check.sts
+
+# don't leave old full output behind on a clean run
+rm -f check.full
+
+# by default don't output timestamps
+timestamp=false
+
+. ./common
+
+[ -f check.time ] || touch check.time
+
+if [ ! -z "$MOUNT_OPTIONS" ]
+then
+ echo "check: \$MOUNT_OPTIONS specifed - \"$MOUNT_OPTIONS\""
+ umount $TEST_DEV
+ # call the overridden mount - make sure the FS starts as
+ # the same as we'll set it later.
+ if ! mount -t xfs $TEST_DEV $TEST_DIR >$tmp.err 2>&1
+ then
+ echo "our mount ..."
+ cat $tmp.err
+ # call the normal mount
+ echo "normal mount ..."
+ /bin/mount -t xfs $TEST_DEV $TEST_DIR
+ echo "check: failed to mount \$TEST_DEV using specified mount options"
+ exit 1
+ fi
+fi
+
+seq="check"
+_check_fs $TEST_DEV
+
+for seq in $list
+do
+ err=false
+ echo -n "$seq"
+ if $showme
+ then
+ echo
+ continue
+ elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
+ then
+ echo " - expunged"
+ rm -f $seq.out.bad
+ echo "/^$seq\$/d" >>$tmp.expunged
+ elif [ ! -f $seq ]
+ then
+ echo " - no such test?"
+ echo "/^$seq\$/d" >>$tmp.expunged
+ else
+ # really going to try and run this one
+ #
+ rm -f $seq.out.bad
+ lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time`
+ [ "X$lasttime" != X ] && echo -n " ${lasttime}s ..."
+ rm -f core $seq.notrun
+
+ # for hangcheck ...
+ echo "$seq" >/tmp/check.sts
+
+ start=`_wallclock`
+ $timestamp && _timestamp
+ sh $seq >$tmp.rawout 2>&1
+ sts=$?
+ $timestamp && _timestamp
+ stop=`_wallclock`
+
+ _fix_malloc <$tmp.rawout >$tmp.out
+ rm -f $tmp.rawout
+
+ if [ -f core ]
+ then
+ echo -n " [dumped core]"
+ mv core $seq.core
+ err=true
+ fi
+
+ if [ -f $seq.notrun ]
+ then
+ echo -n " [not run] "
+ cat $seq.notrun
+ notrun="$notrun $seq"
+ else
+ if [ $sts -ne 0 ]
+ then
+ echo -n " [failed, exit status $sts]"
+ err=true
+ fi
+ if [ ! -f $seq.out ]
+ then
+ echo " - no qualified output"
+ err=true
+ else
+ if diff $seq.out $tmp.out >/dev/null 2>&1
+ then
+ echo ""
+ if $err
+ then
+ :
+ else
+ echo "$seq `expr $stop - $start`" >>$tmp.time
+ fi
+ else
+ echo " - output mismatch (see $seq.out.bad)"
+ mv $tmp.out $seq.out.bad
+ $diff $seq.out $seq.out.bad
+ err=true
+ fi
+ fi
+ fi
+
+ fi
+
+ # come here for each test, except when $showme is true
+ #
+ if $err
+ then
+ bad="$bad $seq"
+ n_bad=`expr $n_bad + 1`
+ quick=false
+ fi
+ [ -f $seq.notrun ] || try=`expr $try + 1`
+
+ seq="after_$seq"
+ _check_fs $TEST_DEV
+
+done
+
+interrupt=false
+status=`expr $n_bad`
+exit
--- /dev/null
+##/bin/sh
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+# common procedures for QA scripts
+#
+# $Header: /disk7/depot/linux/pcp/dev/qa/RCS/common,v 2.52 2000/04/05 18:24:51 kenmcd Exp $
+#
+
+_setenvironment()
+{
+ MSGVERB="text:action"
+ export MSGVERB
+}
+
+here=`pwd`
+rm -f $here/$iam.out
+_setenvironment
+
+check=${check-true}
+
+if $check
+then
+ if make >/tmp/$$.make 2>&1
+ then
+ :
+ else
+ cat /tmp/$$.make
+ echo "Warning: make failed -- some tests may be missing"
+ warn=1
+ fi
+ rm -f /tmp/$$.make
+fi
+
+diff=diff
+if [ ! -z "$DISPLAY" ]
+then
+ which xdiff >/dev/null 2>&1 && diff=xdiff
+ which gdiff >/dev/null 2>&1 && diff=gdiff
+ which tkdiff >/dev/null 2>&1 && diff=tkdiff
+fi
+verbose=false
+quick=${quick-false}
+group=false
+xgroup=false
+showme=false
+sortme=false
+expunge=true
+have_test_arg=false
+rm -f $tmp.list $tmp.tmp $tmp.sed
+
+for r
+do
+
+ if $group
+ then
+ # arg after -g
+ group_list=`sed -n <group -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
+s/ .*//p
+}'`
+ if [ -z "$group_list" ]
+ then
+ echo "Group \"$r\" is empty or not defined?"
+ exit 1
+ fi
+ [ ! -s $tmp.list ] && touch $tmp.list
+ for t in $group_list
+ do
+ if grep -s "^$t\$" $tmp.list >/dev/null
+ then
+ :
+ else
+ echo "$t" >>$tmp.list
+ fi
+ done
+ group=false
+ continue
+
+ elif $xgroup
+ then
+ # arg after -x
+ [ ! -s $tmp.list ] && ls [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] >$tmp.list 2>/dev/null
+ group_list=`sed -n <group -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
+s/ .*//p
+}'`
+ if [ -z "$group_list" ]
+ then
+ echo "Group \"$r\" is empty or not defined?"
+ exit 1
+ fi
+ numsed=0
+ rm -f $tmp.sed
+ for t in $group_list
+ do
+ if [ $numsed -gt 100 ]
+ then
+ sed -f $tmp.sed <$tmp.list >$tmp.tmp
+ mv $tmp.tmp $tmp.list
+ numsed=0
+ rm -f $tmp.sed
+ fi
+ echo "/^$t\$/d" >>$tmp.sed
+ numsed=`expr $numsed + 1`
+ done
+ sed -f $tmp.sed <$tmp.list >$tmp.tmp
+ mv $tmp.tmp $tmp.list
+ xgroup=false
+ continue
+ fi
+
+ xpand=true
+ case "$r"
+ in
+
+ -\?) # usage
+ echo "Usage: $0 [options] [testlist]"'
+
+common options
+ -v verbose
+
+check options
+ -g group[,group...] include tests from these groups
+ -l line mode diff [xdiff]
+ -n show me, do not run tests
+ -q quick, no checks (you are on your own)
+ -T output timestamps
+ -x group[,group...] exclude tests from these groups
+'
+ exit 0
+ ;;
+
+ -g) # -g group ... pick from group file
+ group=true
+ xpand=false
+ ;;
+
+ -l) # line mode for diff, not gdiff over modems
+ diff=diff
+ xpand=false
+ ;;
+
+ -q) # "quick", no checks (you are on your own)
+ quick=true
+ xpand=false
+ ;;
+
+ -n) # show me, don't do it
+ showme=true
+ xpand=false
+ ;;
+
+ -T) # turn on timestamp output
+ timestamp=true
+ xpand=false
+ ;;
+
+ -v)
+ verbose=true
+ xpand=false
+ ;;
+
+ -x) # -x group ... exclude from group file
+ xgroup=true
+ xpand=false
+ ;;
+
+ '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
+ echo "No tests?"
+ status=1
+ exit $status
+ ;;
+
+ [0-9]*-[0-9]*)
+ eval `echo $r | sed -e 's/^/start=/' -e 's/-/ end=/'`
+ ;;
+
+ [0-9]*-)
+ eval `echo $r | sed -e 's/^/start=/' -e 's/-//'`
+ end=`echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //'`
+ if [ -z "$end" ]
+ then
+ echo "No tests in range \"$r\"?"
+ status=1
+ exit $status
+ fi
+ ;;
+
+ *)
+ start=$r
+ end=$r
+ ;;
+
+ esac
+
+ if $xpand
+ then
+ have_test_arg=true
+ $AWK_PROG </dev/null '
+BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
+ | while read id
+ do
+ if grep -s "^$id " group >/dev/null
+ then
+ # in group file ... OK
+ echo $id >>$tmp.list
+ else
+ if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
+ then
+ # expunged ... will be reported, but not run, later
+ echo $id >>$tmp.list
+ else
+ # oops
+ echo "$id - unknown test, ignored"
+ fi
+ fi
+ done
+ fi
+
+done
+
+if [ -s $tmp.list ]
+then
+ # found some valid test numbers ... this is good
+ :
+else
+ if $have_test_arg
+ then
+ # had test numbers, but none in group file ... do nothing
+ touch $tmp.list
+ else
+ # no test numbers, do everything from group file
+ sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <group >$tmp.list
+ fi
+fi
+
+# should be sort -n, but this did not work for Linux when this
+# was ported from IRIX
+#
+list=`sort $tmp.list`
+rm -f $tmp.list $tmp.tmp $tmp.sed
+
+if $quick
+then
+ :
+else
+
+ if ( cd src; make -i )
+ then
+ :
+ else
+ echo
+ echo ":----------------------------------------------"
+ echo ": Warning: make failed in src -- some tests may fail as a result"
+ echo ":----------------------------------------------"
+ echo
+ warn=1
+ fi
+
+fi
--- /dev/null
+##/bin/sh
+
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+#
+# setup and check for config parameters, and in particular
+#
+# TEST_DIR - scratch test directory that is in an already
+# mounted XFS file system, needs to be be world
+# writeable
+# TEST_DEV - device for file system containing TEST_DIR
+# SCRATCH_DEV - device you can make a scratch file system on
+# SCRATCH_MNT - mount point for scratch file system
+#
+# and optionally:
+# SCRATCH_LOGDEV - scratch log device for external log testing
+# SCRATCH_RTDEV - scratch rt dev (only for testing cmds currently)
+# TAPE_DEV - the tape device for the xfsdump tests
+# RMT_TAPE_DEV - the remote tape device for the xfsdump tests
+# RMT_IRIXTAPE_DEV - the IRIX remote tape device for the xfsdump tests
+#
+
+#
+# - This script is shared by the stress test system and the auto-qa
+# system
+# - TEST_DEV & TEST_DIR must be assigned.
+# - this script shouldn't make any assertions about filesystem
+# validity or mountedness.
+#
+
+_readlink()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _readlink filename" 1>&2
+ exit 1
+ fi
+
+ perl -e "\$in=\"$1\";" -e '
+ $lnk = readlink($in);
+ if ($lnk =~ m!^/.*!) {
+ print "$lnk\n";
+ }
+ else {
+ chomp($dir = `dirname $in`);
+ print "$dir/$lnk\n";
+ }'
+}
+
+
+case `hostname -s`
+in
+ fuzzy)
+ TEST_DEV=/dev/sda6
+ TEST_DIR=/mnt/xfs1
+ SCRATCH_DEV=/dev/sda5
+ SCRATCH_MNT=/mnt/xfs0
+ SCRATCH_LOGDEV=/dev/sda7
+ ;;
+ bruce)
+ TEST_DEV=/dev/sda10
+ TEST_DIR=/mnt/xfs1
+ SCRATCH_DEV=/dev/sda9
+ SCRATCH_MNT=/mnt/xfs0
+ SCRATCH_LOGDEV=/dev/sda11
+ TAPE_DEV=/dev/st0
+ RMT_TAPE_DEV=bruce:/dev/st0
+ RMT_IRIXTAPE_DEV=snort:/dev/tape
+ ;;
+ sherman)
+ TEST_DEV=/dev/sda10
+ TEST_DIR=/mnt/xfs1
+ SCRATCH_DEV=/dev/sda9
+ SCRATCH_MNT=/mnt/xfs0
+ ;;
+ sagan)
+ TEST_DEV=/dev/sda6
+ TEST_DIR=/mnt/xfs0
+ SCRATCH_DEV=/dev/sda7
+ SCRATCH_MNT=/mnt/xfs1
+ TAPE_DEV=/dev/st0
+ RMT_TAPE_DEV=sagan:/dev/st0
+ RMT_IRIXTAPE_DEV=snort:/dev/tape
+ ;;
+ leesa)
+ TEST_DEV=/dev/xfs_test
+ TEST_DIR=/mnt/xfs_test
+ SCRATCH_DEV=/dev/xfs_scratch
+ SCRATCH_MNT=/mnt/xfs_scratch
+ SCRATCH_LOGDEV=/dev/xfs_log
+ ;;
+ troppo)
+ TEST_DEV=/dev/hdb6
+ TEST_DIR=/mnt/test
+ SCRATCH_DEV=/dev/hdb7
+ SCRATCH_MNT=/mnt/scratch
+ SCRATCH_LOGDEV=/dev/hdb9
+ SCRATCH_RTDEV=/dev/hdb10
+ ;;
+ lord)
+ TEST_DIR=/xfs
+ TEST_DEV=/dev/sda4
+ SCRATCH_DEV=/dev/hda2
+ SCRATCH_MNT=/xfs1
+ ;;
+ lumpy)
+ TEST_DEV=/dev/sdc5
+ TEST_DIR=/mnt/scratch_0
+ SCRATCH_DEV=/dev/sdc7
+ SCRATCH_MNT=/mnt/scratch_2
+ ;;
+ bongo)
+ TEST_DEV=/dev/hda8
+ TEST_DIR=/xfs1
+ SCRATCH_DEV=/dev/hda9
+ SCRATCH_MNT=/xfs2
+ SCRATCH_LOGDEV=/dev/hda10
+ SCRATCH_RTDEV=/dev/hda11
+ ;;
+
+ *)
+ echo "common.config: Error: need to define parameters for host `hostname -s`"
+ exit 1
+ ;;
+esac
+
+if [ ! -b "$TEST_DEV" ]
+then
+ echo "common.config: Error: \$TEST_DEV ($TEST_DEV) is not a block device"
+ exit 1
+fi
+
+if [ ! -d "$TEST_DIR" ]
+then
+ echo "common.config: Error: \$TEST_DIR ($TEST_DIR) is not a directory"
+ exit 1
+fi
+
+if [ ! -z "$SCRATCH_DEV" -a ! -b "$SCRATCH_DEV" ]
+then
+ echo "common.config: Error: \$SCRATCH_DEV ($SCRATCH_DEV) is not a block device"
+ exit 1
+fi
+
+if [ ! -z "$SCRATCH_DEV" -a ! -d "$SCRATCH_MNT" ]
+then
+ echo "common.config: Error: \$SCRATCH_MNT ($SCRATCH_MNT) is not a directory"
+ exit 1
+fi
+
+# if devfs is running expand the full /dev/.. pathname - this is what will be
+# returned by utilities such as mount
+[ -L "$TEST_DEV" ] && TEST_DEV=`_readlink $TEST_DEV`
+[ -L "$SCRATCH_DEV" ] && SCRATCH_DEV=`_readlink $SCRATCH_DEV`
+[ -L "$SCRATCH_LOGDEV" ] && SCRATCH_LOGDEV=`_readlink $SCRATCH_LOGDEV`
+[ -L "$SCRATCH_RTDEV" ] && SCRATCH_RTDEV=`_readlink $SCRATCH_LOGDEV`
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+##/bin/sh
+
+#
+# Functions useful for xfsdump/xfsrestore tests
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+# --- initializations ---
+rm -f $seq.full
+
+if [ -n "$DEBUGDUMP" ]; then
+ _dump_debug=-v5
+ _restore_debug=-v5
+ _invutil_debug=-d
+fi
+
+# Use dump/restore out of workareas
+PATH="../dump/dump:../dump/restore:../dump/invutil:$PATH"
+export PATH
+
+# status returned for not run tests
+NOTRUNSTS=2
+
+# name those directories
+dump_dir=$SCRATCH_MNT/dump.$$
+dump_file=$tmp.dumpfile
+dump_sdir=dump.$$
+restore_dir=$SCRATCH_MNT/restore.$$
+restore_sdir=restore.$$
+
+dumptape=$TAPE_DEV
+media_label="stress_tape_media"
+session_label="stress_$seq"
+
+nobody=4 # define this uid/gid as a number
+
+_need_to_be_root
+
+# install our cleaner
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# start inventory from a known base - move it aside for test
+if [ -d /var/xfsdump/inventory ]; then
+ if [ -d /var/xfsdump/inventory.$seq ]; then
+ rm -rf /var/xfsdump/inventory.$seq
+ fi
+ mv /var/xfsdump/inventory /var/xfsdump/inventory.$seq
+fi
+
+
+#
+# do a remote/local mt
+#
+_mt()
+{
+ op=$1
+ if _isrmt; then
+ # REMOTE
+ _rmthost=`echo $dumptape | awk -F: '{print $1}'`
+ _rmtdev=`echo $dumptape | awk -F: '{print $2}'`
+ rsh -n $_rmthost "mt -t $_rmtdev $op"
+ # Would have used src/testrmt but get
+ # permission denied from linux to linux for erase !?!
+ else
+ #LOCAL
+ mt -t $dumptape $op
+ fi
+}
+
+_check_onl()
+{
+ _limit=10
+ i=0
+ while [ $i -lt $_limit ]; do
+ echo "Checking online..." >>$seq.full
+ if _mt status >$tmp.status 2>&1; then
+ break;
+ else
+ sleep 2
+ fi
+ i=`expr $i + 1`
+ done
+
+
+ if [ $i -eq $_limit ]; then
+ echo "ERROR: mt -f $dumptape failed"
+ cat $tmp.status
+
+ echo "mt -f $dumptape failed" >$seq.notrun
+ status=$NOTRUNSTS
+ exit
+ fi
+
+
+ if egrep -i 'onl|ready' $tmp.status | grep -iv 'not ready' >/dev/null; then
+ :
+ else
+ echo "ERROR: $dumptape is not online"
+ cat $tmp.status
+
+ echo "dumptape, $dumptape, is not online" >$seq.notrun
+ status=$NOTRUNSTS
+ exit
+ fi
+}
+
+_wait_tape()
+{
+ echo "Wait for tape, $dumptape, ..." >>$seq.full
+
+ i=0
+ while [ $i -lt 20 ]; do
+ echo "Checking status..." >>$seq.full
+ if _mt status 2>&1 | tee -a $seq.full | egrep -i "onl|ready" >/dev/null; then
+ break;
+ else
+ sleep 2
+ fi
+ i=`expr $i + 1`
+ done
+}
+
+#
+# Keep trying so we know we really have rewound
+#
+_rewind()
+{
+ echo "Initiate rewind..." >>$seq.full
+ _wait_tape
+ _mt rewind >/dev/null
+ _wait_tape
+}
+
+#
+# Do a custom erase because:
+# (i) some machines don't support it
+# (ii) some machines take forever to do it
+#
+_erase_soft()
+{
+ echo "Erasing tape" | tee -a $seq.full
+ _rewind
+ _mt weof 3
+# src/testrmt -f $dumptape write
+ _rewind
+}
+
+_erase_hard()
+{
+ echo "Erasing tape" | tee -a $seq.full
+ _mt erase
+}
+
+_isrmt()
+{
+ echo $dumptape | grep ':' >/dev/null
+}
+
+#
+# Get tape ready
+#
+_set_variable()
+{
+ if _isrmt; then
+ :
+ else
+ # LOCAL
+ echo "Put scsi tape driver into variable block size mode"
+ mt -f $dumptape setblk 0
+ fi
+}
+
+_require_tape()
+{
+ if [ $# -eq 0 ]; then
+ dumptape=$TAPE_DEV
+ else
+ dumptape=$1
+ fi
+
+ if [ -z "$dumptape" ]; then
+ echo "This test requires a dump tape - none was specified"
+ echo "No dump tape specified" >$seq.notrun
+ status=$NOTRUNSTS
+ exit
+ fi
+
+ _check_onl
+ _set_variable
+}
+
+_error()
+{
+ echo "Error: $*" | tee -a $seq.full
+ echo "(see $seq.full for details)"
+ status=1
+ exit
+}
+
+_wipe_fs()
+{
+ _require_scratch
+
+ mkfs -t xfs -f $SCRATCH_DEV >>$seq.full ||\
+ _error "mkfs failed"
+
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT >>$seq.full ||\
+ _error "mount failed"
+}
+
+#
+# Cleanup created dirs and files
+# Called by trap
+#
+_cleanup()
+{
+ cd $here
+ rm -f $tmp.*
+
+ if [ -n "$DEBUGDUMP" ]; then
+ # save it for inspection
+ tar -zcvf $seq.inventory.tgz /var/xfsdump/inventory
+ ls -lR /var/xfsdump/inventory >$seq.inventory.ls
+ fi
+
+ # put inventory dir back
+ if [ -d /var/xfsdump/inventory.$seq ]; then
+ rm -rf /var/xfsdump/inventory # get rid of new one
+ mv /var/xfsdump/inventory.$seq /var/xfsdump/inventory
+ fi
+
+ if [ $status -ne $NOTRUNSTS ]; then
+ # Sleep added to stop _check_fs from complaining that the
+ # scratch_dev is still busy
+ sleep 10
+
+ _check_fs $SCRATCH_DEV
+ fi
+}
+
+_stable_fs()
+{
+# umount $SCRATCH_MNT >/dev/null
+# mount $SCRATCH_MNT >/dev/null
+ sync; sync; sleep 15
+}
+
+#
+# Run stress/src/fsstress to create a mixture of
+# files,dirs,links,symlinks
+#
+# Pinched from stress/013.
+#
+_create_dumpdir_stress()
+{
+ echo "Creating directory system to dump using src/fsstress."
+
+ _wipe_fs
+
+ _param="-f link=10 -f creat=10 -f mkdir=10 -f truncate=5 -f symlink=10"
+ _count=200
+ rm -rf $dump_dir
+ if ! mkdir $dump_dir; then
+ echo " failed to mkdir $dump_dir"
+ status=1
+ exit
+ fi
+ echo ""
+ echo "-----------------------------------------------"
+ echo "fsstress : $_param"
+ echo "-----------------------------------------------"
+ if ! $here/src/fsstress $_param $FSSTRESS_AVOID -n $_count -d $dump_dir >$tmp.out 2>&1
+ then
+ echo " fsstress (count=$_count) returned $? - see $seq.full"
+
+ echo "--------------------------------------" >>$here/$seq.full
+ echo "output from fsstress:" >>$here/$seq.full
+ echo "--------------------------------------" >>$here/$seq.full
+ cat $tmp.out >>$here/$seq.full
+ status=1
+ fi
+
+ _stable_fs
+}
+
+_mk_fillconfig1()
+{
+ cat <<End-of-File >$tmp.config
+# pathname size in bytes owner group
+#
+small 10 $nobody $nobody
+big 102400 daemon sys
+sub/small 10 bin bin
+sub/big 102400 $nobody sys
+#
+sub/a 1 $nobody $nobody
+sub/b 2 $nobody $nobody
+sub/c 4 $nobody $nobody
+sub/d 8 $nobody $nobody
+sub/e 16 $nobody $nobody
+sub/f 32 $nobody $nobody
+sub/g 64 $nobody $nobody
+sub/h 128 $nobody $nobody
+sub/i 256 $nobody $nobody
+sub/j 512 $nobody $nobody
+sub/k 1024 $nobody $nobody
+sub/l 2048 $nobody $nobody
+sub/m 4096 $nobody $nobody
+sub/n 8192 $nobody $nobody
+#
+sub/a00 100 $nobody $nobody
+sub/b00 200 $nobody $nobody
+sub/c00 400 $nobody $nobody
+sub/d00 800 $nobody $nobody
+sub/e00 1600 $nobody $nobody
+sub/f00 3200 $nobody $nobody
+sub/g00 6400 $nobody $nobody
+sub/h00 12800 $nobody $nobody
+sub/i00 25600 $nobody $nobody
+sub/j00 51200 $nobody $nobody
+sub/k00 102400 $nobody $nobody
+sub/l00 204800 $nobody $nobody
+sub/m00 409600 $nobody $nobody
+sub/n00 819200 $nobody $nobody
+#
+sub/a000 1000 $nobody $nobody
+sub/e000 16000 $nobody $nobody
+sub/h000 128000 $nobody $nobody
+sub/k000 1024000 $nobody $nobody
+End-of-File
+}
+
+_mk_fillconfig2()
+{
+ cat <<End-of-File >$tmp.config
+# pathname size in bytes
+#
+smalll 10 $nobody $nobody
+biggg 102400 $nobody $nobody
+sub/smalll 10 $nobody $nobody
+sub/biggg 102400 $nobody $nobody
+End-of-File
+}
+
+#
+# Create a bunch of directories/files of different sizes
+# filled with data.
+#
+# Pinched from stress/001.
+#
+_do_create_dumpdir_fill()
+{
+ echo "Creating directory system to dump using src/fill."
+
+ if mkdir -p $dump_dir
+ then
+ :
+ else
+ echo "Error: cannot mkdir \"$dump_dir\""
+ exit 1
+ fi
+ cd $dump_dir
+
+ $verbose && echo -n "Setup "
+ sed -e '/^#/d' $tmp.config \
+ | while read file nbytes owner group perms
+ do
+ dir=`dirname $file`
+ if [ "$dir" != "." ]
+ then
+ if [ ! -d $dir ]
+ then
+ if mkdir $dir
+ then
+ :
+ else
+ $verbose && echo
+ echo "Error: cannot mkdir \"$dir\""
+ exit 1
+ fi
+ fi
+ fi
+ rm -f $file
+ if $here/src/fill $file $file $nbytes
+ then
+ :
+ else
+ $verbose && echo
+ echo "Error: cannot create \"$file\""
+ exit 1
+ fi
+ if [ -n "$owner" -a -n "$group" ]; then
+ chown $owner.$group $file
+ fi
+ if [ -n "$perms" ]; then
+ chmod $perms $file
+ fi
+ $verbose && echo -n "."
+ done
+ $verbose && echo
+
+ cd $here
+}
+
+
+_create_dumpdir_fill()
+{
+ _wipe_fs
+ _mk_fillconfig1
+ _do_create_dumpdir_fill
+ _stable_fs
+}
+
+_create_dumpdir_fill2()
+{
+ _wipe_fs
+ _mk_fillconfig2
+ _do_create_dumpdir_fill
+ _stable_fs
+}
+
+
+
+#
+# Append a subset of the fill'ed files
+# So we can see if just these get dumped on an incremental
+#
+_append_dumpdir_fill()
+{
+ cd $dump_dir
+ cat <<End-of-File >$tmp.config
+# pathname
+#
+small
+sub/big
+#
+sub/a
+sub/c
+sub/e
+End-of-File
+ sed -e '/^#/d' $tmp.config \
+ | while read file
+ do
+ echo 'Extra text' >>$file
+ done
+
+ cd $here
+}
+
+_do_create_dump_symlinks()
+{
+ echo "Creating directory system of symlinks to dump."
+
+ if mkdir -p $dump_dir
+ then
+ :
+ else
+ echo "Error: cannot mkdir \"$dump_dir\""
+ exit 1
+ fi
+ cd $dump_dir
+
+ $verbose && echo -n "Setup "
+ sed -e '/^#/d' $tmp.config \
+ | while read file nbytes owner group owner2 group2 perms perms2
+ do
+ dir=`dirname $file`
+ if [ "$dir" != "." ]
+ then
+ if [ ! -d $dir ]
+ then
+ if mkdir $dir
+ then
+ :
+ else
+ $verbose && echo
+ echo "Error: cannot mkdir \"$dir\""
+ exit 1
+ fi
+ fi
+ fi
+ rm -f $file
+ touch $file
+
+ # Do chmod on symlink using umask.
+ # This won't do the right thing as it subtracts permissions.
+ # However, I don't care, as long as I get some different perms
+ # for testing.
+ if [ -n "$perms2" ]; then
+ omask=`umask`
+ umask $perms2
+ fi
+ ln -s $file $file-link
+ if [ -n "$perms2" ]; then
+ umask $omask
+ fi
+
+ if [ -n "$owner" -a -n "$group" ]; then
+ chown $owner.$group $file
+ fi
+ if [ -n "$owner" -a -n "$group" ]; then
+ chown -h $owner.$group $file-link
+ fi
+ if [ -n "$perms" ]; then
+ chmod $perms $file
+ fi
+ $verbose && echo -n "."
+ done
+ $verbose && echo
+
+ cd $here
+}
+
+_mk_symlink_config()
+{
+ cat <<End-of-File >$tmp.config
+# path size owner1 group1 owner2 group2 perm1 perm2
+#
+a 0 $nobody $nobody daemon sys 124 421
+b 0 daemon sys bin bin 347 743
+sub/a 0 bin bin $nobody sys 777 777
+sub/b 0 $nobody sys $nobody $nobody 367 763
+End-of-File
+}
+
+_create_dumpdir_symlinks()
+{
+ _wipe_fs
+ _mk_symlink_config
+ _do_create_dump_symlinks
+ _stable_fs
+}
+
+#
+# Filter for ls
+# Filter out dates on symlinks
+#
+_ls_filter()
+{
+ $AWK_PROG '/^l/ { date = $8; sub(date,"DATE"); print}
+ {print}' \
+ | sed -e 's/total [0-9][0-9]*/total TOTAL/'
+}
+
+
+#
+# Filter out the non-deterministic dump msgs from
+# xfsdump and xfsrestore
+#
+_dump_filter()
+{
+ sed \
+ -e "s/`hostname`/HOSTNAME/" \
+ -e "s#$SCRATCH_DEV#SCRATCH_DEV#" \
+ -e "s#$dumptape#TAPE_DEV#" \
+ -e "s#$SCRATCH_MNT#SCRATCH_MNT#" \
+ -e "s#$dump_file#DUMP_FILE#" \
+ -e 's/id:[ ]*[0-9a-f-]*/id: ID/' \
+ -e 's/time:[ ].*/time: TIME/' \
+ -e 's/date:[ ].*/date: DATE/' \
+ -e 's/dump begun .*/dump begun DATE/' \
+ -e 's/[0-9][0-9]* seconds/SECS seconds/' \
+ -e '/: dump size/s/[1-9][0-9]*/NUM/' \
+ -e '/dump size:/s/[1-9][0-9]*/NUM/' \
+ -e '/media file size/s/[1-9][0-9]*/NUM/' \
+ -e '/\/dev\/tty/d' \
+ -e '/inventory session uuid/d' \
+
+}
+
+_invutil_filter()
+{
+ _dump_filter \
+ | sed \
+ -e 's/UUID[ ]*:[ ][0-9a-f-]*/UUID : ID/' \
+ -e 's/TIME OF DUMP[ ]*:.*/TIME OF DUMP : TIME/' \
+ -e 's/HOSTNAME:SCRATCH_MNT.*/HOSTNAME:SCRATCH_MNT/' \
+ -e 's#inventory/[0-9a-f-]*#inventory/UUID#' \
+
+}
+
+_dir_filter()
+{
+ sed \
+ -e "s#$dump_file#DUMP_FILE#" \
+ -e "s#$SCRATCH_DEV#SCRATCH_DEV#" \
+ -e "s#$dumptape#TAPE_DEV#" \
+ -e "s#$dump_dir#DUMP_DIR#g" \
+ -e "s#$restore_dir#RESTORE_DIR#g" \
+ -e "s#$SCRATCH_MNT#SCRATCH_MNT#g" \
+ -e "s#$dump_sdir#DUMP_SUBDIR#g" \
+ -e "s#$restore_sdir#RESTORE_SUBDIR#g" \
+
+}
+
+_parse_args()
+{
+ OPTIND=0
+ dump_args=""
+ while getopts "f:FL:o" c $*
+ do
+ case $c
+ in
+ f)
+ [ -z "$OPTARG" ] && _error "missing argument for -f"
+ dumptape=$OPTARG
+ ;;
+ L)
+ [ -z "$OPTARG" ] && _error "missing argument for -L"
+ session_label=$OPTARG
+ ;;
+ o)
+ dump_args="$dump_args -o"
+ ;;
+ F)
+ dump_args="$dump_args -F"
+ ;;
+ \?)
+ _error "invalid argument"
+ ;;
+ esac
+ done
+}
+
+
+#
+# Dump a subdir
+#
+_do_dump_sub()
+{
+ _parse_args $*
+
+ echo "Dumping to tape..."
+ opts="$_dump_debug$dump_args -s $dump_sdir -f $dumptape -M $media_label -L $session_label $SCRATCH_MNT"
+ echo "xfsdump $opts" | _dir_filter
+ xfsdump $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Do full level 0 dump
+#
+_do_dump()
+{
+ _parse_args $*
+
+ echo "Dumping to tape..."
+ opts="$_dump_debug$dump_args -l0 -f $dumptape -M $media_label -L $session_label $SCRATCH_MNT"
+ echo "xfsdump $opts" | _dir_filter
+ xfsdump $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+
+#
+# Do full dump with -m
+#
+_do_dump_min()
+{
+ _parse_args $*
+
+ echo "Dumping to tape..."
+ onemeg=1048576
+ opts="$_dump_debug$dump_args -m -b $onemeg -l0 -f $dumptape -M $media_label -L $session_label $SCRATCH_MNT"
+ echo "xfsdump $opts" | _dir_filter
+ xfsdump $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Do level 1 incremental dump
+#
+_do_dump_incremental()
+{
+ _parse_args $*
+
+ echo "Dumping incrementally to tape..."
+ opts="$_dump_debug$dump_args -l1 -f $dumptape -M $media_label -L $session_label $SCRATCH_MNT"
+ echo "xfsdump $opts" | _dir_filter
+ xfsdump $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Do full dump to file
+#
+_do_dump_file()
+{
+ _parse_args $*
+
+ echo "Dumping to file..."
+ opts="$_dump_debug$dump_args -f $dump_file -M $media_label -L $session_label $SCRATCH_MNT"
+ echo "xfsdump $opts" | _dir_filter
+ xfsdump $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+
+_prepare_restore_dir()
+{
+ rm -rf $restore_dir
+ if ! mkdir $restore_dir; then
+ echo " failed to mkdir $restore_dir"
+ status=1
+ exit
+ fi
+}
+
+
+#
+# Get tape ready and restore dir
+#
+_prepare_restore()
+{
+ _prepare_restore_dir
+
+ echo "Rewinding tape"
+ _rewind
+}
+
+#
+# Restore the tape into $restore_dir
+#
+_do_restore()
+{
+ _parse_args $*
+ _prepare_restore
+
+
+ echo "Restoring from tape..."
+ opts="$_restore_debug$dump_args -f $dumptape -L $session_label $restore_dir"
+ echo "xfsrestore $opts" | _dir_filter
+ xfsrestore $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Restore the tape into $restore_dir using -m
+#
+_do_restore_min()
+{
+ _parse_args $*
+ _prepare_restore
+
+ echo "Restoring from tape..."
+ onemeg=1048576
+ opts="$_restore_debug$dump_args -m -b $onemeg -f $dumptape -L $session_label $restore_dir"
+ echo "xfsrestore $opts" | _dir_filter
+ xfsrestore $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Restore the tape from a dump file
+#
+_do_restore_file()
+{
+ _parse_args $*
+ _prepare_restore_dir
+
+ echo "Restoring from file..."
+ opts="$_restore_debug$dumpargs -f $dump_file -L $session_label $restore_dir"
+ echo "xfsrestore $opts" | _dir_filter
+ xfsrestore $opts 2>&1 | tee -a $seq.full | _dump_filter
+}
+
+#
+# Do xfsdump piped into xfsrestore - xfsdump | xfsrestore
+#
+# Use -s as we want to dump and restore to the same xfs partition
+#
+_do_dump_restore()
+{
+ _parse_args $*
+ _prepare_restore_dir
+ echo "xfsdump|xfsrestore ..."
+ restore_opts="$_restore_debug - $restore_dir"
+ dump_opts="$_dump_debug$dump_args -s $dump_sdir - $SCRATCH_MNT"
+ echo "xfsdump $dump_opts | xfsrestore $restore_opts" | _dir_filter
+ xfsdump $dump_opts 2>$tmp.dump.mlog | xfsrestore $restore_opts 2>&1 | tee -a $seq.full | _dump_filter
+ _dump_filter <$tmp.dump.mlog
+}
+
+#
+# Compare dumped subdirectory with restored dir
+# using ls -lR.
+# Thus no contents are compared but permissions, sizes,
+# owners, etc... are.
+#
+_ls_compare_sub()
+{
+ #
+ # verify we got back what we dumped
+ #
+ echo "Comparing listing of dump directory with restore directory"
+ ls -lR $dump_dir | tee -a $seq.full | _ls_filter >$tmp.dump_dir
+ ls -lR $restore_dir/$dump_sdir | tee -a $seq.full | _ls_filter \
+ | sed -e "s#$restore_sdir\/##" >$tmp.restore_dir
+
+ diff -cs $tmp.dump_dir $tmp.restore_dir | sed -e "s#$tmp#TMP#g"
+}
+
+
+#
+# Compare using recursive diff the files of the dumped
+# subdirectory.
+# This one will compare the contents.
+#
+_diff_compare_sub()
+{
+ echo "Comparing dump directory with restore directory"
+ diff -rs $dump_dir $restore_dir/$dump_sdir | _dir_filter
+}
+
+#
+# Compare using recursive diff the files of the dumped
+# filesystem
+#
+_diff_compare()
+{
+ echo "Comparing dump directory with restore directory"
+ diff -rs $SCRATCH_MNT $restore_dir | _dir_filter
+}
+
+#
+# Check out the dump inventory
+#
+_dump_inventory()
+{
+ xfsdump $_dump_debug -I | tee -a $seq.full | _dump_filter
+}
+
+#
+# Do the xfsinvutil cmd with debug and filters
+# Need to set variable: "$middate" to the invutil date
+#
+_do_invutil()
+{
+ host=`hostname`
+ echo "xfsinvutil $_invutil_debug -M $host:$SCRATCH_MNT \"$middate\" $*" >$seq.full
+ xfsinvutil $_invutil_debug -M $host:$SCRATCH_MNT "$middate" $* \
+ | tee -a $seq.full | _invutil_filter
+}
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+##/bin/sh
+
+#
+# standard filters
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+
+# Checks that given_value is in range of correct_value +/- tolerance.
+# Tolerance can be an absolute value or a percentage of the correct value
+# (see examples with tolerances below).
+# Outputs suitable message to stdout if it's not in range.
+#
+# A verbose option, -v, may be used as the LAST argument
+#
+# e.g.
+# foo: 0.0298 = 0.03 +/- 5%
+# _within_tolerance "foo" 0.0298 0.03 5%
+#
+# foo: 0.0298 = 0.03 +/- 0.01
+# _within_tolerance "foo" 0.0298 0.03 0.01
+#
+# foo: 0.0298 = 0.03 -0.01 +0.002
+# _within_tolerance "foo" 0.0298 0.03 0.01 0.002
+#
+# foo: verbose output of 0.0298 = 0.03 +/- 5%
+# _within_tolerance "foo" 0.0298 0.03 5% -v
+_within_tolerance()
+{
+ _name=$1
+ _given_val=$2
+ _correct_val=$3
+ _mintol=$4
+ _maxtol=$_mintol
+ _verbose=0
+ _debug=false
+
+ # maxtol arg is optional
+ # verbose arg is optional
+ if [ $# -ge 5 ]
+ then
+ if [ "$5" = "-v" ]
+ then
+ _verbose=1
+ else
+ _maxtol=$5
+ fi
+ fi
+ if [ $# -ge 6 ]
+ then
+ [ "$6" = "-v" ] && _verbose=1
+ fi
+
+ # find min with or without %
+ _mintolerance=`echo $_mintol | sed -e 's/%//'`
+ if [ $_mintol = $_mintolerance ]
+ then
+ _min=`echo "scale=5; $_correct_val-$_mintolerance" | bc`
+ else
+ _min=`echo "scale=5; $_correct_val-$_mintolerance*0.01*$_correct_val" | bc`
+ fi
+
+ # find max with or without %
+ _maxtolerance=`echo $_maxtol | sed -e 's/%//'`
+ if [ $_maxtol = $_maxtolerance ]
+ then
+ _max=`echo "scale=5; $_correct_val+$_maxtolerance" | bc`
+ else
+ _max=`echo "scale=5; $_correct_val+$_maxtolerance*0.01*$_correct_val" | bc`
+ fi
+
+ $_debug && echo "min = $_min"
+ $_debug && echo "max = $_max"
+
+ cat <<EOF >$tmp.bc.1
+scale=5;
+if ($_min <= $_given_val) 1;
+if ($_min > $_given_val) 0;
+EOF
+
+ cat <<EOF >$tmp.bc.2
+scale=5;
+if ($_given_val <= $_max) 1;
+if ($_given_val > $_max) 0;
+EOF
+
+ _above_min=`bc <$tmp.bc.1`
+ _below_max=`bc <$tmp.bc.2`
+
+ rm -f $tmp.bc.[12]
+
+ _in_range=`expr $_above_min \& $_below_max`
+
+ # fix up min, max precision for output
+ # can vary for 5.3, 6.2
+ _min=`echo $_min | sed -e 's/0*$//'` # get rid of trailling zeroes
+ _max=`echo $_max | sed -e 's/0*$//'` # get rid of trailling zeroes
+
+ if [ $_in_range -eq 1 ]
+ then
+ [ $_verbose -eq 1 ] && echo $_name is in range
+ return 0
+ else
+ [ $_verbose -eq 1 ] && echo $_name has value of $_given_val
+ [ $_verbose -eq 1 ] && echo $_name is NOT in range $_min .. $_max
+ return 1
+ fi
+}
+
+# ctime(3) dates
+#
+_filter_date()
+{
+ sed \
+ -e 's/[A-Z][a-z][a-z] [A-z][a-z][a-z] *[0-9][0-9]* [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/DATE/'
+}
+
+# prints filtered output on stdout, values (use eval) on stderr
+#
+_filter_mkfs()
+{
+ set -
+ perl -ne '
+ if (/^meta-data=([\w|\/]+)\s+isize=(\d+)\s+agcount=(\d+), agsize=(\d+) blks/) {
+ print STDERR "ddev=$1\nisize=$2\nagcount=$3\nagsize=$4\n";
+ print STDOUT "meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks\n";
+ }
+ if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+), imaxpct=(\d+)/) {
+ print STDERR "dbsize=$1\ndblocks=$2\nimaxpct=$3\n";
+ print STDOUT "data = bsize=XXX blocks=XXX, imaxpct=PCT\n";
+ }
+ if (/^\s+=\s+sunit=(\d+)\s+swidth=(\d+) blks, unwritten=(\d)/) {
+ print STDERR "sunit=$1\nswidth=$2\nunwritten=$3\n";
+ print STDOUT " = sunit=XXX swidth=XXX, unwritten=X\n";
+ }
+ if (/^naming\s+=version\s+(\d+)\s+bsize=(\d+)/) {
+ print STDERR "dirversion=$1\ndirbsize=$2\n";
+ print STDOUT "naming =VERN bsize=XXX\n";
+ }
+ if (/^log\s+=(internal log|[\w|\/]+)\s+bsize=(\d+)\s+blocks=(\d+)/) {
+ print STDERR "ldev=\"$1\"\nlbsize=$2\nlblocks=$3\n";
+ print STDOUT "log =LDEV bsize=XXX blocks=XXX\n";
+ }
+ if (/^realtime\s+=([\w|\/]+)\s+extsz=(\d+)\s+blocks=(\d+), rtextents=(\d+)/) {
+ print STDERR "rtdev=$1\nrtextsz=$2\nrtblocks=$3\nrtextents=$4\n";
+ print STDOUT "realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX\n";
+ }'
+}
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+##/bin/sh
+#
+# Functions useful for quota tests
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+#
+# checks that the XFS quota support in the kernel is enabled
+# and that we have valid quota user tools installed.
+#
+_require_quota()
+{
+ [ ! -x /usr/sbin/repquota ] && _notrun "Quota user tools not installed"
+
+ /usr/sbin/repquota -m -s -a >/dev/null 2>&1
+ [ $? -ne 0 ] && _notrun "Installed quota tools do not support XFS"
+
+ [ ! -f /proc/fs/xfs/xqm ] && _notrun "Kernel does not support XFS quota"
+}
+
+# create a file as a specific user (uid)
+# takes filename, id, type (u/g), blocksize, blockcount
+#
+_file_as_id()
+{
+ [ $# != 5 ] && _notrun "broken call to _file_as_id in test $seq"
+
+ if [ $3 = u ]
+ then
+ magik='$>' # perlspeak for effective uid
+ elif [ $3 = g ]
+ then
+ magik='$)' # perlspeak for effective gid
+ else
+ _notrun "broken type in call to _file_as_id in test $seq"
+ fi
+
+ perl <<EOF
+ \$| = 1;
+ $magik = $2;
+ exec "dd if=/dev/zero of=$1 bs=$4 count=$5 >>$seq.full 2>&1";
+EOF
+}
+
+_choose_uid()
+{
+ perl -ne '@a = split(/:/); END { print $a[2]; }' /etc/passwd
+}
+
+_choose_gid()
+{
+ perl -ne '@a = split(/:/); END { print $a[2]; }' /etc/group
+}
+
+_filter_repquota()
+{
+ perl -ne 's/^(\w+)\s+([-|+])/[NAME] \2/g; print'
+}
+
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+##/bin/sh
+
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+# we need common.config
+if ! . ./common.config
+then
+ echo "$iam: failed to source common.config"
+ exit 1
+fi
+
+# awk
+AWK_PROG=gawk
+
+# ps
+PS_HAVE_BSD=false
+PS_ALL_FLAGS=-efw
+
+# host os
+PLATFORM=linux
+
+# extra parameters for fsstress
+FSSTRESS_AVOID="-f resvsp=0 -f unresvsp=0"
+
+export AWK_PROG PS_HAVE_BSD PS_ALL_FLAGS PLATFORM
+
+# we override mount so we can specify mount options
+
+mount()
+{
+ case "$*"
+ in
+ *remount*)
+ /bin/mount $*
+ ;;
+ *ext2*)
+ /bin/mount $*
+ ;;
+ *xfs*)
+ /bin/mount $* $MOUNT_OPTIONS
+ ;;
+ *)
+ /bin/mount $*
+ ;;
+ esac
+}
+
+#
+
+_get_pids_by_name()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _get_pids_by_name process-name" 1>&2
+ exit 1
+ fi
+
+ # Algorithm ... all ps(1) variants have a time of the form MM:SS or
+ # HH:MM:SS before the psargs field, use this as the search anchor.
+ #
+ # Matches with $1 (process-name) occur if the first psarg is $1
+ # or ends in /$1 ... the matching uses sed's regular expressions,
+ # so passing a regex into $1 will work.
+
+ ps $PS_ALL_FLAGS \
+ | sed -n \
+ -e 's/$/ /' \
+ -e 's/[ ][ ]*/ /g' \
+ -e 's/^ //' \
+ -e 's/^[^ ]* //' \
+ -e "/[0-9]:[0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \
+ -e "/[0-9]:[0-9][0-9] *$1 /s/ .*//p"
+}
+
+# fqdn for localhost
+#
+_get_fqdn()
+{
+ host=`hostname`
+ nslookup $host | $AWK_PROG '{ if ($1 == "Name:") print $2 }'
+}
+
+# fix malloc libs output
+#
+_fix_malloc()
+{
+ # filter out the Electric Fence notice
+ perl -e '
+ while (<>) {
+ if (defined $o && /^\s+Electric Fence/) {
+ chomp($o);
+ print "$o";
+ undef $o;
+ next;
+ }
+ print $o if (defined $o);
+
+ $o=$_;
+ }
+ print $o if (defined $o);
+ '
+}
+
+# check if run as root
+#
+_need_to_be_root()
+{
+ id=`id | sed -e 's/(.*//' -e 's/.*=//'`
+ if [ "$id" -ne 0 ]
+ then
+ echo "Arrgh ... you need to be root (not uid=$id) to run this test"
+ exit 1
+ fi
+}
+
+
+#
+# _df_device : get an IRIX style df line for a given device
+#
+# - returns "" if not mounted
+# - returns fs type in field two (ala IRIX)
+# - joins line together if split by fancy df formatting
+# - strips header etc
+#
+
+_df_device()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _df_device device" 1>&2
+ exit 1
+ fi
+
+ df -T 2>/dev/null | $AWK_PROG -v what=$1 '
+ match($1,what) && NF==1 {
+ v=$1
+ getline
+ print v, $0
+ exit
+ }
+ match($1,what) {
+ print
+ exit
+ }
+ '
+}
+
+#
+# _df_dir : get an IRIX style df line for device where a directory resides
+#
+# - returns fs type in field two (ala IRIX)
+# - joins line together if split by fancy df formatting
+# - strips header etc
+#
+
+_df_dir()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _df_dir device" 1>&2
+ exit 1
+ fi
+
+ df -T $1 2>/dev/null | $AWK_PROG -v what=$1 '
+ NR == 2 && NF==1 {
+ v=$1
+ getline
+ print v, $0;
+ exit 0
+ }
+ NR == 2 {
+ print;
+ exit 0
+ }
+ {}
+ '
+ # otherwise, nada
+}
+
+# return percentage used disk space for mounted device
+
+_used()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _used device" 1>&2
+ exit 1
+ fi
+
+ _df_device $1 | $AWK_PROG '{ sub("%", "") ; print $6 }'
+}
+
+# return the FS type of a mounted device
+#
+_fs_type()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _fs_type device" 1>&2
+ exit 1
+ fi
+
+ _df_device $1 | $AWK_PROG '{ print $2 }'
+}
+
+# return the FS mount options of a mounted device
+#
+_fs_options()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _fs_options device" 1>&2
+ exit 1
+ fi
+
+ $AWK_PROG -v dev=$1 '
+ match($1,dev) { print $4 }
+ ' </proc/mounts
+
+}
+
+# returns device number if a file is a block device
+#
+_is_block_dev()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _is_block_dev dev" 1>&2
+ exit 1
+ fi
+
+ [ -b $1 ] && src/lstat64 $1 | $AWK_PROG '/Device type:/ { print $9 }'
+}
+
+# bail out, setting up .notrun file
+#
+_notrun()
+{
+ echo "$*" >$seq.notrun
+ status=0
+ exit
+}
+
+# just plain bail out
+#
+_fail()
+{
+ echo "$*" | tee -a $seq.full
+ echo "(see $seq.full for details)"
+ status=1
+ exit 1
+}
+
+# this test needs a scratch partition - check we're ok & unmount it
+#
+_require_scratch()
+{
+
+ if [ -z "$SCRATCH_DEV" -o "`_is_block_dev $SCRATCH_DEV`" = "" ]
+ then
+ _notrun "this test requires a valid \$SCRATCH_DEV"
+ fi
+
+ if [ "`_is_block_dev $SCRATCH_DEV`" = "`_is_block_dev $TEST_DEV`" ]
+ then
+ _notrun "this test requires a valid \$SCRATCH_DEV"
+ fi
+
+ # mounted?
+ if mount | grep -q $SCRATCH_DEV
+ then
+ # if it's mounted, make sure its on $SCRATCH_MNT
+ if ! mount | grep $SCRATCH_DEV | grep -q $SCRATCH_MNT
+ then
+ echo "\$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT - aborting"
+ exit 1
+ fi
+
+ # and then unmount it
+
+ if ! umount $SCRATCH_DEV
+ then
+ echo "failed to unmount $SCRATCH_DEV"
+ exit 1
+ fi
+ fi
+
+ # should be ok now
+
+}
+
+# this test needs a logdev
+#
+_require_logdev()
+{
+ if [ -z "$SCRATCH_LOGDEV" -o ! -b "$SCRATCH_LOGDEV" ]
+ then
+ _notrun "This test requires a valid \$SCRATCH_LOGDEV"
+ fi
+}
+
+# this test requires loopback device support
+#
+_require_loop()
+{
+ if grep loop /proc/devices >/dev/null 2>&1
+ then
+ :
+ else
+ _notrun "This test requires loopback device support"
+ fi
+}
+
+
+# check that a FS is mounted as XFS. if so, return mount point
+#
+_xfs_mounted()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _xfs_mounted device" 1>&2
+ exit 1
+ fi
+
+ device=$1
+
+ if mount | grep $device | $AWK_PROG '
+ /type xfs/ { print $3 ; exit 0 }
+ END { exit 1 }
+ '
+ then
+ echo "_xfs_mounted: $device is not a mounted XFS FS"
+ exit 1
+ fi
+}
+
+# remount a FS to a new mode (ro or rw)
+#
+
+_remount()
+{
+ if [ $# -ne 2 ]
+ then
+ echo "Usage: _remount device ro/rw" 1>&2
+ exit 1
+ fi
+ device=$1
+ mode=$2
+
+ if ! mount -o remount,$mode $device
+ then
+ echo "_remount: failed to remount filesystem on $device as $mode"
+ exit 1
+ fi
+
+ # we might like to check here later
+ #options=`_fs_options $device`
+
+}
+
+# run xfs_check on a FS.
+#
+# if the filesystem is mounted, it's either remounted ro before being
+# checked or it's unmounted and then remounted
+#
+
+USE_REMOUNT=0
+
+_check_fs()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _check_fs device" 1>&2
+ exit 1
+ fi
+
+ device=$1
+ type=`_fs_type $device`
+ ok=1
+
+ if [ "$type" = "xfs" ]
+ then
+ # mounted...
+
+ if [ $USE_REMOUNT -eq 0 ]
+ then
+ mountpoint=`_xfs_mounted $device`
+ umount $device
+ else
+ _remount $device ro
+ fi
+ fi
+
+ xfs_logprint -t $device 2>&1 | tee $tmp.fs_check | grep -q "<CLEAN>"
+ if [ $? -ne 0 ]
+ then
+ echo "_check_fs: filesystem on $device has dirty log (see $seq.full)"
+
+ echo "_check_fs: filesystem on $device has dirty log" >>$seq.full
+ echo "*** xfs_logprint -t output ***" >>$seq.full
+ cat $tmp.fs_check >>$seq.full
+ echo "*** end xfs_logprint output" >>$seq.full
+
+ ok=0
+ fi
+
+
+ xfs_check $device 2>&1 | _fix_malloc >$tmp.fs_check
+ if [ -s $tmp.fs_check ]
+ then
+ echo "_check_fs: filesystem on $device is inconsistent (c) (see $seq.full)"
+
+ echo "_check_fs: filesystem on $device is inconsistent" >>$seq.full
+ echo "*** xfs_check output ***" >>$seq.full
+ cat $tmp.fs_check >>$seq.full
+ echo "*** end xfs_check output" >>$seq.full
+
+ ok=0
+ fi
+
+ if ! xfs_repair -n $device >$tmp.fs_check 2>&1
+ then
+ echo "_check_fs: filesystem on $device is inconsistent (r) (see $seq.full)"
+
+ echo "_check_fs: filesystem on $device is inconsistent" >>$seq.full
+ echo "*** xfs_repair -n output ***" >>$seq.full
+ cat $tmp.fs_check | _fix_malloc >>$seq.full
+ echo "*** end xfs_repair output" >>$seq.full
+
+ ok=0
+ fi
+ rm -f $tmp.fs_check
+
+ if [ $ok -eq 0 ]
+ then
+ echo "*** mount output ***" >>$seq.full
+ mount >>$seq.full
+ echo "*** end mount output" >>$seq.full
+ fi
+
+ if [ "$type" = "xfs" ]
+ then
+ # mounted...
+ if [ $USE_REMOUNT -eq 0 ]
+ then
+ if ! mount -t xfs $device $mountpoint
+ then
+ echo "!!! failed to remount $device on $mountpoint"
+ ok=0
+ fi
+ else
+ _remount $device rw
+ fi
+ fi
+
+ [ $ok -eq 0 ] && exit 1
+
+}
+
+################################################################################
+
+[ -d /usr/bsd ] && PATH=$PATH:/usr/bsd
+[ -d /usr/freeware/bin ] && PATH=$PATH:/usr/freeware/bin
+
+if [ "$iam" != new ]
+then
+
+ # make some further configuration checks here
+
+ if [ "$TEST_DEV" = "" ]
+ then
+ echo "common.rc: Error: \$TEST_DEV is not set"
+ exit 1
+ fi
+
+ if [ "`_fs_type $TEST_DEV`" != "xfs" ]
+ then
+ echo "common.rc: Error: \$TEST_DEV ($TEST_DEV) is not a MOUNTED XFS filesystem"
+ df -T $TEST_DEV
+ exit 1
+ fi
+
+fi
+
+# check for some required biunaries on our $PATH
+#
+for exec in mkfs.xfs xfs_logprint xfs_check xfs_repair xfs_db
+do
+ if which $exec >/dev/null 2>&1
+ then
+ :
+ else
+ echo "common.rc: cannot find $exec on \$PATH=$PATH"
+ exit 1
+ fi
+done
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+##/bin/sh
+
+#
+# Functions useful for xfs_repair tests
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+_zero_position()
+{
+ value=$1
+ struct="$2"
+
+ # set values for off/len variables provided by db
+ eval `xfs_db -r -c "$struct" -c stack $SCRATCH_DEV | perl -ne '
+ if (/byte offset (\d+), length (\d+)/) {
+ print "offset=$1\nlength=$2\n"; exit
+ }'`
+ if [ -z "$offset" -o -z "$length" ]; then
+ echo "cannot calculate offset ($offset) or length ($length)"
+ exit
+ fi
+ length=`expr $length / 512`
+ src/devzero -v $value -b 1 -n $length -o $offset $SCRATCH_DEV
+}
+
+_filter_repair()
+{
+ perl -ne '
+# for sb
+/- agno = / && next; # remove each AG line (variable number)
+s/(pointer to) (\d+)/\1 INO/;
+s/(sb root inode value) (\d+)/\1 INO/;
+s/(realtime bitmap inode) (\d+)/\1 INO/;
+s/(realtime summary inode) (\d+)/\1 INO/;
+s/(inconsistent with calculated value) (\d+)/\1 INO/;
+s/\.+(found)/\1/g; # remove "searching" output
+# for agf + agi
+s/(bad length -{0,1}\d+ for ag. 0, should be) (\d+)/\1 LENGTH/;
+s/(bad length # -{0,1}\d+ for ag. 0, should be) (\d+)/\1 LENGTH/;
+s/(bad agbno) (\d+)/\1 AGBNO/g;
+s/(max =) (\d+)/\1 MAX/g;
+# for root inos
+s/(on inode) (\d+)/\1 INO/g;
+s/(imap claims a free inode) (\d+)/\1 INO/;
+s/(cleared root inode) (\d+)/\1 INO/;
+s/(resetting inode) (\d+)/\1 INO/;
+s/(disconnected dir inode) (\d+)/\1 INO/;
+ print;'
+}
+
+_filter_dd()
+{
+ fgrep -v records # lose records in/out lines
+}
+
+# do some controlled corrupting & ensure repair recovers us
+#
+_check_repair()
+{
+ value=$1
+ structure="$2"
+ _zero_position $value "$structure"
+ xfs_repair $SCRATCH_DEV 2>&1 | _filter_repair
+ # some basic sanity checks...
+ _check_fs $SCRATCH_DEV
+ mount -t xfs $SCRATCH_DEV $SCRATCH_MNT #mount
+ dd if=/bin/sh of=$SCRATCH_MNT/sh 2>&1 |_filter_dd #open,write
+ dd if=$SCRATCH_MNT/sh of=/dev/null 2>&1 |_filter_dd #read
+ rm -f $SCRATCH_MNT/sh #unlink
+ umount $SCRATCH_MNT #umount
+}
+
+# make sure this script returns success
+/bin/true
--- /dev/null
+############
+# xfscrash # crash testing setup for XFS
+############
+
+*** disclaimers ***
+
+ work-in-progress, buyer-beware, your-mileage-may-vary, this-is-a-hack
+
+*** what xfscrash does ***
+
+ xfscrash allows realistic testing of XFS log recovery and XFS check/repair
+ by generating log activity on an XFS partition, then rebooting the machine
+ at a random point. When the machine comes back up, xfscrash is restarted
+ and then tests either the log recovery or xfs_repair on the dirtied
+ filesystem. All going well the process continues.
+
+*** getting ready for crash testing ***
+
+ Most filesystems (ext2 included) can't withstand having the machine
+ they're running on rebooted while they're active. So the crash test
+ machine needs to have all filesystems other than the test FS mounted
+ read-only so they won't get trashed when the machine reboots.
+
+*** mouting FSes read-only ***
+
+ Following is a recipe for making a redhat linux (6.2) machine with a single
+ ext2 FS mounted on root able to be booted read-only. Your Mileage May
+ Vary - don't try this on an important machine.
+
+ The idea is to move anything that needs to be r/w into the /initrd_init
+ directory, replacing the moved directories with links to the moved ones.
+ That way the /initrd_init directory may be copied to a ramdisk, and
+ mounted over /initrd on the root FS which never gets remounted r/w.
+
+ # go to single user
+ init 1
+
+ # make a mount point for the ramdisk
+ mkdir /initrd
+
+ # link across to the /initrd_init directory for when
+ # the ramdisk isn't mounted
+ ln -s /initrd_init/dev .
+ ln -s /initrd_init/etc .
+ ln -s /initrd_init/proc .
+ ln -s /initrd_init/sbin .
+ ln -s /initrd_init/tmp .
+ ln -s /initrd_init/var .
+
+ # make the /initrd_init directory
+ mkdir /initrd_init
+ cd /initrd_init
+
+
+ # move /dev
+ mv /dev .
+ ln -s /dev /initrd/dev
+
+ # move /etc
+ mv /etc .
+ ln -s /etc /initrd/etc
+
+ # make proc mount
+ mkdir proc
+
+ # move /tmp
+ mkdir tmp
+ rm -rf /tmp
+ ln -s /tmp /initrd/tmp
+
+ # link /sbin
+ ln -s /sbin .
+
+ # setup a tree for parts of /var
+ mkdir var var/cache var/lock var/lock/console var/lock/subsys
+ mkdir var/log var/preserve var/run
+
+ touch /var/run/utmp /var/log/utmp /var/log/wtmp
+
+ # move parts of /var
+ rm -rf /var/cache /var/lock /var/log /var/preserve /var/run
+ ln -s /initrd/var/cache /var/cache
+ ln -s /initrd/var/lock /var/lock
+ ln -s /initrd/var/log /var/log
+ ln -s /initrd/var/preserve /var/preserve
+ ln -s /initrd/var/run /var/run
+
+ # make a mount for /var/shm
+ mkdir var/shm
+ ln -s /var/shm /initrd/var/shm
+
+ # move /var/spool
+ mkdir var/spool
+ mkdir var/spool/mail var/spool/anacron var/spool/at var/spool/lpd
+ mkdir var/spool/rwho var/spool/mqueue var/spool/cron
+ rm -rf /var/spool
+ ln -s /var/spool /initrd/var/spool
+
+ # move /var/tmp
+ mkdir var/tmp
+ rm -rf /var/tmp
+ ln -s /var/tmp /initrd/var/tmp
+
+ # trim /dev - too many inodes here - remove anything you don't need
+ # (small ramdisk has a small number of inodes)
+ rm -rf /initrd/dev/<....>
+
+ All going well, all the directories you've made should link through
+ /initrd and into /initrd_init, and the machine should come back up
+ if you restart it.
+
+ You want to keep the contents of /initrd_init to a minimum because
+ this stuff has to fit into the ramdisk.
+
+*** getting the ramdisk going ***
+
+ See the rc.sysinit file for some details of what to do to get the
+ ro-root/ramdisk up and running.
+
+ Once everything is going, the root FS should never be remounted to
+ r/w on boot and should be in r/o mode when the machine comes up.
+
+ All going well, any open files have been redirected through the
+ symlinks onto the ramdisk, so you should be able to remount the
+ root FS to r/w and then remount it back to r/o.
+
+ Since there's no r/w filesystems mounted, it should be ok to
+ reboot the machine with 'reboot -fn' and everything should come
+ back without dirty filesystems and without having to fsck.
+
+*** starting xfscrash ***
+
+ The simplest way to restart xfscrash on reboot is to start it
+ in the background from rc.local. The script logs to /dev/tty1,
+ /dev/console & a logfile by default, so the output should be
+ easy to find.
+
+ Link the xfscrash directory off an NFS mounted FS so you can make
+ changes while the machine is rebooting and so you can touch the
+ 'stop' and 'start' control files.
+
+ To configure the system, change the parameters in the configuration
+ section of the 'xfscrash' script.
+
+ To start the system, touch the 'start' control file and then either
+ reboot or manually run the 'xfscrash' script.
+
+ To stop the system, touch the 'stop' control file and wait for the
+ next cycle to start when the control file will be checked and
+ the test terminated.
+
--- /dev/null
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+# xfscrash - control the XFS crash tests
+#
+
+# this is an example of what to add to rc.sysinit on a redhat linux
+# system to get the ro-root/ramdisk system up and running
+
+if [ -f /initrd.active ]
+then
+ echo "*** MAKE RAMDISK ***"
+ dd if=/dev/zero of=/dev/ram0 bs=1024k count=4
+ mkfs -i 1024 /dev/ram0 4096
+ echo "*** MOUNT RAMDISK ***"
+ mount -n -w /dev/ram0 /mnt
+ echo "*** INIT RAMDISK ***"
+ cp -a /initrd_init/* /mnt
+ rm -f /mnt/00_INITRD_REAL
+ touch /mnt/00_INITRD_RAMDISK
+ umount -n /mnt
+ echo "*** REMOUNT RAMDISK ***"
+ mount -n /dev/ram0 /initrd
+
+ echo "*** FIX MTAB ***"
+ >/etc/mtab
+ rm -f /etc/mtab~ /etc/mtab~~
+ mount -f -o ro /
+ mount -f -o rw /dev/ram0 /initrd
+else
+ # old code
+
+ # Remount the root filesystem read-write.
+ action "Remounting root filesystem in read-write mode" mount -n -o remount,rw /
+
+ # Clear mtab
+ >/etc/mtab
+
+ # Remove stale backups
+ rm -f /etc/mtab~ /etc/mtab~~
+
+ # Enter root and /proc into mtab.
+ mount -f /
+ mount -f /proc
+
+fi
--- /dev/null
+#!/bin/sh
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+# xfscrash - control the XFS crash tests
+#
+
+ #######################
+### configuration stuff ########################################################
+ #######################
+
+# remount, repair or corrupt
+MODE=remount
+# where to find xfscrash
+XFSCRASH=/xfscrash
+# put log files here
+LOG=$XFSCRASH
+# put output to these places
+OUTPUT="$LOG/xfscrash.log /dev/tty1 /dev/console"
+# awk...
+AWK_PROG=gawk
+# clear FS if >= this percent full at start of run. 100 is a good
+# number - only used on corrupt test so far
+FULL_LIMIT=80
+
+case `hostname -s`
+in
+ leesa)
+ # mount test partition here
+ TEST_MNT=/mnt/arch0
+ # build test partition here
+ TEST_DEV=/dev/hda6
+ # backup test partition to here (or empty)
+ BACKUP_DEV=/dev/hda8
+ # backup block size for dd
+ BACKUP_BS=1024k
+ # base stress time
+ STRESS_TIME=60
+ # stress random time
+ STRESS_RANDOM=60
+ ;;
+ lumpy)
+ # mount test partition here
+ TEST_MNT=/mnt/scratch_0
+ # build test partition here
+ TEST_DEV=/dev/sdc5
+ # backup test partition to here (or empty)
+ BACKUP_DEV= ;#/dev/sdc6
+ # backup block size for dd
+ BACKUP_BS=10240k
+ # base stress time
+ STRESS_TIME=360
+ # stress random time
+ STRESS_RANDOM=360
+ ;;
+ *)
+ echo "!!! no configuration data for host `hostname -s`"
+ exit 1
+ ;;
+esac
+
+# avoid stress
+
+AVOID="-f resvsp=0 -f unresvsp=0"
+
+# DIY stress command
+STRESS="/usr/local/bin/fsstress -d $TEST_MNT/stress -n 10000000 -p 1 $AVOID"
+#STRESS="/usr/local/bin/randholes -l 10000000 -c 100000 -b 512 $TEST_MNT/stress/holes"
+
+# stress command for the corrupt test
+CORRUPT_STRESS="/usr/local/bin/fsstress -d $TEST_MNT/stress -n 10000 -p 1 $AVOID"
+
+###########################################################################
+
+reboot=-1
+
+_log()
+{
+ tee -a $OUTPUT > /dev/null
+}
+
+_echo()
+{
+ echo "$*" | _log
+}
+
+_mount()
+{
+ _echo " *** Mounting $TEST_DEV on $TEST_MNT"
+ if ! mount -t xfs $TEST_DEV $TEST_MNT
+ then
+ _echo " !!! unable to mount"
+ exit 1
+ fi
+}
+
+_unmount()
+{
+ _echo " *** Unmounting $TEST_DEV"
+ if ! umount $TEST_DEV &> /dev/null
+ then
+ _echo " !!! unable to unmount"
+ exit 1
+ fi
+}
+
+_check()
+{
+ expect=$1
+ fail=0
+
+ if [ $expect -eq 0 ]
+ then
+ _echo " *** Checking FS (expecting clean fs)"
+ else
+ _echo " *** Checking FS (expecting dirty fs)"
+ fi
+
+
+ if [ $expect -eq 0 ]
+ then
+ _echo " *** xfs_check ($LOG/check_clean.out)"
+ xfs_check $TEST_DEV &> $LOG/check_clean.out || fail=1
+ [ -s /tmp/xfs_check_clean.out ] && fail=1
+ else
+ _echo " *** xfs_check ($LOG/check_dirty.out)"
+ xfs_check $TEST_DEV &> $LOG/check_dirty.out || fail=1
+ fi
+
+ if [ $fail -eq 0 -a $expect -eq 0 ]
+ then
+ _echo " *** xfs_repair -n ($LOG/repair_clean.out)"
+ xfs_repair -n $TEST_DEV &> $LOG/repair_clean.out || fail=1
+ fi
+
+ if [ $fail -eq 0 ]
+ then
+ _echo " *** FS checks ok"
+ else
+ if [ $expect -eq 0 ]
+ then
+ _echo " !!! FS check failed - inconsistent FS"
+ _echo " !!! (see $LOG/*.out for details)"
+ exit 1
+ else
+ _echo " *** inconsistent fs (as expected)"
+ fi
+ fi
+}
+
+_check_core()
+{
+ if [ -e core ]
+ then
+ _echo " !!! core file found!"
+ exit 1
+ fi
+}
+
+_repair()
+{
+ rm -f core
+ _echo " *** repair"
+ _echo " *** repair pass 1 (RO)"
+ xfs_repair -n $TEST_DEV &> $LOG/repair_1.out \
+ && _echo " !!! no errors found (eh?)" \
+ || _echo " *** errors found (expected)"
+
+ _check_core
+
+ _echo " *** repair pass 2 (RW)"
+
+ if xfs_repair $TEST_DEV &> $LOG/repair_2.out
+ then
+ _echo " *** FS checks ok (now)"
+ else
+ _echo " !!! xfs_repair returned error code"
+ _echo " !!! (see $LOG/repair_*.out for details)"
+ exit 1
+ fi
+
+ _check_core
+
+ _echo " *** repair pass 3 (RO)"
+ if xfs_repair -n $TEST_DEV &> $LOG/repair_3.out
+ then
+ _echo " *** FS checks ok"
+ else
+ _echo " !!! errors found after repair (unexpected)"
+ _echo " !!! (see $LOG/repair_*.out for details)"
+ exit 1
+ fi
+
+ _check_core
+}
+
+_cleanup()
+{
+ rm -f $XFSCRASH/counter $XFSCRASH/start $XFSCRASH/stop $XFSCRASH/active
+
+ if [ $reboot != -1 ]
+ then
+ kill $reboot
+ fi
+
+}
+
+_random()
+{
+ od -tu -N 4 /dev/random | gawk -v v=$1 'NR==1 { print $2 % v }'
+}
+
+_backup()
+{
+ if [ $count -ne 1 -a "$BACKUP_DEV" != "" ]
+ then
+ _echo " *** Backing up $TEST_DEV to $BACKUP_DEV"
+ if ! dd if=$TEST_DEV of=$BACKUP_DEV bs=$BACKUP_BS &> $LOG/dd.out
+ then
+ _echo " !!! unable to backup fs"
+ _echo " !!! (see $LOG/dd.out)"
+ exit 1
+ fi
+ else
+ _echo " *** skipping back up step"
+ fi
+}
+
+_logprint()
+{
+ _echo " *** dumping log to $LOG/logprint.out"
+ rm -f core
+ xfs_logprint $TEST_DEV &> $LOG/logprint.out
+ if [ -e core ]
+ then
+ _echo " !!! xfs_logprint dumped core"
+ echo "" >> $LOG/logprint.out
+ echo "*** CORE DUMPED ***" >> $LOG/logprint.out
+ echo "" >> $LOG/logprint.out
+ fi
+
+ _echo " *** dumping log (-t -i) to $LOG/logprint_inode.out"
+
+ rm -f core
+ xfs_logprint -t -i $TEST_DEV &> $LOG/logprint_inode.out
+ if [ -e core ]
+ then
+ _echo " !!! xfs_logprint dumped core"
+ echo "" >> $LOG/logprint_inode.out
+ echo "*** CORE DUMPED ***" >> $LOG/logprint_inode.out
+ echo "" >> $LOG/logprint_inode.out
+ fi
+
+ _echo " *** dumping log (-t -b) to $LOG/logprint_buf.out"
+
+ rm -f core
+ xfs_logprint -t -b $TEST_DEV &> $LOG/logprint_buf.out
+ if [ -e core ]
+ then
+ _echo " !!! xfs_logprint dumped core"
+ echo "" >> $LOG/logprint_buf.out
+ echo "*** CORE DUMPED ***" >> $LOG/logprint_buf.out
+ echo "" >> $LOG/logprint_buf.out
+ fi
+}
+#
+# _df_device : get an IRIX style df line for a given device
+#
+# - returns "" if not mounted
+# - returns fs type in field two (ala IRIX)
+# - joins line together if split by fancy df formatting
+# - strips header etc
+#
+
+_df_device()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _df_device device" >&2
+ exit 1
+ fi
+
+ df -T 2> /dev/null | $AWK_PROG -v what=$1 '
+ match($1,what) && NF==1 {
+ v=$1
+ getline
+ print v, $0
+ exit
+ }
+ match($1,what) {
+ print
+ exit
+ }
+ '
+}
+
+#
+# _df_dir : get an IRIX style df line for device where a directory resides
+#
+# - returns fs type in field two (ala IRIX)
+# - joins line together if split by fancy df formatting
+# - strips header etc
+#
+
+_df_dir()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _df_dir device" >&2
+ exit 1
+ fi
+
+ df -T $1 2> /dev/null | $AWK_PROG -v what=$1 '
+ NR == 2 && NF==1 {
+ v=$1
+ getline
+ print v, $0;
+ exit 0
+ }
+ NR == 2 {
+ print;
+ exit 0
+ }
+ {}
+ '
+ # otherwise, nada
+}
+
+# return percentage used disk space for mounted device
+
+_used()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _used device" >&2
+ exit 1
+ fi
+
+ _df_device $1 | $AWK_PROG '{ sub("%", "") ; print $6 }'
+}
+
+_check_free()
+{
+ used=`_used $TEST_DEV`
+
+ if [ $used -ge $FULL_LIMIT ]
+ then
+ _echo " *** $used % used on $TEST_DEV - deleting files"
+ rm -rf $TEST_MNT/stress
+ fi
+}
+
+# loop, stressing, unounting and checking
+# no (expected) rebooting...
+_corrupt()
+{
+ count=0
+
+ # don't want to restart if we reboot...
+ _cleanup
+
+ while true
+ do
+
+ if [ -e $XFSCRASH/stop ]
+ then
+ _echo "### XFS Crash stopped "
+ exit 0
+ fi
+
+ _echo "*** run $count"
+ let "count = count + 1"
+
+ _check 0
+ _mount
+
+ _check_free
+
+ $CORRUPT_STRESS | _log
+
+ _unmount
+ done
+}
+
+###########################################################################
+
+_echo ""
+_echo ""
+echo "XFSCRASH [output to $OUTPUT]"
+_echo ""
+
+if [ "$1" = "start" ]
+then
+ touch $XFSCRASH/start
+fi
+
+if [ "$1" = "stop" ]
+then
+ touch $XFSCRASH/stop
+fi
+
+
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+
+if [ -e $XFSCRASH/stop ]
+then
+ _echo "### XFS Crash stopped "
+ exit 0
+fi
+
+if [ -e $XFSCRASH/start ]
+then
+ _echo "### XFS Crash started "
+ _cleanup
+ rm -f $LOG/*.out $LOG/*.log core
+
+ touch $XFSCRASH/active
+
+ _echo " *** Building fresh XFS FS"
+ umount $TEST_DEV &> /dev/null
+ if ! mkfs -t xfs -f $TEST_DEV &> $LOG/mkfs.out
+ then
+ _echo " !!! unable to mkfs"
+ _echo " !!! (see $LOG/mkfs.out)"
+ exit 1
+ fi
+fi
+
+if [ ! -e $XFSCRASH/active ]
+then
+ _echo "### XFS Crash inactive "
+ exit 0
+fi
+
+
+if [ -r $XFSCRASH/counter ]
+then
+ count=`cat $XFSCRASH/counter`
+else
+ count=0
+fi
+_echo "### Crash test run $count (mode=$MODE, log=$LOG/{*.out,*.log})"
+
+let "count = count +1"
+echo $count > $XFSCRASH/counter
+
+# real test starts here
+
+_echo " *** Checking for R/O root"
+if ! mount | grep "on / type" | grep -q "(ro)"
+then
+ _echo " !!! root not mounted readonly"
+ exit 1
+fi
+
+_echo " *** Loading XFS modules"
+if ! modprobe xfs
+then
+ _echo " !!! unable to modprobe xfs"
+ exit 1
+fi
+
+_echo " *** Unmounting $TEST_DEV"
+umount $TEST_DEV &> /dev/null
+
+_logprint
+if [ $MODE != "corrupt" ]
+then
+ _backup
+fi
+
+case $MODE
+in
+ remount)
+ _check 1 # expect errors
+ _mount
+ _unmount
+ ;;
+ repair)
+ _repair
+ ;;
+ corrupt)
+ _corrupt
+ exit 0
+ ;;
+ *)
+ _echo "xfscrash: MODE must be remount or repair"
+ exit 1
+ ;;
+esac
+
+_check 0 # don't expect errors
+_mount
+
+_echo " *** Cleaning XFS FS"
+if ! rm -rf $TEST_MNT/stress $TEST_MNT/lost+found &> $LOG/clean.out
+then
+ _echo " !!! unable to clean XFS FS"
+ _echo " !!! (see $LOG/clean.out)"
+ exit 1
+fi
+
+_echo " *** Making stress directory"
+if ! mkdir $TEST_MNT/stress
+then
+ _echo " !!! unable to mkdir stress"
+ exit 1
+fi
+
+let "bang = STRESS_TIME + `_random $STRESS_RANDOM`"
+
+_echo " *** Preparing random reboot (in $bang seconds)"
+(
+ sleep $bang
+ _echo " *** BANG ****"
+ reboot -fn
+) &
+reboot=$!
+
+_echo " *** Causing stress & waiting for the inevitable"
+$STRESS | _log
+
+exit 0
--- /dev/null
+#
+# QA groups control file
+# Defines test groups and nominal group owners
+# - do not start group names with a digit
+# - comment line before each group is "new" description
+#
+
+# catch-all
+other fsg@melbourne.sgi.com
+
+# read/write integrity
+rw dxm@sgi.com
+
+# directory operations, e.g. create/unlink
+dir dxm@sgi.com
+
+# metadata and inodes in particular
+metadata dxm@sgi.com
+
+# xfs_db
+db nathans@sgi.com dxm@sgi.com
+
+# xfs_attr
+attr dxm@sgi.com
+
+# xfs_logprint
+logprint dxm@sgi.com
+
+# xfsdump, xfsrestore, xfsinvutil, xfs_copy
+xfsdump tes@sgi.com ivanr@sgi.com
+
+# xfs_growfs
+growfs ajag@sgi.com
+
+# fsr.xfs
+fsr ajag@sgi.com
+
+# mkfs.xfs
+mkfs nathans@sgi.com
+
+# xfs_repair
+repair nathans@sgi.com
+
+# quota tools and XFS quota kernel code (XQM)
+quota nathans@sgi.com
+
+# auto - tests to be run as part of nightly qa
+auto dxm@sgi.com
+
+# test-group association ... one line per test
+#
+001 rw dir auto
+002 metadata auto
+003 db auto
+004 db auto
+005 dir auto
+006 dir auto
+007 dir auto
+008 rw auto
+009 rw auto
+010 other auto
+011 dir auto
+012 rw auto
+013 other auto
+014 rw auto
+015 other auto
+016 rw auto
+017 other auto
+018 logprint auto
+019 mkfs auto
+020 metadata attr auto
+021 db attr auto
+022 xfsdump auto
+023 xfsdump auto
+024 xfsdump auto
+025 xfsdump auto
+026 xfsdump auto
+027 xfsdump auto
+028 xfsdump auto
+029 mkfs logprint auto
+030 repair auto
+031 repair mkfs auto
+032 mkfs auto
+033 repair auto
+034 other auto
+035 xfsdump auto
+036 xfsdump auto
+037 xfsdump auto
+038 xfsdump auto
+039 xfsdump auto
+040 other auto
+041 growfs auto
+042 fsr auto
+043 xfsdump auto
+044 other auto
+045 other auto
+046 xfsdump auto
+047 xfsdump auto
+048 other auto
+049 rw auto
+050 quota auto
+051 acl
--- /dev/null
+#! /bin/sh
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+# Make a new test
+#
+# $Header: /build2/depot/linux/pcp/dev/qa/RCS/new,v 2.22 1999/10/06 19:16:53 kenmcd Exp $
+#
+
+# generic initialization
+iam=new
+. ./common.rc
+
+trap "rm -f /tmp/$$.; exit" 0 1 2 3 15
+
+_cleanup()
+{
+ :
+}
+
+if [ ! -f group ]
+then
+ echo "Creating the group index ..."
+ cat <<'End-of-File' >group
+# QA groups control
+#
+# $Id: new,v 2.22 1999/10/06 19:16:53 kenmcd Exp $
+#
+# define groups and default group owners
+# do not start group name with a digit
+#
+
+# catch-all
+#
+other some-user-login
+
+# test-group association ... one line per test
+#
+End-of-File
+fi
+
+if [ ! -w group ]
+then
+ chmod u+w group
+ echo "Warning: making the index file \"group\" writeable"
+fi
+
+if make
+then
+ :
+else
+ echo "Warning: make failed -- some tests may be missing"
+fi
+
+last=`grep '^[0-9][0-9]* ' group | sort | tail -1 | sed -e 's/[ ].*//'`
+id=`$AWK_PROG </dev/null 'BEGIN{printf "%03d\n",'$last'+1}'`
+echo "Next test is $id"
+
+if [ -f $id ]
+then
+ echo "Error: test $id already exists!"
+ _cleanup
+ exit 1
+fi
+
+echo -n "Creating skeletal script for you to edit ..."
+
+cat <<End-of-File | sed -e '/rcsId/s//Id: 1.1 /' >$id
+#! /bin/sh
+# XFS QA Test No. $id
+# \$rcsId\$
+#
+# what am I here for?
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=$USER@`_get_fqdn`
+
+seq=\`basename \$0\`
+echo "QA output created by \$seq"
+
+here=\`pwd\`
+tmp=/tmp/\$\$
+status=1 # failure is the default!
+trap "rm -f \$tmp.*; exit \\\$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+
+# if error
+exit
+
+# optional stuff if your test has verbose output to help resolve problems
+#echo
+#echo "If failure, check \$seq.full (this) and \$seq.full.ok (reference)"
+
+# success, all done
+status=0
+exit
+End-of-File
+
+sleep 2 # latency to read messages to this point
+echo ""
+
+chmod 755 $id
+${EDITOR-vi} $id
+
+if [ $# -eq 0 ]
+then
+ while true
+ do
+ echo -n "Add to group(s) [other] (? for list): "
+ read ans
+ [ -z "$ans" ] && ans=other
+ if [ "X$ans" = "X?" ]
+ then
+ $AWK_PROG <group '
+BEGIN { text = "# ???" }
+/^[a-zA-z]/ { printf "%-16.16s %s\n",$1,text; text = "# ???"; next }
+NF < 2 { next }
+ { text = $0 }' \
+ | sort
+ else
+ break
+ fi
+ done
+else
+ # expert mode, groups are on the command line
+ #
+ for g in $*
+ do
+ if grep "^$g[ ]" group >/dev/null
+ then
+ :
+ else
+ echo "Warning: group \"$g\" not defined in ./group"
+ fi
+ done
+ ans="$*"
+fi
+
+echo -n "Adding $id to group index ..."
+echo "$id $ans" >>group
+echo " done."
+
+exit 0
--- /dev/null
+#! /bin/sh
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+# Rebuild NNN.out files
+#
+# $Header: /build2/depot/linux/pcp/dev/qa/RCS/remake,v 2.11 1999/09/20 03:42:19 kenmcd Exp $
+#
+
+tmp=/tmp/$$
+trap "rm -f NO-PREVIOUS-OUTPUT $tmp.*; exit" 0 1 2 3 15
+
+# generic initialization
+iam=remake
+. ./common.rc
+
+. ./common
+
+[ -f check.time ] || touch check.time
+
+for seq in $list
+do
+ if [ ! -f $seq ]
+ then
+ echo "Remake: cannot find \"$seq\""
+ else
+ echo -n "$seq"
+ lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time`
+ [ "X$lasttime" != X ] && echo -n " ${lasttime}s"
+ rm -f $seq.bak $seq.full.bak
+ if sh $seq >$seq.new 2>&1
+ then
+ if [ -f $seq.out ]
+ then
+ $diff $seq.out $seq.new
+ rm -f $seq.out.bad
+ else
+ touch NO-PREVIOUS-OUTPUT
+ $diff NO-PREVIOUS-OUTPUT $seq.new
+ rm -f NO-PREVIOUS-OUTPUT
+ fi
+ echo ""
+ [ -f $seq.out ] && mv $seq.out $seq.bak
+ if [ -f $seq.full ]
+ then
+ [ -f $seq.full.ok ] && mv $seq.full.ok $seq.full.bak
+ mv $seq.full $seq.full.ok
+ fi
+ mv $seq.new $seq.out
+ else
+ echo " - failed (exit status $?)"
+ sed 's/^/ /' $seq.new
+ exit 1
+ fi
+ fi
+done
+
+exit 0
--- /dev/null
+#!/bin/sh
+#-----------------------------------------------------------------------
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#-----------------------------------------------------------------------
+#
+# creator
+owner=dxm@sgi.com
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+tmp=/tmp/$$
+seq=soak
+status=1 # failure is the default!
+
+_cleanup()
+{
+ echo " *** umount"
+ umount $SCRATCH_DEV >/dev/null 2>&1
+}
+
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+ROOT="."
+LOG="$ROOT/soak.log"
+FULL="$ROOT/soak.full"
+
+_log()
+{
+ echo "$*" 1>&2
+ echo "$*" >>$LOG
+ echo "$*" >>$FULL
+}
+
+_logp()
+{
+ tee -a $FULL
+}
+
+_fail()
+{
+ _log "$*"
+ status=1
+ exit 1
+}
+
+_require_scratch
+
+passes=-1
+stress=100000
+proc=1
+
+if [ $# -gt 0 ]
+then
+ passes=$1
+ if [ $# -gt 1 ]
+ then
+ stress=$2
+ if [ $# -gt 2 ]
+ then
+ proc=$3
+ fi
+ fi
+fi
+
+echo "" >$FULL
+echo "" >$LOG
+_log "*** soak test started (passes=$passes, stress=$stress, proc=$proc)"
+_log "*** (`date`)"
+
+
+_log " *** init"
+_log " *** unmounting scratch device"
+
+umount $SCRATCH_DEV 2>&1 | _fix_malloc >>$FULL
+
+_log " *** clean scratch device"
+
+mkfs -t xfs -f $SCRATCH_DEV 2>&1 | _fix_malloc >>$FULL \
+ || _fail " !!! failed to mkfs SCRATCH_DEV"
+
+pass=1
+
+while [ $pass -le $passes -o $passes -lt 0 ]
+do
+ _log " *** pass $pass (`date`)"
+
+ _log " *** check"
+ _check_fs $SCRATCH_DEV
+
+ _log " *** mounting scratch device"
+
+ if ! mount -t xfs $SCRATCH_DEV $SCRATCH_MNT 2>&1 | _logp
+ then
+ _fail " !!! failed to mount"
+ fi
+
+ if [ $pass != 1 ]
+ then
+ _log " *** cleanup"
+ rm -rf $SCRATCH_MNT/soak_test \
+ || _fail " !!! couldn't delete old dir"
+
+ _log " *** check"
+ _check_fs $SCRATCH_DEV
+ fi
+
+ _log " *** mkdir"
+ mkdir $SCRATCH_MNT/soak_test \
+ || _fail " !!! couldn't delete old dir"
+
+ _log " *** stress"
+ src/fsstress -d $SCRATCH_MNT/soak_test -p $proc -n $stress $FSSTRESS_AVOID 2>&1 | \
+ _fix_malloc >>$FULL
+
+ _log " *** unmounting scratch device"
+
+ umount $SCRATCH_DEV 2>&1 | _logp \
+ || _fail " !!! failed to umount"
+
+ let "pass = pass + 1"
+done
+
--- /dev/null
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/include/builddefs
+
+TARGETS = alloc bstat dbtest devzero dirstress fault feature fsstress \
+ fill fill2 holes ioctl loggen lstat64 nametest permname \
+ randholes testrmt truncfile usemem runas
+CFILES = $(TARGETS:=.c) random.c
+HFILES = global.h
+LDIRT = $(TARGETS)
+
+DBMLIB = -lgdbm
+RMTLIB = $(TOPDIR)/dump/librmt/librmt.a
+
+default: $(TARGETS)
+
+include $(BUILDRULES)
+
+install: default
+
+# binaries using non-default objects/libs need an entry below
+#
+RANDHOLES_OBJECTS = randholes.o random.o
+randholes: $(HFILES) $(RANDHOLES_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(RANDHOLES_OBJECTS) $(LDLIBS)
+
+TRUNCFILE_OBJECTS = truncfile.o random.o
+truncfile: $(HFILES) $(TRUNCFILE_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(TRUNCFILE_OBJECTS) $(LDLIBS)
+
+FSSTRESS_OBJECTS = fsstress.o random.o $(LIBATTR)
+fsstress: $(HFILES) $(FSSTRESS_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(FSSTRESS_OBJECTS) $(LDLIBS)
+
+DBTEST_OBJECTS = dbtest.o random.o $(DBMLIB)
+dbtest: $(HFILES) $(DBTEST_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(DBTEST_OBJECTS) $(LDLIBS)
+
+NAMETEST_OBJECTS = nametest.o random.o
+nametest: $(HFILES) $(NAMETEST_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(NAMETEST_OBJECTS) $(LDLIBS)
+
+BSTAT_OBJECTS = bstat.o $(LIBHANDLE)
+bstat: $(HFILES) $(BSTAT_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(BSTAT_OBJECTS) $(LDLIBS)
+
+TESTRMT_OBJECTS = testrmt.o $(RMTLIB)
+testrmt: $(TESTRMT_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(TESTRMT_OBJECTS) $(LDLIBS)
+
+LOGGEN_OBJECTS = loggen.o $(LIBXFS)
+loggen: $(HFILES) $(LOGGEN_OBJECTS)
+ $(CCF) -o $@ $(LDFLAGS) $(LOGGEN_OBJECTS) $(LDLIBS)
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+#define FSBTOBB(f) (OFFTOBBT(FSBTOOFF(f)))
+#define BBTOFSB(b) (OFFTOFSB(BBTOOFF(b)))
+#define OFFTOFSB(o) ((o) / blocksize)
+#define FSBTOOFF(f) ((f) * blocksize)
+
+void usage(void)
+{
+ printf("usage: alloc [-b blocksize] [-d dir] [-f file] [-n] [-r] [-t]\n"
+ "flags:\n"
+ " -n - non-interractive mode\n"
+ " -r - real time file\n"
+ " -t - truncate on open\n"
+ "\n"
+ "commands:\n"
+ " r [offset] [length] - reserve\n"
+ " u [offset] [length] - unreserve\n"
+ " a [offset] [length] - alloc *** identical to free\n"
+ " f [offset] [length] - free *** identical to alloc\n"
+ " m/p [offset] [length] - print map\n"
+ " s - sync file\n"
+ " t [offset] - truncate\n"
+ " q - quit\n"
+ " h/? - this help\n");
+
+}
+
+int fd;
+int blocksize = 0;
+
+/* params are in bytes */
+void map(off64_t off, off64_t len)
+{
+ struct getbmap bm[2]={{0}};
+
+ bm[0].bmv_count = 2;
+ bm[0].bmv_offset = OFFTOBB(off);
+ if (len==(off64_t)-1) { /* unsigned... */
+ bm[0].bmv_length = -1;
+ printf(" MAP off=%lld, len=%lld [%lld-]\n",
+ (__s64)off, (__s64)len,
+ (__s64)BBTOFSB(bm[0].bmv_offset));
+ } else {
+ bm[0].bmv_length = OFFTOBB(len);
+ printf(" MAP off=%lld, len=%lld [%lld,%lld]\n",
+ (__s64)off, (__s64)len,
+ (__s64)BBTOFSB(bm[0].bmv_offset),
+ (__s64)BBTOFSB(bm[0].bmv_length));
+ }
+
+ printf(" [ofs,count]: start..end\n");
+ for (;;) {
+ if (ioctl(fd, XFS_IOC_GETBMAP, bm) < 0) {
+ perror("getbmap");
+ break;
+ }
+ if (bm[0].bmv_entries == 0)
+ break;
+ printf(" [%lld,%lld]: ",
+ (__s64)BBTOFSB(bm[1].bmv_offset),
+ (__s64)BBTOFSB(bm[1].bmv_length));
+ if (bm[1].bmv_block == -1)
+ printf("hole");
+ else
+ printf("%lld..%lld",
+ (__s64)BBTOFSB(bm[1].bmv_block),
+ (__s64)BBTOFSB(bm[1].bmv_block +
+ bm[1].bmv_length - 1));
+ printf("\n");
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ char *dirname = NULL;
+ int done = 0;
+ struct flock64 f;
+ char *filename = NULL;
+ off64_t len;
+ char line[1024];
+ off64_t off;
+ int oflags;
+ static char *opnames[] =
+ { "freesp", "allocsp", "unresvsp", "resvsp" };
+ int opno;
+ static int optab[] =
+ { XFS_IOC_FREESP64, XFS_IOC_ALLOCSP64, XFS_IOC_UNRESVSP64, XFS_IOC_RESVSP64 };
+ int rflag = 0;
+ struct statvfs64 svfs;
+ int tflag = 0;
+ int nflag = 0;
+ int unlinkit = 0;
+ __int64_t v;
+
+ while ((c = getopt(argc, argv, "b:d:f:rtn")) != -1) {
+ switch (c) {
+ case 'b':
+ blocksize = atoi(optarg);
+ break;
+ case 'd':
+ if (filename) {
+ printf("can't specify both -d and -f\n");
+ exit(1);
+ }
+ dirname = optarg;
+ break;
+ case 'f':
+ if (dirname) {
+ printf("can't specify both -d and -f\n");
+ exit(1);
+ }
+ filename = optarg;
+ break;
+ case 'r':
+ rflag = 1;
+ break;
+ case 't':
+ tflag = 1;
+ break;
+ case 'n':
+ nflag++;
+ break;
+ default:
+ printf("unknown option\n");
+ usage();
+ exit(1);
+ }
+ }
+ if (!dirname && !filename)
+ dirname = ".";
+ if (!filename) {
+ static char tmpfile[] = "allocXXXXXX";
+
+ mktemp(tmpfile);
+ filename = malloc(strlen(tmpfile) + strlen(dirname) + 2);
+ sprintf(filename, "%s/%s", dirname, tmpfile);
+ unlinkit = 1;
+ }
+ oflags = O_RDWR | O_CREAT | (tflag ? O_TRUNC : 0);
+ fd = open(filename, oflags, 0666);
+ if (!nflag) {
+ printf("alloc:\n");
+ printf(" filename %s\n", filename);
+ }
+ if (fd < 0) {
+ perror(filename);
+ exit(1);
+ }
+ if (unlinkit)
+ unlink(filename);
+ if (!blocksize) {
+ if (fstatvfs64(fd, &svfs) < 0) {
+ perror(filename);
+ exit(1);
+ }
+ blocksize = (int)svfs.f_bsize;
+ }
+ if (blocksize<0) {
+ fprintf(stderr,"illegal blocksize %d\n", blocksize);
+ exit(1);
+ }
+ printf(" blocksize %d\n", blocksize);
+ if (rflag) {
+ struct fsxattr a;
+
+ if (ioctl(fd, XFS_IOC_FSGETXATTR, &a) < 0) {
+ perror("XFS_IOC_FSGETXATTR");
+ exit(1);
+ }
+ a.fsx_xflags |= XFS_XFLAG_REALTIME;
+ if (ioctl(fd, XFS_IOC_FSSETXATTR, &a) < 0) {
+ perror("XFS_IOC_FSSETXATTR");
+ exit(1);
+ }
+ }
+ while (!done) {
+ char *p;
+
+ if (!nflag) printf("alloc> ");
+ fflush(stdout);
+ if (!fgets(line, 1024, stdin)) break;
+
+ p=line+strlen(line);
+ if (p!=line&&p[-1]=='\n') p[-1]=0;
+
+ opno = 0;
+ switch (line[0]) {
+ case 'r':
+ opno++;
+ case 'u':
+ opno++;
+ case 'a':
+ opno++;
+ case 'f':
+ v = strtoll(&line[2], &p, 0);
+ if (*p == 'b') {
+ off = FSBTOOFF(v);
+ p++;
+ } else
+ off = v;
+ f.l_whence = SEEK_SET;
+ f.l_start = off;
+ if (*p == '\0')
+ v = -1;
+ else
+ v = strtoll(p, &p, 0);
+ if (*p == 'b') {
+ len = FSBTOOFF(v);
+ p++;
+ } else
+ len = v;
+
+ printf(" CMD %s, off=%lld, len=%lld\n",
+ opnames[opno], (__s64)off, (__s64)len);
+
+ f.l_len = len;
+ c = ioctl(fd, optab[opno], &f);
+ if (c < 0) {
+ perror(opnames[opno]);
+ break;
+ }
+
+ map(off,len);
+ break;
+ case 'p':
+ case 'm':
+ p = &line[1];
+ v = strtoll(p, &p, 0);
+ if (*p == 'b') {
+ off = FSBTOOFF(v);
+ p++;
+ } else
+ off = v;
+ if (*p == '\0')
+ len = -1;
+ else {
+ v = strtoll(p, &p, 0);
+ if (*p == 'b')
+ len = FSBTOOFF(v);
+ else
+ len = v;
+ }
+ map(off,len);
+ break;
+ case 't':
+ p = &line[1];
+ v = strtoll(p, &p, 0);
+ if (*p == 'b')
+ off = FSBTOOFF(v);
+ else
+ off = v;
+ printf(" TRUNCATE off=%lld\n", (__s64)off);
+ if (ftruncate64(fd, off) < 0) {
+ perror("ftruncate");
+ break;
+ }
+ break;
+ case 's':
+ printf(" SYNC\n");
+ fsync(fd);
+ break;
+ case 'q':
+ printf(" QUIT\n");
+ done = 1;
+ break;
+ case '?':
+ case 'h':
+ usage();
+ break;
+ default:
+ printf("unknown command '%s'\n", line);
+ break;
+ }
+ }
+ if (!nflag) printf("\n");
+ close(fd);
+ exit(0);
+ /* NOTREACHED */
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <libxfs.h>
+#include <jdm.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+void
+dotime(void *ti, char *s)
+{
+ char *c;
+ xfs_bstime_t *t;
+
+ t = (xfs_bstime_t *)ti;
+
+ c = ctime(&t->tv_sec);
+ printf("\t%s %19.19s.%09d %s", s, c, t->tv_nsec, c + 20);
+}
+
+void
+printbstat(xfs_bstat_t *sp)
+{
+ printf("ino %lld mode %#o nlink %d uid %d gid %d rdev %#x\n",
+ sp->bs_ino, sp->bs_mode, sp->bs_nlink,
+ sp->bs_uid, sp->bs_gid, sp->bs_rdev);
+ printf("\tblksize %d size %lld blocks %lld xflags %#x extsize %d\n",
+ sp->bs_blksize, sp->bs_size, sp->bs_blocks,
+ sp->bs_xflags, sp->bs_extsize);
+ dotime(&sp->bs_atime, "atime");
+ dotime(&sp->bs_mtime, "mtime");
+ dotime(&sp->bs_ctime, "ctime");
+ printf( "\textents %d %d gen %d\n",
+ sp->bs_extents, sp->bs_aextents, sp->bs_gen);
+ printf( "\tDMI: event mask 0x%08x state 0x%04x\n",
+ sp->bs_dmevmask, sp->bs_dmstate);
+}
+
+void
+printstat(struct stat64 *sp)
+{
+ printf("ino %lld mode %#o nlink %d uid %d gid %d rdev %#x\n",
+ (xfs_ino_t)sp->st_ino, sp->st_mode, sp->st_nlink,
+ sp->st_uid, sp->st_gid, (unsigned int)sp->st_rdev);
+ printf("\tblksize %llu size %lld blocks %lld\n",
+ (__uint64_t)sp->st_blksize, sp->st_size, sp->st_blocks);
+ dotime(&sp->st_atime, "atime");
+ dotime(&sp->st_mtime, "mtime");
+ dotime(&sp->st_ctime, "ctime");
+}
+
+int
+main(int argc, char **argv)
+{
+ __s32 count;
+ int total = 0;
+ int fsfd;
+ int i;
+ __s64 last = 0;
+ char *name;
+ int nent;
+ int debug = 0;
+ int quiet = 0;
+ int statit = 0;
+ int verbose = 0;
+ xfs_bstat_t *t;
+ int ret;
+ jdm_fshandle_t *fshandlep;
+ int fd;
+ struct stat64 sb;
+ int nread;
+ char *cc_readlinkbufp;
+ int cc_readlinkbufsz;
+ int c;
+ xfs_fsop_bulkreq_t bulkreq;
+
+ while ((c = getopt(argc, argv, "cdl:qv")) != -1) {
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'c':
+ statit = 1;
+ break;
+ case 'd':
+ debug = 1;
+ break;
+ case 'l':
+ last = atoi(optarg);
+ break;
+ case '?':
+ printf("usage: xfs_bstat [-c] [-q] [-v] [ dir [ batch_size ]]\n");
+ printf(" -c Check the results against stat(3) output\n");
+ printf(" -q Quiet\n");
+ printf(" -l _num_ Inode to start with\n");
+ printf(" -v Verbose output\n");
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ name = ".";
+ else
+ name = *argv;
+
+ fsfd = open(name, O_RDONLY);
+ if (fsfd < 0) {
+ perror(name);
+ exit(1);
+ }
+ if (argc < 2)
+ nent = 4096;
+ else
+ nent = atoi(*++argv);
+
+ if (verbose)
+ printf("Bulkstat test on %s, batch size=%d statcheck=%d\n",
+ name, nent, statit);
+
+ if (statit) {
+ fshandlep = jdm_getfshandle( name );
+ if (! fshandlep) {
+ printf("unable to construct sys handle for %s: %s\n",
+ name, strerror(errno));
+ return -1;
+ }
+ }
+
+ t = malloc(nent * sizeof(*t));
+
+ if (verbose)
+ printf(
+ "XFS_IOC_FSBULKSTAT test: last=%lld nent=%d\n", last, nent);
+
+ bulkreq.lastip = &last;
+ bulkreq.icount = nent;
+ bulkreq.ubuffer = t;
+ bulkreq.ocount = &count;
+
+ while ((ret = ioctl(fsfd, XFS_IOC_FSBULKSTAT, &bulkreq)) == 0) {
+ total += count;
+
+ if (verbose)
+ printf(
+ "XFS_IOC_FSBULKSTAT test: last=%lld ret=%d count=%d total=%d\n",
+ last, ret, count, total);
+ if (count == 0)
+ exit(0);
+
+ if ( quiet && ! statit )
+ continue;
+
+ for (i = 0; i < count; i++) {
+ if (! quiet) {
+ printbstat(&t[i]);
+ }
+
+ if (statit) {
+ switch(t[i].bs_mode & S_IFMT) {
+ case S_IFLNK:
+ cc_readlinkbufsz = MAXPATHLEN;
+ cc_readlinkbufp = (char *)calloc(
+ 1,
+ cc_readlinkbufsz);
+ nread = jdm_readlink(
+ fshandlep,
+ &t[i],
+ cc_readlinkbufp,
+ cc_readlinkbufsz);
+ if (verbose && nread > 0)
+ printf(
+ "readlink: ino %lld: <%*s>\n",
+ t[i].bs_ino,
+ nread,
+ cc_readlinkbufp);
+ free(cc_readlinkbufp);
+ if ( nread < 0 ) {
+ printf(
+ "could not read symlink ino %llu\n",
+ t[i].bs_ino );
+ printbstat(&t[i]);
+ }
+ break;
+
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFIFO:
+ case S_IFSOCK:
+ break;
+
+ case S_IFREG:
+ case S_IFDIR:
+ fd = jdm_open( fshandlep, &t[i], O_RDONLY);
+ if (fd < 0) {
+ printf(
+ "unable to open handle ino %lld: %s\n",
+ t[i].bs_ino, strerror(errno));
+ continue;
+ }
+ if (fstat64(fd, &sb) < 0) {
+ printf(
+ "unable to stat ino %lld: %s\n",
+ t[i].bs_ino, strerror(errno));
+ }
+ close(fd);
+
+ /*
+ * Don't compare blksize or blocks,
+ * they are used differently by stat
+ * and bstat.
+ */
+ if ( (t[i].bs_ino != sb.st_ino) ||
+ (t[i].bs_mode != sb.st_mode) ||
+ (t[i].bs_nlink != sb.st_nlink) ||
+ (t[i].bs_uid != sb.st_uid) ||
+ (t[i].bs_gid != sb.st_gid) ||
+ (t[i].bs_rdev != sb.st_rdev) ||
+ (t[i].bs_size != sb.st_size) ||
+ /* (t[i].bs_blksize != sb.st_blksize) || */
+ (t[i].bs_mtime.tv_sec != sb.st_mtime) ||
+ (t[i].bs_ctime.tv_sec != sb.st_ctime) ) {
+ printf("\nstat/bstat missmatch\n");
+ printbstat(&t[i]);
+ printstat(&sb);
+ }
+ }
+ }
+ }
+
+ if (debug)
+ break;
+ }
+
+ if (fsfd)
+ close(fsfd);
+
+ if (ret < 0 )
+ perror("ioctl(XFS_IOC_FSBULKSTAT)");
+
+ if (verbose)
+ printf(
+ "XFS_IOC_FSBULKSTAT test: last=%lld nent=%d ret=%d count=%d\n",
+ last, nent, ret, count);
+
+ return 1;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+#include <gdbm/ndbm.h>
+
+/* #define WorkDir "/xfs" */
+#define DBNAME "DBtest"
+#define DBRECS 100000
+#define LOOPS 100
+
+typedef struct _myDB {
+ char data[976];
+ unsigned short checksum;
+ long align;
+} myDB;
+
+int InitDbmLookup(int);
+int DoDbmLookup(void);
+void CleanupDbmLookup(void);
+void DoSysError(char *, int);
+int creatDbRec(myDB *);
+unsigned short calccksum(char *, int);
+void CkSumError(char *, unsigned short, unsigned short);
+int InsertKey(unsigned short *, int, unsigned short);
+void DumpKeys(int, unsigned short);
+
+DBM *dbm;
+int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
+unsigned short *KeyArray, *DupsArray;
+int debugflg = 0; /* are we in debugging mode? */
+int errflg = 0; /* usage option errors */
+int ignoreflg = 1; /* ignore errors in lookup; default = on */
+int loops = LOOPS;
+int randseed = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int numrecs = DBRECS, c, l;
+
+ while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
+ switch(c) {
+ case 'i':
+ ignoreflg++; break;
+ case 'd':
+ debugflg++; break;
+ case 'n':
+ numrecs = atoi(optarg);
+ numrecs = (numrecs < 1) ? DBRECS : numrecs;
+ break;
+ case 'l':
+ loops = atoi(optarg);
+ loops = (loops < 1) ? LOOPS : loops;
+ break;
+ case 's':
+ randseed = atoi(optarg);
+ randseed = (randseed < 0) ? 0 : randseed;
+ break;
+ case '?':
+ errflg++;
+ break;
+ }
+ }
+ if (errflg) {
+ printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
+ exit(0);
+ }
+ if (optind > argc) {
+ printf("Extra arguments ignored\n");
+ for ( ; optind<argc; optind++)
+ printf("\t%s\n", argv[optind]);
+ }
+
+ printf("dbtest v1.0\n\n");
+ printf("Creating database containing %d records...\n", numrecs);
+ printf("\tperforming lookups for %d iterations...\n", loops);
+ if (randseed)
+ printf("\tusing %d as seed for srandom()...\n\n", randseed);
+ InitDbmLookup(numrecs);
+ printf("\t\nThere were %d duplicate checksums generated\n", Dups);
+ for (l=0; l<loops; l++) {
+ printf("\nPerforming lookups on database...\n");
+ if (DoDbmLookup() != numrecs)
+ printf("\nError performing lookups!\n");
+ else
+ printf("\nLookups succeeded...\n");
+ }
+ printf("\nCleaning up database...\n");
+ printf("\t\nThere were %d duplicate checksums generated\n", Dups);
+ CleanupDbmLookup();
+ if (debugflg)
+ for (l=0; l<Dups; l++) {
+ if ((l % 8) == 0)
+ putchar('\n');
+ printf("0x%x\t", DupsArray[l]);
+ }
+
+ return 0;
+}
+
+
+int InitDbmLookup(int howmany)
+{
+ char filename[100];
+ datum key, content;
+ int i, rc;
+ myDB dbRec;
+
+ sprintf(filename, "%s-%d", DBNAME, getpid());
+ dbm = dbm_open(filename, O_WRONLY|O_CREAT, 0644);
+ if(dbm == NULL) DoSysError("\ndbm_open", (int)dbm);
+
+ if ((KeyArray = (unsigned short *)calloc( howmany,
+ sizeof(unsigned short))) == NULL)
+ DoSysError("\ncalloc:KeyArray", -1);
+ if ((DupsArray = (unsigned short *)calloc( 100,
+ sizeof(unsigned short))) == NULL)
+ DoSysError("\ncalloc:DupsArray", -1);
+
+ keyIdx = 0;
+ for(i=0; i<howmany; i++) {
+
+ if ( creatDbRec(&dbRec) )
+ DoSysError("\ncreatDbRec", -1);
+ if (debugflg)
+ printf("created rec #%-7d\t%x\r", i+1, dbRec.checksum);
+
+ if (InsertKey(KeyArray, keyIdx, dbRec.checksum))
+ keyIdx++;
+
+ key.dptr = (char *)&(dbRec.checksum);
+ key.dsize = sizeof(dbRec.checksum);
+ content.dptr = (char *)&dbRec;
+ content.dsize = sizeof(dbRec);
+write(2, NULL, 0);
+ rc = dbm_store(dbm, key, content, DBM_INSERT);
+ if (rc < 0)
+ DoSysError("\ndbm_store", rc);
+ else if (rc == 1) {
+ keyIdx--; /* key is already in database */
+ DupsArray[Dups++] = dbRec.checksum;
+ }
+ }
+ numDbmEntries = i;
+ dbm_close(dbm); /* close to eliminate chance of in-memory caching */
+ dbm = dbm_open(filename, O_RDONLY, 0);
+ if(dbm == NULL) DoSysError("\ndbm_open", (int)dbm);
+ return 0;
+}
+
+int DoDbmLookup(void)
+{
+ datum key, content;
+ int i, j, n;
+ myDB *dbp;
+ unsigned tmpck;
+
+ printf("\n\tSequential lookups...\n");
+ for(i=0, j=0; i<numDbmEntries; i++) {
+ key.dptr = (char *)(KeyArray+j);
+ key.dsize = sizeof(KeyArray[0]);
+
+write(2, NULL, 0);
+ content = dbm_fetch(dbm, key);
+ dbp = (myDB *)content.dptr;
+ if ( !content.dptr ) {
+ n = dbm_error(dbm);
+ if (n) printf("\n\ndbm_error: %d\n", n);
+ printf("\n%d: Sequential Lookup of key %4x failed!\n",
+ i, KeyArray[j]);
+ DumpKeys(i, KeyArray[j]);
+ Errors++;
+ if (ignoreflg) {
+ j++;
+ continue;
+ }
+ assert( dbp );
+ }
+
+ if (debugflg && dbp)
+ printf("Seq rec #%-6d: checksum %4x (%4x)\r", i,
+ dbp->checksum, KeyArray[j]);
+
+ if (content.dsize == 0) {
+ printf("\nrec #%-8d: key = %4x (%d)\n", i, KeyArray[j], j);
+ DoSysError("\ndbm_fetch", content.dsize);
+ }
+ if (dbp->checksum != KeyArray[j])
+ CkSumError("KeySequential", dbp->checksum, KeyArray[j]);
+ if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[j])
+ CkSumError("DataSequential", tmpck, KeyArray[j]);
+ if (++j >= keyIdx)
+ j = 0;
+ }
+ printf("\n\n\tRandom lookups...\n");
+ for(i=0; i<numDbmEntries; i++) {
+ n = random() % keyIdx;
+ key.dptr = (char *)(KeyArray+n);
+ key.dsize = sizeof(KeyArray[0]);
+ content = dbm_fetch(dbm, key);
+ dbp = (myDB *)content.dptr;
+ if ( !content.dptr ) {
+ n = dbm_error(dbm);
+ if (n) printf("\n\ndbm_error: %d\n", n);
+ printf("\n%d: Random Lookup of key %4x failed!\n",
+ i, KeyArray[n]);
+ DumpKeys(n, KeyArray[n]);
+ Errors++;
+ if (ignoreflg) {
+ continue;
+ }
+ assert( dbp );
+ }
+
+ if (debugflg && dbp)
+ printf("Rnd rec #%-6d: checksum %4x (%4x)\r", i,
+ dbp->checksum, KeyArray[n]);
+
+ if (content.dsize == 0)
+ DoSysError("\ndbm_fetch", content.dsize);
+ if (dbp->checksum != KeyArray[n])
+ CkSumError("KeyRand", dbp->checksum, KeyArray[n]);
+ if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[n])
+ CkSumError("DataRand", tmpck, KeyArray[n]);
+ }
+ return i;
+}
+
+void CleanupDbmLookup(void)
+{
+ char filename[100];
+ int rc;
+
+ dbm_close(dbm);
+ sprintf(filename, "%s-%d.dir", DBNAME, getpid());
+ rc = unlink(filename);
+ if (rc) DoSysError("\nunlink", rc);
+ sprintf(filename, "%s-%d.pag", DBNAME, getpid());
+ rc = unlink(filename);
+ if (rc) DoSysError("\nunlink", rc);
+}
+
+void DoSysError(char *msg, int rc)
+{
+ perror(msg);
+ fprintf(stderr, "Bailing out! status = %d\n", rc);
+ exit(-1);
+}
+
+int creatDbRec(myDB *dbp)
+{
+ static int once = 0;
+ int i, j;
+ long *ptr;
+ long timeseed;
+
+ if (!once) {
+ once++;
+ if ( !randseed ) {
+ timeseed = time(0);
+ printf("\tusing %ld as seed for srandom()...\n\n",
+ timeseed);
+ srandom(timeseed);
+ } else
+ srandom(randseed);
+ }
+ ptr = (long *)&(dbp->data);
+ j = sizeof(dbp->data) / sizeof(long);
+ for (i=0; i < j; i++, ptr++) {
+ *ptr = random();
+ }
+ for (i=(j*sizeof(long)); i<sizeof(dbp->data); i++)
+ dbp->data[i] = (char)time(0);
+
+ dbp->checksum = calccksum(dbp->data, sizeof(dbp->data));
+ return 0;
+}
+
+unsigned short calccksum(char *ptr, int size)
+{
+ unsigned short sum;
+ int i, n;
+
+ sum = 0;
+ n = ((size > 100) ? 100 : size);
+ for (i=0; i<n && ptr; i++, ptr++) {
+ if (sum & 01)
+ sum = (sum >> 1) + 0x8000;
+ else
+ sum >>= 1;
+ sum += (unsigned short)*ptr;
+ sum &= 0xffff;
+ }
+ return sum;
+}
+
+/*ARGSUSED*/
+void CkSumError(char *msg, unsigned short ck1, unsigned short ck2)
+{
+ Errors++;
+ printf("%s\n\tChecksum error, %u != %u, Total errors = %d\n",
+ msg, ck1, ck2, Errors);
+ exit(1);
+}
+
+int InsertKey(unsigned short *k, int idx, unsigned short val)
+{
+/*
+ int i, found=0;
+*/
+
+ return( (k[idx] = val) );
+
+/*
+ for (i=0; i<idx; i++) {
+ if (k[i] == val) {
+ found++;
+ break;
+ }
+ }
+
+ if (!found)
+ k[idx] = val;
+
+ return(!found);
+*/
+}
+
+void DumpKeys(int n, unsigned short key)
+{
+/*
+ int i;
+ unsigned short *p;
+*/
+ FILE *f;
+
+ if ((f = fopen("keys", "a")) == NULL) {
+ perror("open(keys)");
+ exit(1);
+ }
+/*
+ for (i=0, p=arr; i<keyIdx && p; i++, p++)
+*/
+ fprintf(f, "%d: 0x%x\n", n, key);
+
+ fclose(f);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <libxfs.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <errno.h>
+
+int
+main(int argc, char **argv)
+{
+ off_t offset = 0;
+ int blksize = 4096;
+ long long maxblks = -1; /* no limit */
+ long long nblks = 0;
+ int value = 0;
+ int sts = 0;
+ int fd;
+ char *z;
+ char *path;
+ int oflags = O_WRONLY;
+
+ char *progname;
+
+ if (strrchr(argv[0],'/'))
+ progname = strrchr(argv[0],'/')+1;
+ else
+ progname = argv[0];
+
+ while ((fd = getopt(argc, argv, "b:n:o:v:ct")) != EOF) {
+ switch (fd) {
+ case 'b':
+ blksize = atoi(optarg) * 512;
+ break;
+ case 'n':
+ maxblks = atoll(optarg);
+ break;
+ case 'o':
+ offset = atoll(optarg);
+ break;
+ case 'v':
+ value = atoi(optarg);
+ break;
+ case 'c':
+ oflags |= O_CREAT;
+ break;
+ case 't':
+ oflags |= O_TRUNC;
+ break;
+ default:
+ sts++;
+ }
+ }
+ if (sts || argc - optind != 1) {
+ fprintf(stderr,
+ "Usage: %s [-b N*512] [-n N] [-o off] [-v val] "
+ " [-c] [-t] <dev/file>\n",
+ progname);
+ fprintf(stderr," -c: create -t: truncate\n");
+ exit(1);
+ }
+
+ path = argv[optind];
+
+ if ((fd = open(path, oflags)) < 0) {
+ fprintf(stderr,
+ "error opening \"%s\": %s\n",
+ path, strerror(errno));
+ exit(1);
+ }
+ if ((lseek64(fd, offset, SEEK_SET)) < 0) {
+ fprintf(stderr, "%s: error seeking to offset %llu "
+ "on \"%s\": %s\n",
+ progname, offset, path, strerror(errno));
+ exit(1);
+ }
+
+ if ((z = memalign(getpagesize(), blksize)) == NULL) {
+ fprintf(stderr, "%s: can't memalign %u bytes: %s\n",
+ progname, blksize, strerror(errno));
+ exit(1);
+ }
+ memset(z, value, blksize);
+ errno = 0;
+ for (;;) {
+ if (nblks++ == maxblks)
+ break;
+ if ((sts = write(fd, z, blksize)) < blksize) {
+ if (errno == ENOSPC || sts >= 0)
+ break;
+ fprintf(stderr, "%s: write failed: %s\n",
+ progname, strerror(errno));
+ break;
+ }
+ }
+ printf("Wrote %.2fKb (value 0x%x)\n",
+ (double) ((--nblks) * blksize) / 1024, value);
+ free(z);
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+ /*
+ * This is mostly a "crash & burn" test. -v turns on verbosity
+ * and -c actually fails on errors - but expected errors aren't
+ * expected...
+ */
+
+#include "global.h"
+
+int verbose;
+int pid;
+
+int checkflag=0;
+
+#define MKNOD_DEV 0
+
+static int dirstress(char *dirname, int dirnum, int nfiles, int keep);
+static int create_entries(int nfiles);
+static int scramble_entries(int nfiles);
+static int remove_entries(int nfiles);
+
+int
+main(
+ int argc,
+ char *argv[])
+{
+ char *dirname;
+ int nprocs;
+ int nfiles;
+ int c;
+ int errflg;
+ int i;
+ long seed;
+ int childpid;
+ int nprocs_per_dir;
+ int keep;
+ int status, istatus;
+
+ pid=getpid();
+
+ errflg = 0;
+ dirname = NULL;
+ nprocs = 4;
+ nfiles = 100;
+ seed = time(NULL);
+ nprocs_per_dir = 1;
+ keep = 0;
+ verbose = 0;
+ while ((c = getopt(argc, argv, "d:p:f:s:n:kvc")) != EOF) {
+ switch(c) {
+ case 'p':
+ nprocs = atoi(optarg);
+ break;
+ case 'f':
+ nfiles = atoi(optarg);
+ break;
+ case 'n':
+ nprocs_per_dir = atoi(optarg);
+ break;
+ case 'd':
+ dirname = optarg;
+ break;
+ case 's':
+ seed = strtol(optarg, NULL, 0);
+ break;
+ case 'k':
+ keep = 1;
+ break;
+ case '?':
+ errflg++;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'c':
+ checkflag++;
+ break;
+ }
+ }
+ if (errflg || (dirname == NULL)) {
+ printf("Usage: dirstress [-d dir] [-p nprocs] [-f nfiles] [-n procs per dir]\n"
+ " [-v] [-s seed] [-k] [-c]\n");
+ exit(0);
+ }
+
+ printf("** [%d] Using seed %ld\n", pid, seed);
+ srandom(seed);
+
+ for (i = 0; i < nprocs; i++) {
+ if (verbose) fprintf(stderr,"** [%d] fork\n", pid);
+ childpid = fork();
+ if (childpid < 0) {
+ perror("Fork failed");
+ exit(errno);
+ }
+ if (childpid == 0) {
+ int r;
+ /* child */
+ pid=getpid();
+
+ if (verbose) fprintf(stderr,"** [%d] forked\n", pid);
+ r=dirstress(dirname, i / nprocs_per_dir, nfiles, keep);
+ if (verbose) fprintf(stderr,"** [%d] exit\n", pid);
+ exit(r);
+ }
+ }
+ if (verbose) fprintf(stderr,"** [%d] wait\n", pid);
+ istatus=0;
+
+ /* wait & reap children, accumulating error results */
+ while (wait(&status) != -1)
+ istatus+=status/256;
+
+ printf("INFO: Dirstress complete\n");
+ if (verbose) fprintf(stderr,"** [%d] exit %d\n", pid, istatus);
+ return istatus;
+}
+
+
+
+int
+dirstress(
+ char *dirname,
+ int dirnum,
+ int nfiles,
+ int keep)
+{
+ int error;
+ char buf[1024];
+ int r;
+
+ sprintf(buf, "%s/stressdir", dirname);
+ if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
+ error = mkdir(buf, 0777);
+ if (error && (errno != EEXIST)) {
+ perror("Create stressdir directory failed");
+ return 1;
+ }
+
+ if (verbose) fprintf(stderr,"** [%d] chdir %s\n", pid, buf);
+ error = chdir(buf);
+ if (error) {
+ perror("Cannot chdir to main directory");
+ return 1;
+ }
+
+ sprintf(buf, "stress.%d", dirnum);
+ if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
+ error = mkdir(buf, 0777);
+ if (error && (errno != EEXIST)) {
+ perror("Create pid directory failed");
+ return 1;
+ }
+
+ if (verbose) fprintf(stderr,"** [%d] chdir %s\n", pid, buf);
+ error = chdir(buf);
+ if (error) {
+ perror("Cannot chdir to dirnum directory");
+ return 1;
+ }
+
+ r=1; /* assume failure */
+ if (verbose) fprintf(stderr,"** [%d] create entries\n", pid);
+ if (create_entries(nfiles)) {
+ printf("!! [%d] create failed\n", pid);
+ } else {
+ if (verbose) fprintf(stderr,"** [%d] scramble entries\n", pid);
+ if (scramble_entries(nfiles)) {
+ printf("!! [%d] scramble failed\n", pid);
+ } else {
+ if (keep) {
+ if (verbose) fprintf(stderr,"** [%d] keep entries\n", pid);
+ r=0; /* success */
+ } else {
+ if (verbose) fprintf(stderr,"** [%d] remove entries\n", pid);
+ if (remove_entries(nfiles)) {
+ printf("!! [%d] remove failed\n", pid);
+ } else {
+ r=0; /* success */
+ }
+ }
+ }
+ }
+
+ if (verbose) fprintf(stderr,"** [%d] chdir ..\n", pid);
+ error = chdir("..");
+ if (error) {
+ perror("Cannot chdir out of pid directory");
+ return 1;
+ }
+
+ if (!keep) {
+ sprintf(buf, "stress.%d", dirnum);
+ if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
+ if (rmdir(buf)) {
+ perror("rmdir");
+ if (checkflag) return 1;
+ }
+ }
+
+ if (verbose) fprintf(stderr,"** [%d] chdir ..\n", pid);
+ error = chdir("..");
+ if (error) {
+ perror("Cannot chdir out of working directory");
+ return 1;
+ }
+
+ if (!keep) {
+ if (verbose) fprintf(stderr,"** [%d] rmdir stressdir\n", pid);
+ if (rmdir("stressdir")) {
+ perror("rmdir");
+ if (checkflag) return 1;
+ }
+ }
+
+ return r;
+}
+
+int
+create_entries(
+ int nfiles)
+{
+ int i;
+ int fd;
+ char buf[1024];
+
+ for (i = 0; i < nfiles; i++) {
+ sprintf(buf, "XXXXXXXXXXXX.%d", i);
+ switch (i % 4) {
+ case 0:
+ /*
+ * Create a file
+ */
+ if (verbose) fprintf(stderr,"** [%d] creat %s\n", pid, buf);
+ fd = creat(buf, 0666);
+ if (fd > 0) {
+ if (verbose) fprintf(stderr,"** [%d] close %s\n", pid, buf);
+ close(fd);
+ } else {
+ fprintf(stderr,"!! [%d] close %s failed\n", pid, buf);
+ perror("close");
+ if (checkflag) return 1;
+ }
+
+ break;
+ case 1:
+ /*
+ * Make a directory.
+ */
+ if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
+ if (mkdir(buf, 0777)) {
+ fprintf(stderr,"!! [%d] mkdir %s 0777 failed\n", pid, buf);
+ perror("mkdir");
+ if (checkflag) return 1;
+ }
+
+ break;
+ case 2:
+ /*
+ * Make a symlink
+ */
+ if (verbose) fprintf(stderr,"** [%d] symlink %s %s\n", pid, buf, buf);
+ if (symlink(buf, buf)) {
+ fprintf(stderr,"!! [%d] symlink %s %s failed\n", pid, buf, buf);
+ perror("symlink");
+ if (checkflag) return 1;
+ }
+
+ break;
+ case 3:
+ /*
+ * Make a dev node
+ */
+ if (verbose) fprintf(stderr,"** [%d] mknod %s 0x%x\n", pid, buf, MKNOD_DEV);
+ if (mknod(buf, S_IFCHR | 0666, MKNOD_DEV)) {
+ fprintf(stderr,"!! [%d] mknod %s 0x%x failed\n", pid, buf, MKNOD_DEV);
+ perror("mknod");
+ if (checkflag) return 1;
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+
+int
+scramble_entries(
+ int nfiles)
+{
+ int i;
+ char buf[1024];
+ char buf1[1024];
+ long r;
+ int fd;
+
+ for (i = 0; i < nfiles * 2; i++) {
+ switch (i % 5) {
+ case 0:
+ /*
+ * rename two random entries
+ */
+ r = random() % nfiles;
+ sprintf(buf, "XXXXXXXXXXXX.%ld", r);
+ r = random() % nfiles;
+ sprintf(buf1, "XXXXXXXXXXXX.%ld", r);
+
+ if (verbose) fprintf(stderr,"** [%d] rename %s %s\n", pid, buf, buf1);
+ if (rename(buf, buf1)) {
+ perror("rename");
+ if (checkflag) return 1;
+ }
+ break;
+ case 1:
+ /*
+ * unlink a random entry
+ */
+ r = random() % nfiles;
+ sprintf(buf, "XXXXXXXXXXXX.%ld", r);
+ if (verbose) fprintf(stderr,"** [%d] unlink %s\n", pid, buf);
+ if (unlink(buf)) {
+ fprintf(stderr,"!! [%d] unlink %s failed\n", pid, buf);
+ perror("unlink");
+ if (checkflag) return 1;
+ }
+ break;
+ case 2:
+ /*
+ * rmdir a random entry
+ */
+ r = random() % nfiles;
+ sprintf(buf, "XXXXXXXXXXXX.%ld", r);
+ if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
+ if (rmdir(buf)) {
+ fprintf(stderr,"!! [%d] rmdir %s failed\n", pid, buf);
+ perror("rmdir");
+ if (checkflag) return 1;
+ }
+ break;
+ case 3:
+ /*
+ * create a random entry
+ */
+ r = random() % nfiles;
+ sprintf(buf, "XXXXXXXXXXXX.%ld", r);
+
+ if (verbose) fprintf(stderr,"** [%d] creat %s 0666\n", pid, buf);
+ fd = creat(buf, 0666);
+ if (fd > 0) {
+ if (verbose) fprintf(stderr,"** [%d] close %s\n", pid, buf);
+ if (close(fd)) {
+ fprintf(stderr,"!! [%d] close %s failed\n", pid, buf);
+ perror("close");
+ if (checkflag) return 1;
+ }
+ } else {
+ fprintf(stderr,"!! [%d] creat %s 0666 failed\n", pid, buf);
+ perror("creat");
+ if (checkflag) return 1;
+ }
+ break;
+ case 4:
+ /*
+ * mkdir a random entry
+ */
+ r = random() % nfiles;
+ sprintf(buf, "XXXXXXXXXXXX.%ld", r);
+ if (verbose) fprintf(stderr,"** [%d] mkdir %s\n", pid, buf);
+ if (mkdir(buf, 0777)) {
+ fprintf(stderr,"!! [%d] mkdir %s failed\n", pid, buf);
+ perror("mkdir");
+ if (checkflag) return 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+remove_entries(
+ int nfiles)
+{
+ int i;
+ char buf[1024];
+ struct stat statb;
+ int error;
+
+ for (i = 0; i < nfiles; i++) {
+ sprintf(buf, "XXXXXXXXXXXX.%d", i);
+ error = lstat(buf, &statb);
+ if (error) {
+ /* ignore this one */
+ continue;
+ }
+ if (S_ISDIR(statb.st_mode)) {
+ if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
+ if (rmdir(buf)) {
+ fprintf(stderr,"!! [%d] rmdir %s failed\n", pid, buf);
+ perror("rmdir");
+ if (checkflag) return 1;
+ }
+ } else {
+ if (verbose) fprintf(stderr,"** [%d] unlink %s\n", pid, buf);
+ if (unlink(buf)) {
+ fprintf(stderr,"!! [%d] unlink %s failed\n", pid, buf);
+ perror("unlink");
+ if (checkflag) return 1;
+ }
+ }
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <libxfs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+void expect_error(int r, int err)
+{
+ if (r<0) {
+ if (errno == err) {
+ printf(" --- got error %d as expected\n", err);
+ } else {
+ perror(" !!! unexpected error");
+ }
+ } else {
+ printf(" !!! success instead of error %d as expected\n", err);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int fsfd;
+
+ if (argc != 2) {
+ fprintf(stderr,"usage: %s <filesystem>\n",
+ argv[0]);
+ exit(0);
+ }
+
+ fsfd = open(argv[1], O_RDONLY);
+ if (fsfd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ printf("--- ioctl with bad output address\n");
+ expect_error(ioctl(fsfd, XFS_IOC_FSCOUNTS, NULL), EFAULT);
+ printf("--- ioctl with bad input address\n");
+ expect_error(ioctl(fsfd, XFS_IOC_SET_RESBLKS, NULL), EFAULT);
+
+ close(fsfd);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+/*
+ * Test for filesystem features on given mount point or device
+ * -q test for quota support (kernel compile option)
+ * -u test for user quota support (mount option)
+ * -g test for group quota support (mount option)
+ * Return code: 0 is true, anything else is error/not supported
+ */
+
+#include <libxfs.h>
+#include <sys/quota.h>
+#include <xqm.h>
+
+int verbose = 0;
+
+void
+usage(void)
+{
+ fprintf(stderr, "Usage: feature [-v] -<q|u|g|U|G> <filesystem>\n");
+ exit(1);
+}
+
+int
+hasxfsquota(int type, int q, char *device)
+{
+ fs_quota_stat_t qstat;
+ int qcmd;
+
+ memset(&qstat, 0, sizeof(fs_quota_stat_t));
+ qcmd = QCMD(Q_XGETQSTAT, type);
+ if (quotactl(qcmd, device, 0, (caddr_t)&qstat) < 0) {
+ if (verbose)
+ perror("quotactl");
+ return (1);
+ }
+ else if (q == 0)
+ return (0);
+ else if (q == XFS_QUOTA_UDQ_ENFD && qstat.qs_flags & XFS_QUOTA_UDQ_ENFD)
+ return (0);
+ else if (q == XFS_QUOTA_GDQ_ENFD && qstat.qs_flags & XFS_QUOTA_GDQ_ENFD)
+ return (0);
+ else if (q == XFS_QUOTA_UDQ_ACCT && qstat.qs_flags & XFS_QUOTA_UDQ_ACCT)
+ return (0);
+ else if (q == XFS_QUOTA_GDQ_ACCT && qstat.qs_flags & XFS_QUOTA_GDQ_ACCT)
+ return (0);
+ if (verbose)
+ fprintf(stderr, "quota type (%d) not available\n", q);
+ return (1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int gflag = 0;
+ int Gflag = 0;
+ int qflag = 0;
+ int uflag = 0;
+ int Uflag = 0;
+ char *fs;
+
+ while ((c = getopt(argc, argv, "gGquUv")) != EOF) {
+ switch (c) {
+ case 'g':
+ gflag++;
+ break;
+ case 'G':
+ Gflag++;
+ break;
+ case 'q':
+ qflag++;
+ break;
+ case 'u':
+ uflag++;
+ break;
+ case 'U':
+ Uflag++;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (!uflag && !gflag && !qflag && !Uflag && !Gflag)
+ usage();
+ if (optind != argc-1)
+ usage();
+ fs = argv[argc-1];
+
+ if (qflag)
+ return(hasxfsquota(0, 0, fs));
+ if (gflag)
+ return(hasxfsquota(GRPQUOTA, XFS_QUOTA_GDQ_ENFD, fs));
+ if (uflag)
+ return(hasxfsquota(USRQUOTA, XFS_QUOTA_UDQ_ENFD, fs));
+ if (Gflag)
+ return(hasxfsquota(GRPQUOTA, XFS_QUOTA_GDQ_ACCT, fs));
+ if (Uflag)
+ return(hasxfsquota(USRQUOTA, XFS_QUOTA_UDQ_ACCT, fs));
+
+ fprintf(stderr, "feature: dunno what you're doing?\n");
+ return(1);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * fill pathname key nbyte
+ *
+ * use key to seed random number generator so data is deterministic
+ *
+ * lines are at most 72 bytes long so diff(1) does not choke
+ */
+
+int
+main(int argc, char **argv)
+{
+ FILE *f;
+ unsigned int seed;
+ long i;
+ int nbyte;
+ char *hdr;
+ char *hp;
+ char c;
+
+ /* quick and dirty, no args checking */
+ if ((f = fopen(argv[1], "w")) == NULL) {
+ fprintf(stderr, "fill: cannot create \"%s\": %s\n", argv[1], strerror(errno));
+ exit(1);
+ }
+ seed = 0;
+ i = 0;
+ while (argv[2][i]) {
+ seed <<= 8;
+ seed |= argv[2][i];
+ i++;
+ }
+ srand(seed);
+
+ nbyte = atoi(argv[3]);
+
+ /*
+ * line format
+ *
+ * byte offset @ start of this line XXXXXXXXXXXX
+ * test iteration number XXXX
+ * key (usually file name) argv[2]
+ * random bytes to fill the line
+ */
+
+ hdr = (char *)malloc(12+1+4+1+strlen(argv[2])+1+1);
+ sprintf(hdr, "%012ld %04d %s ", (long int)0, 0, argv[2]);
+ hp = hdr;
+
+ for (i = 0; i < nbyte-1; i++) {
+ if (*hp) {
+ c = *hp;
+ hp++;
+ }
+ else if ((i % 72) == 71)
+ c = '\n';
+ else
+ c = 32+(rand() % (128-32));
+ fputc(c, f);
+ if (c == '\n') {
+ hp = hdr;
+ sprintf(hdr, "%012ld %04d %s ", i+1, 0, argv[2]);
+ }
+ }
+ fputc('\n', f);
+
+ exit(0);
+}
--- /dev/null
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+
+/*
+ * fill2:
+ * Derived from fill.c, adds command line options, block boundary marking
+ * and allows me to tweak to suit fill2fs without breaking other qa tests.
+ * This version marks block boundaries (512, 1k, 4k and 16k) within the file
+ * using characters guaranteed not to appear anywhere else, this may allow
+ * simple checks in future which can inspect these offsets and ensure one of
+ * of the four characters is present. Also fixes off-by-one error in fill.c
+ * and is more careful about checking when write operations fail - this is
+ * needed by fill2fs to ensure that the number of bytes written is accurately
+ * determined.
+ *
+ * $Id$
+ */
+
+
+#include <libxfs.h>
+#include <errno.h>
+
+#define N(x) (sizeof(x)/sizeof(x[0]))
+
+/* function prototypes */
+static void illegal(char *, char *);
+static void reqval(char, char * [], int);
+static void respec(char, char * [], int);
+static void unknown(char, char *);
+static void usage(void);
+static char *progname;
+
+char *dopts[] = { "nbytes", "linelength", "seed", "file", NULL };
+enum { D_NBYTES, D_LINELENGTH, D_SEED, D_FILE, D_ISSET, D_NUM };
+int dflags[D_NUM] = { 0 };
+char *bopts[] = { "512", "1k", "4k", "16k" };
+enum { B_512, B_1K, B_4K, B_16K, B_ISSET, B_NUM };
+int bflags[B_NUM] = { 0 };
+
+
+/*
+ * block boundaries
+ *
+ */
+
+/* block boundaries which should be flagged in the output file */
+/* flag is the character that should be used to indicate each type */
+/* of block boundary */
+
+
+struct s_block_type {
+ int mark;
+ int size;
+ char flag;
+};
+
+static struct s_block_type btypes[] = {
+ { 0, 512, '!' }, /* 512 */
+ { 0, 1024, '"' }, /* 1k */
+ { 0, 4096, '#' }, /* 4k */
+ { 0, 16384, '$' }, /* 16k */
+};
+
+/*
+ * main
+ *
+ */
+
+int
+main(int argc, char **argv)
+{
+ int status = 0; /* return status */
+ int c; /* current option character */
+ char *p; /* for getsubopt calls */
+ long nbytes; /* total number of bytes to write */
+ int dlen; /* length of normal output data line */
+ const char *dseed; /* input string for seeding rand */
+ unsigned int seed; /* seed for output data */
+ char *dfile; /* where to write output */
+
+ FILE *f; /* output file */
+ char *dbuf; /* output line buffer */
+ char bbuf[50]; /* block boundary string */
+ char *active; /* active buffer to copy out of */
+ size_t hlen; /* header length (bytes+key) in output */
+ /* lines */
+ char *hptr; /* pointer to end of header */
+ char *ptr; /* current position to copy from */
+ int blktype; /* current block boundary type */
+ int boundary; /* set if current output char lies on */
+ /* block boundary */
+ long i;
+ int j;
+ int l;
+
+
+ /* defaults */
+ progname = basename(argv[0]);
+ nbytes = 1024 * 1024;
+ dlen = 73; /* includes the trailing newline */
+
+ while ((c = getopt(argc, argv, "d:b:")) != EOF) {
+ switch (c) {
+ case 'd':
+ if (dflags[D_ISSET])
+ respec('d', NULL, 0);
+ dflags[D_ISSET] = 1;
+
+ p = optarg;
+ while (*p != '\0') {
+ char *value;
+ switch (getsubopt(&p, (constpp)dopts, &value)) {
+ case D_NBYTES:
+ if (! value) reqval('d', dopts, D_NBYTES);
+ if (dflags[D_NBYTES]) respec('d', dopts, D_NBYTES);
+ dflags[D_NBYTES] = 1;
+ nbytes = strtol(value, &ptr, 10);
+ if (ptr == value) illegal(value, "d nbytes");
+ break;
+
+ case D_LINELENGTH:
+ if (! value) reqval('d', dopts, D_LINELENGTH);
+ if (dflags[D_LINELENGTH]) respec('d', dopts, D_LINELENGTH);
+ dflags[D_LINELENGTH] = 1;
+ dlen = (int) strtol(value, &ptr, 10) + 1;
+ if (ptr == value) illegal(value, "d linelength");
+ break;
+
+ case D_SEED:
+ if (! value) reqval('d', dopts, D_SEED);
+ if (dflags[D_SEED]) respec('D', dopts, D_SEED);
+ dflags[D_SEED] = 1;
+ dseed = value;
+ break;
+
+ case D_FILE:
+ if (! value) reqval('d', dopts, D_FILE);
+ if (dflags[D_FILE]) respec('d', dopts, D_FILE);
+ dflags[D_FILE] = 1;
+ dfile = value;
+ break;
+
+ default:
+ unknown('d', value);
+ }
+ }
+ break;
+
+ case 'b':
+ if (bflags[B_ISSET])
+ respec('b', NULL, 0);
+ bflags[B_ISSET] = 1;
+
+ p = optarg;
+ while (*p != '\0') {
+ char *value;
+ switch (getsubopt(&p, (constpp)bopts, &value)) {
+ case B_512:
+ if (value) illegal(value, "b 512");
+ if (bflags[B_512]) respec('b', bopts, B_512);
+ bflags[B_512] = 1;
+ btypes[0].mark = 1;
+ break;
+
+ case B_1K:
+ if (value) illegal(value, "b 1k");
+ if (bflags[B_1K]) respec('b', bopts, B_1K);
+ bflags[B_1K] = 1;
+ btypes[1].mark = 1;
+ break;
+
+ case B_4K:
+ if (value) illegal(value, "b 4k");
+ if (bflags[B_4K]) respec('b', bopts, B_4K);
+ bflags[B_4K] = 1;
+ btypes[2].mark = 1;
+ break;
+
+ case B_16K:
+ if (value) illegal(value, "b 16k");
+ if (bflags[B_16K]) respec('b', bopts, B_16K);
+ bflags[B_16K] = 1;
+ btypes[3].mark = 1;
+ break;
+
+ default:
+ unknown('b', value);
+ break;
+ }
+ }
+ break;
+
+ case '?':
+ usage();
+ }
+ }
+
+ if (dflags[D_FILE] && optind != argc)
+ usage();
+
+ if (! dflags[D_FILE] && argc - optind != 1)
+ usage();
+
+ if (! dflags[D_FILE])
+ dfile = argv[optind];
+
+ if ((f = fopen(dfile, "w")) == NULL) {
+ fprintf(stderr, "fill2: cannot create \"%s\": %s\n",
+ dfile, strerror(errno));
+ status = 1;
+ goto cleanup;
+ }
+
+ if (! dflags[D_SEED])
+ dseed = dfile;
+
+ /* seed is an ascii string */
+ seed = 0;
+ i = 0;
+ while (dseed[i]) {
+ seed <<= 8;
+ seed |= dseed[i];
+ i++;
+ }
+ srand(seed);
+
+
+ /* normal data line format: XXXXXXXXXXXX CCCC...CCC CCCCCCCCCCCC...CCC */
+ /* block boundary format: CXXXXXXX */
+
+ dbuf = (char *) malloc(dlen + 1);
+ hlen = 12+1+strlen(dseed)+1;
+ assert(hlen < dlen);
+ hptr = dbuf + hlen;
+
+ for (i = 0; i < nbytes; i++) {
+
+
+ /* is this a block boundary? check largest to smallest */
+ boundary = 0;
+ for (j = N(btypes) - 1; j >= 0; j--) {
+ if (btypes[j].mark) {
+ /* first time through or just before a block boundary? */
+ if (i == 0 || i % btypes[j].size == btypes[j].size - 1) {
+ boundary = 1;
+ blktype = j;
+ break;
+ }
+ }
+ }
+
+
+ /* are there block boundaries to check? */
+ /* is this the first time through? */
+ /* block boundaries take priority over other output */
+ if (bflags[B_ISSET] && (i == 0 || boundary)) {
+ sprintf(bbuf, "%s%c%07ld\n",
+ i ? "\n" : "",
+ btypes[blktype].flag,
+ /* remember i is one less than block boundary */
+ i ? (i+1) / btypes[blktype].size : 0);
+ active = bbuf;
+ ptr = bbuf;
+ }
+ /* are we at the start of a new line? */
+ else if (i == 0
+ || (active == bbuf && *ptr == '\0')
+ || (active == dbuf && l == dlen))
+ {
+ sprintf(dbuf, "%012ld %s ", i, dseed);
+ assert(*hptr == '\0');
+ for (ptr = hptr; ptr != dbuf + dlen - 1; ptr++) {
+ /* characters upto 126 '~' are used */
+ /* do not use !"#$ - leave free for use as block markers */
+ *ptr = 37 + (rand() % (127 - 37));
+ }
+ *ptr++ = '\n';
+ *ptr = '\0';
+ assert(ptr == dbuf + dlen);
+ active = dbuf;
+ ptr = dbuf;
+ l = 0;
+ }
+ else {
+ /* continue copying from the active buffer */
+ }
+
+ /* output one new character from current buffer */
+ if (fputc(*ptr++, f) == EOF) {
+ fprintf(stderr, "fill2: could not write character to \"%s\": %s\n",
+ dfile, strerror(errno));
+ status = 1;
+ goto cleanup;
+ }
+ if (active == dbuf) l++;
+
+ }
+
+ cleanup:
+
+ /* close file and flush buffers - check if this fails */
+ if (fclose(f) != 0) {
+ fprintf(stderr, "fill2: fclose() on \"%s\" failed: %s\n",
+ dfile, strerror(errno));
+ status = 1;
+ }
+ exit(status);
+}
+
+
+
+/*
+ * suboption checking functions
+ *
+ */
+
+static void
+illegal(char *value, char *opt)
+{
+ fprintf(stderr, "%s: Error: Illegal value \"%s\" for -%s option\n",
+ progname, value, opt);
+ usage();
+}
+static void
+reqval(char opt, char *tab[], int idx)
+{
+ fprintf(stderr, "%s: Error: -%c %s option requires a value\n",
+ progname, opt, tab[idx]);
+ usage();
+}
+static void
+respec(char opt, char *tab[], int idx)
+{
+ fprintf(stderr, "%s: Error: ", progname);
+ fprintf(stderr, "-%c ", opt);
+ if (tab) fprintf(stderr, "%s ", tab[idx]);
+ fprintf(stderr, "option respecified\n");
+ usage();
+}
+static void
+unknown(char opt, char *s)
+{
+ fprintf(stderr, "%s: Error: Unknown option -%c %s\n", progname, opt, s);
+ usage();
+}
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] filename\n"
+"Options:\n"
+" -d [nbytes=num,linelength=num, output data properties\n"
+" seed=string,file=name]\n"
+" -b [512,1k,4k,16k] where to mark block boundaries\n", progname);
+ exit(2);
+}
--- /dev/null
+#!/usr/bin/perl -w
+#
+
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+
+#
+# fill2fs:
+# Fill a filesystem, or write a specified number of bits.
+# Script runs deterministically given a seed for the random number
+# generator. Will generate the same set of directories and files,
+# with the only source of variation the precise point at which the
+# filesystem fills up. When used with XFS filesystems, and when
+# the filesize is small, XFS pre-allocation may cause the filesystem
+# to "fill up" before the actual disk space is gone. Using this
+# script repeatedly, with a delay between invocations, to account
+# for extent flushing, will allow more of the filesystem to be filled.
+#
+# All generated files are checksummed and this sum is stored in the
+# filename (files are named: <sequence number>.<checksum>.data.
+# Normally script is invoked using the --list option, which causes all
+# data files to be written to standard output (--list=-) or a file
+# (--list=filename). This list can be fed into fill2fs_check, which
+# recomputes the checksums and flags any errors.
+#
+# The --stddev=0 forces all files to be precisely --filesize bytes in
+# length, some other value (--stddev=val) produces filesizes with a
+# normal distribution with standard deviation val. If not specified
+# most file sizes are set to lie within 30% of the requested file size.
+#
+# fill2fs is not guaranteed to write the requested number of bytes, or
+# fill the filesystem completely. However, it and fill2 are both very
+# careful about establishing when write operations fail. When the
+# --verbose option is used the number of bytes "actually written"
+# is guaranteed to be the number of bytes on disk.
+#
+# $Id$
+#
+
+use Getopt::Long;
+use File::Basename;
+
+chomp($os = `uname`);
+
+#
+# fsinfo: get filesystem info put it into the global namespace, assigns:
+# $dev, $type, $blocks, $used, $avail, $cap, $mnt, $mnt_options
+# $fsblocks, $fsblocksize, $agblocks, $agcount, $imax_pct, $logblocks
+# $logstart, $internal
+#
+# if $verbose is set then output fs info to STDERR
+#
+
+sub fsinfo {
+ my($file) = $_[0];
+
+ # filesystem space and mount point
+
+ $cmd = "df" if ($os =~ /IRIX/);
+ $cmd = "df -P -T --block-size=512" if ($os =~ /Linux/);
+ chomp($_ = `$cmd $file | tail -1`);
+ $n = ($dev, $type, $blocks, $used, $avail, $cap, $mnt) = split(/ +/);
+ die("df failed") if ($n != 7);
+
+ if ($fscheck && $type ne "xfs") {
+ die("Error: $progname: filesystem is not xfs")
+ }
+
+ # how was this filesystem mounted
+ $_ = `grep $dev /etc/mtab`;
+ @mtab = split(/ +/);
+ $mnt_options = $mtab[3];
+
+ # xfs_db: read only, use the default superblock, print everything
+ die("Error: $progname: can't read device: \"$dev\"\n") if (! -r $dev);
+ $_=`xfs_db -r -c sb -c p $dev`;
+ # multiline matching ^$ refers to individual lines...
+ /^dblocks = (\d+)$/m; $fsblocks=$1;
+ /^blocksize = (\d+)$/m; $fsblocksize=$1;
+ /^agblocks = (\d+)$/m; $agblocks=$1;
+ /^agcount = (\d+)$/m; $agcount=$1;
+ /^imax_pct = (\d+)$/m; $imax_pct=$1;
+ /^logblocks = (\d+)$/m; $logblocks=$1;
+ /^logstart = (\d+)$/m; $logstart=$1;
+ $internal = $logstart > 0 ? " (internal)" : "";
+
+ $verbose && print STDERR <<"EOF"
+Filesystem information:
+ type=$type; device=$dev
+ mount point=$mnt; mount options=$mnt_options
+ percent full=$cap; size (512 byte blocks)=$blocks; used=$used; avail=$avail
+ total filesystem size (fs blocks)=$fsblocks; fs block size=$fsblocksize; imax_pct=$imax_pct
+ agcount=$agcount; agblocks=$agblocks; logblocks=$logblocks; logstart=$logstart$internal
+EOF
+}
+
+
+# returns numbers with a normal distribution
+sub normal {
+ my($mean) = $_[0];
+ my($stddev) = $_[1];
+
+ $x = -6.0;
+ for ($i = 0; $i < 12; $i++) {
+ $x += rand;
+ }
+
+ $x = $mean + $stddev * $x;
+ return $x;
+}
+
+#
+# determine script location and find fill2
+#
+
+chomp($cwd = `pwd`);
+chomp($_ = `which fill2 2>&1 | head -1`);
+if (-x $_) {
+ # look in the path
+ $fill2 = fill2;
+}
+else {
+ # in the same directory - get absolute path
+ chomp($dirname = dirname $0);
+ if ($dirname =~ m!^/.*!) {
+ $fill2 = $dirname . "/fill2";
+ }
+ else {
+ # relative
+ $fill2 = $cwd . "/" . $dirname . "/fill2";
+ }
+ if (! -x $fill2) {
+ die("Error: $progname: can't find fill2, tried \"$fill2\"\n");
+ }
+}
+
+#
+# process/check args
+#
+
+$progname=$0;
+GetOptions("bytes=f" => \$bytes,
+ "dir=s" => \$root,
+ "filesize=i" => \$filesize,
+ "force!" => \$force,
+ "help!" => \$help,
+ "list=s" => \$list,
+ "fscheck!" => \$fscheck,
+ "percent=f" => \$percentage,
+ "seed=i" => \$seed,
+ "stddev=i" => \$stddev,
+ "verbose!" => \$verbose);
+
+
+# check/remove output directory, get filesystem info
+if (defined $help
+ || (! defined $root && @ARGV != 1)
+ || (defined $root && @ARGV == 1))
+{
+ # newline at end of die message suppresses line number
+ print STDERR <<"EOF";
+Usage: $progname [options] root_dir
+Options:
+ --bytes=num total number of bytes to write
+ --dir=name where to write files
+ --filesize=num set all files to num bytes in size
+ --force overwrite any existing files
+ --help print this help message
+ --list=filename store created files to filename (- for stdout)
+ --percent=num percentage of filesystem to fill
+ --seed=num seed for random number generator
+ --stddev set file size standard deviation
+ --verbose verbose output
+EOF
+ exit(1) unless defined $help;
+ # otherwise...
+ exit(0);
+
+}
+
+
+#
+# lots of boring argument checking
+#
+
+# root directory and filesystem info
+$root = $ARGV[0] if (@ARGV == 1);
+if (-e $root) {
+ if (! $force) {
+ die("Error: $progname: \"$root\" already exists\n");
+ }
+ else {
+ $verbose && print STDERR "Removing \"$root\"... ";
+ system("rm -rf $root");
+ $verbose && print STDERR "done\n";
+ }
+}
+chomp($root_dir = dirname $root);
+fsinfo $root_dir;
+
+# $list can be "-" for stdout, perl open ">-" opens stdout
+open LIST, ">$list" if (defined $list);
+
+# how many bytes should we write
+if (defined $bytes && defined $percentage) {
+ die("Error: $progname: can't specify --bytes and --percent\n");
+}
+# check percentage
+if (defined $percentage && ($percentage < 0 || $percentage > 100)) {
+ die("Error: $progname: invalid percentage\n");
+}
+if (! defined $bytes && ! defined $percentage) {
+ $bytes = $avail * 512;
+ $verbose && print STDERR <<"EOF";
+Neither --bytes nor --percent specified: filling filesystem ($bytes bytes)
+EOF
+}
+elsif (! defined $bytes) {
+ $bytes = int($blocks * 512 * $percentage / 100.0);
+}
+if (($bytes > $blocks * 512) || (! $force && $bytes > $avail * 512))
+{
+ die("Error: $progname: not enough free disk space, disk is $cap full\n");
+}
+
+
+
+#
+# To get fix sized files set stddev to 0. The default is to make most files
+# within 30% of the requested filesize (or 4k if filesize is not specified).
+# Set the standard deviation to be half of the required percentage: ~95% of
+# samples lie within 2 standard deviations of the mean.
+#
+
+$filesize = 4096 if (! defined $filesize);
+die("Error: $progname: --filesize must be >= 1 byte") if ($filesize < 1);
+$stddev = 0.5 * 0.3 * $filesize if (! defined $stddev);
+$seed = time ^ $$ if (! defined $seed);
+srand $seed;
+umask 0000;
+mkdir $root, 0777;
+chdir $root;
+$total = 0;
+$files = 0;
+$dirs = 0;
+$d = 0;
+
+#
+# fill filesystem
+#
+
+$verbose && print STDERR "Writing $bytes bytes (seed is $seed)... ";
+while ($total < $bytes) {
+ $r = rand(3.0);
+
+ if (($d == 0 && $r < 0.5) || ($d > 0 && $r >= 0.0 && $r < 2.4)) {
+ # create a new data file
+ $n = sprintf("%04d", $names[$d]++);
+ if ($stddev == 0) {
+ $size = $filesize;
+ }
+ else {
+ $size = int(normal($filesize, $stddev));
+ }
+ $left = $bytes - $total;
+ $size = 0 if ($size < 0);
+ $size = $left if ($size > $left);
+
+ # fill2 will fail if the filesystem is full - not an error!
+ $cmd = "$fill2 -d nbytes=$size,linelength=72,seed=$n -b 4k $n";
+ $cmd .= " > /dev/null 2>&1" if (! $verbose);
+ if (system($cmd) != 0) {
+ if ($verbose) {
+ warn("can't create a file - assuming filesystem is full\n");
+ }
+ if (-e $n && unlink($n) != 1) {
+ warn("couldn't delete \"$n\"");
+ }
+ last;
+ }
+ $_ = `sum $n`;
+ ($sum) = split(/ +/);
+ $name = "$n.$sum.data";
+ $cmd = "mv $n $name"; # perl rename failed earlier than using mv
+ $cmd .= " > /dev/null 2>&1" if (! $verbose);
+ if (system($cmd) != 0) {
+ if ($verbose) {
+ warn("can't rename a file - assuming filesystem is full\n");
+ }
+ if (-e $name && unlink($name) != 1) {
+ warn("couldn't delete \"$name\"");
+ }
+ last;
+ }
+ if (defined $list) {
+ chomp($_ = `pwd`);
+ printf LIST ("%s/%s\n", $_, $name);
+ }
+ $total += $size;
+ $files++;
+ }
+ # note that if d==0 create directories more frequently than files
+ elsif (($d == 0 && $r >= 0.5) || ($d > 0 && $r >= 2.4 && $r < 2.7)) {
+ # create a new directory and descend
+ $name = sprintf("%04d.d", $names[$d]++);
+ if (! mkdir($name, 0777)) {
+ warn("can't make a directory - assuming filesystem is full\n");
+ last;
+ }
+ chdir($name) or die();
+ $d++;
+ $dirs++;
+ }
+ elsif ($r >= 2.7 && $r < 3.0) {
+ # pop up to the parent directory same probability as descend
+ die("Error: $progname: panic: shouldn't be here!") if ($d == 0);
+ chdir("..") or die();
+ $d--;
+ }
+}
+# make sure we return to the original working directory
+chdir($cwd) or die();
+$verbose && print STDERR "done\n";
+$verbose && print STDERR "$total bytes (in $files files and $dirs directories) were actually written\n";
+close LIST;
+exit(0) if ($total = $bytes);
+exit(1) if ($total == 0);
+exit(2) if ($total > 0 && $total < $bytes);
+
+# - to sum all generated data:
+# find /home/fill/ -name \*data | xargs ls -al | awk '{total = total + $5; } END { printf("total = %d bytes\n", total); }'
+# - to find any files not of the required size
+# find . -name \*data -a \! -size 4096c
+# - count new files
+# find ./fill -name \*.data | wc
+# - count new directories
+# find ./fill -name \*.d | wc
--- /dev/null
+#!/usr/bin/perl -w
+#
+
+#
+# Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like. Any license provided herein, whether implied or
+# otherwise, applies only to this software file. Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA 94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+#
+
+#
+# fill2fs_check:
+# Read a manifest generated by fill2fs from the command
+# line or stdin, checksum every file listed
+#
+# $Id$
+#
+
+use File::Basename;
+
+while (<>) {
+ chomp;
+ if ( ! -e $_) {
+ print "$0: $_ not found\n";
+ exit(1);
+ }
+ (undef, $expected) = split(/\./, basename $_);
+ chomp($sum = `sum $_`);
+ ($actual) = split(/\s+/, $sum);
+ if ($actual != $expected) {
+ print "$0: checksum is wrong for \"$_\"\n";
+ exit(1);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+/* XXX temporary hack - error injection is disabled */
+#define ERROR_INJECT_DISABLE
+#define XFS_ERRTAG_MAX 17
+
+typedef enum {
+ OP_ALLOCSP,
+ OP_ATTR_REMOVE,
+ OP_ATTR_SET,
+ OP_BULKSTAT,
+ OP_BULKSTAT1,
+ OP_CHOWN,
+ OP_CREAT,
+ OP_DREAD,
+ OP_DWRITE,
+ OP_FDATASYNC,
+ OP_FREESP,
+ OP_FSYNC,
+ OP_GETDENTS,
+ OP_LINK,
+ OP_MKDIR,
+ OP_MKNOD,
+ OP_READ,
+ OP_READLINK,
+ OP_RENAME,
+ OP_RESVSP,
+ OP_RMDIR,
+ OP_STAT,
+ OP_SYMLINK,
+ OP_SYNC,
+ OP_TRUNCATE,
+ OP_UNLINK,
+ OP_UNRESVSP,
+ OP_WRITE,
+ OP_LAST
+} opty_t;
+
+typedef void (*opfnc_t)(int, long);
+
+typedef struct opdesc {
+ opty_t op;
+ char *name;
+ opfnc_t func;
+ int freq;
+ int iswrite;
+} opdesc_t;
+
+typedef struct fent {
+ int id;
+ int parent;
+} fent_t;
+
+typedef struct flist {
+ int nfiles;
+ int nslots;
+ int tag;
+ fent_t *fents;
+} flist_t;
+
+typedef struct pathname {
+ int len;
+ char *path;
+} pathname_t;
+
+#define FT_DIR 0
+#define FT_DIRm (1 << FT_DIR)
+#define FT_REG 1
+#define FT_REGm (1 << FT_REG)
+#define FT_SYM 2
+#define FT_SYMm (1 << FT_SYM)
+#define FT_DEV 3
+#define FT_DEVm (1 << FT_DEV)
+#define FT_RTF 4
+#define FT_RTFm (1 << FT_RTF)
+#define FT_nft 5
+#define FT_ANYm ((1 << FT_nft) - 1)
+#define FT_REGFILE (FT_REGm | FT_RTFm)
+#define FT_NOTDIR (FT_ANYm & ~FT_DIRm)
+
+#define FLIST_SLOT_INCR 16
+#define NDCACHE 64
+
+#define MAXFSIZE ((1ULL << 63) - 1ULL)
+#define MAXFSIZE32 ((1ULL << 40) - 1ULL)
+
+void allocsp_f(int, long);
+void attr_remove_f(int, long);
+void attr_set_f(int, long);
+void bulkstat_f(int, long);
+void bulkstat1_f(int, long);
+void chown_f(int, long);
+void creat_f(int, long);
+void dread_f(int, long);
+void dwrite_f(int, long);
+void fdatasync_f(int, long);
+void freesp_f(int, long);
+void fsync_f(int, long);
+void getdents_f(int, long);
+void link_f(int, long);
+void mkdir_f(int, long);
+void mknod_f(int, long);
+void read_f(int, long);
+void readlink_f(int, long);
+void rename_f(int, long);
+void resvsp_f(int, long);
+void rmdir_f(int, long);
+void stat_f(int, long);
+void symlink_f(int, long);
+void sync_f(int, long);
+void truncate_f(int, long);
+void unlink_f(int, long);
+void unresvsp_f(int, long);
+void write_f(int, long);
+
+opdesc_t ops[] = {
+ { OP_ALLOCSP, "allocsp", allocsp_f, 1, 1 },
+ { OP_ATTR_REMOVE, "attr_remove", attr_remove_f, /* 1 */ 0, 1 },
+ { OP_ATTR_SET, "attr_set", attr_set_f, /* 2 */ 0, 1 },
+ { OP_BULKSTAT, "bulkstat", bulkstat_f, 1, 0 },
+ { OP_BULKSTAT1, "bulkstat1", bulkstat1_f, 1, 0 },
+ { OP_CHOWN, "chown", chown_f, 3, 1 },
+ { OP_CREAT, "creat", creat_f, 4, 1 },
+ { OP_DREAD, "dread", dread_f, /* 4 */ 0, 0 },
+ { OP_DWRITE, "dwrite", dwrite_f, /* 4 */ 0, 1 },
+ { OP_FDATASYNC, "fdatasync", fdatasync_f, 1, 1 },
+ { OP_FREESP, "freesp", freesp_f, 1, 1 },
+ { OP_FSYNC, "fsync", fsync_f, 1, 1 },
+ { OP_GETDENTS, "getdents", getdents_f, 1, 0 },
+ { OP_LINK, "link", link_f, 1, 1 },
+ { OP_MKDIR, "mkdir", mkdir_f, 2, 1 },
+ { OP_MKNOD, "mknod", mknod_f, 2, 1 },
+ { OP_READ, "read", read_f, 1, 0 },
+ { OP_READLINK, "readlink", readlink_f, 1, 0 },
+ { OP_RENAME, "rename", rename_f, 2, 1 },
+ { OP_RESVSP, "resvsp", resvsp_f, 1, 1 },
+ { OP_RMDIR, "rmdir", rmdir_f, 1, 1 },
+ { OP_STAT, "stat", stat_f, 1, 0 },
+ { OP_SYMLINK, "symlink", symlink_f, 2, 1 },
+ { OP_SYNC, "sync", sync_f, 1, 0 },
+ { OP_TRUNCATE, "truncate", truncate_f, 2, 1 },
+ { OP_UNLINK, "unlink", unlink_f, 1, 1 },
+ { OP_UNRESVSP, "unresvsp", unresvsp_f, 1, 1 },
+ { OP_WRITE, "write", write_f, 4, 1 },
+}, *ops_end;
+
+flist_t flist[FT_nft] = {
+ { 0, 0, 'd', NULL },
+ { 0, 0, 'f', NULL },
+ { 0, 0, 'l', NULL },
+ { 0, 0, 'c', NULL },
+ { 0, 0, 'r', NULL },
+};
+
+int dcache[NDCACHE];
+int errrange;
+int errtag;
+opty_t *freq_table;
+int freq_table_size;
+xfs_fsop_geom_t geom;
+char *homedir;
+int *ilist;
+int ilistlen;
+off64_t maxfsize;
+char *myprog;
+int namerand;
+int nameseq;
+int nops;
+int nproc = 1;
+int operations = 1;
+int procid;
+int rtpct;
+unsigned long seed = 0;
+ino_t top_ino;
+int verbose = 0;
+
+void add_to_flist(int, int, int);
+void append_pathname(pathname_t *, char *);
+int attr_list_path(pathname_t *, char *, const int, int,
+ attrlist_cursor_t *);
+int attr_remove_path(pathname_t *, const char *, int);
+int attr_set_path(pathname_t *, const char *, const char *, const int, int);
+void check_cwd(void);
+int creat_path(pathname_t *, mode_t);
+void dcache_enter(int, int);
+void dcache_init(void);
+fent_t *dcache_lookup(int);
+void dcache_purge(int);
+void del_from_flist(int, int);
+int dirid_to_name(char *, int);
+void doproc(void);
+void fent_to_name(pathname_t *, flist_t *, fent_t *);
+void fix_parent(int, int);
+void free_pathname(pathname_t *);
+int generate_fname(fent_t *, int, pathname_t *, int *, int *);
+int get_fname(int, long, pathname_t *, flist_t **, fent_t **, int *);
+void init_pathname(pathname_t *);
+int lchown_path(pathname_t *, uid_t, gid_t);
+int link_path(pathname_t *, pathname_t *);
+int lstat64_path(pathname_t *, struct stat64 *);
+void make_freq_table(void);
+int mkdir_path(pathname_t *, mode_t);
+int mknod_path(pathname_t *, mode_t, dev_t);
+void namerandpad(int, char *, int);
+int open_path(pathname_t *, int);
+DIR *opendir_path(pathname_t *);
+void process_freq(char *);
+int readlink_path(pathname_t *, char *, size_t);
+int rename_path(pathname_t *, pathname_t *);
+int rmdir_path(pathname_t *);
+void separate_pathname(pathname_t *, char *, pathname_t *);
+void show_ops(int, char *);
+int stat64_path(pathname_t *, struct stat64 *);
+int symlink_path(const char *, pathname_t *);
+int truncate64_path(pathname_t *, off64_t);
+int unlink_path(pathname_t *);
+void usage(void);
+void write_freq(void);
+void zero_freq(void);
+
+int main(int argc, char **argv)
+{
+ char buf[10];
+ int c;
+ char *dirname = NULL;
+ int fd;
+ int i;
+ int j;
+ char *p;
+ int stat;
+ struct timeval t;
+ ptrdiff_t srval;
+ int nousage=0;
+ xfs_error_injection_t err_inj;
+
+ errrange = errtag = 0;
+ umask(0);
+ nops = sizeof(ops) / sizeof(ops[0]);
+ ops_end = &ops[nops];
+ myprog = argv[0];
+ while ((c = getopt(argc, argv, "d:e:f:i:n:p:rs:vwzHS")) != -1) {
+ switch (c) {
+ case 'd':
+ dirname = optarg;
+ break;
+ case 'e':
+ sscanf(optarg, "%d", &errtag);
+ if (errtag < 0) {
+ errtag = -errtag;
+ errrange = 1;
+ } else if (errtag == 0)
+ errtag = -1;
+ if (errtag >= XFS_ERRTAG_MAX) {
+ fprintf(stderr,
+ "error tag %d too large (max %d)\n",
+ errtag, XFS_ERRTAG_MAX - 1);
+ exit(1);
+ }
+ break;
+ case 'f':
+ process_freq(optarg);
+ break;
+ case 'i':
+ ilist = realloc(ilist, ++ilistlen * sizeof(*ilist));
+ ilist[ilistlen - 1] = strtol(optarg, &p, 16);
+ break;
+ case 'n':
+ operations = atoi(optarg);
+ break;
+ case 'p':
+ nproc = atoi(optarg);
+ break;
+ case 'r':
+ namerand = 1;
+ break;
+ case 's':
+ seed = strtoul(optarg, NULL, 0);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'w':
+ write_freq();
+ break;
+ case 'z':
+ zero_freq();
+ break;
+ case 'S':
+ show_ops(0, NULL);
+ printf("\n");
+ nousage=1;
+ break;
+ case '?':
+ fprintf(stderr, "%s - invalid parameters\n",
+ myprog);
+ /* fall through */
+ case 'H':
+ usage();
+ exit(1);
+ }
+ }
+
+ if (!dirname) {
+ /* no directory specified */
+ if (!nousage) usage();
+ exit(1);
+ }
+
+ (void)mkdir(dirname, 0777);
+ if (chdir(dirname) < 0) {
+ perror(dirname);
+ exit(1);
+ }
+ sprintf(buf, "fss%x", getpid());
+ fd = creat(buf, 0666);
+ if (lseek64(fd, (off64_t)(MAXFSIZE32 + 1ULL), SEEK_SET) < 0)
+ maxfsize = (off64_t)MAXFSIZE32;
+ else
+ maxfsize = (off64_t)MAXFSIZE;
+ make_freq_table();
+ dcache_init();
+ setlinebuf(stdout);
+ if (!seed) {
+ gettimeofday(&t, (void *)NULL);
+ seed = (int)t.tv_sec ^ (int)t.tv_usec;
+ printf("seed = %ld\n", seed);
+ }
+ i = ioctl(fd, XFS_IOC_FSGEOMETRY, &geom);
+ if (i >= 0 && geom.rtblocks)
+ rtpct = MIN(MAX(geom.rtblocks * 100 /
+ (geom.rtblocks + geom.datablocks), 1), 99);
+ else
+ rtpct = 0;
+ if (errtag != 0) {
+ if (errrange == 0) {
+ if (errtag <= 0) {
+ srandom(seed);
+ j = random() % 100;
+
+ for (i = 0; i < j; i++)
+ (void) random();
+
+ errtag = (random() % (XFS_ERRTAG_MAX-1)) + 1;
+ }
+ } else {
+ srandom(seed);
+ j = random() % 100;
+
+ for (i = 0; i < j; i++)
+ (void) random();
+
+ errtag += (random() % (XFS_ERRTAG_MAX - errtag));
+ }
+ printf("Injecting failure on tag #%d\n", errtag);
+#ifndef ERROR_INJECT_DISABLE
+ err_inj.errtag = errtag;
+ err_inj.fd = fd;
+ srval = ioctl(fd, XFS_IOC_ERROR_INJECTION, &err_inj);
+#else
+ srval = -1;
+#endif
+ if (srval < -1) {
+ perror("fsstress - XFS_SYSSGI error injection call");
+ close(fd);
+ unlink(buf);
+ exit(1);
+ }
+ } else
+ close(fd);
+ unlink(buf);
+ for (i = 0; i < nproc; i++) {
+ if (fork() == 0) {
+ procid = i;
+ doproc();
+ return 0;
+ }
+ }
+ while (wait(&stat) > 0)
+ continue;
+ if (errtag != 0) {
+#ifndef ERROR_INJECT_DISABLE
+ err_inj.errtag = 0;
+ err_inj.fd = fd;
+ if((srval = ioctl(fd, XFS_IOC_ERROR_CLEARALL, &err_inj)) != 0) {
+#else
+ if (1) {
+#endif
+ perror("fsstress - XFS_SYSSGI clear error injection call");
+ close(fd);
+ exit(1);
+ }
+ close(fd);
+ }
+
+ return 0;
+}
+
+void
+add_to_flist(int ft, int id, int parent)
+{
+ fent_t *fep;
+ flist_t *ftp;
+
+ ftp = &flist[ft];
+ if (ftp->nfiles == ftp->nslots) {
+ ftp->nslots += FLIST_SLOT_INCR;
+ ftp->fents = realloc(ftp->fents, ftp->nslots * sizeof(fent_t));
+ }
+ fep = &ftp->fents[ftp->nfiles++];
+ fep->id = id;
+ fep->parent = parent;
+}
+
+void
+append_pathname(pathname_t *name, char *str)
+{
+ int len;
+
+ len = strlen(str);
+#ifdef DEBUG
+ if (len && *str == '/' && name->len == 0) {
+ fprintf(stderr, "fsstress: append_pathname failure\n");
+ chdir(homedir);
+ abort();
+ /* NOTREACHED */
+ }
+#endif
+ name->path = realloc(name->path, name->len + 1 + len);
+ strcpy(&name->path[name->len], str);
+ name->len += len;
+}
+
+int
+attr_list_path(pathname_t *name, char *buffer, const int buffersize, int flags,
+ attrlist_cursor_t *cursor)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = attr_list(name->path, buffer, buffersize, flags, cursor);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = attr_list_path(&newname, buffer, buffersize, flags,
+ cursor);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+attr_remove_path(pathname_t *name, const char *attrname, int flags)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = attr_remove(name->path, attrname, flags);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = attr_remove_path(&newname, attrname, flags);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+attr_set_path(pathname_t *name, const char *attrname, const char *attrvalue,
+ const int valuelength, int flags)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = attr_set(name->path, attrname, attrvalue, valuelength, flags);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = attr_set_path(&newname, attrname, attrvalue, valuelength,
+ flags);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+check_cwd(void)
+{
+#ifdef DEBUG
+ struct stat64 statbuf;
+
+ if (stat64(".", &statbuf) == 0 && statbuf.st_ino == top_ino)
+ return;
+ chdir(homedir);
+ fprintf(stderr, "fsstress: check_cwd failure\n");
+ abort();
+ /* NOTREACHED */
+#endif
+}
+
+int
+creat_path(pathname_t *name, mode_t mode)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = creat(name->path, mode);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = creat_path(&newname, mode);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+dcache_enter(int dirid, int slot)
+{
+ dcache[dirid % NDCACHE] = slot;
+}
+
+void
+dcache_init(void)
+{
+ int i;
+
+ for (i = 0; i < NDCACHE; i++)
+ dcache[i] = -1;
+}
+
+fent_t *
+dcache_lookup(int dirid)
+{
+ fent_t *fep;
+ int i;
+
+ i = dcache[dirid % NDCACHE];
+ if (i >= 0 && (fep = &flist[FT_DIR].fents[i])->id == dirid)
+ return fep;
+ return NULL;
+}
+
+void
+dcache_purge(int dirid)
+{
+ int *dcp;
+
+ dcp = &dcache[dirid % NDCACHE];
+ if (*dcp >= 0 && flist[FT_DIR].fents[*dcp].id == dirid)
+ *dcp = -1;
+}
+
+void
+del_from_flist(int ft, int slot)
+{
+ flist_t *ftp;
+
+ ftp = &flist[ft];
+ if (ft == FT_DIR)
+ dcache_purge(ftp->fents[slot].id);
+ if (slot != ftp->nfiles - 1) {
+ if (ft == FT_DIR)
+ dcache_purge(ftp->fents[ftp->nfiles - 1].id);
+ ftp->fents[slot] = ftp->fents[--ftp->nfiles];
+ } else
+ ftp->nfiles--;
+}
+
+fent_t *
+dirid_to_fent(int dirid)
+{
+ fent_t *efep;
+ fent_t *fep;
+ flist_t *flp;
+
+ if ((fep = dcache_lookup(dirid)))
+ return fep;
+ flp = &flist[FT_DIR];
+ for (fep = flp->fents, efep = &fep[flp->nfiles]; fep < efep; fep++) {
+ if (fep->id == dirid) {
+ dcache_enter(dirid, fep - flp->fents);
+ return fep;
+ }
+ }
+ return NULL;
+}
+
+void
+doproc(void)
+{
+ struct stat64 statbuf;
+ char buf[10];
+ int opno;
+ int rval;
+ opdesc_t *p;
+
+ sprintf(buf, "p%x", procid);
+ (void)mkdir(buf, 0777);
+ if (chdir(buf) < 0 || stat64(".", &statbuf) < 0) {
+ perror(buf);
+ _exit(1);
+ }
+ top_ino = statbuf.st_ino;
+ homedir = getcwd(NULL, -1);
+ seed += procid;
+ srandom(seed);
+ if (namerand)
+ namerand = random();
+ for (opno = 0; opno < operations; opno++) {
+ p = &ops[freq_table[random() % freq_table_size]];
+ p->func(opno, random());
+ /*
+ * test for forced shutdown by stat'ing the test
+ * directory. If this stat returns EIO, assume
+ * the forced shutdown happened.
+ */
+ if (errtag != 0 && opno % 100 == 0) {
+ rval = stat64(".", &statbuf);
+ if (rval == EIO) {
+ fprintf(stderr, "Detected EIO\n");
+ return;
+ }
+ }
+ }
+}
+
+void
+fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep)
+{
+ char buf[MAXNAMELEN];
+ int i;
+ fent_t *pfep;
+
+ if (fep == NULL)
+ return;
+ if (fep->parent != -1) {
+ pfep = dirid_to_fent(fep->parent);
+ fent_to_name(name, &flist[FT_DIR], pfep);
+ append_pathname(name, "/");
+ }
+ i = sprintf(buf, "%c%x", flp->tag, fep->id);
+ namerandpad(fep->id, buf, i);
+ append_pathname(name, buf);
+}
+
+void
+fix_parent(int oldid, int newid)
+{
+ fent_t *fep;
+ flist_t *flp;
+ int i;
+ int j;
+
+ for (i = 0, flp = flist; i < FT_nft; i++, flp++) {
+ for (j = 0, fep = flp->fents; j < flp->nfiles; j++, fep++) {
+ if (fep->parent == oldid)
+ fep->parent = newid;
+ }
+ }
+}
+
+void
+free_pathname(pathname_t *name)
+{
+ if (name->path) {
+ free(name->path);
+ name->path = NULL;
+ name->len = 0;
+ }
+}
+
+int
+generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v)
+{
+ char buf[MAXNAMELEN];
+ flist_t *flp;
+ int id;
+ int j;
+ int len;
+
+ flp = &flist[ft];
+ len = sprintf(buf, "%c%x", flp->tag, id = nameseq++);
+ namerandpad(id, buf, len);
+ if (fep) {
+ fent_to_name(name, &flist[FT_DIR], fep);
+ append_pathname(name, "/");
+ }
+ append_pathname(name, buf);
+ *idp = id;
+ *v = verbose;
+ for (j = 0; !*v && j < ilistlen; j++) {
+ if (ilist[j] == id) {
+ *v = 1;
+ break;
+ }
+ }
+ return 1;
+}
+
+int
+get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp,
+ int *v)
+{
+ int c;
+ fent_t *fep;
+ flist_t *flp;
+ int i;
+ int j;
+ int x;
+
+ for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) {
+ if (which & (1 << i))
+ c += flp->nfiles;
+ }
+ if (c == 0) {
+ if (flpp)
+ *flpp = NULL;
+ if (fepp)
+ *fepp = NULL;
+ *v = verbose;
+ return 0;
+ }
+ x = (int)(r % c);
+ for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) {
+ if (which & (1 << i)) {
+ if (x < c + flp->nfiles) {
+ fep = &flp->fents[x - c];
+ if (name)
+ fent_to_name(name, flp, fep);
+ if (flpp)
+ *flpp = flp;
+ if (fepp)
+ *fepp = fep;
+ *v = verbose;
+ for (j = 0; !*v && j < ilistlen; j++) {
+ if (ilist[j] == fep->id) {
+ *v = 1;
+ break;
+ }
+ }
+ return 1;
+ }
+ c += flp->nfiles;
+ }
+ }
+#ifdef DEBUG
+ fprintf(stderr, "fsstress: get_fname failure\n");
+ abort();
+#endif
+ return -1;
+ /* NOTREACHED */
+}
+
+void
+init_pathname(pathname_t *name)
+{
+ name->len = 0;
+ name->path = NULL;
+}
+
+int
+lchown_path(pathname_t *name, uid_t owner, gid_t group)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = lchown(name->path, owner, group);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = lchown_path(&newname, owner, group);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+link_path(pathname_t *name1, pathname_t *name2)
+{
+ char buf1[MAXNAMELEN];
+ char buf2[MAXNAMELEN];
+ int down1;
+ pathname_t newname1;
+ pathname_t newname2;
+ int rval;
+
+ rval = link(name1->path, name2->path);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name1, buf1, &newname1);
+ separate_pathname(name2, buf2, &newname2);
+ if (strcmp(buf1, buf2) == 0) {
+ if (chdir(buf1) == 0) {
+ rval = link_path(&newname1, &newname2);
+ chdir("..");
+ }
+ } else {
+ if (strcmp(buf1, "..") == 0)
+ down1 = 0;
+ else if (strcmp(buf2, "..") == 0)
+ down1 = 1;
+ else if (strlen(buf1) == 0)
+ down1 = 0;
+ else if (strlen(buf2) == 0)
+ down1 = 1;
+ else
+ down1 = MAX(newname1.len, 3 + name2->len) <=
+ MAX(3 + name1->len, newname2.len);
+ if (down1) {
+ free_pathname(&newname2);
+ append_pathname(&newname2, "../");
+ append_pathname(&newname2, name2->path);
+ if (chdir(buf1) == 0) {
+ rval = link_path(&newname1, &newname2);
+ chdir("..");
+ }
+ } else {
+ free_pathname(&newname1);
+ append_pathname(&newname1, "../");
+ append_pathname(&newname1, name1->path);
+ if (chdir(buf2) == 0) {
+ rval = link_path(&newname1, &newname2);
+ chdir("..");
+ }
+ }
+ }
+ free_pathname(&newname1);
+ free_pathname(&newname2);
+ return rval;
+}
+
+int
+lstat64_path(pathname_t *name, struct stat64 *sbuf)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = lstat64(name->path, sbuf);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = lstat64_path(&newname, sbuf);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+make_freq_table(void)
+{
+ int f;
+ int i;
+ opdesc_t *p;
+
+ for (p = ops, f = 0; p < ops_end; p++)
+ f += p->freq;
+ freq_table = malloc(f * sizeof(*freq_table));
+ freq_table_size = f;
+ for (p = ops, i = 0; p < ops_end; p++) {
+ for (f = 0; f < p->freq; f++, i++)
+ freq_table[i] = p->op;
+ }
+}
+
+int
+mkdir_path(pathname_t *name, mode_t mode)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = mkdir(name->path, mode);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = mkdir_path(&newname, mode);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+mknod_path(pathname_t *name, mode_t mode, dev_t dev)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = mknod(name->path, mode, dev);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = mknod_path(&newname, mode, dev);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+namerandpad(int id, char *buf, int i)
+{
+ int bucket;
+ static int buckets[] =
+ { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN - 1 };
+ int padlen;
+ int padmod;
+
+ if (namerand == 0)
+ return;
+ bucket = (id ^ namerand) % (sizeof(buckets) / sizeof(buckets[0]));
+ padmod = buckets[bucket] + 1 - i;
+ if (padmod <= 0)
+ return;
+ padlen = (id ^ namerand) % padmod;
+ if (padlen) {
+ memset(&buf[i], 'X', padlen);
+ buf[i + padlen] = '\0';
+ }
+}
+
+int
+open_path(pathname_t *name, int oflag)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = open(name->path, oflag);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = open_path(&newname, oflag);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+DIR *
+opendir_path(pathname_t *name)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ DIR *rval;
+
+ rval = opendir(name->path);
+ if (rval || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = opendir_path(&newname);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+process_freq(char *arg)
+{
+ opdesc_t *p;
+ char *s;
+
+ s = strchr(arg, '=');
+ if (s == NULL) {
+ fprintf(stderr, "bad argument '%s'\n", arg);
+ exit(1);
+ }
+ *s++ = '\0';
+ for (p = ops; p < ops_end; p++) {
+ if (strcmp(arg, p->name) == 0) {
+ p->freq = atoi(s);
+ return;
+ }
+ }
+ fprintf(stderr, "can't find op type %s for -f\n", arg);
+ exit(1);
+}
+
+int
+readlink_path(pathname_t *name, char *lbuf, size_t lbufsiz)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = readlink(name->path, lbuf, lbufsiz);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = readlink_path(&newname, lbuf, lbufsiz);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+rename_path(pathname_t *name1, pathname_t *name2)
+{
+ char buf1[MAXNAMELEN];
+ char buf2[MAXNAMELEN];
+ int down1;
+ pathname_t newname1;
+ pathname_t newname2;
+ int rval;
+
+ rval = rename(name1->path, name2->path);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name1, buf1, &newname1);
+ separate_pathname(name2, buf2, &newname2);
+ if (strcmp(buf1, buf2) == 0) {
+ if (chdir(buf1) == 0) {
+ rval = rename_path(&newname1, &newname2);
+ chdir("..");
+ }
+ } else {
+ if (strcmp(buf1, "..") == 0)
+ down1 = 0;
+ else if (strcmp(buf2, "..") == 0)
+ down1 = 1;
+ else if (strlen(buf1) == 0)
+ down1 = 0;
+ else if (strlen(buf2) == 0)
+ down1 = 1;
+ else
+ down1 = MAX(newname1.len, 3 + name2->len) <=
+ MAX(3 + name1->len, newname2.len);
+ if (down1) {
+ free_pathname(&newname2);
+ append_pathname(&newname2, "../");
+ append_pathname(&newname2, name2->path);
+ if (chdir(buf1) == 0) {
+ rval = rename_path(&newname1, &newname2);
+ chdir("..");
+ }
+ } else {
+ free_pathname(&newname1);
+ append_pathname(&newname1, "../");
+ append_pathname(&newname1, name1->path);
+ if (chdir(buf2) == 0) {
+ rval = rename_path(&newname1, &newname2);
+ chdir("..");
+ }
+ }
+ }
+ free_pathname(&newname1);
+ free_pathname(&newname2);
+ return rval;
+}
+
+int
+rmdir_path(pathname_t *name)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = rmdir(name->path);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = rmdir_path(&newname);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+separate_pathname(pathname_t *name, char *buf, pathname_t *newname)
+{
+ char *slash;
+
+ init_pathname(newname);
+ slash = strchr(name->path, '/');
+ if (slash == NULL) {
+ buf[0] = '\0';
+ return;
+ }
+ *slash = '\0';
+ strcpy(buf, name->path);
+ *slash = '/';
+ append_pathname(newname, slash + 1);
+}
+
+#define WIDTH 80
+
+void
+show_ops(int flag, char *lead_str)
+{
+ opdesc_t *p;
+
+ if (flag<0) {
+ /* print in list form */
+ int x = WIDTH;
+
+ for (p = ops; p < ops_end; p++) {
+ if (lead_str != NULL && x+strlen(p->name)>=WIDTH-5)
+ x=printf("%s%s", (p==ops)?"":"\n", lead_str);
+ x+=printf("%s ", p->name);
+ }
+ printf("\n");
+ } else {
+ int f;
+ for (f = 0, p = ops; p < ops_end; p++)
+ f += p->freq;
+
+ if (f == 0)
+ flag = 1;
+
+ for (p = ops; p < ops_end; p++) {
+ if (flag != 0 || p->freq > 0) {
+ if (lead_str != NULL)
+ printf("%s", lead_str);
+ printf("%20s %d/%d %s\n",
+ p->name, p->freq, f,
+ (p->iswrite == 0) ? " " : "write op");
+ }
+ }
+ }
+}
+
+int
+stat64_path(pathname_t *name, struct stat64 *sbuf)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = stat64(name->path, sbuf);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = stat64_path(&newname, sbuf);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+symlink_path(const char *name1, pathname_t *name)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ if (!strcmp(name1, name->path)) {
+ printf("yikes! %s %s\n", name1, name->path);
+ return 0;
+ }
+
+ rval = symlink(name1, name->path);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = symlink_path(name1, &newname);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+truncate64_path(pathname_t *name, off64_t length)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = truncate64(name->path, length);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = truncate64_path(&newname, length);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+int
+unlink_path(pathname_t *name)
+{
+ char buf[MAXNAMELEN];
+ pathname_t newname;
+ int rval;
+
+ rval = unlink(name->path);
+ if (rval >= 0 || errno != ENAMETOOLONG)
+ return rval;
+ separate_pathname(name, buf, &newname);
+ if (chdir(buf) == 0) {
+ rval = unlink_path(&newname);
+ chdir("..");
+ }
+ free_pathname(&newname);
+ return rval;
+}
+
+void
+usage(void)
+{
+ printf("Usage: %s -H or\n", myprog);
+ printf(" %s [-d dir][-e errtg][-f op_name=freq][-n nops]\n",
+ myprog);
+ printf(" [-p nproc][-r len][-s seed][-v][-w][-z][-S]\n");
+ printf("where\n");
+ printf(" -d dir specifies the base directory for operations\n");
+ printf(" -e errtg specifies error injection stuff\n");
+ printf(" -f op_name=freq changes the frequency of option name to freq\n");
+ printf(" the valid operation names are:\n");
+ show_ops(-1, " ");
+ printf(" -n nops specifies the no. of operations per process (default 1)\n");
+ printf(" -p nproc specifies the no. of processes (default 1)\n");
+ printf(" -r specifies random name padding\n");
+ printf(" -s seed specifies the seed for the random generator (default random)\n");
+ printf(" -v specifies verbose mode\n");
+ printf(" -w zeros frequencies of non-write operations\n");
+ printf(" -z zeros frequencies of all operations\n");
+ printf(" -S prints the table of operations (omitting zero frequency)\n");
+ printf(" -H prints usage and exits\n");
+}
+
+void
+write_freq(void)
+{
+ opdesc_t *p;
+
+ for (p = ops; p < ops_end; p++) {
+ if (!p->iswrite)
+ p->freq = 0;
+ }
+}
+
+void
+zero_freq(void)
+{
+ opdesc_t *p;
+
+ for (p = ops; p < ops_end; p++)
+ p->freq = 0;
+}
+
+void
+allocsp_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ struct flock64 fl;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: allocsp - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDWR);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: allocsp - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: allocsp - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = off;
+ fl.l_len = 0;
+ e = ioctl(fd, XFS_IOC_ALLOCSP64, &fl) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: ioctl(XFS_IOC_ALLOCSP64) %s %lld 0 %d\n",
+ procid, opno, f.path, off, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+attr_remove_f(int opno, long r)
+{
+ attrlist_ent_t *aep;
+ attrlist_t *alist;
+ char *aname;
+ char buf[4096];
+ attrlist_cursor_t cursor;
+ int e;
+ int ent;
+ pathname_t f;
+ int total;
+ int v;
+ int which;
+
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v))
+ append_pathname(&f, ".");
+ total = 0;
+ bzero(&cursor, sizeof(cursor));
+ do {
+ e = attr_list_path(&f, buf, sizeof(buf), ATTR_DONTFOLLOW,
+ &cursor);
+ check_cwd();
+ if (e)
+ break;
+ alist = (attrlist_t *)buf;
+ total += alist->al_count;
+ } while (alist->al_more);
+ if (total == 0) {
+ if (v)
+ printf("%d/%d: attr_remove - no attrs for %s\n",
+ procid, opno, f.path);
+ free_pathname(&f);
+ return;
+ }
+ which = (int)(random() % total);
+ bzero(&cursor, sizeof(cursor));
+ ent = 0;
+ aname = NULL;
+ do {
+ e = attr_list_path(&f, buf, sizeof(buf), ATTR_DONTFOLLOW,
+ &cursor);
+ check_cwd();
+ if (e)
+ break;
+ alist = (attrlist_t *)buf;
+ if (which < ent + alist->al_count) {
+ aep = (attrlist_ent_t *)
+ &buf[alist->al_offset[which - ent]];
+ aname = aep->a_name;
+ break;
+ }
+ ent += alist->al_count;
+ } while (alist->al_more);
+ if (aname == NULL) {
+ if (v)
+ printf(
+ "%d/%d: attr_remove - name %d not found at %s\n",
+ procid, opno, which, f.path);
+ free_pathname(&f);
+ return;
+ }
+ e = attr_remove_path(&f, aname, ATTR_DONTFOLLOW) < 0 ? errno : 0;
+ check_cwd();
+ if (v)
+ printf("%d/%d: attr_remove %s %s %d\n",
+ procid, opno, f.path, aname, e);
+ free_pathname(&f);
+}
+
+void
+attr_set_f(int opno, long r)
+{
+ char aname[10];
+ char *aval;
+ int e;
+ pathname_t f;
+ int len;
+ static int lengths[] = { 10, 100, 1000, 10000 };
+ int li;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v))
+ append_pathname(&f, ".");
+ sprintf(aname, "a%x", nameseq++);
+ li = (int)(random() % (sizeof(lengths) / sizeof(lengths[0])));
+ len = (int)(random() % lengths[li]);
+ if (len == 0)
+ len = 1;
+ aval = malloc(len);
+ memset(aval, nameseq & 0xff, len);
+ e = attr_set_path(&f, aname, aval, len, ATTR_DONTFOLLOW) < 0 ?
+ errno : 0;
+ check_cwd();
+ free(aval);
+ if (v)
+ printf("%d/%d: attr_set %s %s %d\n", procid, opno, f.path,
+ aname, e);
+ free_pathname(&f);
+}
+
+void
+bulkstat_f(int opno, long r)
+{
+ int count;
+ int fd;
+ __uint64_t last;
+ int nent;
+ xfs_bstat_t *t;
+ __int64_t total;
+ xfs_fsop_bulkreq_t bsr;
+
+ last = 0;
+ nent = (r % 999) + 2;
+ t = malloc(nent * sizeof(*t));
+ fd = open(".", O_RDONLY);
+ total = 0;
+
+ bsr.lastip=&last;
+ bsr.icount=nent;
+ bsr.ubuffer=t;
+ bsr.ocount=&count;
+
+ while (ioctl(fd, XFS_IOC_FSBULKSTAT, &bsr) == 0 && count > 0)
+ total += count;
+ free(t);
+ if (verbose)
+ printf("%d/%d: bulkstat nent %d total %lld\n",
+ procid, opno, nent, total);
+ close(fd);
+}
+
+void
+bulkstat1_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ int good;
+ __uint64_t ino;
+ struct stat64 s;
+ xfs_bstat_t t;
+ int v;
+ xfs_fsop_bulkreq_t bsr;
+
+
+ good = random() & 1;
+ if (good) {
+ /* use an inode we know exists */
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v))
+ append_pathname(&f, ".");
+ ino = stat64_path(&f, &s) < 0 ? (ino64_t)r : s.st_ino;
+ check_cwd();
+ free_pathname(&f);
+ } else {
+ /*
+ * pick a random inode
+ *
+ * note this can generate kernel warning messages
+ * since bulkstat_one will read the disk block that
+ * would contain a given inode even if that disk
+ * block doesn't contain inodes.
+ *
+ * this is detected later, but not until after the
+ * warning is displayed.
+ *
+ * "XFS: device 0x825- bad inode magic/vsn daddr 0x0 #0"
+ *
+ */
+ ino = (ino64_t)r;
+ v = verbose;
+ }
+ fd = open(".", O_RDONLY);
+
+ bsr.lastip=&ino;
+ bsr.icount=1;
+ bsr.ubuffer=&t;
+ bsr.ocount=NULL;
+
+ e = ioctl(fd, XFS_IOC_FSBULKSTAT_SINGLE, &bsr) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: bulkstat1 %s ino %lld %d\n",
+ procid, opno, good?"real":"random", (int64_t)ino, e);
+ close(fd);
+}
+
+void
+chown_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int nbits;
+ uid_t u;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v))
+ append_pathname(&f, ".");
+ u = (uid_t)random();
+ nbits = (int)(random() % 32);
+ u &= (1 << nbits) - 1;
+ e = lchown_path(&f, u, -1) < 0 ? errno : 0;
+ check_cwd();
+ if (v)
+ printf("%d/%d: chown %s %d %d\n", procid, opno, f.path, u, e);
+ free_pathname(&f);
+}
+
+void
+creat_f(int opno, long r)
+{
+ struct fsxattr a;
+ int e;
+ int e1;
+ int extsize;
+ pathname_t f;
+ int fd;
+ fent_t *fep;
+ int id;
+ int parid;
+ int type;
+ int v;
+ int v1;
+
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v1))
+ parid = -1;
+ else
+ parid = fep->id;
+ init_pathname(&f);
+ type = rtpct ? ((random() % 100) > rtpct ? FT_REG : FT_RTF) : FT_REG;
+ if (type == FT_RTF)
+ extsize = (random() % 10) + 1;
+ else
+ extsize = 0;
+ e = generate_fname(fep, type, &f, &id, &v);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&f, &flist[FT_DIR], fep);
+ printf("%d/%d: creat - no filename from %s\n",
+ procid, opno, f.path);
+ }
+ free_pathname(&f);
+ return;
+ }
+ fd = creat_path(&f, 0666);
+ e = fd < 0 ? errno : 0;
+ e1 = 0;
+ check_cwd();
+ if (fd >= 0) {
+ if (extsize && ioctl(fd, XFS_IOC_FSGETXATTR, &a) >= 0) {
+ a.fsx_xflags |= XFS_XFLAG_REALTIME;
+ a.fsx_extsize =
+ geom.rtextsize * geom.blocksize * extsize;
+ if (ioctl(fd, XFS_IOC_FSSETXATTR, &a) < 0)
+ e1 = errno;
+ }
+ add_to_flist(type, id, parid);
+ close(fd);
+ }
+ if (v)
+ printf("%d/%d: creat %s x:%d %d %d\n", procid, opno, f.path,
+ extsize ? a.fsx_extsize : 0, e, e1);
+ free_pathname(&f);
+}
+
+void
+dread_f(int opno, long r)
+{
+ __int64_t align;
+ char *buf;
+ struct dioattr diob;
+ int e;
+ pathname_t f;
+ int fd;
+ size_t len;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: dread - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDONLY|O_DIRECT);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: dread - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: dread - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ if (stb.st_size == 0) {
+ if (v)
+ printf("%d/%d: dread - %s zero size\n", procid, opno,
+ f.path);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ if (ioctl(fd, XFS_IOC_DIOINFO, &diob) < 0) {
+ if (v)
+ printf(
+ "%d/%d: dread - ioctl(fd, XFS_IOC_DIOINFO) %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ align = (__int64_t)diob.d_miniosz;
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % stb.st_size);
+ off -= (off % align);
+ lseek64(fd, off, SEEK_SET);
+ len = (random() % (getpagesize() * 32)) + 1;
+ len -= (len % align);
+ if (len <= 0)
+ len = align;
+ else if (len > diob.d_maxiosz)
+ len = diob.d_maxiosz;
+ buf = memalign(diob.d_mem, len);
+ e = read(fd, buf, len) < 0 ? errno : 0;
+ free(buf);
+ if (v)
+ printf("%d/%d: dread %s [%lld,%d] %d\n",
+ procid, opno, f.path, off, len, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+dwrite_f(int opno, long r)
+{
+ __int64_t align;
+ char *buf;
+ struct dioattr diob;
+ int e;
+ pathname_t f;
+ int fd;
+ size_t len;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: dwrite - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_WRONLY|O_DIRECT);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: dwrite - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: dwrite - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ if (ioctl(fd, XFS_IOC_DIOINFO, &diob) < 0) {
+ if (v)
+ printf(
+ "%d/%d: dwrite - ioctl(fd, XFS_IOC_DIOINFO) %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ align = (__int64_t)diob.d_miniosz;
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off -= (off % align);
+ lseek64(fd, off, SEEK_SET);
+ len = (random() % (getpagesize() * 32)) + 1;
+ len -= (len % align);
+ if (len <= 0)
+ len = align;
+ else if (len > diob.d_maxiosz)
+ len = diob.d_maxiosz;
+ buf = memalign(diob.d_mem, len);
+ off %= maxfsize;
+ lseek64(fd, off, SEEK_SET);
+ memset(buf, nameseq & 0xff, len);
+ e = write(fd, buf, len) < 0 ? errno : 0;
+ free(buf);
+ if (v)
+ printf("%d/%d: dwrite %s [%lld,%d] %d\n",
+ procid, opno, f.path, off, len, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+fdatasync_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: fdatasync - no filename\n",
+ procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_WRONLY);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: fdatasync - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ e = fdatasync(fd) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: fdatasync %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+freesp_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ struct flock64 fl;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: freesp - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDWR);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: freesp - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: freesp - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = off;
+ fl.l_len = 0;
+ e = ioctl(fd, XFS_IOC_FREESP64, &fl) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: ioctl(XFS_IOC_FREESP64) %s %lld 0 %d\n",
+ procid, opno, f.path, off, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+fsync_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: fsync - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_WRONLY);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: fsync - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ e = fsync(fd) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: fsync %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+getdents_f(int opno, long r)
+{
+ DIR *dir;
+ pathname_t f;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_DIRm, r, &f, NULL, NULL, &v))
+ append_pathname(&f, ".");
+ dir = opendir_path(&f);
+ check_cwd();
+ if (dir == NULL) {
+ if (v)
+ printf("%d/%d: getdents - can't open %s\n",
+ procid, opno, f.path);
+ free_pathname(&f);
+ return;
+ }
+ while (readdir64(dir) != NULL)
+ continue;
+ if (v)
+ printf("%d/%d: getdents %s 0\n", procid, opno, f.path);
+ free_pathname(&f);
+ closedir(dir);
+}
+
+void
+link_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ flist_t *flp;
+ int id;
+ pathname_t l;
+ int parid;
+ int v;
+ int v1;
+
+ init_pathname(&f);
+ if (!get_fname(FT_NOTDIR, r, &f, &flp, NULL, &v1)) {
+ if (v1)
+ printf("%d/%d: link - no file\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ if (!get_fname(FT_DIRm, random(), NULL, NULL, &fep, &v))
+ parid = -1;
+ else
+ parid = fep->id;
+ v |= v1;
+ init_pathname(&l);
+ e = generate_fname(fep, flp - flist, &l, &id, &v1);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&l, &flist[FT_DIR], fep);
+ printf("%d/%d: link - no filename from %s\n",
+ procid, opno, l.path);
+ }
+ free_pathname(&l);
+ free_pathname(&f);
+ return;
+ }
+ e = link_path(&f, &l) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ add_to_flist(flp - flist, id, parid);
+ if (v)
+ printf("%d/%d: link %s %s %d\n", procid, opno, f.path, l.path,
+ e);
+ free_pathname(&l);
+ free_pathname(&f);
+}
+
+void
+mkdir_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ int id;
+ int parid;
+ int v;
+ int v1;
+
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v))
+ parid = -1;
+ else
+ parid = fep->id;
+ init_pathname(&f);
+ e = generate_fname(fep, FT_DIR, &f, &id, &v1);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&f, &flist[FT_DIR], fep);
+ printf("%d/%d: mkdir - no filename from %s\n",
+ procid, opno, f.path);
+ }
+ free_pathname(&f);
+ return;
+ }
+ e = mkdir_path(&f, 0777) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ add_to_flist(FT_DIR, id, parid);
+ if (v)
+ printf("%d/%d: mkdir %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+mknod_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ int id;
+ int parid;
+ int v;
+ int v1;
+
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v))
+ parid = -1;
+ else
+ parid = fep->id;
+ init_pathname(&f);
+ e = generate_fname(fep, FT_DEV, &f, &id, &v1);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&f, &flist[FT_DIR], fep);
+ printf("%d/%d: mknod - no filename from %s\n",
+ procid, opno, f.path);
+ }
+ free_pathname(&f);
+ return;
+ }
+ e = mknod_path(&f, S_IFCHR|0444, 0) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ add_to_flist(FT_DEV, id, parid);
+ if (v)
+ printf("%d/%d: mknod %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+read_f(int opno, long r)
+{
+ char *buf;
+ int e;
+ pathname_t f;
+ int fd;
+ size_t len;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: read - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDONLY);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: read - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: read - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ if (stb.st_size == 0) {
+ if (v)
+ printf("%d/%d: read - %s zero size\n", procid, opno,
+ f.path);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % stb.st_size);
+ lseek64(fd, off, SEEK_SET);
+ len = (random() % (getpagesize() * 32)) + 1;
+ buf = malloc(len);
+ e = read(fd, buf, len) < 0 ? errno : 0;
+ free(buf);
+ if (v)
+ printf("%d/%d: read %s [%lld,%d] %d\n",
+ procid, opno, f.path, off, len, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+readlink_f(int opno, long r)
+{
+ char buf[PATH_MAX];
+ int e;
+ pathname_t f;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_SYMm, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: readlink - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ e = readlink_path(&f, buf, PATH_MAX) < 0 ? errno : 0;
+ check_cwd();
+ if (v)
+ printf("%d/%d: readlink %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+rename_f(int opno, long r)
+{
+ fent_t *dfep;
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ flist_t *flp;
+ int id;
+ pathname_t newf;
+ int oldid;
+ int parid;
+ int v;
+ int v1;
+
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, &flp, &fep, &v1)) {
+ if (v1)
+ printf("%d/%d: rename - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ if (!get_fname(FT_DIRm, random(), NULL, NULL, &dfep, &v))
+ parid = -1;
+ else
+ parid = dfep->id;
+ v |= v1;
+ init_pathname(&newf);
+ e = generate_fname(dfep, flp - flist, &newf, &id, &v1);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&f, &flist[FT_DIR], dfep);
+ printf("%d/%d: rename - no filename from %s\n",
+ procid, opno, f.path);
+ }
+ free_pathname(&newf);
+ free_pathname(&f);
+ return;
+ }
+ e = rename_path(&f, &newf) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0) {
+ if (flp - flist == FT_DIR) {
+ oldid = fep->id;
+ fix_parent(oldid, id);
+ }
+ del_from_flist(flp - flist, fep - flp->fents);
+ add_to_flist(flp - flist, id, parid);
+ }
+ if (v)
+ printf("%d/%d: rename %s to %s %d\n", procid, opno, f.path,
+ newf.path, e);
+ free_pathname(&newf);
+ free_pathname(&f);
+}
+
+void
+resvsp_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ struct flock64 fl;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: resvsp - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDWR);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: resvsp - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: resvsp - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = off;
+ fl.l_len = (off64_t)(random() % (1024 * 1024));
+ e = ioctl(fd, XFS_IOC_RESVSP64, &fl) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: ioctl(XFS_IOC_RESVSP64) %s %lld %lld %d\n",
+ procid, opno, f.path, off, fl.l_len, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+rmdir_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_DIRm, r, &f, NULL, &fep, &v)) {
+ if (v)
+ printf("%d/%d: rmdir - no directory\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ e = rmdir_path(&f) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ del_from_flist(FT_DIR, fep - flist[FT_DIR].fents);
+ if (v)
+ printf("%d/%d: rmdir %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+stat_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: stat - no entries\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ e = lstat64_path(&f, &stb) < 0 ? errno : 0;
+ check_cwd();
+ if (v)
+ printf("%d/%d: stat %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+symlink_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ int i;
+ int id;
+ int len;
+ int parid;
+ int v;
+ int v1;
+ char *val;
+
+ if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v))
+ parid = -1;
+ else
+ parid = fep->id;
+ init_pathname(&f);
+ e = generate_fname(fep, FT_SYM, &f, &id, &v1);
+ v |= v1;
+ if (!e) {
+ if (v) {
+ fent_to_name(&f, &flist[FT_DIR], fep);
+ printf("%d/%d: symlink - no filename from %s\n",
+ procid, opno, f.path);
+ }
+ free_pathname(&f);
+ return;
+ }
+ len = (int)(random() % PATH_MAX);
+ val = malloc(len + 1);
+ if (len)
+ memset(val, 'x', len);
+ val[len] = '\0';
+ for (i = 10; i < len - 1; i += 10)
+ val[i] = '/';
+ e = symlink_path(val, &f) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ add_to_flist(FT_SYM, id, parid);
+ free(val);
+ if (v)
+ printf("%d/%d: symlink %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+/* ARGSUSED */
+void
+sync_f(int opno, long r)
+{
+ sync();
+ if (verbose)
+ printf("%d/%d: sync\n", procid, opno);
+}
+
+void
+truncate_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: truncate - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ e = stat64_path(&f, &stb) < 0 ? errno : 0;
+ check_cwd();
+ if (e > 0) {
+ if (v)
+ printf("%d/%d: truncate - stat64 %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ e = truncate64_path(&f, off) < 0 ? errno : 0;
+ check_cwd();
+ if (v)
+ printf("%d/%d: truncate %s %lld %d\n", procid, opno, f.path,
+ off, e);
+ free_pathname(&f);
+}
+
+void
+unlink_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ fent_t *fep;
+ flist_t *flp;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_NOTDIR, r, &f, &flp, &fep, &v)) {
+ if (v)
+ printf("%d/%d: unlink - no file\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ e = unlink_path(&f) < 0 ? errno : 0;
+ check_cwd();
+ if (e == 0)
+ del_from_flist(flp - flist, fep - flp->fents);
+ if (v)
+ printf("%d/%d: unlink %s %d\n", procid, opno, f.path, e);
+ free_pathname(&f);
+}
+
+void
+unresvsp_f(int opno, long r)
+{
+ int e;
+ pathname_t f;
+ int fd;
+ struct flock64 fl;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: unresvsp - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_RDWR);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: unresvsp - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: unresvsp - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = off;
+ fl.l_len = (off64_t)(random() % (1 << 20));
+ e = ioctl(fd, XFS_IOC_UNRESVSP64, &fl) < 0 ? errno : 0;
+ if (v)
+ printf("%d/%d: ioctl(XFS_IOC_UNRESVSP64) %s %lld %lld %d\n",
+ procid, opno, f.path, off, fl.l_len, e);
+ free_pathname(&f);
+ close(fd);
+}
+
+void
+write_f(int opno, long r)
+{
+ char *buf;
+ int e;
+ pathname_t f;
+ int fd;
+ size_t len;
+ __int64_t lr;
+ off64_t off;
+ struct stat64 stb;
+ int v;
+
+ init_pathname(&f);
+ if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) {
+ if (v)
+ printf("%d/%d: write - no filename\n", procid, opno);
+ free_pathname(&f);
+ return;
+ }
+ fd = open_path(&f, O_WRONLY);
+ e = fd < 0 ? errno : 0;
+ check_cwd();
+ if (fd < 0) {
+ if (v)
+ printf("%d/%d: write - open %s failed %d\n",
+ procid, opno, f.path, e);
+ free_pathname(&f);
+ return;
+ }
+ if (fstat64(fd, &stb) < 0) {
+ if (v)
+ printf("%d/%d: write - fstat64 %s failed %d\n",
+ procid, opno, f.path, errno);
+ free_pathname(&f);
+ close(fd);
+ return;
+ }
+ lr = ((__int64_t)random() << 32) + random();
+ off = (off64_t)(lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE));
+ off %= maxfsize;
+ lseek64(fd, off, SEEK_SET);
+ len = (random() % (getpagesize() * 32)) + 1;
+ buf = malloc(len);
+ memset(buf, nameseq & 0xff, len);
+ e = write(fd, buf, len) < 0 ? errno : 0;
+ free(buf);
+ if (v)
+ printf("%d/%d: write %s [%lld,%d] %d\n",
+ procid, opno, f.path, off, len, e);
+ free_pathname(&f);
+ close(fd);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+/* includes */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <getopt.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <dirent.h>
+
+/* xfs specific includes */
+
+#include <libxfs.h>
+#include <attributes.h>
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+int verbose; /* print lots of debugging info */
+
+void usage(char *progname);
+void writeblks(int fd, long filesize, int blocksize,
+ int interleave, int base, int rev);
+int readblks(int fd, long filesize, int blocksize,
+ int interleave, int count);
+
+void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-i interleave]\n"
+ "\t\t[-c count] [-r(everse)] [-v(erbose)] filename\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int interleave, blocksize, count, rev, i, ch, fd;
+ long filesize;
+ char *filename;
+ int errs;
+
+ filesize = 1024*1024;
+ blocksize = 4096;
+ count = interleave = 4;
+ rev = verbose = 0;
+ while ((ch = getopt(argc, argv, "b:l:i:c:rv")) != EOF) {
+ switch(ch) {
+ case 'b': blocksize = atoi(optarg); break;
+ case 'c': count = atoi(optarg); break;
+ case 'i': interleave = atoi(optarg); break;
+ case 'l': filesize = atol(optarg); break;
+ case 'v': verbose++; break;
+ case 'r': rev++; break;
+ default: usage(argv[0]); break;
+ }
+ }
+ if (optind == argc-1)
+ filename = argv[optind];
+ else
+ usage(argv[0]);
+ if ((filesize % (blocksize*interleave)) != 0) {
+ filesize -= filesize % (blocksize * interleave);
+ printf("filesize not a multiple of blocksize*interleave,\n");
+ printf("reducing filesize to %ld\n", filesize);
+ }
+ if (count > interleave) {
+ count = interleave;
+ printf("count of passes is too large, setting to %d\n", count);
+ } else if (count < 1) {
+ count = 1;
+ printf("count of passes is too small, setting to %d\n", count);
+ }
+
+ if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
+ perror("open");
+ return 1;
+ }
+ for (i = 0; i < count; i++) {
+ writeblks(fd, filesize, blocksize, interleave, i, rev);
+ }
+ errs=readblks(fd, filesize, blocksize, interleave, count);
+ if (close(fd) < 0) {
+ perror("close");
+ return 1;
+ }
+ if (errs) {
+ printf("%d errors detected during readback\n", errs);
+ return 1;
+ }
+ return 0;
+}
+
+void
+writeblks(int fd, long filesize, int blocksize, int interleave, int base, int rev)
+{
+ long offset;
+ char *buffer;
+
+ if ((buffer = calloc(1, blocksize)) == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ if (rev) {
+ offset = (filesize-blocksize) - (base * blocksize);
+ } else {
+ offset = base * blocksize;
+ }
+ for (;;) {
+ if (lseek(fd, offset, SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ *(long *)buffer = *(long *)(buffer+256) = offset;
+ if (write(fd, buffer, blocksize) < blocksize) {
+ perror("write");
+ exit(1);
+ }
+ if (verbose) {
+ printf("writing data at offset=%ld, delta=%d, value 0x%lx and 0x%lx\n",
+ offset-base*blocksize, base,
+ *(long *)buffer,
+ *(long *)(buffer+256));
+ }
+
+ if (rev) {
+ offset -= interleave*blocksize;
+ if (offset < 0)
+ break;
+ } else {
+ offset += interleave*blocksize;
+ if (offset >= filesize)
+ break;
+ }
+ }
+
+ {
+ /* pad file out to full length */
+ char *zero="";
+ if (lseek(fd, filesize-1, SEEK_SET)<0) {
+ perror("lseek");
+ exit(1);
+ }
+ if (write(fd, zero, 1)!=1) {
+ perror("write");
+ exit(1);
+ }
+ }
+
+ free(buffer);
+}
+
+int
+readblks(int fd, long filesize, int blocksize, int interleave, int count)
+{
+ long offset;
+ char *buffer, *tmp;
+ int xfer, i;
+ int errs=0;
+
+ if ((buffer = calloc(interleave, blocksize)) == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ xfer = interleave * blocksize;
+
+ if (lseek(fd, (long)0, SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ for (offset = 0; offset < filesize; offset += xfer) {
+ if ((i = read(fd, buffer, xfer) < xfer)) {
+ if (i == 0)
+ break;
+ if (i < 0)
+ perror("read");
+ printf("short read: %d of %d bytes read\n", i, xfer);
+
+ exit(1);
+ }
+ for (tmp = buffer, i = 0; i < count; i++, tmp += blocksize) {
+ if ( (*(long *)tmp != (offset+i*blocksize)) ||
+ (*(long *)(tmp+256) != (offset+i*blocksize)) ) {
+ printf("mismatched data at offset=%ld, delta=%d, expected 0x%lx, got 0x%lx and 0x%lx\n",
+ offset, i,
+ offset+i*blocksize,
+ *(long *)tmp,
+ *(long *)(tmp+256));
+ errs++;
+ }
+ }
+ }
+
+ free(buffer);
+ return errs;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <libxfs.h>
+#include <jdm.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+/* simple test program to try out a bunch of ioctls:
+ * XFS_IOC_FSCOUNTS
+ * XFS_IOC_GET_RESBLKS
+ * XFS_IOC_SET_RESBLKS
+ * XFS_IOC_PATH_TO_FSHANDLE
+ * XFS_IOC_PATH_TO_HANDLE
+ * XFS_IOC_FD_TO_HANDLE
+ * XFS_IOC_OPEN_BY_HANDLE
+ * XFS_IOC_READLINK_BY_HANDLE
+*/
+
+
+void fscounts(int fsfd)
+{
+ xfs_fsop_counts_t counts;
+ int ret;
+
+ ret=ioctl(fsfd, XFS_IOC_FSCOUNTS, &counts);
+ if (ret) {
+ perror("ioctl(XFS_IOC_FSCOUNTS)");
+ exit(1);
+ }
+
+ printf("XFS_IOC_FSCOUNTS-\n freedata: %lld freertx: %lld freeino: %lld allocino: %lld\n",
+ counts.freedata, counts.freertx, counts.freeino, counts.allocino);
+}
+
+__u64 getresblks(int fsfd)
+{
+ xfs_fsop_resblks_t res;
+ int ret;
+
+ ret=ioctl(fsfd, XFS_IOC_GET_RESBLKS, &res);
+ if (ret) {
+ perror("ioctl(XFS_IOC_GET_RESBLKS)");
+ exit(1);
+ }
+
+ printf("XFS_IOC_GET_RESBLKS-\n resblks: %lld blksavail: %lld\n",
+ res.resblks, res.resblks_avail);
+
+ return res.resblks;
+}
+
+__u64 setresblks(int fsfd, __u64 blks)
+{
+ xfs_fsop_resblks_t res;
+ int ret;
+
+ res.resblks=blks;
+ ret=ioctl(fsfd, XFS_IOC_SET_RESBLKS, &res);
+ if (ret) {
+ perror("ioctl(XFS_IOC_SET_RESBLKS)");
+ exit(1);
+ }
+
+ printf("XFS_IOC_SET_RESBLKS-\n resblks: %lld blksavail: %lld\n",
+ res.resblks, res.resblks_avail);
+
+ return res.resblks;
+}
+
+void handle_print(void *handle, int handlen)
+{
+ char *p=handle;
+ if (!handle||!handlen) {
+ printf("%s",handle?"<zero len>":"<NULL>");
+ return;
+ };
+
+ printf("#");
+ while (handlen--)
+ printf("%02x", *p++);
+}
+
+void stat_print(int fd)
+{
+ struct stat buf;
+
+ if (fstat(fd, &buf)) {
+ perror("stat");
+ exit(1);
+ }
+ printf("dev: %llu ino: %llu mode: %o\n",
+ (__u64)buf.st_dev, (__u64)buf.st_ino, buf.st_mode);
+}
+
+
+void handle(int fsfd, char *path)
+{
+ xfs_fsop_handlereq_t handle;
+ char buffer[1024];
+ char link[1024];
+ int ret;
+ __u32 len;
+ __u32 linklen;
+ int fd;
+
+ handle.path=path;
+ handle.ohandle=buffer;
+ handle.ohandlen=&len;
+ ret=ioctl(fsfd, XFS_IOC_PATH_TO_FSHANDLE, &handle);
+ if (ret) {
+ perror("ioctl(XFS_IOC_PATH_TO_FSHANDLE)");
+ exit(1);
+ }
+ printf("XFS_IOC_PATH_TO_FSHANDLE-\n handle: ");
+ handle_print(handle.ohandle, *handle.ohandlen);
+ printf("\n");
+
+ fd=open(path,O_RDONLY);
+ if (fd<0) {
+ perror("open");
+ exit(1);
+ }
+ handle.path=NULL;
+ handle.fd=fd;
+ handle.ohandle=buffer;
+ handle.ohandlen=&len;
+ ret=ioctl(fsfd, XFS_IOC_FD_TO_HANDLE, &handle);
+ if (ret) {
+ perror("ioctl(XFS_IOC_FD_TO_HANDLE)");
+ exit(1);
+ }
+
+ printf("XFS_IOC_FD_TO_HANDLE-\n path: %s\n handle: ", path);
+ handle_print(handle.ohandle, *handle.ohandlen);
+ printf("\n");
+
+ close(fd);
+
+ handle.path=NULL;
+ handle.fd=-1;
+ handle.ihandle=buffer;
+ handle.ihandlen=len;
+ handle.ohandle=NULL;
+ handle.ohandlen=NULL;
+ ret=ioctl(fsfd, XFS_IOC_OPEN_BY_HANDLE, &handle);
+ if (ret<0) {
+ perror("ioctl(XFS_IOC_OPEN_BY_HANDLE)");
+ exit(1);
+ }
+ printf("XFS_IOC_OPEN_BY_HANDLE-\n handle: ");
+ handle_print(handle.ihandle, handle.ihandlen);
+ printf("\n fd: %d\n stat- ", ret);
+ stat_print(ret);
+ close(ret);
+
+ handle.path=path;
+ handle.ohandle=buffer;
+ handle.ohandlen=&len;
+ ret=ioctl(fsfd, XFS_IOC_PATH_TO_HANDLE, &handle);
+ if (ret) {
+ perror("ioctl(XFS_IOC_PATH_TO_HANDLE)");
+ exit(1);
+ }
+ printf("XFS_IOC_PATH_TO_HANDLE-\n path: %s\n handle: ", path);
+ handle_print(handle.ohandle, *handle.ohandlen);
+ printf("\n");
+
+ handle.path=NULL;
+ handle.fd=-1;
+ handle.ihandle=buffer;
+ handle.ihandlen=len;
+ handle.ohandle=link;
+ linklen=sizeof(link);
+ handle.ohandlen=&linklen;
+ ret=ioctl(fsfd, XFS_IOC_READLINK_BY_HANDLE, &handle);
+ if (ret<0) {
+ perror("ioctl(XFS_IOC_READLINK_BY_HANDLE)");
+ fprintf(stderr,"ERROR IGNORED\n");
+ } else {
+ printf("XFS_IOC_READLINK_BY_HANDLE-\n handle: ");
+ handle_print(handle.ihandle, handle.ihandlen);
+ printf("\n link=\"%*.*s\"\n",
+ ret, ret, (char*)handle.ohandle);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int fsfd;
+
+ if (argc != 3) {
+ fprintf(stderr,"usage: %s <filesystem> <file/link in FS>\n",
+ argv[0]);
+ exit(0);
+ }
+
+ fsfd = open(argv[1], O_RDONLY);
+ if (fsfd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ /* XFS_IOC_FSCOUNTS */
+ fscounts(fsfd);
+ /* XFS_IOC_GET_RESBLKS & XFS_IOC_SET_RESBLKS */
+ getresblks(fsfd);
+ setresblks(fsfd, 1000);
+ getresblks(fsfd);
+ setresblks(fsfd, 0);
+ /* XFS_IOC_FSINUMBERS */
+
+ /* NYI in kernel */
+
+ /* XFS_IOC_PATH_TO_FSHANDLE */
+ /* XFS_IOC_PATH_TO_HANDLE */
+ /* XFS_IOC_FD_TO_HANDLE */
+ /* XFS_IOC_OPEN_BY_HANDLE */
+ /* XFS_IOC_READLINK_BY_HANDLE */
+ handle(fsfd, argv[2]);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+/*
+ *
+ * loggen: Generate log entries. Very much incomplete. The empty log
+ * record is a bit of a misnomer since we need to jump through
+ * hoops to get a log record that parses ok yet does nothing.
+ *
+ * - dxm 29/09/00
+ */
+
+#include <libxfs.h>
+#include <malloc.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <xfs_log.h>
+#include <xfs_log_priv.h>
+
+void
+usage()
+{
+ fprintf(stderr,"Usage: loggen\n"
+ " set up parameters before writing record(s):\n"
+ " -f f - set format\n"
+ " -u u - set uuid\n"
+ " -c c - set cycle\n"
+ " -b b - set block\n"
+ " -C c - set tail cycle\n"
+ " -B b - set tail block\n"
+ " write log record(s):\n"
+ " -z n - write n zero block(s) (1BB)\n"
+ " -e n - write n empty record(s) (2BB)\n"
+ " -m n - write n unmount record(s) (2BB)\n"
+ "\n"
+ " redirect stdout to external log partition, or pipe to\n"
+ " dd with appropriate parameters to stuff into internal log.\n"
+ );
+ exit(1);
+}
+
+int bufblocks = 0;
+void *buf = NULL;
+int param_cycle = 1;
+int param_block = 0;
+int param_tail_cycle = 1;
+int param_tail_block = 0;
+int param_fmt = XLOG_FMT;
+uuid_t param_uuid = {0};
+
+void
+loggen_alloc(int blocks)
+{
+ if (!(buf=realloc(buf, blocks*BBSIZE))) {
+ fprintf(stderr,"failed to allocate %d block(s)\n", blocks);
+ exit(1);
+ }
+ memset(buf, 0, blocks*BBSIZE);
+ bufblocks=blocks;
+}
+
+void
+loggen_write()
+{
+ if (!buf) {
+ fprintf(stderr,"no buffer allocated\n");
+ exit(1);
+ }
+
+ if (fwrite(buf, BBSIZE, bufblocks, stdout) != bufblocks) {
+ perror("fwrite");
+ exit(1);
+ }
+
+}
+
+void
+loggen_zero(int count)
+{
+ if (!count) count=1;
+
+ fprintf(stderr," *** zero block (1BB) x %d\n", count);
+ loggen_alloc(1);
+ while (count--)
+ loggen_write(count);
+}
+
+void
+loggen_unmount(int count)
+{
+ xlog_rec_header_t *head;
+ xlog_op_header_t *op;
+ /* the data section must be 32 bit size aligned */
+ struct {
+ __uint16_t magic;
+ __uint16_t pad1;
+ __uint32_t pad2; /* may as well make it 64 bits */
+ } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
+
+ if (!count) count=1;
+
+ fprintf(stderr," *** unmount record (2BB) x %d\n", count);
+ loggen_alloc(2);
+
+ head = (xlog_rec_header_t *)buf;
+ op = (xlog_op_header_t *)(((char*)buf)+BBSIZE);
+
+ /* note that oh_tid actually contains the cycle number
+ * and the tid is stored in h_cycle_data[0] - that's the
+ * way things end up on disk.
+ */
+
+ INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
+ INT_SET(head->h_cycle, ARCH_CONVERT, param_cycle);
+ INT_SET(head->h_version, ARCH_CONVERT, 1);
+ INT_SET(head->h_len, ARCH_CONVERT, 20);
+ INT_SET(head->h_chksum, ARCH_CONVERT, 0);
+ INT_SET(head->h_prev_block, ARCH_CONVERT, -1);
+ INT_SET(head->h_num_logops, ARCH_CONVERT, 1);
+ INT_SET(head->h_cycle_data[0], ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(head->h_fmt, ARCH_CONVERT, param_fmt);
+
+ ASSIGN_ANY_LSN(head->h_tail_lsn,
+ param_tail_cycle, param_tail_block, ARCH_CONVERT);
+
+ memcpy(head->h_fs_uuid, param_uuid, sizeof(uuid_t));
+
+ /* now a log unmount op */
+ INT_SET(op->oh_tid, ARCH_CONVERT, param_cycle);
+ INT_SET(op->oh_len, ARCH_CONVERT, sizeof(magic));
+ INT_SET(op->oh_clientid, ARCH_CONVERT, XFS_LOG);
+ INT_SET(op->oh_flags, ARCH_CONVERT, XLOG_UNMOUNT_TRANS);
+ INT_SET(op->oh_res2, ARCH_CONVERT, 0);
+
+ /* and the data for this op */
+
+ memcpy(op+1, &magic, sizeof(magic));
+
+ while (count--) {
+ ASSIGN_ANY_LSN(head->h_lsn,
+ param_cycle, param_block++, ARCH_CONVERT);
+
+ loggen_write(count);
+ }
+}
+
+void
+loggen_empty(int count)
+{
+ xlog_rec_header_t *head;
+ xlog_op_header_t *op1, *op2, *op3, *op4, *op5;
+ xfs_trans_header_t *trans;
+ xfs_buf_log_format_t *blf;
+ int *data;
+ char *p;
+
+ if (!count) count=1;
+
+ fprintf(stderr," *** empty record (2BB) x %d\n", count);
+ loggen_alloc(2);
+
+ p=(char*)buf;
+ head = (xlog_rec_header_t *)p; p+=BBSIZE;
+ op1 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
+ op2 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
+ trans = (xfs_trans_header_t *)p; p+=sizeof(xfs_trans_header_t);
+ op3 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
+ blf = (xfs_buf_log_format_t*)p; p+=sizeof(xfs_buf_log_format_t);
+ op4 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
+ data = (int *)p; p+=sizeof(int);
+ op5 = (xlog_op_header_t *)p; p+=sizeof(xlog_op_header_t);
+
+ /* note that oh_tid actually contains the cycle number
+ * and the tid is stored in h_cycle_data[0] - that's the
+ * way things end up on disk.
+ */
+
+ INT_SET(head->h_magicno, ARCH_CONVERT, XLOG_HEADER_MAGIC_NUM);
+ INT_SET(head->h_cycle, ARCH_CONVERT, param_cycle);
+ INT_SET(head->h_version, ARCH_CONVERT, 1);
+ INT_SET(head->h_len, ARCH_CONVERT, 5*sizeof(xlog_op_header_t) +
+ sizeof(xfs_trans_header_t)+
+ sizeof(xfs_buf_log_format_t)+
+ sizeof(int));
+ INT_SET(head->h_chksum, ARCH_CONVERT, 0);
+ INT_SET(head->h_prev_block, ARCH_CONVERT, -1);
+ INT_SET(head->h_num_logops, ARCH_CONVERT, 5);
+ INT_SET(head->h_cycle_data[0], ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(head->h_fmt, ARCH_CONVERT, param_fmt);
+
+ ASSIGN_ANY_LSN(head->h_tail_lsn,
+ param_tail_cycle, param_tail_block, ARCH_CONVERT);
+
+ memcpy(head->h_fs_uuid, param_uuid, sizeof(uuid_t));
+
+ /* start */
+ INT_SET(op1->oh_tid, ARCH_CONVERT, 1);
+ INT_SET(op1->oh_len, ARCH_CONVERT, 0);
+ INT_SET(op1->oh_clientid, ARCH_CONVERT, XFS_TRANSACTION);
+ INT_SET(op1->oh_flags, ARCH_CONVERT, XLOG_START_TRANS);
+ INT_SET(op1->oh_res2, ARCH_CONVERT, 0);
+ /* dummy */
+ INT_SET(op2->oh_tid, ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(op2->oh_len, ARCH_CONVERT, sizeof(xfs_trans_header_t));
+ INT_SET(op2->oh_clientid, ARCH_CONVERT, XFS_TRANSACTION);
+ INT_SET(op2->oh_flags, ARCH_CONVERT, 0);
+ INT_SET(op2->oh_res2, ARCH_CONVERT, 0);
+ /* dummy transaction - this stuff doesn't get endian converted */
+ trans->th_magic = XFS_TRANS_MAGIC;
+ trans->th_type = XFS_TRANS_DUMMY1;
+ trans->th_tid = 0;
+ trans->th_num_items = 1;
+ /* buffer */
+ INT_SET(op3->oh_tid, ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(op3->oh_len, ARCH_CONVERT, sizeof(xfs_buf_log_format_t));
+ INT_SET(op3->oh_clientid, ARCH_CONVERT, XFS_TRANSACTION);
+ INT_SET(op3->oh_flags, ARCH_CONVERT, 0);
+ INT_SET(op3->oh_res2, ARCH_CONVERT, 0);
+ /* an empty buffer too */
+ blf->blf_type = XFS_LI_BUF;
+ blf->blf_size = 2;
+ blf->blf_flags = XFS_BLI_CANCEL;
+ blf->blf_blkno = 1;
+ blf->blf_map_size = 1;
+ blf->blf_data_map[0]= 0;
+ /* commit */
+ INT_SET(op4->oh_tid, ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(op4->oh_len, ARCH_CONVERT, sizeof(int));
+ INT_SET(op4->oh_clientid, ARCH_CONVERT, XFS_TRANSACTION);
+ INT_SET(op4->oh_flags, ARCH_CONVERT, 0);
+ INT_SET(op4->oh_res2, ARCH_CONVERT, 0);
+ /* and the data */
+ *data=*(int*)(char*)"FISH"; /* this won't get written (I hope) */
+ /* commit */
+ INT_SET(op5->oh_tid, ARCH_CONVERT, 0xb0c0d0d0);
+ INT_SET(op5->oh_len, ARCH_CONVERT, 0);
+ INT_SET(op5->oh_clientid, ARCH_CONVERT, XFS_TRANSACTION);
+ INT_SET(op5->oh_flags, ARCH_CONVERT, XLOG_COMMIT_TRANS);
+ INT_SET(op5->oh_res2, ARCH_CONVERT, 0);
+
+ while (count--) {
+ ASSIGN_ANY_LSN(head->h_lsn,
+ param_cycle, param_block++, ARCH_CONVERT);
+
+ loggen_write(count);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+
+ fprintf(stderr,"*** loggen\n");
+
+ if (argc<2) usage();
+
+ while ((c = getopt(argc, argv, "f:u:c:b:C:B:z:e:m:")) != -1) {
+ switch (c) {
+ case 'f':
+ param_fmt=atoi(optarg);
+ break;
+ case 'u':
+ memset(param_uuid, atoi(optarg), sizeof(param_uuid));
+ break;
+ case 'c':
+ param_cycle=atoi(optarg);
+ break;
+ case 'b':
+ param_block=atoi(optarg);
+ break;
+ case 'C':
+ param_tail_cycle=atoi(optarg);
+ break;
+ case 'B':
+ param_tail_block=atoi(optarg);
+ break;
+
+ case 'z':
+ loggen_zero(atoi(optarg));
+ break;
+ case 'e':
+ loggen_empty(atoi(optarg));
+ break;
+ case 'm':
+ loggen_unmount(atoi(optarg));
+ break;
+
+ default:
+ fprintf(stderr, "unknown option\n");
+ usage();
+ }
+ }
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/sysmacros.h>
+
+long timebuf;
+
+void
+timesince(long timesec)
+{
+ long d_since; /* days */
+ long h_since; /* hours */
+ long m_since; /* minutes */
+ long s_since; /* seconds */
+
+ s_since = timebuf - timesec;
+ d_since = s_since / 86400l ;
+ s_since -= d_since * 86400l ;
+ h_since = s_since / 3600l ;
+ s_since -= h_since * 3600l ;
+ m_since = s_since / 60l ;
+ s_since -= m_since * 60l ;
+
+ printf("(%05ld.%02ld:%02ld:%02ld)\n",
+ d_since, h_since, m_since, s_since);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct stat64 sbuf;
+ char mode[10];
+ int i;
+
+ time(&timebuf);
+
+ for (i = 1; i < argc; i++) {
+
+ if( lstat64(argv[i], &sbuf) < 0) {
+ perror(argv[i]);
+ continue;
+ }
+
+ printf(" File: \"%s\"\n", argv[i]);
+ printf(" Size: %-10llu", sbuf.st_size);
+
+ strcpy(mode,"----------");
+ if (sbuf.st_mode & (S_IEXEC>>6))
+ mode[9] = 'x';
+ if (sbuf.st_mode & (S_IWRITE>>6))
+ mode[8] = 'w';
+ if (sbuf.st_mode & (S_IREAD>>6))
+ mode[7] = 'r';
+ if (sbuf.st_mode & (S_IEXEC>>3))
+ mode[6] = 'x';
+ if (sbuf.st_mode & (S_IWRITE>>3))
+ mode[5] = 'w';
+ if (sbuf.st_mode & (S_IREAD>>3))
+ mode[4] = 'r';
+ if (sbuf.st_mode & S_IEXEC)
+ mode[3] = 'x';
+ if (sbuf.st_mode & S_IWRITE)
+ mode[2] = 'w';
+ if (sbuf.st_mode & S_IREAD)
+ mode[1] = 'r';
+ if (sbuf.st_mode & S_ISVTX)
+ mode[9] = 't';
+ if (sbuf.st_mode & S_ISGID)
+ mode[6] = 's';
+ if (sbuf.st_mode & S_ISUID)
+ mode[3] = 's';
+
+ printf(" Filetype: ");
+ switch (sbuf.st_mode & S_IFMT) {
+ case S_IFSOCK:
+ puts("Socket");
+ mode[0] = 's';
+ break;
+ case S_IFDIR:
+ puts("Directory");
+ mode[0] = 'd';
+ break;
+ case S_IFCHR:
+ puts("Character Device");
+ mode[0] = 'c';
+ break;
+ case S_IFBLK:
+ puts("Block Device");
+ mode[0] = 'b';
+ break;
+ case S_IFREG:
+ puts("Regular File");
+ mode[0] = '-';
+ break;
+ case S_IFLNK:
+ puts("Symbolic Link");
+ mode[0] = 'l';
+ break;
+ case S_IFIFO:
+ puts("Fifo File");
+ mode[0] = 'f';
+ break;
+ default:
+ puts("Unknown");
+ mode[0] = '?';
+ }
+
+ printf(" Mode: (%04o/%s)", sbuf.st_mode & 07777, mode);
+ printf(" Uid: (%d)", sbuf.st_uid);
+ printf(" Gid: (%d)\n", sbuf.st_gid);
+ printf("Device: %2d,%-2d", major(sbuf.st_dev),
+ minor(sbuf.st_dev));
+ printf(" Inode: %-10lu", sbuf.st_ino);
+ printf("Links: %-5d", sbuf.st_nlink);
+
+ if ( ((sbuf.st_mode & S_IFMT) == S_IFCHR)
+ || ((sbuf.st_mode & S_IFMT) == S_IFBLK) )
+ printf(" Device type: %2d,%-2d\n",
+ major(sbuf.st_rdev), minor(sbuf.st_rdev));
+ else
+ printf("\n");
+
+ printf("Access: %.24s",ctime(&sbuf.st_atime));
+ timesince(sbuf.st_atime);
+ printf("Modify: %.24s",ctime(&sbuf.st_mtime));
+ timesince(sbuf.st_mtime);
+ printf("Change: %.24s",ctime(&sbuf.st_ctime));
+ timesince(sbuf.st_ctime);
+
+ if (i+1 < argc)
+ printf("\n");
+ }
+ if (i == 1) {
+ fprintf(stderr, "Usage: lstat64 filename...\n");
+ exit(1);
+ }
+ exit(0);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+/*
+ * nametest.c
+ *
+ * Run a fully automatic, random test of the directory routines.
+ *
+ * Given an input file of a list of filenames (one per line)
+ * It does a number of iterations of operations
+ * chosen pseudo-randomly in certain percentages:
+ * creating (open),
+ * deleting (unlink) and
+ * looking up (stat)
+ * on a pseudo-randomly chosen filename (from input file).
+ *
+ * The percentage thresholds for operation selection change
+ * every <number-of-names> iterations.
+ * e.g.
+ * If had 100 names then:
+ * iterations:
+ * 1-100: pct_remove = 33; pct_create = 33;
+ * 101-200: pct_remove = 60; pct_create = 20;
+ * 201-300: pct_remove = 20; pct_create = 60;
+ * 301-400: pct_remove = 33; pct_create = 33;
+ * 401-500: pct_remove = 60; pct_create = 20;
+ * 501-600: pct_remove = 20; pct_create = 60;
+ * etc...
+ *
+ * op > (pct_remove + pct_create) => auto_lookup(ip);
+ * op > pct_remove => auto_create(ip);
+ * t => auto_remove(ip);
+ *
+ * Each iteration an op is chosen as shown above
+ * and a filename is randomly chosen.
+ *
+ * The operation is done and any error codes are
+ * verified considering whether file exists (info.exists)
+ * or not. The stat(3) call also compares inode number.
+ */
+
+
+#define DOT_COUNT 100 /* print a '.' every X operations */
+
+struct info {
+ ino64_t inumber;
+ char *name;
+ short namelen;
+ short exists;
+} *table;
+
+char *table_data; /* char string storage for info table */
+
+int good_adds, good_rms, good_looks, good_tot; /* ops that suceeded */
+int bad_adds, bad_rms, bad_looks, bad_tot; /* ops that failed */
+
+int verbose;
+
+int auto_lookup(struct info *);
+int auto_create(struct info *);
+int auto_remove(struct info *);
+
+void usage(void);
+
+void
+usage(void)
+{
+ printf("usage: nametest [-l srcfile] [-i iterations] [-s seed] [-z] [-v]\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *sourcefile, *c;
+ int totalnames, iterations, zeroout;
+ int zone, op, pct_remove, pct_create, ch, i, retval, fd;
+ struct stat64 statb;
+ struct info *ip;
+ int seed, linedots;
+
+ linedots = zeroout = verbose = 0;
+ seed = (int)time(NULL) % 1000;
+ iterations = 100000;
+ sourcefile = "input";
+ while ((ch = getopt(argc, argv, "l:i:s:zv")) != EOF) {
+ switch (ch) {
+ case 'l': sourcefile = optarg; break;
+ case 's': seed = atoi(optarg); break;
+ case 'i': iterations = atoi(optarg); break;
+ case 'z': zeroout++; break;
+ case 'v': verbose++; break;
+ default: usage(); break;
+ }
+ }
+
+ /*
+ * Read in the source file.
+ */
+ if (stat64(sourcefile, &statb) < 0) {
+ perror(sourcefile);
+ usage();
+ return 1;
+ }
+ if ((table_data = malloc(statb.st_size)) == NULL) {
+ perror("calloc");
+ return 1;
+ }
+ if ((fd = open(sourcefile, O_RDONLY)) < 0) {
+ perror(sourcefile);
+ return 1;
+ }
+ if (read(fd, table_data, statb.st_size) < 0) {
+ perror(sourcefile);
+ return 1;
+ }
+ close(fd);
+
+ /*
+ * Allocate space for the info table and fill it in.
+ */
+
+ /*
+ * Add up number of lines in file
+ * and replace '\n' by '\0'
+ */
+ totalnames = 0;
+ for (c = table_data, i = 0; i < statb.st_size; c++, i++) {
+ if (*c == '\n') {
+ *c = 0;
+ totalnames++;
+ }
+ }
+ if (!totalnames) {
+ printf("no names found in input file\n");
+ return 1;
+ }
+
+ table = (struct info *)calloc(totalnames+1, sizeof(struct info));
+ if (table == NULL) {
+ perror("calloc");
+ return 1;
+ }
+ /*
+ * Copy over names from file (in <table_data>) into name fields
+ * of info structures in <table>.
+ */
+ ip = table;
+ ip->name = c = table_data;
+ for (i = 0; i < totalnames; ) {
+ if (*c++ == 0) {
+ ip++;
+ ip->name = c;
+ i++;
+ } else {
+ ip->namelen++;
+ }
+ }
+ /*
+ * Check table of names.
+ * Name are of files and not commands.
+ *
+ * ??? I guess use of an input file with commands
+ * has been done before ???
+ * "touch fred" => "fred"
+ * "rm fred" => error
+ * "ls fred" => error
+ */
+ for (ip = table, i = 0; i < totalnames; ip++, i++) {
+ if (strncmp(ip->name, "touch ", strlen("touch ")) == 0) {
+ /* make name skip over "touch " string */
+ ip->name += strlen("touch ");
+ ip->namelen -= strlen("touch ");
+ } else if (strncmp(ip->name, "rm ", strlen("rm ")) == 0) {
+ printf("bad input file, \"rm\" cmds not allowed\n");
+ return 1;
+ } else if (strncmp(ip->name, "ls ", strlen("ls ")) == 0) {
+ printf("bad input file, \"ls\" cmds not allowed\n");
+ return 1;
+ }
+ }
+
+ /*
+ * Run random transactions against the directory.
+ */
+ zone = -1;
+ printf("Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed);
+ srandom(seed);
+
+ for (i = 0; i < iterations; i++) {
+ /*
+ * The distribution of transaction types changes over time.
+ * At first we have an equal distribution which gives us
+ * a steady state directory of 50% total size.
+ * Later, we have an unequal distribution which gives us
+ * more creates than removes, growing the directory.
+ * Later still, we have an unequal distribution which gives
+ * us more removes than creates, shrinking the directory.
+ */
+ if ((i % totalnames) == 0) {
+ zone++;
+ switch(zone % 3) {
+ case 0: pct_remove = 20; pct_create = 60; break;
+ case 1: pct_remove = 33; pct_create = 33; break;
+ case 2: pct_remove = 60; pct_create = 20; break;
+ }
+ }
+
+ /*
+ * Choose an operation based on the current distribution.
+ */
+ ip = &table[ random() % totalnames ];
+ op = random() % 100;
+ if (op > (pct_remove + pct_create)) {
+ retval = auto_lookup(ip);
+ } else if (op > pct_remove) {
+ retval = auto_create(ip);
+ } else {
+ retval = auto_remove(ip);
+ }
+
+ /* output '.' every DOT_COUNT ops
+ * and output '\n" every 72 dots
+ */
+ if ((i % DOT_COUNT) == 0) {
+ if (linedots++ == 72) {
+ linedots = 0;
+ write(1, "\n", 1);
+ }
+ write(1, ".", 1);
+ fflush(stdout);
+ }
+ }
+ printf("\n");
+
+ printf("creates: %6d OK, %6d EEXIST (%6d total, %2d%% EEXIST)\n",
+ good_adds, bad_adds, good_adds + bad_adds,
+ (good_adds+bad_adds)
+ ? (bad_adds*100) / (good_adds+bad_adds)
+ : 0);
+ printf("removes: %6d OK, %6d ENOENT (%6d total, %2d%% ENOENT)\n",
+ good_rms, bad_rms, good_rms + bad_rms,
+ (good_rms+bad_rms)
+ ? (bad_rms*100) / (good_rms+bad_rms)
+ : 0);
+ printf("lookups: %6d OK, %6d ENOENT (%6d total, %2d%% ENOENT)\n",
+ good_looks, bad_looks, good_looks + bad_looks,
+ (good_looks+bad_looks)
+ ? (bad_looks*100) / (good_looks+bad_looks)
+ : 0);
+ good_tot = good_looks + good_adds + good_rms;
+ bad_tot = bad_looks + bad_adds + bad_rms;
+ printf("total : %6d OK, %6d w/error (%6d total, %2d%% w/error)\n",
+ good_tot, bad_tot, good_tot + bad_tot,
+ (good_tot + bad_tot)
+ ? (bad_tot*100) / (good_tot+bad_tot)
+ : 0);
+
+ /*
+ * If asked to clear the directory out after the run,
+ * remove everything that is left.
+ */
+ if (zeroout) {
+ good_rms = 0;
+ for (ip = table, i = 0; i < totalnames; ip++, i++) {
+ if (!ip->exists)
+ continue;
+ good_rms++;
+ retval = unlink(ip->name);
+ if (retval < 0) {
+ if (errno == ENOENT) {
+ printf("\"%s\"(%lu) not removed, should have existed\n",
+ ip->name, ip->inumber);
+ } else {
+ printf("\"%s\"(%lu) on remove: ",
+ ip->name, ip->inumber);
+ perror("unlink");
+ }
+ }
+
+ if ((good_rms % DOT_COUNT) == 0) {
+ write(1, ".", 1);
+ fflush(stdout);
+ }
+ }
+ printf("\ncleanup: %6d removes\n", good_rms);
+ }
+ return 0;
+}
+
+int
+auto_lookup(struct info *ip)
+{
+ struct stat64 statb;
+ int retval;
+
+ retval = stat64(ip->name, &statb);
+ if (retval >= 0) {
+ good_looks++;
+ retval = 0;
+ if (ip->exists == 0) {
+ printf("\"%s\"(%lu) lookup, should not exist\n",
+ ip->name, statb.st_ino);
+ retval = 1;
+ } else if (ip->inumber != statb.st_ino) {
+ printf("\"%s\"(%lu) lookup, should be inumber %lu\n",
+ ip->name, statb.st_ino, ip->inumber);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) lookup ok\n",
+ ip->name, statb.st_ino);
+ }
+ } else if (errno == ENOENT) {
+ bad_looks++;
+ retval = 0;
+ if (ip->exists == 1) {
+ printf("\"%s\"(%lu) lookup, should exist\n",
+ ip->name, ip->inumber);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) lookup ENOENT ok\n",
+ ip->name, ip->inumber);
+ }
+ } else {
+ retval = errno;
+ printf("\"%s\"(%lu) on lookup: ", ip->name, ip->inumber);
+ perror("stat64");
+ }
+ return(retval);
+}
+
+int
+auto_create(struct info *ip)
+{
+ struct stat64 statb;
+ int retval;
+
+ retval = open(ip->name, O_RDWR|O_EXCL|O_CREAT, 0666);
+ if (retval >= 0) {
+ close(retval);
+ good_adds++;
+ retval = 0;
+ if (stat64(ip->name, &statb) < 0) {
+ perror("stat64");
+ exit(1);
+ }
+ if (ip->exists == 1) {
+ printf("\"%s\"(%lu) created, but already existed as inumber %lu\n",
+ ip->name, statb.st_ino, ip->inumber);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) create new ok\n",
+ ip->name, statb.st_ino);
+ }
+ ip->exists = 1;
+ ip->inumber = statb.st_ino;
+ } else if (errno == EEXIST) {
+ bad_adds++;
+ retval = 0;
+ if (ip->exists == 0) {
+ if (stat64(ip->name, &statb) < 0) {
+ perror("stat64");
+ exit(1);
+ }
+ printf("\"%s\"(%lu) not created, should not exist\n",
+ ip->name, statb.st_ino);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) not created ok\n",
+ ip->name, ip->inumber);
+ }
+ ip->exists = 1;
+ } else {
+ retval = errno;
+ printf("\"%s\"(%lu) on create: ", ip->name, ip->inumber);
+ perror("creat");
+ }
+ return(retval);
+}
+
+int
+auto_remove(struct info *ip)
+{
+ int retval;
+
+ retval = unlink(ip->name);
+ if (retval >= 0) {
+ good_rms++;
+ retval = 0;
+ if (ip->exists == 0) {
+ printf("\"%s\"(%lu) removed, should not have existed\n",
+ ip->name, ip->inumber);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) remove ok\n",
+ ip->name, ip->inumber);
+ }
+ ip->exists = 0;
+ ip->inumber = 0;
+ } else if (errno == ENOENT) {
+ bad_rms++;
+ retval = 0;
+ if (ip->exists == 1) {
+ printf("\"%s\"(%lu) not removed, should have existed\n",
+ ip->name, ip->inumber);
+ retval = 1;
+ } else if (verbose) {
+ printf("\"%s\"(%lu) not removed ok\n",
+ ip->name, ip->inumber);
+ }
+ ip->exists = 0;
+ } else {
+ retval = errno;
+ printf("\"%s\"(%lu) on remove: ", ip->name, ip->inumber);
+ perror("unlink");
+ }
+ return(retval);
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+char *alpha;
+int asize = 1;
+int asplit;
+char *buf;
+int dflag;
+int len = 1;
+int nproc = 1;
+int nflag;
+int vflag;
+int pid;
+
+void mkf(int idx, int p);
+
+int
+main(int argc, char **argv)
+{
+ int a;
+ int stat;
+ long long tot;
+ int usage=0;
+ char * argv0=argv[0];
+
+ argc--;
+ argv++;
+ pid=getpid();
+
+ if (!argc) usage++;
+ while (argc) {
+ if (strcmp(*argv, "-c") == 0) {
+ argc--;
+ argv++;
+ asize = atoi(*argv);
+ if (asize > 64 || asize < 1) {
+ fprintf(stderr, "bad alpha size %s\n", *argv);
+ return 1;
+ }
+ } else if (strcmp(*argv, "-d") == 0) {
+ dflag = 1;
+ } else if (strcmp(*argv, "-l") == 0) {
+ argc--;
+ argv++;
+ len = atoi(*argv);
+ if (len < 1) {
+ fprintf(stderr, "bad name length %s\n", *argv);
+ return 1;
+ }
+ } else if (strcmp(*argv, "-p") == 0) {
+ argc--;
+ argv++;
+ nproc = atoi(*argv);
+ if (nproc < 1) {
+ fprintf(stderr, "bad process count %s\n",
+ *argv);
+ return 1;
+ }
+ } else if (strcmp(*argv, "-n") == 0) {
+ nflag = 1;
+ } else if (strcmp(*argv, "-v") == 0) {
+ vflag = 1;
+ } else if (strcmp(*argv, "-h") == 0) {
+ usage++;
+ } else {
+ fprintf(stderr,"unknown switch \"%s\"\n", *argv);
+ usage++;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (usage) {
+ fprintf(stderr,"permname: usage %s [-c alpha size] [-l name length] "
+ "[-p proc count] [-n] [-v] [-d] [-h]\n", argv0);
+ fprintf(stderr," -n : don't actually perform action\n");
+ fprintf(stderr," -v : be verbose\n");
+ fprintf(stderr," -d : create directories, not files\n");
+ exit(1);
+ }
+
+ if (asize % nproc) {
+ fprintf(stderr,
+ "alphabet size must be multiple of process count\n");
+ return 1;
+ }
+ asplit = asize / nproc;
+ alpha = malloc(asize + 1);
+ buf = malloc(len + 1);
+ for (a = 0, tot = 1; a < len; a++)
+ tot *= asize;
+ if (vflag) fprintf(stderr,"[%d] ",pid);
+ fprintf(stderr,
+ "alpha size = %d, name length = %d, total files = %lld, nproc=%d\n",
+ asize, len, tot, nproc);
+ fflush(stderr);
+ for (a = 0; a < asize; a++) {
+ if (a < 26)
+ alpha[a] = 'a' + a;
+ else if (a < 52)
+ alpha[a] = 'A' + a - 26;
+ else if (a < 62)
+ alpha[a] = '0' + a - 52;
+ else if (a == 62)
+ alpha[62] = '_';
+ else if (a == 63)
+ alpha[63] = '@';
+ }
+ for (a = 0; a < nproc; a++) {
+ int r=fork();
+ if (r<0) {
+ perror("fork");
+ exit(1);
+ }
+ if (!r) {
+ pid=getpid();
+ mkf(0, a);
+ return 0;
+ }
+ }
+ while (1) {
+ int r=wait(&stat);
+ if (r<0) {
+ if (errno==ECHILD) break;
+ perror("wait");
+ exit(1);
+ }
+ if (!r) break;
+ }
+
+ return 0;
+}
+
+void
+mkf(int idx, int p)
+{
+ int i;
+ int last;
+
+ last = (idx == len - 1);
+ if (last) {
+ buf[len] = '\0';
+ for (i = p * asplit; i < (p + 1) * asplit; i++) {
+ buf[idx] = alpha[i];
+
+ if (dflag) {
+ if (vflag) printf("[%d] mkdir %s\n", pid, buf);
+ if (!nflag) {
+ if (mkdir(buf, 0777)<0) {
+ perror("mkdir");
+ exit(1);
+ }
+ }
+ } else {
+ if (vflag) printf("[%d] touch %s\n", pid, buf);
+ if (!nflag) {
+ int f=creat(buf, 0666);
+ if (f<0) {
+ perror("creat");
+ exit(1);
+ }
+ if (close(f)) {
+ perror("close");
+ exit(1);
+ }
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < asize; i++) {
+ buf[idx] = alpha[i];
+ mkf(idx + 1, p);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+unsigned char *valid; /* Bit-vector array showing which blocks have been written */
+int nvalid; /* number of bytes in valid array */
+#define SETBIT(ARRAY, N) ((ARRAY)[(N)/8] |= (1 << ((N)%8)))
+#define BITVAL(ARRAY, N) ((ARRAY)[(N)/8] & (1 << ((N)%8)))
+
+off64_t filesize;
+int blocksize;
+int count;
+int verbose;
+int wsync;
+int direct;
+int alloconly;
+int rt;
+int extsize;
+int preserve;
+int test;
+off64_t fileoffset;
+struct dioattr diob;
+struct fsxattr rtattr;
+
+#define READ_XFER 10 /* block to read at a time when checking */
+
+void usage(char *progname);
+int findblock(void);
+void writeblks(int fd);
+int readblks(int fd);
+void dumpblock(int *buffer, off64_t offset, int blocksize);
+
+void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-c count] [-o write offset] [-s seed] [-x extentsize] [-w] [-v] [-d] [-r] [-a] [-p] filename\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int seed, ch, fd, oflags;
+ char *filename;
+ int r;
+
+ filesize = ((off64_t)256)*1024*1024;
+ blocksize = 512;
+ count = filesize/blocksize;
+ verbose = 0;
+ wsync = 0;
+ seed = time(NULL);
+ test = 0;
+ while ((ch = getopt(argc, argv, "b:l:s:c:o:x:vwdrapt")) != EOF) {
+ switch(ch) {
+ case 'b': blocksize = atoi(optarg); break;
+ case 'l': filesize = strtoll(optarg, NULL, 16); break;
+ case 's': seed = atoi(optarg); break;
+ case 'c': count = atoi(optarg); break;
+ case 'o': fileoffset = strtoll(optarg, NULL, 16); break;
+ case 'x': extsize = atoi(optarg); break;
+ case 'v': verbose++; break;
+ case 'w': wsync++; break;
+ case 'd': direct++; break;
+ case 'r': rt++; break;
+ case 'a': alloconly++; break;
+ case 'p': preserve++; break;
+ case 't': test++; preserve++; break;
+ default: usage(argv[0]); break;
+ }
+ }
+ if (optind == argc-1)
+ filename = argv[optind];
+ else
+ usage(argv[0]);
+ if ((filesize % blocksize) != 0) {
+ filesize -= filesize % blocksize;
+ printf("filesize not a multiple of blocksize, reducing filesize to %lld\n",
+ filesize);
+ }
+ if ((fileoffset % blocksize) != 0) {
+ fileoffset -= fileoffset % blocksize;
+ printf("fileoffset not a multiple of blocksize, reducing fileoffset to %lld\n",
+ fileoffset);
+ }
+ if (count > (filesize/blocksize)) {
+ count = (filesize/blocksize);
+ printf("count of blocks written is too large, setting to %d\n",
+ count);
+ } else if (count < 1) {
+ count = 1;
+ printf("count of blocks written is too small, setting to %d\n",
+ count);
+ }
+ printf("randholes: Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed);
+ srandom(seed);
+
+ printf("randholes: blocksize=%d, filesize=%Ld, seed=%d\n"
+ "randholes: count=%d, offset=%Ld, extsize=%d\n",
+ blocksize, filesize, seed, count, fileoffset, extsize);
+ printf("randholes: verbose=%d, wsync=%d, direct=%d, rt=%d, alloconly=%d, preserve=%d, test=%d\n",
+ verbose, wsync, direct, rt, alloconly, preserve, test);
+
+ /*
+ * Open the file, write rand block in random places, read them all
+ * back to check for correctness, then close the file.
+ */
+ nvalid = (filesize / blocksize) / 8 + 1;
+ if ((valid = (unsigned char *)calloc(1, (unsigned)nvalid)) == NULL) {
+ perror("malloc");
+ return 1;
+ }
+ if (rt)
+ direct++;
+
+ oflags=test?(O_RDONLY):(O_RDWR | O_CREAT);
+ oflags |= (preserve ? 0 : O_TRUNC) |
+ (wsync ? O_SYNC : 0) |
+ (direct ? O_DIRECT : 0);
+
+ if ((fd = open(filename, oflags, 0666)) < 0) {
+ perror("open");
+ return 1;
+ }
+ if (rt) {
+ if (ioctl(fd, XFS_IOC_FSGETXATTR, &rtattr) < 0) {
+ perror("ioctl(XFS_IOC_FSGETXATTR)");
+ return 1;
+ }
+ if ((rtattr.fsx_xflags & XFS_XFLAG_REALTIME) == 0 ||
+ (extsize && rtattr.fsx_extsize != extsize * blocksize)) {
+ rtattr.fsx_xflags |= XFS_XFLAG_REALTIME;
+ if (extsize)
+ rtattr.fsx_extsize = extsize * blocksize;
+ if (ioctl(fd, XFS_IOC_FSSETXATTR, &rtattr) < 0) {
+ perror("ioctl(XFS_IOC_FSSETXATTR)");
+ return 1;
+ }
+ }
+ }
+ if (direct) {
+ if (ioctl(fd, XFS_IOC_DIOINFO, &diob) < 0) {
+ perror("ioctl(XFS_IOC_FIOINFO)");
+ return 1;
+ }
+ if (blocksize % diob.d_miniosz) {
+ fprintf(stderr, "blocksize %d must be a multiple of %d for direct I/O\n", blocksize, diob.d_miniosz);
+ return 1;
+ }
+ }
+ printf(test?"write (skipped)\n":"write\n");
+ writeblks(fd);
+ printf("readback\n");
+ r=readblks(fd);
+ if (close(fd) < 0) {
+ perror("close");
+ return 1;
+ }
+ free(valid);
+
+ if (r) {
+ printf("randholes: %d errors found during readback\n", r);
+ return 2;
+ } else {
+ printf("randholes: ok\n");
+ return 0;
+ }
+}
+
+void
+writeblks(int fd)
+{
+ off64_t offset;
+ char *buffer;
+ int block;
+ struct flock64 fl;
+
+ if (direct)
+ buffer = memalign(diob.d_mem, blocksize);
+ else
+ buffer = malloc(blocksize);
+ if (buffer == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(buffer, 0, blocksize);
+
+ for ( ; count > 0; count--) {
+ if (verbose && ((count % 100) == 0)) {
+ printf(".");
+ fflush(stdout);
+ }
+ block = findblock();
+ offset = (off64_t)block * blocksize;
+ if (alloconly) {
+ if (test) continue;
+
+ fl.l_start = offset;
+ fl.l_len = blocksize;
+ fl.l_whence = 0;
+ if (ioctl(fd, XFS_IOC_RESVSP64, &fl) < 0) {
+ perror("ioctl(XFS_IOC_RESVSP64)");
+ exit(1);
+ }
+ continue;
+ }
+ SETBIT(valid, block);
+ if (!test) {
+ if (lseek64(fd, fileoffset + offset, SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ }
+ *(off64_t *)buffer = *(off64_t *)(buffer+256) =
+ fileoffset + offset;
+ if (!test) {
+ if (write(fd, buffer, blocksize) < blocksize) {
+ perror("write");
+ exit(1);
+ }
+ }
+ if (test && verbose>1) printf("NOT ");
+ if (verbose > 1) {
+ printf("writing data at offset=%llx, value 0x%llx and 0x%llx\n",
+ fileoffset + offset,
+ *(off64_t *)buffer, *(off64_t *)(buffer+256));
+ }
+ }
+
+ free(buffer);
+}
+
+int
+readblks(int fd)
+{
+ long offset;
+ char *buffer, *tmp;
+ int xfer, block, i;
+ int err=0;
+
+ if (alloconly)
+ return 0;
+ xfer = READ_XFER*blocksize;
+ if (direct)
+ buffer = memalign(diob.d_mem, xfer);
+ else
+ buffer = malloc(xfer);
+ if (buffer == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(buffer, 0, xfer);
+ if (verbose)
+ printf("\n");
+
+ if (lseek64(fd, fileoffset, SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ for (offset = 0, block = 0; offset < filesize; offset += xfer) {
+ if ((i = read(fd, buffer, xfer) < xfer)) {
+ if (i < 2)
+ break;
+ perror("read");
+ exit(1);
+ }
+ for (tmp = buffer, i = 0; i < READ_XFER; i++, block++, tmp += blocksize) {
+ if (verbose && ((block % 100) == 0)) {
+ printf("+");
+ fflush(stdout);
+ }
+ if (BITVAL(valid, block) == 0) {
+ if ((*(off64_t *)tmp != 0LL) ||
+ (*(off64_t *)(tmp+256) != 0LL)) {
+ printf("mismatched data at offset=%llx, expected 0x%llx, got 0x%llx and 0x%llx\n",
+ fileoffset + block * blocksize,
+ 0LL,
+ *(off64_t *)tmp,
+ *(off64_t *)(tmp+256));
+ err++;
+ }
+ } else {
+ if ( (*(off64_t *)tmp !=
+ fileoffset + block * blocksize) ||
+ (*(off64_t *)(tmp+256) !=
+ fileoffset + block * blocksize) ) {
+ printf("mismatched data at offset=%llx, expected 0x%llx, got 0x%llx and 0x%llx\n",
+ fileoffset + block * blocksize,
+ fileoffset + block * blocksize,
+ *(off64_t *)tmp,
+ *(off64_t *)(tmp+256));
+ err++;
+ }
+ }
+ if (verbose > 2) {
+ printf("block %d blocksize %d\n", block,
+ blocksize);
+ dumpblock((int *)tmp,
+ fileoffset + block * blocksize,
+ blocksize);
+ }
+ }
+ }
+ if (verbose)
+ printf("\n");
+
+ free(buffer);
+ return err;
+}
+
+int
+findblock(void)
+{
+ int block, numblocks;
+
+ numblocks = filesize / blocksize;
+ block = random() % numblocks;
+ if (BITVAL(valid, block) == 0)
+ return(block);
+
+ for ( ; BITVAL(valid, block) != 0; block++) {
+ if (block == (numblocks-1))
+ block = -1;
+ }
+ if (block == -1)
+ printf("returning block -1\n");
+ return(block);
+}
+
+void
+dumpblock(int *buffer, off64_t offset, int blocksize)
+{
+ int i;
+
+ for (i = 0; i < (blocksize / 16); i++) {
+ printf("%llx: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ offset, *buffer, *(buffer + 1), *(buffer + 2),
+ *(buffer + 3));
+ offset += 16;
+ buffer += 4;
+ }
+}
--- /dev/null
+/**************************************************************************
+ *
+ * random.c -- pseudo random number generator
+ * Copyright (C) 1994 Chris Wallace (csw@bruce.cs.monash.edu.au)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ **************************************************************************/
+
+
+/*
+ * modified by dxm@sgi.com so that this file acts as a drop in replacement
+ * for srandom and random.
+ */
+
+/*
+ * A random number generator called as a function by
+ * random (iseed) or irandm (iseed)
+ * The parameter should be a pointer to a 2-element long vector.
+ * The first function returns a double uniform in 0 .. 1.
+ * The second returns a long integer uniform in 0 .. 2**31-1
+ * Both update iseed[] in exactly the same way.
+ * iseed[] must be a 2-element integer vector.
+ * The initial value of the second element may be anything.
+ *
+ * The period of the random sequence is 2**32 * (2**32-1)
+ * The table mt[0:127] is defined by mt[i] = 69069 ** (128-i)
+ */
+
+#define MASK ((long) 593970775)
+/* or in hex, 23674657 */
+
+#define SCALE ((double) 1.0 / (1024.0 * 1024.0 * 1024.0 * 2.0))
+/* i.e. 2 to power -31 */
+
+static long mt [128] = {
+ 902906369,
+ 2030498053,
+ -473499623,
+ 1640834941,
+ 723406961,
+ 1993558325,
+ -257162999,
+ -1627724755,
+ 913952737,
+ 278845029,
+ 1327502073,
+ -1261253155,
+ 981676113,
+ -1785280363,
+ 1700077033,
+ 366908557,
+ -1514479167,
+ -682799163,
+ 141955545,
+ -830150595,
+ 317871153,
+ 1542036469,
+ -946413879,
+ -1950779155,
+ 985397153,
+ 626515237,
+ 530871481,
+ 783087261,
+ -1512358895,
+ 1031357269,
+ -2007710807,
+ -1652747955,
+ -1867214463,
+ 928251525,
+ 1243003801,
+ -2132510467,
+ 1874683889,
+ -717013323,
+ 218254473,
+ -1628774995,
+ -2064896159,
+ 69678053,
+ 281568889,
+ -2104168611,
+ -165128239,
+ 1536495125,
+ -39650967,
+ 546594317,
+ -725987007,
+ 1392966981,
+ 1044706649,
+ 687331773,
+ -2051306575,
+ 1544302965,
+ -758494647,
+ -1243934099,
+ -75073759,
+ 293132965,
+ -1935153095,
+ 118929437,
+ 807830417,
+ -1416222507,
+ -1550074071,
+ -84903219,
+ 1355292929,
+ -380482555,
+ -1818444007,
+ -204797315,
+ 170442609,
+ -1636797387,
+ 868931593,
+ -623503571,
+ 1711722209,
+ 381210981,
+ -161547783,
+ -272740131,
+ -1450066095,
+ 2116588437,
+ 1100682473,
+ 358442893,
+ -1529216831,
+ 2116152005,
+ -776333095,
+ 1265240893,
+ -482278607,
+ 1067190005,
+ 333444553,
+ 86502381,
+ 753481377,
+ 39000101,
+ 1779014585,
+ 219658653,
+ -920253679,
+ 2029538901,
+ 1207761577,
+ -1515772851,
+ -236195711,
+ 442620293,
+ 423166617,
+ -1763648515,
+ -398436623,
+ -1749358155,
+ -538598519,
+ -652439379,
+ 430550625,
+ -1481396507,
+ 2093206905,
+ -1934691747,
+ -962631983,
+ 1454463253,
+ -1877118871,
+ -291917555,
+ -1711673279,
+ 201201733,
+ -474645415,
+ -96764739,
+ -1587365199,
+ 1945705589,
+ 1303896393,
+ 1744831853,
+ 381957665,
+ 2135332261,
+ -55996615,
+ -1190135011,
+ 1790562961,
+ -1493191723,
+ 475559465,
+ 69069
+ };
+
+double
+_random (long is [2])
+{
+ long it, leh, nit;
+
+ it = is [0];
+ leh = is [1];
+ if (it <= 0)
+ it = (it + it) ^ MASK;
+ else
+ it = it + it;
+ nit = it - 1;
+/* to ensure all-ones pattern omitted */
+ leh = leh * mt[nit & 127] + nit;
+ is [0] = it; is [1] = leh;
+ if (leh < 0) leh = ~leh;
+ return (SCALE * ((long) (leh | 1)));
+}
+
+
+
+long
+_irandm (long is [2])
+{
+ long it, leh, nit;
+
+ it = is [0];
+ leh = is [1];
+ if (it <= 0)
+ it = (it + it) ^ MASK;
+ else
+ it = it + it;
+ nit = it - 1;
+/* to ensure all-ones pattern omitted */
+ leh = leh * mt[nit & 127] + nit;
+ is [0] = it; is [1] = leh;
+ if (leh < 0) leh = ~leh;
+ return (leh);
+}
+
+/*
+ * make this a drop in replacement for random and srandom
+ *
+ * XXX not thread safe I guess.
+ */
+
+static long saved_seed[2];
+
+long random(void)
+{
+ return _irandm(saved_seed);
+}
+
+void srandom(unsigned seed)
+{
+ saved_seed[0]=seed;
+ saved_seed[1]=0;
+ _irandm(saved_seed);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+/*
+ * Run a command with a particular
+ * - effective user id
+ * - effective group id
+ * - supplementary group list
+ */
+
+#include "global.h"
+#include <grp.h>
+
+
+
+char *prog;
+
+void usage(void)
+{
+ fprintf(stderr, "usage: %s [-u uid] [-g gid] [-s gid] cmd\n"
+ "flags:\n"
+ " -u - effective user-id\n"
+ " -g - effective group-id\n"
+ " -s - supplementary group-id\n", prog);
+
+}
+
+#define SUP_MAX 20
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ uid_t uid = -1;
+ gid_t gid = -1;
+ char *cmd=NULL;
+ gid_t sgids[SUP_MAX];
+ int sup_cnt = 0;
+ int status;
+
+ prog = basename(argv[0]);
+
+ while ((c = getopt(argc, argv, "u:g:s:")) != -1) {
+ switch (c) {
+ case 'u':
+ uid = atoi(optarg);
+ break;
+ case 'g':
+ gid = atoi(optarg);
+ break;
+ case 's':
+ if (sup_cnt+1 > SUP_MAX) {
+ fprintf(stderr, "%s: too many sup groups\n", prog);
+ exit(1);
+ }
+ sgids[sup_cnt++] = atoi(optarg);
+ break;
+ case '?':
+ usage();
+ exit(1);
+ }
+ }
+
+ /* build up the cmd */
+ for ( ; optind < argc; optind++) {
+ cmd = realloc(cmd, (cmd==NULL?0:strlen(cmd)) +
+ strlen(argv[optind]) + 4);
+ strcat(cmd, " ");
+ strcat(cmd, argv[optind]);
+ }
+
+
+ if (gid != -1) {
+ if (setegid(gid) == -1) {
+ fprintf(stderr, "%s: setegid(%d) failed: %s\n",
+ prog, gid, strerror(errno));
+ exit(1);
+ }
+ }
+
+ if (sup_cnt > 0) {
+ if (setgroups(sup_cnt, sgids) == -1) {
+ fprintf(stderr, "%s: setgroups() failed: %s\n",
+ prog, strerror(errno));
+ exit(1);
+ }
+ }
+
+ if (uid != -1) {
+ if (seteuid(uid) == -1) {
+ fprintf(stderr, "%s: seteuid(%d) failed: %s\n",
+ prog, uid, strerror(errno));
+ exit(1);
+ }
+ }
+
+ status = system(cmd);
+
+ if (WIFSIGNALED(status)) {
+ fprintf(stderr, "%s: command terminated with signal %d\n",
+ prog, WTERMSIG(status));
+ exit(1);
+ }
+ else if (WIFEXITED(status)) {
+ exit(WEXITSTATUS(status));
+ }
+ else {
+ fprintf(stderr, "%s: command bizarre wait status 0x%x\n",
+ prog, status);
+ exit(1);
+ }
+
+ exit(0);
+ /* NOTREACHED */
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include "global.h"
+
+long filesize;
+int blocksize;
+int count;
+int verbose;
+off64_t fileoffset;
+
+void usage(char *progname);
+void writeblk(int fd);
+void truncfile(int fd);
+
+void
+usage(char *progname)
+{
+ fprintf(stderr, "usage: %s [-l filesize] [-b blocksize] [-c count] [-s seed] [-o fileoffset (hex)] [-v] filename\n",
+ progname);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int seed, i, ch, fd;
+ char *filename;
+
+ filesize = 256*1024*1024;
+ blocksize = 512;
+ count = filesize/blocksize;
+ verbose = 0;
+ fileoffset = 0;
+ seed = time(NULL);
+ while ((ch = getopt(argc, argv, "b:l:s:c:o:v")) != EOF) {
+ switch(ch) {
+ case 'b': blocksize = atoi(optarg); break;
+ case 'l': filesize = atol(optarg); break;
+ case 's': seed = atoi(optarg); break;
+ case 'c': count = atoi(optarg); break;
+ case 'o': fileoffset = strtoll(optarg, NULL, 16); break;
+ case 'v': verbose++; break;
+ default: usage(argv[0]); break;
+ }
+ }
+ if (optind == argc-1)
+ filename = argv[optind];
+ else
+ usage(argv[0]);
+ printf("Seed = %d (use \"-s %d\" to re-execute this test)\n", seed, seed);
+ srandom(seed);
+
+ /*
+ * Open the file, write rand block in random places, truncate the file,
+ * repeat ad-nauseum, then close the file.
+ */
+ if ((fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
+ perror("open");
+ return 1;
+ }
+ for (i = 0; i < count; i++) {
+ writeblk(fd);
+ truncfile(fd);
+ if (verbose && ((i % 100) == 0)) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+ if (close(fd) < 0) {
+ perror("close");
+ return 1;
+ }
+ return 0;
+}
+
+void
+writeblk(int fd)
+{
+ off_t offset;
+ static char *buffer = NULL;
+
+ if ((buffer == NULL) && ((buffer = calloc(1, blocksize)) == NULL)) {
+ perror("malloc");
+ exit(1);
+ }
+
+ offset = random() % filesize;
+ if (lseek64(fd, (off64_t)(fileoffset + offset), SEEK_SET) < 0) {
+ perror("lseek");
+ exit(1);
+ }
+ *(long *)buffer = *(long *)(buffer+256) = (long)offset;
+ if (write(fd, buffer, blocksize) < blocksize) {
+ perror("write");
+ exit(1);
+ }
+ if (verbose > 1)
+ printf("writing data at offset=%llx\n",
+ (fileoffset + offset));
+}
+
+void
+truncfile(int fd)
+{
+ off_t offset;
+
+ offset = random() % filesize;
+ if (ftruncate64(fd, (off64_t)(fileoffset + offset)) < 0) {
+ perror("truncate");
+ exit(1);
+ }
+ if (verbose > 1)
+ printf("truncated file to offset %llx\n",
+ (fileoffset + offset));
+}
--- /dev/null
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like. Any license provided herein, whether implied or
+ * otherwise, applies only to this software file. Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA 94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+/*
+ *
+ * usemem: allocate and lock a chunk of memory effectively removing
+ * it from the usable physical memory range
+ *
+ * - dxm 04/10/00
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+
+void
+usage(char *argv0)
+{
+ fprintf(stderr,"Usage: %s <mb>\n", argv0);
+ exit(1);
+}
+
+static void
+signalled(int sig)
+{
+ printf("*** signal\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int mb;
+ char *buf;
+
+ if (argc!=2) usage(argv[0]);
+ mb=atoi(argv[1]);
+ if (mb<=0) usage(argv[0]);
+
+ buf=malloc(mb*1024*1024);
+ if (!buf) {
+ perror("malloc");
+ exit(1);
+ }
+ if (mlock(buf,mb*1024*1024)) {
+ perror("mlock");
+ exit(1);
+ }
+
+ printf("%s: %d mb locked - interrupt to release\n", argv[0], mb);
+ signal(SIGINT, signalled);
+ pause();
+ printf("%s: %d mb unlocked\n", argv[0], mb);
+
+ return 0;
+}
+
+