mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] jobserver: Handle read errors before claiming a slot
@ 2026-11-07  5:17 Shanmugapriyan S
  0 siblings, 0 replies; only message in thread
From: Shanmugapriyan S @ 2026-11-07  5:17 UTC (permalink / raw)
  To: mchehab, corbet; +Cc: skhan, rdunlap, linux-doc, linux-kernel, Shanmugapriyan S

If os.read() fails with an error other than EWOULDBLOCK before any
jobserver tokens are collected, the error handler falls through to
self.jobs += slot. Since slot was never assigned, this raises
UnboundLocalError instead of gracefully disabling jobserver parallelism.

Keep returning collected tokens conditional, but reset the claim, warn, and
return for every unexpected read error. Add a regression test that injects
EIO on the first read.

OpenAI Codex assisted with finding the issue and developing the fix and
regression test.

Fixes: b2664a90c171 ("jobserver: Split up the big try: block")
Signed-off-by: Shanmugapriyan S <sundar25sengai@gmail.com>
---
 tools/lib/python/jobserver.py     |  6 ++---
 tools/unittests/test_jobserver.py | 43 +++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 3 deletions(-)
 create mode 100644 tools/unittests/test_jobserver.py

diff --git a/tools/lib/python/jobserver.py b/tools/lib/python/jobserver.py
index 7e94635bf..c8f220a36 100755
--- a/tools/lib/python/jobserver.py
+++ b/tools/lib/python/jobserver.py
@@ -154,9 +154,9 @@ class JobserverExec:
                 #
                 if self.jobs:
                     os.write(self.writer, self.jobs)
-                    self.claim = None
-                    warn('error reading from jobserver pipe', repr(e))
-                    return
+                self.claim = None
+                warn('error reading from jobserver pipe', repr(e))
+                return
             self.jobs += slot
         #
         # Add a bump for our caller's reserveration, since we're just going
diff --git a/tools/unittests/test_jobserver.py b/tools/unittests/test_jobserver.py
new file mode 100644
index 000000000..eafac510c
--- /dev/null
+++ b/tools/unittests/test_jobserver.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""Unit tests for the GNU make jobserver helper."""
+
+import errno
+import os
+import sys
+import unittest
+
+from unittest.mock import patch
+
+
+SRC_DIR = os.path.dirname(os.path.realpath(__file__))
+sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python"))
+
+from jobserver import JobserverExec
+from unittest_helper import run_unittest
+
+
+class TestJobserverExec(unittest.TestCase):
+    """Test jobserver error handling."""
+
+    @patch.dict(os.environ, {"MAKEFLAGS": "--jobserver-auth=3,4"})
+    @patch("jobserver.warn")
+    @patch("jobserver.os.read", side_effect=OSError(errno.EIO, "I/O error"))
+    @patch("jobserver.os.open", return_value=5)
+    def test_read_error_without_claimed_jobs(self, mock_open, mock_read,
+                                             mock_warn):
+        """A first-read failure disables jobserver use without crashing."""
+        jobserver = JobserverExec()
+
+        jobserver.open()
+
+        self.assertIsNone(jobserver.claim)
+        mock_open.assert_called_once_with("/proc/self/fd/3",
+                                          os.O_RDONLY | os.O_NONBLOCK)
+        mock_read.assert_called_once_with(5, 8)
+        mock_warn.assert_called_once()
+
+
+if __name__ == "__main__":
+    run_unittest(__file__)

base-commit: d48723711bae9b8cdc56719c448ba42fef28cbee
-- 
2.43.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-11-07  5:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-07  5:17 [PATCH] jobserver: Handle read errors before claiming a slot Shanmugapriyan S

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®