qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]