Re: [PATCH v2] xfs: test xfsdump when an inode < root inode is present

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



On Fri, Apr 08, 2022 at 09:00:56PM -0700, Darrick J. Wong wrote:
> On Sat, Apr 09, 2022 at 01:08:47AM +0800, Zorro Lang wrote:
> > From: Eric Sandeen <sandeen@xxxxxxxxxx>
> > 
> > This tests a longstanding bug where xfsdumps are not properly
> > created when an inode is present on the filesytsem which has
> > a lower number than the root inode.
> > 
> > Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx>
> > Signed-off-by: Zorro Lang <zlang@xxxxxxxxxx>
> > ---
> > 
> > Friendly ping for reviewing.
> > 
> > Thanks,
> > Zorro
> > 
> >  common/dump       |  1 +
> >  tests/xfs/543     | 63 +++++++++++++++++++++++++++++++++++++++++++++++
> >  tests/xfs/543.out | 47 +++++++++++++++++++++++++++++++++++
> >  3 files changed, 111 insertions(+)
> >  create mode 100755 tests/xfs/543
> >  create mode 100644 tests/xfs/543.out
> > 
> > diff --git a/common/dump b/common/dump
> > index ea16d442..ab48cd13 100644
> > --- a/common/dump
> > +++ b/common/dump
> > @@ -219,6 +219,7 @@ _require_tape()
> >  
> >  _wipe_fs()
> >  {
> > +    [[ "$WIPE_FS" = "no" ]] && return
> 
> Is WIPE_FS intended as a general means to prevent wipefs -a between
> tests?  If so, it ought to be in the README.

Actually I don't know how to if I should say WIPE_FS means to prevent
wipefs -a between tests. Due to:

1) We have a _wipe_fs() in common/dump[1], it's very old, and it only
try to make a new xfs, although it calls wipe "fs"... And it's only used
for tests/xfs/* cases to call _create_dumpdir_*() function.

2) Then we have _try_wipe_scratch_devs() in common/rc [2], which calls
_try_wipe_scratch_xfs() in common/xfs [3] (which is newer), it's only
used in ./check script now.

So I'm wondering if we'd better to change the _wipe_fs() to:
_wipe_dump()
{
	[[ "$WIPE_DUMP" = "no" ]] && return
	_require_scratch

	_try_wipe_scratch_devs >>$seqres.full
	_scratch_mount >>$seqres.full
}

What do you think?

Thanks,
Zorro

[1]
_wipe_fs()
{
    [[ "$WIPE_FS" = "no" ]] && return
    _require_scratch

    _scratch_mkfs_xfs >>$seqres.full || _fail "mkfs failed"
    _scratch_mount >>$seqres.full
}

[2]
_try_wipe_scratch_devs()
{
        test -x "$WIPEFS_PROG" || return 0

        # Do specified filesystem wipe at first
        case "$FSTYP" in
        "xfs")
                _try_wipe_scratch_xfs
                ;;
        esac

        # Then do wipefs on all scratch devices
        for dev in $SCRATCH_DEV_POOL $SCRATCH_DEV $SCRATCH_LOGDEV $SCRATCH_RTDEV; do
                test -b $dev && $WIPEFS_PROG -a $dev
        done
}

[3]
# Wipe the superblock of each XFS AGs
_try_wipe_scratch_xfs()
{
        local num='^[0-9]+$'
        local agcount
        local agsize
        local dbsize

        # Try to wipe each SB if there's an existed XFS
        agcount=`_scratch_xfs_get_sb_field agcount 2>/dev/null`
        agsize=`_scratch_xfs_get_sb_field agblocks 2>/dev/null`
        dbsize=`_scratch_xfs_get_sb_field blocksize 2>/dev/null`
        if [[ $agcount =~ $num && $agsize =~ $num && $dbsize =~ $num ]];then
                for ((i = 0; i < agcount; i++)); do
                        $XFS_IO_PROG -c "pwrite $((i * dbsize * agsize)) $dbsize" \
                                $SCRATCH_DEV >/dev/null;
                done
        fi

        # Try to wipe each SB by default mkfs.xfs geometry
        local tmp=`mktemp -u`
        unset agcount agsize dbsize
        _scratch_mkfs_xfs -N 2>/dev/null | perl -ne '
                if (/^meta-data=.*\s+agcount=(\d+), agsize=(\d+) blks/) {
                        print STDOUT "agcount=$1\nagsize=$2\n";
                }
                if (/^data\s+=\s+bsize=(\d+)\s/) {
                        print STDOUT "dbsize=$1\n";
                }' > $tmp.mkfs

        . $tmp.mkfs
        if [[ $agcount =~ $num && $agsize =~ $num && $dbsize =~ $num ]];then
                for ((i = 0; i < agcount; i++)); do
                        $XFS_IO_PROG -c "pwrite $((i * dbsize * agsize)) $dbsize" \
                                $SCRATCH_DEV >/dev/null;
                done
        fi
        rm -f $tmp.mkfs
}

> 
> --D
> 
> >      _require_scratch
> >  
> >      _scratch_mkfs_xfs >>$seqres.full || _fail "mkfs failed"
> > diff --git a/tests/xfs/543 b/tests/xfs/543
> > new file mode 100755
> > index 00000000..4e3c823a
> > --- /dev/null
> > +++ b/tests/xfs/543
> > @@ -0,0 +1,63 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2022 Red Hat, Inc. All Rights Reserved.
> > +#
> > +# FS QA Test 543
> > +#
> > +# Create a filesystem which contains an inode with a lower number
> > +# than the root inode. Ensure that xfsdump/xfsrestore handles this.
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick dump
> > +
> > +# Import common functions.
> > +. ./common/dump
> > +
> > +_supported_fs xfs
> > +_require_scratch
> > +
> > +# A large stripe unit will put the root inode out quite far
> > +# due to alignment, leaving free blocks ahead of it.
> > +_scratch_mkfs_xfs -d sunit=1024,swidth=1024 > $seqres.full 2>&1
> > +
> > +# Mounting /without/ a stripe should allow inodes to be allocated
> > +# in lower free blocks, without the stripe alignment.
> > +_scratch_mount -o sunit=0,swidth=0
> > +
> > +root_inum=$(stat -c %i $SCRATCH_MNT)
> > +
> > +# Consume space after the root inode so that the blocks before
> > +# root look "close" for the next inode chunk allocation
> > +$XFS_IO_PROG -f -c "falloc 0 16m" $SCRATCH_MNT/fillfile
> > +
> > +# And make a bunch of inodes until we (hopefully) get one lower
> > +# than root, in a new inode chunk.
> > +echo "root_inum: $root_inum" >> $seqres.full
> > +for i in $(seq 0 4096) ; do
> > +	fname=$SCRATCH_MNT/$(printf "FILE_%03d" $i)
> > +	touch $fname
> > +	inum=$(stat -c "%i" $fname)
> > +	[[ $inum -lt $root_inum ]] && break
> > +done
> > +
> > +echo "created: $inum" >> $seqres.full
> > +
> > +[[ $inum -lt $root_inum ]] || _notrun "Could not set up test"
> > +
> > +# Now try a dump and restore. Cribbed from xfs/068
> > +WIPE_FS="no"
> > +_create_dumpdir_stress
> > +
> > +echo -n "Before: " >> $seqres.full
> > +_count_dumpdir_files | tee $tmp.before >> $seqres.full
> > +
> > +# filter out the file count, it changes as fsstress adds new operations
> > +_do_dump_restore | sed -e "/entries processed$/s/[0-9][0-9]*/NUM/g"
> > +
> > +echo -n "After: " >> $seqres.full
> > +_count_restoredir_files | tee $tmp.after >> $seqres.full
> > +diff -u $tmp.before $tmp.after
> > +
> > +# success, all done
> > +status=0
> > +exit
> > diff --git a/tests/xfs/543.out b/tests/xfs/543.out
> > new file mode 100644
> > index 00000000..a5224aaf
> > --- /dev/null
> > +++ b/tests/xfs/543.out
> > @@ -0,0 +1,47 @@
> > +QA output created by 543
> > +Creating directory system to dump using fsstress.
> > +
> > +-----------------------------------------------
> > +fsstress : -f link=10 -f creat=10 -f mkdir=10 -f truncate=5 -f symlink=10
> > +-----------------------------------------------
> > +xfsdump|xfsrestore ...
> > +xfsdump  -s DUMP_SUBDIR - SCRATCH_MNT | xfsrestore  - RESTORE_DIR
> > +xfsrestore: using file dump (drive_simple) strategy
> > +xfsrestore: searching media for dump
> > +xfsrestore: examining media file 0
> > +xfsrestore: dump description: 
> > +xfsrestore: hostname: HOSTNAME
> > +xfsrestore: mount point: SCRATCH_MNT
> > +xfsrestore: volume: SCRATCH_DEV
> > +xfsrestore: session time: TIME
> > +xfsrestore: level: 0
> > +xfsrestore: session label: ""
> > +xfsrestore: media label: ""
> > +xfsrestore: file system ID: ID
> > +xfsrestore: session id: ID
> > +xfsrestore: media ID: ID
> > +xfsrestore: searching media for directory dump
> > +xfsrestore: reading directories
> > +xfsrestore: NUM directories and NUM entries processed
> > +xfsrestore: directory post-processing
> > +xfsrestore: restoring non-directory files
> > +xfsrestore: restore complete: SECS seconds elapsed
> > +xfsrestore: Restore Status: SUCCESS
> > +xfsdump: using file dump (drive_simple) strategy
> > +xfsdump: level 0 dump of HOSTNAME:SCRATCH_MNT
> > +xfsdump: dump date: DATE
> > +xfsdump: session id: ID
> > +xfsdump: session label: ""
> > +xfsdump: ino map <PHASES>
> > +xfsdump: ino map construction complete
> > +xfsdump: estimated dump size: NUM bytes
> > +xfsdump: /var/xfsdump/inventory created
> > +xfsdump: creating dump session media file 0 (media 0, file 0)
> > +xfsdump: dumping ino map
> > +xfsdump: dumping directories
> > +xfsdump: dumping non-directory files
> > +xfsdump: ending media file
> > +xfsdump: media file size NUM bytes
> > +xfsdump: dump size (non-dir files) : NUM bytes
> > +xfsdump: dump complete: SECS seconds elapsed
> > +xfsdump: Dump Status: SUCCESS
> > -- 
> > 2.31.1
> > 
> 




[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux