| |

LFCE 146 🐧 KVM Snapshots and Cloning

⏱️ Estimated read: 11 min | |

A KVM snapshot captures the state of a virtual machine at a point in time. A clone creates a new virtual machine from an existing one. Both are managed through libvirt, and both are frequently misunderstood as substitutes for backups. A snapshot lives on the same storage as the VM and depends on the original disk chain. If the underlying storage is destroyed or the base disk is deleted, every snapshot built on it is lost too. A snapshot is a rollback point, not a backup. Cloning duplicates the disk and the hardware configuration, but it does not modify anything inside the guest operating system.

This chapter covers the two snapshot models (internal and external), the virsh snapshot-* commands that create, list, revert, and delete snapshots, the virt-clone command that produces a full clone, and the linked clone that uses a copy-on-write overlay to avoid duplicating the entire disk.

Key point: Snapshots require the qcow2 disk format. A raw disk cannot hold an internal snapshot and needs an external-overlay workflow. A snapshot is not a backup: it shares storage with the VM and depends on the base disk. Pair it with an off-host backup for anything that matters.


Why snapshots and clones are separate operations

The rollback problem. A snapshot lets an administrator return a VM to a previous state after a failed upgrade, a botched configuration change, or a test that went wrong. The state can include the disk, the memory, or both. The snapshot is a point-in-time marker that the VM can be reverted to, and it is created and managed through libvirt.

The duplication problem. A clone creates a new VM from an existing one. The clone has its own name, its own UUID, its own MAC address, and its own disk. The source VM is unchanged. Cloning is how a template becomes a fleet of VMs, and how a known-good configuration is replicated without reinstalling the guest OS.

The storage problem. Both operations interact with the disk chain. A snapshot adds a layer to the chain; a clone either copies the chain into an independent disk (full clone) or creates a new overlay that references the source as a backing file (linked clone). The chain length and the storage dependency are the operational concerns that determine which approach is appropriate.


a. Internal and external snapshots

The internal snapshot stores the snapshot data inside the same qcow2 file as the VM disk. It is the simpler model: a single file, no separate overlay to track. It is also the model that libvirt no longer supports well for live VMs. The internal live-snapshot path was deprecated, and virsh snapshot-create-as on a running VM effectively falls back to an external snapshot in modern libvirt. The practical rule is to use internal snapshots only for offline VMs with simple single-file qcow2 disks.

The external snapshot creates a new qcow2 overlay file on top of the base disk. The base disk becomes a read-only backing file, and the overlay receives the new writes. This is the live-safe model: the VM can keep running while the snapshot is taken, because the base disk is not modified. Each external snapshot adds a layer to the chain, and reads must potentially traverse every layer back to the base. Long chains degrade I/O performance, which is why flattening the chain with blockcommit or blockpull matters operationally.

The libvirt domain state capture documentation describes the trade-offs: capturing memory allows a precise point-in-time restore, capturing disk state alone is crash-consistent, and quiescing the guest filesystem is an optional step that produces a fully consistent disk snapshot. The guest agent is required for the freeze/thaw operation that quiesces the filesystem.


b. The virsh snapshot commands

The snapshot lifecycle has four commands: create, list, revert, and delete.

# Create a snapshot with a name
virsh snapshot-create-as --domain my-vm --name before-upgrade

# List snapshots
virsh snapshot-list --domain my-vm

# Revert to a snapshot
virsh snapshot-revert --domain my-vm --snapshotname before-upgrade --running

# Delete a snapshot
virsh snapshot-delete --domain my-vm --snapshotname before-upgrade

The snapshot-create-as command accepts a --disk-only flag, which captures only the disk state and not the memory. A disk-only snapshot is the appropriate choice for a VM that is running and does not need its memory preserved, because it is faster and does not require the VM to be paused for as long. The --live flag takes the snapshot while the VM is running. The documentation for the ALT Linux distribution shows the combined form: virsh snapshot-create-as --domain alt-server-test --name alt-server-test-30jun2025.

The snapshot-revert command accepts a --running flag, which starts the VM after the revert if it was not running before. Without the flag, the VM remains in the state it was in when the snapshot was taken.

The snapshot configuration files are stored in /var/lib/libvirt/qemu/snapshot/. The snapshot itself is tracked by libvirt, and the snapshot-list output shows the name, the creation time, and the state (running, disk-snapshot, or shutoff).

A disk-only external snapshot can be created with an explicit overlay path:

virsh snapshot-create-as --domain my-vm --name 01jul2025 \
  --diskspec vda,file=/var/lib/libvirt/images/my-vm-01jul2025.qcow2 \
  --disk-only --atomic

The --diskspec names the target disk and the overlay file, and --atomic ensures the operation either succeeds completely or has no effect.


c. Full clone with virt-clone

virt-clone copies the disk images of an existing VM and defines a new guest with an identical hardware configuration. Elements that require uniqueness—the name, the UUID, the MAC address—are regenerated or specified. The source VM must be shut off for the clone to be safe.

# Clone a VM with a new name and new disk paths
virt-clone --original source-vm --name clone-vm \
  --file /var/lib/libvirt/images/clone-vm.qcow2

The --original flag names the source VM. The --name flag sets the new VM’s name, which must be unique. The --file flag specifies the path for the new disk; if the source VM has multiple disks, the flag is repeated once per disk. The --auto-clone option generates the name and the disk paths automatically, appending -clone to the source name and a number if the generated name collides.

The clone does not change anything inside the guest OS. Passwords, static IP addresses, hostnames, and SSH keys are duplicated from the source. The documentation points to virt-sysprep for those changes, which is the tool that generalizes the guest before cloning.

The --reflink option performs a lightweight copy on a btrfs filesystem, and --nonsparse fully allocates the new storage. The --preserve-data option does not copy the disk at all; it creates the new VM definition referencing the specified disk paths as they are, which is useful for cloning a VM template without duplicating the storage.


Complete Example Session

# ============================================
# PART 1: CHECK THE DISK FORMAT
# ============================================
virsh domblklist my-vm
qemu-img info /var/lib/libvirt/images/my-vm.qcow2

# The disk must be qcow2 for snapshots.
# ============================================
# PART 2: CREATE AN OFFLINE SNAPSHOT
# ============================================
virsh shutdown my-vm
virsh snapshot-create-as --domain my-vm --name pre-upgrade
# ============================================
# PART 3: CREATE A LIVE DISK-ONLY SNAPSHOT
# ============================================
virsh snapshot-create-as --domain my-vm --name live-snap \
  --disk-only --atomic
# ============================================
# PART 4: LIST SNAPSHOTS
# ============================================
virsh snapshot-list --domain my-vm

# Name         Creation Time             State
# pre-upgrade  2026-11-07 10:00:00 +0100 shutoff
# live-snap    2026-11-07 10:05:00 +0100 disk-snapshot
# ============================================
# PART 5: REVERT TO A SNAPSHOT
# ============================================
virsh snapshot-revert --domain my-vm --snapshotname pre-upgrade --running
# ============================================
# PART 6: DELETE A SNAPSHOT
# ============================================
virsh snapshot-delete --domain my-vm --snapshotname live-snap
# ============================================
# PART 7: FULL CLONE
# ============================================
virsh shutdown source-vm
virt-clone --original source-vm --name clone-vm \
  --file /var/lib/libvirt/images/clone-vm.qcow2
# ============================================
# PART 8: AUTO-CLONE
# ============================================
virt-clone --original source-vm --auto-clone
# ============================================
# PART 9: LINKED CLONE (MANUAL OVERLAY)
# ============================================
qemu-img create -f qcow2 -b /var/lib/libvirt/images/source-vm.qcow2 \
  -F qcow2 /var/lib/libvirt/images/linked-clone.qcow2
# Define a new VM referencing the overlay.
# ============================================
# PART 10: THE SNAPSHOT IS NOT A BACKUP
# ============================================
# Copy the disk to off-host storage.
# Use virsh backup-begin or rsync.

The ten parts covered the disk format check, the offline snapshot, the live disk-only snapshot, listing, reverting, deleting, the full clone, the auto-clone, the linked clone overlay, and the backup boundary.


Quick Reference

Snapshot commands

CommandPurpose
virsh snapshot-create-as --domain <vm> --name <n>Create a snapshot
virsh snapshot-list --domain <vm>List snapshots
virsh snapshot-revert --domain <vm> --snapshotname <n>Revert
virsh snapshot-delete --domain <vm> --snapshotname <n>Delete
virsh snapshot-info --domain <vm> --snapshotname <n>Show details
virsh snapshot-current --domain <vm>Show current snapshot

Snapshot flags

FlagEffect
--disk-onlyDisk state only, no memory
--liveTake while running
--atomicAll-or-nothing
--diskspecSpecify disk and overlay path

Clone commands

CommandPurpose
virt-clone --original <vm> --name <n> --file <path>Full clone
virt-clone --original <vm> --auto-cloneAuto-generate name and paths
virt-clone --original <vm> --name <n> --preserve-data --file <path>Clone definition without copying disk

Snapshot types

TypeStorageLive-safe
InternalSame qcow2 fileNo (deprecated for live)
ExternalNew overlay qcow2Yes
Disk-onlyDisk onlyYes
Full systemDisk + memoryYes

Best Practices

✅ Do This:

# Shut down the VM before a full clone
virsh shutdown source-vm                                      # ✅
# Use disk-only snapshots for running VMs
virsh snapshot-create-as --domain vm --name snap --disk-only  # ✅
# Use virt-sysprep to generalize the guest before cloning
virt-sysprep -d clone-vm                                      # ✅
# Pair snapshots with off-host backups
virsh backup-begin vm                                         # ✅

❌ Don’t Do This:

# Treat a snapshot as a backup
# It shares storage with the VM and depends on the base disk   # ❌
# Clone a running VM
virt-clone --original source-vm ...                           # ❌
# Use internal snapshots on a live VM
# libvirt falls back to external or fails                       # ❌
# Leave a long external snapshot chain
# Reads traverse every layer, degrading I/O                    # ❌

Common Pitfalls

PitfallWhy It HappensFix
Snapshot failsDisk is raw, not qcow2Convert to qcow2 or use an external overlay
Clone failsSource VM is runningShut down the source VM
Guest has the same IP after cloneCloning duplicates the guest configurationUse virt-sysprep or configure the network manually
Snapshot chain grows unboundedExternal snapshots never flattenedUse blockcommit or blockpull
Data lost with the snapshotStorage failure destroyed the base diskKeep an off-host backup

Real-World Examples

1. Offline snapshot

virsh snapshot-create-as --domain vm --name pre-upgrade

2. Live disk-only snapshot

virsh snapshot-create-as --domain vm --name snap --disk-only

3. List snapshots

virsh snapshot-list --domain vm

4. Revert

virsh snapshot-revert --domain vm --snapshotname pre-upgrade --running

5. Delete

virsh snapshot-delete --domain vm --snapshotname pre-upgrade

6. Full clone

virt-clone --original source-vm --name clone-vm --file /var/lib/libvirt/images/clone-vm.qcow2

7. Auto-clone

virt-clone --original source-vm --auto-clone

8. Linked clone overlay

qemu-img create -f qcow2 -b base.qcow2 -F qcow2 overlay.qcow2

9. Generalize the guest

virt-sysprep -d clone-vm

10. Off-host backup

virsh backup-begin vm

Visual

The snapshot types

┌─────────────────────────────────────────────────────────────┐
│  INTERNAL                                                    │
│    disk.qcow2 contains base + snapshot metadata + deltas    │
│    Single file. Offline only in practice.                   │
│                                                              │
│  EXTERNAL                                                    │
│    base.qcow2 (read-only) ← overlay.qcow2 (new writes)      │
│    Live-safe. Adds a layer to the chain.                    │
└─────────────────────────────────────────────────────────────┘

The snapshot chain

┌─────────────────────────────────────────────────────────────┐
│  base.qcow2 ← snap1.qcow2 ← snap2.qcow2 ← live.qcow2       │
│                                                              │
│  Each external snapshot adds a layer.                        │
│  Reads traverse the chain back to the base.                  │
└─────────────────────────────────────────────────────────────┘

Full clone vs linked clone

┌─────────────────────────────────────────────────────────────┐
│  FULL CLONE                                                  │
│    source.qcow2 ──► independent copy                         │
│    No dependency on the source.                              │
│                                                              │
│  LINKED CLONE                                                │
│    source.qcow2 (backing) ← overlay.qcow2                   │
│    Fast, space-efficient, depends on the source.            │
└─────────────────────────────────────────────────────────────┘

The backup boundary

┌─────────────────────────────────────────────────────────────┐
│  SNAPSHOT                      BACKUP                        │
│                                                              │
│  Same storage                  Off-host storage              │
│  Depends on base disk          Independent copy              │
│  Rollback point                Recovery point                │
└─────────────────────────────────────────────────────────────┘

Summary

ItemValue
Snapshot requirementqcow2 disk format
Internal snapshotSame file, offline in practice
External snapshotOverlay file, live-safe
Createvirsh snapshot-create-as
Listvirsh snapshot-list
Revertvirsh snapshot-revert
Deletevirsh snapshot-delete
Full clonevirt-clone --original <vm> --name <n> --file <path>
Linked cloneqemu-img create -b base.qcow2
Guest generalizationvirt-sysprep

Key takeaways:

  • Snapshots require qcow2. A raw disk cannot hold an internal snapshot and needs an external-overlay workflow. Check the format with qemu-img info before attempting a snapshot .
  • Internal snapshots are for offline VMs; external snapshots are for live VMs. The internal live-snapshot path was deprecated, and virsh snapshot-create-as on a running VM falls back to external in modern libvirt. Use --disk-only for a live snapshot that does not need memory preserved .
  • A snapshot is not a backup. It shares storage with the VM and depends on the base disk. If the storage is destroyed, every snapshot built on it is lost. Pair snapshots with off-host backups .
  • virt-clone requires the source VM to be shut off. The clone copies the disk and defines a new VM with a unique name, UUID, and MAC address. It does not change anything inside the guest, so virt-sysprep is needed to generalize passwords, IPs, and SSH keys .
  • The --auto-clone option generates the name and disk paths. It appends -clone to the source name and a number if the generated name collides. The --reflink option performs a lightweight copy on btrfs, and --preserve-data creates the new VM definition without copying the disk.
  • Long external snapshot chains degrade I/O. Each layer must be traversed on read. Flatten the chain with blockcommit or blockpull when the snapshots are no longer needed.

Remember: Snapshots and clones are rollback and duplication tools, not backup tools. A snapshot captures a point in time on the same storage; a clone creates an independent VM. Both require qcow2 for the snapshot path, and the clone requires the source VM to be shut off. Use virsh snapshot-create-as for the snapshot, virsh snapshot-revert for the rollback, and virt-clone for the duplicate. Generalize the clone with virt-sysprep before starting it. And keep an off-host backup of anything that matters, because the snapshot cannot survive the loss of the storage it lives on.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!