Repository navigation
fix(runtime): reclaim TAP devices orphaned by a crashed manager - #203
Merged
Merged
Conversation
`cancel()` removes a VM's TAP, but a manager that is SIGKILLed or crashes never
gets to run it. The device — and the /30 assigned to it — then stays on the host
forever: the subnet allocator skips that block, and orphans accumulate until the
host has duplicate routes for the same network and replies leave via a dead
device. This was the one leak path the earlier teardown fixes could not cover,
because no in-process cleanup runs when the process is killed outright.
The manager now sweeps once at startup, before any VM is scheduled.
The safety question is not deleting a TAP that a LIVE VM still uses — that would
cut its only link. A TAP whose VMM is alive holds its carrier and reports UP;
when the process goes away the carrier drops and it falls to DOWN. Only DOWN
devices carrying the `fc-` prefix are reclaimed, so a running VM's TAP is never
touched and neither is any host networking.
Parsing is split into a pure `orphaned_tap_names` so that rule is testable: a
live (UP) TAP is never selected, non-Lantern devices (lo, eth0, docker0, tap0)
are ignored, and `dev@if7` suffixes and malformed lines are survivable.
Verified on real KVM, both directions:
- two planted DOWN taps plus a non-Lantern `nottap0` -> found 2, removed 2,
`nottap0` untouched.
- a VM left running while its manager was SIGKILLed, then restarted ->
reconcile removed nothing; the VM's TAP and its firecracker process were
both still alive afterwards.
350 manager tests pass (4 new), clippy and rustfmt clean.
Contributor
🔎 Codex cross-audit (agent:audit)Blocking
Non-blocking
I did not run tests; this was a read-only audit of |
Contributor
🧪 QA — ❌ tests failing |
Contributor
🔷 Gemini cross-audit (agent:audit-gemini)Audit Report: Startup Reconciliation of Orphaned TAP DevicesBlocking Issues
Correctness, Performance & Robustness Bottlenecks1. Unnecessary Retries and Startup Stalls on Orphan Reconciliation (Performance / Robustness)
Missed Edge Cases2. Race Conditions in Multi-Instance Manager Deployments (Operational Edge Case)
3. Hard Dependency on
|
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.
Closes the last TAP leak path — the one the earlier teardown fixes structurally could not cover.
The gap
cancel()removes a VM's TAP, but a manager that is SIGKILLed or crashes never runs it. The device — and the /30 assigned to it — then stays on the host forever: the subnet allocator skips that block, and orphans accumulate until the host has duplicate routes for the same network and replies leave via a dead device.No in-process cleanup can fix this, because the process is gone. So the manager now sweeps once at startup, before any VM is scheduled.
The safety question
Not deleting a TAP that a live VM still uses — that would cut its only link.
A TAP whose VMM is alive holds its carrier and reports
UP; when the process goes away the carrier drops and it falls toDOWN. OnlyDOWNdevices with thefc-prefix are reclaimed, so a running VM's TAP is never touched, and neither is any host networking.Parsing is split into a pure
orphaned_tap_namesso that rule is directly testable:UP) TAP is never selectedlo,eth0,docker0,tap0) are ignoreddev@if7suffixes and malformed lines are survivableVerified on real KVM — both directions
nottap0nottap0untouchedThe second is the one that matters: it's the exact scenario reconciliation could get catastrophically wrong.
350 manager tests pass (4 new), clippy and rustfmt clean.