QOM infrastructure fixes and device conversions
* Dynamic class properties * Property iterator cleanup * Device hot-unplug ID race fix -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABAgAGBQJWnSBlAAoJEPou0S0+fgE/qHgP/2nhaUf0kCyKODCrl4DoJ5gz 0+33lxm0woIdYFyejW3YSiu+S0pwXtU0YwdGqLsIW5gMxEWTBFuguJgKgQuA7eOH kyyyjCssiwTPxre7A/cf3O/JjGMpuqdQEeXRmYdISv50QhiczF80RtJgV3Lj8CVb aFzIiaIOaNULMkeLtBfVJcQnvi5ZUCY2rw/rMUfUP2jlLRzfFb6BD/s/NU6rxYVB g8DOHhQKjc28xTBKAxAQWDeWGSZa388OeJO9q4zirYWNt3MNpU4GNM3f16aro21h 1WVMCeY9ZBvvQX0mq/ricE4hVpSP1iienvt2SnHMLhz3tzqw2CeaRw0kJ4wwtv6R poczKD9AVJtbdn1CEwFeqkKsH41vlxNbR3FnDBN7MtPHtgPg1GYOdQOVijcIO/0q DpzYnw+mZtSOcDaZMZ0gmxGHTohQ8ifQTkD00j0/KxHHudxDEkfQt7t/yTorlbU+ tZ4KazbGxwdyQkQCnocBUtFGPAqfge7ccnMhf5guv4ByyX273K4MHYfm5qGijYxj UycvUx0u5J7sqqVZJIa9dTdEYD4cQx1MNJdK/sQGinf7jmc41roI+rcD1OF3vpJ8 dCmotCHJ4siNW/kBcAuyY1pHu9ZF/398/D4ndm+TsmQKkuTXBZ8OMnnAv3V0SSsR ylCAwbujpWYCqVPJYX0E =P8kY -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-peter' into staging QOM infrastructure fixes and device conversions * Dynamic class properties * Property iterator cleanup * Device hot-unplug ID race fix # gpg: Signature made Mon 18 Jan 2016 17:27:01 GMT using RSA key ID 3E7E013F # gpg: Good signature from "Andreas Färber <afaerber@suse.de>" # gpg: aka "Andreas Färber <afaerber@suse.com>" * remotes/afaerber/tags/qom-devices-for-peter: MAINTAINERS: Fix sPAPR entry heading qdev: Free QemuOpts when the QOM path goes away qom: Change object property iterator API contract qom: Allow properties to be registered against classes Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
3db34bf64a
|
@ -587,7 +587,7 @@ F: hw/ppc/prep.c
|
||||||
F: hw/pci-host/prep.[hc]
|
F: hw/pci-host/prep.[hc]
|
||||||
F: hw/isa/pc87312.[hc]
|
F: hw/isa/pc87312.[hc]
|
||||||
|
|
||||||
sPAPR (pseries)
|
sPAPR
|
||||||
M: David Gibson <david@gibson.dropbear.id.au>
|
M: David Gibson <david@gibson.dropbear.id.au>
|
||||||
M: Alexander Graf <agraf@suse.de>
|
M: Alexander Graf <agraf@suse.de>
|
||||||
L: qemu-ppc@nongnu.org
|
L: qemu-ppc@nongnu.org
|
||||||
|
|
|
@ -1206,7 +1206,6 @@ static void device_finalize(Object *obj)
|
||||||
NamedGPIOList *ngl, *next;
|
NamedGPIOList *ngl, *next;
|
||||||
|
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
qemu_opts_del(dev->opts);
|
|
||||||
|
|
||||||
QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
|
QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
|
||||||
QLIST_REMOVE(ngl, node);
|
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);
|
qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
|
||||||
g_free(path);
|
g_free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemu_opts_del(dev->opts);
|
||||||
|
dev->opts = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_class_init(ObjectClass *class, void *data)
|
static void device_class_init(ObjectClass *class, void *data)
|
||||||
|
|
|
@ -684,7 +684,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
|
||||||
{
|
{
|
||||||
Object *root_container;
|
Object *root_container;
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
uint32_t drc_count = 0;
|
uint32_t drc_count = 0;
|
||||||
GArray *drc_indexes, *drc_power_domains;
|
GArray *drc_indexes, *drc_power_domains;
|
||||||
GString *drc_names, *drc_types;
|
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);
|
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
|
||||||
|
|
||||||
iter = object_property_iter_init(root_container);
|
object_property_iter_init(&iter, root_container);
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
Object *obj;
|
Object *obj;
|
||||||
sPAPRDRConnector *drc;
|
sPAPRDRConnector *drc;
|
||||||
sPAPRDRConnectorClass *drck;
|
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));
|
spapr_drc_get_type_str(drc->type));
|
||||||
drc_types = g_string_insert_len(drc_types, -1, "\0", 1);
|
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
|
/* now write the drc count into the space we reserved at the
|
||||||
* beginning of the arrays previously
|
* beginning of the arrays previously
|
||||||
|
|
|
@ -381,6 +381,8 @@ struct ObjectClass
|
||||||
const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
|
const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
|
||||||
|
|
||||||
ObjectUnparent *unparent;
|
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);
|
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:
|
* object_property_find:
|
||||||
* @obj: the object
|
* @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,
|
ObjectProperty *object_property_find(Object *obj, const char *name,
|
||||||
Error **errp);
|
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:
|
* object_property_iter_init:
|
||||||
* @obj: the object
|
* @obj: the object
|
||||||
*
|
*
|
||||||
* Initializes an iterator for traversing all properties
|
* 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,
|
* It is forbidden to modify the property list while iterating,
|
||||||
* whether removing or adding properties.
|
* whether removing or adding properties.
|
||||||
|
@ -973,32 +987,27 @@ typedef struct ObjectPropertyIterator ObjectPropertyIterator;
|
||||||
* <title>Using object property iterators</title>
|
* <title>Using object property iterators</title>
|
||||||
* <programlisting>
|
* <programlisting>
|
||||||
* ObjectProperty *prop;
|
* ObjectProperty *prop;
|
||||||
* ObjectPropertyIterator *iter;
|
* ObjectPropertyIterator iter;
|
||||||
*
|
*
|
||||||
* iter = object_property_iter_init(obj);
|
* object_property_iter_init(&iter, obj);
|
||||||
* while ((prop = object_property_iter_next(iter))) {
|
* while ((prop = object_property_iter_next(&iter))) {
|
||||||
* ... do something with prop ...
|
* ... do something with prop ...
|
||||||
* }
|
* }
|
||||||
* object_property_iter_free(iter);
|
|
||||||
* </programlisting>
|
* </programlisting>
|
||||||
* </example>
|
* </example>
|
||||||
*
|
|
||||||
* Returns: the new iterator
|
|
||||||
*/
|
*/
|
||||||
ObjectPropertyIterator *object_property_iter_init(Object *obj);
|
void object_property_iter_init(ObjectPropertyIterator *iter,
|
||||||
|
Object *obj);
|
||||||
/**
|
|
||||||
* object_property_iter_free:
|
|
||||||
* @iter: the iterator instance
|
|
||||||
*
|
|
||||||
* Releases any resources associated with the iterator.
|
|
||||||
*/
|
|
||||||
void object_property_iter_free(ObjectPropertyIterator *iter);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* object_property_iter_next:
|
* object_property_iter_next:
|
||||||
* @iter: the iterator instance
|
* @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
|
* Returns: the next property, or %NULL when all properties
|
||||||
* have been traversed.
|
* have been traversed.
|
||||||
*/
|
*/
|
||||||
|
@ -1371,6 +1380,12 @@ void object_property_add_str(Object *obj, const char *name,
|
||||||
void (*set)(Object *, const char *, Error **),
|
void (*set)(Object *, const char *, Error **),
|
||||||
Error **errp);
|
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:
|
* object_property_add_bool:
|
||||||
* @obj: the object to add a property to
|
* @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 **),
|
void (*set)(Object *, bool, Error **),
|
||||||
Error **errp);
|
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:
|
* object_property_add_enum:
|
||||||
* @obj: the object to add a property to
|
* @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 **),
|
void (*set)(Object *, int, Error **),
|
||||||
Error **errp);
|
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:
|
* object_property_add_tm:
|
||||||
* @obj: the object to add a property to
|
* @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 **),
|
void (*get)(Object *, struct tm *, Error **),
|
||||||
Error **errp);
|
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:
|
* object_property_add_uint8_ptr:
|
||||||
* @obj: the object to add a property to
|
* @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,
|
void object_property_add_uint8_ptr(Object *obj, const char *name,
|
||||||
const uint8_t *v, Error **errp);
|
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:
|
* 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,
|
void object_property_add_uint16_ptr(Object *obj, const char *name,
|
||||||
const uint16_t *v, Error **errp);
|
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:
|
* 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,
|
void object_property_add_uint32_ptr(Object *obj, const char *name,
|
||||||
const uint32_t *v, Error **errp);
|
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:
|
* 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,
|
void object_property_add_uint64_ptr(Object *obj, const char *name,
|
||||||
const uint64_t *v, Error **Errp);
|
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:
|
* 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,
|
void object_property_set_description(Object *obj, const char *name,
|
||||||
const char *description, Error **errp);
|
const char *description, Error **errp);
|
||||||
|
void object_class_property_set_description(ObjectClass *klass, const char *name,
|
||||||
|
const char *description,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* object_child_foreach:
|
* object_child_foreach:
|
||||||
|
|
|
@ -137,7 +137,7 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *str, *info;
|
char *str, *info;
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
StringOutputVisitor *ov;
|
StringOutputVisitor *ov;
|
||||||
|
|
||||||
if (!nf->netdev_id) {
|
if (!nf->netdev_id) {
|
||||||
|
@ -174,8 +174,8 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
|
||||||
QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
|
QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
|
||||||
|
|
||||||
/* generate info str */
|
/* generate info str */
|
||||||
iter = object_property_iter_init(OBJECT(nf));
|
object_property_iter_init(&iter, OBJECT(nf));
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
if (!strcmp(prop->name, "type")) {
|
if (!strcmp(prop->name, "type")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,6 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
|
||||||
g_free(str);
|
g_free(str);
|
||||||
g_free(info);
|
g_free(info);
|
||||||
}
|
}
|
||||||
object_property_iter_free(iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netfilter_finalize(Object *obj)
|
static void netfilter_finalize(Object *obj)
|
||||||
|
|
14
qmp.c
14
qmp.c
|
@ -210,7 +210,7 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
|
||||||
bool ambiguous = false;
|
bool ambiguous = false;
|
||||||
ObjectPropertyInfoList *props = NULL;
|
ObjectPropertyInfoList *props = NULL;
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
|
|
||||||
obj = object_resolve_path(path, &ambiguous);
|
obj = object_resolve_path(path, &ambiguous);
|
||||||
if (obj == NULL) {
|
if (obj == NULL) {
|
||||||
|
@ -223,8 +223,8 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter = object_property_iter_init(obj);
|
object_property_iter_init(&iter, obj);
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
|
ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
|
||||||
|
|
||||||
entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
|
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->name = g_strdup(prop->name);
|
||||||
entry->value->type = g_strdup(prop->type);
|
entry->value->type = g_strdup(prop->type);
|
||||||
}
|
}
|
||||||
object_property_iter_free(iter);
|
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
@ -506,7 +505,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
|
||||||
ObjectClass *klass;
|
ObjectClass *klass;
|
||||||
Object *obj;
|
Object *obj;
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
DevicePropertyInfoList *prop_list = NULL;
|
DevicePropertyInfoList *prop_list = NULL;
|
||||||
|
|
||||||
klass = object_class_by_name(typename);
|
klass = object_class_by_name(typename);
|
||||||
|
@ -535,8 +534,8 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
|
||||||
|
|
||||||
obj = object_new(typename);
|
obj = object_new(typename);
|
||||||
|
|
||||||
iter = object_property_iter_init(obj);
|
object_property_iter_init(&iter, obj);
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
DevicePropertyInfo *info;
|
DevicePropertyInfo *info;
|
||||||
DevicePropertyInfoList *entry;
|
DevicePropertyInfoList *entry;
|
||||||
|
|
||||||
|
@ -567,7 +566,6 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
|
||||||
entry->next = prop_list;
|
entry->next = prop_list;
|
||||||
prop_list = entry;
|
prop_list = entry;
|
||||||
}
|
}
|
||||||
object_property_iter_free(iter);
|
|
||||||
|
|
||||||
object_unref(obj);
|
object_unref(obj);
|
||||||
|
|
||||||
|
|
254
qom/object.c
254
qom/object.c
|
@ -67,10 +67,6 @@ struct TypeImpl
|
||||||
InterfaceImpl interfaces[MAX_INTERFACES];
|
InterfaceImpl interfaces[MAX_INTERFACES];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectPropertyIterator {
|
|
||||||
GHashTableIter iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
static Type type_interface;
|
static Type type_interface;
|
||||||
|
|
||||||
static GHashTable *type_table_get(void)
|
static GHashTable *type_table_get(void)
|
||||||
|
@ -246,6 +242,16 @@ static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
|
||||||
iface_impl->class);
|
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)
|
static void type_initialize(TypeImpl *ti)
|
||||||
{
|
{
|
||||||
TypeImpl *parent;
|
TypeImpl *parent;
|
||||||
|
@ -268,6 +274,8 @@ static void type_initialize(TypeImpl *ti)
|
||||||
g_assert_cmpint(parent->class_size, <=, ti->class_size);
|
g_assert_cmpint(parent->class_size, <=, ti->class_size);
|
||||||
memcpy(ti->class, parent->class, parent->class_size);
|
memcpy(ti->class, parent->class, parent->class_size);
|
||||||
ti->class->interfaces = NULL;
|
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) {
|
for (e = parent->class->interfaces; e; e = e->next) {
|
||||||
InterfaceClass *iface = e->data;
|
InterfaceClass *iface = e->data;
|
||||||
|
@ -292,6 +300,9 @@ static void type_initialize(TypeImpl *ti)
|
||||||
|
|
||||||
type_initialize_interface(ti, t, t);
|
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;
|
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)
|
void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
|
||||||
{
|
{
|
||||||
Object *obj = data;
|
Object *obj = data;
|
||||||
|
@ -918,10 +919,10 @@ object_property_add(Object *obj, const char *name, const char *type,
|
||||||
return ret;
|
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'"
|
error_setg(errp, "attempt to add duplicate property '%s'"
|
||||||
" to object (type '%s')", name,
|
" to object (type '%s')", name,
|
||||||
object_get_typename(obj));
|
object_get_typename(obj));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,10 +940,50 @@ object_property_add(Object *obj, const char *name, const char *type,
|
||||||
return prop;
|
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,
|
ObjectProperty *object_property_find(Object *obj, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
ObjectProperty *prop;
|
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);
|
prop = g_hash_table_lookup(obj->properties, name);
|
||||||
if (prop) {
|
if (prop) {
|
||||||
|
@ -953,30 +994,47 @@ ObjectProperty *object_property_find(Object *obj, const char *name,
|
||||||
return NULL;
|
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(&iter->iter, obj->properties);
|
||||||
g_hash_table_iter_init(&ret->iter, obj->properties);
|
iter->nextclass = object_get_class(obj);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void object_property_iter_free(ObjectPropertyIterator *iter)
|
|
||||||
{
|
|
||||||
if (!iter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_free(iter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
|
ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter)
|
||||||
{
|
{
|
||||||
gpointer key, val;
|
gpointer key, val;
|
||||||
if (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
|
while (!g_hash_table_iter_next(&iter->iter, &key, &val)) {
|
||||||
return NULL;
|
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;
|
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)
|
void object_property_del(Object *obj, const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
|
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
|
typedef struct BoolProperty
|
||||||
{
|
{
|
||||||
bool (*get)(Object *, Error **);
|
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,
|
static void property_get_enum(Object *obj, Visitor *v, void *opaque,
|
||||||
const char *name, Error **errp)
|
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 {
|
typedef struct TMProperty {
|
||||||
void (*get)(Object *, struct tm *, Error **);
|
void (*get)(Object *, struct tm *, Error **);
|
||||||
} TMProperty;
|
} 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)
|
static char *qdev_get_type(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
return g_strdup(object_get_typename(obj));
|
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);
|
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,
|
void object_property_add_uint16_ptr(Object *obj, const char *name,
|
||||||
const uint16_t *v, Error **errp)
|
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);
|
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,
|
void object_property_add_uint32_ptr(Object *obj, const char *name,
|
||||||
const uint32_t *v, Error **errp)
|
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);
|
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,
|
void object_property_add_uint64_ptr(Object *obj, const char *name,
|
||||||
const uint64_t *v, Error **errp)
|
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);
|
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 {
|
typedef struct {
|
||||||
Object *target_obj;
|
Object *target_obj;
|
||||||
char *target_name;
|
char *target_name;
|
||||||
|
@ -2101,6 +2276,23 @@ void object_property_set_description(Object *obj, const char *name,
|
||||||
op->description = g_strdup(description);
|
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)
|
static void object_instance_init(Object *obj)
|
||||||
{
|
{
|
||||||
object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
|
object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
|
||||||
|
|
|
@ -123,18 +123,28 @@ static void dummy_init(Object *obj)
|
||||||
dummy_get_bv,
|
dummy_get_bv,
|
||||||
dummy_set_bv,
|
dummy_set_bv,
|
||||||
NULL);
|
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)
|
static void dummy_finalize(Object *obj)
|
||||||
{
|
{
|
||||||
DummyObject *dobj = DUMMY_OBJECT(obj);
|
DummyObject *dobj = DUMMY_OBJECT(obj);
|
||||||
|
@ -150,6 +160,7 @@ static const TypeInfo dummy_info = {
|
||||||
.instance_init = dummy_init,
|
.instance_init = dummy_init,
|
||||||
.instance_finalize = dummy_finalize,
|
.instance_finalize = dummy_finalize,
|
||||||
.class_size = sizeof(DummyObjectClass),
|
.class_size = sizeof(DummyObjectClass),
|
||||||
|
.class_init = dummy_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -444,11 +455,11 @@ static void test_dummy_iterator(void)
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
bool seenbv = false, seensv = false, seenav = false, seentype;
|
bool seenbv = false, seensv = false, seenav = false, seentype;
|
||||||
|
|
||||||
iter = object_property_iter_init(OBJECT(dobj));
|
object_property_iter_init(&iter, OBJECT(dobj));
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
if (g_str_equal(prop->name, "bv")) {
|
if (g_str_equal(prop->name, "bv")) {
|
||||||
seenbv = true;
|
seenbv = true;
|
||||||
} else if (g_str_equal(prop->name, "sv")) {
|
} else if (g_str_equal(prop->name, "sv")) {
|
||||||
|
@ -463,7 +474,6 @@ static void test_dummy_iterator(void)
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object_property_iter_free(iter);
|
|
||||||
g_assert(seenbv);
|
g_assert(seenbv);
|
||||||
g_assert(seenav);
|
g_assert(seenav);
|
||||||
g_assert(seensv);
|
g_assert(seensv);
|
||||||
|
|
7
vl.c
7
vl.c
|
@ -1535,14 +1535,14 @@ MachineInfoList *qmp_query_machines(Error **errp)
|
||||||
static int machine_help_func(QemuOpts *opts, MachineState *machine)
|
static int machine_help_func(QemuOpts *opts, MachineState *machine)
|
||||||
{
|
{
|
||||||
ObjectProperty *prop;
|
ObjectProperty *prop;
|
||||||
ObjectPropertyIterator *iter;
|
ObjectPropertyIterator iter;
|
||||||
|
|
||||||
if (!qemu_opt_has_help_opt(opts)) {
|
if (!qemu_opt_has_help_opt(opts)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter = object_property_iter_init(OBJECT(machine));
|
object_property_iter_init(&iter, OBJECT(machine));
|
||||||
while ((prop = object_property_iter_next(iter))) {
|
while ((prop = object_property_iter_next(&iter))) {
|
||||||
if (!prop->set) {
|
if (!prop->set) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1555,7 +1555,6 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine)
|
||||||
error_printf("\n");
|
error_printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object_property_iter_free(iter);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue