]> git.proxmox.com Git - mirror_zfs.git/commitdiff
ZTS: Log test name to /dev/kmsg on Linux
authorTony Hutter <hutter2@llnl.gov>
Wed, 23 Mar 2022 15:15:02 +0000 (08:15 -0700)
committerTony Hutter <hutter2@llnl.gov>
Mon, 3 Apr 2023 20:50:02 +0000 (13:50 -0700)
Add a -K option to the test suite to log each test name to /dev/kmsg
(on Linux), so if there's a kernel warning we'll be able to match
it up to a particular test.

Reviewed-by: John Kennedy <john.kennedy@delphix.com>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes  #13227

scripts/zfs-tests.sh
tests/test-runner/bin/test-runner.py.in

index 70d1e394427e14ac711b4357c4cece88c29320c4..1e0cf66d1cdc5bf2fb45206ec9e2412282997dbd 100755 (executable)
@@ -38,6 +38,7 @@ VERBOSE="no"
 QUIET=""
 CLEANUP="yes"
 CLEANUPALL="no"
+KMSG=""
 LOOPBACK="yes"
 STACK_TRACER="no"
 FILESIZE="4G"
@@ -325,6 +326,7 @@ OPTIONS:
        -q          Quiet test-runner output
        -x          Remove all testpools, dm, lo, and files (unsafe)
        -k          Disable cleanup after test failure
+       -K          Log test names to /dev/kmsg
        -f          Use files only, disables block device tests
        -S          Enable stack tracer (negative performance impact)
        -c          Only create and populate constrained path
@@ -356,7 +358,7 @@ $0 -x
 EOF
 }
 
-while getopts 'hvqxkfScRmn:d:s:r:?t:T:u:I:' OPTION; do
+while getopts 'hvqxkKfScRmn:d:s:r:?t:T:u:I:' OPTION; do
        case $OPTION in
        h)
                usage
@@ -374,6 +376,9 @@ while getopts 'hvqxkfScRmn:d:s:r:?t:T:u:I:' OPTION; do
        k)
                CLEANUP="no"
                ;;
+       K)
+               KMSG="yes"
+               ;;
        f)
                LOOPBACK="no"
                ;;
@@ -702,11 +707,13 @@ REPORT_FILE=$(mktemp_file zts-report)
 msg "${TEST_RUNNER}" \
     "${QUIET:+-q}" \
     "${KMEMLEAK:+-m}" \
+    "${KMSG:+-K}" \
     "-c \"${RUNFILES}\"" \
     "-T \"${TAGS}\"" \
     "-i \"${STF_SUITE}\"" \
     "-I \"${ITERATIONS}\""
 ${TEST_RUNNER} ${QUIET:+-q} ${KMEMLEAK:+-m} \
+    ${KMSG:+-K} \
     -c "${RUNFILES}" \
     -T "${TAGS}" \
     -i "${STF_SUITE}" \
index b40b8de7285ae3866adbe0bb7d51b4ee399786c1..4e439d2b5624a78ad343fe6256deacdc22cb54be 100755 (executable)
@@ -39,6 +39,7 @@ from subprocess import Popen
 from subprocess import check_output
 from threading import Timer
 from time import time
+from os.path import exists
 
 BASEDIR = '/var/tmp/test_results'
 TESTDIR = '/usr/share/zfs/'
@@ -264,7 +265,7 @@ User: %s
 
         return out.lines, err.lines
 
-    def run(self, dryrun, kmemleak):
+    def run(self, dryrun, kmemleak, kmsg):
         """
         This is the main function that runs each individual test.
         Determine whether or not the command requires sudo, and modify it
@@ -283,6 +284,18 @@ User: %s
         except OSError as e:
             fail('%s' % e)
 
+        """
+        Log each test we run to /dev/kmsg (on Linux), so if there's a kernel
+        warning we'll be able to match it up to a particular test.
+        """
+        if kmsg is True and exists("/dev/kmsg"):
+            try:
+                kp = Popen([SUDO, "sh", "-c",
+                            f"echo ZTS run {self.pathname} > /dev/kmsg"])
+                kp.wait()
+            except Exception:
+                pass
+
         self.result.starttime = monotonic_time()
 
         if kmemleak:
@@ -467,14 +480,14 @@ Tags: %s
 
         cont = True
         if len(pretest.pathname):
-            pretest.run(options.dryrun, False)
+            pretest.run(options.dryrun, False, options.kmsg)
             cont = pretest.result.result == 'PASS'
             pretest.log(options)
 
         if cont:
-            test.run(options.dryrun, options.kmemleak)
+            test.run(options.dryrun, options.kmemleak, options.kmsg)
             if test.result.result == 'KILLED' and len(failsafe.pathname):
-                failsafe.run(options.dryrun, False)
+                failsafe.run(options.dryrun, False, options.kmsg)
                 failsafe.log(options, suppress_console=True)
         else:
             test.skip()
@@ -482,7 +495,7 @@ Tags: %s
         test.log(options)
 
         if len(posttest.pathname):
-            posttest.run(options.dryrun, False)
+            posttest.run(options.dryrun, False, options.kmsg)
             posttest.log(options)
 
 
@@ -585,7 +598,7 @@ Tags: %s
 
         cont = True
         if len(pretest.pathname):
-            pretest.run(options.dryrun, False)
+            pretest.run(options.dryrun, False, options.kmsg)
             cont = pretest.result.result == 'PASS'
             pretest.log(options)
 
@@ -598,9 +611,9 @@ Tags: %s
             failsafe = Cmd(self.failsafe, outputdir=odir, timeout=self.timeout,
                            user=self.failsafe_user, identifier=self.identifier)
             if cont:
-                test.run(options.dryrun, options.kmemleak)
+                test.run(options.dryrun, options.kmemleak, options.kmsg)
                 if test.result.result == 'KILLED' and len(failsafe.pathname):
-                    failsafe.run(options.dryrun, False)
+                    failsafe.run(options.dryrun, False, options.kmsg)
                     failsafe.log(options, suppress_console=True)
             else:
                 test.skip()
@@ -608,7 +621,7 @@ Tags: %s
             test.log(options)
 
         if len(posttest.pathname):
-            posttest.run(options.dryrun, False)
+            posttest.run(options.dryrun, False, options.kmsg)
             posttest.log(options)
 
 
@@ -1068,6 +1081,8 @@ def parse_args():
     parser.add_option('-i', action='callback', callback=options_cb,
                       default=TESTDIR, dest='testdir', type='string',
                       metavar='testdir', help='Specify a test directory.')
+    parser.add_option('-K', action='store_true', default=False, dest='kmsg',
+                      help='Log tests names to /dev/kmsg')
     parser.add_option('-m', action='callback', callback=kmemleak_cb,
                       default=False, dest='kmemleak',
                       help='Enable kmemleak reporting (Linux only)')