Running a dm-flakey or dm-error test that loads a table that returns
EIO to all IO and then running a command that is expected to fail
with a specific error is racy.
If there is memory pressure at the same time that the table is
loaded, cached inodes can be turfed from memory and the command then
needs to read the inode it is about to act on from disk again. This
results in the inode read getting EIO and failing (e.g. xfs_io will
return a stat() error) rather than having the desired operation
fail.
This results in spurious test failures that look like this:
generic/331 - output mismatch (see /mnt/xfs/runner-41/results-2024-11-20-10:57:31/xfs/generic/331.out.bad)
--- tests/generic/331.out 2022-12-21 15:53:25.
487044098 +1100
+++ /mnt/xfs/runner-41/results-2024-11-20-10:57:31/xfs/generic/331.out.bad 2024-11-20 11:02:12.
123572607 +1100
@@ -5,7 +5,8 @@
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-331/file1
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-331/file2
CoW and unmount
-fdatasync: Input/output error
+/mnt/xfs/runner-41/scratch/test-331/file2: Input/output error
+stat: Input/output error
Compare files
...
Add a new "flakey EIO filter" that will catch -any- EIO error from
the command and change it to the error we expected to see.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Zorro lang <zlang@redhat.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
sed -E -e "s/\s+$//"
}
+# Catch -any- EIO error regardless of it's source and replace it with the
+# supplied error message.
+_filter_flakey_EIO()
+{
+ local message="$*"
+
+ sed -e "s#.*: Input\/output error#$message#"
+}
+
# make sure this script returns success
/bin/true
# open again and call fsync
echo "The following fsync should fail with EIO:"
-$XFS_IO_PROG -c fsync $testfile
+$XFS_IO_PROG -c fsync $testfile |& \
+ _filter_flakey_EIO "fsync: Input/output error"
echo "done"
# close file
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
_scratch_sync
_dmerror_load_error_table
-$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
+$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 |& \
+ _filter_flakey_EIO "write missed bytes expect 8388608 got 0"
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
_scratch_sync
_dmerror_load_error_table
-$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
+$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 |& \
+ _filter_flakey_EIO "write missed bytes expect 8388608 got 0"
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
_scratch_sync
_dmerror_load_error_table
-$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
-$XFS_IO_PROG -c "fdatasync" $testdir/file2
+$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full 2>&1
+$XFS_IO_PROG -c "fdatasync" $testdir/file2 |& \
+ _filter_flakey_EIO "fdatasync: Input/output error"
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
_dmerror_load_error_table
# rewrite the data and call fdatasync
-$XFS_IO_PROG -c "pwrite -w -q 0 $datalen" $testfile
+$XFS_IO_PROG -c "pwrite -w -q 0 $datalen" $testfile |& \
+ _filter_flakey_EIO "fdatasync: Input/output error"
# heal the device error
_dmerror_load_working_table
}
# Import common functions.
+. ./common/filter
. ./common/dmerror
_fixed_by_kernel_commit 631426ba1d45 \
stat "$SCRATCH_MNT/a" >> $seqres.full
echo read with IO errors
_dmerror_load_error_table
-$TIMEOUT_PROG -s KILL 10s $XFS_IO_PROG -c "mmap -r 0 $filesz" -c "madvise -R 0 $filesz" "$SCRATCH_MNT/a"
+$TIMEOUT_PROG -s KILL 10s $XFS_IO_PROG -c "mmap -r 0 $filesz" -c "madvise -R 0 $filesz" "$SCRATCH_MNT/a" |& \
+ _filter_flakey_EIO "madvise: Bad address"
_dmerror_load_working_table
# success, all done
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
_scratch_sync
_dmerror_load_error_table
-$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
+$AIO_TEST -a $alignment -f DIRECT -b $bufsize $TEST_DIR/moo $testdir/file2 |& \
+ _filter_flakey_EIO "write missed bytes expect 8388608 got 0"
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
_scratch_sync
_dmerror_load_error_table
-$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
-$XFS_IO_PROG -c "fdatasync" $testdir/file2
+$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full 2>&1
+$XFS_IO_PROG -c "fdatasync" $testdir/file2 |& \
+ _filter_flakey_EIO "fdatasync: Input/output error"
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount