From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33917) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aNcSV-0005OI-3j for qemu-devel@nongnu.org; Mon, 25 Jan 2016 03:25:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aNcSQ-0001gz-71 for qemu-devel@nongnu.org; Mon, 25 Jan 2016 03:25:11 -0500 Received: from mail-pf0-x241.google.com ([2607:f8b0:400e:c00::241]:34522) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aNcSP-0001gt-Rx for qemu-devel@nongnu.org; Mon, 25 Jan 2016 03:25:06 -0500 Received: by mail-pf0-x241.google.com with SMTP id 65so6539128pfd.1 for ; Mon, 25 Jan 2016 00:25:05 -0800 (PST) From: Valentin Rakush Date: Mon, 25 Jan 2016 11:24:47 +0300 Message-Id: <1453710287-12706-1-git-send-email-valentin.rakush@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [PATCH v5] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: ehabkost@redhat.com, armbru@redhat.com, lcapitulino@redhat.com, asmetanin@virtuozzo.com, den@openvz.org, Valentin Rakush , afaerber@suse.de This patch adds support for qom-type-prop-list command to list object class properties. A later patch will use this functionality to implement x86_64-cpu properties. Signed-off-by: Valentin Rakush Cc: Luiz Capitulino Cc: Eric Blake Cc: Markus Armbruster Cc: Andreas Färber Cc: Daniel P. Berrange Cc: Eduardo Habkost --- V5: fixes after scripts/checkpatch.pl V4: review fixes - the typename argument in the hmp command changed to be mandatory V3: commit message fix - commit message changed to reflect actual command name V2: Fixes after first review - changed command name from qom-type-list to qom-type-prop-list - changed memory allocation from g_malloc0 to g_new0 - changed parameter name from path to typename - fixed wordings and comments - fixed source code formatting - registered the command in monitor hmp-commands.hx | 13 +++++++++++++ hmp.c | 21 +++++++++++++++++++++ hmp.h | 1 + include/qom/object.h | 31 +++++++++++++++++++++++++++++++ qapi-schema.json | 19 +++++++++++++++++++ qmp-commands.hx | 6 ++++++ qmp.c | 31 +++++++++++++++++++++++++++++++ qom/object.c | 7 +++++++ 8 files changed, 129 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index bb52e4d..ee4d1e2 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path} ETEXI { + .name = "qom-type-prop-list", + .args_type = "typename:s", + .params = "typename", + .help = "list QOM class properties", + .mhandler.cmd = hmp_qom_type_prop_list, + }, + +STEXI +@item qom-type-prop-list [@var{typename}] +Print QOM properties of the type @var{typename} +ETEXI + + { .name = "qom-set", .args_type = "path:s,property:s,value:s", .params = "path property value", diff --git a/hmp.c b/hmp.c index 54f2620..6de9bf0 100644 --- a/hmp.c +++ b/hmp.c @@ -2052,6 +2052,27 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } +void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict) +{ + const char *typename = qdict_get_try_str(qdict, "typename"); + ObjectPropertyInfoList *list; + Error *err = NULL; + + list = qmp_qom_type_prop_list(typename, &err); + if (!err) { + ObjectPropertyInfoList *start = list; + while (list) { + ObjectPropertyInfo *value = list->value; + + monitor_printf(mon, "%s (%s)\n", + value->name, value->type); + list = list->next; + } + qapi_free_ObjectPropertyInfoList(start); + } + hmp_handle_error(mon, &err); +} + void hmp_qom_set(Monitor *mon, const QDict *qdict) { const char *path = qdict_get_str(qdict, "path"); diff --git a/hmp.h b/hmp.h index a8c5b5a..8c12ebe 100644 --- a/hmp.h +++ b/hmp.h @@ -103,6 +103,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void hmp_qom_list(Monitor *mon, const QDict *qdict); +void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict); void hmp_qom_set(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/include/qom/object.h b/include/qom/object.h index d0dafe9..0c8379d 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1013,6 +1013,37 @@ void object_property_iter_init(ObjectPropertyIterator *iter, */ ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter); +/** + * object_class_property_iter_init: + * @klass: the class owning the properties to be iterated over + * + * Initializes an iterator for traversing all properties + * registered against a class type and all parent classes. + * + * It is forbidden to modify the property list while iterating, + * whether removing or adding properties. + * + * NB For getting next property in the list the object related + * function object_property_iter_next is still used. + * + * Typical usage pattern would be + * + * + * Using object class property iterators + * + * ObjectProperty *prop; + * ObjectPropertyIterator iter; + * + * object_class property_iter_init(&iter, obj); + * while ((prop = object_property_iter_next(&iter))) { + * ... do something with prop ... + * } + * + * + */ +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass); + void object_unparent(Object *obj); /** diff --git a/qapi-schema.json b/qapi-schema.json index b3038b2..2e960db 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4081,3 +4081,22 @@ ## { 'enum': 'ReplayMode', 'data': [ 'none', 'record', 'play' ] } + +## +# @qom-type-prop-list: +# +# This command will list any properties of an object class +# given its typename. +# +# @typename: the typename of the class. See @qom-list-types to check +# available typenames. +# +# Returns: a list of @ObjectPropertyInfo that describe the properties +# of the class. +# +# Since: 2.6 +## +{ 'command': 'qom-type-prop-list', + 'data': { 'typename': 'str' }, + 'returns': [ 'ObjectPropertyInfo' ] } + diff --git a/qmp-commands.hx b/qmp-commands.hx index db072a6..d3be962 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3789,6 +3789,12 @@ EQMP }, { + .name = "qom-type-prop-list", + .args_type = "typename:s", + .mhandler.cmd_new = qmp_marshal_qom_type_prop_list, + }, + + { .name = "qom-set", .args_type = "path:s,property:s,value:q", .mhandler.cmd_new = qmp_marshal_qom_set, diff --git a/qmp.c b/qmp.c index 53affe2..baf25c0 100644 --- a/qmp.c +++ b/qmp.c @@ -460,6 +460,37 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements, return ret; } +ObjectPropertyInfoList *qmp_qom_type_prop_list(const char *typename, Error **errp) +{ + ObjectClass *klass; + ObjectPropertyInfoList *props = NULL; + ObjectProperty *prop; + ObjectPropertyIterator iter; + + klass = object_class_by_name(typename); + if (!klass) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Object class '%s' not found", typename); + return NULL; + } + + object_class_property_iter_init(&iter, klass); + while ((prop = object_property_iter_next(&iter))) { + ObjectPropertyInfoList *entry = g_new0(ObjectPropertyInfoList, 1); + + if (entry) { + entry->value = g_new0(ObjectPropertyInfo, 1); + entry->next = props; + props = entry; + + entry->value->name = g_strdup(prop->name); + entry->value->type = g_strdup(prop->type); + } + } + + return props; +} + /* Return a DevicePropertyInfo for a qdev property. * * If a qdev property with the given name does not exist, use the given default diff --git a/qom/object.c b/qom/object.c index 5ff97ab..cabd91d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -994,6 +994,13 @@ ObjectProperty *object_property_find(Object *obj, const char *name, return NULL; } +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass) +{ + g_hash_table_iter_init(&iter->iter, klass->properties); + iter->nextclass = object_class_get_parent(klass); +} + void object_property_iter_init(ObjectPropertyIterator *iter, Object *obj) { -- 1.8.3.1