mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
be529ae745
Merge of master-melb:xfs-cmds:23822a by kenmcd. paranoid testing that mkfs of scratch works without ipaths option
462 lines
9.9 KiB
Bash
Executable File
462 lines
9.9 KiB
Bash
Executable File
#! /bin/sh
|
|
# 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 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@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
|