fix(minimald): bound the boot-path gvproxy expose so it can't stall SSH accept - #676
fix(minimald): bound the boot-path gvproxy expose so it can't stall SSH accept#676norrietaylor wants to merge 1 commit into
Conversation
…SH accept start_host_proxies awaits expose_proxy_on_host on Server::run's boot path, before the SSH accept loop begins serving. When no host gvproxy answers (none configured), that await runs to the full 5s GVPROXY_CONTROL_TIMEOUT, holding the accept loop closed. The cold `minimal ls` connect-retry deadline (~5s) then expires just as the loop would resume, so the first list fails with `ssh connect: Disconnected`. main clears this by only a ~40ms margin, relying on client retries landing the instant the loop unblocks. Cap the publish at HOST_EXPOSE_PUBLISH_TIMEOUT (1s) so the accept loop is never held more than briefly; a present gvproxy answers in well under it. Best-effort semantics are unchanged (a timeout warns and continues). Refs: #588
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded a ChangesPublish Timeout Handling
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Server as minimald server
participant Timeout as tokio::time::timeout
participant Forwarder as host gvproxy forwarder
Server->>Timeout: expose_proxy_on_host -> post_json(/services/forwarder/expose)
Timeout->>Forwarder: forward request
alt success within HOST_EXPOSE_PUBLISH_TIMEOUT
Forwarder-->>Timeout: Ok response
Timeout-->>Server: success (no-op)
else forwarder error
Forwarder-->>Timeout: Err response
Timeout-->>Server: warn forwarder error
else timeout elapsed
Timeout-->>Server: warn timeout, continue
end
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
Problem
autospawn-e2eis green onmainbut only by a ~40 ms margin, and it's a pre-existing latent flake — surfaced while working the volume PR (#672), whose extra ~60 ms first-boot cost tips it red.Root cause (from the green-main boot log):
start_host_proxiesawaitsexpose_proxy_on_hostonServer::run's boot path, before the SSH accept loop serves. When no host gvproxy answers — which is always the case in theautospawn-e2ejob (noMINVMD_GVPROXY_BIN) — that await runs to the full 5 sGVPROXY_CONTROL_TIMEOUT, holding the accept loop closed:The cold
minimal lsclears it only because the CLI retries and one retry lands the instant the loop unblocks at ~5 s. Any perturbation past that edge (CI load, or #672's mkfs) flips it tossh connect: Disconnected.In production this never happens — a host gvproxy is present, so the expose returns in <100 ms and the accept loop is never delayed.
Fix
Cap the best-effort publish at
HOST_EXPOSE_PUBLISH_TIMEOUT(1 s), so a missing/slow gvproxy can't hold the accept loop near the CLI's retry deadline. The accept loop now resumes at ~1.6 s (vs ~5 s) — a multi-second margin instead of 40 ms. Best-effort semantics unchanged (timeout warns and continues); when a gvproxy is present the 1 s cap never triggers.Validation
cross clippy -p minimald --features networking-proxy,networking-wg --target aarch64-unknown-linux-musl -- -D warnings→ clean.autospawn-e2eonmain; also unblocks feat(minvmd,minimald): per-VM writable /dev/vdb ext4 volume #672'sautospawn-e2eonce feat(minvmd,minimald): per-VM writable /dev/vdb ext4 volume #672 rebases onto this.Refs: #588
Summary by CodeRabbit