Am 19.03.2014 16:48, schrieb Stefan Hajnoczi: > Child alias properties allow a parent object to expose child object > properties. This makes it possible for a parent object to forward all > or a subset of a child's properties. > > Currently we achieve similar behavior by duplicating property > definitions and copying the fields around. It turns out virtio has > several double-frees since we didn't get the memory management right. > > Using child alias properties it will be much easier for a parent object > to set a child's properties without fragile memory management issues > since the actual field only exists once in the child object. > > Signed-off-by: Stefan Hajnoczi <stefa...@redhat.com> > --- > hw/core/qdev-properties.c | 28 ++++++++++++++++++++++++++++ > include/hw/qdev-properties.h | 28 ++++++++++++++++++++++++++++ > 2 files changed, 56 insertions(+) > > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c > index 77d0c66..e62a4fd 100644 > --- a/hw/core/qdev-properties.c > +++ b/hw/core/qdev-properties.c > @@ -1002,3 +1002,31 @@ PropertyInfo qdev_prop_size = { > .get = get_size, > .set = set_size, > }; > + > +/* --- alias that forwards to a child object's property --- */ > + > +static void get_child_alias(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + Object *child = OBJECT(qdev_get_prop_ptr(dev, prop)); > + > + object_property_get(child, v, name, errp); > +} > + > +static void set_child_alias(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + Object *child = OBJECT(qdev_get_prop_ptr(dev, prop)); > + > + object_property_set(child, v, name, errp); > +} > + > +PropertyInfo qdev_prop_child_alias = { > + .name = "ChildAlias",
Won't this turn into the QMP-exposed type of the property? That would be wrong then, requiring per-type alias property types. They could be macro-automated of course, if we need them. Paolo had cleaned up type names to match QAPI schema for 2.0, CC'ing. Regards, Andreas > + .get = get_child_alias, > + .set = set_child_alias, > +}; > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > index 3c000ee..5ab1cac 100644 > --- a/include/hw/qdev-properties.h > +++ b/include/hw/qdev-properties.h > @@ -13,6 +13,7 @@ extern PropertyInfo qdev_prop_uint32; > extern PropertyInfo qdev_prop_int32; > extern PropertyInfo qdev_prop_uint64; > extern PropertyInfo qdev_prop_size; > +extern PropertyInfo qdev_prop_child_alias; > extern PropertyInfo qdev_prop_string; > extern PropertyInfo qdev_prop_chr; > extern PropertyInfo qdev_prop_ptr; > @@ -61,6 +62,33 @@ extern PropertyInfo qdev_prop_arraylen; > .defval = (bool)_defval, \ > } > > +/** > + * DEFINE_PROP_CHILD_ALIAS: > + * @_name: property name > + * @_state: name of the device state structure type > + * @_field: name of field in @_state, must be Object subclass > + * > + * Define device properties that alias a child object's property. For > example, > + * use the following to forward the 'baz' property where Foo embeds a Bar > + * object: > + * > + * typedef struct { > + * Object parent_obj; > + * > + * Bar bar_obj; > + * } Foo; > + * > + * DEFINE_PROP_CHILD_ALIAS("baz", Foo, bar_obj) > + * > + * Any access to Foo's 'baz' property actually accesses bar_obj's 'baz' > + * property. > + */ > +#define DEFINE_PROP_CHILD_ALIAS(_name, _state, _field) { \ > + .name = (_name), \ > + .info = &(qdev_prop_child_alias), \ > + .offset = offsetof(_state, _field), \ > + } > + > #define PROP_ARRAY_LEN_PREFIX "len-" > > /** -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg