diff mbox

[RFC,v3,2/6] VMState test: get information about the registered devices

Message ID 1407565595-18861-3-git-send-email-sanidhya.iiith@gmail.com
State New
Headers show

Commit Message

Sanidhya Kashyap Aug. 9, 2014, 6:26 a.m. UTC
Added both qmp and hmp interface to get the information about the devices that
have been qdevified and are registered with the SaveVMHandlers. I have not used 
any format to print the device information for the hmp interface. It would be
great if anyone can give me some pointers about this about the printing format
if there is something.

The qmp command to extract the information about the devices is
qmp_query_devices which provides the list of device names and their respective
version. The hmp command name is 'info devices' which lists the same information
as provided by the qmp interface.

Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
---
 hmp-commands.hx  |  2 ++
 hmp.c            | 23 +++++++++++++++++++++++
 hmp.h            |  1 +
 monitor.c        |  7 +++++++
 qapi-schema.json | 26 ++++++++++++++++++++++++++
 qmp-commands.hx  | 43 +++++++++++++++++++++++++++++++++++++++++++
 savevm.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 147 insertions(+)

Comments

Eric Blake Aug. 11, 2014, 4:24 p.m. UTC | #1
On 08/09/2014 12:26 AM, Sanidhya Kashyap wrote:
> Added both qmp and hmp interface to get the information about the devices that
> have been qdevified and are registered with the SaveVMHandlers. I have not used 
> any format to print the device information for the hmp interface. It would be
> great if anyone can give me some pointers about this about the printing format
> if there is something.
> 
> The qmp command to extract the information about the devices is
> qmp_query_devices which provides the list of device names and their respective
> version. The hmp command name is 'info devices' which lists the same information
> as provided by the qmp interface.
> 
> Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
> ---
>  hmp-commands.hx  |  2 ++
>  hmp.c            | 23 +++++++++++++++++++++++
>  hmp.h            |  1 +
>  monitor.c        |  7 +++++++
>  qapi-schema.json | 26 ++++++++++++++++++++++++++
>  qmp-commands.hx  | 43 +++++++++++++++++++++++++++++++++++++++++++
>  savevm.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 147 insertions(+)
> 
> +++ b/qapi-schema.json
> @@ -3480,3 +3480,29 @@
>  # Since: 2.1
>  ##
>  { 'command': 'rtc-reset-reinjection' }
> +
> +##
> +# @QemuDevice
> +#
> +# device that is registered with SaveVMHandlers

This sounds like an internal implementation detail; is there a better
description more suited to what this struct represents from the API
point of view, maybe as simple as: "Information about a device"


> +{ 'command': 'query-devices',
> +  'returns': [ 'QemuDevice' ] }

Looks okay here...

> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 4be4765..e489197 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx

> +
> +Example (1):

s/ (1)// - unless you have a second example, you don't need to label the
first example with a 1 suffix

> +
> +-> { "execute": "query-devices" }
> +<- { "return": [
> +       {
> +           [ { 'device-name': 'kvm-tpr-opt', 'version': 1 },

... but this doesn't match your command.  You have too many layers.
Also, QMP wire format uses ONLY ", never '.  It should look like:

{ "return": [ { "device-name": "kvm-tpr-opt", "version": 1 },
              ...
            ] }

In fact, rather than trying to write it by hand, actually compile your
code and test the actual QMP output and paste that in - then you'll know
you got it right.


> +static QemuDeviceList *create_device_list(const char *name, int version,
> +                                           QemuDeviceList *list)

Indentation is off.
diff mbox

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index d0943b1..a221459 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1780,6 +1780,8 @@  show qdev device model list
 show roms
 @item info tpm
 show the TPM device
+@item info devices
+show the devices registered with migration capability
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index 4d1838e..6e1802a 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1714,3 +1714,26 @@  void hmp_info_memdev(Monitor *mon, const QDict *qdict)
 
     monitor_printf(mon, "\n");
 }
+
+void hmp_info_devices(Monitor *mon, const QDict *qdict)
+{
+    Error *err = NULL;
+    QemuDeviceList *device_list = qmp_query_devices(&err);
+
+    if (device_list) {
+        monitor_printf(mon, "devices:\n");
+        while (device_list) {
+            monitor_printf(mon, "device-name: %s, ",
+                           device_list->value->device_name);
+            monitor_printf(mon, "version: %ld\n",
+                           device_list->value->version);
+            device_list = device_list->next;
+        }
+    }
+
+    if (err) {
+        hmp_handle_error(mon, &err);
+    }
+
+    qapi_free_QemuDeviceList(device_list);
+}
diff --git a/hmp.h b/hmp.h
index 4fd3c4a..9d6b577 100644
--- a/hmp.h
+++ b/hmp.h
@@ -38,6 +38,7 @@  void hmp_info_balloon(Monitor *mon, const QDict *qdict);
 void hmp_info_pci(Monitor *mon, const QDict *qdict);
 void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
 void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+void hmp_info_devices(Monitor *mon, const QDict *qdict);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 5bc70a6..2431686 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2918,6 +2918,13 @@  static mon_cmd_t info_cmds[] = {
         .mhandler.cmd = hmp_info_memdev,
     },
     {
+        .name       = "devices",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show registered devices",
+        .mhandler.cmd = hmp_info_devices,
+    },
+    {
         .name       = NULL,
     },
 };
diff --git a/qapi-schema.json b/qapi-schema.json
index b11aad2..74d26fe 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3480,3 +3480,29 @@ 
 # Since: 2.1
 ##
 { 'command': 'rtc-reset-reinjection' }
+
+##
+# @QemuDevice
+#
+# device that is registered with SaveVMHandlers
+#
+# @device-name: name of the device that is registered with
+# SaveVMHandlers (in vmsd structure).
+#
+# @version: version of the device.
+#
+# Since 2.2
+##
+{ 'type': 'QemuDevice',
+  'data': { 'device-name':  'str',
+            '*version':     'int' } }
+
+##
+# @query-devices
+#
+# returns the list of QemuDevice
+#
+# Since 2.2
+##
+{ 'command': 'query-devices',
+  'returns': [ 'QemuDevice' ] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4be4765..e489197 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3755,3 +3755,46 @@  Example:
 <- { "return": {} }
 
 EQMP
+
+    {
+        .name       = "query-devices",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_query_devices,
+    },
+
+SQMP
+query-devices
+-------------
+
+Shows registered devices along with the version
+
+Example (1):
+
+-> { "execute": "query-devices" }
+<- { "return": [
+       {
+           [ { 'device-name': 'kvm-tpr-opt', 'version': 1 },
+             { 'device-name': 'apic', 'version': 3 },
+             { 'device-name': 'kvmclock', 'version': 1 },
+             { 'device-name': 'fw_cfg', 'version': 2 },
+             { 'device-name': 'I440FX', 'version': 3 },
+             { 'device-name': 'PIIX3', 'version': 3 },
+             { 'device-name': 'i8259', 'version': 1 },
+             { 'device-name': 'i8259', 'version': 1 },
+             { 'device-name': 'ioapic', 'version': 3 },
+             { 'device-name': 'cirrus_vga', 'version': 2 },
+             { 'device-name': 'hpet', 'version': 2 },
+             { 'device-name': 'mc146818rtc', 'version': 3 },
+             { 'device-name': 'i8254', 'version': 3 },
+             { 'device-name': 'serial', 'version': 3 },
+             { 'device-name': 'pckbd', 'version': 3 },
+             { 'device-name': 'vmmouse', 'version': 0 },
+             { 'device-name': 'port92', 'version': 1 },
+             { 'device-name': 'fdc', 'version': 2 },
+             { 'device-name': 'e1000', 'version': 2 },
+             { 'device-name': 'ide', 'version': 3 },
+             { 'device-name': 'piix4_pm', 'version': 3 } ]
+       }
+     ]
+   }
+EQMP
diff --git a/savevm.c b/savevm.c
index e19ae0a..764ca71 100644
--- a/savevm.c
+++ b/savevm.c
@@ -233,6 +233,7 @@  typedef struct SaveStateEntry {
     void *opaque;
     CompatEntry *compat;
     int is_ram;
+    DeviceState *dev;
 } SaveStateEntry;
 
 
@@ -429,6 +430,7 @@  int register_savevm_live(DeviceState *dev,
     se->ops = ops;
     se->opaque = opaque;
     se->vmsd = NULL;
+    se->dev = dev;
     /* if this is a live_savem then set is_ram */
     if (ops->save_live_setup != NULL) {
         se->is_ram = 1;
@@ -519,6 +521,7 @@  int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
     se->opaque = opaque;
     se->vmsd = vmsd;
     se->alias_id = alias_id;
+    se->dev = dev;
 
     if (dev) {
         char *id = qdev_get_dev_path(dev);
@@ -1137,6 +1140,48 @@  void do_savevm(Monitor *mon, const QDict *qdict)
     }
 }
 
+static QemuDeviceList *create_device_list(const char *name, int version,
+                                           QemuDeviceList *list)
+{
+    QemuDeviceList *temp_list;
+    QemuDeviceList *parent_list = list;
+    int len;
+
+    temp_list = g_malloc0(sizeof(QemuDeviceList));
+    len = strlen(name);
+    temp_list->value = g_malloc0(sizeof(QemuDevice));
+    temp_list->value->device_name = g_malloc0(sizeof(char)*(len+1));
+    strcpy(temp_list->value->device_name, name);
+    temp_list->value->version = version;
+    temp_list->next = NULL;
+
+    if (!list) {
+        return temp_list;
+    }
+
+    while (list->next) {
+        list = list->next;
+    }
+    list->next = temp_list;
+
+    return parent_list;
+}
+
+QemuDeviceList *qmp_query_devices(Error **errp)
+{
+    QemuDeviceList *device_list = NULL;
+    SaveStateEntry *se;
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        if (se->dev) {
+            device_list = create_device_list(se->vmsd->name, se->version_id,
+                                             device_list);
+        }
+    }
+
+    return device_list;
+}
+
 void qmp_xen_save_devices_state(const char *filename, Error **errp)
 {
     QEMUFile *f;