fix(slurm): don't restart slurmctld on a topology-only reconfigure - #6236
fix(slurm): don't restart slurmctld on a topology-only reconfigure#6236nir0s wants to merge 1 commit into
Conversation
update_topology() runs on every node power-up, so the unconditional slurmctld restart added to scontrol_reconfigure() in GoogleCloudPlatform#4609 puts a controller restart on the autoscaling hot path. Nodes that register during the restart window are then falsely flagged not responding. Make the restart opt-out and have the topology path skip it; the config-change path is unchanged.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses an issue where frequent Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces an option to skip restarting the slurmctld daemon during configuration updates, preventing node flapping during topology updates. The review feedback suggests a valuable optimization: when a daemon restart is performed, running scontrol reconfigure is redundant and can cause race conditions. The reviewer recommends only running scontrol reconfigure when restart is False, and provides suggestions to update both the implementation and its unit tests accordingly.
| if restart: | ||
| log.info("Running systemctl restart slurmctld.service") | ||
| run("sudo systemctl restart slurmctld.service", timeout=30) | ||
| log.info("Running scontrol reconfigure") | ||
| run(f"{lkp.scontrol} reconfigure") |
There was a problem hiding this comment.
When restart is True, slurmctld is restarted. A restarted daemon will automatically read all configuration files upon startup, making a subsequent scontrol reconfigure completely redundant. Furthermore, running scontrol reconfigure immediately after a restart can introduce a race condition where the command fails because the daemon is not yet fully initialized and listening for connections. It is safer and more efficient to only run scontrol reconfigure when restart is False.
| if restart: | |
| log.info("Running systemctl restart slurmctld.service") | |
| run("sudo systemctl restart slurmctld.service", timeout=30) | |
| log.info("Running scontrol reconfigure") | |
| run(f"{lkp.scontrol} reconfigure") | |
| if restart: | |
| log.info("Running systemctl restart slurmctld.service") | |
| run("sudo systemctl restart slurmctld.service", timeout=30) | |
| else: | |
| log.info("Running scontrol reconfigure") | |
| run(f"{lkp.scontrol} reconfigure") |
| commands = [c.args[0] for c in mock_run.call_args_list] | ||
| assert "scontrol reconfigure" in commands | ||
| assert ("sudo systemctl restart slurmctld.service" in commands) == expect_restart |
There was a problem hiding this comment.
Update the test assertions to match the updated behavior where scontrol reconfigure is only executed when restart is False.
| commands = [c.args[0] for c in mock_run.call_args_list] | |
| assert "scontrol reconfigure" in commands | |
| assert ("sudo systemctl restart slurmctld.service" in commands) == expect_restart | |
| commands = [c.args[0] for c in mock_run.call_args_list] | |
| if expect_restart: | |
| assert "sudo systemctl restart slurmctld.service" in commands | |
| assert "scontrol reconfigure" not in commands | |
| else: | |
| assert "sudo systemctl restart slurmctld.service" not in commands | |
| assert "scontrol reconfigure" in commands |
|
Additional evidence, from 49 days of production I correlated every Every Restart rate on the same log, per day: 16, 24, 16, 8, 10, 16, 10, 4, 28, 16, 10, 22 — i.e. ~15/day typical, 28 peak, all from the This is what the PR removes: the topology path no longer restarts, so the window in which a registering node can be falsely flagged no longer opens on every scale event. (Full disclosure on scope: this is natural-history evidence that the restart causes the flags. Validation that the patched build behaves correctly — specifically that a plain |
|
Hi @nir0s Could you please take a look at the Gemini suggestions? Thanks |
|
/gcbrun |
Problem
util.scontrol_reconfigure()has two callers inslurmsync.py:reconfigure_slurm()cloud.conf)update_topology()#4609 moved an unconditional
systemctl restart slurmctld.serviceinto that shared helper. It is reasonable for the first caller(which already restarted explicitly on the line above). But it also applied to the second, which had
been doing a plain
scontrol reconfigure— so since then an autoscaling cluster restarts itscontroller once per scale event. On our cluster that is ~25 slurmctld restarts/day.
The restart is not harmless. A node that registers within 300 s of a slurmctld restart is
subsequently flagged
not responding, and jobs running on it are requeued.Evidence
Reproduced on demand on a live cluster, 4/4, on idle and busy nodes:
The flag fires at exactly restart + 300 s on a node that registers in the seconds after the
restart. A node that was already steady before the restart is unaffected.
A plain
scontrol reconfigure(no restart) does not reproduce it.It is immune to every relevant configured timeout — each varied to a distinct value and confirmed
live via
scontrol show configacross the restart:SlurmdTimeout= 150 / 200 / 450ResumeTimeout= 600 (global and partition)SuspendTimeout= 500BatchStartTimeout= 500300 s is Slurm's default
SlurmdTimeout, which suggests a node registering just after a restartis health-checked against the default rather than the configured value. That part may well be a
Slurm-side issue — but it is only reachable because we restart slurmctld on the hot path.
This is most visible on slow-provisioning machine types. Ours (
h4d-standard-192with Cloud RDMA)takes 563–576 s to provision and register, so during a batch bring-up node N's power-up restarts the
controller while node N+1 is still registering. Faster types tend to register before the restart
their own power-up triggers, so they never land in the window — which is likely why this has not been
widely reported.
Fix
Make the restart opt-out on the helper, and have the topology path skip it. A topology change takes
effect on
scontrol reconfigure(per thetopology.confman page), so the restart is not neededthere. The config-change path in
reconfigure_slurm()is deliberately left untouched — node-setreconciliation may genuinely require the restart, and this change is scoped not to alter it. In effect
this restores the pre-#4609 behaviour for the topology path only.
Testing
tests/test_util.pyassertingscontrol reconfigurealways runsand the restart is opt-out.
173 passed.