fix(gateway): don't accept systemd's not-found default for TimeoutStopUSec - #72943
Closed
henryberliand-design wants to merge 2 commits into
Closed
Conversation
…pUSec `systemctl show <unit>` never errors for a unit that isn't loaded under the manager you queried -- it returns rc=0 plus the compiled-in template defaults (LoadState=not-found, TimeoutStopUSec=1min 30s). Gateways installed as system-managed units (confirmed live in production with real TimeoutStopSec overrides) had their --user query "succeed" with this bogus default and never reached the system manager holding the real value, producing false-positive timeout-misalignment warnings. Now also fetch LoadState and only trust a TimeoutStopUSec whose unit is actually loaded under the manager that answered.
Collaborator
teknium1
reviewed
Jul 30, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for adding focused manager-selection regression coverage; the false-positive premise is verified on current main at gateway/shutdown_forensics.py:367-389.
Problems
gateway/shutdown_forensics.py:399rejects onlyLoadState=not-found, while the new comment atgateway/shutdown_forensics.py:374-375says the result must be trusted only when loaded. This accepts any other or absentLoadStateifTimeoutStopUSecparses. The existing canonical duplicate, #34734, uses the stricterload_state != "loaded"rejection.
Suggested changes
- Require
LoadState == "loaded"before assigningtimeout_us, matching #34734. - Preserve these useful mock tests and add a non-
loadedLoadState fallback case alongsidetests/gateway/test_shutdown_forensics.py:283-360.
Automated hermes-sweeper review.
| timeout_us = _parse_systemd_duration_to_us(value) | ||
| if timeout_us is not None: | ||
| break | ||
| if load_state == "not-found" or value is None: |
Contributor
There was a problem hiding this comment.
This should require load_state == "loaded", not merely reject not-found: the surrounding comment says values are trusted only for loaded units, and canonical duplicate #34734 uses that stricter guard. Otherwise any other or absent LoadState with a parseable timeout is accepted.
Unblocks contributor-check on PR #2 — the only failing gate; all 27 substantive checks pass.
henryberliand-design
deleted the
fix/systemd-timing-alignment-not-found-default
branch
July 31, 2026 01:48
This was referenced Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes a false-positive warning in the gateway's shutdown-timing diagnostics (
gateway/shutdown_forensics.py::check_systemd_timing_alignment) for any Hermes gateway installed as a system-managed systemd unit (e.g./etc/systemd/system/hermes-gateway-*.service) that carries a realTimeoutStopSec=override.Root cause:
systemctl show <unit> --property=TimeoutStopUSecdoes not error (rc=0) when the unit isn't loaded under the manager you queried — it silently returns systemd's compiled-in template default (TimeoutStopUSec=1min 30s) instead. The lookup tried--userfirst (the common case), took that rc=0 response at face value, and never fell through to the--systemmanager that actually owns the unit and holds the real timeout override. The result: gateways with a longer, deliberately-configuredTimeoutStopSecgot flagged with a bogus timing-misalignment warning based on the generic 90s default, not their real value.The fix: also request
--property=LoadStatein the samesystemctl showcall, and only trust aTimeoutStopUSecreading whoseLoadStateis actuallyloadedunder the manager that answered. If both--userand--systemreportnot-found, the function now correctly returnsNone("can't determine") instead of manufacturing a mismatch from the template default.Related Issue
No existing issue — found this via a false-positive warning in production on a system-managed gateway unit with a real
TimeoutStopSec=240override.Type of Change
Changes Made
gateway/shutdown_forensics.py: fetchLoadStatealongsideTimeoutStopUSecin thesystemctl showcall; skip any result whereLoadState=not-found, falling through to the next manager instead of accepting the compiled-in default.tests/gateway/test_shutdown_forensics.py: addedTestCheckSystemdTimingAlignmentManagerSelectionwith 3 regression tests:TimeoutStopSec=240override is correctly read from the--systemmanager instead of accepting the--usermanager's bogusnot-founddefault (mirrors a real production unit),LoadState=not-found) must returnNone, never a manufactured mismatch — this proves the fix doesn't just move the false positive somewhere else,--useris still accepted directly without needlessly falling through to--system.How to Test
pytest tests/gateway/test_shutdown_forensics.py -v— 33 tests pass, including the 3 new ones above.TimeoutStopSec=240(no matching--userunit loaded), then callcheck_systemd_timing_alignment()under that unit's cgroup — before this fix it reports a mismatch against the wrong 90s default; after, it correctly reads 240s from the system manager.Checklist
Code
fix(scope):)pytest tests/ -qand all tests pass (ran the fulltests/gateway/suite; 33/33 pass)Documentation & Housekeeping