fstests: remove old electric fence support
[xfstests-dev.git] / common / log
1 ##/bin/bash
2 #
3 # Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it would be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write the Free Software Foundation,
16 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 #
18 #
19 # common routines for log testing
20 # Created by dxm@sgi.com & tes@sgi.com
21 #
22
23 fulldir=$seqres.fulldir
24 rm -rf $fulldir
25
26 _cleanup_logfiles()
27 {
28     if [ $status -eq 0 ]; then
29         # don't keep these files around unless something went wrong
30         rm -rf $fulldir
31     fi
32 }
33
34 _full()
35 {
36     echo ""            >>$seqres.full
37     echo "*** $* ***"  >>$seqres.full
38     echo ""            >>$seqres.full
39 }
40
41 _echofull()
42 {
43     echo ""            | tee -a $seqres.full
44     echo "*** $* ***"  | tee -a $seqres.full
45     echo ""            | tee -a $seqres.full
46 }
47
48 # Handle the operations which get split over Log Record
49 # boundaries.
50 # Oper (379)..... flags: CONTINUE
51 # ...
52 # Oper (0)....... flags: WAS_CONT END
53 #
54 # or
55 #
56 # Oper (379)..... flags: none 
57 # ...
58 # Oper (0)....... flags: none 
59 #
60 _filter_opnum()
61 {
62     $AWK_PROG '
63 BEGIN { 
64         debug = 0 
65         }
66 /^Oper/ && debug {
67             printf "line = %s\n", $0
68         }
69 /^Oper/ {
70             was_cont = 0
71         }
72 /^Oper/ && /flags: CONTINUE/ { 
73             # this will be the first op of split region
74             $9 = "none" # overwrite CONTINUE flags
75             print
76             print "Not printing rest"
77             was_cont = 1
78             next        
79         }
80 /^Oper/ && /flags: WAS_CONT END/ {
81             # this will be the last op of split region
82             # skip over was-continued op
83             # we assume there can be only 1
84             was_cont = 1
85             next        
86         }
87 (was_cont == 1) { 
88             # skip over any continued op stuff
89             next
90         }
91         {print}
92     '
93 }
94
95 #
96 # Filter out things that can change
97 # We have complexities which change when log is sync'ed at different
98 # times.
99 # Example1: DATA FORK EXTENTS
100 # These will not show up if inode is sync'ed sooner
101 #       /DATA FORK EXTENTS/d;
102 #       /INODE:/s/flags:0x5/flags:0x1/g;
103 # define XFS_ILOG_CORE   0x001   /* log standard inode fields */
104 # define XFS_ILOG_DEXT   0x004   /* log i_df.if_extents */
105 #
106 #
107
108 _filter_logprint()
109 {
110     sed '
111         s/ver:[0-9]/ver:<VERS>/;
112         s/version [0-9] format [0-9]/version <VERS> format <FORMAT>/;
113         s/data device: 0x[0-9a-f][0-9a-f]*/data device: <DEVICE>/;
114         s/log device: 0x[0-9a-f][0-9a-f]*/log device: <DEVICE>/;
115         s/log file: \".*\"/log device: <DEVICE>/;
116         s/daddr: [0-9][0-9]*/daddr: <DADDR>/;
117         s/length: [0-9][0-9]*/length: <LENGTH>/;
118         s/length: [0-9][0-9]*/length: <LENGTH>/;
119         s/^cycle num overwrites: .*$/cycle num overwrites: <TIDS>/;
120         s/tid: [0-9a-f][0-9a-f]*/tid: <TID>/;
121         s/tid:0x[0-9a-f][0-9a-f]*/tid:<TID>/;
122         s/q:0x[0-9a-f][0-9a-f]*/q:<Q>/;
123         s/a:0x[0-9a-f][0-9a-f]*/a:<A>/g;
124         s/blkno:0x[0-9a-f][0-9a-f]*/blkno:<BLKNO>/g;
125         s/blkno: *[0-9][0-9]* (0x[0-9a-f]*)/blkno: <BLKNO> (<BLKNO>)/g;
126         s/blkno: *[0-9][0-9]*/blkno: <BLKNO>/g;
127         s/boff: [0-9][0-9]*/boff: <BOFF>/g;
128         s/len: *[0-9][0-9]*/len:<LEN>/g;
129         /BUF:/s/[       ]*flags:.*$//;
130         /zeroed blocks/s/[0-9][0-9]*/<COUNT>/g;
131         /cleared blocks/d;
132         /log tail/s/[0-9][0-9]*/<COUNT>/g;
133         s/atime:[0-9a-fx]*  *mtime:[0-9a-fx]*  *ctime:[0-9a-fx]*/atime:<TIME>  mtime:<TIME>  ctime:<TIME>/;
134         s/atime 0x[0-9a-f]* mtime 0x[0-9a-f]* ctime 0x[0-9a-f]*/atime <TIME>  mtime <TIME>  ctime <TIME>/;
135         s/block [0-9][0-9]*/block <BLOCK>/;
136         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>/;
137         s/sunit: *[0-9][0-9]*  *swidth: *[0-9][0-9]*/sunit:<SUNIT> swidth:<SWIDTH>/;
138         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>/;
139         s/^uuid: *[0-9a-f-][0-9a-f-]* *format: *.*$/uuid: <UUID> format: <FORMAT>/;
140         /flushiter:/d;
141         /version:/,/h_size:/d;
142         /override tail/s/[0-9][0-9]*/<TAIL_BLK>/;
143         /^---*/d;
144         /^===*/d;
145         /^~~~*/d;
146         /extended-header/d;
147         /LOG REC AT LSN/d;
148         /DATA FORK EXTENTS/d;
149         s/BUF: cnt:[1-9][0-9]* total:[1-9][0-9]*.*/BUF: cnt:C total:T/;
150         s/INO: cnt:[1-9][0-9]* total:[1-9][0-9]*.*/INO: cnt:C total:T/;
151         s/#regs: *[1-9][0-9]*/#regs:R/;
152         /INODE:/s/flags:0x5/flags:0x1/g;
153         s/Oper ([0-9][0-9]*)/Oper (OPNUM)/;
154         /^[     ]*$/d;
155         s/  */ /g;
156         s/ $//;
157         s/newino: 0x[0-9a-f]*$/newino: <INO>/g
158         s/newino:0x[0-9a-f]*$/newino:<INO>/g
159         s/ino: 0x[0-9a-f]* flags:/ino: <INO> flags:/g
160         s/ino:0x[0-9a-f]* flags:/ino:<INO> flags:/g
161         s/onlink:[0-9][0-9]*/onlink:<ONLINK>/;
162         s/gen:-*[0-9][0-9]*/gen:<GEN>/;
163         s/gen 0x[0-9a-f][0-9a-f]*/gen <GEN>/;
164     '|\
165     awk '
166         # collapse BUF DATA group into 1 line
167         # for Oper data this can be over separate operations...ughh
168         /BUF DATA/ { 
169                 if (!buf_data) { # 1st one
170                     if (oper) { 
171                         print oper
172                         oper = 0
173                     }           
174                     print
175                 }
176                 buf_data = 1
177                 oper = 0 # wont need it now
178                 next
179         }
180         /^Oper/ { 
181                 # store it as we dont know if 2nd BUF DATA is to follow
182                 if (oper) {
183                     print oper
184                 }
185                 oper = $0
186                 next
187         }
188         /^TRANS/ && dummy_rec == 1 {
189                 # start printing again - dummy transaction over
190                 dummy_rec = 0
191         }
192         /DUMMY1/ {
193                 # filter out dummy transactions
194                 dummy_rec = 1
195                 next
196         }
197         {
198                 if (dummy_rec) {
199                     next
200                 }
201                 buf_data = 0
202                 if (oper) { # now we can print out oper
203                     print oper
204                     oper = 0    
205                 }
206                 print
207         }
208     '
209 }
210
211 _check_log()
212 {
213     _full "clean_log : xfs_logprint"
214     _scratch_xfs_logprint -t | tee -a $seqres.full \
215         | head | grep -q "<CLEAN>" || _fail "DIRTY LOG"
216 }
217
218 _scratch_xfs_logstate()
219 {
220     _scratch_xfs_logprint -t | tee -a $seqres.full | grep -q "<CLEAN>"
221     echo $?
222 }
223
224 _scratch_f2fs_logstate()
225 {
226     $DUMP_F2FS_PROG $SCRATCH_DEV | tee -a $seqres.full | grep -q "unmount"
227     echo $?
228 }
229
230 _scratch_ext4_logstate()
231 {
232     $DUMPE2FS_PROG -h $SCRATCH_DEV 2> /dev/null | tee -a $seqres.full | \
233         grep "^Filesystem features" | grep -q needs_recovery
234     test $? -ne 0
235     echo $?
236 }
237
238 _scratch_dump_log()
239 {
240         case "$FSTYP" in
241         xfs)
242                 _scratch_xfs_logprint
243                 ;;
244         f2fs)
245                 $DUMP_F2FS_PROG $SCRATCH_DEV
246                 ;;
247         ext4)
248                 $DUMPE2FS_PROG -h $SCRATCH_DEV
249                 ;;
250         *)
251                 ;;
252         esac
253 }
254
255 _test_dump_log()
256 {
257         case "$FSTYP" in
258         xfs)
259                 _test_xfs_logprint
260                 ;;
261         f2fs)
262                 $DUMP_F2FS_PROG $TEST_DEV
263                 ;;
264         ext4)
265                 $DUMPE2FS_PROG -h $TEST_DEV
266                 ;;
267         *)
268                 ;;
269         esac
270 }
271
272 _print_logstate()
273 {
274     case "$FSTYP" in
275     xfs)
276         dirty=$(_scratch_xfs_logstate)
277         ;;
278     f2fs)
279         dirty=$(_scratch_f2fs_logstate)
280         ;;
281     ext4)
282         dirty=$(_scratch_ext4_logstate)
283         ;;
284     *)
285         ;;
286     esac
287
288     if [ $dirty -ne 0 ]; then
289         echo "dirty log"
290     else
291         echo "clean log"
292     fi
293 }
294
295 _print_operation()
296 {
297     mkdir $fulldir >/dev/null 2>&1
298     mntopt=`echo $MOUNT_OPTIONS | sed 's/ //g'`
299     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ //g'`
300     raw=$fulldir/op.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
301     filtered=$fulldir/op.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
302
303     echo "### xfs_logprint output ###" | tee $raw >$filtered
304     _scratch_xfs_logprint -c  2>&1 \
305     | tee -a $raw      \
306     | _filter_logprint \
307     | _filter_opnum    \
308     >>$filtered
309 }
310
311 # start at rec#2 "-s 2" so we skip over UMOUNT record which will always
312 # be a 512b single header at mkfs time
313 # and may not match with the FS mounted at a different LR size 
314 # => xlog_do_recovery_pass() can not handle the different hdr sizes
315 #    it assumes them all to be the same between the start..finish
316
317 _print_transaction_inode()
318 {
319     _start=$1
320     mkdir $fulldir >/dev/null 2>&1
321     mntopt=`echo $MOUNT_OPTIONS | sed 's/ //g'`
322     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ //g'`
323     raw=$fulldir/trans_inode.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
324     filtered=$fulldir/trans_inode.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
325
326     echo "### xfs_logprint -t -i -s START output ###" | tee $raw >$filtered
327     _scratch_xfs_logprint -t -i -s $_start 2>&1 \
328     | tee -a $raw      \
329     | _filter_logprint \
330     >>$filtered
331 }
332
333 _print_transaction_buf()
334 {
335     _start=$1
336     mkdir $fulldir >/dev/null 2>&1
337     mntopt=`echo $MOUNT_OPTIONS | sed 's/ //g'`
338     mkfsopt=`echo $MKFS_OPTIONS | sed 's/ //g'`
339     raw=$fulldir/trans_buf.mnt$mntopt.mkfs$mkfsopt$sync_suffix.raw
340     filtered=$fulldir/trans_buf.mnt$mntopt.mkfs$mkfsopt$sync_suffix.filtered
341
342     echo "### xfs_logprint -t -b -s START output ###" | tee $raw >$filtered
343     _scratch_xfs_logprint -t -b -s $_start 2>&1 \
344     | tee -a $raw      \
345     | _filter_logprint \
346     >>$filtered
347 }
348
349 _mkfs_log()
350 {
351     # create the FS
352     # mkfs options to append to log size otion can be specified ($*)
353     export MKFS_OPTIONS="-l size=2000b -l lazy-count=1 $*"
354     _full "mkfs"
355     _scratch_mkfs_xfs >>$seqres.full 2>&1
356     if [ $? -ne 0 ] ; then 
357         _echofull "Cannot mkfs for this test using option specified: $MKFS_OPTIONS"
358         return 1
359     fi  
360
361     return 0
362 }
363
364
365 #
366 # mount fs and create some log traffic
367 #
368 _create_log()
369 {
370     # mount the FS
371     _full "mount"
372     _try_scratch_mount >>$seqres.full 2>&1
373     if [ $? -ne 0 ] ; then 
374         _echofull "mount failed: $MOUNT_OPTIONS"
375         return 1
376     fi
377
378     # generate some log traffic - but not too much - life gets a little
379     # more complicated if the log wraps around. This traffic is
380     # pretty much arbitary, but could probably be made better than this.
381     touch $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
382         
383     # unmount the FS
384     _full "umount"
385     _scratch_unmount >>$seqres.full 2>&1
386     if [ $? -ne 0 ] ; then 
387         _echofull "umount failed"
388         return 1
389     fi
390
391     return 0
392 }
393
394 #
395 # mount fs and create some log traffic with sync'ing
396 #
397 _create_log_sync()
398 {
399     # mount the FS
400     _full " mount"
401     _try_scratch_mount >>$seqres.full 2>&1
402     if [ $? -ne 0 ] ; then 
403         _echofull "mount failed: $MOUNT_OPTIONS"
404         return 1
405     fi
406
407     # generate some log traffic - but not too much
408     # add some syncs to get the log flushed to disk 
409     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
410         touch $file
411         sync
412     done
413
414     # unmount the FS
415     _full "umount"
416     _scratch_unmount >>$seqres.full 2>&1
417     if [ $? -ne 0 ] ; then 
418         _echofull "umount failed"
419         return 1
420     fi
421 }
422
423 _cmp_output()
424 {
425     echo "*** compare logprint: $1 with $2"
426     if ! diff $1 $2 >/dev/null; then
427         _fail "logprint output $1 differs to $2"
428     fi
429 }
430
431 #
432 # Op data of different Log Record sizes will mean that data is
433 # split at different points and in op printing it will not
434 # try and decode the data which has been split up.
435 # So we do a special diff processing to complain of differences
436 # if no split is involved.
437 #
438 # Example diff with forms of:
439 # "Left over region from split log item"
440 # "Not printing rest of data"
441 #
442 #   2149c2149
443 #   < Left over region from split log item
444 #   ---
445 #   > BUF DATA
446 #   2888c2888,2889
447 #   < INODE: #regs: 3 Not printing rest of data
448 #   ---
449 #   > INODE: #regs: 3 ino: 0x80 flags: 0x5 dsize: 16
450 #   >  blkno: <BLKNO> len:<LEN> boff: <BOFF>
451 #
452 _process_op_diff()
453 {
454     $AWK_PROG <$1 '
455         BEGIN { num_splits = 1; max_splits = 50 }
456         /^[0-9]/ {
457
458                 # ensure a split happened in previous difference
459                 if (num_splits < 1 || num_splits > max_splits) {
460                         print num_splits, " split(s) found prior to diff cmd: ", $0
461                         num_splits = 1 # shut-up end condition
462                         exit 1
463                 }
464                 num_splits = 0
465
466                 next
467         }
468         /Left over region/ || /Not printing rest/ { 
469                 num_splits++
470                 next
471         }
472         { next }
473         END { 
474                 if (num_splits < 1 || num_splits > max_splits) {
475                         print num_splits, " split(s) found prior to diff end"
476                         exit 1
477                 }
478         }
479     '
480     return $?
481 }
482
483 _cmp_op_output()
484 {
485     echo "*** compare logprint: $1 with $2"
486
487     diff $1 $2 >$filtered.diff
488     if ! _process_op_diff $filtered.diff
489     then
490         _fail "logprint output $1 differs to $2 considering splits"
491     fi
492 }
493
494 # return xfs log version of device
495 # e.g.
496 #   _log_version /dev/dsk/dks0d1s4
497 #
498 _log_version()
499 {
500     _dev=$1 
501     vers=`xfs_db -c 'sb 0' -c 'p versionnum' -r $_dev | $AWK_PROG '{print $3}'`
502     logver=`echo $vers | sed -e 's/0x[0-9a-f]\([0-9a-f]\)[0-9a-f][0-9a-f]/\1/'` 
503     if [ $logver = 4 -o $logver = 5 -o $logver = 6 -o $logver = 7 -o \
504          $logver = c -o $logver = d -o $logver = e -o $logver = f ]; then
505         echo 2
506     else
507         echo 1
508     fi
509 }
510
511 _require_v2log()
512 {
513     # test out mkfs to see if it supports "-l version=2"
514     export MKFS_OPTIONS="-l version=2"
515     if ! _scratch_mkfs_xfs >>$seqres.full 2>&1; then
516         _notrun "mkfs does not support v2 logs"
517     fi
518
519     # test out mount to see if it mounts a v2 log fs
520     export MOUNT_OPTIONS="-o logbsize=32k"
521     if ! _try_scratch_mount >>$seqres.full 2>&1; then
522         _notrun "mount/kernel does not support v2 logs"
523     fi
524
525     # check after unmount to see if it is clean
526     # i.e. it is not a 6.5.25 buggy version checking kernel
527     touch $SCRATCH_MNT/file
528     _scratch_unmount >>$seqres.full 2>&1
529     if _scratch_xfs_logprint -t | tee -a $seqres.full \
530         | head | grep -q "<DIRTY>"; then
531         _notrun "kernel does not support v2 logs"
532     fi
533  
534     # otherwise presume it does support v2 logs...:)
535 }
536
537 _require_logstate()
538 {
539     case "$FSTYP" in
540     xfs)
541         if [ -z "$XFS_LOGPRINT_PROG" ]; then
542             _notrun "This test requires xfs_logprint utility."
543         fi
544         ;;
545     f2fs)
546         if [ -z "$DUMP_F2FS_PROG" ]; then
547             _notrun "This test requires dump.f2fs utility."
548         fi
549         ;;
550     ext4)
551         if [ -z "$DUMPE2FS_PROG" ]; then
552                 _notrun "This test requires dumpe2fs utility."
553         fi
554         ;;
555     *)
556         _notrun "$FSTYP does not support log state probing."
557         ;;
558     esac
559 }
560
561 _xfs_log_config()
562 {
563     echo "# mkfs-opt             mount-opt"
564     echo "# ------------------------------"
565     echo "  version=2            logbsize=32k"
566     echo "  version=2,su=4096    logbsize=32k"
567     echo "  version=2,su=32768   logbsize=32k"
568     echo "  version=2,su=32768   logbsize=64k"
569     echo "  version=2            logbsize=64k"
570     echo "  version=2,su=64k     logbsize=64k"
571     echo "  version=2            logbsize=128k"
572     echo "  version=2,su=128k    logbsize=128k"
573     echo "  version=2            logbsize=256k"
574     echo "  version=2,su=256k    logbsize=256k"
575 }
576
577 _f2fs_log_config()
578 {
579     echo "# mkfs-opt             mount-opt"
580     echo "# ------------------------------"
581     echo "  test1     active_logs=6,background_gc=off"
582     echo "  test2     active_logs=6,background_gc=off,inline_data"
583     echo "  test3     active_logs=6,background_gc=off,inline_dentry"
584     echo "  test4     active_logs=6,background_gc=off,inline_data,inline_dentry"
585     echo "  test5     active_logs=6,background_gc=off,disable_roll_forward"
586     echo "  test6     active_logs=6,background_gc=off,discard,inline_data,inline_dentry"
587     echo "  test7     active_logs=6,background_gc=on"
588     echo "  test8     active_logs=6,background_gc=on,inline_data"
589     echo "  test9     active_logs=6,background_gc=on,inline_data,inline_dentry"
590     echo "  test10    active_logs=6,background_gc=on,discard,inline_data,inline_dentry"
591 }
592
593 _ext4_log_config()
594 {
595     echo "# mkfs-opt             mount-opt"
596     echo "# ------------------------------"
597     echo "  /dev/null     data=writeback"
598     echo "  /dev/null     data=ordered"
599     echo "  /dev/null     data=journal"
600     echo "  /dev/null     data=ordered,data_err=abort"
601     echo "  /dev/null     data=writeback,nojournal_checksum"
602     echo "  /dev/null     data=ordered,nojournal_checksum"
603     echo "  /dev/null     data=journal,nojournal_checksum"
604     echo "  /dev/null     data=ordered,data_err=abort,nojournal_checksum"
605     echo "  /dev/null     data=writeback,journal_checksum"
606     echo "  /dev/null     data=ordered,journal_checksum"
607 }
608
609 _get_log_configs()
610 {
611     case "$FSTYP" in
612     xfs)
613         _xfs_log_config
614         ;;
615     f2fs)
616         _f2fs_log_config
617         ;;
618     ext4)
619         _ext4_log_config
620         ;;
621     *)
622         _notrun "$FSTYP does not support log configs."
623         ;;
624     esac
625 }
626
627 # make sure this script returns success
628 /bin/true