fix(guest): init skips kernel-premounted targets, ending the false /dev ERROR#683
Conversation
…ev ERROR Every VM boot logged 'ERROR mount /dev: Resource busy': the guest kernel automounts devtmpfs on /dev (CONFIG_DEVTMPFS_MOUNT) before init runs, so init's own devtmpfs mount always returned EBUSY, was logged at ERROR, and execution continued. The line was benign and deterministic (14 occurrences in a fully green main firecracker-test run) but it got real CI failures misattributed to the guest; issue #668 itself was filed against it while the actual failures were the PTY stdin race (#670) and PR-local bugs. init now checks /proc/mounts before each mount-table entry: a target already carrying the expected fstype is skipped at info level; a target mounted with a different fstype is left in place and logged at ERROR (that state is genuinely unexpected); an unmounted target is mounted as before. is_mounted is refactored onto the same parser, which now returns the LAST matching /proc/mounts line so overmounts resolve to the visible mount. The firecracker-test boot smoke gains a regression gate: the serial log must not contain the false /dev ERROR. Verified: cargo test in rust:1-bookworm (privileged) passes 134 tests with the same 10 environment-dependent failures as origin/main baseline; the fork::volumes mount-namespace tests exercise the refactored is_mounted against real mounts. Closes #668. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Jannes Stubbemann <jannes@openclaw.rocks>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR makes guest init mount handling idempotent by adding a ChangesIdempotent Mount Handling
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant InitSystem as init_system
participant MountSys as mounted_fstype
participant PremountAction as premount_action
participant Kernel
InitSystem->>MountSys: mounted_fstype(m.target)
MountSys-->>InitSystem: existing fstype option
InitSystem->>PremountAction: premount_action(existing, want_fstype)
PremountAction-->>InitSystem: Mount / SkipSilently / SkipWithError
alt Mount decision
InitSystem->>Kernel: mount(m.source, m.target, m.fstype, 0)
else Skip decision
InitSystem->>InitSystem: log info or error
end
Related issues: Suggested labels: guest-agent, ci, bug-fix Suggested reviewers: Security-sensitive path reviewer for guest/agent-rs mount logic Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Thinking Path
Linked Issues or Issue Description
Closes #668.
What Changed
guest/agent-rs/src/sys/mount.rs: newmounted_fstype()returns the fstype mounted at a path from /proc/mounts; the parser (fstype_from_mounts) is a pure function, unit-tested on any host, and resolves overmounts to the LAST matching line (the visible mount).is_mounted()is refactored onto the same parser, semantics unchanged.guest/agent-rs/src/init/mod.rs: init decides per mount-table entry viapremount_action():Mountwhen nothing is mounted,SkipAlreadyMounted(info log) when the expected fstype is already there,SkipUnexpectedFstype(error log, mount left in place) when something else is. Decision logic is a pure function with unit tests..github/workflows/kvm-test.yaml: the boot smoke now fails if the serial log contains the falsemount /dev: Resource busyERROR, so the fix cannot silently regress.Verification
cargo test --libinrust:1-bookworm(privileged): 134 passed, and the SAME 10 environment-dependent failures (netlink dummy-link, in-container python kernel tests) as an origin/main baseline run in the identical container; zero regressions, 8 new tests pass.fork::volumesmount-namespace tests, which exercise the refactoredis_mountedagainst real mounts; they pass.rustfmt --check: the only diff in touched files within this change's regions is resolved; pre-existing hand-aligned regions (MOUNT_TABLE) left untouched.cargo clippy --lib: no new warnings introduced (checked for all new symbols).Risks
Low risk, but this is the PID-1 boot path of every guest (security-sensitive path, named human reviewer required). Behavior change: init no longer attempts to mount over an already-mounted target. For /dev this is strictly more correct (the EBUSY attempt was a no-op); for a hypothetical target premounted with a DIFFERENT fstype init now leaves it in place with an ERROR instead of stacking a mount over it, which is the more conservative and more visible behavior. No new interface, no secret handling, no threat-model surface move.
Model Used
claude-fable-5, extended thinking enabled, via Claude Code.Checklist
#NNN/ mitos-run/mitos URLs)Signed-off-bytrailer (git commit -s)Summary by CodeRabbit
Bug Fixes
New Features