[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/4] qom: add set() argument to object_property_add_
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH 3/4] qom: add set() argument to object_property_add_link() |
Date: |
Tue, 4 Mar 2014 22:45:11 +0100 |
There are currently three types of object_property_add_link() callers:
1. The link property may be set at any time.
2. The link property of a DeviceState instance may only be set before
realize.
3. The link property may never be set, it is read-only.
Something similar can already be achieved with
object_property_add_str()'s set() argument. Follow its example and add
a set() argument to object_property_add_link().
Also provide default set() functions for case #1 and #2. Case #3 is
covered by passing a NULL function pointer.
Cc: "Andreas Färber" <address@hidden>
Cc: Peter Crosthwaite <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Cc: Alexander Graf <address@hidden>
Cc: Anthony Liguori <address@hidden>
Cc: "Michael S. Tsirkin" <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
hw/core/qdev-properties.c | 12 ++++++++++++
hw/core/qdev.c | 4 +++-
hw/dma/xilinx_axidma.c | 4 ++++
hw/net/xilinx_axienet.c | 4 ++++
hw/pcmcia/pxa2xx.c | 1 +
hw/s390x/s390-virtio-bus.c | 1 +
hw/s390x/virtio-ccw.c | 1 +
hw/virtio/virtio-pci.c | 1 +
hw/virtio/virtio-rng.c | 1 +
include/hw/qdev-properties.h | 11 +++++++++++
include/qom/object.h | 12 ++++++++++++
qom/object.c | 18 ++++++++++++++++++
ui/console.c | 1 +
13 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 77d0c66..2858f11 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -21,6 +21,18 @@ void qdev_prop_set_after_realize(DeviceState *dev, const
char *name,
}
}
+void qdev_prop_default_set_link(Object *obj, const char *name,
+ Object *val, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+
+ if (dev->realized) {
+ error_setg(errp, "Attempt to set link property '%s' on device '%s' "
+ "(type '%s') after it was realized",
+ name, dev->id, object_get_typename(obj));
+ }
+}
+
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
{
void *ptr = dev;
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 273c737..c40fd8b 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -98,6 +98,7 @@ static void bus_add_child(BusState *bus, DeviceState *child)
object_property_add_link(OBJECT(bus), name,
object_get_typename(OBJECT(child)),
(Object **)&kid->child,
+ NULL, /* read-only property */
false, /* return ownership on prop deletion */
NULL);
}
@@ -762,7 +763,7 @@ static void device_initfn(Object *obj)
} while (class != object_class_by_name(TYPE_DEVICE));
object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
- (Object **)&dev->parent_bus, false,
+ (Object **)&dev->parent_bus, NULL, false,
&error_abort);
}
@@ -884,6 +885,7 @@ static void qbus_initfn(Object *obj)
object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
TYPE_HOTPLUG_HANDLER,
(Object **)&bus->hotplug_handler,
+ object_property_default_set_link,
true, NULL);
}
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index cc5826d..a0da529 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -538,9 +538,11 @@ static void xilinx_axidma_realize(DeviceState *dev, Error
**errp)
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&ds->dma,
+ object_property_default_set_link,
true, &local_errp);
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
(Object **)&cs->dma,
+ object_property_default_set_link,
true, &local_errp);
if (local_errp) {
goto xilinx_axidma_realize_fail;
@@ -574,10 +576,12 @@ static void xilinx_axidma_init(Object *obj)
object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
(Object **)&s->tx_data_dev,
+ qdev_prop_default_set_link,
true, &error_abort);
object_property_add_link(obj, "axistream-control-connected",
TYPE_STREAM_SLAVE,
(Object **)&s->tx_control_dev,
+ qdev_prop_default_set_link,
true, &error_abort);
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 385e059..4e139b7 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -946,9 +946,11 @@ static void xilinx_enet_realize(DeviceState *dev, Error
**errp)
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
(Object **) &ds->enet,
+ object_property_default_set_link,
true, &local_errp);
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
(Object **) &cs->enet,
+ object_property_default_set_link,
true, &local_errp);
if (local_errp) {
goto xilinx_enet_realize_fail;
@@ -985,10 +987,12 @@ static void xilinx_enet_init(Object *obj)
object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
(Object **) &s->tx_data_dev,
+ qdev_prop_default_set_link,
true, &error_abort);
object_property_add_link(obj, "axistream-control-connected",
TYPE_STREAM_SLAVE,
(Object **) &s->tx_control_dev,
+ qdev_prop_default_set_link,
true, &error_abort);
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
index f55a806..ee113e1 100644
--- a/hw/pcmcia/pxa2xx.c
+++ b/hw/pcmcia/pxa2xx.c
@@ -199,6 +199,7 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,
(Object **)&s->card,
+ NULL, /* read-only property */
false, /* don't unref on prop deletion */
NULL);
}
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 0c9ff92..027558b 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -314,6 +314,7 @@ static void s390_virtio_rng_instance_init(Object *obj)
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
+ qdev_prop_default_set_link,
true, NULL);
}
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 2fe782b..53fa86e 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1185,6 +1185,7 @@ static void virtio_ccw_rng_instance_init(Object *obj)
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
+ qdev_prop_default_set_link,
true, NULL);
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e91de26..2b3c93f 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1518,6 +1518,7 @@ static void virtio_rng_initfn(Object *obj)
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&dev->vdev.conf.rng,
+ qdev_prop_default_set_link,
true, NULL);
}
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 54ae848..8efe0aa 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -224,6 +224,7 @@ static void virtio_rng_initfn(Object *obj)
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
(Object **)&vrng->conf.rng,
+ qdev_prop_default_set_link,
true, NULL);
}
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 0c0babf..da35cb3 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -201,4 +201,15 @@ void qdev_property_add_static(DeviceState *dev, Property
*prop, Error **errp);
*/
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp);
+
+/**
+ * @qdev_prop_default_set_link:
+ *
+ * Set the Error object if an attempt is made to set the link after realize.
+ * This function should be used as the set() argument to
+ * object_property_add_link().
+ */
+void qdev_prop_default_set_link(Object *obj, const char *name,
+ Object *val, Error **errp);
+
#endif
diff --git a/include/qom/object.h b/include/qom/object.h
index 276d02e..fc25888 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1060,11 +1060,21 @@ void object_property_add_child(Object *obj, const char
*name,
Object *child, Error **errp);
/**
+ * object_property_default_set_link:
+ *
+ * The default implementation of the object_property_add_link() set callback
+ * function. It allows the link property to be set and never returns an error.
+ */
+void object_property_default_set_link(Object *, const char *,
+ Object *, Error **);
+
+/**
* object_property_add_link:
* @obj: the object to add a property to
* @name: the name of the property
* @type: the qobj type of the link
* @child: a pointer to where the link object reference is stored
+ * @set: the setter or NULL if the property is read-only
* @unref_on_release: whether to release the link object reference when
* the property is deleted
* @errp: if an error occurs, a pointer to an area to store the area
@@ -1084,6 +1094,8 @@ void object_property_add_child(Object *obj, const char
*name,
*/
void object_property_add_link(Object *obj, const char *name,
const char *type, Object **child,
+ void (*set)(Object *obj, const char *name,
+ Object *val, Error **errp),
bool unref_on_release,
Error **errp);
diff --git a/qom/object.c b/qom/object.c
index 89c5358..c430286 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1023,9 +1023,16 @@ out:
g_free(type);
}
+void object_property_default_set_link(Object *obj, const char *name,
+ Object *val, Error **errp)
+{
+ /* Allow the link to be set, always */
+}
+
typedef struct {
Object **child;
bool unref_on_release;
+ void (*set)(Object *, const char *, Object *, Error **);
} LinkProperty;
static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
@@ -1100,6 +1107,14 @@ static void object_set_link_property(Object *obj,
Visitor *v, void *opaque,
return;
}
+ if (prop->set) {
+ prop->set(obj, name, new_target, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
if (new_target) {
object_ref(new_target);
}
@@ -1122,6 +1137,8 @@ static void object_release_link_property(Object *obj,
const char *name,
void object_property_add_link(Object *obj, const char *name,
const char *type, Object **child,
+ void (*set)(Object *, const char *,
+ Object *, Error **),
bool unref_on_release,
Error **errp)
{
@@ -1130,6 +1147,7 @@ void object_property_add_link(Object *obj, const char
*name,
gchar *full_type;
prop->child = child;
+ prop->set = set;
prop->unref_on_release = unref_on_release;
full_type = g_strdup_printf("link<%s>", type);
diff --git a/ui/console.c b/ui/console.c
index af2d617..6220654 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1179,6 +1179,7 @@ static QemuConsole *new_console(DisplayState *ds,
console_type_t console_type)
s = QEMU_CONSOLE(obj);
object_property_add_link(obj, "device", TYPE_DEVICE,
(Object **)&s->device,
+ object_property_default_set_link,
true, &local_err);
if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE)
&&
--
1.8.5.3