From 184c031857fe6fd9d37306619a554b1d3a0320a0 Mon Sep 17 00:00:00 2001 From: Simon Lindholm Date: Wed, 13 May 2026 15:45:31 +0200 Subject: [PATCH 1/2] Fix controller hang when submission exits early --- cms/grading/tasktypes/interactive_keeper.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cms/grading/tasktypes/interactive_keeper.py b/cms/grading/tasktypes/interactive_keeper.py index 0399cb77c9..26bd705fff 100644 --- a/cms/grading/tasktypes/interactive_keeper.py +++ b/cms/grading/tasktypes/interactive_keeper.py @@ -87,10 +87,8 @@ def main(): for i in range(process_limit): c_to_u_r, c_to_u_w = os.pipe() u_to_c_r, u_to_c_w = os.pipe() - os.set_inheritable(c_to_u_r, True) os.set_inheritable(c_to_u_w, True) os.set_inheritable(u_to_c_r, True) - os.set_inheritable(u_to_c_w, True) pipes.append({"c_to_u": (c_to_u_r, c_to_u_w), "u_to_c": (u_to_c_r, u_to_c_w)}) controller_sandbox = Sandbox(0, shard, name="controller", temp_dir=temp_dir) @@ -165,7 +163,8 @@ def main(): wait=False, ) - os.close(p["c_to_u"][0]) + # We do not close p["c_to_u"][0] -- it only risks crashing the + # controller with SIGPIPE if the submission exits early. os.close(p["u_to_c"][1]) try: From e0af54703bebd27caaceedd15a762affe380f94f Mon Sep 17 00:00:00 2001 From: Simon Lindholm Date: Wed, 13 May 2026 16:02:55 +0200 Subject: [PATCH 2/2] Improve error handling for hung interactive keeper --- cms/grading/tasktypes/Interactive.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cms/grading/tasktypes/Interactive.py b/cms/grading/tasktypes/Interactive.py index 9f3d8b1498..b2fad2a8aa 100644 --- a/cms/grading/tasktypes/Interactive.py +++ b/cms/grading/tasktypes/Interactive.py @@ -252,7 +252,11 @@ def evaluate(self, job, file_cacher): stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, ) - stdout, _ = p.communicate(timeout=self.controller_wall_limit * 2) + try: + stdout, _ = p.communicate(timeout=self.controller_wall_limit * 2) + except subprocess.TimeoutExpired: + p.kill() + stdout, _ = p.communicate() KEEPER_ERROR_MESSAGE = "Internal error in interactive keeper"