VM Hibernation and Memory State in KubeVirt#
KubeVirt provides several distinct mechanisms for capturing, suspending, and streaming VM memory state: suspend-to-disk hibernation (under active development), memory dumps to PVCs (stable), disk-only snapshots (memory intentionally excluded), and live migration memory streaming (pre/post-copy). Understanding which mechanism applies to a given use case requires knowing how they differ at the API and implementation level.
PMSuspended Domain State#
PMSuspended is a libvirt domain lifecycle constant defined in pkg/virt-launcher/virtwrap/api/schema.go:
PMSuspended LifeCycle = "PMSuspended"
It is mapped from the libvirt DOMAIN_PMSUSPENDED state (power-management suspend). Currently, virt-handler treats PMSuspended identically to Running — a VMI in this state is reported as Running phase and not surfaced as a distinct KubeVirt status. Full suspend-to-disk hibernation that exploits this state is being added via PR #16775 (see below).
VM Hibernation (Suspend-to-Disk) — PR #16775#
Full suspend-to-disk hibernation support is being added in PR #16775 ("Vmhiberation"), linked to VEP #66. As of the current codebase snapshot, the hibernation package does not yet exist at the anticipated path pkg/virt-launcher/virtwrap/hibernation/, meaning this feature is in-flight.
Key API additions introduced by the PR:
| Type / Field | Description |
|---|---|
VirtualMachineHibernationStatus | New struct with ClaimName and HibernationPhase |
VirtualMachineStatus.ResumeStatus | Tracks resume state |
| New gRPC commands | Hibernation operations added to cmd.proto / client.go |
Implementation components added:
pkg/virt-launcher/virtwrap/hibernation/manager.go— hibernation lifecycle managerpkg/virt-launcher/virtwrap/hibernation/suspendToDisk.go— QEMU suspend-to-disk logic- Changes to
pkg/virt-controller/watch/vm/vm.go,pkg/virt-handler/vm.go, andpkg/virt-handler/controller.go
When complete, this wires QEMU/libvirt's PM suspend mechanism through the full virt-handler → virt-launcher → virtwrap stack, writing VM memory state to a PVC.
Memory Dumps to PVCs#
Memory dumps capture a running VM's guest memory (RAM) to a PVC for forensic or debugging purposes. This is a stable, shipped feature — distinct from hibernation in that the VM keeps running.
API types (in staging/src/kubevirt.io/api/core/v1/types.go):
VirtualMachineMemoryDumpRequest— tracked inVirtualMachine.Status.MemoryDumpRequest; fields:ClaimName,Phase,StartTimestamp,EndTimestamp,FileName,MessageMemoryDumpPhase:Associating → InProgress → Unmounting → Completed(plusDissociatingandFailed)DomainMemoryDumpInfo— embedded inVolumeStatus.MemoryDumpVolume, tracks per-VMI timestamps and target file name- Volume phases used:
MemoryDumpVolumeCompleted,MemoryDumpVolumeInProgress,MemoryDumpVolumeFailed
Controller logic is in pkg/storage/memorydump/memorydump.go:
HandleRequest()— hotplugs/unplugs the PVC as aMemoryDumpVolumeSourceon the VMI based on the currentMemoryDumpPhaseUpdateRequest()— advances the phase state machine by observingVolumeStatuschanges on the VMI- On completion,
patchMemoryDumpPVCAnnotation()stamps the PVC with thekubevirt.io/memory-dumpannotation (value = target filename)
The PVC is hotplugged to the virt-launcher pod with Hotpluggable: true , so no VM restart is required.
Disk-Only Snapshots (Memory Excluded)#
KubeVirt VM snapshots capture disk state only — memory is intentionally not included. This behavior is implemented in pkg/storage/snapshot/source.go:
- Offline VMs: the
Spec()method resetsVirtualMachineStatusto empty (kubevirtv1.VirtualMachineStatus{}), ensuring no runtime memory state leaks into the snapshot spec. - Paused VMs: the
Freeze()method skips filesystem quiescing and logs a warning — paused VMs cannot flush memory buffers to disk. The snapshot is marked withVMSnapshotPausedIndication: "Snapshot taken while the VM was paused. Snapshot is crash-consistent and may not be application-consistent."
Snapshottable volume types :
PersistentVolumeClaim | DataVolume | MemoryDump
Note: MemoryDump volumes are treated as snapshottable (the PVC can be snapshotted) but are explicitly excluded from restore — memory dump PVCs are skipped when restoring from a snapshot, as replaying a raw memory dump file to a new VM would be meaningless.
Snapshot indications recorded on the VirtualMachineSnapshot.Status.Indications field describe the consistency level: OnlineSnapshot, GuestAgent, NoGuestAgent, QuiesceTimeout, Paused, PartialSnapshot.
Live Migration Memory Streaming#
Live migration moves a running VM's memory across nodes without stopping it. Memory streaming is handled entirely within virtwrap and exposed via VirtualMachineInstanceMigrationState.
- Migration modes :
PreCopy(default),PostCopy(switches whenCompletionTimeoutPerGiBtriggers), andPaused(VM paused during switchover). MigrationPaused(MigrationMode = "Paused") is set when the domain has a user-pause reason at migration time — theMIGRATE_PAUSEDlibvirt flag is passed to ensure the guest remains paused on the destination .- Pre-copy streams dirty pages iteratively; post-copy pages-in from source on demand after cutover. Configuration is driven by
VMIMConfigurationOptions(bandwidth limit, completion timeout, post-copy flag, etc.). - Memory compression (zstd) is an experimental option in
ExperimentalMigrationOptions.
Live migration memory streaming is separate from memory dumps and hibernation — it is a transient transfer, not a persistent capture.
Key Files and References#
| Area | File |
|---|---|
| Core API types (VMI phases, memory dump, migration) | staging/src/kubevirt.io/api/core/v1/types.go |
| libvirt domain lifecycle / PMSuspended | pkg/virt-launcher/virtwrap/api/schema.go |
| Libvirt state translation | pkg/virt-launcher/virtwrap/util/libvirt_helper.go |
| Virt-handler VMI phase calculation | pkg/virt-handler/vm.go |
| Memory dump controller | pkg/storage/memorydump/memorydump.go |
| Snapshot controller | pkg/storage/snapshot/snapshot.go |
| Snapshot source (disk-only, freeze, paused) | pkg/storage/snapshot/source.go |
| Snapshot restore (memory dump exclusion) | pkg/storage/snapshot/restore.go |
| Live migration source (MIGRATE_PAUSED) | pkg/virt-launcher/virtwrap/live-migration-source.go |
| Hibernation PR (in-flight) | PR #16775 — Vmhiberation |
| VEP for hibernation | VEP #66 |