Patchwork [RFC] QMP: new query-snapshots command

login
register
mail settings
Submitter Miguel Di Ciurcio Filho
Date June 8, 2010, 12:26 p.m.
Message ID <1275999977-2813-1-git-send-email-miguel.filho@gmail.com>
Download mbox | patch
Permalink /patch/54966/
State New
Headers show

Comments

Miguel Di Ciurcio Filho - June 8, 2010, 12:26 p.m.
Hi there,

This is just an initial draft. I would like to align everybody's opinions and
expectations about this feature before starting coding and submitting patches.
(although I've already started to hack some stuff [1])

The way QEMU tracks snapshot identification is not consistent and lacks various
features already available in other virtualization solutions (free or not).

This proposal tries to bring QEMU to the level of other virtualization solutions
when snapshoting is concerned and to define the QMP semantics for it.

Case A:
$ savevm (no parameters)

When no name is provided, a new id_str is created by searching for the
bigger id_str among the available snapshots in the device being taken
an snapshot.

This is done in block/qcow2-snapshot.c:find_new_snapshot_id() with
conversions from char, to int, and then to char again.

Problems:
A VM is loaded with two devices, one device with three previous snapshots and
the other device with two previous snapshots.

I take a new snapshot of the VM without a name: the first device will
save the snapshot as id_str 4 and the second device with id_str 3.

I play around for a while and I want to restore the VM to my latest
state. When 'info snapshots' is run, only the first device is show
with the VM state, and the latest ID shown will be 4.

So, I fire up loadvm 4. qemu will try to load by id or name anyway,
will succeed loading the VM state from the first device, but will fail
to load an non-existent snapshot id from the second device and will
still be running with the second device out of sync with the VM state.
Just take a look at savevm.c:load_vmstate().

Case B:
qemu allows tacking a new snapshot and use a previously used id_str.

Running again:
$ savevm 4

The previously saved state identified by id_str 4 will be deleted and
replaced by a new one, but only in the first device of my example
above. The second device will get a new snapshot, since it does not
have a id_str equal to 4.

If I run loadvm 4 again, the snapshot id 3 in the second device will be left
there in an state diferent from the snapshot id 3 from the first device.

Case C:
Regarding the history of snapshots, qemu does not keep the
last/current snapshot taken.

typedef struct QEMUSnapshotInfo {
   char id_str[128]; /* unique snapshot id */
   /* the following fields are informative. They are not needed for
      the consistency of the snapshot */
   char name[256]; /* user choosen name */
   uint32_t vm_state_size; /* VM state info size */
   uint32_t date_sec; /* UTC date of the snapshot */
   uint32_t date_nsec;
   uint64_t vm_clock_nsec; /* VM clock relative to boot */
} QEMUSnapshotInfo;

There is no "parent"-like information.

To solve this problems, I believe we need to:

- Use a stronger identification for an snapshot, i.e.: bigger and
virtually unique identification for a certain snapshot being taken and
do not re-use an previous used ID for a new snapshot. UUID seams to be
a common denominator, as other virtualization projects use it.

- Add a 'parent_uuid' information. (uuid information can be added using the
  extra_data field in qcow2, other formats like VDI already have)

- Take the calculation of the snapshot ID outside the block driver's level.

[1] http://github.com/miguelzinho/qemu-uuid/commits/master

Signed-off-by: Miguel Di Ciurcio Filho <miguel.filho@gmail.com>
---
 qemu-monitor.hx |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

Patch

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index f6a94f2..27bd3d7 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -2207,6 +2207,67 @@  show information about active capturing
 @item info snapshots
 show list of VM snapshots
 ETEXI
+SQMP
+query-snapshots
+---------------
+
+Show snapshot information about a VM.
+
+Each block device that supports and have snapshot information is stored in a
+json-object and the returned value is a json-array containing all devices.
+
+- "device": device name (json-string)
+- "state": true if the device is elected to hold the VM state. (json-bool)
+- "snapshots": a json-object containing:
+     - "uuid": UUID that identifies the snapshot (json-string)
+     - "parent_uuid": UUID that identifies the a parent snapshot (json-string)
+     - "date": date when the snapshot was taken, formated as YYYYMMDDHHMMSS (json-int)
+     - "tag": friendly name for an snapshot. It is not unique (json-string, optional)
+
+Example:
+
+-> { "execute": "query-snapshots" }
+<- {
+     "return": [
+        {
+            "device": "virtio0",
+            "state": true,
+            "snaphots": [
+                {
+                    "uuid": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5",
+                    "parent_uuid": "00000000-0000-0000-0000-000000000000",
+                    "date": 20100415164856
+                },
+                {
+                    "uuid": "54ad75b9-552e-4fd1-852b-a1a20ac66bf5",
+                    "parent_uuid": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5",
+                    "tag": "test1",
+                    "date": 20100416100000
+                }
+            ]
+        },
+        {
+            "device": "virtio1",
+            "state": false,
+            "snaphots": [
+                {
+                    "uuid": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5",
+                    "parent_uuid": "00000000-0000-0000-0000-000000000000",
+                    "date": 20100415164856
+                },
+                {
+                    "uuid": "54ad75b9-552e-4fd1-852b-a1a20ac66bf5",
+                    "parent_uuid": "3fab28c9-a6bd-4659-b9bc-683780d8a2d5",
+                    "tag": "test1",
+                    "date": 20100416100000
+                }
+            ]
+        }
+    ]
+}
+
+
+EQMP
 
 STEXI
 @item info status