| #! /bin/bash | |
| # FS QA Test No. 114 | |
| # | |
| # Test some parent ptr stuff | |
| # | |
| #----------------------------------------------------------------------- | |
| # Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved. | |
| # | |
| # 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. | |
| # | |
| # 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. 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 the Free Software Foundation, | |
| # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| # | |
| #----------------------------------------------------------------------- | |
| # | |
| # creator | |
| owner=tes@crackle.melbourne.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() | |
| { | |
| cd / | |
| rm -f $tmp.* | |
| } | |
| _check_paths() | |
| { | |
| _path=$1 # might want to only check this path | |
| sync; sleep 1 | |
| echo "" | |
| echo "Check parent" | |
| if ! xfs_io -x -c 'parent -c' $SCRATCH_MNT | _filter_num; then | |
| exit 1 | |
| fi | |
| } | |
| _print_names() | |
| { | |
| echo "" | |
| echo "Print out hardlink names for given path, $1" | |
| echo "" | |
| xfs_io -x -c parent $1 | awk '/p_ino.*=/ {$3 = "inodeXXX"; print; next} {print}' | |
| } | |
| _test_create() | |
| { | |
| echo "" | |
| echo "Testing create" | |
| echo "" | |
| # Test out some creations | |
| cd $SCRATCH_MNT | |
| touch file1 | |
| mkdir dir2 | |
| touch dir2/file2 | |
| mkdir dir2/dir3 | |
| touch dir2/dir3/file3 | |
| mkdir dir2/dir3/dir4 | |
| p=dir2/dir3/dir4/file4 | |
| touch $p | |
| #_print_names $p >>$here/$seq.full | |
| _print_names $p | tee -a $here/$seq.full | |
| _check_paths $SCRATCH_MNT/$p | |
| } | |
| _test_symlink() | |
| { | |
| echo "" | |
| echo "Testing symlink" | |
| echo "" | |
| d=sym1/sym2/sym3 | |
| f=$d/sym4_f | |
| mkdir -p $d | |
| ln -s $f symlink1 | |
| ln symlink1 hlink1 | |
| ln symlink1 hlink2 | |
| ln symlink1 hlink3 | |
| _check_paths $SCRATCH_MNT/symlink1 | |
| _check_paths $SCRATCH_MNT/hlink1 | |
| _check_paths $SCRATCH_MNT/hlink2 | |
| _check_paths $SCRATCH_MNT/hlink3 | |
| } | |
| # | |
| # create hardlinks from the same dir | |
| # and some from different dirs | |
| # | |
| # test out removing hardlinks too | |
| # | |
| _test_hardlink() | |
| { | |
| echo "" | |
| echo "Testing hardlink" | |
| echo "" | |
| d=dir2/dir3/dir4 | |
| d2=dir2/dir5/dir6 | |
| mkdir -p $d | |
| mkdir -p $d2 | |
| p=$d/file4 | |
| touch $p | |
| # create hardlinks | |
| paths="$d/l1 $d/l2 $d/l3 $d2/l4 $d2/l5 $d2/l6" | |
| for x in $paths; do | |
| ln $p $x | |
| done | |
| _print_names $p >>$here/$seq.full | |
| echo "" | |
| echo "print out names and check after created hardlinks" | |
| echo "" | |
| for x in $paths; do | |
| _print_names $x | tee -a $here/$seq.full | |
| _check_paths $SCRATCH_MNT/$x | |
| done | |
| echo "" | |
| echo "now try removing half of the hardlinks" | |
| echo "" | |
| paths="$d/l1 $d/l2 $d/l3 $d2/l4 $d2/l5 $d2/l6" | |
| i=0 | |
| for x in $paths; do | |
| let i=$i+1 | |
| let j=$i%2 | |
| if [ $j -eq 0 ]; then | |
| echo "rm'ing $x" | |
| rm $x | |
| fi | |
| done | |
| echo "" | |
| echo "print out names and check after removed hardlinks" | |
| echo "" | |
| for x in $paths; do | |
| if [ -e $x ]; then | |
| _print_names $x | tee -a $here/$seq.full | |
| _check_paths $SCRATCH_MNT/$x | |
| fi | |
| done | |
| } | |
| # | |
| # in dir, file1 to file2 where file2 does not exist | |
| # in dir, file1 to file2 where file2 does exist | |
| # dir/file1 to dir2/file2 where file2 does not exist | |
| # dir/file1 to dir2/file2 where file2 does exist | |
| # dir to dir2 where dir2 does not exist | |
| # dir to dir/dir3 - not allowed | |
| # | |
| # | |
| _test_rename() | |
| { | |
| echo "" | |
| echo "Testing rename" | |
| echo "" | |
| echo "" | |
| echo "1. in dir, file1 to file2 where file2 does not exist" | |
| echo "" | |
| d1=$SCRATCH_MNT/ren1/ren2/ren3/ren4 | |
| mkdir -p $d1 | |
| p1=$d1/f1 | |
| p2=$d1/f2 | |
| touch $p1 | |
| mv $p1 $p2 | |
| _check_paths $p2 | |
| echo "" | |
| echo "2. in dir, file1 to file2 where file2 does exist" | |
| echo "" | |
| touch $p1 | |
| mv $p1 $p2 | |
| _check_paths $p2 | |
| echo "" | |
| echo "3. dir/file1 to dir2/file2 where file2 does not exist" | |
| echo "" | |
| d2=$SCRATCH_MNT/ren1/ren2/ren3/ren5 | |
| mkdir -p $d2 | |
| p3=$d2/f3 | |
| touch $p1 | |
| mv $p1 $p3 | |
| _check_paths $p3 | |
| echo "" | |
| echo "4. dir/file1 to dir2/file2 where file2 does exist" | |
| echo "" | |
| d2=$SCRATCH_MNT/ren1/ren2/ren3/ren5 | |
| p3=$d2/f3 | |
| touch $p1 | |
| mv $p1 $p3 | |
| _check_paths $p3 | |
| echo "" | |
| echo "5. dir to dir2 where dir2 does not exist" | |
| echo "" | |
| d3=$SCRATCH_MNT/ren1/ren2/ren3/ren6 | |
| mv $d1 $d3 | |
| _check_paths $d3 | |
| } | |
| _filter_num() | |
| { | |
| tee -a $here/$seq.full |\ | |
| sed -e 's/[0-9][0-9]* inodes/I inodes/g' \ | |
| -e 's/[0-9][0-9]* paths/P paths/g' \ | |
| -e 's/seed = [0-9][0-9]*/seed = S/' | |
| } | |
| _test_fsstress() | |
| { | |
| echo "" | |
| echo "Testing fsstress" | |
| echo "" | |
| out=$SCRATCH_MNT/fsstress.$$ | |
| count=1000 | |
| args="-z \ | |
| -f rmdir=10 -f link=10 -f creat=10 \ | |
| -f mkdir=10 -f rename=30 -f unlink=10 \ | |
| -f symlink=10 \ | |
| -n $count -d $out -p 3" | |
| echo "fsstress $args" | sed -e "s#$out#outdir#" | |
| if ! $FSSTRESS_PROG $args | _filter_num | |
| then | |
| echo " fsstress $args returned $?" | |
| cat $tmp.out | tee -a $here/$seq.full | |
| status=1 | |
| fi | |
| _check_paths | |
| } | |
| _test_dirstress() | |
| { | |
| echo "" | |
| echo "Testing dirstress" | |
| echo "" | |
| out=$SCRATCH_MNT/dirstress.$$ | |
| count=1000 | |
| if ! mkdir $out | |
| then | |
| echo "!! couldn't mkdir $out" | |
| status=1 | |
| exit | |
| fi | |
| args="-d $out -f $count -k -p 3 -n 1" | |
| echo "dirstress $args" | sed -e "s#$out#outdir#" | |
| if ! $here/src/dirstress $args >$tmp.out 2>&1 | _filter_num | |
| then | |
| echo " dirstress failed" | |
| echo "*** dirstress $args" | tee -a $here/$seq.full | |
| cat $tmp.out >>$here/$seq.full | |
| status=1 | |
| exit | |
| fi | |
| args="-d $out -f $count -k -p 3 -n 5" | |
| echo "dirstress $args" | sed -e "s#$out#outdir#" | |
| if ! $here/src/dirstress $args >$tmp.out 2>&1 | _filter_num | |
| then | |
| echo " dirstress failed" | |
| echo "*** dirstress $args" | tee -a $here/$seq.full | |
| cat $tmp.out >>$here/$seq.full | |
| status=1 | |
| exit | |
| fi | |
| _check_paths | |
| } | |
| # get standard environment, filters and checks | |
| . ./common.rc | |
| . ./common.filter | |
| . ./common.attr | |
| _supported_fs xfs | |
| _supported_os IRIX | |
| _require_scratch | |
| _require_attrs | |
| _need_to_be_root | |
| rm -f $here/$seq.full | |
| echo "mkfs" | |
| _scratch_mkfs_xfs >>$here/$seq.full 2>&1 \ | |
| || _fail "mkfs scratch failed" | |
| _scratch_mkfs_xfs -i parent=1 >>$here/$seq.full 2>&1 \ | |
| || _notrun "parent inodes not supported" | |
| echo "mount" | |
| _scratch_mount >>$here/$seq.full 2>&1 \ | |
| || _fail "mount failed: $MOUNT_OPTIONS" | |
| # real QA test starts here | |
| verbose=false | |
| _test_create | |
| _test_hardlink | |
| _test_rename | |
| _test_symlink | |
| # stress testing with verification by parent checking programs | |
| _test_fsstress | |
| _test_dirstress | |
| # success, all done | |
| status=0 | |
| exit |