[BACK]Return to 114 CVS log [TXT][DIR] Up to [Development] / xfs-cmds / xfstests

File: [Development] / xfs-cmds / xfstests / 114 (download)

Revision 1.3, Wed Nov 9 02:49:08 2005 UTC (11 years, 11 months ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
Changes since 1.2: +0 -28 lines

Update copyright annotations and license boilerplates to correspond with SGI Legals preferences.
Merge of master-melb:xfs-cmds:24327a by kenmcd.

#! /bin/sh
# FS QA Test No. 114
#
# Test some parent ptr stuff
#
#-----------------------------------------------------------------------
# Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
#-----------------------------------------------------------------------
#
# 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.*
}

# Example output:
#
# ~/attr -Fl a/b/c/d/foo
# Attribute "0000000000180080 0000000000000001" has a 3 byte value for a/b/c/d/foo
#
# ~/attr -Fg "0000000000180080 0000000000000001" a/b/c/d/foo
# Attribute "0000000000180080 0000000000000001" had a 3 byte value for a/b/c/d/foo:
# foo
#
# ~/attr -Pg "0000000000180080 0000000000000001" a/b/c/d/foo
# Attribute "0000000000180080 0000000000000001" had a 12 byte value for a/b/c/d/foo:
# /a/b/c/d/foo
#


_print_names()
{
	typeset path
	path=$1

	echo ""
	echo "Print out hardlink names for given path, $path"
	echo ""

	# get out the ea name
	attr -Fl $path | tee $tmp.attr1
	cat $tmp.attr1 |\
	sed -e 's/"//g' |\
	nawk >$tmp.attr2 '/^Attribute/ { print $2, $3; next }'

	while read ino cnt; do
		eaname="$ino $cnt"

		# use the ea name to get the filename value
		attr -Fg "$eaname" $path

		# use the ea name to get the pathname value
		attr -Pg "$eaname" $path
	done < $tmp.attr2
}

_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

	_check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/$p
}

_get_ea_fields()
{
	# get out the ea name components for all the hardlinks
	attr -Fl $1 |\
	tee -a $here/$seq.full |\
	sed -e 's/"//g' |\
	nawk '/^Attribute/ { print $2, $3; next }'
}

_parent_path()
{
	# given: abc/def/ghi/jkl
	# want:  abc/def/ghi
	child=$1
	parent=`echo $child | sed -e 's#/[^/]*$##'`

	# issue of path starting with '/' or not
        # relatives paths wouldn't and we need to handle this
	if [ $child = $parent ]; then
		echo ""
	else
		echo $parent
	fi
}

#
# Go thru each component of the hierarchy and compare 
# inode# from "stat -i" with the ino from the parent EA name
#
# So I need to be given a path and go thru compenent by component.
# e.g. a/b/c/d/e
# Need to look at: a a/b a/b/c a/b/c/d
#
# Also need to do this for all the hardlinks
#
_check_parentinos_path()
{
        mntpt=$1
	path=$2
	parent="$path"

        # representing all the hard links for a particular path

	_get_ea_fields $path |\
	while read parent_ino cnt; do

		while [ "$parent" != "$mntpt" ]; do
			# compare paths
			eaname="$parent_ino $cnt"
			eavalue=`attr -qPg "$eaname" $parent`
			parentrel=`echo $parent | sed -e "s#^$mntpt##"`
			if [ "$eavalue" = "$parentrel" ]; then
				echo "EA path $eavalue matches on path"
			else
				$verbose && echo "EA path mismatch on $parentrel: $eavalue"
				break # maybe wrong hardlink
			fi

			# compare parent_ino from ea-name with parent-ino from
			# actual parent dir using stat

			parent=`_parent_path $parent`
			parent_ino_dec=`printf "%d" 0x$parent_ino` # decimal version (not hex)
			stat_ino=`stat -iq $parent`

			if [ "$parent_ino_dec" = "$stat_ino" ]; then
				echo "parent ino $parent_ino_dec matches"
			else
				echo "parent ino mismatch on $parent: EA=$parent_ino_dec stat=$stat_ino"
			fi


			# go onto next subdir up the path
			line=`_get_ea_fields $parent`
			parent_ino=`echo $line | cut -f1 -d' '`  # 1st field
			cnt=`echo $line | cut -f2 -d' '`         # 2nd field
		done
	done
}

_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_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/symlink1
	_check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/hlink1
	_check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/hlink2
	_check_parentinos_path $SCRATCH_MNT $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_parentinos_path $SCRATCH_MNT $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
		i=`expr $i + 1`
		j=`expr $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 
echo "looking at $x"
			_print_names $x | tee -a $here/$seq.full
			_check_parentinos_path $SCRATCH_MNT $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_parentinos_path $SCRATCH_MNT $p2

	echo ""
	echo "2. in dir, file1 to file2 where file2 does exist" 
	echo ""
	touch $p1
	mv $p1 $p2
	_check_parentinos_path $SCRATCH_MNT $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_parentinos_path $SCRATCH_MNT $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_parentinos_path $SCRATCH_MNT $p3

	echo ""
	echo "5. dir to dir2 where dir2 does not exist"
	echo ""
	d3=$SCRATCH_MNT/ren1/ren2/ren3/ren6
	mv $d1 $d3
	_check_parentinos_path $SCRATCH_MNT $d3
}

_filter_num()
{
	tee -a $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 "ltp/fsstress $args" | sed -e "s#$out#outdir#"
	if ! $here/ltp/fsstress $args | _filter_num
	then
		echo "    fsstress $args returned $?"
		cat $tmp.out | tee -a $here/$seq.full
		status=1
	fi

	xfs_repair_ipaths -n $SCRATCH_MNT | _filter_num
	xfs_check_ipaths $SCRATCH_MNT | _filter_num
}


_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 "src/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 "src/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

	xfs_repair_ipaths -n $SCRATCH_MNT | _filter_num
	xfs_check_ipaths $SCRATCH_MNT | _filter_num
}

# get standard environment, filters and checks
. ./common.rc
. ./common.filter

_supported_fs xfs
_supported_os IRIX

_require_scratch

rm -f $here/$seq.full

echo "mkfs"
_scratch_mkfs_xfs >>$here/$seq.full 2>&1 \
    || _fail "mkfs scratch failed"
export MKFS_OPTIONS="$MKFS_OPTIONS -i paths=1"
_scratch_mkfs_xfs >>$here/$seq.full 2>&1 \
    || _notrun "i_paths not supported"

echo "mount"
_scratch_mount >>$here/$seq.full 2>&1 \
    || _fail "mount failed: $MOUNT_OPTIONS"

# real QA test starts here

verbose=false

# initial testing with scripting and modified attr(1)
# in order to test parent EAs
_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