Repository navigation
fix(controller): default n>1 REST spawns to per-child netns (fan-out unblocked) - #2
Merged
keeganmccallum merged 6 commits intoOct 10, 2026
Conversation
…unblocked)
POST /v1/sandboxes with n>1 and no explicit per_child_netns previously
503'd ('shared-TAP spawns with n>1 are not supported') — the shared
forkd-tap0 cannot back a concurrent multi-restore batch, blocking all
daemon-side fan-out (s2-03 receipt: 'REST n>1 fails - shared tap busy').
per_child_netns is now Option<bool>: absent => controller picks
(n=1 shared tap, n>1 per-child netns); explicit false with n>1 keeps
the 503. CLI flag defaults, n=1 behavior, and the workspace path are
unchanged.
Red-first: create_sandbox_n_gt_1_defaults_to_per_child_netns failed on
the old behavior with the exact production 503; green after the fix.
Explicit-false test pins the 503 stays.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
… -D warnings The inner 'use std::os::unix::fs::MetadataExt' at the diff-snapshot site makes the top-level import dead; Linux CI (cargo clippy --all-targets --all-features -D warnings) fails on it while macOS builds skip the cfg(target_os = "linux") import entirely, so it slipped through. Blocking release CI for v0.5.3-urun.2.
…T create) sync_guest_clocks blocked POST /v1/sandboxes on a 10s/child guest-agent poll. Agent-less snapshots (E2B-shaped envd images, no forkd-agent on :8888) burned the full budget every spawn: measured 10s on n=1 and 20-26s on n=2 on forkd-p0-1 while the restore itself took ~60ms. ForkOpts gains clock_sync_timeout_secs (0 = historical 10s default). The daemon's sandbox-create and workspace-spawn paths use 2s: a restored forkd-agent answers in well under a second, so real sync still lands; agent-less snapshots cap their penalty at 2s instead of 10s. Clock sync stays best-effort non-fatal (unchanged semantics). CLI paths keep the 10s default; sync_guest_clocks=false paths are untouched.
717846a threaded the agent-wait budget through ForkOpts but left the old const as a non-test definition — dead in lib builds (clippy noise, same class as d7914dc) — and shipped no guard pinning the default. Adds fork_opts_clock_sync_default_is_historical_10s (default stays 10s so CLI/restore keep their budget; 0 falls back, never a zero-second poll) and cfg(test)-gates the legacy const.
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
POST /v1/sandboxeswith n>1 and no explicitper_child_netnspreviously 503'd ('shared-TAP spawns with n>1 are not supported') — the sharedforkd-tap0cannot back a concurrent multi-restore batch, blocking all daemon-side fan-out (s2-03 receipt: 'REST n>1 fails - shared tap busy', reproduced live on forkd-p0-1).per_child_netnsbecomesOption<bool>: absent ⇒ controller picks (n=1 → shared tap, n>1 → per-child netns); explicitfalsewith n>1 keeps the 503. n=1 behavior and the workspace path unchanged.Follow-on (717846a): the clock-sync agent poll burned 10 s/child on agent-less (E2B-shaped envd) snapshots — measured 10.9 s for a 60 ms restore. ForkOpts gains
clock_sync_timeout_secs; daemon spawn paths use 2 s. 94db790 pins the 10 s default + test-gates the legacy const.Root cause (live repro on forkd-p0-1, stock v0.5.3 controller)
strings vmstateshowsforkd-tap0) → every child re-opens ONE host tap → second restore EBUSY (os error 16) → 500.work_dir(forkd-daemon-{tag}-o{offset}, check-then-actpick_netns_offset): two/snapshot/loadPUTs landed in ONE firecracker 5 ms apart; loser gotThe requested operation is not supported after starting the microVM. Our fork's fix(controller): bound netns allocator to provisioned namespaces deeplethe/forkd#282 NetnsAllocator (in this base) fixes that half.Proof (lane s3-01, forkd-p0-1 c3-standard-8)
create_sandbox_n_gt_1_defaults_to_per_child_netnsFAILED on parent 2e3f9ea with the exact production 503; green on the fix.create_sandbox_explicit_shared_tap_n_gt_1_still_503pins the explicit-false 503. 94db790 adds the clock-sync default pin.v0.5.3-urun.2→ 1093c62; release run 38026932175 green (tarball sha256 bc469592… = SHA256SUMS, verified on laptop AND node); running daemon's/proc/<pid>/exebyte-identical to the release controller (sha256 f77b2354…, checked across 3 daemon restarts). Live on that binary: n=2 absent-flag → 201 (forkd-child-1/2); n=10 absent-flag → 201, 10 children netns 3–12 disjoint; both batches cleaned 204. Node left at 0 live sandboxes.cargo test --workspacefailures inexperiments/PoC crates pre-exist on HEAD.Not in this PR (filed to owners)
publish-pypion v0.5.3-urun.2 failsinvalid-publisher: PyPI trusted-publisher still registered to deeplethe, needs PyPI-side registration for urun-sh (same failure on urun.1).re-point child rootfs … connect ENOENT/ECONNREFUSEDunder daemon-restart contention: feat(vmm): give every restored child its own rootfs backing deeplethe/forkd#321's fail-closed guard (base phase0-fork feature), for s3-02/s3-03 to re-test on a stable daemon + production rootfs.Merge: coordinator only (never self-merge). 717846a (clock-sync cap) is post-release: verify live on the node during lanes 02/03's re-test, then cut
-urun.3if desired.