feat: wire host balloon controls#873
Draft
enricoschaaf wants to merge 1 commit into
Draft
Conversation
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.
Summary
Wires host-driven memory balloon configuration through microsandbox and stacks it on the libkrun support in superradcompany/libkrun#59.
This adds app-level fields for the guest-visible boot target, the minimum guest-visible target, and the host Unix control socket, then carries those values through sandbox spawning into
msb_krun::VmBuilder::balloon(...).Technical implementation
SandboxConfigwith three optional fields:balloon_initial_mib: guest-visible memory at boot;balloon_min_mib: minimum guest-visible memory allowed at runtime;balloon_control_socket: Unix socket path used by the host to submit runtime memory targets.SandboxBuilder::balloon(initial, min, control_socket)as the fluent API. The builder stores guest-visible MiB values instead of reclaimed pages so callers do not need to know the virtio-balloon representation.--balloon-initial-mib,--balloon-min-mib, and--balloon-control-socketonly when the corresponding config values are present.msb sandboxclap args with matching fields and passes them intomicrosandbox_runtime::vm::VmConfig.VmConfigand itsDebugoutput with the balloon fields.build_vm(), enablesmsb_krun::VmBuilder::balloon(...)whenever any balloon field is set. Missinginitialdefaults to the configured memory ceiling, and missingmindefaults to0, leaving the lower-level libkrun validation and max-page clamping as the final enforcement layer.msb_krundependency requirements to0.1.15and temporarily patchesmsb_krunto theenricoschaaf/msb-libkrunbranch used by feat: add host-driven balloon controls libkrun#59. The lockfile resolves all internalmsb_krun*crates from that same branch so microsandbox compiles against the new API before a crates.io release exists.Dependency and firmware notes
msb_krun 0.1.15is published, the[patch.crates-io]entry can be removed and the dependency can resolve from crates.io normally.Validation
cargo check -p microsandbox-runtime -p microsandbox-cli -p microsandboxcargo test -p microsandbox balloonCaviats
Main caveats in the current PRs:
No encrypted guest support.
teebuilds reject ballooning. The C API returnsEOPNOTSUPP; the Rust builder returns a config error.Guest cooperation is required. This only changes the virtio-balloon target. The guest kernel must have and load a working virtio-balloon driver. If the guest ignores the device or cannot reclaim memory, the host request may not take effect.
It is best-effort, not a hard memory cap. The VM still has the configured
memory_mibceiling. Ballooning asks the guest to give pages back; it does not resize the guest physical address space or enforce a cgroup-like limit.Runtime targets are clamped, not rejected. If the control socket receives a target above the ceiling, it effectively becomes the ceiling. If it receives a target below
min_mib, it clamps tomin_mib. The response isOK <pages>, not the effective MiB target.Dangerous default when partially configured. In microsandbox runtime, setting only one balloon field enables ballooning. If only the socket is set,
initialdefaults to the full memory ceiling andmindefaults to0, meaning the controller can request reclaiming essentially all guest memory.The control socket is very simple. It accepts one decimal MiB target per connection. No auth, no structured protocol, no status query, no actual-memory reporting. Access control is only filesystem permissions on the socket path.
Socket bind failure does not fail VM startup. The listener is spawned after the VMM is built. If the parent directory does not exist, bind fails, or stale socket removal fails, it logs but the VM continues.
A stuck socket client can block control. The listener handles connections serially and uses
read_line; a client that connects and never sends a newline/EOF can block later resize commands.No cleanup lifecycle for the socket. The code removes a stale socket before binding, but does not explicitly unlink the socket on VM exit.
No SDK/top-level CLI exposure yet. The internal
msb sandboxprocess accepts the flags, and Rust config/builder fields exist, but I did not wire publicmsb run/createflags or update Node/Python/Go SDK APIs.Metrics still use the ceiling. Existing memory-limit metrics/reservation are based on
memory_mib, not the current balloon target.