Skip to content

feat(sdk): capture firecracker stdio via console_path#6

Draft
PeronGH wants to merge 1 commit into
fix/validate-vm-idfrom
feat/stdio-capture
Draft

feat(sdk): capture firecracker stdio via console_path#6
PeronGH wants to merge 1 commit into
fix/validate-vm-idfrom
feat/stdio-capture

Conversation

@PeronGH

@PeronGH PeronGH commented Apr 24, 2026

Copy link
Copy Markdown

Depends on #5 — this branch is based on fix/validate-vm-id, so hold off on merging until that lands. Will retarget to master once #5 is in.

Summary

Firecracker pipes the guest serial console (ttyS0) to its own stdout. FirecrackerProcessBuilder::spawn was leaving stdio on inherit, so the kernel boot log landed wherever the parent's stdout happened to go — and if that parent's stdout closed (e.g. piped through head), firecracker spammed Failed the write to serial: BrokenPipe into its own log-path file. Long-running callers like arcbox-agent couldn't actually see whether the kernel made it to userspace.

This PR adds four additive knobs to FirecrackerProcessBuilder:

  • console_path(path) — the common case. Opens the file in create+append mode at spawn() time and routes both stdout and stderr to it (the stderr fd is a try_clone of the stdout fd, so they land in the same file). Matches the existing log_path / metrics_path style.
  • stdin(Stdio) / stdout(Stdio) / stderr(Stdio) — raw std::process::Stdio overrides for callers that need Stdio::null(), Stdio::piped(), or a specific File.

Resolution order at spawn(): explicit per-channel override wins, else console_path fills any unset stdout/stderr, else the channel inherits from the parent (today's default). Refactored into apply_stdio so the decision matrix is testable without a live firecracker binary.

fc-cli gains a --console-path flag on the firecracker backend; the jailer backend rejects it with a clear error for now. JailerProcessBuilder carries a TODO near its spawn documenting the follow-up — jailer's --daemonize detaches stdio, so the semantics need their own design.

Additive only — bump 0.3.00.3.1.

Test plan

  • `cargo test -p fc-sdk` — 21 unit tests pass (five new for `apply_stdio`: both-channels-to-console, explicit override wins per channel, append preserves prior content, missing parent dir surfaces as `Error::Io`, no-config noop), plus existing vm_id / builder / doc-tests.
  • `cargo test --workspace` — full suite green.
  • `cargo clippy --workspace --all-targets -- -D warnings` — clean.
  • `cargo fmt --check` — clean.
  • Manual repro (reviewer-side): `fc-cli start --console-path /tmp/fc-con.log --kernel ... --rootfs ...` against a bootable template; `/tmp/fc-con.log` should contain the kernel boot messages, and firecracker's own `--log-path` file should be free of `BrokenPipe` spam.

Firecracker pipes the guest serial console (ttyS0) to its own
stdout, and FirecrackerProcessBuilder::spawn was leaving stdio
on inherit — so kernel boot output landed wherever the parent's
stdout happened to go, and a closed parent pipe produced
`Failed the write to serial: BrokenPipe` spam in firecracker's
own log file.

Add four additive knobs to FirecrackerProcessBuilder:

- console_path(path): open the file in create+append mode at
  spawn time; use it for stdout and stderr (cloned fd) unless
  a per-channel override is set. Typical use: capturing the
  guest serial console into an instance-local log file.
- stdin(Stdio) / stdout(Stdio) / stderr(Stdio): raw Stdio
  overrides for callers that need finer control.

Resolution is "explicit per-channel override wins, then
console_path, then command default (inherit)". Factored into
`apply_stdio` so the matrix is testable without a live
firecracker binary.

fc-cli gains a --console-path flag on the firecracker backend;
the jailer backend rejects it for now (TODO near the jailer
builder spawn documents a follow-up).

Additive only — bump 0.3.0 -> 0.3.1.
@PeronGH PeronGH force-pushed the feat/stdio-capture branch from 5d750db to a0a63ac Compare May 8, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant