From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=58362 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OLe1i-0000iS-Cw for qemu-devel@nongnu.org; Mon, 07 Jun 2010 11:14:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OLe1d-0002Ml-0M for qemu-devel@nongnu.org; Mon, 07 Jun 2010 11:14:10 -0400 Received: from mail-iw0-f173.google.com ([209.85.214.173]:48047) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OLe1c-0002MZ-Pr for qemu-devel@nongnu.org; Mon, 07 Jun 2010 11:14:04 -0400 Received: by iwn41 with SMTP id 41so3598386iwn.4 for ; Mon, 07 Jun 2010 08:14:04 -0700 (PDT) Message-ID: <4C0D0CB8.903@codemonkey.ws> Date: Mon, 07 Jun 2010 10:14:00 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 11/19] Add a query-devices command to QMP References: <1275921752-29420-1-git-send-email-berrange@redhat.com> <1275921752-29420-12-git-send-email-berrange@redhat.com> In-Reply-To: <1275921752-29420-12-git-send-email-berrange@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Daniel P. Berrange" Cc: qemu-devel@nongnu.org On 06/07/2010 09:42 AM, Daniel P. Berrange wrote: > Adds a command to QMP called 'query-devices' to allow for discovery > of all devices known to the QEMU binary. THis is inteded to replace > use of the '-device ?' and '-device devtype,?' command line args > > The data format is designed to allow easy extension to support more > data: > query-qdm? Regards, Anthony Liguori > [ > { > "name": "virtio-9p-pci", > "creatable": true, > "bus": "PCI", > "props": [ > { > "name": "indirect_desc", > "type": "bit", > "info": "on/off" > }, > { > "name": "mount_tag", > "type": "string", > "info": "string" > }, > { > "name": "fsdev", > "type": "string", > "info": "string" > } > ] > }, > { > "name": "virtio-balloon-pci", > "creatable": true, > "bus": "PCI", > "props": [ > { > "name": "indirect_desc", > "type": "bit", > "info": "on/off" > } > ] > }, > ... > ] > > No legacy readline monitor output is provided. > > Signed-off-by: Daniel P. Berrange > --- > hw/qdev.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > hw/qdev.h | 2 + > monitor.c | 8 +++ > 3 files changed, 156 insertions(+), 0 deletions(-) > > diff --git a/hw/qdev.c b/hw/qdev.c > index 1186dfa..0a10c3c 100644 > --- a/hw/qdev.c > +++ b/hw/qdev.c > @@ -29,6 +29,7 @@ > #include "qdev.h" > #include "sysemu.h" > #include "monitor.h" > +#include "qjson.h" > > static int qdev_hotplug = 0; > > @@ -810,3 +811,148 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data) > } > return qdev_unplug(dev); > } > + > +static const char *qdev_property_type_to_string(int type) { > + switch (type) { > + case PROP_TYPE_UNSPEC: > + return "unknown"; > + case PROP_TYPE_UINT8: > + return "uint8"; > + case PROP_TYPE_UINT16: > + return "uint16"; > + case PROP_TYPE_UINT32: > + return "uint32"; > + case PROP_TYPE_INT32: > + return "int32"; > + case PROP_TYPE_UINT64: > + return "uint64"; > + case PROP_TYPE_TADDR: > + return "taddr"; > + case PROP_TYPE_MACADDR: > + return "macaddr"; > + case PROP_TYPE_DRIVE: > + return "drive"; > + case PROP_TYPE_CHR: > + return "chr"; > + case PROP_TYPE_STRING: > + return "string"; > + case PROP_TYPE_NETDEV: > + return "netdev"; > + case PROP_TYPE_VLAN: > + return "vlan"; > + case PROP_TYPE_PTR: > + return "pointer"; > + case PROP_TYPE_BIT: > + return "bit"; > + } > + return NULL; > +} > + > + > +/* > + * Describe capabilities of all devices registered with qdev > + * > + * The returned output is a QList, each element is a QDict > + * describing a single device type. The valid keys for the > + * device dictionary are > + * > + * - "name": the short name of the device > + * - "bus": the name of the bus type for the device > + * - "alias": an alias by which the device is also known (optional) > + * - "description": a long description the device (optional) > + * - "props": a list of device properties > + * - "creatable": whether this device can be created on command line > + * > + * The 'props' list is a QList, with each element being a > + * QDict describing a single property of the device. The > + * valid property keys are > + * > + * - "name": the short name of the property > + * - "info": short description of the property > + * - "type": the data type of the property value > + * > + * An example: > + * > + * [ > + * { > + * "name": "virtio-9p-pci", > + * "creatable": true, > + * "bus": "PCI", > + * "props": [ > + * { > + * "name": "indirect_desc", > + * "type": "bit", > + * "info": "on/off" > + * }, > + * { > + * "name": "mount_tag", > + * "type": "string", > + * "info": "string" > + * }, > + * { > + * "name": "fsdev", > + * "type": "string", > + * "info": "string" > + * } > + * ] > + * }, > + * { > + * "name": "virtio-balloon-pci", > + * "creatable": true, > + * "bus": "PCI", > + * "props": [ > + * { > + * "name": "indirect_desc", > + * "type": "bit", > + * "info": "on/off" > + * } > + * ] > + * }, > + * .... > + * ] > + */ > +void do_info_devices(Monitor *mon, QObject **data) > +{ > + DeviceInfo *info; > + QList *devs = qlist_new(); > + > + for (info = device_info_list; info != NULL; info = info->next) { > + QObject *dev; > + QList *props = qlist_new(); > + Property *prop; > + > + for (prop = info->props; prop&& prop->name; prop++) { > + QObject *entry; > + /* > + * TODO Properties without a parser are just for dirty hacks. > + * qdev_prop_ptr is the only such PropertyInfo. It's marked > + * for removal. This conditional should be removed along with > + * it. > + */ > + if (!prop->info->parse) { > + continue; /* no way to set it, don't show */ > + } > + > + const char *type = qdev_property_type_to_string(prop->info->type); > + > + entry = qobject_from_jsonf("{ 'name': %s, 'info': %s, 'type': %s }", > + prop->name, prop->info->name, type); > + > + qlist_append_obj(props, entry); > + } > + > + dev = qobject_from_jsonf("{ 'name': %s, 'bus': %s, 'props': %p, 'creatable': %i }", > + info->name, > + info->bus_info->name, > + props, > + info->no_user ? 0 : 1); > + if (info->alias) > + qdict_put_obj((QDict*)dev, "alias", QOBJECT(qstring_from_str(info->alias))); > + if (info->desc) > + qdict_put_obj((QDict*)dev, "description", QOBJECT(qstring_from_str(info->desc))); > + > + qlist_append_obj(devs, dev); > + } > + > + *data = QOBJECT(devs); > +} > diff --git a/hw/qdev.h b/hw/qdev.h > index a44060e..fe6f981 100644 > --- a/hw/qdev.h > +++ b/hw/qdev.h > @@ -280,6 +280,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props); > void qdev_prop_register_global_list(GlobalProperty *props); > void qdev_prop_set_globals(DeviceState *dev); > > +void do_info_devices(Monitor *mon, QObject **data); > + > /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ > extern struct BusInfo system_bus_info; > > diff --git a/monitor.c b/monitor.c > index b6aa2b4..13f70a0 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -2458,6 +2458,14 @@ static const mon_cmd_t info_cmds[] = { > .mhandler.info_new = do_info_machines, > }, > { > + .name = "devices", > + .args_type = "", > + .params = "", > + .help = "show the registered QDev devices", > + .user_print = monitor_user_noop, > + .mhandler.info_new = do_info_devices, > + }, > + { > .name = "commands", > .args_type = "", > .params = "", >