Features/Snapshots2

From QEMU

Overview

This describes an alternative mechanism of live snapshotting for QEMU. It's based on simple mechanisms that combined together create a rich API.

Contact

Requirements

  • Live snapshot: when command execution completes, all future writes will be redirected into a separate location. The previous block device has a consistent state whereas it represents a point-in-time snapshot compare to the new write location. This operation does not guarantee the exact point in time when the disk separation happened except for the fact that it was before the command completed and that the view is consistent.
  • Managing live snapshots. It should be possible to delete a live snapshot. Upon deletion, writes should go to normal storage.
  • Live snapshotting should only affect performance while the a live snapshot is active.
  • Interaction with guest. It should be possible to alert the guest that a live snapshot is about to take place and wait for the guest to respond with an Ack. Additionally, it should be possible to notify the guest that live snapshot operation has completed.

Example work flow

qemu-img create -f raw foo.img 10G
qemu -hda foo.img

Alter guest that snapshot is about to be performed by issuing monitor command

(qemu) guest_cmd begin_snapshot

Waits to receive notification that guest is ready (based on command completion. In the background, create a new qcow2 image that refers to the guest image, then redirect write operations to new location:

# qemu-img create -f qcow2 -b foo.img tmp_disk.img 10G
(qemu) guest_cmd begin_snapshot
(qemu) change -l ide0-hd0 file=tmp_disk.img

Alter guest that snapshot is over once command completes

# qemu-img create -f qcow2 -b foo.img tmp_disk.img 10G
(qemu) guest_cmd begin_snapshot
(qemu) change -l ide0-hd0 file=tmp_disk.img
(qemu) guest_cmd end_snapshot

foo.img can now be accessed as a snapshot. When backup is complete, merge the image into itself.

(qemu) merge_disk tmp_disk.img

The merge_disk command will copy the allocated block content into the backing file and once the image is empty, reopen the backing file with read/write access closing the original disk image.

Tracking dirty blocks

The following sequence can be used to track dirty blocks at 4k granularity on a 10G image:

# qemu-img create -f dirty_bitmap -o cluster_size=4k t0_dirty.dbmp 10G
(qemu) set_dirty ide0-hd0 t0_dirty.dbmp

The following sequence combines dirty tracking with snapshotting to enable live snapshotting with incremental backups. Shell commands are intermixed with monitor commands for clarity.

# qemu-img create -f raw foo.img 10G
# qemu-img create -f dirty_bitmap -o cluster_size=4k t0.dbmp 10G
# qemu -hda foo.img -S

(qemu) set_dirty ide0-hd0 t0_dirty.dbmp
(qemu) cont

// guest runs for some predetermined time period
// backup software initiates backup

# qemu-img create -f qcow2 -b foo.img tmp_write.img 10G
# qemu-img create -f dirty_bitmap -o cluster_size=4k t1.dbmp 10G

(qemu) guest_cmd begin_snapshot
(qemu) set_dirty ide0-hd0 t1_dirty.dbmp  ;; start t1 a little earlier than t0 ends, but that's okay
(qemu) change -l ide0-hd0 file=tmp_write.img
(qemu) guest_cmd end_snapshot

// backup software now reads foo.img using t0_dirty.dbmp to perform incremental backup, when finished
// t0_dirty.dbmp can be removed
// after backup is complete

(qemu) merge_disk tmp_write.img

// when this command completes, tmp_write.img can be deleted.  at this point, we're left with
// the guest using foo.img directly, and t1_dirty.dbmp tracking the write operations for the guest
// when the next backup period comes, we restart the process except we use t2.dbmp as the new dirty
// bitmap and use t1.dbmp to determine what parts have changed

Other proposed qemu features that solve the same problem

Snapshots and Livebackup

snapshots
livebackup