Patchwork [V9,09/14] qmp: add interface query-images

login
register
mail settings
Submitter Wayne Xia
Date March 11, 2013, 11:23 a.m.
Message ID <1363000996-13221-10-git-send-email-xiawenc@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/226526/
State New
Headers show

Comments

Wayne Xia - March 11, 2013, 11:23 a.m.
This mirror function will return image info including snapshots,
and if specified backing image's info will also be returned. Now
Qemu have both query-images and query-block interfaces.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 block/qapi.c     |   83 +++++++++++++++++++++++++++++++++++++++++++++++++
 qapi-schema.json |   33 ++++++++++++++++++++
 qmp-commands.hx  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 206 insertions(+), 0 deletions(-)
Eric Blake - March 12, 2013, 9:24 p.m.
On 03/11/2013 05:23 AM, Wenchao Xia wrote:
>   This mirror function will return image info including snapshots,
> and if specified backing image's info will also be returned. Now
> Qemu have both query-images and query-block interfaces.

In the middle of a sentence, we prefer QEMU or qemu, not Qemu.

> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  block/qapi.c     |   83 +++++++++++++++++++++++++++++++++++++++++++++++++
>  qapi-schema.json |   33 ++++++++++++++++++++
>  qmp-commands.hx  |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 206 insertions(+), 0 deletions(-)
> 

As pointed out at the top level, why do we need a new command?  Could
query-devices be enhanced instead to provide this information as
additional dictionary members, so that a single query provides entire
backing chain and internal snapshot data alongside everything else?

>  ##
> +# @query-images:
> +#
> +# Get block device image information
> +#
> +# @device: #optional the name of the device to get image info from. If not
> +#          specified, all block devices will be queried

Even if we decide to add a new command, I still think this is overkill
for QMP.  Just return the data on all the devices, all the time.

> +# @backing: #optional true to show information on backing images, false or
> +#          omitted to show just the top image of a block device

Likewise.  Calling apps can filter out what they need, without you
having to add filtering into the qmp code.  HMP can do filtering, since
it is supposed to be human-friendly, but I don't see a reason to make
QMP give reduced information.

Patch

diff --git a/block/qapi.c b/block/qapi.c
index 7bf2581..0cbbb8c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -201,3 +201,86 @@  SnapshotInfoList *qmp_query_snapshots(Error **errp)
 
     return list;
 }
+
+/* Collect all info for one bs, p_list point to the empty tail to be filled,
+   return the empty tail of the new list. @bs must be the top one. */
+static DeviceImageInfoList **
+collect_device_image_info_list(BlockDriverState *bs,
+                               bool show_backing,
+                               DeviceImageInfoList **p_list,
+                               Error **errp)
+{
+    DeviceImageInfoList **p_next = p_list;
+    char *device_name = bs->device_name;
+
+    while (bs) {
+        DeviceImageInfo *dii = g_malloc0(sizeof(*dii));
+        DeviceImageInfoList *diil = g_malloc0(sizeof(*diil));
+        diil->value = dii;
+        *p_next = diil;
+        p_next = &diil->next;
+
+        dii->device = g_strdup(device_name);
+        if (!bdrv_is_inserted(bs)) {
+            dii->has_image = false;
+            break;
+        }
+        dii->has_image = true;
+        if (bdrv_query_image_info(bs, &dii->image, errp)) {
+            break;
+        }
+
+        if (show_backing && bs->drv && bs->backing_hd) {
+            bs = bs->backing_hd;
+        } else {
+            bs = NULL;
+        }
+    }
+    return p_next;
+}
+
+DeviceImageInfoList *qmp_query_images(bool has_device,
+                                      const char *device,
+                                      bool has_backing,
+                                      bool backing,
+                                      Error **errp)
+{
+    DeviceImageInfoList *head = NULL, **p_next = &head;
+    BlockDriverState *bs = NULL;
+    Error *err = NULL;
+    const char *target_device = NULL;
+    bool show_backing = false;
+
+    if (has_device) {
+        target_device = device;
+    }
+    if (has_backing) {
+        show_backing = backing;
+    }
+
+    if (target_device) {
+        bs = bdrv_find(device);
+        if (!bs) {
+            error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+            return NULL;
+        }
+        collect_device_image_info_list(bs, show_backing, p_next, errp);
+        if (error_is_set(&err)) {
+            goto err;
+        }
+    } else {
+        while ((bs = bdrv_next(bs))) {
+            p_next = collect_device_image_info_list(bs, show_backing,
+                                                    p_next, errp);
+            if (error_is_set(&err)) {
+                goto err;
+            }
+        }
+    }
+
+    return head;
+
+ err:
+    qapi_free_DeviceImageInfoList(head);
+    return NULL;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index 014365b..642a10a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -294,6 +294,21 @@ 
            '*total-clusters': 'int', '*allocated-clusters': 'int',
            '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
 
+# @DeviceImageInfo:
+#
+# Information about an image used by a QEMU block device
+#
+# @device: name of the block device
+#
+# @image: #optional info of the image used
+#
+# Since: 1.5
+#
+##
+
+{ 'type': 'DeviceImageInfo',
+  'data': {'device': 'str', '*image': 'ImageInfo' } }
+
 ##
 # @StatusInfo:
 #
@@ -853,6 +868,24 @@ 
   'returns': ['SnapshotInfo'] }
 
 ##
+# @query-images:
+#
+# Get block device image information
+#
+# @device: #optional the name of the device to get image info from. If not
+#          specified, all block devices will be queried
+# @backing: #optional true to show information on backing images, false or
+#          omitted to show just the top image of a block device
+#
+# Returns: a list of @DeviceImageInfo describing each virtual block device
+#
+# Since: 1.5
+##
+{ 'command': 'query-images',
+  'data': { '*device': 'str', '*backing': 'bool' },
+  'returns': ['DeviceImageInfo'] }
+
+##
 # @BlockDeviceStats:
 #
 # Statistics of a virtual block device or a block backing device.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index bd9e127..0c4c08c 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1798,6 +1798,96 @@  EQMP
     },
 
 SQMP
+query-images
+------------
+
+Show block device image information
+
+Each device is represented by a json-object. The returned value is a json-array
+of all devices' images
+
+Each json-object contain the following:
+
+- "device": device name (json-string)
+- "image": image information(json-object, optional) containing:
+         - "filename": image file name (json-string)
+         - "format": image format (json-string)
+         - "virtual-size": image capacity in bytes (json-int)
+         - "dirty-flag": true if image is not cleanly closed, not present means
+                         clean (json-bool, optional)
+         - "actual-size": actual size on disk in bytes of the image, not
+                          present when image does not support thin provision
+                          (json-int, optional)
+         - "cluster-size": size of a cluster in bytes, not present if image
+                           format does not support it (json-int, optional)
+         - "encrypted": true if the image is encrypted, not present means false
+                        or the image format does not support encryption
+                        (json-bool, optional)
+         - "backing_file": backing file name, not present means no backing file
+                           is used or the image format does not support
+                           backing file chain (json-string, optional)
+         - "full-backing-filename": full path of the backing file, not present
+                                    if it equals backing_file or no backing
+                                    file is used. (json-string, optional)
+         - "backing-filename-format": the format of the backing file, not
+                                      present means unknown or no backing file
+                                      (json-string, optional)
+         - "snapshots": the internal snapshot info, it is an optional list of
+            json-object containing the following:
+             - "id": unique snapshot id (json-string)
+             - "name": snapshot name (json-string)
+             - "vm-state-size": size of the VM state in bytes (json-int)
+             - "date-sec": UTC date of the snapshot in seconds (json-int)
+             - "date-nsec": fractional part in nanoseconds to be used with
+                            date-sec(json-int)
+             - "vm-clock-sec": VM clock relative to boot in seconds (json-int)
+             - "vm-clock-nsec": fractional part in nanoseconds to be used with
+                                vm-clock-sec (json-int)
+
+Example:
+
+-> { "execute": "query-images" }
+<- {
+      "return":[
+         {
+            "device":"ide0-hd0",
+            "image":{
+               "filename":"disks/test0.img",
+               "format":"qcow2",
+               "virtual-size":1024000
+            }
+         },
+         {
+            "device":"ide0-hd1",
+            "image":{
+               "filename":"disks/test1.img",
+               "format":"qcow2",
+               "virtual-size":2048000,
+               "snapshots":[
+                  {
+                     "id": "1",
+                     "name": "snapshot1",
+                     "vm-state-size": 0,
+                     "date-sec": 10000200,
+                     "date-nsec": 12,
+                     "vm-clock-sec": 206,
+                     "vm-clock-nsec": 30
+                  }
+               ]
+            }
+         }
+      ]
+   }
+
+EQMP
+
+    {
+        .name       = "query-images",
+        .args_type  = "device:B?, backing:-b",
+        .mhandler.cmd_new = qmp_marshal_input_query_images,
+    },
+
+SQMP
 query-blockstats
 ----------------