[PATCH] fstests: fix bug with _check_dmesg "some pattern"

Josef Bacik
2025-11-21T17:55:40Z

I've been rigging up Claude to run fstests via an MCP, and part of this
means it mounts a 9p file system to save the fstests results. This was
giving me occasional ENODATA errors, which I dug into. Turns out it's a
race between truncate and read on 9p which is completely normal for 9p,
but it's uncovering an actual bug in _check_dmesg. The way bash works is
when you do

cat foo | whatever > foo

bash will setup the various communication channels first, which is the |
and >, and then it will execute the commands. This means that it
truncates foo FIRST, and then it launches cat. Which means we'd race
with truncate and sometimes get data, sometimes get nothing. And even
worse on 9p we'd get ENODATA because we get a 0 read back when we
thought the isize was reasonable.

Fix this by changing this case in _check_dmesg to redirect to another
file, and move that file over $seqres.dmesg to be checked later.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
common/rc | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/common/rc b/common/rc
index a10ac177..947685df 100644
--- a/common/rc
+++ b/common/rc
@@ -4844,7 +4844,14 @@ _check_dmesg()
# test failures. Custom filters are then applied afterwards.
_dmesg_since_test_start | _check_dmesg_filter > $seqres.dmesg
if [ -n "$1" ]; then
- cat $seqres.dmesg | $1 > $seqres.dmesg
+ # We use $seqres.dmesg.tmp because shell will setup the
+ # redirections first, which means we would truncate
+ # $seqres.dmesg before cat'ing it. This is racy so sometimes it
+ # would work, but othertimes it would silently fail, or in the
+ # case of 9p you'd get ENODATA. We must redirect into a
+ # temporary file and then move it.
+ cat $seqres.dmesg | $1 > $seqres.dmesg.tmp && \
+ mv $seqres.dmesg.tmp $seqres.dmesg
fi

grep -E -q -e "kernel BUG at" \
--
2.51.1