Features/SnapshottingImprovements
Summary
Adjust the savevm, loadvm and info snapshots commands to facilitate the transtion to QMP.
This page is being maintained by the GSoC student Miguel Di Ciurcio Filho as part the QMP project. All feedback is appreciated.
Issues
Problem | Difficulty | Proposed solution | Status |
---|---|---|---|
Snapshot existence is not verified before bdrv_snapshot_goto() | Easy |
|
|
Monitor shows wrong information about snapshots | Easy |
|
|
Do not allow empty names | Easy |
|
|
Snapshot overwriting | Easy |
|
|
snapshot ID collision | Easy |
|
|
ID and TAG confusion | Medium |
|
|
inheritance | Hard |
|
Snapshot existence is not verified before bdrv_snapshot_goto()
This patch improves the resilience of the load_vmstate() function, doing further and better ordered tests.
In load_vmstate(), if there is any error on bdrv_snapshot_goto(), except if the error is on VM state device, load_vmstate() will return zero and the VM will be started with major corruption chances.
Monitor shows wrong information about snapshots
The output generated by 'info snapshots' shows only snapshots that exist on the block device that saves the VM state. This output can cause an user to erroneously try to load an snapshot that is not available on all block devices.
$ qemu-img snapshot -l xxtest.qcow2 Snapshot list: ID TAG VM SIZE DATE VM CLOCK 1 1.5M 2010-07-26 16:51:52 00:00:08.599 2 1.5M 2010-07-26 16:51:53 00:00:09.719 3 1.5M 2010-07-26 17:26:49 00:00:13.245 4 1.5M 2010-07-26 19:01:00 00:00:46.763
$ qemu-img snapshot -l xxtest2.qcow2 Snapshot list: ID TAG VM SIZE DATE VM CLOCK 3 0 2010-07-26 17:26:49 00:00:13.245 4 0 2010-07-26 19:01:00 00:00:46.763
Current output:
$ qemu -hda xxtest.qcow2 -hdb xxtest2.qcow2 -monitor stdio -vnc :0 QEMU 0.12.4 monitor - type 'help' for more information (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 1.5M 2010-07-26 16:51:52 00:00:08.599 2 1.5M 2010-07-26 16:51:53 00:00:09.719 3 1.5M 2010-07-26 17:26:49 00:00:13.245 4 1.5M 2010-07-26 19:01:00 00:00:46.763
Snapshots 1 and 2 do not exist on xxtest2.qcow, but they are displayed anyway.
New output:
(qemu) info snapshots ID TAG VM SIZE DATE VM CLOCK 3 1.5M 2010-07-26 17:26:49 00:00:13.245 4 1.5M 2010-07-26 19:01:00 00:00:46.763
Do not allow empty names
When running:
(qemu) savevm
The snapshot is saved without a name and can only be loaded using the generated ID. The idea is to not have IDs exposed, so every snapshot must have a name.
Snapshot overwriting
Is this the expected behavior? Don't think so.
By id
(qemu) savevm (qemu) savevm (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 3.9M 2010-07-21 17:08:31 00:00:03.696 2 3.9M 2010-07-21 17:08:33 00:00:05.419 <-- 17:08:33 (qemu) savevm 2 <overwrittes the snapshot with id 2> (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 3.9M 2010-07-21 17:08:31 00:00:03.696 2 3.9M 2010-07-21 17:08:53 00:00:25.918 <-- 17:08:53
By tag
(qemu) savevm test1 (qemu) savevm test2 (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 test1 3.9M 2010-07-21 17:12:11 00:00:08.126 <-- 17:12:11 2 test2 3.9M 2010-07-21 17:12:19 00:00:16.053 (qemu) savevm test1 (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 2 test2 3.9M 2010-07-21 17:12:19 00:00:16.053 1 test1 3.9M 2010-07-21 17:12:33 00:00:29.221 <-- 17:12:33
Ideas for improvements:
- Do not allow the user to overwrite an snapshot, even if saving with the same name (will have different IDs anyway)
snapshot ID collision
qemu-img create -f qcow2 diskA.qcow2 10G qemu-img create -f qcow2 diskB.qcow2 10G
qemu -hda diskA.qcow2 (qemu) savevm a (qemu) savevm b (qemu) savevm c
qemu -hda diskB.qcow2 (qemu) savevm a (qemu) savevm b
qemu -hda diskB.qcow2 -hdb diskA.qcow2 (qemu) loadvm b
diskA.qcow2 and diskB.qcow2 have both the same snapshot identification b and 2, but they were taken at different moments and must not be loaded. We need an stronger ID mechanism to identify snapshots among different disks. It is not a common case, but we reduce the chance of anyone having trouble.
ID and TAG confusion
What other projects do?
- VirtualBox does not allow specifying an ID, just a name and description of an snapshot. http://www.virtualbox.org/manual/ch01.html#snapshots
- VMware does not allow specifying and ID, just a name and description. http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1015180
- XenServer does not allow specifying an ID, just a name. http://support.citrix.com/servlet/KbServlet/download/23735-102-646135/Administrators_Guide.pdf - page 127
Starting a VM with no previous snapshot on the disks.
(qemu) savevm 2 (qemu) savevm (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 2 1.5M 2010-07-21 16:55:48 00:00:15.581 2 1.5M 2010-07-21 16:55:55 00:00:21.501 (qemu) loadvm 2 <loads the VM with the id 2>
It is not clear witch snapshot is going to be loaded.
Ideas for improvements:
- savevm tests the argument to check if it is an ID or a TAG. Make it accept only a TAG and do not allow the user to specify and ID.
- loadvm does the same thing. The user must specify if an ID or TAG is wanted. Suggestions:
(qemu) loadvm id=3 (qemu) loadvm tag=xxx (qemu) loadvm xxx <error> (qemu) loadvm 3 <error>
In case loadvm cannot be changed due to retro-compatibility, introduce a new command. Suggestions:
(qemu) load_vm id=3 (qemu) load_vm tag=xxx (qemu) loadvm_byid 3 (qemu) loadvm_bytag xxx
inheritance
The only way to know witch snapshot came before of after another is to look at the date, but it is not possible to fully deduct the relationship. e.g.:
(qemu) savevm a (qemu) savevm b (qemu) savevm c (qemu) savevm d (qemu) loadvm b (qemu) savevm e (qemu) info snapshots Snapshot devices: ide0-hd0 Snapshot list (from ide0-hd0): ID TAG VM SIZE DATE VM CLOCK 1 a 3.9M 2010-07-21 17:32:55 00:00:06.144 2 b 3.9M 2010-07-21 17:33:00 00:00:11.103 3 c 3.9M 2010-07-21 17:33:13 00:00:22.953 4 d 3.9M 2010-07-21 17:33:16 00:00:26.289 5 e 3.9M 2010-07-21 17:33:28 00:00:15.548
Snapshot e is newer than d, but it is an state saved right after b, and not d as implied by the ids and dates. libvirt wants this.
QMP
Here is a list of suggested commands to manipulate snapshots information on a QEMU VM.
query-snapshot-status
Returns true when the VM can be snapshotted, false otherwise.
-> {"execute": "query-snapshot-status"} <- {"return": true }
- Not sure if QMP allow returning just a boolean.
snapshot-create
Runs savevm.
-> {"execute": "snapshot-create", "arguments": {"name": "vm_before_upgrade"} } <- { "return": {} }
- "name" is mandatory and must be unique.
- Needs to return any errors.
snapshot-delete
Runs delvm.
-> {"execute": "snapshot-delete", "arguments": {"name": "vm_before_upgrade"} } <- { "return": {} }
- "name" is mandatory and must be unique.
- Needs to return any errors.
snapshot-load
Runs loadvm.
-> {"execute": "snapshot-load", "arguments": {"name": "vm_before_upgrade"} } <- { "return": {} }
- "name" is mandatory and must be unique.
- Needs to return any errors.
query-snapshots
-> {"execute": "query-snapshots"} <- { "return": [ { "name": "vm_before_upgrade", "parent_name": "", "id": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5", "parent_id": "00000000-0000-0000-0000-000000000000", "date": 20100415164856 }, { "name": "vm_before_upgrade-2", "parent_name": "vm_before_upgrade", "id": "e693dce2-6e12-4474-9bbf-2b3f97323423", "parent_id": "00000000-0000-0000-0000-000000000000", "date": 20100415100000 } ] }
- Do we really need to expose IDs or names should be enough?
- Does JSON has a date type of just using a integer like YYYYMMDDHHMMSS would be better?
Instead of a list, how about this:
-> {"execute": "query-snapshots"} <- { "return": [ { "vm_before_upgrade": { "id": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5", "date": 20100415164856, "child": { "vm_before_upgrade-2": "id": "e693dce2-6e12-4474-9bbf-2b3f97323423", "date": 20100415100000 } } "random-backup": { "id": "abcdefcc-a6bd-4659-b9bc-683780d8a2d5", "date": 20111111111111 } } ]