Fix fsstress builds when setting the project identifier (fsx interface now).
[xfstests-dev.git] / 114
1 #! /bin/sh
2 # FS QA Test No. 114
3 #
4 # Test some parent ptr stuff
5 #
6 #-----------------------------------------------------------------------
7 # Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
8 #
9 # This program is free software; you can redistribute it and/or modify it
10 # under the terms of version 2 of the GNU General Public License as
11 # published by the Free Software Foundation.
12 #
13 # This program is distributed in the hope that it would be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 #
17 # Further, this software is distributed without any warranty that it is
18 # free of the rightful claim of any third person regarding infringement
19 # or the like.  Any license provided herein, whether implied or
20 # otherwise, applies only to this software file.  Patent licenses, if
21 # any, provided herein do not apply to combinations of this program with
22 # other software, or any other product whatsoever.
23 #
24 # You should have received a copy of the GNU General Public License along
25 # with this program; if not, write the Free Software Foundation, Inc., 59
26 # Temple Place - Suite 330, Boston MA 02111-1307, USA.
27 #
28 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
29 # Mountain View, CA  94043, or:
30 #
31 # http://www.sgi.com
32 #
33 # For further information regarding this notice, see:
34 #
35 # http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
36 #-----------------------------------------------------------------------
37 #
38 # creator
39 owner=tes@crackle.melbourne.sgi.com
40
41 seq=`basename $0`
42 echo "QA output created by $seq"
43
44 here=`pwd`
45 tmp=/tmp/$$
46 status=1        # failure is the default!
47 trap "_cleanup; exit \$status" 0 1 2 3 15
48
49 _cleanup()
50 {
51     cd /
52     rm -f $tmp.*
53 }
54
55 # Example output:
56 #
57 # ~/attr -Fl a/b/c/d/foo
58 # Attribute "0000000000180080 0000000000000001" has a 3 byte value for a/b/c/d/foo
59 #
60 # ~/attr -Fg "0000000000180080 0000000000000001" a/b/c/d/foo
61 # Attribute "0000000000180080 0000000000000001" had a 3 byte value for a/b/c/d/foo:
62 # foo
63 #
64 # ~/attr -Pg "0000000000180080 0000000000000001" a/b/c/d/foo
65 # Attribute "0000000000180080 0000000000000001" had a 12 byte value for a/b/c/d/foo:
66 # /a/b/c/d/foo
67 #
68
69
70 _print_names()
71 {
72         typeset path
73         path=$1
74
75         echo ""
76         echo "Print out hardlink names for given path, $path"
77         echo ""
78
79         # get out the ea name
80         attr -Fl $path | tee $tmp.attr1
81         cat $tmp.attr1 |\
82         sed -e 's/"//g' |\
83         nawk >$tmp.attr2 '/^Attribute/ { print $2, $3; next }'
84
85         while read ino cnt; do
86                 eaname="$ino $cnt"
87
88                 # use the ea name to get the filename value
89                 attr -Fg "$eaname" $path
90
91                 # use the ea name to get the pathname value
92                 attr -Pg "$eaname" $path
93         done < $tmp.attr2
94 }
95
96 _test_create()
97 {
98         echo ""
99         echo "Testing create"
100         echo ""
101
102         # Test out some creations
103         cd $SCRATCH_MNT
104         touch file1
105
106         mkdir dir2
107         touch dir2/file2
108
109         mkdir dir2/dir3
110         touch dir2/dir3/file3
111
112         mkdir dir2/dir3/dir4
113
114         p=dir2/dir3/dir4/file4
115         touch $p
116
117         _print_names $p >>$here/$seq.full
118
119         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/$p
120 }
121
122 _get_ea_fields()
123 {
124         # get out the ea name components for all the hardlinks
125         attr -Fl $1 |\
126         tee -a $here/$seq.full |\
127         sed -e 's/"//g' |\
128         nawk '/^Attribute/ { print $2, $3; next }'
129 }
130
131 _parent_path()
132 {
133         # given: abc/def/ghi/jkl
134         # want:  abc/def/ghi
135         child=$1
136         parent=`echo $child | sed -e 's#/[^/]*$##'`
137
138         # issue of path starting with '/' or not
139         # relatives paths wouldn't and we need to handle this
140         if [ $child = $parent ]; then
141                 echo ""
142         else
143                 echo $parent
144         fi
145 }
146
147 #
148 # Go thru each component of the hierarchy and compare 
149 # inode# from "stat -i" with the ino from the parent EA name
150 #
151 # So I need to be given a path and go thru compenent by component.
152 # e.g. a/b/c/d/e
153 # Need to look at: a a/b a/b/c a/b/c/d
154 #
155 # Also need to do this for all the hardlinks
156 #
157 _check_parentinos_path()
158 {
159         mntpt=$1
160         path=$2
161         parent="$path"
162
163         # representing all the hard links for a particular path
164
165         _get_ea_fields $path |\
166         while read parent_ino cnt; do
167
168                 while [ "$parent" != "$mntpt" ]; do
169                         # compare paths
170                         eaname="$parent_ino $cnt"
171                         eavalue=`attr -qPg "$eaname" $parent`
172                         parentrel=`echo $parent | sed -e "s#^$mntpt##"`
173                         if [ "$eavalue" = "$parentrel" ]; then
174                                 echo "EA path $eavalue matches on path"
175                         else
176                                 $verbose && echo "EA path mismatch on $parentrel: $eavalue"
177                                 break # maybe wrong hardlink
178                         fi
179
180                         # compare parent_ino from ea-name with parent-ino from
181                         # actual parent dir using stat
182
183                         parent=`_parent_path $parent`
184                         parent_ino_dec=`printf "%d" 0x$parent_ino` # decimal version (not hex)
185                         stat_ino=`stat -iq $parent`
186
187                         if [ "$parent_ino_dec" = "$stat_ino" ]; then
188                                 echo "parent ino $parent_ino_dec matches"
189                         else
190                                 echo "parent ino mismatch on $parent: EA=$parent_ino_dec stat=$stat_ino"
191                         fi
192
193
194                         # go onto next subdir up the path
195                         line=`_get_ea_fields $parent`
196                         parent_ino=`echo $line | cut -f1 -d' '`  # 1st field
197                         cnt=`echo $line | cut -f2 -d' '`         # 2nd field
198                 done
199         done
200 }
201
202 _test_symlink()
203 {
204         echo ""
205         echo "Testing symlink"
206         echo ""
207
208         d=sym1/sym2/sym3
209         f=$d/sym4_f
210
211         mkdir -p $d
212         ln -s $f symlink1
213         ln symlink1 hlink1
214         ln symlink1 hlink2
215         ln symlink1 hlink3
216         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/symlink1
217         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/hlink1
218         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/hlink2
219         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/hlink3
220 }
221
222 #
223 # create hardlinks from the same dir
224 # and some from different dirs
225 #
226 # test out removing hardlinks too
227 #
228 _test_hardlink()
229 {
230         echo ""
231         echo "Testing hardlink"
232         echo ""
233
234         d=dir2/dir3/dir4
235         d2=dir2/dir5/dir6
236         mkdir -p $d
237         mkdir -p $d2
238         p=$d/file4
239         touch $p
240
241         # create hardlinks
242         paths="$d/l1 $d/l2 $d/l3 $d2/l4 $d2/l5 $d2/l6"
243         for x in $paths; do
244                 ln $p $x
245         done
246
247         _print_names $p >>$here/$seq.full
248
249         echo ""
250         echo "print out names and check after created hardlinks"
251         echo ""
252         for x in $paths; do
253                 _print_names $x | tee -a $here/$seq.full
254                 _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/$x
255         done
256
257         echo ""
258         echo "now try removing half of the hardlinks"
259         echo ""
260         paths="$d/l1 $d/l2 $d/l3 $d2/l4 $d2/l5 $d2/l6"
261         i=0
262         for x in $paths; do
263                 i=`expr $i + 1`
264                 j=`expr $i % 2`
265                 if [ $j -eq 0 ]; then
266                         echo "rm'ing $x"
267                         rm $x
268                 fi
269         done
270
271         echo ""
272         echo "print out names and check after removed hardlinks"
273         echo ""
274         for x in $paths; do
275                 if [ -e $x ]; then 
276 echo "looking at $x"
277                         _print_names $x | tee -a $here/$seq.full
278                         _check_parentinos_path $SCRATCH_MNT $SCRATCH_MNT/$x
279                 fi
280         done
281
282 }
283
284 #
285 # in dir, file1 to file2 where file2 does not exist
286 # in dir, file1 to file2 where file2 does exist 
287 # dir/file1 to dir2/file2 where file2 does not exist
288 # dir/file1 to dir2/file2 where file2 does exist
289 # dir to dir2 where dir2 does not exist
290 # dir to dir/dir3 - not allowed
291 #
292 #
293 _test_rename()
294 {
295         echo ""
296         echo "Testing rename"
297         echo ""
298
299         echo ""
300         echo "1. in dir, file1 to file2 where file2 does not exist" 
301         echo ""
302         d1=$SCRATCH_MNT/ren1/ren2/ren3/ren4
303         mkdir -p $d1
304         p1=$d1/f1
305         p2=$d1/f2
306         touch $p1
307         mv $p1 $p2
308         _check_parentinos_path $SCRATCH_MNT $p2
309
310         echo ""
311         echo "2. in dir, file1 to file2 where file2 does exist" 
312         echo ""
313         touch $p1
314         mv $p1 $p2
315         _check_parentinos_path $SCRATCH_MNT $p2
316
317         echo ""
318         echo "3. dir/file1 to dir2/file2 where file2 does not exist"
319         echo ""
320         d2=$SCRATCH_MNT/ren1/ren2/ren3/ren5
321         mkdir -p $d2
322         p3=$d2/f3
323         touch $p1
324         mv $p1 $p3
325         _check_parentinos_path $SCRATCH_MNT $p3
326
327         echo ""
328         echo "4. dir/file1 to dir2/file2 where file2 does exist"
329         echo ""
330         d2=$SCRATCH_MNT/ren1/ren2/ren3/ren5
331         p3=$d2/f3
332         touch $p1
333         mv $p1 $p3
334         _check_parentinos_path $SCRATCH_MNT $p3
335
336         echo ""
337         echo "5. dir to dir2 where dir2 does not exist"
338         echo ""
339         d3=$SCRATCH_MNT/ren1/ren2/ren3/ren6
340         mv $d1 $d3
341         _check_parentinos_path $SCRATCH_MNT $d3
342 }
343
344 _filter_num()
345 {
346         tee -a $seq.full |\
347         sed -e 's/[0-9][0-9]* inodes/I inodes/g' \
348             -e 's/[0-9][0-9]* paths/P paths/g' \
349             -e 's/seed = [0-9][0-9]*/seed = S/'
350 }
351
352
353 _test_fsstress()
354 {
355         echo ""
356         echo "Testing fsstress"
357         echo ""
358
359         out=$SCRATCH_MNT/fsstress.$$
360         count=1000
361         args="-z \
362 -f rmdir=10 -f link=10 -f creat=10 \
363 -f mkdir=10 -f rename=30 -f unlink=10 \
364 -f symlink=10 \
365 -n $count -d $out -p 3"
366
367         echo "ltp/fsstress $args" | sed -e "s#$out#outdir#"
368         if ! $here/ltp/fsstress $args | _filter_num
369         then
370                 echo "    fsstress $args returned $?"
371                 cat $tmp.out | tee -a $here/$seq.full
372                 status=1
373         fi
374
375         xfs_repair_ipaths -n $SCRATCH_MNT | _filter_num
376         xfs_check_ipaths $SCRATCH_MNT | _filter_num
377 }
378
379
380 _test_dirstress()
381 {
382         echo ""
383         echo "Testing dirstress"
384         echo ""
385
386         out=$SCRATCH_MNT/dirstress.$$
387         count=1000
388
389         if ! mkdir $out
390         then
391             echo "!! couldn't mkdir $out"
392             status=1
393             exit
394         fi
395
396         args="-d $out -f $count -k -p 3 -n 1"
397         echo "src/dirstress $args" | sed -e "s#$out#outdir#"
398         if ! $here/src/dirstress $args >$tmp.out 2>&1 | _filter_num
399         then
400                 echo "    dirstress failed"
401                 echo "*** dirstress $args" | tee -a $here/$seq.full
402                 cat $tmp.out >>$here/$seq.full
403                 status=1
404                 exit
405         fi
406
407         args="-d $out -f $count -k -p 3 -n 5"
408         echo "src/dirstress $args" | sed -e "s#$out#outdir#"
409         if ! $here/src/dirstress $args >$tmp.out 2>&1 | _filter_num
410         then
411                 echo "    dirstress failed"
412                 echo "*** dirstress $args" | tee -a $here/$seq.full
413                 cat $tmp.out >>$here/$seq.full
414                 status=1
415                 exit
416         fi
417
418         xfs_repair_ipaths -n $SCRATCH_MNT | _filter_num
419         xfs_check_ipaths $SCRATCH_MNT | _filter_num
420 }
421
422 # get standard environment, filters and checks
423 . ./common.rc
424 . ./common.filter
425
426 _supported_fs xfs
427 _supported_os IRIX
428
429 _require_scratch
430
431 rm -f $here/$seq.full
432
433 echo "mkfs"
434 export MKFS_OPTIONS="$MKFS_OPTIONS -i paths=1"
435 _scratch_mkfs_xfs >>$here/$seq.full 2>&1 \
436     || _fail "mkfs scratch failed"
437
438 echo "mount"
439 _scratch_mount >>$here/$seq.full 2>&1 \
440     || _fail "mount failed: $MOUNT_OPTIONS"
441
442 # real QA test starts here
443
444 verbose=false
445
446 # initial testing with scripting and modified attr(1)
447 # in order to test parent EAs
448 _test_create
449 _test_hardlink
450 _test_rename
451 _test_symlink
452
453 # stress testing with verification by parent checking programs
454 _test_fsstress
455 _test_dirstress
456
457 # success, all done
458 status=0
459 exit