Snapshot Format
This page documents the on-disk format used by OpenVMM snapshots, intended for developers working on the save/restore subsystem.
Directory layout
A snapshot is stored as a directory containing three files:
snapshot-dir/
├── manifest.bin # Protobuf-encoded SnapshotManifest
├── state.bin # Protobuf-encoded device saved state
└── memory.bin # Hard link to the guest memory backing file
Manifest format
The manifest is a protobuf message defined as
SnapshotManifest
in openvmm/openvmm_helpers/src/snapshot.rs, encoded using the mesh
crate's protobuf encoding.
Device state (state.bin)
The device state contains every device's saved state, collected via the
SaveRestore trait and encoded as a mesh protobuf message. The
Save State compatibility rules (mesh tag stability,
default values, forward/backward compatibility) apply.
Memory (memory.bin)
memory.bin is a hard link to the file-backed guest RAM file. During a save,
write_snapshot() creates this hard link using std::fs::hard_link.
The hard-link approach means the memory backing file and snapshot directory
must reside on the same filesystem. If they are on different filesystems,
write_snapshot returns an error with a suggestion to place the backing
file inside the snapshot directory.
Same-file detection
If the user passes --memory-backing-file <snapshot_dir>/memory.bin, the
source and target of the hard link are the same file. The code detects this
by canonicalizing both paths and comparing them. When they match, the
hard-link step is skipped.
Code references
- Manifest type and I/O:
openvmm/openvmm_helpers/src/snapshot.rs - Restore entry point:
prepare_snapshot_restore()inopenvmm/openvmm_entry/src/lib.rs - File-backed memory:
SharedMemoryFdtype alias inopenvmm/openvmm_defs/src/worker.rs
Device state architecture
Each VM component that participates in save/restore is registered as a
"state unit" with a unique string name via StateUnits::add("name").
During save, every state unit receives a StateRequest::Save. Units that
have state return Ok(Some(blob)); units with no persistent state (e.g.
the input distributor) return Ok(None) and are omitted from state.bin.
The resulting state.bin contains a Vec<SavedStateUnit>, where each
entry pairs a unit name with its opaque protobuf-encoded state blob.
Restore matching rules
During restore, StateUnits::restore() matches saved-state entries to
currently registered units by name:
| Scenario | Result |
|---|---|
| Names match exactly | State is dispatched to the unit |
| Saved entry has no matching unit | Error — unknown unit name |
| Unit exists with no saved entry | Unit is skipped (keeps default state) |
| Duplicate name in saved state | Error — duplicate unit name |
This means removing a device between save and restore will fail, but adding a new device is allowed (it initialises to its power-on defaults).
Unit naming conventions
- Chipset devices — registered via
arc_mutex_device("name")invmotherboard, e.g."pit","rtc","uefi","ide". - VMBus devices — named
"{interface_name}:{instance_id}", e.g."StorageVsp:ba6163d9-...". The instance GUID makes each offer unique. - Infrastructure units —
"vmtime","input","vmbus".
Devices that do not support save/restore
Not all devices implement save/restore. Devices signal this in one of two ways:
SaveError::NotSupported— thesave()method returns this error. If any state unit does this, the entire save operation fails.supports_save_restore() -> false(virtio) orsupports_save_restore() -> None(VMBus) — transport-level check that causes the transport'ssave()to returnSaveError::NotSupported.
Key unsupported categories:
- PCIe —
GenericPcieRootComplex,GenericPcieSwitchreturnSaveError::NotSupported. - NVMe —
NvmeControllerreturnsSaveError::NotSupported. - Pass-through PCI —
AssignedPciDevice,RelayedVpciDevice. - VGA / GDMA — marked
todo!()(will panic on save). - Virtio devices — the
VirtioDevicetrait defaultssupports_save_restore()tofalse. Onlyvirtio-blk,virtio-net,virtio-pmem, andvirtio-rngoverride it totrue. Devices with host-side session state (virtio-9p,virtiofs,virtio-console) intentionally leave itfalse. - Some VMBus devices —
GuestCrashDevice,GuestEmulationDevice,VmbusSerialHost,VmbfsreturnNonefromsupports_save_restore().
Extending the format
When adding new fields to SnapshotManifest, use the next available mesh
tag number. The protobuf encoding is forward-compatible: older readers will
ignore unknown fields. However, removing or reordering existing fields is a
breaking change. See Save State for the full set of
compatibility rules.