[config reload] Skip swss readiness check when swss is not present#4606
Conversation
config reload's pre-flight gate calls _swss_ready(), which fails on platforms that do not ship the swss container (e.g. BMC): swss.service reads LoadState=not-found, so the gate blocks reload unless -f is passed. Treat a swss service whose LoadState is not-found or masked as "nothing to wait for" in _per_namespace_swss_ready(), so config reload proceeds without -f. No behavior change on platforms that ship swss, where swss.service is loaded and the existing active/settle checks still apply. Add unit tests for the not-found/masked (ready) paths and regression guards for the loaded/inactive and active/settle behavior. Signed-off-by: William Tsai <willtsai@nvidia.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…ready Signed-off-by: William Tsai <willtsai@nvidia.com>
a96364e to
392d456
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
yxieca
left a comment
There was a problem hiding this comment.
Nice, well-targeted fix. config reload without -f was effectively deadlocked on platforms that don't ship the swss container (BMC), since the readiness gate waited on a swss.service that doesn't exist. Checking systemd LoadState first and treating not-found/masked as "nothing to wait for" is the right call, and it's at the correct abstraction layer — the function that probes the service decides from systemd ground truth, rather than threading a platform conditional through the reload path.
I verified the important properties:
- Switch behavior is provably unchanged. The change is purely additive (
+5/-0, no existing line touched). A swss-shipping switch reportsLoadState=loaded, so the new branch is skipped and the existingActiveState=="active"+ 120s-settle logic runs verbatim. - Failure modes fail safe. Empty/garbage/failed-
systemctloutput (out.strip()not in the tuple) falls through to the existing ActiveState check →!= active→ not ready. So there's no path where a switch that should have swss wrongly skips the wait.not-foundalso can't transiently fire on a real switch — an installed unit file reportsloadedlong beforeconfig reloadruns. - Including
maskedis correct, not scope creep — it's the same deadlock class (a masked unit can never become active). - Tests are great for a 5-line change: both new paths (with
call_count == 1asserting the short-circuit) plus regression guards for theloaded/inactive/active/settle behavior, and the settle-math mocks match the production formula.
Two small, non-blocking suggestions:
-
Optional multi-ASIC
not-foundtest._swss_ready()already has a single-ASIC not-found end-to-end case; aget_num_asics() == 2case with bothswss@0/1reportingnot-foundwould round out coverage. The multi-ASIC iteration itself is unchanged code, so this is belt-and-suspenders rather than a gap. -
Docstring on the overloaded return.
_per_namespace_swss_ready()now returnsTruefor both "swss active and settled" and "swss absent." That's exactly right for this gate (both mean "safe to proceed"), but a one-line docstring noting the contract is "safe to proceed past the swss gate" (not "swss is active") would prevent a future caller from misreading it.
Neither blocks. Approving.
AI agent on behalf of Ying.
|
Cherry-pick PR to msft-202608: Azure/sonic-utilities.msft#384 |
…onic-net#4606) - What I did config reload (without -f) fails on platforms that do not ship the swss container (e.g. BMC) with swss container is not ready. Retry later or use -f to avoid system checks. The readiness gate waits on a swss.service that does not exist on such images, so reload can never proceed without -f. This makes the gate skip the wait when swss is not present. - How I did it In _per_namespace_swss_ready(), check the service's systemd LoadState first. If it is not-found (service not built into the image) or masked, return ready — there is no swss to wait for. Platforms that ship swss read LoadState=loaded, so the existing active/120s-settle checks are unchanged. Added unit tests for the not-found/masked paths and regression guards for the loaded/inactive and active/settle behavior. - How to verify it pytest tests/config_test.py::TestSwssReady On a platform without swss (swss.service is not-found): config reload -y proceeds instead of aborting. On a switch that ships swss: behavior is unchanged (still waits until swss has been active for >120s). Previous command output (if the output of a command-line utility has changed) root@sonic:~# config reload -y Acquired lock on /etc/sonic/reload.lock swss container is not ready. Retry later or use -f to avoid system checks Released lock on /etc/sonic/reload.lock New command output (if the output of a command-line utility has changed) root@sonic:~# config reload -y Acquired lock on /etc/sonic/reload.lock Running command: ... # reload proceeds normally Released lock on /etc/sonic/reload.lock Signed-off-by: William Tsai <willtsai@nvidia.com> Signed-off-by: Yogapriya Mohankumar <ymohanku@cisco.com>
What I did
config reload(without-f) fails on platforms that do not ship the swss container (e.g. BMC) withswss container is not ready. Retry later or use -f to avoid system checks. The readiness gate waits on aswss.servicethat does not exist on such images, so reload can never proceed without-f. This makes the gate skip the wait when swss is not present.How I did it
In
_per_namespace_swss_ready(), check the service's systemdLoadStatefirst. If it isnot-found(service not built into the image) ormasked, return ready — there is no swss to wait for. Platforms that ship swss readLoadState=loaded, so the existing active/120s-settle checks are unchanged. Added unit tests for the not-found/masked paths and regression guards for the loaded/inactive and active/settle behavior.How to verify it
pytest tests/config_test.py::TestSwssReadyswss.serviceisnot-found):config reload -yproceeds instead of aborting.Previous command output (if the output of a command-line utility has changed)
New command output (if the output of a command-line utility has changed)