The Object::realized property can only be set once and, on setting it, invokes the ObjectClass::realize callback.
Signed-off-by: Andreas Färber <afaer...@suse.de> Cc: Anthony Liguori <anth...@codemonkey.ws> Cc: Paolo Bonzini <pbonz...@redhat.com> --- include/qemu/object.h | 2 ++ qom/object.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/include/qemu/object.h b/include/qemu/object.h index e8fc126..742b5b6 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -239,6 +239,7 @@ struct ObjectClass { /*< private >*/ Type type; + int (*realize)(Object *obj); }; /** @@ -264,6 +265,7 @@ struct Object QTAILQ_HEAD(, ObjectProperty) properties; uint32_t ref; Object *parent; + bool realized; }; /** diff --git a/qom/object.c b/qom/object.c index 9cd9506..ec143ad 100644 --- a/qom/object.c +++ b/qom/object.c @@ -273,6 +273,34 @@ static void object_init_with_type(Object *obj, TypeImpl *ti) } } +static void object_get_realized(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + visit_type_bool(v, &obj->realized, name, errp); +} + +static void object_set_realized(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + bool value; + + if (obj->realized) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_bool(v, &value, name, errp); + if (error_is_set(errp) || !value) { + return; + } + + if (obj->class->realize != NULL && obj->class->realize(obj) != 0) { + error_set(errp, QERR_DEVICE_INIT_FAILED, object_get_typename(obj)); + return; + } + obj->realized = true; +} + void object_initialize_with_type(void *data, TypeImpl *type) { Object *obj = data; @@ -287,6 +315,9 @@ void object_initialize_with_type(void *data, TypeImpl *type) obj->class = type->class; QTAILQ_INIT(&obj->properties); object_init_with_type(obj, type); + object_property_add(obj, "realized", "boolean", + object_get_realized, object_set_realized, + NULL, NULL, NULL); } void object_initialize(void *data, const char *typename) -- 1.7.7