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

File: [Development] / xfs-cmds / xfstests / common.log (download)

Revision 1.1, Mon Oct 6 07:46:19 2003 UTC (14 years ago) by ptools
Branch: MAIN

Split up v2 log testing

##/bin/sh

#
# Copyright (c) 2000-2002 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/
#

#
# common routines for log testing
# Created by dxm@sgi.com & tes@sgi.com
#

fulldir=$seq.fulldir
rm -rf $fulldir
mkdir $fulldir

_cleanup_logfiles()
{
    if [ $status -eq 0 ]; then
	# don't keep these files around unless something went wrong
        rm -rf $fulldir
    fi
}

_full()
{
    echo ""            >>$seq.full      
    echo "*** $* ***"  >>$seq.full
    echo ""            >>$seq.full
}

# Handle the operations which get split over Log Record
# boundaries.
# Oper (379)..... flags: CONTINUE
# ...
# Oper (0)....... flags: WAS_CONT END
#
# or
#
# Oper (379)..... flags: none 
# ...
# Oper (0)....... flags: none 
#
_filter_opnum()
{
    $AWK_PROG '
function extract_opnum(str) {
	# e.g. "(379):" => "379"
	gsub(/[():]/,"",str)
	return str
}
BEGIN { 
	opnum = -1
        #debug = 1
	}
/^Oper/ && debug {
	    printf "line = %s\n", $0
	}
/^Oper/ {
	    was_cont = 0
	    prev_opnum = opnum
	    opnum = extract_opnum($2)
	}
/^Oper/ && /flags: CONTINUE/ { 
	    $9 = "none" # overwrite CONTINUE flags
	    $2 = sprintf("(%d):", remember+opnum)	
	    remember += opnum
	    print
	    next        
	}
/^Oper/ && /flags: WAS_CONT END/ {
	    # skip over was-continued op
	    # we assume there can be only 1
	    was_cont = 1
	    next        
	}
(was_cont == 1) { 
	    # skip over any continued op stuff
	    next
	}
/^Oper/ && /UNMOUNT/ {
	    remember = 0
	    opnum = -1
	    print
	    next
	}
/^Oper/ && (opnum == 0) { 
	    # have operation 0 with NO continued op
	    remember += (prev_opnum+1)
	}
/^Oper/ && debug { printf "line2 = %s, remember = %d, prev_opnum = %d\n", $0, remember, prev_opnum}
/^Oper/ && (remember > 0) {
	    # add in opnum accumulation from previous LRs 
	    $2 = sprintf("(%d):", remember+opnum)	
	    print
	    next
	}
	{print}
    '
}

_filter_logprint()
{
    sed '
        s/data device: 0x[0-9a-f][0-9a-f]*/data device: <DEVICE>/;
        s/log device: 0x[0-9a-f][0-9a-f]*/log device: <DEVICE>/;
        s/log file: \".*\"/log device: <DEVICE>/;
        s/daddr: [0-9][0-9]*/daddr: <DADDR>/;
        s/length: [0-9][0-9]*/length: <LENGTH>/;
        s/length: [0-9][0-9]*/length: <LENGTH>/;
        s/^cycle num overwrites: .*$/cycle num overwrites: <TIDS>/;
        s/tid: [0-9a-f][0-9a-f]*/tid: <TID>/;
        s/tid:0x[0-9a-f][0-9a-f]*/tid:<TID>/;
        s/q:0x[0-9a-f][0-9a-f]*/q:<Q>/;
        s/a:0x[0-9a-f][0-9a-f]*/a:<A>/g;
        s/blkno:0x[0-9a-f][0-9a-f]*/blkno:<BLKNO>/g;
        s/blkno: [0-9][0-9]* (0x[0-9a-f]*)/blkno: <BLKNO> (<BLKNO>)/g;
        s/blkno: [0-9][0-9]*/blkno: <BLKNO>/g;
        s/boff: [0-9][0-9]*/boff: <BOFF>/g;
        s/len: *[0-9][0-9]*/len:<LEN>/g;
	/zeroed blocks/s/[0-9][0-9]*/<COUNT>/g;
	/cleared blocks/d;
	/log tail/s/[0-9][0-9]*/<COUNT>/g;
        s/atime:[0-9a-fx]*  *mtime:[0-9a-fx]*  *ctime:[0-9a-fx]*/atime:<TIME>  mtime:<TIME>  ctime:<TIME>/;
        s/atime 0x[0-9a-f]* mtime 0x[0-9a-f]* ctime 0x[0-9a-f]*/atime <TIME>  mtime <TIME>  ctime <TIME>/;
        s/block [0-9][0-9]*/block <BLOCK>/;
        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>/;
        s/sunit: *[0-9][0-9]*  *swidth: *[0-9][0-9]*/sunit:<SUNIT> swidth:<SWIDTH>/;
        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>/;
        s/^uuid: *[0-9a-f-][0-9a-f-]* *format: *.*$/uuid: <UUID> format: <FORMAT>/;
        /flushiter:/d;
	/version:/,/h_size:/d;
	/override tail/s/[0-9][0-9]*/<TAIL_BLK>/;
	/^---*/d;
	/^===*/d;
	/^~~~*/d;
	/extended-header/d;
	/LOG REC AT LSN/d;
	/^[ 	]*$/d;
	s/  */ /g;
	s/ $//;
    ' \
    | _fix_malloc
}

_check_log()
{
    _full "clean_log : xfs_logprint"
    _scratch_xfs_logprint -t | tee -a $seq.full \
        | head | grep -q "<CLEAN>" || _fail "DIRTY LOG"
}

_print_operation()
{
    raw=$fulldir/op.mnt$mnt.mkfs$mkfs$sync_suffix.raw
    filtered=$fulldir/op.mnt$mnt.mkfs$mkfs$sync_suffix.filtered

    echo "### xfs_logprint output ###" | tee $raw >$filtered
    _scratch_xfs_logprint -c  2>&1 \
    | tee -a $raw      \
    | _filter_logprint \
    | _filter_opnum    \
    >>$filtered
}

# start at rec#2 "-s 2" so we skip over UMOUNT record which will always
# be a 512b single header at mkfs time
# and may not match with the FS mounted at a different LR size 
# => xlog_do_recovery_pass() can not handle the different hdr sizes
#    it assumes them all to be the same between the start..finish
# NB: On IRIX there is no UMOUNT record and so we could start from -s 0.

_print_transaction_inode()
{
    _start=$1
    raw=$fulldir/trans_inode.mnt$mnt.mkfs$mkfs$sync_suffix.raw
    filtered=$fulldir/trans_inode.mnt$mnt.mkfs$mkfs$sync_suffix.filtered

    echo "### xfs_logprint -t -i -s START output ###" | tee $raw >$filtered
    _scratch_xfs_logprint -t -i -s $_start 2>&1 \
    | tee -a $raw      \
    | _filter_logprint \
    >>$filtered
}

_print_transaction_buf()
{
    _start=$1
    raw=$fulldir/trans_buf.mnt$mnt.mkfs$mkfs$sync_suffix.raw
    filtered=$fulldir/trans_buf.mnt$mnt.mkfs$mkfs$sync_suffix.filtered

    echo "### xfs_logprint -t -b -s START output ###" | tee $raw >$filtered
    _scratch_xfs_logprint -t -b -s $_start 2>&1 \
    | tee -a $raw      \
    | _filter_logprint \
    >>$filtered
}

_mkfs_log()
{
    typeset _mkfs_opts
    _mkfs_opts=$1

    # create the FS
    _full "mkfs"
    extra_ops="-lsize=2000b $_mkfs_opts"
    _scratch_mkfs_xfs $extra_ops >$tmp.mkfs0 2>&1
    [ $? -ne 0 ] && \
	_notrun "Cannot mkfs for this test using MKFS_OPTIONS specified: $MKFS_OPTIONS $extra_ops"
    cat $tmp.mkfs0 >>$seq.full

    # check the mkfs settings
    _filter_mkfs <$tmp.mkfs0 2>$tmp.mkfs
    source $tmp.mkfs
    [ $dbsize -eq 4096 ] \
	|| _notrun "Logprint test, tailored to 4K blocks ($dbsize in use)"
    [ $isize -eq 256 ] \
	|| _notrun "Logprint test, tailored to 256b inodes ($isize in use)"
}


#
# mount fs and create some log traffic
#
_create_log()
{
    typeset _mnt_opts

    _mnt_opts=$1

    # mount the FS
    _full " mount"
    _scratch_mount $_mnt_opts >>$seq.full 2>&1 \
	|| _fail "mount failed: $_mnt_opts $MOUNT_OPTIONS"

    # generate some log traffic - but not too much - life gets a little
    # more complicated if the log wraps around. This traffic is
    # pretty much arbitary, but could probably be made better than this.
    touch $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}
	
    # unmount the FS
    _full "umount"
    umount $SCRATCH_DEV >>$seq.full 2>&1 \
	|| _fail "umount failed"

}

#
# mount fs and create some log traffic with sync'ing
#
_create_log_sync()
{
    typeset _mnt_opts

    _mnt_opts=$1

    # mount the FS
    _full " mount"
    _scratch_mount $_mnt_opts >>$seq.full 2>&1 \
	|| _fail "mount failed: $_mnt_opts $MOUNT_OPTIONS"

    # generate some log traffic - but not too much
    # add some syncs to get the log flushed to disk 
    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
	touch $file
	sync
    done
	
    # unmount the FS
    _full "umount"
    umount $SCRATCH_DEV >>$seq.full 2>&1 \
	|| _fail "umount failed"

}

_cmp_output()
{
    echo "*** compare logprint: $1 with $2"
    if ! diff $1 $2 >/dev/null; then
	echo "FAILED: logprint output $1 differs to $2"
	touch $tmp.error
    fi
}

_clear_opts()
{
    # clear opts
    # - remove the log options in mkfs
    # - remove the log options in mount
    # - remove the quota options in mount
    # leave any other options given
    MKFS_OPTIONS=`echo $MKFS_OPTIONS | sed -e 's/-l[ ]*[^ $]*//g'`
    MOUNT_OPTIONS=`echo $MOUNT_OPTIONS |\
	    sed -e 's/logbsize=[^ ,]*,*//g' \
		-e 's/usrquota,*//g'        \
		-e 's/grpquota,*//g'        \
		-e 's/quota,*//g'           \
		-e 's/uqnoenforce,*//g'     \
		-e 's/gqnoenforce,*//g'     \
		-e 's/-o *$//g'		    \
		-e 's/-o *-/-/g'	    \
		`
	
    # export opts
    export MKFS_OPTIONS
    export MOUNT_OPTIONS
}

#
# Op data of different Log Record sizes will mean that data is
# split at different points and in op printing it will not
# try and decode the data which has been split up.
# So we do a special diff processing to complain of differences
# if no split is involved.
#
# Example diff with forms of:
# "Left over region from split log item"
# "Not printing rest of data"
#
#   2149c2149
#   < Left over region from split log item
#   ---
#   > BUF DATA
#   2888c2888,2889
#   < INODE: #regs: 3 Not printing rest of data
#   ---
#   > INODE: #regs: 3 ino: 0x80 flags: 0x5 dsize: 16
#   >  blkno: <BLKNO> len:<LEN> boff: <BOFF>
#
_process_op_diff()
{
    $AWK_PROG <$1 '
	BEGIN { num_splits = 1 }
	/^[0-9]/ {

		# ensure cmd is a change op
		cmd = $1
		gsub(/[0-9][0-9]*/,"", cmd)
		gsub(/,/,"", cmd)
		if (cmd != "c") {
			print "bad diff cmd: ", $0
			exit 1
		}

		# ensure a split happened in previous difference
		if (num_splits != 1 && num_splits != 2) {
			print num_splits, " split(s) found prior to diff cmd: ", $0
			num_splits = 1 # shut-up end condition
			exit 1
		}
		num_splits = 0

		next
	}
	/Left over region/ || /Not printing rest/ { 
		num_splits++
		next
	}
	{ next }
	END { 
		if (num_splits != 1 && num_splits != 2) {
			print num_splits, " split(s) found prior to diff end"
			exit 1
		}
	}
    '
    return $?
}

_cmp_op_output()
{
    echo "*** compare logprint: $1 with $2"

    diff $1 $2 >$filtered.diff
    if ! _process_op_diff $filtered.diff
    then
	echo "FAILED: logprint output $1 differs to $2 considering splits"
	touch $tmp.error
    fi
}


# make sure this script returns success
/bin/true