qom: qom-list-get

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.sistare@oracle.com>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <1752248703-217318-2-git-send-email-steven.sistare@oracle.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Steve Sistare 2025-07-11 08:45:01 -07:00 committed by Markus Armbruster
parent f96b157ebb
commit 8eb6d39e22
2 changed files with 103 additions and 0 deletions

View file

@ -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)
{