Repository navigation
Description
Consolidated scope covering every remaining "daemon must die cleanly and not leak state" concern. Expanded during the 2026-04-17 issue consolidation to absorb the SO_LINGER 0 half of the old B5a hardening item.
Checklist
-
Process containment via
running-process(original Daemon teardown hardening: process containment + socket lingering + console events #32 scope)
Adoptrunning-process'sContainedProcessGroup/Containmentprimitives for spawned subprocesses so child / grandchild process trees die with the daemon. Windows uses Job Objects with kill-on-close semantics; Linux/macOS use process groups with Linux parent-death handling. Symptoms today: orphanedbash.exe,conhost.exe,OpenConsole.exeon Windows after higher-level jobs disappear. Add an integration test that kills the parentfbuildprocess and asserts child + grandchild cleanup on Windows. -
SO_LINGER 0on accepted client sockets (was Outstanding work: ledger removal, send_op errors, async API, B5a hardening, espflash native, sector-selective flashing #18 item 4b)
After a hard kill, danglingCLOSE_WAITstate on sockets accepted by the daemon's axum listener can outlive the daemon. SettingSO_LINGER 0on every accepted socket forces an immediateRSTon close instead of the FIN / CLOSE_WAIT / TIME_WAIT dance. Requires hooking into the axum accept loop or implementing a customListener/IncomingStreamwrapper. Regression test exists atcrates/fbuild-daemon/tests/port_recovery.rs(run with--ignored). -
SetConsoleCtrlHandlerfor Windows CTRL_CLOSE / LOGOFF / SHUTDOWN events (was Outstanding work: ledger removal, send_op errors, async API, B5a hardening, espflash native, sector-selective flashing #18 item 4a) — merged in PR feat(daemon): Windows console ctrl handler for graceful shutdown (#18) #61
Why one issue
All three mechanisms target the same outcome: a daemon that terminates cleanly under every termination path (graceful, Ctrl+C, window close, logoff, shutdown, hard-kill) without leaking child processes, sockets, or file handles. Keeping them in one tracker makes it clear which hardening surfaces remain.
Context
The sidecar concern that zccache may also participate in the Windows orphan chain — see original scope note below — still warrants a linked issue in the zccache repo once process containment lands here.
Original scope (preserved for reference)
fbuildshould move daemon and long-lived subprocess management over torunning-processso child/grandchild trees are explicitly contained and torn down on parent exit.We are seeing orphaned shell / console-host processes in Windows (
bash.exe,conhost.exe,OpenConsole.exe) after higher-level jobs disappear. The current failure mode looks like a process-management gap, not just a one-off hung command.Why
running-process: Recentrunning-processwork already added the containment primitives needed for this —ContainedProcessGroup/Containmentin commits 4fccf1b and 868faa1. Windows uses Job Objects with kill-on-close semantics; Linux/macOS use process groups, with extra Linux parent-death handling. Tests explicitly cover killing contained children and grandchildren.Requested change: Use
running-processfor all daemon / worker / background process spawning in fbuild, especially on Windows. Wrap daemon lifetime inContainedProcessGroup. Ensure every subprocess that should die withfbuildis spawned as contained, not detached. Reserve detached mode only for intentionally persistent daemons.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTriage
Activity
zackees commentedon Apr 11, 2026
Related zccache tracking issue: forge-ci/zccache#7
[-]Use running-process containment for daemon and subprocess lifecycle management[/-][+]Daemon teardown hardening: process containment + socket lingering + console events[/+]fix(daemon): set SO_LINGER 0 on accepted sockets to avoid CLOSE_WAIT …
fix(daemon): set SO_LINGER 0 on accepted sockets to avoid CLOSE_WAIT …
zackees commentedon Apr 18, 2026
Progress update — partial work merged since this issue was filed:
bind_listener_with_retrynow setsSO_LINGER=0on the listener so accepted sockets inherit it (relies on Linux/macOS/Windowsaccept(2)linger inheritance). Theport_recovery.rs --ignoredregression test passes.SetConsoleCtrlHandlerfor Windows CTRL_CLOSE / LOGOFF / SHUTDOWN — PR feat(daemon): Windows console ctrl handler for graceful shutdown (#18) #61 (already noted in the body)running-process— still open. Touches every subprocess spawn site; deferred to its own PR.Remaining scope is now just the
running-processadoption. Picking that up next.feat(daemon): process containment via running-process (closes #32)
feat(daemon): process containment via running-process (closes #32)
feat(daemon): process containment via running-process (closes #32)
feat(daemon): process containment via running-process (closes #32)
chore(deps): adopt upstream soldr/zccache/setup-soldr updates (#253)
feat(zccache): embedded mandatory — delete wrapper fallback (#800, cl…