nova采用 libvirt blockcopy(python API virDomainBlockRebase)来做live snapshot.
Create the base image:
$ qemu-img create -f qcow2 base 1G
$ guestfish -a base.qcow2
[. . .]
><fs> run
><fs> part-disk /dev/sda mbr
><fs> mkfs ext4 /dev/sda1
><fs> mount /dev/sda1 /
><fs> touch /foo
><fs> ls /
foo
><fs> exit
Create another QCOW2 overlay snapshot ‘snap1’, with backing file as ‘base’:
$ qemu-img create -f qcow2 -b base.qcow2 \
-o backing_fmt=qcow2 snap1.qcow2
Add a file to snap1.qcow2:
$ guestfish -a snap1.qcow2 [. . .] ><fs> run ><fs> part-disk /dev/sda mbr ><fs> mkfs ext4 /dev/sda1 ><fs> mount /dev/sda1 / ><fs> touch /bar ><fs> ls / bar baz foo lost+found ><fs> exit
Create another QCOW2 overlay snapshot ‘snap2’, with backing file as ‘snap1’:
$ qemu-img create -f qcow2 -b snap1.qcow2 \ -o backing_fmt=qcow2 snap2.qcow2
Add another test file ‘baz’ into snap2.qcow2 using guestfish
(refer to previous examples above) to distinguish contents of base, snap1 and snap2.
Create a simple libvirt XML file as below, with source file pointing to snap2.qcow2 — which will be the active block device (i.e. it tracks all new guest writes):
$ cat <<EOF > /etc/libvirt/qemu/testvm.xml
<domain type='kvm'>
<name>testvm</name>
<memory unit='MiB'>512</memory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64'>hvm</type>
</os>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/export/vmimages/snap2.qcow2'/>
<target dev='vda' bus='virtio'/>
</disk>
</devices>
</domain>
EOF
Define the guest and start it:
$ virsh define etc/libvirt/qemu/testvm.xml Domain testvm defined from /etc/libvirt/qemu/testvm.xml $ virsh start testvm Domain testvm started
Perform live disk migration
Undefine the running libvirt guest to make it transient[*]:
$ virsh dumpxml --inactive testvm > /var/tmp/testvm.xml
$ virsh undefine testvm
Check what is the current block device before performing live disk migration:
$ virsh domblklist testvm Target Source ------------------------------------------------ vda /export/vmimages/snap2.qcow2
Optionally, display the backing chain of snap2.qcow2:
$ qemu-img info --backing-chain /export/vmimages/snap2.qcow2 [. . .] # Output removed for brevity
Initiate blockcopy
(live disk mirroring):
$ virsh blockcopy --domain testvm vda \
/export/blockcopy-test/backups/copy.qcow2 \
--wait --verbose --shallow \
--pivot
Details of the above command: It creates copy.qcow2 file in the specified path; performs a --shallow
blockcopy (i.e. the ‘copy’ shares the backing chain) of the current block device (vda
); –pivot will pivot the live QEMU to the ‘copy’.
Confirm that QEMU has pivoted to the ‘copy’ by enumerating the current block device in use:
$ virsh domblklist testvm Target Source ------------------------------------------------ vda /export/vmimages/copy.qcow2
Again, display the backing chain of ‘copy’, it should be the resultant chain as noted in the Scenario section above).
$ qemu-img info --backing-chain /export/vmimages/copy.qcow2
Enumerate the contents of copy.qcow2:
$ guestfish -a copy.qcow2
[. . .]
><fs> run
><fs> mount /dev/sda1 /
><fs> ls /
bar
foo
baz
lost+found
><fs> quit
(You can notice above: all the content from base.qcow2, snap1.qcow2, and snap2.qcow2 mirrored into copy.qcow2.)
Edit the libvirt guest XML to use the copy.qcow2, and define it:
$ virsh edit testvm # Replace the<source file='/export/vmimages/snap2.qcow2'/>
# with<source file='/export/vmimages/copy.qcow2'/>
[. . .] $ virsh define /var/tmp/testvm.xml
[*] Reason for the undefining and defining the guest again: As of writing this, QEMU has to support persistent dirty bitmap — this enables us to restart a QEMU process with disk mirroring intact. There are some in-progress patches upstream for a while. Until they are in main line QEMU, the current approach (as illustrated above) is: make a running libvirt guest transient temporarily, perform live blockcopy
, and make the guest persistent again. (Thanks to Eric Blake, one of libvirt project’s principal developers, for this detail.)
http://kashyapc.com/2014/07/06/live-disk-migration-with-libvirt-blockcopy/
In QEMU, pre-copy storage migration has two phases:
- add a streaming mirror to the existing image (not a snapshot+mirror);
- reopen the image to the new mirror ("pivot" the mirror).
http://wiki.qemu.org/Features/SnapshotsMultipleDevices