Re: [PATCH v2 08/10] generic/574: test multiple Merkle tree block sizes

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

 



On Thu, Dec 22, 2022 at 05:05:52PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@xxxxxxxxxx>
> 
> Instead of only testing 4K Merkle tree blocks, test FSV_BLOCK_SIZE, and
> also other sizes if they happen to be supported.  This allows this test
> to run in cases where it couldn't before and improves test coverage in
> cases where it did run before.
> 
> Given that the list of Merkle tree block sizes that will actually work
> is not fixed, this required reworking the test to not rely on the .out
> file so heavily.
> 
> Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx>
> ---
>  tests/generic/574     | 177 ++++++++++++++++++++++++++----------------
>  tests/generic/574.out |  83 ++------------------
>  2 files changed, 114 insertions(+), 146 deletions(-)
> 
> diff --git a/tests/generic/574 b/tests/generic/574
> index fd4488c9..8f7923ba 100755
> --- a/tests/generic/574
> +++ b/tests/generic/574
> @@ -37,18 +37,19 @@ fsv_file=$SCRATCH_MNT/file.fsv
>  
>  setup_zeroed_file()
>  {
> -	local len=$1
> -	local sparse=$2
> +	local block_size=$1
> +	local file_len=$2
> +	local sparse=$3
>  
>  	if $sparse; then
> -		dd if=/dev/zero of=$fsv_orig_file bs=1 count=0 seek=$len \
> +		dd if=/dev/zero of=$fsv_orig_file bs=1 count=0 seek=$file_len \
>  			status=none
>  	else
> -		head -c $len /dev/zero > $fsv_orig_file
> +		head -c $file_len /dev/zero > $fsv_orig_file
>  	fi
>  	cp $fsv_orig_file $fsv_file
> -	_fsv_enable $fsv_file
> -	md5sum $fsv_file |& _filter_scratch
> +	_fsv_enable $fsv_file --block-size=$block_size
> +	cmp $fsv_orig_file $fsv_file
>  }
>  
>  filter_sigbus()
> @@ -66,63 +67,84 @@ round_up_to_page_boundary()
>  
>  corruption_test()
>  {
> -	local file_len=$1
> -	local zap_offset=$2
> -	local zap_len=$3
> -	local is_merkle_tree=${4:-false} # if true, zap tree instead of data
> -	local use_sparse_file=${5:-false}
> +	local block_size=$1
> +	local file_len=$2
> +	local zap_offset=$3
> +	local zap_len=$4
> +	local is_merkle_tree=${5:-false} # if true, zap tree instead of data
> +	local use_sparse_file=${6:-false}
>  	local page_aligned_eof=$(round_up_to_page_boundary $file_len)
> -	local measurement
> +
> +	local paramstr="block_size=$block_size"
> +	paramstr+=", file_len=$file_len"
> +	paramstr+=", zap_offset=$zap_offset"
> +	paramstr+=", zap_len=$zap_len"
> +	paramstr+=", is_merkle_tree=$is_merkle_tree"
> +	paramstr+=", use_sparse_file=$use_sparse_file"
>  
>  	if $is_merkle_tree; then
>  		local corrupt_func=_fsv_scratch_corrupt_merkle_tree
>  	else
>  		local corrupt_func=_fsv_scratch_corrupt_bytes
>  	fi
> +	local fs_block_size=$(_get_block_size $SCRATCH_MNT)
>  
> -	local msg="Corruption test:"
> -	msg+=" file_len=$file_len"
> -	if $use_sparse_file; then
> -		msg+=" (sparse)"
> -	fi
> -	msg+=" zap_offset=$zap_offset"
> -	if $is_merkle_tree; then
> -		msg+=" (in Merkle tree)"
> -	fi
> -	msg+=" zap_len=$zap_len"
> +	rm -rf "${SCRATCH_MNT:?}"/*
> +	setup_zeroed_file $block_size $file_len $use_sparse_file
>  
> -	_fsv_scratch_begin_subtest "$msg"
> -	setup_zeroed_file $file_len $use_sparse_file
> -	cmp $fsv_file $fsv_orig_file
> -	echo "Corrupting bytes..."
> +	# Corrupt part of the file (data or Merkle tree).
>  	head -c $zap_len /dev/zero | tr '\0' X \
>  		| $corrupt_func $fsv_file $zap_offset
>  
> -	echo "Validating corruption (reading full file)..."
> +	# Reading the full file with buffered I/O should fail.
>  	_scratch_cycle_mount
> -	md5sum $fsv_file |& _filter_scratch
> +	if cat $fsv_file >/dev/null 2>$tmp.out; then
> +		echo "Unexpectedly was able to read full file ($paramstr)"
> +	elif ! grep -q 'Input/output error' $tmp.out; then
> +		echo "Wrong error reading full file ($paramstr):"
> +		cat $tmp.out
> +	fi
>  
> -	echo "Validating corruption (direct I/O)..."
> +	# Reading the full file with direct I/O should fail.
>  	_scratch_cycle_mount
> -	dd if=$fsv_file bs=$FSV_BLOCK_SIZE iflag=direct status=none \
> -		of=/dev/null |& _filter_scratch
> +	if dd if=$fsv_file bs=$fs_block_size iflag=direct status=none \
> +		of=/dev/null 2>$tmp.out
> +	then
> +		echo "Unexpectedly was able to read full file with DIO ($paramstr)"
> +	elif ! grep -q 'Input/output error' $tmp.out; then
> +		echo "Wrong error reading full file with DIO ($paramstr):"
> +		cat $tmp.out
> +	fi
>  
> -	if (( zap_offset < file_len )) && ! $is_merkle_tree; then
> -		echo "Validating corruption (reading just corrupted part)..."
> -		dd if=$fsv_file bs=1 skip=$zap_offset count=$zap_len \
> -			of=/dev/null status=none |& _filter_scratch
> +	# Reading just the corrupted part of the file should fail.
> +	if ! $is_merkle_tree; then
> +		if dd if=$fsv_file bs=1 skip=$zap_offset count=$zap_len \
> +			of=/dev/null status=none 2>$tmp.out; then
> +			echo "Unexpectedly was able to read corrupted part ($paramstr)"
> +		elif ! grep -q 'Input/output error' $tmp.out; then
> +			echo "Wrong error reading corrupted part ($paramstr):"
> +			cat $tmp.out
> +		fi
>  	fi
>  
> -	echo "Validating corruption (reading full file via mmap)..."
> +	# Reading the full file via mmap should fail.
>  	bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
>  		-c 'mmap -r 0 $page_aligned_eof' \
> -		-c 'mread 0 $file_len'" |& filter_sigbus
> +		-c 'mread 0 $file_len'" >/dev/null 2>$tmp.out
> +	if ! grep -q 'Bus error' $tmp.out; then
> +		echo "Didn't see SIGBUS when reading file via mmap"

Hmm... will sigbus error really be output to stderr? From a testing, the
generic/574 fails as:

# ./check -s simpledev generic/574
SECTION       -- simpledev
FSTYP         -- ext4
PLATFORM      -- Linux/x86_64 xx-xxxxxx-xxx 6.1.0-rc3 #5 SMP PREEMPT_DYNAMIC Tue Nov  1 01:08:52 CST 2022
MKFS_OPTIONS  -- -F /dev/sdb
MOUNT_OPTIONS -- -o acl,user_xattr -o context=system_u:object_r:root_t:s0 /dev/sdb /mnt/scratch

generic/574       - output mismatch (see /root/git/xfstests/results//simpledev/generic/574.out.bad)
    --- tests/generic/574.out   2022-12-25 20:02:41.609104749 +0800
    +++ /root/git/xfstests/results//simpledev/generic/574.out.bad       2022-12-25 20:21:57.430719504 +0800
    @@ -1,6 +1,32 @@
     QA output created by 574
     
     # Testing block_size=FSV_BLOCK_SIZE
    +/root/git/xfstests/tests/generic/574: line 69: 1949533 Bus error               (core dumped) bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file            -c 'mmap -r 0 $page_aligned_eof'               -c 'mread 0 $file_len'" > /dev/null 2> $tmp.out
    +Didn't see SIGBUS when reading file via mmap
    +/root/git/xfstests/tests/generic/574: line 69: 1949544 Bus error               (core dumped) bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file                    -c 'mmap -r 0 $page_aligned_eof'                       -c 'mread $zap_offset $zap_len'" > /dev/null 2> $tmp.out
    +Didn't see SIGBUS when reading corrupted part via mmap
    ...
    (Run 'diff -u /root/git/xfstests/tests/generic/574.out /root/git/xfstests/results//simpledev/generic/574.out.bad'  to see the entire diff)
Ran: generic/574
Failures: generic/574
Failed 1 of 1 tests

Thanks,
Zorro

> +		cat $tmp.out
> +	fi
>  
> +	# Reading just the corrupted part via mmap should fail.
>  	if ! $is_merkle_tree; then
> -		echo "Validating corruption (reading just corrupted part via mmap)..."
>  		bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
>  			-c 'mmap -r 0 $page_aligned_eof' \
> -			-c 'mread $zap_offset $zap_len'" |& filter_sigbus
> +			-c 'mread $zap_offset $zap_len'" >/dev/null 2>$tmp.out
> +		if ! grep -q 'Bus error' $tmp.out; then
> +			echo "Didn't see SIGBUS when reading corrupted part via mmap"
> +			cat $tmp.out
> +		fi
>  	fi
>  }
>  
> @@ -131,18 +153,18 @@ corruption_test()
>  # return zeros in the last block past EOF, regardless of the contents on
>  # disk. In the former, corruption should be detected and result in SIGBUS,
>  # while in the latter we would expect zeros past EOF, but no error.
> -corrupt_eof_block_test() {
> -	local file_len=$1
> -	local zap_len=$2
> +corrupt_eof_block_test()
> +{
> +	local block_size=$1
> +	local file_len=$2
> +	local zap_len=$3
>  	local page_aligned_eof=$(round_up_to_page_boundary $file_len)
> -	_fsv_scratch_begin_subtest "Corruption test: EOF block"
> -	setup_zeroed_file $file_len false
> -	cmp $fsv_file $fsv_orig_file
> -	echo "Corrupting bytes..."
> +
> +	rm -rf "${SCRATCH_MNT:?}"/*
> +	setup_zeroed_file $block_size $file_len false
>  	head -c $zap_len /dev/zero | tr '\0' X \
>  		| _fsv_scratch_corrupt_bytes $fsv_file $file_len
>  
> -	echo "Reading eof block via mmap into a temporary file..."
>  	bash -c "trap '' SIGBUS; $XFS_IO_PROG -r $fsv_file \
>  		-c 'mmap -r 0 $page_aligned_eof' \
>  		-c 'mread -v $file_len $zap_len'" \
> @@ -153,30 +175,49 @@ corrupt_eof_block_test() {
>  		-c "mmap -r 0 $page_aligned_eof" \
>  		-c "mread -v $file_len $zap_len" >$tmp.eof_zero_read
>  
> -	echo "Checking for SIGBUS or zeros..."
> -	grep -q -e '^Bus error$' $tmp.eof_block_read \
> -		|| diff $tmp.eof_block_read $tmp.eof_zero_read \
> -		&& echo "OK"
> +	grep -q -e '^Bus error$' $tmp.eof_block_read || \
> +		diff $tmp.eof_block_read $tmp.eof_zero_read
>  }
>  
> -# Note: these tests just overwrite some bytes without checking their original
> -# values.  Therefore, make sure to overwrite at least 5 or so bytes, to make it
> -# nearly guaranteed that there will be a change -- even when the test file is
> -# encrypted due to the test_dummy_encryption mount option being specified.
> -
> -corruption_test 131072 0 5
> -corruption_test 131072 4091 5
> -corruption_test 131072 65536 65536
> -corruption_test 131072 131067 5
> -
> -corrupt_eof_block_test 130999 72
> -
> -# Merkle tree corruption.
> -corruption_test 200000 100 10 true
> +test_block_size()
> +{
> +	local block_size=$1
> +
> +	# Note: these tests just overwrite some bytes without checking their
> +	# original values.  Therefore, make sure to overwrite at least 5 or so
> +	# bytes, to make it nearly guaranteed that there will be a change --
> +	# even when the test file is encrypted due to the test_dummy_encryption
> +	# mount option being specified.
> +	corruption_test $block_size 131072 0 5
> +	corruption_test $block_size 131072 4091 5
> +	corruption_test $block_size 131072 65536 65536
> +	corruption_test $block_size 131072 131067 5
> +
> +	corrupt_eof_block_test $block_size 130999 72
> +
> +	# Merkle tree corruption.
> +	corruption_test $block_size 200000 100 10 true
> +
> +	# Sparse file.  Corrupting the Merkle tree should still cause reads to
> +	# fail, i.e. the filesystem must verify holes.
> +	corruption_test $block_size 200000 100 10 true true
> +}
>  
> -# Sparse file.  Corrupting the Merkle tree should still cause reads to fail,
> -# i.e. the filesystem must verify holes.
> -corruption_test 200000 100 10 true true
> +# Always test FSV_BLOCK_SIZE.  Also test some other block sizes if they happen
> +# to be supported.
> +_fsv_scratch_begin_subtest "Testing block_size=FSV_BLOCK_SIZE"
> +test_block_size $FSV_BLOCK_SIZE
> +for block_size in 1024 4096 16384 65536; do
> +	_fsv_scratch_begin_subtest "Testing block_size=$block_size if supported"
> +	if (( block_size == FSV_BLOCK_SIZE )); then
> +		continue # Skip redundant test case.
> +	fi
> +	if ! _fsv_can_enable $fsv_file --block-size=$block_size; then
> +		echo "block_size=$block_size is unsupported" >> $seqres.full
> +		continue
> +	fi
> +	test_block_size $block_size
> +done
>  
>  # success, all done
>  status=0
> diff --git a/tests/generic/574.out b/tests/generic/574.out
> index d40d1263..3ed57f1c 100644
> --- a/tests/generic/574.out
> +++ b/tests/generic/574.out
> @@ -1,84 +1,11 @@
>  QA output created by 574
>  
> -# Corruption test: file_len=131072 zap_offset=0 zap_len=5
> -0dfbe8aa4c20b52e1b8bf3cb6cbdf193  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading just corrupted part)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -Validating corruption (reading just corrupted part via mmap)...
> -Bus error
> +# Testing block_size=FSV_BLOCK_SIZE
>  
> -# Corruption test: file_len=131072 zap_offset=4091 zap_len=5
> -0dfbe8aa4c20b52e1b8bf3cb6cbdf193  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading just corrupted part)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -Validating corruption (reading just corrupted part via mmap)...
> -Bus error
> +# Testing block_size=1024 if supported
>  
> -# Corruption test: file_len=131072 zap_offset=65536 zap_len=65536
> -0dfbe8aa4c20b52e1b8bf3cb6cbdf193  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading just corrupted part)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -Validating corruption (reading just corrupted part via mmap)...
> -Bus error
> +# Testing block_size=4096 if supported
>  
> -# Corruption test: file_len=131072 zap_offset=131067 zap_len=5
> -0dfbe8aa4c20b52e1b8bf3cb6cbdf193  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading just corrupted part)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -Validating corruption (reading just corrupted part via mmap)...
> -Bus error
> +# Testing block_size=16384 if supported
>  
> -# Corruption test: EOF block
> -f5cca0d7fbb8b02bc6118a9954d5d306  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Reading eof block via mmap into a temporary file...
> -Checking for SIGBUS or zeros...
> -OK
> -
> -# Corruption test: file_len=200000 zap_offset=100 (in Merkle tree) zap_len=10
> -4a1e4325031b13f933ac4f1db9ecb63f  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> -
> -# Corruption test: file_len=200000 (sparse) zap_offset=100 (in Merkle tree) zap_len=10
> -4a1e4325031b13f933ac4f1db9ecb63f  SCRATCH_MNT/file.fsv
> -Corrupting bytes...
> -Validating corruption (reading full file)...
> -md5sum: SCRATCH_MNT/file.fsv: Input/output error
> -Validating corruption (direct I/O)...
> -dd: error reading 'SCRATCH_MNT/file.fsv': Input/output error
> -Validating corruption (reading full file via mmap)...
> -Bus error
> +# Testing block_size=65536 if supported
> -- 
> 2.39.0
> 




[Index of Archives]     [linux Cryptography]     [Asterisk App Development]     [PJ SIP]     [Gnu Gatekeeper]     [IETF Sipping]     [Info Cyrus]     [ALSA User]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite News]     [Deep Creek Hot Springs]     [Yosemite Campsites]     [ISDN Cause Codes]

  Powered by Linux