msb_krun

Native Rust builder API for creating and entering libkrun-powered microVMs, with typed configuration instead of the C ABI.

Library
Cargo
v0.1.32
4stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
53/100Fair
Development Activity92
Maintenance52
Community24
Maturity44
Momentum0

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture84
Code Quality88
Innovation78
Learning Curve65

msb_krun is the native Rust crate inside the libkrun workspace that exposes libkrun’s VMM (KVM on Linux, Hypervisor.framework on macOS) directly to Rust programs through a nested builder API, instead of the C ABI defined in include/libkrun.h. It gives typed access to machine sizing, kernel/initramfs loading, filesystem passthrough, console multiplexing, virtio-net, virtio-block, virtio-vsock and NUMA/CPU placement, all validated up front through a dedicated error hierarchy (ConfigError, BuildError, RuntimeError) rather than status codes.

It underlies the same microVM isolation used by crun, krunkit and muvm, giving Rust callers a route to spin up an isolated Linux guest, mount a rootfs, exec a process inside it, and receive its exit code — without linking against the dynamic library or writing FFI shims by hand.

What You Get

  • Nested builder types (MachineBuilder, KernelBuilder, FsBuilder, ExecBuilder, ConsoleBuilder, VsockBuilder, plus feature-gated NetBuilder and DiskBuilder) covering every virtio device libkrun exposes
  • A typed Result<T, Error> with Config/Build/Runtime/Io variants instead of C-style status codes
  • ExitHandle and exit-observer callbacks for reading a guest’s exit code after Vm::enter() takes over the process
  • VmControl for live CPU and memory resizing of a running guest via virtio-mem
  • Cargo feature flags (net, blk, gpu, snd, tee, amd-sev, tdx, aws-nitro, efi, input) to opt into only the virtio devices and confidential-computing backends a given deployment needs

Common Use Cases

  • Adding KVM/HVF-based process isolation to a container runtime or CLI tool
  • Booting a disposable Linux rootfs to run a single untrusted binary and capture its exit code
  • Running GPU-accelerated guest workloads via virtio-gpu (venus/native-context)
  • Building confidential-computing guests under AMD SEV, Intel TDX or AWS Nitro Enclaves
  • Resizing a long-running guest’s CPU/memory allocation without a restart

Under The Hood

Architecture msb_krun sits as a thin, typed Rust facade (src/krun) over the workspace’s internal vmm crate, which itself composes msb_krun_devices (virtio device models), msb_krun_polly (event loop / epoll abstraction), msb_krun_utils and platform backends (msb_krun_hvf on macOS, kvm-ioctls/kvm-bindings plus msb-vm-memory on Linux). VmBuilder (api/builder.rs, ~1770 lines) holds one sub-builder per concern — MachineBuilder, KernelBuilder, FsBuilder, ExecBuilder, ConsoleBuilder, VsockBuilder, and feature-gated NetBuilder/DiskBuilder — and its build() method translates each into vmm::vmm_config types (VmConfig, FsDeviceConfig, NetworkInterfaceConfig, BlockDeviceConfig, VsockDeviceConfig) before assembling a VmResources and returning a Vm (api/vm.rs). Vm::enter() is documented as never returning on success — the VMM takes over the process and calls _exit() when the guest shuts down — so the crate’s error surface (BuildError/RuntimeError) only covers the setup path, and post-boot control instead flows through separate VmControl/ExitHandle/MetricsHandle handles obtained before enter() is called. Pluggable I/O — vsock ports, dyn filesystems, console backends — is expressed as trait objects (VsockPortBackend, DynFileSystem, ConsolePortBackend) stored in maps keyed by port/index, so host code can supply custom backends without forking the crate.

Tech Stack The crate targets Rust 2021 edition and depends on crossbeam-channel for exit-code signalling, libc/libloading for dynamically loading libkrunfw at runtime, and log for tracing; its real weight comes from sibling workspace crates pinned to the same version (msb_krun_devices, msb_krun_polly, msb_krun_utils, msb_krun_vmm) plus platform-specific dependencies — kvm-ioctls/kvm-bindings and a forked msb-vm-memory on Linux, msb_krun_hvf on macOS. Optional dependencies (krun_display, krun_input, aws-nitro, nitro-enclaves) are gated behind Cargo features and only compiled in when gpu/input/aws-nitro features are enabled. There is no async runtime — the VMM’s event loop is driven by the workspace’s own polly crate rather than tokio/async-std. The workspace also ships a companion C API and Makefile-based build for producing libkrun.so with SEV/TDX/EFI variants, so msb_krun is one of several consumers of the same underlying vmm crate rather than a standalone library with its own build pipeline.

Code Quality The crate has dozens of #[test] functions across builder.rs, builders.rs and vm.rs plus a separate tests/test_cases workspace member exercising VM config, vsock guest connect, multiport console and TSI TCP scenarios end to end; CI (unit_tests.yml, integration_tests.yml, code-quality.yml, formatting.yml) runs cargo test and cargo clippy -D warnings across every feature combination (default, amd-sev, tdx, efi+gpu, net+blk+gpu+snd+input) plus cargo fmt —check, so both unit and integration coverage are enforced per change rather than aspirational. Error handling is fully typed rather than swallowed: Error/ConfigError/BuildError/RuntimeError are explicit enums with structured variants (InvalidVcpuAffinityLength { expected, actual }, InvalidNumaTopology(String)) instead of ad hoc string errors, and public builder methods return Result rather than panicking on bad input. Naming is consistent (Builder::new()/consuming setters returning Self), and public API doc comments carry runnable rust,no_run examples.

API Design The crate’s differentiator versus using libkrun’s C API directly is ergonomics: a single fluent VmBuilder chain (.machine(|m| …).fs(|fs| …).exec(|e| …).build()?.enter()?) replaces many krun_set_/krun_add_ C calls and hand-written FFI bindings, while staying a thin translation layer over the same vmm crate the C API uses. Feature flags map directly onto libkrun’s C-side variants (SEV, TDX, EFI, AWS Nitro) so Rust callers opt into confidential-computing or GPU support at compile time rather than through runtime capability checks. The API documents an unusual but honest contract up front — enter() never returns on success, taking over the whole process — instead of hiding that behind a conventional async run loop, and exposes VmControl/ExitHandle/MetricsHandle as explicit escape hatches for anything that needs to happen before or in parallel with that handoff. Onboarding is moderate: the single rust_vm example and inline rustdoc cover the common path, but understanding vsock port maps, NUMA placement, and the tee/aws-nitro feature interactions requires reading builder source directly, since there is no separate guide beyond the top-level libkrun README and C header.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search