Fixed merge issue with TIMESTAMP string printing twice.
[xfstests-dev.git] / common.log
1 ##/bin/sh
2
3 #
4 # Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of version 2 of the GNU General Public License as
8 # published by the Free Software Foundation.
9
10 # This program is distributed in the hope that it would be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 # Further, this software is distributed without any warranty that it is
15 # free of the rightful claim of any third person regarding infringement
16 # or the like.  Any license provided herein, whether implied or
17 # otherwise, applies only to this software file.  Patent licenses, if
18 # any, provided herein do not apply to combinations of this program with
19 # other software, or any other product whatsoever.
20
21 # You should have received a copy of the GNU General Public License along
22 # with this program; if not, write the Free Software Foundation, Inc., 59
23 # Temple Place - Suite 330, Boston MA 02111-1307, USA.
24
25 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 # Mountain View, CA  94043, or:
27
28 # http://www.sgi.com 
29
30 # For further information regarding this notice, see: 
31
32 # http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33 #
34
35 #
36 # common routines for log testing
37 # Created by dxm@sgi.com & tes@sgi.com
38 #
39
40 fulldir=$seq.fulldir
41 rm -rf $fulldir
42
43 _cleanup_logfiles()
44 {
45     if [ $status -eq 0 ]; then
46         # don't keep these files around unless something went wrong
47         rm -rf $fulldir
48     fi
49 }
50
51 _full()
52 {
53     echo ""            >>$seq.full      
54     echo "*** $* ***"  >>$seq.full
55     echo ""            >>$seq.full
56 }
57
58 _echofull()
59 {
60     echo ""            | tee -a $seq.full      
61     echo "*** $* ***"  | tee -a $seq.full
62     echo ""            | tee -a $seq.full
63 }
64
65 # Handle the operations which get split over Log Record
66 # boundaries.
67 # Oper (379)..... flags: CONTINUE
68 # ...
69 # Oper (0)....... flags: WAS_CONT END
70 #
71 # or
72 #
73 # Oper (379)..... flags: none 
74 # ...
75 # Oper (0)....... flags: none 
76 #
77 _filter_opnum()
78 {
79     $AWK_PROG '
80 BEGIN { 
81         debug = 0 
82         }
83 /^Oper/ && debug {
84             printf "line = %s\n", $0
85         }
86 /^Oper/ {
87             was_cont = 0
88         }
89 /^Oper/ && /flags: CONTINUE/ { 
90             # this will be the first op of split region
91             $9 = "none" # overwrite CONTINUE flags
92             print
93             print "Not printing rest"
94             was_cont = 1
95             next        
96         }
97 /^Oper/ && /flags: WAS_CONT END/ {
98             # this will be the last op of split region
99             # skip over was-continued op
100             # we assume there can be only 1
101             was_cont = 1
102             next        
103         }
104 (was_cont == 1) { 
105             # skip over any continued op stuff
106             next
107         }
108         {print}
109     '
110 }
111
112 #
113 # Filter out things that can change
114 # We have complexities which change when log is sync'ed at different
115 # times.
116 # Example1: DATA FORK EXTENTS
117 # These will not show up if inode is sync'ed sooner
118 #       /DATA FORK EXTENTS/d;
119 #       /INODE:/s/flags:0x5/flags:0x1/g;
120 # define XFS_ILOG_CORE   0x001   /* log standard inode fields */
121 # define XFS_ILOG_DEXT   0x004   /* log i_df.if_extents */
122 #
123 #
124
125 _filter_logprint()
126 {
127     _fix_malloc |\
128     sed '
129         s/data device: 0x[0-9a-f][0-9a-f]*/data device: <DEVICE>/;
130         s/log device: 0x[0-9a-f][0-9a-f]*/log device: <DEVICE>/;
131         s/log file: \".*\"/log device: <DEVICE>/;
132         s/daddr: [0-9][0-9]*/daddr: <DADDR>/;
133         s/length: [0-9][0-9]*/length: <LENGTH>/;
134         s/length: [0-9][0-9]*/length: <LENGTH>/;
135         s/^cycle num overwrites: .*$/cycle num overwrites: <TIDS>/;
136         s/tid: [0-9a-f][0-9a-f]*/tid: <TID>/;
137         s/tid:0x[0-9a-f][0-9a-f]*/tid:<TID>/;
138         s/q:0x[0-9a-f][0-9a-f]*/q:<Q>/;
139         s/a:0x[0-9a-f][0-9a-f]*/a:<A>/g;
140         s/blkno:0x[0-9a-f][0-9a-f]*/blkno:<BLKNO>/g;
141         s/blkno: [0-9][0-9]* (0x[0-9a-f]*)/blkno: <BLKNO> (<BLKNO>)/g;
142         s/blkno: [0-9][0-9]*/blkno: <BLKNO>/g;
143         s/boff: [0-9][0-9]*/boff: <BOFF>/g;
144         s/len: *[0-9][0-9]*/len:<LEN>/g;
145         /zeroed blocks/s/[0-9][0-9]*/<COUNT>/g;
146         /cleared blocks/d;
147         /log tail/s/[0-9][0-9]*/<COUNT>/g;
148         s/atime:[0-9a-fx]*  *mtime:[0-9a-fx]*  *ctime:[0-9a-fx]*/atime:<TIME>  mtime:<TIME>  ctime:<TIME>/;
149         s/atime 0x[0-9a-f]* mtime 0x[0-9a-f]* ctime 0x[0-9a-f]*/atime <TIME>  mtime <TIME>  ctime <TIME>/;
150         s/block [0-9][0-9]*/block <BLOCK>/;
151         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>/;
152         s/sunit: *[0-9][0-9]*  *swidth: *[0-9][0-9]*/sunit:<SUNIT> swidth:<SWIDTH>/;
153         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>/;
154         s/^uuid: *[0-9a-f-][0-9a-f-]* *format: *.*$/uuid: <UUID> format: <FORMAT>/;
155         /flushiter:/d;
156         /version:/,/h_size:/d;
157         /override tail/s/[0-9][0-9]*/<TAIL_BLK>/;
158         /^---*/d;
159         /^===*/d;
160         /^~~~*/d;
161         /extended-header/d;
162         /LOG REC AT LSN/d;
163         /DATA FORK EXTENTS/d;
164         s/BUF: cnt:[1-9][0-9]* total:[1-9][0-9]*.*/BUF: cnt:C total:T/;
165         s/INO: cnt:[1-9][0-9]* total:[1-9][0-9]*.*/INO: cnt:C total:T/;
166         s/#regs: *[1-9][0-9]*/#regs:R/;
167         /INODE:/s/flags:0x5/flags:0x1/g;
168         s/Oper ([0-9][0-9]*)/Oper (OPNUM)/;
169         /^[     ]*$/d;
170         s/  */ /g;
171         s/ $//;
172     '|\
173     awk '
174         # collapse BUF DATA group into 1 line
175         # for Oper data this can be over separate operations...ughh
176         /BUF DATA/ { 
177                 if (!buf_data) { # 1st one
178                     if (oper) { 
179                         print oper
180                         oper = 0
181                     }           
182                     print
183                 }
184                 buf_data = 1
185                 oper = 0 # wont need it now
186                 next
187         }
188         /^Oper/ { 
189                 # store it as we dont know if 2nd BUF DATA is to follow
190                 if (oper) {
191                     print oper
192                 }
193                 oper = $0
194                 next
195         }
196         {
197                 buf_data = 0
198                 if (oper) { # now we can print out oper
199                     print oper
200                     oper = 0    
201                 }
202                 print
203         }
204     '
205 }
206
207 _check_log()
208 {
209     _full "clean_log : xfs_logprint"
210     _scratch_xfs_logprint -t | tee -a $seq.full \
211         | head | grep -q "<CLEAN>" || _fail "DIRTY LOG"
212 }
213
214 _print_logstate()
215 {
216     _scratch_xfs_logprint -t | tee -a $seq.full >$tmp.logprint
217     if grep -q "<DIRTY>" $tmp.logprint; then
218         echo "dirty log"
219     fi
220     if grep -q "<CLEAN>" $tmp.logprint; then
221         echo "clean log"
222     fi
223 }
224
225 _print_operation()
226 {
227     mkdir $fulldir >/dev/null 2>&1
228     mntopt=`echo $MOUNT_OPTIONS | sed 's/ /_/g'`
229     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ /_/g'`
230     raw=$fulldir/op.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
231     filtered=$fulldir/op.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
232
233     echo "### xfs_logprint output ###" | tee $raw >$filtered
234     _scratch_xfs_logprint -c  2>&1 \
235     | tee -a $raw      \
236     | _filter_logprint \
237     | _filter_opnum    \
238     >>$filtered
239 }
240
241 # start at rec#2 "-s 2" so we skip over UMOUNT record which will always
242 # be a 512b single header at mkfs time
243 # and may not match with the FS mounted at a different LR size 
244 # => xlog_do_recovery_pass() can not handle the different hdr sizes
245 #    it assumes them all to be the same between the start..finish
246 # NB: On IRIX there is no UMOUNT record and so we could start from -s 0.
247
248 _print_transaction_inode()
249 {
250     _start=$1
251     mkdir $fulldir >/dev/null 2>&1
252     mntopt=`echo $MOUNT_OPTIONS | sed 's/ /_/g'`
253     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ /_/g'`
254     raw=$fulldir/trans_inode.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
255     filtered=$fulldir/trans_inode.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
256
257     echo "### xfs_logprint -t -i -s START output ###" | tee $raw >$filtered
258     _scratch_xfs_logprint -t -i -s $_start 2>&1 \
259     | tee -a $raw      \
260     | _filter_logprint \
261     >>$filtered
262 }
263
264 _print_transaction_buf()
265 {
266     _start=$1
267     mkdir $fulldir >/dev/null 2>&1
268     mntopt=`echo $MOUNT_OPTIONS | sed 's/ /_/g'`
269     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ /_/g'`
270     raw=$fulldir/trans_buf.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
271     filtered=$fulldir/trans_buf.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
272
273     echo "### xfs_logprint -t -b -s START output ###" | tee $raw >$filtered
274     _scratch_xfs_logprint -t -b -s $_start 2>&1 \
275     | tee -a $raw      \
276     | _filter_logprint \
277     >>$filtered
278 }
279
280 _mkfs_log()
281 {
282     # create the FS
283     _full "mkfs"
284     extra_ops="-l size=2000b"
285     _scratch_mkfs_xfs $extra_ops >>$seq.full 2>&1
286     if [ $? -ne 0 ] ; then 
287         _echofull "Cannot mkfs for this test using option specified: $MKFS_OPTIONS $extra_ops"
288         return 1
289     fi  
290
291     return 0
292 }
293
294
295 #
296 # mount fs and create some log traffic
297 #
298 _create_log()
299 {
300     # mount the FS
301     _full " mount"
302     _scratch_mount >>$seq.full 2>&1
303     if [ $? -ne 0 ] ; then 
304         _echofull "mount failed: $MOUNT_OPTIONS"
305         return 1
306     fi
307
308     # generate some log traffic - but not too much - life gets a little
309     # more complicated if the log wraps around. This traffic is
310     # pretty much arbitary, but could probably be made better than this.
311     touch $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
312         
313     # unmount the FS
314     _full "umount"
315     umount $SCRATCH_DEV >>$seq.full 2>&1
316     if [ $? -ne 0 ] ; then 
317         _echofull "umount failed"
318         return 1
319     fi
320
321     return 0
322 }
323
324 #
325 # mount fs and create some log traffic with sync'ing
326 #
327 _create_log_sync()
328 {
329     # mount the FS
330     _full " mount"
331     _scratch_mount >>$seq.full 2>&1
332     if [ $? -ne 0 ] ; then 
333         _echofull "mount failed: $MOUNT_OPTIONS"
334         return 1
335     fi
336
337     # generate some log traffic - but not too much
338     # add some syncs to get the log flushed to disk 
339     for file in $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}; do
340         touch $file
341         sync
342     done
343         
344     # unmount the FS
345     _full "umount"
346     umount $SCRATCH_DEV >>$seq.full 2>&1
347     if [ $? -ne 0 ] ; then 
348         _echofull "umount failed"
349         return 1
350     fi
351
352 }
353
354 _cmp_output()
355 {
356     echo "*** compare logprint: $1 with $2"
357     if ! diff $1 $2 >/dev/null; then
358         _fail "logprint output $1 differs to $2"
359     fi
360 }
361
362 #
363 # Op data of different Log Record sizes will mean that data is
364 # split at different points and in op printing it will not
365 # try and decode the data which has been split up.
366 # So we do a special diff processing to complain of differences
367 # if no split is involved.
368 #
369 # Example diff with forms of:
370 # "Left over region from split log item"
371 # "Not printing rest of data"
372 #
373 #   2149c2149
374 #   < Left over region from split log item
375 #   ---
376 #   > BUF DATA
377 #   2888c2888,2889
378 #   < INODE: #regs: 3 Not printing rest of data
379 #   ---
380 #   > INODE: #regs: 3 ino: 0x80 flags: 0x5 dsize: 16
381 #   >  blkno: <BLKNO> len:<LEN> boff: <BOFF>
382 #
383 _process_op_diff()
384 {
385     $AWK_PROG <$1 '
386         BEGIN { num_splits = 1 }
387         /^[0-9]/ {
388
389                 # ensure a split happened in previous difference
390                 if (num_splits < 1 || num_splits > 3) {
391                         print num_splits, " split(s) found prior to diff cmd: ", $0
392                         num_splits = 1 # shut-up end condition
393                         exit 1
394                 }
395                 num_splits = 0
396
397                 next
398         }
399         /Left over region/ || /Not printing rest/ { 
400                 num_splits++
401                 next
402         }
403         { next }
404         END { 
405                 if (num_splits < 1 || num_splits > 3) {
406                         print num_splits, " split(s) found prior to diff end"
407                         exit 1
408                 }
409         }
410     '
411     return $?
412 }
413
414 _cmp_op_output()
415 {
416     echo "*** compare logprint: $1 with $2"
417
418     diff $1 $2 >$filtered.diff
419     if ! _process_op_diff $filtered.diff
420     then
421         _fail "logprint output $1 differs to $2 considering splits"
422     fi
423 }
424
425
426 # make sure this script returns success
427 /bin/true