]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfstests-dev.git/commitdiff
check: capture dmesg of mount failures if test fails
authorDarrick J. Wong <djwong@kernel.org>
Thu, 16 Apr 2026 19:15:43 +0000 (12:15 -0700)
committerZorro Lang <zlang@kernel.org>
Fri, 1 May 2026 15:42:41 +0000 (23:42 +0800)
Capture the kernel output after a mount failure occurs.  If the test
itself fails, then keep the logging output for further diagnosis.  The
xunit.xsd update adds a <mount-failure> element to the xml output, whose
output is the mountfail file.

Note that because the .mountfail file is preserved by ./check, the new
selftest requires the user to check for the .mountfail file.  This is a
little awkward.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Zorro Lang <zlang@kernel.org>
check
common/rc
common/report
doc/xunit.xsd
tests/selftest/008 [new file with mode: 0755]
tests/selftest/008.out [new file with mode: 0644]

diff --git a/check b/check
index cd7a79347eac2896c9cab6bcf23b06da940c98e1..ad685edc8dda85f0e789b15e098ed4e87ea87a66 100755 (executable)
--- a/check
+++ b/check
@@ -608,7 +608,7 @@ _stash_fail_loop_files() {
        local seq_prefix="${REPORT_DIR}/${1}"
        local cp_suffix="$2"
 
-       for i in ".full" ".dmesg" ".out.bad" ".notrun" ".core" ".hints"; do
+       for i in ".full" ".dmesg" ".out.bad" ".notrun" ".core" ".hints" ".mountfail"; do
                rm -f "${seq_prefix}${i}${cp_suffix}"
                if [ -f "${seq_prefix}${i}" ]; then
                        cp "${seq_prefix}${i}" "${seq_prefix}${i}${cp_suffix}"
@@ -982,6 +982,7 @@ function run_section()
                                      echo -n " $seqnum -- "
                        cat $seqres.notrun
                        tc_status="notrun"
+                       rm -f "$seqres.mountfail?"
                        _stash_test_status "$seqnum" "$tc_status"
 
                        # Unmount the scratch fs so that we can wipe the scratch
@@ -1045,6 +1046,7 @@ function run_section()
                if [ ! -f $seq.out ]; then
                        _dump_err "no qualified output"
                        tc_status="fail"
+                       rm -f "$seqres.mountfail?"
                        _stash_test_status "$seqnum" "$tc_status"
                        continue;
                fi
@@ -1081,6 +1083,22 @@ function run_section()
                                rm -f $seqres.hints
                        fi
                fi
+
+               if [ -f "$seqres.mountfail?" ]; then
+                       if [ "$tc_status" = "fail" ]; then
+                               # Let the user know if there were mount
+                               # failures on a test that failed because that
+                               # could be interesting.
+                               mv "$seqres.mountfail?" "$seqres.mountfail"
+                               _dump_err "check: possible mount failures (see $seqres.mountfail)"
+                       else
+                               # Don't retain mount failure logs for tests
+                               # that pass or were skipped because some tests
+                               # intentionally drive mount failures.
+                               rm -f "$seqres.mountfail?"
+                       fi
+               fi
+
                _stash_test_status "$seqnum" "$tc_status"
        done
 
index 9632b211b58fe4870d7abf4b9970174b38162583..26db5bbd3289f1b8a1d186b5efcf5066141f184d 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -288,9 +288,26 @@ _get_hugepagesize()
        awk '/Hugepagesize/ {print $2 * 1024}' /proc/meminfo
 }
 
+# Does dmesg have a --since flag?
+_has_dmesg_since_option()
+{
+       grep -q -- --since <(dmesg --help)
+}
+
 _mount()
 {
-    $MOUNT_PROG $*
+       $MOUNT_PROG $*
+       ret=$?
+       if [ "$ret" -ne 0 ]; then
+               echo "\"$MOUNT_PROG $*\" failed at $(date)" >> "$seqres.mountfail?"
+               if _has_dmesg_since_option; then
+                       dmesg --since '30s ago' >> "$seqres.mountfail?"
+               else
+                       dmesg | tail -n 100 >> "$seqres.mountfail?"
+               fi
+       fi
+
+       return $ret
 }
 
 # Call _mount to do mount operation but also save mountpoint to
index 0d9ad78c612d02049dd3264ce8f9ac73bf83775a..2fa15e62f1e7070333ff7023771e93315187b129 100644 (file)
@@ -201,6 +201,7 @@ _xunit_make_testcase_report()
                local out_src="${SRC_DIR}/${test_name}.out"
                local full_file="${REPORT_DIR}/${test_name}.full"
                local dmesg_file="${REPORT_DIR}/${test_name}.dmesg"
+               local mountfail_file="${REPORT_DIR}/${test_name}.mountfail"
                local outbad_file="${REPORT_DIR}/${test_name}.out.bad"
                if [ -z "$_err_msg" ]; then
                        _err_msg="Test $test_name failed, reason unknown"
@@ -227,6 +228,13 @@ _xunit_make_testcase_report()
                        printf ']]>\n'  >>$report
                        echo -e "\t\t</system-err>" >> $report
                fi
+               if [ -z "$quiet" -a -f "$mountfail_file" ]; then
+                       echo -e "\t\t<mount-failure>" >> $report
+                       printf  '<![CDATA[\n' >>$report
+                       cat "$mountfail_file" | tr -dc '[:print:][:space:]' | encode_cdata >>$report
+                       printf ']]>\n'  >>$report
+                       echo -e "\t\t</mount-failure>" >> $report
+               fi
                ;;
        *)
                echo -e "\t\t<failure message=\"Unknown test_status=$test_status\" type=\"TestFail\"/>" >> $report
index d287eaf5a25fb604913de898a639b9ebb2955329..efe0badbb338b5460cfbe5bc824737d909eb9475 100644 (file)
                                 </xs:complexType>
                             </xs:element>
                         </xs:choice>
-                        <xs:choice minOccurs="0" maxOccurs="3">
+                        <xs:choice minOccurs="0" maxOccurs="4">
                             <xs:element name="system-out" minOccurs="0" maxOccurs="1">
                                 <xs:annotation>
                                     <xs:documentation xml:lang="en">Data that was written to the .full log file while the test was executed.</xs:documentation>
                                     </xs:restriction>
                                 </xs:simpleType>
                             </xs:element>
+                            <xs:element name="mount-failure" minOccurs="0" maxOccurs="1">
+                                <xs:annotation>
+                                    <xs:documentation xml:lang="en">Kernel log recorded when mount failed.</xs:documentation>
+                                </xs:annotation>
+                                <xs:simpleType>
+                                    <xs:restriction base="pre-string">
+                                        <xs:whiteSpace value="preserve"/>
+                                    </xs:restriction>
+                                </xs:simpleType>
+                            </xs:element>
                         </xs:choice>
                     </xs:sequence>
                     <xs:attribute name="name" type="xs:token" use="required">
diff --git a/tests/selftest/008 b/tests/selftest/008
new file mode 100755 (executable)
index 0000000..e6cc87f
--- /dev/null
@@ -0,0 +1,22 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2024-2026 Oracle.  All Rights Reserved.
+#
+# FS QA Test 008
+#
+# Test mount failure capture.  Test runners will have to look for the
+# 008.mountfail file in the results directory since ./check handles the
+# preservation.
+#
+. ./common/preamble
+_begin_fstest selftest
+
+_require_command "$WIPEFS_PROG" wipefs
+_require_scratch
+
+$WIPEFS_PROG -a $SCRATCH_DEV
+_scratch_mount &>> $seqres.full
+
+# success, all done
+status=0
+exit
diff --git a/tests/selftest/008.out b/tests/selftest/008.out
new file mode 100644 (file)
index 0000000..aaff95f
--- /dev/null
@@ -0,0 +1 @@
+QA output created by 008