Skip to content

Reference

Filesystem & Drives

Drive model, mount points, and filesystem layout inside microVMs.

Each microVM gets up to four virtio-block drives on the supported workload backends:

DriveMount PointPermissionsPurpose
/dev/vda/Read-write (ext4) or read-only (squashfs)Root filesystem
/dev/vdb/mnt/configRead-onlyApplication configuration
/dev/vdc/mnt/secretsRead-onlyAPI keys, tokens, credentials
/dev/vdd/mnt/dataRead-writePersistent data (survives restarts)

The rootfs is built by mkGuest and contains:

  • Busybox β€” init system, core utilities
  • Overlay-aware boot logic β€” the /init path and /mvm/runtime mount point needed to bring the guest runtime online
  • Guest agent β€” present directly in dev/preferred-overlay images; provided by the sealed runtime overlay on overlay-required boots
  • Your packages β€” specified in the flake’s packages parameter
  • Service scripts β€” generated from services.<name> definitions
  • Health check configs β€” generated from healthChecks.<name>

Sealed workload boots can attach a second read-only, verity-protected runtime overlay that is mounted inside the guest at /mvm/runtime.

  • The overlay carries the guest runtime binaries such as mvm-guest-agent, mvm-guest-netinit, and mvm-egress-client.
  • Only guest-executed runtime binaries belong in this artifact. Host-side helpers and bootstrap tools stay outside the overlay.
  • The rootfs keeps the mount point and boot logic, but sealed RequiredOverlay images intentionally omit the baked fallback binaries.
  • The overlay is version-matched to the running mvmctl build; mvm does not attach an arbitrary β€œlatest” overlay.
  • The overlay is mounted read-only in the guest. A backend that cannot provide that read-only contract must stay on the fallback policy instead of using RequiredOverlay.
  • Before attach, mvm re-verifies the cached overlay.ext4, overlay.verity, overlay.roothash, and VERSION files against the recorded checksums-sha256.txt manifest and refuses the boot on any mismatch.
  • The artifact is shared across microVMs from the local cache under ~/.mvm/cache/runtime-overlay/<version>/<arch>/.

Runtime overlay updates are a next-boot operation:

  • A stopped VM can pick up a newer version-matched overlay the next time it starts.
  • A running VM keeps the overlay version it booted with until restart.
  • mvm does not support hot-swapping or live-remounting a different runtime overlay into an already-running guest.
ext4squashfs
Read-writeYesNo (tmpfs overlays on /etc, /var)
SizeLarger~76% smaller (LZ4 compression)
Agent injectionSupportedNot supported (read-only)
Boot timeSimilarSimilar

The config drive (/dev/vdb, mounted at /mnt/config/) contains non-sensitive configuration:

  • config.json β€” mvm instance metadata (name, role, resources)
  • Application config files from host directories you mounted yourself

Files are written with mode 0444 (world-readable, read-only mount).

The secrets drive (/dev/vdc, mounted at /mnt/secrets/) contains sensitive data:

  • secrets.json β€” tenant-level secrets
  • Application secret files from host directories you mounted yourself

Security hardening:

  • Uses tmpfs-backed file (never hits persistent storage)
  • Drive image files are 0400 (root-only); at boot, secrets are copied to a tmpfs with 0440 root:<serviceGroup> so only service group members can read them
  • Mount with ro,noexec,nodev,nosuid
  • Recreated on every start (never reused)

The data drive (/dev/vdd, mounted at /mnt/data/) is a persistent ext4 volume:

  • Created once per instance (specified size)
  • Survives restarts and snapshots
  • Use for application state, databases, logs

Specify size with --volume:

Terminal window
mvmctl machine run --flake . --volume ./data:/data:1024

For managed encrypted local volumes and workspace cleanup policy, see Persistent workspaces.

/ # rootfs (ext4 or squashfs)
β”œβ”€β”€ bin/ # busybox symlinks
β”œβ”€β”€ etc/
β”‚ └── mvm/
β”‚ β”œβ”€β”€ integrations.d/ # health check definitions (JSON)
β”‚ └── probes.d/ # read-only probe definitions (JSON)
β”œβ”€β”€ init # busybox init script
β”œβ”€β”€ mvm/
β”‚ └── runtime/ # read-only runtime overlay mount point when attached
β”œβ”€β”€ nix/store/ # Nix packages
β”œβ”€β”€ mnt/
β”‚ β”œβ”€β”€ config/ # /dev/vdb (ro) β€” config drive
β”‚ β”œβ”€β”€ secrets/ # /dev/vdc (ro) β€” secrets drive
β”‚ └── data/ # /dev/vdd (rw) β€” data drive
└── var/ # runtime state (tmpfs on squashfs)

On the host (on Linux) or inside the builder VM (on macOS), mvm stores data at:

~/.mvm/ # MVM_HOME
β”œβ”€β”€ templates/
β”‚ └── <name>/
β”‚ └── revisions/
β”‚ └── <hash>/
β”‚ β”œβ”€β”€ vmlinux
β”‚ β”œβ”€β”€ rootfs.ext4 (or rootfs.squashfs)
β”‚ └── warm-meta.json (if warmed)
└── vms/
└── <name>/
β”œβ”€β”€ firecracker.pid
β”œβ”€β”€ firecracker.socket
β”œβ”€β”€ firecracker.log
β”œβ”€β”€ console.log
β”œβ”€β”€ fc-base.json
β”œβ”€β”€ vmlinux
β”œβ”€β”€ rootfs.ext4
β”œβ”€β”€ runtime/
β”‚ └── v.sock # per-VM Firecracker vsock UDS
└── volumes/
β”œβ”€β”€ config.ext4
β”œβ”€β”€ secrets.ext4
└── data.ext4

The shared guest-runtime overlay cache lives separately under ~/.mvm/cache/runtime-overlay/<version>/<arch>/ and contains the sealed overlay.ext4, overlay.verity, overlay.roothash, VERSION, and checksums-sha256.txt metadata reused by every VM that boots that runtime version.