diff --git a/MAINTAINERS b/MAINTAINERS index 8f44dca48a..4030e2749d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -587,7 +587,7 @@ F: hw/ppc/prep.c F: hw/pci-host/prep.[hc] F: hw/isa/pc87312.[hc] -sPAPR (pseries) +sPAPR M: David Gibson M: Alexander Graf L: qemu-ppc@nongnu.org diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 2c7101d91d..44bf790b01 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -1206,7 +1206,6 @@ static void device_finalize(Object *obj) NamedGPIOList *ngl, *next; DeviceState *dev = DEVICE(obj); - qemu_opts_del(dev->opts); QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) { QLIST_REMOVE(ngl, node); @@ -1254,6 +1253,9 @@ static void device_unparent(Object *obj) qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort); g_free(path); } + + qemu_opts_del(dev->opts); + dev->opts = NULL; } static void device_class_init(ObjectClass *class, void *data) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 4fb86a68c4..dccb908c31 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -684,7 +684,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, { Object *root_container; ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; uint32_t drc_count = 0; GArray *drc_indexes, *drc_power_domains; GString *drc_names, *drc_types; @@ -708,8 +708,8 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, */ root_container = container_get(object_get_root(), DRC_CONTAINER_PATH); - iter = object_property_iter_init(root_container); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, root_container); + while ((prop = object_property_iter_next(&iter))) { Object *obj; sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; @@ -750,7 +750,6 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner, spapr_drc_get_type_str(drc->type)); drc_types = g_string_insert_len(drc_types, -1, "\0", 1); } - object_property_iter_free(iter); /* now write the drc count into the space we reserved at the * beginning of the arrays previously diff --git a/include/qom/object.h b/include/qom/object.h index 4509166f6f..d0dafe986c 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -381,6 +381,8 @@ struct ObjectClass const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; ObjectUnparent *unparent; + + GHashTable *properties; }; /** @@ -944,6 +946,13 @@ ObjectProperty *object_property_add(Object *obj, const char *name, void object_property_del(Object *obj, const char *name, Error **errp); +ObjectProperty *object_class_property_add(ObjectClass *klass, const char *name, + const char *type, + ObjectPropertyAccessor *get, + ObjectPropertyAccessor *set, + ObjectPropertyRelease *release, + void *opaque, Error **errp); + /** * object_property_find: * @obj: the object @@ -954,15 +963,20 @@ void object_property_del(Object *obj, const char *name, Error **errp); */ ObjectProperty *object_property_find(Object *obj, const char *name, Error **errp); +ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name, + Error **errp); -typedef struct ObjectPropertyIterator ObjectPropertyIterator; +typedef struct ObjectPropertyIterator { + ObjectClass *nextclass; + GHashTableIter iter; +} ObjectPropertyIterator; /** * object_property_iter_init: * @obj: the object * * Initializes an iterator for traversing all properties - * registered against an object instance. + * registered against an object instance, its class and all parent classes. * * It is forbidden to modify the property list while iterating, * whether removing or adding properties. @@ -973,32 +987,27 @@ typedef struct ObjectPropertyIterator ObjectPropertyIterator; * Using object property iterators * * ObjectProperty *prop; - * ObjectPropertyIterator *iter; + * ObjectPropertyIterator iter; * - * iter = object_property_iter_init(obj); - * while ((prop = object_property_iter_next(iter))) { + * object_property_iter_init(&iter, obj); + * while ((prop = object_property_iter_next(&iter))) { * ... do something with prop ... * } - * object_property_iter_free(iter); * * - * - * Returns: the new iterator */ -ObjectPropertyIterator *object_property_iter_init(Object *obj); - -/** - * object_property_iter_free: - * @iter: the iterator instance - * - * Releases any resources associated with the iterator. - */ -void object_property_iter_free(ObjectPropertyIterator *iter); +void object_property_iter_init(ObjectPropertyIterator *iter, + Object *obj); /** * object_property_iter_next: * @iter: the iterator instance * + * Return the next available property. If no further properties + * are available, a %NULL value will be returned and the @iter + * pointer should not be used again after this point without + * re-initializing it. + * * Returns: the next property, or %NULL when all properties * have been traversed. */ @@ -1371,6 +1380,12 @@ void object_property_add_str(Object *obj, const char *name, void (*set)(Object *, const char *, Error **), Error **errp); +void object_class_property_add_str(ObjectClass *klass, const char *name, + char *(*get)(Object *, Error **), + void (*set)(Object *, const char *, + Error **), + Error **errp); + /** * object_property_add_bool: * @obj: the object to add a property to @@ -1387,6 +1402,11 @@ void object_property_add_bool(Object *obj, const char *name, void (*set)(Object *, bool, Error **), Error **errp); +void object_class_property_add_bool(ObjectClass *klass, const char *name, + bool (*get)(Object *, Error **), + void (*set)(Object *, bool, Error **), + Error **errp); + /** * object_property_add_enum: * @obj: the object to add a property to @@ -1406,6 +1426,13 @@ void object_property_add_enum(Object *obj, const char *name, void (*set)(Object *, int, Error **), Error **errp); +void object_class_property_add_enum(ObjectClass *klass, const char *name, + const char *typename, + const char * const *strings, + int (*get)(Object *, Error **), + void (*set)(Object *, int, Error **), + Error **errp); + /** * object_property_add_tm: * @obj: the object to add a property to @@ -1420,6 +1447,10 @@ void object_property_add_tm(Object *obj, const char *name, void (*get)(Object *, struct tm *, Error **), Error **errp); +void object_class_property_add_tm(ObjectClass *klass, const char *name, + void (*get)(Object *, struct tm *, Error **), + Error **errp); + /** * object_property_add_uint8_ptr: * @obj: the object to add a property to @@ -1432,6 +1463,8 @@ void object_property_add_tm(Object *obj, const char *name, */ void object_property_add_uint8_ptr(Object *obj, const char *name, const uint8_t *v, Error **errp); +void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, + const uint8_t *v, Error **errp); /** * object_property_add_uint16_ptr: @@ -1445,6 +1478,8 @@ void object_property_add_uint8_ptr(Object *obj, const char *name, */ void object_property_add_uint16_ptr(Object *obj, const char *name, const uint16_t *v, Error **errp); +void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, + const uint16_t *v, Error **errp); /** * object_property_add_uint32_ptr: @@ -1458,6 +1493,8 @@ void object_property_add_uint16_ptr(Object *obj, const char *name, */ void object_property_add_uint32_ptr(Object *obj, const char *name, const uint32_t *v, Error **errp); +void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, + const uint32_t *v, Error **errp); /** * object_property_add_uint64_ptr: @@ -1471,6 +1508,8 @@ void object_property_add_uint32_ptr(Object *obj, const char *name, */ void object_property_add_uint64_ptr(Object *obj, const char *name, const uint64_t *v, Error **Errp); +void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, + const uint64_t *v, Error **Errp); /** * object_property_add_alias: @@ -1522,6 +1561,9 @@ void object_property_add_const_link(Object *obj, const char *name, */ void object_property_set_description(Object *obj, const char *name, const char *description, Error **errp); +void object_class_property_set_description(ObjectClass *klass, const char *name, + const char *description, + Error **errp); /** * object_child_foreach: diff --git a/net/filter.c b/net/filter.c index f777ba2899..5d90f83429 100644 --- a/net/filter.c +++ b/net/filter.c @@ -137,7 +137,7 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) Error *local_err = NULL; char *str, *info; ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; StringOutputVisitor *ov; if (!nf->netdev_id) { @@ -174,8 +174,8 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); /* generate info str */ - iter = object_property_iter_init(OBJECT(nf)); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, OBJECT(nf)); + while ((prop = object_property_iter_next(&iter))) { if (!strcmp(prop->name, "type")) { continue; } @@ -189,7 +189,6 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) g_free(str); g_free(info); } - object_property_iter_free(iter); } static void netfilter_finalize(Object *obj) diff --git a/qmp.c b/qmp.c index 0a1fa19925..3ff6db79b9 100644 --- a/qmp.c +++ b/qmp.c @@ -210,7 +210,7 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) bool ambiguous = false; ObjectPropertyInfoList *props = NULL; ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; obj = object_resolve_path(path, &ambiguous); if (obj == NULL) { @@ -223,8 +223,8 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) return NULL; } - iter = object_property_iter_init(obj); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, obj); + while ((prop = object_property_iter_next(&iter))) { ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry)); entry->value = g_malloc0(sizeof(ObjectPropertyInfo)); @@ -234,7 +234,6 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp) entry->value->name = g_strdup(prop->name); entry->value->type = g_strdup(prop->type); } - object_property_iter_free(iter); return props; } @@ -506,7 +505,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, ObjectClass *klass; Object *obj; ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; DevicePropertyInfoList *prop_list = NULL; klass = object_class_by_name(typename); @@ -535,8 +534,8 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, obj = object_new(typename); - iter = object_property_iter_init(obj); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, obj); + while ((prop = object_property_iter_next(&iter))) { DevicePropertyInfo *info; DevicePropertyInfoList *entry; @@ -567,7 +566,6 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, entry->next = prop_list; prop_list = entry; } - object_property_iter_free(iter); object_unref(obj); diff --git a/qom/object.c b/qom/object.c index d7515697a3..5ff97ab91e 100644 --- a/qom/object.c +++ b/qom/object.c @@ -67,10 +67,6 @@ struct TypeImpl InterfaceImpl interfaces[MAX_INTERFACES]; }; -struct ObjectPropertyIterator { - GHashTableIter iter; -}; - static Type type_interface; static GHashTable *type_table_get(void) @@ -246,6 +242,16 @@ static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, iface_impl->class); } +static void object_property_free(gpointer data) +{ + ObjectProperty *prop = data; + + g_free(prop->name); + g_free(prop->type); + g_free(prop->description); + g_free(prop); +} + static void type_initialize(TypeImpl *ti) { TypeImpl *parent; @@ -268,6 +274,8 @@ static void type_initialize(TypeImpl *ti) g_assert_cmpint(parent->class_size, <=, ti->class_size); memcpy(ti->class, parent->class, parent->class_size); ti->class->interfaces = NULL; + ti->class->properties = g_hash_table_new_full( + g_str_hash, g_str_equal, g_free, object_property_free); for (e = parent->class->interfaces; e; e = e->next) { InterfaceClass *iface = e->data; @@ -292,6 +300,9 @@ static void type_initialize(TypeImpl *ti) type_initialize_interface(ti, t, t); } + } else { + ti->class->properties = g_hash_table_new_full( + g_str_hash, g_str_equal, g_free, object_property_free); } ti->class->type = ti; @@ -330,16 +341,6 @@ static void object_post_init_with_type(Object *obj, TypeImpl *ti) } } -static void object_property_free(gpointer data) -{ - ObjectProperty *prop = data; - - g_free(prop->name); - g_free(prop->type); - g_free(prop->description); - g_free(prop); -} - void object_initialize_with_type(void *data, size_t size, TypeImpl *type) { Object *obj = data; @@ -918,10 +919,10 @@ object_property_add(Object *obj, const char *name, const char *type, return ret; } - if (g_hash_table_lookup(obj->properties, name) != NULL) { + if (object_property_find(obj, name, NULL) != NULL) { error_setg(errp, "attempt to add duplicate property '%s'" - " to object (type '%s')", name, - object_get_typename(obj)); + " to object (type '%s')", name, + object_get_typename(obj)); return NULL; } @@ -939,10 +940,50 @@ object_property_add(Object *obj, const char *name, const char *type, return prop; } +ObjectProperty * +object_class_property_add(ObjectClass *klass, + const char *name, + const char *type, + ObjectPropertyAccessor *get, + ObjectPropertyAccessor *set, + ObjectPropertyRelease *release, + void *opaque, + Error **errp) +{ + ObjectProperty *prop; + + if (object_class_property_find(klass, name, NULL) != NULL) { + error_setg(errp, "attempt to add duplicate property '%s'" + " to object (type '%s')", name, + object_class_get_name(klass)); + return NULL; + } + + prop = g_malloc0(sizeof(*prop)); + + prop->name = g_strdup(name); + prop->type = g_strdup(type); + + prop->get = get; + prop->set = set; + prop->release = release; + prop->opaque = opaque; + + g_hash_table_insert(klass->properties, g_strdup(name), prop); + + return prop; +} + ObjectProperty *object_property_find(Object *obj, const char *name, Error **errp) { ObjectProperty *prop; + ObjectClass *klass = object_get_class(obj); + + prop = object_class_property_find(klass, name, NULL); + if (prop) { + return prop; + } prop = g_hash_table_lookup(obj->properties, name); if (prop) { @@ -953,30 +994,47 @@ ObjectProperty *object_property_find(Object *obj, const char *name, return NULL; } -ObjectPropertyIterator *object_property_iter_init(Object *obj) +void object_property_iter_init(ObjectPropertyIterator *iter, + Object *obj) { - ObjectPropertyIterator *ret = g_new0(ObjectPropertyIterator, 1); - g_hash_table_iter_init(&ret->iter, obj->properties); - return ret; -} - -void object_property_iter_free(ObjectPropertyIterator *iter) -{ - if (!iter) { - return; - } - g_free(iter); + g_hash_table_iter_init(&iter->iter, obj->properties); + iter->nextclass = object_get_class(obj); } ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) { gpointer key, val; - if (!g_hash_table_iter_next(&iter->iter, &key, &val)) { - return NULL; + while (!g_hash_table_iter_next(&iter->iter, &key, &val)) { + if (!iter->nextclass) { + return NULL; + } + g_hash_table_iter_init(&iter->iter, iter->nextclass->properties); + iter->nextclass = object_class_get_parent(iter->nextclass); } return val; } +ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name, + Error **errp) +{ + ObjectProperty *prop; + ObjectClass *parent_klass; + + parent_klass = object_class_get_parent(klass); + if (parent_klass) { + prop = object_class_property_find(parent_klass, name, NULL); + if (prop) { + return prop; + } + } + + prop = g_hash_table_lookup(klass->properties, name); + if (!prop) { + error_setg(errp, "Property '.%s' not found", name); + } + return prop; +} + void object_property_del(Object *obj, const char *name, Error **errp) { ObjectProperty *prop = g_hash_table_lookup(obj->properties, name); @@ -1730,6 +1788,29 @@ void object_property_add_str(Object *obj, const char *name, } } +void object_class_property_add_str(ObjectClass *klass, const char *name, + char *(*get)(Object *, Error **), + void (*set)(Object *, const char *, + Error **), + Error **errp) +{ + Error *local_err = NULL; + StringProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + prop->set = set; + + object_class_property_add(klass, name, "string", + get ? property_get_str : NULL, + set ? property_set_str : NULL, + property_release_str, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + typedef struct BoolProperty { bool (*get)(Object *, Error **); @@ -1797,6 +1878,28 @@ void object_property_add_bool(Object *obj, const char *name, } } +void object_class_property_add_bool(ObjectClass *klass, const char *name, + bool (*get)(Object *, Error **), + void (*set)(Object *, bool, Error **), + Error **errp) +{ + Error *local_err = NULL; + BoolProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + prop->set = set; + + object_class_property_add(klass, name, "bool", + get ? property_get_bool : NULL, + set ? property_set_bool : NULL, + property_release_bool, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + static void property_get_enum(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { @@ -1860,6 +1963,31 @@ void object_property_add_enum(Object *obj, const char *name, } } +void object_class_property_add_enum(ObjectClass *klass, const char *name, + const char *typename, + const char * const *strings, + int (*get)(Object *, Error **), + void (*set)(Object *, int, Error **), + Error **errp) +{ + Error *local_err = NULL; + EnumProperty *prop = g_malloc(sizeof(*prop)); + + prop->strings = strings; + prop->get = get; + prop->set = set; + + object_class_property_add(klass, name, typename, + get ? property_get_enum : NULL, + set ? property_set_enum : NULL, + property_release_enum, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + typedef struct TMProperty { void (*get)(Object *, struct tm *, Error **); } TMProperty; @@ -1939,6 +2067,25 @@ void object_property_add_tm(Object *obj, const char *name, } } +void object_class_property_add_tm(ObjectClass *klass, const char *name, + void (*get)(Object *, struct tm *, Error **), + Error **errp) +{ + Error *local_err = NULL; + TMProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + + object_class_property_add(klass, name, "struct tm", + get ? property_get_tm : NULL, NULL, + property_release_tm, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + static char *qdev_get_type(Object *obj, Error **errp) { return g_strdup(object_get_typename(obj)); @@ -1983,6 +2130,13 @@ void object_property_add_uint8_ptr(Object *obj, const char *name, NULL, NULL, (void *)v, errp); } +void object_class_property_add_uint8_ptr(ObjectClass *klass, const char *name, + const uint8_t *v, Error **errp) +{ + object_class_property_add(klass, name, "uint8", property_get_uint8_ptr, + NULL, NULL, (void *)v, errp); +} + void object_property_add_uint16_ptr(Object *obj, const char *name, const uint16_t *v, Error **errp) { @@ -1990,6 +2144,13 @@ void object_property_add_uint16_ptr(Object *obj, const char *name, NULL, NULL, (void *)v, errp); } +void object_class_property_add_uint16_ptr(ObjectClass *klass, const char *name, + const uint16_t *v, Error **errp) +{ + object_class_property_add(klass, name, "uint16", property_get_uint16_ptr, + NULL, NULL, (void *)v, errp); +} + void object_property_add_uint32_ptr(Object *obj, const char *name, const uint32_t *v, Error **errp) { @@ -1997,6 +2158,13 @@ void object_property_add_uint32_ptr(Object *obj, const char *name, NULL, NULL, (void *)v, errp); } +void object_class_property_add_uint32_ptr(ObjectClass *klass, const char *name, + const uint32_t *v, Error **errp) +{ + object_class_property_add(klass, name, "uint32", property_get_uint32_ptr, + NULL, NULL, (void *)v, errp); +} + void object_property_add_uint64_ptr(Object *obj, const char *name, const uint64_t *v, Error **errp) { @@ -2004,6 +2172,13 @@ void object_property_add_uint64_ptr(Object *obj, const char *name, NULL, NULL, (void *)v, errp); } +void object_class_property_add_uint64_ptr(ObjectClass *klass, const char *name, + const uint64_t *v, Error **errp) +{ + object_class_property_add(klass, name, "uint64", property_get_uint64_ptr, + NULL, NULL, (void *)v, errp); +} + typedef struct { Object *target_obj; char *target_name; @@ -2101,6 +2276,23 @@ void object_property_set_description(Object *obj, const char *name, op->description = g_strdup(description); } +void object_class_property_set_description(ObjectClass *klass, + const char *name, + const char *description, + Error **errp) +{ + ObjectProperty *op; + + op = g_hash_table_lookup(klass->properties, name); + if (!op) { + error_setg(errp, "Property '.%s' not found", name); + return; + } + + g_free(op->description); + op->description = g_strdup(description); +} + static void object_instance_init(Object *obj) { object_property_add_str(obj, "type", qdev_get_type, NULL, NULL); diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index e674c0fa89..448d270b68 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -123,18 +123,28 @@ static void dummy_init(Object *obj) dummy_get_bv, dummy_set_bv, NULL); - object_property_add_str(obj, "sv", - dummy_get_sv, - dummy_set_sv, - NULL); - object_property_add_enum(obj, "av", - "DummyAnimal", - dummy_animal_map, - dummy_get_av, - dummy_set_av, - NULL); } + +static void dummy_class_init(ObjectClass *cls, void *data) +{ + object_class_property_add_bool(cls, "bv", + dummy_get_bv, + dummy_set_bv, + NULL); + object_class_property_add_str(cls, "sv", + dummy_get_sv, + dummy_set_sv, + NULL); + object_class_property_add_enum(cls, "av", + "DummyAnimal", + dummy_animal_map, + dummy_get_av, + dummy_set_av, + NULL); +} + + static void dummy_finalize(Object *obj) { DummyObject *dobj = DUMMY_OBJECT(obj); @@ -150,6 +160,7 @@ static const TypeInfo dummy_info = { .instance_init = dummy_init, .instance_finalize = dummy_finalize, .class_size = sizeof(DummyObjectClass), + .class_init = dummy_class_init, }; @@ -444,11 +455,11 @@ static void test_dummy_iterator(void) NULL)); ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; bool seenbv = false, seensv = false, seenav = false, seentype; - iter = object_property_iter_init(OBJECT(dobj)); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, OBJECT(dobj)); + while ((prop = object_property_iter_next(&iter))) { if (g_str_equal(prop->name, "bv")) { seenbv = true; } else if (g_str_equal(prop->name, "sv")) { @@ -463,7 +474,6 @@ static void test_dummy_iterator(void) g_assert_not_reached(); } } - object_property_iter_free(iter); g_assert(seenbv); g_assert(seenav); g_assert(seensv); diff --git a/vl.c b/vl.c index b7a083eb56..f043009f67 100644 --- a/vl.c +++ b/vl.c @@ -1535,14 +1535,14 @@ MachineInfoList *qmp_query_machines(Error **errp) static int machine_help_func(QemuOpts *opts, MachineState *machine) { ObjectProperty *prop; - ObjectPropertyIterator *iter; + ObjectPropertyIterator iter; if (!qemu_opt_has_help_opt(opts)) { return 0; } - iter = object_property_iter_init(OBJECT(machine)); - while ((prop = object_property_iter_next(iter))) { + object_property_iter_init(&iter, OBJECT(machine)); + while ((prop = object_property_iter_next(&iter))) { if (!prop->set) { continue; } @@ -1555,7 +1555,6 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine) error_printf("\n"); } } - object_property_iter_free(iter); return 1; }