From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43315) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WQIk7-0000ST-33 for qemu-devel@nongnu.org; Wed, 19 Mar 2014 11:49:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WQIk0-0001Ov-KN for qemu-devel@nongnu.org; Wed, 19 Mar 2014 11:49:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:19432) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WQIk0-0001Or-CP for qemu-devel@nongnu.org; Wed, 19 Mar 2014 11:49:16 -0400 From: Stefan Hajnoczi Date: Wed, 19 Mar 2014 16:48:54 +0100 Message-Id: <1395244138-8834-2-git-send-email-stefanha@redhat.com> In-Reply-To: <1395244138-8834-1-git-send-email-stefanha@redhat.com> References: <1395244138-8834-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [RFC 1/5] qdev: add child alias properties List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Andreas Faerber , Stefan Hajnoczi , fred.konrad@greensocs.com 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 --- 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", + .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-" /** -- 1.8.5.3