diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2014-05-20 14:29:01 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-07-07 11:10:05 +0200 |
commit | f4eb32b590bf58c1c67570775eb78beb09964fad (patch) | |
tree | ee7bc6587f75b4804722704fd0215743bf711d0f | |
parent | dd67c1d7e75151e2c058ccdd2162643074357442 (diff) |
qmp: show QOM properties in device-list-properties
Devices can use a mix of qdev and QOM properties. Currently only the
qdev properties are displayed by device-list-properties.
This patch extends the property enumeration algorithm to also display
QOM properties (excluding the implicit "type", "realized",
"hotpluggable", and "parent_bus" properties).
When a qdev property exists, use the qdev type name to preserve
backwards compatibility. QOM type names can be different for bool (qdev
on/off) and str (used by qdev pointers).
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | qmp.c | 99 |
1 files changed, 76 insertions, 23 deletions
@@ -433,11 +433,57 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements, return ret; } +/* Return a DevicePropertyInfo for a qdev property. + * + * If a qdev property with the given name does not exist, use the given default + * type. If the qdev property info should not be shown, return NULL. + * + * The caller must free the return value. + */ +static DevicePropertyInfo *make_device_property_info(ObjectClass *klass, + const char *name, + const char *default_type) +{ + DevicePropertyInfo *info; + Property *prop; + + do { + for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) { + if (strcmp(name, prop->name) != 0) { + continue; + } + + /* + * 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->set) { + return NULL; /* no way to set it, don't show */ + } + + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(prop->name); + info->type = g_strdup(prop->info->legacy_name ?: prop->info->name); + return info; + } + klass = object_class_get_parent(klass); + } while (klass != object_class_by_name(TYPE_DEVICE)); + + /* Not a qdev property, use the default type */ + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(name); + info->type = g_strdup(default_type); + return info; +} + DevicePropertyInfoList *qmp_device_list_properties(const char *typename, Error **errp) { ObjectClass *klass; - Property *prop; + Object *obj; + ObjectProperty *prop; DevicePropertyInfoList *prop_list = NULL; klass = object_class_by_name(typename); @@ -453,32 +499,39 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, return NULL; } - do { - for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) { - DevicePropertyInfoList *entry; - DevicePropertyInfo *info; + obj = object_new(typename); - /* - * 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->set) { - continue; /* no way to set it, don't show */ - } + QTAILQ_FOREACH(prop, &obj->properties, node) { + DevicePropertyInfo *info; + DevicePropertyInfoList *entry; + + /* Skip Object and DeviceState properties */ + if (strcmp(prop->name, "type") == 0 || + strcmp(prop->name, "realized") == 0 || + strcmp(prop->name, "hotpluggable") == 0 || + strcmp(prop->name, "parent_bus") == 0) { + continue; + } - info = g_malloc0(sizeof(*info)); - info->name = g_strdup(prop->name); - info->type = g_strdup(prop->info->legacy_name ?: prop->info->name); + /* Skip legacy properties since they are just string versions of + * properties that we already list. + */ + if (strstart(prop->name, "legacy-", NULL)) { + continue; + } - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - entry->next = prop_list; - prop_list = entry; + info = make_device_property_info(klass, prop->name, prop->type); + if (!info) { + continue; } - klass = object_class_get_parent(klass); - } while (klass != object_class_by_name(TYPE_DEVICE)); + + entry = g_malloc0(sizeof(*entry)); + entry->value = info; + entry->next = prop_list; + prop_list = entry; + } + + object_unref(obj); return prop_list; } |