Appendix A: Command-Line And Inspection Tools

The tools around a microVM fall into three groups: launchers, live inspectors, and static host inspectors. They do not all carry the same risk.

Lab boundary. Starting firecracker, firectl, or accelerated QEMU opens /dev/kvm. The Jailer changes namespaces, cgroups, identity, mounts, and device nodes. kvm_stat and perf kvm read system-wide KVM counters or tracepoints unless carefully filtered. Use those tools only on bare-metal Linux or in a disposable VM with nested virtualization. Do not attach them to an unrelated multi-tenant host. The cpuid, lscpu, lsmod, and documented /proc or /sys reads below are non-mutating, though access controls still apply.

Tool Answers Important boundary
firecracker How is one microVM configured and controlled? opens KVM and device fds
jailer Which host resources can Firecracker see? privileged host mutation
firectl Can a simple CLI assemble a Firecracker VM? development wrapper, opens KVM
qemu-system-x86_64 -M microvm How does QEMU expose a similar small machine? KVM or slower TCG execution
kvm_stat Which KVM events are accumulating? debugfs and tracepoint access
perf kvm Which exits occurred, when, and for how long? perf and tracepoint access
cpuid, lscpu Which CPU and hypervisor features are visible here? reports the current host or guest view
lsmod, /sys/module Which KVM modules and parameters are loaded? presence is not usability

firecracker

The firecracker binary owns one microVM. Its command line configures the control plane around that VM; the HTTP API or JSON configuration describes the machine itself.

The current command-line switches worth recognizing are:

Switch Purpose
--api-sock <path> Unix socket for the HTTP API; defaults to /run/firecracker.socket
--id <id> instance identifier used by logs and metrics
--config-file <path> complete JSON VM configuration
--no-api disable the API; requires --config-file
--mmds-content <path> preload MMDS JSON from a file
--log-path, --level, --module configure startup logging
--metrics-path configure startup metrics output
--seccomp-filter <path> load a custom compiled filter
--no-seccomp disable seccomp; incompatible with --seccomp-filter
--enable-pci use PCI transport for virtio devices instead of default MMIO
--snapshot-version print the supported snapshot data format version
--describe-snapshot <path> inspect a snapshot state's format version

--no-api is batch mode, not merely "do not create a socket." Firecracker loads the configuration file and starts without an active API server. The startup-only logger and metrics flags are useful in that mode because there is no later API call with which to configure them.

The PCI switch changes transport, not the guest device type. A virtio block device is still a virtio block device; the guest discovers its registers through PCI capabilities instead of the virtio-MMIO register page. Current developer-preview device hotplug requires this mode.

--start-time-us, --start-time-cpu-us, and --parent-cpu-time-us may appear in a jailed process's arguments. They carry launcher timing into Firecracker's boot metrics and are not normal operator configuration.

The API Socket

The API is HTTP/1.1 over the Unix socket. Pre-boot PUT requests configure the boot source, machine, drives, network interfaces, entropy, balloon, memory hotplug, pmem, vsock, MMDS, logging, and metrics. InstanceStart crosses the state boundary after which only selected endpoints remain mutable. The exact schema lives in Firecracker's in-tree OpenAPI document; Chapter 15 owns the request sequence.

An API client needs filesystem permission to connect to the socket. It does not thereby need /dev/kvm, but the already-running Firecracker process does. Treat the socket as a privileged control interface: its caller can select host files for guest drives and alter the VM lifecycle.

jailer

The Jailer is Firecracker's privileged launcher. Its required arguments are --id, --exec-file, --uid, and --gid. The current optional interface includes:

Switch Purpose
--chroot-base-dir jail tree base, default /srv/jailer
--netns <path> join an existing network namespace
--new-pid-ns run Firecracker as the child in a new PID namespace
--cgroup <file=value> repeatable cgroup setting
--cgroup-version select v1 or v2; current default is v1
--parent-cgroup relative parent for the per-VM cgroup
--resource-limit <name=value> set fsize or no-file limits
--daemonize call setsid and redirect standard streams to /dev/null

Arguments after -- are passed to the jailed executable. The Jailer closes inherited fds, clears the environment, builds the jail, configures requested cgroups and limits, changes root, drops identity, and execs Firecracker. The exact ordering and optional namespace paths are covered in Chapter 18; avoid inferring enabled isolation merely from the presence of the binary.

The PID file is useful evidence, but remember which PID namespace you are reading it from. A process may be PID 1 inside the optional child namespace and have a different PID on the host.

firectl

firectl is a small Go wrapper around firecracker-go-sdk. It translates one command line into Firecracker configuration calls and connects the guest console. Its main inputs are a kernel, root drive, optional additional drives, vCPU and memory counts, TAP and vsock descriptions, kernel arguments, MMDS JSON, and logging paths. Current source also contains optional Jailer settings.

Use firectl to explore a known kernel and rootfs, not as the specification of Firecracker itself. Its defaults include an MMIO-oriented x86 kernel command line, its feature surface trails the complete API, and the README's historical getting-started download example still names very old Firecracker artifacts. For an orchestrator or a reproducible production configuration, drive the OpenAPI surface or a version-pinned SDK directly.

QEMU microvm

QEMU's x86 microvm machine is the closest stock comparison to Firecracker's default machine. It has no PCI or ACPI, directly boots a host-supplied kernel, and permits up to eight virtio-MMIO transports. Its optional legacy pieces are the PIC, PIT, RTC, and ISA serial port. It has no hotplug and no live migration across QEMU versions.

The machine properties pit, pic, rtc, isa-serial, and x-option-roms can disable those optional pieces. auto-kernel-cmdline lets QEMU append virtio-MMIO discovery arguments. -nodefaults and -no-user-config remain relevant when constructing a controlled experiment, because they suppress implicit devices and per-user configuration.

KVM acceleration and TCG answer different questions. KVM measures the hardware-assisted path this book studies and requires /dev/kvm. TCG can run without KVM and is useful for boot debugging, but QEMU's security policy gives the non-virtualization TCG use case no guest-isolation guarantee. Do not compare TCG timing with Firecracker timing as if the execution engines were equivalent.

HMP And QMP

The Human Monitor Protocol, or HMP, is QEMU's interactive console. Commands such as info kvm, info registers, info cpus, info mtree, and the info virtio* family expose accelerator state, CPU state, the memory map, and virtio device or queue state. Command availability changes with QEMU builds; help info is the live inventory.

The QEMU Machine Protocol, or QMP, is the JSON automation interface. A client receives a greeting and must execute qmp_capabilities before normal commands. A QMP socket is privileged: commands can add block backends, inspect VM state, and initiate migration. Bind it to a protected local channel and let a trusted management process own it.

kvm_stat

kvm_stat is a top-like Python tool shipped in the Linux source tree. It can sample two providers:

It can display a curses UI, a one-shot batch, CSV, or a log. Important filters include --pid, --guest, --fields, --debugfs, and --tracepoints. --debugfs-include-past determines whether counters from dead VMs are included.

The counters need interpretation. A hardware VM exit need not become a userspace return from KVM_RUN: KVM handles many exits in the kernel. An ioeventfd notification may avoid a KVM_EXIT_MMIO return even though guest I/O occurred. kvm_stat therefore describes KVM activity, not a direct count of VMM event-loop iterations.

Exit names are architecture-specific. On x86, VMX reasons such as EPT_VIOLATION and SVM reasons such as NPF describe hardware exits; names such as MMIO, IO, and HLT in KVM_EXIT_* describe the userspace ABI. They are related layers, not interchangeable enumerations.

perf kvm

perf kvm records and summarizes KVM trace events. Its stat family has three useful phases:

Architecture support determines which event classes are available. On x86, the KVM statistics code can group VM exits and events such as MMIO and PIO and report counts, total time, mean time, and time distribution. Because it uses the perf subsystem and KVM tracepoints, permission depends on user identity, perf_event_paranoid, capabilities, tracefs access, and kernel configuration.

Guest symbolization is a separate problem from exit accounting. It requires the correct guest kernel image and symbol files and a way to associate samples with the guest. An exit histogram can be valid even when every guest address is unresolved.

cpuid And lscpu

On x86, cpuid prints the feature leaves visible to the current CPU context. The two first checks are:

Feature Leaf and bit Meaning
VMX leaf 0x1, ECX[5] Intel virtualization instructions are visible
SVM leaf 0x80000001, ECX[2] AMD virtualization instructions are visible

Visibility is not availability. Firmware may disable virtualization; a guest may see the bit without nested virtualization being usable; permissions may deny /dev/kvm; and KVM may reject a capability needed by a VMM.

When CPUID leaf 0x1 reports the hypervisor-present bit, leaf 0x40000000 identifies the paravirtual hypervisor interface and its maximum leaf. A KVM guest commonly sees the KVMKVMKVM signature. That is the interface presented to the guest, not proof that a particular userspace VMM such as Firecracker or QEMU created it.

lscpu summarizes the same environment through kernel data. Its Virtualization line describes a CPU extension such as VT-x or AMD-V. Its hypervisor vendor and virtualization-type lines describe a detected guest environment. Do not read a guest's lscpu output as an inventory of hidden host hardware.

lsmod, /proc, And /sys

lsmod is a formatted view of /proc/modules. Typical x86 KVM hosts show the common kvm module plus kvm_intel or kvm_amd; built-in modules need not appear. A loaded module proves neither that firmware enabled virtualization nor that the current user can open /dev/kvm.

Useful non-mutating paths include:

Path Information
/sys/module/kvm*/parameters/ live KVM module parameters
/sys/kernel/tracing/events/kvm/ available KVM tracepoints and formats
/sys/kernel/debug/kvm/ KVM debugfs counters, when mounted and permitted
/proc/<vmm-pid>/task/ threads and host TIDs
/proc/<vmm-pid>/fd/ open KVM, TAP, eventfd, file, and socket descriptors
/proc/<vmm-pid>/maps userspace mappings, including guest RAM backings

Some module parameters are writable. Changing nested virtualization, EPT/NPT, or interrupt-virtualization settings changes host behavior and may require a module reload that disrupts every VM using it. This appendix intentionally does not provide mutation commands. Record the current values on an isolated lab host, consult the kernel parameter documentation for that exact version, and change them only as part of a host maintenance plan.

Sources And Further Reading