From: Steve Sistare <steven.sist...@oracle.com> Using qom-list and qom-get to get all the nodes and property values in a QOM tree can take multiple seconds because it requires 1000's of individual QOM requests. Some managers fetch the entire tree or a large subset of it when starting a new VM, and this cost is a substantial fraction of start up time.
Define the qom-list-get command, which fetches all the properties and values for a list of paths. This can be much faster than qom-list plus qom-get. When getting an entire QOM tree, I measured a 10x speedup in elapsed time. Signed-off-by: Steve Sistare <steven.sist...@oracle.com> Tested-by: Philippe Mathieu-Daudé <phi...@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org> Reviewed-by: Markus Armbruster <arm...@redhat.com> Message-ID: <1752248703-217318-2-git-send-email-steven.sist...@oracle.com> Signed-off-by: Markus Armbruster <arm...@redhat.com> --- qapi/qom.json | 50 +++++++++++++++++++++++++++++++++++++++++++ qom/qom-qmp-cmds.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/qapi/qom.json b/qapi/qom.json index 96d56df6cd..830cb2ffe7 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -47,6 +47,34 @@ '*description': 'str', '*default-value': 'any' } } +## +# @ObjectPropertyValue: +# +# @name: the name of the property. +# +# @type: the type of the property, as described in `ObjectPropertyInfo`. +# +# @value: the value of the property. Absent when the property cannot +# be read. +# +# Since 10.1 +## +{ 'struct': 'ObjectPropertyValue', + 'data': { 'name': 'str', + 'type': 'str', + '*value': 'any' } } + +## +# @ObjectPropertiesValues: +# +# @properties: a list of properties. +# +# Since 10.1 +## +{ 'struct': 'ObjectPropertiesValues', + 'data': { 'properties': [ 'ObjectPropertyValue' ] }} + + ## # @qom-list: # @@ -124,6 +152,28 @@ 'returns': 'any', 'allow-preconfig': true } +## +# @qom-list-get: +# +# List properties and their values for each object path in the input +# list. +# +# @paths: The absolute or partial path for each object, as described +# in `qom-get`. +# +# Errors: +# - If any path is not valid or is ambiguous +# +# Returns: A list where each element is the result for the +# corresponding element of @paths. +# +# Since 10.1 +## +{ 'command': 'qom-list-get', + 'data': { 'paths': [ 'str' ] }, + 'returns': [ 'ObjectPropertiesValues' ], + 'allow-preconfig': true } + ## # @qom-set: # diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c index 293755f409..57f1898cf6 100644 --- a/qom/qom-qmp-cmds.c +++ b/qom/qom-qmp-cmds.c @@ -69,6 +69,59 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) return props; } +static void qom_list_add_property_value(Object *obj, ObjectProperty *prop, + ObjectPropertyValueList **props) +{ + ObjectPropertyValue *item = g_new0(ObjectPropertyValue, 1); + + QAPI_LIST_PREPEND(*props, item); + + item->name = g_strdup(prop->name); + item->type = g_strdup(prop->type); + item->value = object_property_get_qobject(obj, prop->name, NULL); +} + +static ObjectPropertyValueList *qom_get_property_value_list(const char *path, + Error **errp) +{ + Object *obj; + ObjectProperty *prop; + ObjectPropertyIterator iter; + ObjectPropertyValueList *props = NULL; + + obj = qom_resolve_path(path, errp); + if (obj == NULL) { + return NULL; + } + + object_property_iter_init(&iter, obj); + while ((prop = object_property_iter_next(&iter))) { + qom_list_add_property_value(obj, prop, &props); + } + + return props; +} + +ObjectPropertiesValuesList *qmp_qom_list_get(strList *paths, Error **errp) +{ + ObjectPropertiesValuesList *head = NULL, **tail = &head; + strList *path; + + for (path = paths; path; path = path->next) { + ObjectPropertiesValues *item = g_new0(ObjectPropertiesValues, 1); + + QAPI_LIST_APPEND(tail, item); + + item->properties = qom_get_property_value_list(path->value, errp); + if (!item->properties) { + qapi_free_ObjectPropertiesValuesList(head); + return NULL; + } + } + + return head; +} + void qmp_qom_set(const char *path, const char *property, QObject *value, Error **errp) { -- 2.49.0