All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2)
@ 2011-12-02 20:20 Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 01/18] qom: add a reference count to qdev objects Anthony Liguori
                   ` (17 more replies)
  0 siblings, 18 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

This is a follow up to my previous series to get us started in the QOM
direction.  A few things are different this time around.  Most notably:

 1) Devices no longer have names.  Instead, path names are always used to
    identify devices.

 2) In order to support (1), dynamic properties are now supported.

 3) The concept of a "root device" has been introduced.  The root device is
    roughly modelling the motherboard of a machine.  This type is a container
    type and it's best to think of it as something like a PCB board I guess.

To try it out, here's an example session:

Launch:

anthony@titi:~/build/qemu$ x86_64-softmmu/qemu-system-x86_64 -hda ~/images/linux.img -snapshot -device virtio-balloon-pci,id=foo -qmp unix:/tmp/server.sock,server,nowait

Explore the object model:

anthony@titi:~/git/qemu/QMP$ ./qom-list /
peripheral/
i440fx/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/
piix3/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/piix3
rtc/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/piix3/rtc
date
base_year
anthony@titi:~/git/qemu/QMP$ ./qom-get /i440fx/piix3/rtc.date
tm_sec: 33
tm_hour: 21
tm_mday: 30
tm_year: 111
tm_mon: 10
tm_min: 2
anthony@titi:~/git/qemu/QMP$ ./qom-get rtc.date
tm_sec: 38
tm_hour: 21
tm_mday: 30
tm_year: 111
tm_mon: 10
tm_min: 2
anthony@titi:~/git/qemu/QMP$ ./qom-list /peripheral
foo/
anthony@titi:~/git/qemu/QMP$ ./qom-list /peripheral/foo
event_idx
indirect_desc

Anthony Liguori (18):
  qom: add a reference count to qdev objects
  qom: add new dynamic property infrastructure based on Visitors (v2)
  qom: register legacy properties as new style properties (v2)
  qom: introduce root device
  qdev: provide an interface to return canonical path from root (v2)
  qdev: provide a path resolution (v2)
  qom: add child properties (composition) (v2)
  qom: add link properties (v2)
  qapi: allow a 'gen' key to suppress code generation
  qmp: add qom-list command
  qom: qom_{get,set} monitor commands (v2)
  qdev: add explicitly named devices to the root complex
  dev: add an anonymous peripheral container
  rtc: make piix3 set the rtc as a child (v2)
  rtc: add a dynamic property for retrieving the date
  qom: optimize qdev_get_canonical_path using a parent link
  qmp: make qmp.py easier to use
  qom: add test tools (v2)

 Makefile.objs            |    2 +-
 QMP/qmp.py               |    6 +
 QMP/qom-get              |   26 +++
 QMP/qom-list             |   30 +++
 QMP/qom-set              |   21 ++
 hw/container.c           |   20 ++
 hw/mc146818rtc.c         |   27 +++
 hw/pc_piix.c             |   11 +
 hw/piix_pci.c            |    3 +
 hw/qdev.c                |  489 +++++++++++++++++++++++++++++++++++++++++++++-
 hw/qdev.h                |  245 +++++++++++++++++++++++
 monitor.h                |    4 +
 qapi-schema.json         |  107 ++++++++++
 qerror.c                 |    4 +
 qerror.h                 |    3 +
 qmp-commands.hx          |   18 ++
 qmp.c                    |   93 +++++++++
 scripts/qapi-commands.py |    1 +
 scripts/qapi-types.py    |    1 +
 19 files changed, 1109 insertions(+), 2 deletions(-)
 create mode 100755 QMP/qom-get
 create mode 100755 QMP/qom-list
 create mode 100755 QMP/qom-set
 create mode 100644 hw/container.c

-- 
1.7.4.1

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 01/18] qom: add a reference count to qdev objects
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 02/18] qom: add new dynamic property infrastructure based on Visitors (v2) Anthony Liguori
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

To ensure that a device isn't removed from the graph until all of its links are
broken.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |   16 ++++++++++++++++
 hw/qdev.h |   26 ++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 106407f..fdc9843 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -323,6 +323,11 @@ int qdev_unplug(DeviceState *dev)
     }
     assert(dev->info->unplug != NULL);
 
+    if (dev->ref != 0) {
+        qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
+        return -1;
+    }
+
     qdev_hot_removed = true;
 
     return dev->info->unplug(dev);
@@ -962,3 +967,14 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 
     return strdup(path);
 }
+
+void qdev_ref(DeviceState *dev)
+{
+    dev->ref++;
+}
+
+void qdev_unref(DeviceState *dev)
+{
+    g_assert(dev->ref > 0);
+    dev->ref--;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 36a4198..2397b4e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -45,6 +45,12 @@ struct DeviceState {
     QTAILQ_ENTRY(DeviceState) sibling;
     int instance_id_alias;
     int alias_required_for_version;
+
+    /**
+     * This tracks the number of references between devices.  See @qdev_ref for
+     * more information.
+     */
+    uint32_t ref;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
@@ -329,4 +335,24 @@ char *qdev_get_fw_dev_path(DeviceState *dev);
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 extern struct BusInfo system_bus_info;
 
+/**
+ * @qdev_ref
+ *
+ * Increase the reference count of a device.  A device cannot be freed as long
+ * as its reference count is greater than zero.
+ *
+ * @dev - the device
+ */
+void qdev_ref(DeviceState *dev);
+
+/**
+ * @qdef_unref
+ *
+ * Decrease the reference count of a device.  A device cannot be freed as long
+ * as its reference count is greater than zero.
+ *
+ * @dev - the device
+ */
+void qdev_unref(DeviceState *dev);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 02/18] qom: add new dynamic property infrastructure based on Visitors (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 01/18] qom: add a reference count to qdev objects Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 03/18] qom: register legacy properties as new style properties (v2) Anthony Liguori
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

qdev properties are settable only during construction and static to classes.
This isn't flexible enough for QOM.

This patch introduces a property interface for qdev that provides dynamic
properties that are tied to objects, instead of classes.  These properties are
Visitor based instead of string based too.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - Etter -> Accessor (Stefan)
 - spelling mistakes (Stefan)
 - switch to qemu-queue (Kevin/Gerd)
---
 hw/qdev.c |   97 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |  120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qerror.c  |    4 ++
 qerror.h  |    3 ++
 4 files changed, 224 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index fdc9843..94f14c1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -98,6 +98,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
         qdev_hot_added = true;
     }
     dev->instance_id_alias = -1;
+    QTAILQ_INIT(&dev->properties);
     dev->state = DEV_STATE_CREATED;
     return dev;
 }
@@ -395,12 +396,31 @@ void qdev_init_nofail(DeviceState *dev)
     }
 }
 
+static void qdev_property_del_all(DeviceState *dev)
+{
+    while (!QTAILQ_EMPTY(&dev->properties)) {
+        DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
+
+        QTAILQ_REMOVE(&dev->properties, prop, node);
+
+        if (prop->release) {
+            prop->release(dev, prop->name, prop->opaque);
+        }
+
+        g_free(prop->name);
+        g_free(prop->type);
+        g_free(prop);
+    }
+}
+
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
     BusState *bus;
     Property *prop;
 
+    qdev_property_del_all(dev);
+
     if (dev->state == DEV_STATE_INITIALIZED) {
         while (dev->num_child_bus) {
             bus = QLIST_FIRST(&dev->child_bus);
@@ -978,3 +998,80 @@ void qdev_unref(DeviceState *dev)
     g_assert(dev->ref > 0);
     dev->ref--;
 }
+
+void qdev_property_add(DeviceState *dev, const char *name, const char *type,
+                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
+                       DevicePropertyRelease *release,
+                       void *opaque, Error **errp)
+{
+    DeviceProperty *prop = g_malloc0(sizeof(*prop));
+
+    prop->name = g_strdup(name);
+    prop->type = g_strdup(type);
+
+    prop->get = get;
+    prop->set = set;
+    prop->release = release;
+    prop->opaque = opaque;
+
+    QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
+}
+
+static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
+{
+    DeviceProperty *prop;
+
+    QTAILQ_FOREACH(prop, &dev->properties, node) {
+        if (strcmp(prop->name, name) == 0) {
+            return prop;
+        }
+    }
+
+    return NULL;
+}
+
+void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
+                       Error **errp)
+{
+    DeviceProperty *prop = qdev_property_find(dev, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+        return;
+    }
+
+    if (!prop->get) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->get(dev, v, prop->opaque, name, errp);
+    }
+}
+
+void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
+                       Error **errp)
+{
+    DeviceProperty *prop = qdev_property_find(dev, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+        return;
+    }
+
+    if (!prop->set) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->set(dev, prop->opaque, v, name, errp);
+    }
+}
+
+const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
+{
+    DeviceProperty *prop = qdev_property_find(dev, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+        return NULL;
+    }
+
+    return prop->type;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 2397b4e..2df3bb7 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -5,6 +5,7 @@
 #include "qemu-queue.h"
 #include "qemu-char.h"
 #include "qemu-option.h"
+#include "qapi/qapi-visit-core.h"
 
 typedef struct Property Property;
 
@@ -27,6 +28,44 @@ enum {
     DEV_NVECTORS_UNSPECIFIED = -1,
 };
 
+/**
+ * @DevicePropertyAccessor - called when trying to get/set a property
+ *
+ * @dev the device that owns the property
+ * @v the visitor that contains the property data
+ * @opaque the device property opaque
+ * @name the name of the property
+ * @errp a pointer to an Error that is filled if getting/setting fails.
+ */
+typedef void (DevicePropertyAccessor)(DeviceState *dev,
+                                      Visitor *v,
+                                      void *opaque,
+                                      const char *name,
+                                      Error **errp);
+
+/**
+ * @DevicePropertyRelease - called when a property is removed from a device
+ *
+ * @dev the device that owns the property
+ * @name the name of the property
+ * @opaque the opaque registered with the property
+ */
+typedef void (DevicePropertyRelease)(DeviceState *dev,
+                                     const char *name,
+                                     void *opaque);
+
+typedef struct DeviceProperty
+{
+    gchar *name;
+    gchar *type;
+    DevicePropertyAccessor *get;
+    DevicePropertyAccessor *set;
+    DevicePropertyRelease *release;
+    void *opaque;
+
+    QTAILQ_ENTRY(DeviceProperty) node;
+} DeviceProperty;
+
 /* This structure should not be accessed directly.  We declare it here
    so that it can be embedded in individual device state structures.  */
 struct DeviceState {
@@ -51,6 +90,8 @@ struct DeviceState {
      * more information.
      */
     uint32_t ref;
+
+    QTAILQ_HEAD(, DeviceProperty) properties;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
@@ -355,4 +396,83 @@ void qdev_ref(DeviceState *dev);
  */
 void qdev_unref(DeviceState *dev);
 
+/**
+ * @qdev_property_add - add a new property to a device
+ *
+ * @dev - the device to add a property to
+ *
+ * @name - the name of the property.  This can contain any character except for
+ *         a forward slash.  In general, you should use hyphens '-' instead of
+ *         underscores '_' when naming properties.
+ *
+ * @type - the type name of the property.  This namespace is pretty loosely
+ *         defined.  Sub namespaces are constructed by using a prefix and then
+ *         to angle brackets.  For instance, the type 'virtio-net-pci' in the
+ *         'link' namespace would be 'link<virtio-net-pci>'.
+ *
+ * @get - the getter to be called to read a property.  If this is NULL, then
+ *        the property cannot be read.
+ *
+ * @set - the setter to be called to write a property.  If this is NULL,
+ *        then the property cannot be written.
+ *
+ * @release - called when the property is removed from the device.  This is
+ *            meant to allow a property to free its opaque upon device
+ *            destruction.  This may be NULL.
+ *
+ * @opaque - an opaque pointer to pass to the callbacks for the property
+ *
+ * @errp - returns an error if this function fails
+ */
+void qdev_property_add(DeviceState *dev, const char *name, const char *type,
+                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
+                       DevicePropertyRelease *release,
+                       void *opaque, Error **errp);
+
+/**
+ * @qdev_property_get - reads a property from a device
+ *
+ * @dev - the device
+ *
+ * @v - the visitor that will receive the property value.  This should be an
+ *      Output visitor and the data will be written with @name as the name.
+ *
+ * @name - the name of the property
+ *
+ * @errp - returns an error if this function fails
+ */
+void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
+                       Error **errp);
+
+/**
+ * @qdev_property_set - writes a property to a device
+ *
+ * @dev - the device
+ *
+ * @v - the visitor that will be used to write the property value.  This should
+ *      be an Input visitor and the data will be first read with @name as the
+ *      name and then written as the property value.
+ *
+ * @name - the name of the property
+ *
+ * @errp - returns an error if this function fails
+ */
+void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
+                       Error **errp);
+
+/**
+ * @qdev_property_get_type - returns the type of a property
+ *
+ * @dev - the device
+ *
+ * @name - the name of the property
+ *
+ * @errp - returns an error if this function fails
+ *
+ * Returns:
+ *   The type name of the property.
+ */
+const char *qdev_property_get_type(DeviceState *dev, const char *name,
+                                   Error **errp);
+
 #endif
diff --git a/qerror.c b/qerror.c
index fdf62b9..dd0ee76 100644
--- a/qerror.c
+++ b/qerror.c
@@ -178,6 +178,10 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "Could not open '%(filename)'",
     },
     {
+        .error_fmt = QERR_PERMISSION_DENIED,
+        .desc      = "Insufficient permission to perform this operation",
+    },
+    {
         .error_fmt = QERR_PROPERTY_NOT_FOUND,
         .desc      = "Property '%(device).%(property)' not found",
     },
diff --git a/qerror.h b/qerror.h
index 2d3d43b..2b1d743 100644
--- a/qerror.h
+++ b/qerror.h
@@ -150,6 +150,9 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_OPEN_FILE_FAILED \
     "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
 
+#define QERR_PERMISSION_DENIED \
+    "{ 'class': 'PermissionDenied', 'data': {} }"
+
 #define QERR_PROPERTY_NOT_FOUND \
     "{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 03/18] qom: register legacy properties as new style properties (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 01/18] qom: add a reference count to qdev objects Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 02/18] qom: add new dynamic property infrastructure based on Visitors (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 04/18] qom: introduce root device Anthony Liguori
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Expose all legacy properties through the new QOM property mechanism.  The qdev
property types are exposed through the 'legacy<>' namespace.  They are always
visited as strings since they do their own string parsing.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - add bus properties (Gerd)
---
 hw/qdev.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |    7 +++++
 2 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 94f14c1..6f77af9 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -83,6 +83,7 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
 {
     DeviceState *dev;
+    Property *prop;
 
     assert(bus->info == info->bus_info);
     dev = g_malloc0(info->size);
@@ -100,6 +101,15 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     dev->instance_id_alias = -1;
     QTAILQ_INIT(&dev->properties);
     dev->state = DEV_STATE_CREATED;
+
+    for (prop = dev->info->props; prop && prop->name; prop++) {
+        qdev_property_add_legacy(dev, prop, NULL);
+    }
+
+    for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
+        qdev_property_add_legacy(dev, prop, NULL);
+    }
+
     return dev;
 }
 
@@ -1075,3 +1085,79 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **e
 
     return prop->type;
 }
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Property *prop = opaque;
+
+    if (prop->info->print) {
+        char buffer[1024];
+        char *ptr = buffer;
+
+        prop->info->print(dev, prop, buffer, sizeof(buffer));
+        visit_type_str(v, &ptr, name, errp);
+    } else {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    }
+}
+
+static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Property *prop = opaque;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    if (prop->info->parse) {
+        Error *local_err = NULL;
+        char *ptr = NULL;
+
+        visit_type_str(v, &ptr, name, &local_err);
+        if (!local_err) {
+            int ret;
+            ret = prop->info->parse(dev, prop, ptr);
+            if (ret != 0) {
+                error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+                          name, prop->info->name);
+            }
+            g_free(ptr);
+        } else {
+            error_propagate(errp, local_err);
+        }
+    } else {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    }
+}
+
+/**
+ * @qdev_add_legacy_property - adds a legacy property
+ *
+ * Do not use this is new code!  Properties added through this interface will
+ * be given types in the "legacy<>" type namespace.
+ *
+ * Legacy properties are always processed as strings.  The format of the string
+ * depends on the property type.
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    gchar *type;
+
+    type = g_strdup_printf("legacy<%s>", prop->info->name);
+
+    qdev_property_add(dev, prop->name, type,
+                      qdev_get_legacy_property,
+                      qdev_set_legacy_property,
+                      NULL,
+                      prop, errp);
+
+    g_free(type);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 2df3bb7..3b629d4 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -475,4 +475,11 @@ void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
 const char *qdev_property_get_type(DeviceState *dev, const char *name,
                                    Error **errp);
 
+/**
+ * @qdev_property_add_legacy - add a legacy @Property to a device
+ *
+ * DO NOT USE THIS IN NEW CODE!
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 04/18] qom: introduce root device
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (2 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 03/18] qom: register legacy properties as new style properties (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 05/18] qdev: provide an interface to return canonical path from root (v2) Anthony Liguori
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

This is based on Jan's suggestion for how to do unique naming.  The root device
is the root of composition.  All devices are reachable via child<> links from
this device.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs  |    2 +-
 hw/container.c |   20 ++++++++++++++++++++
 hw/qdev.c      |   12 ++++++++++++
 hw/qdev.h      |    8 ++++++++
 4 files changed, 41 insertions(+), 1 deletions(-)
 create mode 100644 hw/container.c

diff --git a/Makefile.objs b/Makefile.objs
index d7a6539..10e794c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -279,7 +279,7 @@ hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
 hw-obj-$(CONFIG_ESP) += esp.o
 
 hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
-hw-obj-y += qdev-addr.o
+hw-obj-y += qdev-addr.o container.o
 
 # VGA
 hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
diff --git a/hw/container.c b/hw/container.c
new file mode 100644
index 0000000..9cbf399
--- /dev/null
+++ b/hw/container.c
@@ -0,0 +1,20 @@
+#include "sysbus.h"
+
+static int container_initfn(SysBusDevice *dev)
+{
+    return 0;
+}
+
+static SysBusDeviceInfo container_info = {
+    .init = container_initfn,
+    .qdev.name = "container",
+    .qdev.size = sizeof(SysBusDevice),
+    .qdev.no_user = 1,
+};
+
+static void container_init(void)
+{
+    sysbus_register_withprop(&container_info);
+}
+
+device_init(container_init);
diff --git a/hw/qdev.c b/hw/qdev.c
index 6f77af9..bb0b9f7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1161,3 +1161,15 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 
     g_free(type);
 }
+
+DeviceState *qdev_get_root(void)
+{
+    static DeviceState *qdev_root;
+
+    if (!qdev_root) {
+        qdev_root = qdev_create(NULL, "container");
+        qdev_init_nofail(qdev_root);
+    }
+
+    return qdev_root;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 3b629d4..52aadd2 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -482,4 +482,12 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name,
  */
 void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
 
+/**
+ * @qdev_get_root - returns the root device of the composition tree
+ *
+ * Returns:
+ *   The root of the composition tree.
+ */
+DeviceState *qdev_get_root(void);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 05/18] qdev: provide an interface to return canonical path from root (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (3 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 04/18] qom: introduce root device Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 06/18] qdev: provide a path resolution (v2) Anthony Liguori
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

The canonical path is the path in the composition tree from the root to the
device.  This is effectively the name of the device.

This is an incredibly unefficient implementation that will be optimized in
a future patch.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - change from gslist to qemu-queue (Kevin/Gerd)
---
 hw/qdev.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |    9 +++++++++
 2 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index bb0b9f7..79849c9 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1173,3 +1173,51 @@ DeviceState *qdev_get_root(void)
 
     return qdev_root;
 }
+
+static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
+{
+    DeviceProperty *prop;
+
+    if (parent == dev) {
+        return g_strdup("");
+    }
+
+    QTAILQ_FOREACH(prop, &parent->properties, node) {
+        gchar *subpath;
+
+        if (!strstart(prop->type, "child<", NULL)) {
+            continue;
+        }
+
+        /* Check to see if the device is one of parent's children */
+        if (prop->opaque == dev) {
+            return g_strdup(prop->name);
+        }
+
+        /* Check to see if the device is a child of our child */
+        subpath = qdev_get_path_in(prop->opaque, dev);
+        if (subpath) {
+            gchar *path;
+
+            path = g_strdup_printf("%s/%s", prop->name, subpath);
+            g_free(subpath);
+
+            return path;
+        }
+    }
+
+    return NULL;
+}
+
+gchar *qdev_get_canonical_path(DeviceState *dev)
+{
+    gchar *path, *newpath;
+
+    path = qdev_get_path_in(qdev_get_root(), dev);
+    g_assert(path != NULL);
+
+    newpath = g_strdup_printf("/%s", path);
+    g_free(path);
+
+    return newpath;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 52aadd2..0f00497 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -490,4 +490,13 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
  */
 DeviceState *qdev_get_root(void);
 
+/**
+ * @qdev_get_canonical_path - returns the canonical path for a device.  This
+ * is the path within the composition tree starting from the root.
+ *
+ * Returns:
+ *   The canonical path in the composition tree.
+ */
+gchar *qdev_get_canonical_path(DeviceState *dev);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 06/18] qdev: provide a path resolution (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (4 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 05/18] qdev: provide an interface to return canonical path from root (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2) Anthony Liguori
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

There are two types of supported paths--absolute paths and partial paths.

Absolute paths are derived from the root device and can follow child<> or
link<> properties.  Since they can follow link<> properties, they can be
arbitrarily long.  Absolute paths look like absolute filenames and are prefixed
with a leading slash.

Partial paths are look like relative filenames.  They do not begin with a
prefix.  The matching rules for partial paths are subtle but designed to make
specifying devices easy.  At each level of the composition tree, the partial
path is matched as an absolute path.  The first match is not returned.  At
least two matches are searched for.  A successful result is only returned if
only one match is founded.  If more than one match is found, a flag is returned
to indicate that the match was ambiguous.

At the end of the day, partial path support means that if you create a device
called 'ide0', you can just say 'ide0' as the path name and it will Just Work.
If we internally create a device called 'i440fx', you can just say 'i440fx' and
it will Just Work and long as you don't do anything silly.

A management tool should probably always use absolute paths since then they
don't have to deal with the possibility of ambiguity.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - fix comments (Stefan)
 - always initialize ambiguous to false (Stefan)
 - change from gslist to qemu-queue (Kevin/Gerd)
---
 hw/qdev.c |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |   28 ++++++++++++++++
 2 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 79849c9..2519f00 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1221,3 +1221,106 @@ gchar *qdev_get_canonical_path(DeviceState *dev)
 
     return newpath;
 }
+
+static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
+                                          gchar **parts,
+                                          int index)
+{
+    DeviceProperty *prop;
+    DeviceState *child;
+
+    if (parts[index] == NULL) {
+        return parent;
+    }
+
+    if (strcmp(parts[index], "") == 0) {
+        return qdev_resolve_abs_path(parent, parts, index + 1);
+    }
+
+    prop = qdev_property_find(parent, parts[index]);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    child = NULL;
+    if (strstart(prop->type, "link<", NULL)) {
+        DeviceState **pchild = prop->opaque;
+        if (*pchild) {
+            child = *pchild;
+        }
+    } else if (strstart(prop->type, "child<", NULL)) {
+        child = prop->opaque;
+    }
+
+    if (!child) {
+        return NULL;
+    }
+
+    return qdev_resolve_abs_path(child, parts, index + 1);
+}
+
+static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
+                                              gchar **parts,
+                                              bool *ambiguous)
+{
+    DeviceState *dev;
+    DeviceProperty *prop;
+
+    dev = qdev_resolve_abs_path(parent, parts, 0);
+
+    QTAILQ_FOREACH(prop, &parent->properties, node) {
+        DeviceState *found;
+
+        if (!strstart(prop->type, "child<", NULL)) {
+            continue;
+        }
+
+        found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
+        if (found) {
+            if (dev) {
+                if (ambiguous) {
+                    *ambiguous = true;
+                }
+                return NULL;
+            }
+            dev = found;
+        }
+
+        if (ambiguous && *ambiguous) {
+            return NULL;
+        }
+    }
+
+    return dev;
+}
+
+DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
+{
+    bool partial_path = true;
+    DeviceState *dev;
+    gchar **parts;
+
+    parts = g_strsplit(path, "/", 0);
+    if (parts == NULL || parts[0] == NULL) {
+        g_strfreev(parts);
+        return qdev_get_root();
+    }
+
+    if (strcmp(parts[0], "") == 0) {
+        partial_path = false;
+    }
+
+    if (partial_path) {
+        if (ambiguous) {
+            *ambiguous = false;
+        }
+        dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
+    } else {
+        dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
+    }
+
+    g_strfreev(parts);
+
+    return dev;
+}
+
diff --git a/hw/qdev.h b/hw/qdev.h
index 0f00497..641d134 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -499,4 +499,32 @@ DeviceState *qdev_get_root(void);
  */
 gchar *qdev_get_canonical_path(DeviceState *dev);
 
+/**
+ * @qdev_resolve_path - resolves a path returning a device
+ *
+ * There are two types of supported paths--absolute paths and partial paths.
+ * 
+ * Absolute paths are derived from the root device and can follow child<> or
+ * link<> properties.  Since they can follow link<> properties, they can be
+ * arbitrarily long.  Absolute paths look like absolute filenames and are
+ * prefixed with a leading slash.
+ * 
+ * Partial paths look like relative filenames.  They do not begin with a
+ * prefix.  The matching rules for partial paths are subtle but designed to make
+ * specifying devices easy.  At each level of the composition tree, the partial
+ * path is matched as an absolute path.  The first match is not returned.  At
+ * least two matches are searched for.  A successful result is only returned if
+ * only one match is founded.  If more than one match is found, a flag is
+ * return to indicate that the match was ambiguous.
+ *
+ * @path - the path to resolve
+ *
+ * @ambiguous - returns true if the path resolution failed because of an
+ *              ambiguous match
+ *
+ * Returns:
+ *   The matched device or NULL on path lookup failure.
+ */
+DeviceState *qdev_resolve_path(const char *path, bool *ambiguous);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (5 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 06/18] qdev: provide a path resolution (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-08 15:38   ` Kevin Wolf
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 08/18] qom: add link properties (v2) Anthony Liguori
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Child properties express a relationship of composition.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - fix comments (Kevin)
 - add a reference when adding a child property (Kevin)
---
 hw/qdev.c |   26 ++++++++++++++++++++++++++
 hw/qdev.h |   20 ++++++++++++++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 2519f00..fa6b489 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1174,6 +1174,32 @@ DeviceState *qdev_get_root(void)
     return qdev_root;
 }
 
+static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
+                                    const char *name, Error **errp)
+{
+    DeviceState *child = opaque;
+    gchar *path;
+
+    path = qdev_get_canonical_path(child);
+    visit_type_str(v, &path, name, errp);
+    g_free(path);
+}
+
+void qdev_property_add_child(DeviceState *dev, const char *name,
+                             DeviceState *child, Error **errp)
+{
+    gchar *type;
+
+    type = g_strdup_printf("child<%s>", child->info->name);
+
+    qdev_property_add(dev, name, type, qdev_get_child_property,
+                      NULL, NULL, child, errp);
+
+    qdev_ref(dev);
+
+    g_free(type);
+}
+
 static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
 {
     DeviceProperty *prop;
diff --git a/hw/qdev.h b/hw/qdev.h
index 641d134..38b36e8 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -527,4 +527,24 @@ gchar *qdev_get_canonical_path(DeviceState *dev);
  */
 DeviceState *qdev_resolve_path(const char *path, bool *ambiguous);
 
+/**
+ * @qdev_property_add_child - Add a child property to a device
+ *
+ * Child properties form the composition tree.  All devices need to be a child
+ * of another device.  Devices can only be a child of one device.
+ *
+ * There is no way for a child to determine what its parent is.  It is not
+ * a bidirectional relationship.  This is by design.
+ *
+ * @dev - the device to add a property to
+ *
+ * @name - the name of the property
+ *
+ * @child - the child device
+ *
+ * @errp - if an error occurs, a pointer to an area to store the area
+ */
+void qdev_property_add_child(DeviceState *dev, const char *name,
+                             DeviceState *child, Error **errp);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 08/18] qom: add link properties (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (6 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation Anthony Liguori
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Links represent an ephemeral relationship between devices.  They are meant to
replace the qdev concept of busses by allowing more informal relationships
between devices.

Links are fairly limited in their usefulness without implementing QOM-style
subclassing and interfaces.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - comments (Stefan)
 - maintain a reference when adding/removing a link property (Kevin)
---
 hw/qdev.c |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.h |   23 +++++++++++++++++++
 2 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index fa6b489..42430fa 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1200,6 +1200,80 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
     g_free(type);
 }
 
+static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
+                                   const char *name, Error **errp)
+{
+    DeviceState **child = opaque;
+    gchar *path;
+
+    if (*child) {
+        path = qdev_get_canonical_path(*child);
+        visit_type_str(v, &path, name, errp);
+        g_free(path);
+    } else {
+        path = (gchar *)"";
+        visit_type_str(v, &path, name, errp);
+    }
+}
+
+static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
+                                   const char *name, Error **errp)
+{
+    DeviceState **child = opaque;
+    bool ambiguous = false;
+    const char *type;
+    char *path;
+
+    type = qdev_property_get_type(dev, name, NULL);
+
+    visit_type_str(v, &path, name, errp);
+
+    if (*child) {
+        qdev_unref(*child);
+    }
+
+    if (strcmp(path, "") != 0) {
+        DeviceState *target;
+
+        target = qdev_resolve_path(path, &ambiguous);
+        if (target) {
+            gchar *target_type;
+
+            target_type = g_strdup_printf("link<%s>", target->info->name);
+            if (strcmp(target_type, type) == 0) {
+                *child = target;
+                qdev_ref(target);
+            } else {
+                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
+            }
+
+            g_free(target_type);
+        } else {
+            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+        }
+    } else {
+        *child = NULL;
+    }
+
+    g_free(path);
+}
+
+void qdev_property_add_link(DeviceState *dev, const char *name,
+                            const char *type, DeviceState **child,
+                            Error **errp)
+{
+    gchar *full_type;
+
+    full_type = g_strdup_printf("link<%s>", type);
+
+    qdev_property_add(dev, name, full_type,
+                      qdev_get_link_property,
+                      qdev_set_link_property,
+                      NULL, child, errp);
+
+    g_free(full_type);
+}
+
 static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
 {
     DeviceProperty *prop;
diff --git a/hw/qdev.h b/hw/qdev.h
index 38b36e8..4351e2e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -547,4 +547,27 @@ DeviceState *qdev_resolve_path(const char *path, bool *ambiguous);
 void qdev_property_add_child(DeviceState *dev, const char *name,
                              DeviceState *child, Error **errp);
 
+/**
+ * @qdev_property_add_link - Add a link property to a device
+ *
+ * Links establish relationships between devices.  Links are unidirectional
+ * although two links can be combined to form a bidirectional relationship
+ * between devices.
+ *
+ * Links form the graph in the device model.
+ *
+ * @dev - the device to add a property to
+ *
+ * @name - the name of the property
+ *
+ * @type - the qdev type of the link
+ *
+ * @child - a pointer to where the link device reference is stored
+ *
+ * @errp - if an error occurs, a pointer to an area to store the area
+ */
+void qdev_property_add_link(DeviceState *dev, const char *name,
+                            const char *type, DeviceState **child,
+                            Error **errp);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (7 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 08/18] qom: add link properties (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-08 16:04   ` Kevin Wolf
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 10/18] qmp: add qom-list command Anthony Liguori
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 scripts/qapi-commands.py |    1 +
 scripts/qapi-types.py    |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index f7def16..54d1f5d 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -405,6 +405,7 @@ except os.error, e:
 
 exprs = parse_schema(sys.stdin)
 commands = filter(lambda expr: expr.has_key('command'), exprs)
+commands = filter(lambda expr: not expr.has_key('gen'), commands)
 
 if dispatch_type == "sync":
     fdecl = open(h_file, 'w')
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index f64d84c..267cb49 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -238,6 +238,7 @@ fdecl.write(mcgen('''
                   guard=guardname(h_file)))
 
 exprs = parse_schema(sys.stdin)
+exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
 
 for expr in exprs:
     ret = "\n"
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 10/18] qmp: add qom-list command
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (8 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 11/18] qom: qom_{get, set} monitor commands (v2) Anthony Liguori
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

This can be used to list properties in the device model.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qapi-schema.json |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 qmp-commands.hx  |    6 ++++++
 qmp.c            |   28 ++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index cb1ba77..276b7c3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -887,3 +887,51 @@
 # Notes: Do not use this command.
 ##
 { 'command': 'cpu', 'data': {'index': 'int'} }
+
+##
+# @DevicePropertyInfo:
+#
+# @name: the name of the property
+#
+# @type: the type of the property.  This will typically come in one of four
+#        forms:
+#
+#        1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
+#           These types are mapped to the appropriate JSON type.
+#
+#        2) A legacy type in the form 'legacy<subtype>' where subtype is the
+#           legacy qdev typename.  These types are always treated as strings.
+#
+#        3) A child type in the form 'child<subtype>' where subtype is a qdev
+#           device type name.  Child properties create the composition tree.
+#
+#        4) A link type in the form 'link<subtype>' where subtype is a qdev
+#           device type name.  Link properties form the device model graph.
+#
+# Since: 1.1
+#
+# Notes: This type is experimental.  Its syntax may change in future releases.
+##
+{ 'type': 'DevicePropertyInfo',
+  'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @qom-list:
+#
+# This command will list any properties of a device given a path in the device
+# model.
+#
+# @path: the path within the device model.  See @qom-get for a description of
+#        this parameter.
+#
+# Returns: a list of @DevicePropertyInfo that describe the properties of the
+#          device.
+#
+# Since: 1.1
+#
+# Notes: This command is experimental.  It's syntax may change in future
+#        releases.
+##
+{ 'command': 'qom-list',
+  'data': { 'path': 'str' },
+  'returns': [ 'DevicePropertyInfo' ] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 97975a5..d6ff466 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2001,3 +2001,9 @@ EQMP
         .args_type  = "",
         .mhandler.cmd_new = qmp_marshal_input_query_balloon,
     },
+
+    {
+        .name       = "qom-list",
+        .args_type  = "path:s",
+        .mhandler.cmd_new = qmp_marshal_input_qom_list,
+    },
diff --git a/qmp.c b/qmp.c
index 511dd62..06ae569 100644
--- a/qmp.c
+++ b/qmp.c
@@ -16,6 +16,7 @@
 #include "qmp-commands.h"
 #include "kvm.h"
 #include "arch_init.h"
+#include "hw/qdev.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -117,3 +118,30 @@ SpiceInfo *qmp_query_spice(Error **errp)
     return NULL;
 };
 #endif
+
+DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp)
+{
+    DeviceState *dev;
+    bool ambiguous = false;
+    DevicePropertyInfoList *props = NULL;
+    DeviceProperty *prop;
+
+    dev = qdev_resolve_path(path, &ambiguous);
+    if (dev == NULL) {
+        error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+        return NULL;
+    }
+
+    QTAILQ_FOREACH(prop, &dev->properties, node) {
+        DevicePropertyInfoList *entry = g_malloc0(sizeof(*entry));
+
+        entry->value = g_malloc0(sizeof(DevicePropertyInfo));
+        entry->next = props;
+        props = entry;
+
+        entry->value->name = g_strdup(prop->name);
+        entry->value->type = g_strdup(prop->type);
+    }
+
+    return props;
+}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 11/18] qom: qom_{get, set} monitor commands (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (9 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 10/18] qmp: add qom-list command Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 12/18] qdev: add explicitly named devices to the root complex Anthony Liguori
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

This allows clients to read and write device model properties through QMP.  QAPI
doesn't support Visitor types yet and these commands are special in that they
don't work with fixed types.

I've added a documentation stub to qapi-schema.json so we can keep consistency
there.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - comments (Stefan)
---
 monitor.h        |    4 +++
 qapi-schema.json |   59 +++++++++++++++++++++++++++++++++++++++++++++++++
 qmp-commands.hx  |   12 ++++++++++
 qmp.c            |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+), 0 deletions(-)

diff --git a/monitor.h b/monitor.h
index e76795f..efc76c7 100644
--- a/monitor.h
+++ b/monitor.h
@@ -64,4 +64,8 @@ typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
 
 void monitor_set_error(Monitor *mon, QError *qerror);
 
+int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret);
+
+int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret);
+
 #endif /* !MONITOR_H */
diff --git a/qapi-schema.json b/qapi-schema.json
index 276b7c3..76a8a53 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -935,3 +935,62 @@
 { 'command': 'qom-list',
   'data': { 'path': 'str' },
   'returns': [ 'DevicePropertyInfo' ] }
+
+##
+# @qom-get:
+#
+# This command will get a property from a device model path and return the
+# value.
+#
+# @path: The path within the device model.  There are two forms of supported
+#        paths--absolute and partial paths.
+#
+#        Absolute paths are derived from the root device and can follow child<>
+#        or link<> properties.  Since they can follow link<> properties, they
+#        can be arbitrarily long.  Absolute paths look like absolute filenames
+#        and are prefixed  with a leading slash.
+#
+#        Partial paths look like relative filenames.  They do not begin
+#        with a prefix.  The matching rules for partial paths are subtle but
+#        designed to make specifying devices easy.  At each level of the
+#        composition tree, the partial path is matched as an absolute path.
+#        The first match is not returned.  At least two matches are searched
+#        for.  A successful result is only returned if only one match is
+#        found.  If more than one match is found, a flag is return to
+#        indicate that the match was ambiguous.
+#
+# @property: The property name to read
+#
+# Returns: The property value.  The type depends on the property type.  legacy<>
+#          properties are returned as #str.  child<> and link<> properties are
+#          returns as #str pathnames.  All integer property types (u8, u16, etc)
+#          are returned as #int.
+#
+# Since: 1.1
+#
+# Notes: This command is experimental and may change syntax in future releases.
+##
+{ 'command': 'qom-get',
+  'data': { 'path': 'str', 'property': 'str' },
+  'returns': 'visitor',
+  'gen': 'no' }
+
+##
+# @qom-set:
+#
+# This command will set a property from a device model path.
+#
+# @path: see @qom-get for a description of this parameter
+#
+# @property: the property name to set
+#
+# @value: a value who's type is appropriate for the property type.  See @qom-get
+#         for a description of type mapping.
+#
+# Since: 1.1
+#
+# Notes: This command is experimental and may change syntax in future releases.
+##
+{ 'command': 'qom-set',
+  'data': { 'path': 'str', 'property': 'str', 'value': 'visitor' },
+  'gen': 'no' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index d6ff466..027189a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2007,3 +2007,15 @@ EQMP
         .args_type  = "path:s",
         .mhandler.cmd_new = qmp_marshal_input_qom_list,
     },
+
+    {
+        .name       = "qom-set",
+	.args_type  = "path:s,property:s,opts:O",
+	.mhandler.cmd_new = qmp_qom_set,
+    },
+
+    {
+        .name       = "qom-get",
+	.args_type  = "path:s,property:s",
+	.mhandler.cmd_new = qmp_qom_get,
+    },
diff --git a/qmp.c b/qmp.c
index 06ae569..641761e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -17,6 +17,8 @@
 #include "kvm.h"
 #include "arch_init.h"
 #include "hw/qdev.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -145,3 +147,66 @@ DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp)
 
     return props;
 }
+
+/* FIXME: teach qapi about how to pass through Visitors */
+int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    const char *path = qdict_get_str(qdict, "path");
+    const char *property = qdict_get_str(qdict, "property");
+    QObject *value = qdict_get(qdict, "value");
+    Error *local_err = NULL;
+    QmpInputVisitor *mi;
+    DeviceState *dev;
+
+    dev = qdev_resolve_path(path, NULL);
+    if (!dev) {
+        error_set(&local_err, QERR_DEVICE_NOT_FOUND, path);
+        goto out;
+    }
+
+    mi = qmp_input_visitor_new(value);
+    qdev_property_set(dev, qmp_input_get_visitor(mi), property, &local_err);
+
+    qmp_input_visitor_cleanup(mi);
+
+out:
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+
+    return 0;
+}
+
+int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    const char *path = qdict_get_str(qdict, "path");
+    const char *property = qdict_get_str(qdict, "property");
+    Error *local_err = NULL;
+    QmpOutputVisitor *mo;
+    DeviceState *dev;
+
+    dev = qdev_resolve_path(path, NULL);
+    if (!dev) {
+        error_set(&local_err, QERR_DEVICE_NOT_FOUND, path);
+        goto out;
+    }
+
+    mo = qmp_output_visitor_new();
+    qdev_property_get(dev, qmp_output_get_visitor(mo), property, &local_err);
+    if (!local_err) {
+        *ret = qmp_output_get_qobject(mo);
+    }
+
+    qmp_output_visitor_cleanup(mo);
+
+out:
+    if (local_err) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+
+    return 0;
+}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 12/18] qdev: add explicitly named devices to the root complex
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (10 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 11/18] qom: qom_{get, set} monitor commands (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container Anthony Liguori
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

We first add a 'peripheral' container to the root device that we add user
created devices to.  This provides all user created devices with a unique and
isolated namespace.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 42430fa..af4c6a2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -227,6 +227,19 @@ int qdev_device_help(QemuOpts *opts)
     return 1;
 }
 
+static DeviceState *qdev_get_peripheral(void)
+{
+    static DeviceState *dev;
+
+    if (dev == NULL) {
+        dev = qdev_create(NULL, "container");
+        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
+        qdev_init_nofail(dev);
+    }
+
+    return dev;
+}
+
 DeviceState *qdev_device_add(QemuOpts *opts)
 {
     const char *driver, *path, *id;
@@ -278,6 +291,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     id = qemu_opts_id(opts);
     if (id) {
         qdev->id = id;
+        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
     }
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
         qdev_free(qdev);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (11 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 12/18] qdev: add explicitly named devices to the root complex Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-08 16:27   ` Kevin Wolf
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 14/18] rtc: make piix3 set the rtc as a child (v2) Anthony Liguori
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |   21 ++++++++++++++++++++-
 1 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index af4c6a2..5348f26 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -240,6 +240,19 @@ static DeviceState *qdev_get_peripheral(void)
     return dev;
 }
 
+static DeviceState *qdev_get_peripheral_anon(void)
+{
+    static DeviceState *dev;
+
+    if (dev == NULL) {
+        dev = qdev_create(NULL, "container");
+        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
+        qdev_init_nofail(dev);
+    }
+
+    return dev;
+}
+
 DeviceState *qdev_device_add(QemuOpts *opts)
 {
     const char *driver, *path, *id;
@@ -292,7 +305,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     if (id) {
         qdev->id = id;
         qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
-    }
+    } else {
+        static int anon_count;
+        gchar *name = g_strdup_printf("device[%d]", anon_count++);
+        qdev_property_add_child(qdev_get_peripheral_anon(), name,
+                                qdev, NULL);
+        g_free(name);
+    }        
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
         qdev_free(qdev);
         return NULL;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 14/18] rtc: make piix3 set the rtc as a child (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (12 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date Anthony Liguori
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - comments (Stefan)
---
 hw/pc_piix.c  |   11 +++++++++++
 hw/piix_pci.c |    3 +++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 970f43c..2d5ea2c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -205,6 +205,17 @@ static void pc_init1(MemoryRegion *system_memory,
         }
     }
 
+    /* FIXME there's some major spaghetti here.  Somehow we create the devices
+     * on the PIIX before we actually create it.  We create the PIIX3 deep in
+     * the recess of the i440fx creation too and then lose the DeviceState.
+     *
+     * For now, let's "fix" this by making judicious use of paths.  This is not
+     * generally the right way to do this.
+     */
+
+    qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
+                            "rtc", (DeviceState *)rtc_state, NULL);
+
     audio_init(gsi, pci_enabled ? pci_bus : NULL);
 
     pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index d183443..d785d4b 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -288,6 +288,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
                     address_space_io, 0);
     s->bus = b;
     qdev_init_nofail(dev);
+    qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL);
 
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -323,6 +324,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
                 pci_create_simple_multifunction(b, -1, true, "PIIX3"));
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
+
+        qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
     }
     piix3->pic = pic;
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (13 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 14/18] rtc: make piix3 set the rtc as a child (v2) Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-09 11:26   ` Kevin Wolf
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link Anthony Liguori
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

This really shows the power of dynamic object properties compared to qdev
static properties.

This property represents a complex structure who's format is preserved over the
wire.  This is enabled by visitors.

It also shows an entirely synthetic property that is not tied to device state.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/mc146818rtc.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2aaca2f..0c23cb0 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -614,6 +614,29 @@ static const MemoryRegionOps cmos_ops = {
     .old_portio = cmos_portio
 };
 
+// FIXME add int32 visitor
+static void visit_type_int32(Visitor *v, int *value, const char *name, Error **errp)
+{
+    int64_t val = *value;
+    visit_type_int(v, &val, name, errp);
+}
+
+static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque,
+                         const char *name, Error **errp)
+{
+    ISADevice *isa = DO_UPCAST(ISADevice, qdev, dev);
+    RTCState *s = DO_UPCAST(RTCState, dev, isa);
+
+    visit_start_struct(v, NULL, "struct tm", name, 0, errp);
+    visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
+    visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
+    visit_type_int32(v, &s->current_tm.tm_mday, "tm_mday", errp);
+    visit_type_int32(v, &s->current_tm.tm_hour, "tm_hour", errp);
+    visit_type_int32(v, &s->current_tm.tm_min, "tm_min", errp);
+    visit_type_int32(v, &s->current_tm.tm_sec, "tm_sec", errp);
+    visit_end_struct(v, errp);
+}
+
 static int rtc_initfn(ISADevice *dev)
 {
     RTCState *s = DO_UPCAST(RTCState, dev, dev);
@@ -647,6 +670,10 @@ static int rtc_initfn(ISADevice *dev)
 
     qdev_set_legacy_instance_id(&dev->qdev, base, 2);
     qemu_register_reset(rtc_reset, s);
+
+    qdev_property_add(&s->dev.qdev, "date", "struct tm",
+                      rtc_get_date, NULL, NULL, s, NULL);
+
     return 0;
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (14 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-09 11:13   ` Kevin Wolf
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 17/18] qmp: make qmp.py easier to use Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2) Anthony Liguori
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

The full tree search was a bit unreasonable.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |   56 ++++++++++++++++++++++++--------------------------------
 hw/qdev.h |    4 ++++
 2 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 5348f26..1102efd 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1229,6 +1229,8 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
                       NULL, NULL, child, errp);
 
     qdev_ref(dev);
+    g_assert(child->parent == NULL);
+    child->parent = dev;
 
     g_free(type);
 }
@@ -1307,48 +1309,38 @@ void qdev_property_add_link(DeviceState *dev, const char *name,
     g_free(full_type);
 }
 
-static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
+gchar *qdev_get_canonical_path(DeviceState *dev)
 {
-    DeviceProperty *prop;
+    DeviceState *root = qdev_get_root();
+    char *newpath = NULL, *path = NULL;
 
-    if (parent == dev) {
-        return g_strdup("");
-    }
+    while (dev != root) {
+        DeviceProperty *prop = NULL;
 
-    QTAILQ_FOREACH(prop, &parent->properties, node) {
-        gchar *subpath;
+        g_assert(dev->parent != NULL);
 
-        if (!strstart(prop->type, "child<", NULL)) {
-            continue;
-        }
+        QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
+            if (!strstart(prop->type, "child<", NULL)) {
+                continue;
+            }
 
-        /* Check to see if the device is one of parent's children */
-        if (prop->opaque == dev) {
-            return g_strdup(prop->name);
+            if (prop->opaque == dev) {
+                if (path) {
+                    newpath = g_strdup_printf("%s/%s", prop->name, path);
+                    g_free(path);
+                    path = newpath;
+                } else {
+                    path = g_strdup(prop->name);
+                }
+                break;
+            }
         }
 
-        /* Check to see if the device is a child of our child */
-        subpath = qdev_get_path_in(prop->opaque, dev);
-        if (subpath) {
-            gchar *path;
+        g_assert(prop != NULL);
 
-            path = g_strdup_printf("%s/%s", prop->name, subpath);
-            g_free(subpath);
-
-            return path;
-        }
+        dev = dev->parent;
     }
 
-    return NULL;
-}
-
-gchar *qdev_get_canonical_path(DeviceState *dev)
-{
-    gchar *path, *newpath;
-
-    path = qdev_get_path_in(qdev_get_root(), dev);
-    g_assert(path != NULL);
-
     newpath = g_strdup_printf("/%s", path);
     g_free(path);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 4351e2e..fdab848 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -92,6 +92,10 @@ struct DeviceState {
     uint32_t ref;
 
     QTAILQ_HEAD(, DeviceProperty) properties;
+
+    /* Do not, under any circumstance, use this parent link below anywhere
+     * outside of qdev.c.  You have been warned. */
+    DeviceState *parent;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 17/18] qmp: make qmp.py easier to use
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (15 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2) Anthony Liguori
  17 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 QMP/qmp.py |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/QMP/qmp.py b/QMP/qmp.py
index c7dbea0..36ecc1d 100644
--- a/QMP/qmp.py
+++ b/QMP/qmp.py
@@ -128,6 +128,12 @@ class QEMUMonitorProtocol:
             qmp_cmd['id'] = id
         return self.cmd_obj(qmp_cmd)
 
+    def command(self, cmd, **kwds):
+        ret = self.cmd(cmd, kwds)
+        if ret.has_key('error'):
+            raise Exception(ret['error']['desc'])
+        return ret['return']
+
     def get_events(self, wait=False):
         """
         Get a list of available QMP events.
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2)
  2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
                   ` (16 preceding siblings ...)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 17/18] qmp: make qmp.py easier to use Anthony Liguori
@ 2011-12-02 20:20 ` Anthony Liguori
  2011-12-09 11:19   ` Kevin Wolf
  17 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-02 20:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Peter Maydell, Anthony Liguori, Stefan Hajnoczi,
	Jan Kiszka, Markus Armbruster, Luiz Capitulino, Gerd Hoffman

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - fix comments (Stefan)
---
 QMP/qom-get  |   26 ++++++++++++++++++++++++++
 QMP/qom-list |   30 ++++++++++++++++++++++++++++++
 QMP/qom-set  |   21 +++++++++++++++++++++
 3 files changed, 77 insertions(+), 0 deletions(-)
 create mode 100755 QMP/qom-get
 create mode 100755 QMP/qom-list
 create mode 100755 QMP/qom-set

diff --git a/QMP/qom-get b/QMP/qom-get
new file mode 100755
index 0000000..e6c063a
--- /dev/null
+++ b/QMP/qom-get
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.  See
+# the COPYING file in the top-level directory.
+##
+
+import sys
+from qmp import QEMUMonitorProtocol
+
+srv = QEMUMonitorProtocol('/tmp/server.sock')
+srv.connect()
+
+path, prop = sys.argv[1].rsplit('.', 1)
+rsp = srv.command('qom-get', path=path, property=prop)
+if type(rsp) == dict:
+    for i in rsp.keys():
+        print '%s: %s' % (i, rsp[i])
+else:
+    print rsp
diff --git a/QMP/qom-list b/QMP/qom-list
new file mode 100755
index 0000000..b91f814
--- /dev/null
+++ b/QMP/qom-list
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.  See
+# the COPYING file in the top-level directory.
+##
+
+import sys
+from qmp import QEMUMonitorProtocol
+
+srv = QEMUMonitorProtocol('/tmp/server.sock')
+srv.connect()
+
+if len(sys.argv) == 1:
+    print '/'
+    sys.exit(0)
+
+for item in srv.command('qom-list', path=sys.argv[1]):
+    if item['type'].startswith('child<'):
+        print '%s/' % item['name']
+    elif item['type'].startswith('link<'):
+        print '@%s/' % item['name']
+    else:
+        print '%s' % item['name']
diff --git a/QMP/qom-set b/QMP/qom-set
new file mode 100755
index 0000000..c5589d8
--- /dev/null
+++ b/QMP/qom-set
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+##
+# QEMU Object Model test tools
+#
+# Copyright IBM, Corp. 2011
+#
+# Authors:
+#  Anthony Liguori   <aliguori@us.ibm.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.  See
+# the COPYING file in the top-level directory.
+##
+
+import sys
+from qmp import QEMUMonitorProtocol
+
+srv = QEMUMonitorProtocol('/tmp/server.sock')
+srv.connect()
+
+path, prop = sys.argv[1].rsplit('.', 1)
+print srv.command('qom-set', path=path, property=prop, value=sys.argv[2])
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2) Anthony Liguori
@ 2011-12-08 15:38   ` Kevin Wolf
  2011-12-08 16:45     ` Anthony Liguori
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2011-12-08 15:38 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> Child properties express a relationship of composition.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> v1 -> v2
>  - fix comments (Kevin)
>  - add a reference when adding a child property (Kevin)
> ---
>  hw/qdev.c |   26 ++++++++++++++++++++++++++
>  hw/qdev.h |   20 ++++++++++++++++++++
>  2 files changed, 46 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 2519f00..fa6b489 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -1174,6 +1174,32 @@ DeviceState *qdev_get_root(void)
>      return qdev_root;
>  }
>  
> +static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
> +                                    const char *name, Error **errp)
> +{
> +    DeviceState *child = opaque;
> +    gchar *path;
> +
> +    path = qdev_get_canonical_path(child);
> +    visit_type_str(v, &path, name, errp);
> +    g_free(path);
> +}
> +
> +void qdev_property_add_child(DeviceState *dev, const char *name,
> +                             DeviceState *child, Error **errp)
> +{
> +    gchar *type;
> +
> +    type = g_strdup_printf("child<%s>", child->info->name);
> +
> +    qdev_property_add(dev, name, type, qdev_get_child_property,
> +                      NULL, NULL, child, errp);
> +
> +    qdev_ref(dev);

Shouldn't you increase the refcount for child rather than dev?

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation Anthony Liguori
@ 2011-12-08 16:04   ` Kevin Wolf
  2011-12-08 16:45     ` Anthony Liguori
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2011-12-08 16:04 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  scripts/qapi-commands.py |    1 +
>  scripts/qapi-types.py    |    1 +
>  2 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index f7def16..54d1f5d 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -405,6 +405,7 @@ except os.error, e:
>  
>  exprs = parse_schema(sys.stdin)
>  commands = filter(lambda expr: expr.has_key('command'), exprs)
> +commands = filter(lambda expr: not expr.has_key('gen'), commands)

Might be confusing if someone uses something like gen = True. Shouldn't
we better check the value instead of just existence?

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container Anthony Liguori
@ 2011-12-08 16:27   ` Kevin Wolf
  2011-12-08 16:44     ` Anthony Liguori
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2011-12-08 16:27 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/qdev.c |   21 ++++++++++++++++++++-
>  1 files changed, 20 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/qdev.c b/hw/qdev.c
> index af4c6a2..5348f26 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -240,6 +240,19 @@ static DeviceState *qdev_get_peripheral(void)
>      return dev;
>  }
>  
> +static DeviceState *qdev_get_peripheral_anon(void)
> +{
> +    static DeviceState *dev;
> +
> +    if (dev == NULL) {
> +        dev = qdev_create(NULL, "container");
> +        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
> +        qdev_init_nofail(dev);
> +    }
> +
> +    return dev;
> +}
> +
>  DeviceState *qdev_device_add(QemuOpts *opts)
>  {
>      const char *driver, *path, *id;
> @@ -292,7 +305,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
>      if (id) {
>          qdev->id = id;
>          qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
> -    }
> +    } else {
> +        static int anon_count;
> +        gchar *name = g_strdup_printf("device[%d]", anon_count++);

Does any code depend on this name? If not, I would suggest making it a
bit more convenient for users: g_strdump_printf("%s[%d]", info->name,
info->anon_count++)

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container
  2011-12-08 16:27   ` Kevin Wolf
@ 2011-12-08 16:44     ` Anthony Liguori
  0 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-08 16:44 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Anthony Liguori, Stefan Hajnoczi, Jan Kiszka,
	qemu-devel, Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/08/2011 10:27 AM, Kevin Wolf wrote:
> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>>   hw/qdev.c |   21 ++++++++++++++++++++-
>>   1 files changed, 20 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/qdev.c b/hw/qdev.c
>> index af4c6a2..5348f26 100644
>> --- a/hw/qdev.c
>> +++ b/hw/qdev.c
>> @@ -240,6 +240,19 @@ static DeviceState *qdev_get_peripheral(void)
>>       return dev;
>>   }
>>
>> +static DeviceState *qdev_get_peripheral_anon(void)
>> +{
>> +    static DeviceState *dev;
>> +
>> +    if (dev == NULL) {
>> +        dev = qdev_create(NULL, "container");
>> +        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
>> +        qdev_init_nofail(dev);
>> +    }
>> +
>> +    return dev;
>> +}
>> +
>>   DeviceState *qdev_device_add(QemuOpts *opts)
>>   {
>>       const char *driver, *path, *id;
>> @@ -292,7 +305,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
>>       if (id) {
>>           qdev->id = id;
>>           qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
>> -    }
>> +    } else {
>> +        static int anon_count;
>> +        gchar *name = g_strdup_printf("device[%d]", anon_count++);
>
> Does any code depend on this name? If not, I would suggest making it a
> bit more convenient for users: g_strdump_printf("%s[%d]", info->name,
> info->anon_count++)

Nothing does and that's a great suggestion, thanks!

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2)
  2011-12-08 15:38   ` Kevin Wolf
@ 2011-12-08 16:45     ` Anthony Liguori
  0 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-08 16:45 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Anthony Liguori, Stefan Hajnoczi, Jan Kiszka,
	qemu-devel, Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/08/2011 09:38 AM, Kevin Wolf wrote:
> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>> Child properties express a relationship of composition.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>> v1 ->  v2
>>   - fix comments (Kevin)
>>   - add a reference when adding a child property (Kevin)
>> ---
>>   hw/qdev.c |   26 ++++++++++++++++++++++++++
>>   hw/qdev.h |   20 ++++++++++++++++++++
>>   2 files changed, 46 insertions(+), 0 deletions(-)
>>
>> diff --git a/hw/qdev.c b/hw/qdev.c
>> index 2519f00..fa6b489 100644
>> --- a/hw/qdev.c
>> +++ b/hw/qdev.c
>> @@ -1174,6 +1174,32 @@ DeviceState *qdev_get_root(void)
>>       return qdev_root;
>>   }
>>
>> +static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
>> +                                    const char *name, Error **errp)
>> +{
>> +    DeviceState *child = opaque;
>> +    gchar *path;
>> +
>> +    path = qdev_get_canonical_path(child);
>> +    visit_type_str(v,&path, name, errp);
>> +    g_free(path);
>> +}
>> +
>> +void qdev_property_add_child(DeviceState *dev, const char *name,
>> +                             DeviceState *child, Error **errp)
>> +{
>> +    gchar *type;
>> +
>> +    type = g_strdup_printf("child<%s>", child->info->name);
>> +
>> +    qdev_property_add(dev, name, type, qdev_get_child_property,
>> +                      NULL, NULL, child, errp);
>> +
>> +    qdev_ref(dev);
>
> Shouldn't you increase the refcount for child rather than dev?

Indeed, I've fixed it in my tree.  Thanks.

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation
  2011-12-08 16:04   ` Kevin Wolf
@ 2011-12-08 16:45     ` Anthony Liguori
  0 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-08 16:45 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/08/2011 10:04 AM, Kevin Wolf wrote:
> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>>   scripts/qapi-commands.py |    1 +
>>   scripts/qapi-types.py    |    1 +
>>   2 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
>> index f7def16..54d1f5d 100644
>> --- a/scripts/qapi-commands.py
>> +++ b/scripts/qapi-commands.py
>> @@ -405,6 +405,7 @@ except os.error, e:
>>
>>   exprs = parse_schema(sys.stdin)
>>   commands = filter(lambda expr: expr.has_key('command'), exprs)
>> +commands = filter(lambda expr: not expr.has_key('gen'), commands)
>
> Might be confusing if someone uses something like gen = True. Shouldn't
> we better check the value instead of just existence?

Yes, it was a lazy short cut.  I'll fix appropriately.

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link Anthony Liguori
@ 2011-12-09 11:13   ` Kevin Wolf
  0 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2011-12-09 11:13 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> The full tree search was a bit unreasonable.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

> diff --git a/hw/qdev.h b/hw/qdev.h
> index 4351e2e..fdab848 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -92,6 +92,10 @@ struct DeviceState {
>      uint32_t ref;
>  
>      QTAILQ_HEAD(, DeviceProperty) properties;
> +
> +    /* Do not, under any circumstance, use this parent link below anywhere
> +     * outside of qdev.c.  You have been warned. */
> +    DeviceState *parent;
>  };

I would expect that a warning works better if it tells people _why_
their code will break if they do it anyway (it's not clear to me)

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2)
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2) Anthony Liguori
@ 2011-12-09 11:19   ` Kevin Wolf
  0 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2011-12-09 11:19 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> v1 -> v2
>  - fix comments (Stefan)
> ---
>  QMP/qom-get  |   26 ++++++++++++++++++++++++++
>  QMP/qom-list |   30 ++++++++++++++++++++++++++++++
>  QMP/qom-set  |   21 +++++++++++++++++++++
>  3 files changed, 77 insertions(+), 0 deletions(-)
>  create mode 100755 QMP/qom-get
>  create mode 100755 QMP/qom-list
>  create mode 100755 QMP/qom-set
> 
> diff --git a/QMP/qom-get b/QMP/qom-get
> new file mode 100755
> index 0000000..e6c063a
> --- /dev/null
> +++ b/QMP/qom-get
> @@ -0,0 +1,26 @@
> +#!/usr/bin/python
> +##
> +# QEMU Object Model test tools
> +#
> +# Copyright IBM, Corp. 2011
> +#
> +# Authors:
> +#  Anthony Liguori   <aliguori@us.ibm.com>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or later.  See
> +# the COPYING file in the top-level directory.
> +##
> +
> +import sys
> +from qmp import QEMUMonitorProtocol
> +
> +srv = QEMUMonitorProtocol('/tmp/server.sock')

Hard coding paths is fine for initial tests, but they probably shouldn't
make their way into the git. :-)

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date Anthony Liguori
@ 2011-12-09 11:26   ` Kevin Wolf
  2011-12-09 13:08     ` Anthony Liguori
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2011-12-09 11:26 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 02.12.2011 21:20, schrieb Anthony Liguori:
> This really shows the power of dynamic object properties compared to qdev
> static properties.
> 
> This property represents a complex structure who's format is preserved over the
> wire.  This is enabled by visitors.
> 
> It also shows an entirely synthetic property that is not tied to device state.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

There's one thing that I was hoping to find answered when I would have
reviewed the whole series, but it hasn't happened: There is no doubt
that dynamic properties (in the sense of being able to modify them after
constructions) are a useful thing. But you also claim that class-based
properties are not enough for QOM and that we need object-based ones,
which is a requirement not immediately obvious to me.

Can you provide some examples where we would explicitly need
object-based properties?

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-09 11:26   ` Kevin Wolf
@ 2011-12-09 13:08     ` Anthony Liguori
  2011-12-09 14:04       ` Kevin Wolf
  0 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-09 13:08 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/09/2011 05:26 AM, Kevin Wolf wrote:
> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>> This really shows the power of dynamic object properties compared to qdev
>> static properties.
>>
>> This property represents a complex structure who's format is preserved over the
>> wire.  This is enabled by visitors.
>>
>> It also shows an entirely synthetic property that is not tied to device state.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>
> There's one thing that I was hoping to find answered when I would have
> reviewed the whole series, but it hasn't happened: There is no doubt
> that dynamic properties (in the sense of being able to modify them after
> constructions) are a useful thing. But you also claim that class-based
> properties are not enough for QOM and that we need object-based ones,
> which is a requirement not immediately obvious to me.
>
> Can you provide some examples where we would explicitly need
> object-based properties?

Sure.  Any property that's dynamic needs to be object based.  A good example 
would be PCI slots.

Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be 
desirable to eventually make this configurable.  So you can imagine where you 
would have an 'slot-count' property and if that was set to 16, it would result 
in 'slot[0]..slot[15]' being created.

There are other good examples too.

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-09 13:08     ` Anthony Liguori
@ 2011-12-09 14:04       ` Kevin Wolf
  2011-12-09 14:25         ` Anthony Liguori
  0 siblings, 1 reply; 36+ messages in thread
From: Kevin Wolf @ 2011-12-09 14:04 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 09.12.2011 14:08, schrieb Anthony Liguori:
> On 12/09/2011 05:26 AM, Kevin Wolf wrote:
>> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>>> This really shows the power of dynamic object properties compared to qdev
>>> static properties.
>>>
>>> This property represents a complex structure who's format is preserved over the
>>> wire.  This is enabled by visitors.
>>>
>>> It also shows an entirely synthetic property that is not tied to device state.
>>>
>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>
>> There's one thing that I was hoping to find answered when I would have
>> reviewed the whole series, but it hasn't happened: There is no doubt
>> that dynamic properties (in the sense of being able to modify them after
>> constructions) are a useful thing. But you also claim that class-based
>> properties are not enough for QOM and that we need object-based ones,
>> which is a requirement not immediately obvious to me.
>>
>> Can you provide some examples where we would explicitly need
>> object-based properties?
> 
> Sure.  Any property that's dynamic needs to be object based.  A good example 
> would be PCI slots.
> 
> Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be 
> desirable to eventually make this configurable.  So you can imagine where you 
> would have an 'slot-count' property and if that was set to 16, it would result 
> in 'slot[0]..slot[15]' being created.
> 
> There are other good examples too.

So is it mostly about variably sized arrays, which just happen to be
considered independent properties in your approach? Or are there cases
where a logically separate property may be there or missing depending on
some condition, or possibly even that a new property is created during
runtime?

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-09 14:04       ` Kevin Wolf
@ 2011-12-09 14:25         ` Anthony Liguori
  2011-12-13  9:27           ` Kevin Wolf
  0 siblings, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-09 14:25 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/09/2011 08:04 AM, Kevin Wolf wrote:
> Am 09.12.2011 14:08, schrieb Anthony Liguori:
>> On 12/09/2011 05:26 AM, Kevin Wolf wrote:
>>> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>>>> This really shows the power of dynamic object properties compared to qdev
>>>> static properties.
>>>>
>>>> This property represents a complex structure who's format is preserved over the
>>>> wire.  This is enabled by visitors.
>>>>
>>>> It also shows an entirely synthetic property that is not tied to device state.
>>>>
>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>
>>> There's one thing that I was hoping to find answered when I would have
>>> reviewed the whole series, but it hasn't happened: There is no doubt
>>> that dynamic properties (in the sense of being able to modify them after
>>> constructions) are a useful thing. But you also claim that class-based
>>> properties are not enough for QOM and that we need object-based ones,
>>> which is a requirement not immediately obvious to me.
>>>
>>> Can you provide some examples where we would explicitly need
>>> object-based properties?
>>
>> Sure.  Any property that's dynamic needs to be object based.  A good example
>> would be PCI slots.
>>
>> Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be
>> desirable to eventually make this configurable.  So you can imagine where you
>> would have an 'slot-count' property and if that was set to 16, it would result
>> in 'slot[0]..slot[15]' being created.
>>
>> There are other good examples too.
>
> So is it mostly about variably sized arrays, which just happen to be
> considered independent properties in your approach? Or are there cases
> where a logically separate property may be there or missing depending on
> some condition, or possibly even that a new property is created during
> runtime?

So there are three possibilities for properties:

1) Properties have no per-object state, and exist entirely within the classes. 
This is what qdev does today.

2) Properties are defined in the class, but carry per-object state.

3) Properties are defined in the object and carry per-object state.

We definitely can rule out (1).  Stateful properties are needed to implement 
links, composition, and just about anything interesting.

Another way that (3) is useful is that it allows you to create container devices 
that more or less model a PCB.  That's how peripheral[-anon] is implemented and 
I imagine that it will also be useful for implementing "machine" devices.

Of course, you could find a way to special case this with (2) but that's why I 
ended up going with (3).  You can avoid having a lot of special cases this way.

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-09 14:25         ` Anthony Liguori
@ 2011-12-13  9:27           ` Kevin Wolf
  2011-12-13  9:48             ` Gerd Hoffmann
  2011-12-13 13:31             ` Anthony Liguori
  0 siblings, 2 replies; 36+ messages in thread
From: Kevin Wolf @ 2011-12-13  9:27 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 09.12.2011 15:25, schrieb Anthony Liguori:
> On 12/09/2011 08:04 AM, Kevin Wolf wrote:
>> Am 09.12.2011 14:08, schrieb Anthony Liguori:
>>> On 12/09/2011 05:26 AM, Kevin Wolf wrote:
>>>> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>>>>> This really shows the power of dynamic object properties compared to qdev
>>>>> static properties.
>>>>>
>>>>> This property represents a complex structure who's format is preserved over the
>>>>> wire.  This is enabled by visitors.
>>>>>
>>>>> It also shows an entirely synthetic property that is not tied to device state.
>>>>>
>>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>>
>>>> There's one thing that I was hoping to find answered when I would have
>>>> reviewed the whole series, but it hasn't happened: There is no doubt
>>>> that dynamic properties (in the sense of being able to modify them after
>>>> constructions) are a useful thing. But you also claim that class-based
>>>> properties are not enough for QOM and that we need object-based ones,
>>>> which is a requirement not immediately obvious to me.
>>>>
>>>> Can you provide some examples where we would explicitly need
>>>> object-based properties?
>>>
>>> Sure.  Any property that's dynamic needs to be object based.  A good example
>>> would be PCI slots.
>>>
>>> Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be
>>> desirable to eventually make this configurable.  So you can imagine where you
>>> would have an 'slot-count' property and if that was set to 16, it would result
>>> in 'slot[0]..slot[15]' being created.
>>>
>>> There are other good examples too.
>>
>> So is it mostly about variably sized arrays, which just happen to be
>> considered independent properties in your approach? Or are there cases
>> where a logically separate property may be there or missing depending on
>> some condition, or possibly even that a new property is created during
>> runtime?
> 
> So there are three possibilities for properties:
> 
> 1) Properties have no per-object state, and exist entirely within the classes. 
> This is what qdev does today.

Not quite sure what you mean by per-object state. The properties are
fields in the XyzState, so they certainly are per-object?

> 2) Properties are defined in the class, but carry per-object state.
> 
> 3) Properties are defined in the object and carry per-object state.
> 
> We definitely can rule out (1).  Stateful properties are needed to implement 
> links, composition, and just about anything interesting.
> 
> Another way that (3) is useful is that it allows you to create container devices 
> that more or less model a PCB.  That's how peripheral[-anon] is implemented and 
> I imagine that it will also be useful for implementing "machine" devices.

What would this look like? The user creates new child/link properties on
the board, and some more automatically created properties somehow
describe the wiring between them?

> Of course, you could find a way to special case this with (2) but that's why I 
> ended up going with (3).  You can avoid having a lot of special cases this way.

I'm not entirely convinced that we really need this, but on the other
hand I don't feel strong enough about it to argue.

Actually I think my real problem isn't about per-object properties
(although they might add unnecessary complexity), but more about going
away from the qdev style of things where you had _one_ struct definition
that nicely described all of the properties in a central place. Instead,
I'm seeing patches that spread property definitions all over the code.

Now I understand that for dynamically created properties (like on your
PCB) this is necessary and can't be avoided. For about 99% of the
devices static definition of properties would be enough, though.

So basically what I'm asking for is getting the static structs back for
the 99% and have common code that parses them and calls the appropriate
functions to actually the properties. The remaining 1% that
creates/deletes properties during runtime and isn't covered can directly
call whatever it needs.

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-13  9:27           ` Kevin Wolf
@ 2011-12-13  9:48             ` Gerd Hoffmann
  2011-12-13 13:33               ` Anthony Liguori
  2011-12-13 13:31             ` Anthony Liguori
  1 sibling, 1 reply; 36+ messages in thread
From: Gerd Hoffmann @ 2011-12-13  9:48 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Markus Armbruster

  Hi,

> Now I understand that for dynamically created properties (like on your
> PCB) this is necessary and can't be avoided. For about 99% of the
> devices static definition of properties would be enough, though.
> 
> So basically what I'm asking for is getting the static structs back for
> the 99% and have common code that parses them and calls the appropriate
> functions to actually the properties. The remaining 1% that
> creates/deletes properties during runtime and isn't covered can directly
> call whatever it needs.

Fully agree.  I guess we can even generate those structs in many cases.
 We will parse the ${device}State structs anyway for visitor-based
vmstate, so with some extra declaration we can generate property
descriptions too.  For example this ...

static PCIDeviceInfo intel_hda_info = {
    .qdev.name    = "intel-hda",
    [ ... ]
    .qdev.props   = (Property[]) {
        DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
        DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
        DEFINE_PROP_END_OF_LIST(),
    }
};

... could be just ...

struct IntelHDAState {
    [ ... ]
    /* properties */
    uint32_t debug __property(0);
    uint32_t msi   __property(1);
};

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-13  9:27           ` Kevin Wolf
  2011-12-13  9:48             ` Gerd Hoffmann
@ 2011-12-13 13:31             ` Anthony Liguori
  2011-12-13 13:49               ` Kevin Wolf
  1 sibling, 1 reply; 36+ messages in thread
From: Anthony Liguori @ 2011-12-13 13:31 UTC (permalink / raw)
  To: Kevin Wolf
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

On 12/13/2011 03:27 AM, Kevin Wolf wrote:
> Am 09.12.2011 15:25, schrieb Anthony Liguori:
>> On 12/09/2011 08:04 AM, Kevin Wolf wrote:
>>> Am 09.12.2011 14:08, schrieb Anthony Liguori:
>>>> On 12/09/2011 05:26 AM, Kevin Wolf wrote:
>>>>> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>>>>>> This really shows the power of dynamic object properties compared to qdev
>>>>>> static properties.
>>>>>>
>>>>>> This property represents a complex structure who's format is preserved over the
>>>>>> wire.  This is enabled by visitors.
>>>>>>
>>>>>> It also shows an entirely synthetic property that is not tied to device state.
>>>>>>
>>>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>>>
>>>>> There's one thing that I was hoping to find answered when I would have
>>>>> reviewed the whole series, but it hasn't happened: There is no doubt
>>>>> that dynamic properties (in the sense of being able to modify them after
>>>>> constructions) are a useful thing. But you also claim that class-based
>>>>> properties are not enough for QOM and that we need object-based ones,
>>>>> which is a requirement not immediately obvious to me.
>>>>>
>>>>> Can you provide some examples where we would explicitly need
>>>>> object-based properties?
>>>>
>>>> Sure.  Any property that's dynamic needs to be object based.  A good example
>>>> would be PCI slots.
>>>>
>>>> Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be
>>>> desirable to eventually make this configurable.  So you can imagine where you
>>>> would have an 'slot-count' property and if that was set to 16, it would result
>>>> in 'slot[0]..slot[15]' being created.
>>>>
>>>> There are other good examples too.
>>>
>>> So is it mostly about variably sized arrays, which just happen to be
>>> considered independent properties in your approach? Or are there cases
>>> where a logically separate property may be there or missing depending on
>>> some condition, or possibly even that a new property is created during
>>> runtime?
>>
>> So there are three possibilities for properties:
>>
>> 1) Properties have no per-object state, and exist entirely within the classes.
>> This is what qdev does today.
>
> Not quite sure what you mean by per-object state. The properties are
> fields in the XyzState, so they certainly are per-object?

In qdev today, the objects have no state reflecting properties.  They properties 
refer to object state, but the objects have no knowledge of the properties 
themselves.

>
>> 2) Properties are defined in the class, but carry per-object state.
>>
>> 3) Properties are defined in the object and carry per-object state.
>>
>> We definitely can rule out (1).  Stateful properties are needed to implement
>> links, composition, and just about anything interesting.
>>
>> Another way that (3) is useful is that it allows you to create container devices
>> that more or less model a PCB.  That's how peripheral[-anon] is implemented and
>> I imagine that it will also be useful for implementing "machine" devices.
>
> What would this look like? The user creates new child/link properties on
> the board, and some more automatically created properties somehow
> describe the wiring between them?

The way I imagine this all working out is that a user creates does something 
like this:

(qemu) device_add driver=pc,id=pc
(qemu) qom_list /pc
/pc
   /i440fx
   /ide
     /ide1
       /drive[0]
   /net[0]
   /serial[0]

>
>> Of course, you could find a way to special case this with (2) but that's why I
>> ended up going with (3).  You can avoid having a lot of special cases this way.
>
> I'm not entirely convinced that we really need this, but on the other
> hand I don't feel strong enough about it to argue.
>
> Actually I think my real problem isn't about per-object properties
> (although they might add unnecessary complexity), but more about going
> away from the qdev style of things where you had _one_ struct definition
> that nicely described all of the properties in a central place. Instead,
> I'm seeing patches that spread property definitions all over the code.

There isn't one struct as bus properties get inherited, but I understand your 
point.  The problem with "legacy" properties isn't how they're express, it's 
that the mix parsing with the property types.  I have no problem with using 
DEFINE_ style properties and would expect that we would find a way to make the 
current properties have a string and non-string interface.

> Now I understand that for dynamically created properties (like on your
> PCB) this is necessary and can't be avoided. For about 99% of the
> devices static definition of properties would be enough, though.
>
> So basically what I'm asking for is getting the static structs back for
> the 99% and have common code that parses them and calls the appropriate
> functions to actually the properties. The remaining 1% that
> creates/deletes properties during runtime and isn't covered can directly
> call whatever it needs.

If you look at my qom-next branch, the static structs are still there for 99%er 
devices.  I have no immediate plans of removing them.

Regards,

Anthony Liguori

>
> Kevin
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-13  9:48             ` Gerd Hoffmann
@ 2011-12-13 13:33               ` Anthony Liguori
  0 siblings, 0 replies; 36+ messages in thread
From: Anthony Liguori @ 2011-12-13 13:33 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Kevin Wolf, Peter Maydell, Stefan Hajnoczi, Jan Kiszka,
	qemu-devel, Luiz Capitulino, Markus Armbruster

On 12/13/2011 03:48 AM, Gerd Hoffmann wrote:
>    Hi,
>
>> Now I understand that for dynamically created properties (like on your
>> PCB) this is necessary and can't be avoided. For about 99% of the
>> devices static definition of properties would be enough, though.
>>
>> So basically what I'm asking for is getting the static structs back for
>> the 99% and have common code that parses them and calls the appropriate
>> functions to actually the properties. The remaining 1% that
>> creates/deletes properties during runtime and isn't covered can directly
>> call whatever it needs.
>
> Fully agree.  I guess we can even generate those structs in many cases.
>   We will parse the ${device}State structs anyway for visitor-based
> vmstate, so with some extra declaration we can generate property
> descriptions too.  For example this ...
>
> static PCIDeviceInfo intel_hda_info = {
>      .qdev.name    = "intel-hda",
>      [ ... ]
>      .qdev.props   = (Property[]) {
>          DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
>          DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
>          DEFINE_PROP_END_OF_LIST(),
>      }
> };
>
> ... could be just ...
>
> struct IntelHDAState {
>      [ ... ]
>      /* properties */
>      uint32_t debug __property(0);
>      uint32_t msi   __property(1);
> };


Yup, that's where I want to go.  In qom-next, I've started splitting header 
files out specifically so we can do stuff like this.  There's quite a bit of 
work to do before we can really start exploring here but I think it's not that 
much work to get the pc device models cleaned up such that we could run qc 
against the headers.

Regards,

Anthony Liguori

>
> cheers,
>    Gerd
>
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date
  2011-12-13 13:31             ` Anthony Liguori
@ 2011-12-13 13:49               ` Kevin Wolf
  0 siblings, 0 replies; 36+ messages in thread
From: Kevin Wolf @ 2011-12-13 13:49 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Stefan Hajnoczi, Jan Kiszka, qemu-devel,
	Luiz Capitulino, Gerd Hoffman, Markus Armbruster

Am 13.12.2011 14:31, schrieb Anthony Liguori:
> On 12/13/2011 03:27 AM, Kevin Wolf wrote:
>> Am 09.12.2011 15:25, schrieb Anthony Liguori:
>>> On 12/09/2011 08:04 AM, Kevin Wolf wrote:
>>>> Am 09.12.2011 14:08, schrieb Anthony Liguori:
>>>>> On 12/09/2011 05:26 AM, Kevin Wolf wrote:
>>>>>> Am 02.12.2011 21:20, schrieb Anthony Liguori:
>>>>>>> This really shows the power of dynamic object properties compared to qdev
>>>>>>> static properties.
>>>>>>>
>>>>>>> This property represents a complex structure who's format is preserved over the
>>>>>>> wire.  This is enabled by visitors.
>>>>>>>
>>>>>>> It also shows an entirely synthetic property that is not tied to device state.
>>>>>>>
>>>>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>>>>
>>>>>> There's one thing that I was hoping to find answered when I would have
>>>>>> reviewed the whole series, but it hasn't happened: There is no doubt
>>>>>> that dynamic properties (in the sense of being able to modify them after
>>>>>> constructions) are a useful thing. But you also claim that class-based
>>>>>> properties are not enough for QOM and that we need object-based ones,
>>>>>> which is a requirement not immediately obvious to me.
>>>>>>
>>>>>> Can you provide some examples where we would explicitly need
>>>>>> object-based properties?
>>>>>
>>>>> Sure.  Any property that's dynamic needs to be object based.  A good example
>>>>> would be PCI slots.
>>>>>
>>>>> Today, we unconditionally advertise 32 slots in our ACPI tables.  It could be
>>>>> desirable to eventually make this configurable.  So you can imagine where you
>>>>> would have an 'slot-count' property and if that was set to 16, it would result
>>>>> in 'slot[0]..slot[15]' being created.
>>>>>
>>>>> There are other good examples too.
>>>>
>>>> So is it mostly about variably sized arrays, which just happen to be
>>>> considered independent properties in your approach? Or are there cases
>>>> where a logically separate property may be there or missing depending on
>>>> some condition, or possibly even that a new property is created during
>>>> runtime?
>>>
>>> So there are three possibilities for properties:
>>>
>>> 1) Properties have no per-object state, and exist entirely within the classes.
>>> This is what qdev does today.
>>
>> Not quite sure what you mean by per-object state. The properties are
>> fields in the XyzState, so they certainly are per-object?
> 
> In qdev today, the objects have no state reflecting properties.  They properties 
> refer to object state, but the objects have no knowledge of the properties 
> themselves.

You mean that an object doesn't have access to the property metadata? Or
what else would an object want to know about them?

>>> 2) Properties are defined in the class, but carry per-object state.
>>>
>>> 3) Properties are defined in the object and carry per-object state.
>>>
>>> We definitely can rule out (1).  Stateful properties are needed to implement
>>> links, composition, and just about anything interesting.
>>>
>>> Another way that (3) is useful is that it allows you to create container devices
>>> that more or less model a PCB.  That's how peripheral[-anon] is implemented and
>>> I imagine that it will also be useful for implementing "machine" devices.
>>
>> What would this look like? The user creates new child/link properties on
>> the board, and some more automatically created properties somehow
>> describe the wiring between them?
> 
> The way I imagine this all working out is that a user creates does something 
> like this:
> 
> (qemu) device_add driver=pc,id=pc
> (qemu) qom_list /pc
> /pc
>    /i440fx
>    /ide
>      /ide1
>        /drive[0]
>    /net[0]
>    /serial[0]

So you instantiated an object of the class pc, right? Which of the
properties qom_list shows is per-object rather than per-class?

>>> Of course, you could find a way to special case this with (2) but that's why I
>>> ended up going with (3).  You can avoid having a lot of special cases this way.
>>
>> I'm not entirely convinced that we really need this, but on the other
>> hand I don't feel strong enough about it to argue.
>>
>> Actually I think my real problem isn't about per-object properties
>> (although they might add unnecessary complexity), but more about going
>> away from the qdev style of things where you had _one_ struct definition
>> that nicely described all of the properties in a central place. Instead,
>> I'm seeing patches that spread property definitions all over the code.
> 
> There isn't one struct as bus properties get inherited, but I understand your 
> point.  The problem with "legacy" properties isn't how they're express, it's 
> that the mix parsing with the property types.  I have no problem with using 
> DEFINE_ style properties and would expect that we would find a way to make the 
> current properties have a string and non-string interface.
> 
>> Now I understand that for dynamically created properties (like on your
>> PCB) this is necessary and can't be avoided. For about 99% of the
>> devices static definition of properties would be enough, though.
>>
>> So basically what I'm asking for is getting the static structs back for
>> the 99% and have common code that parses them and calls the appropriate
>> functions to actually the properties. The remaining 1% that
>> creates/deletes properties during runtime and isn't covered can directly
>> call whatever it needs.
> 
> If you look at my qom-next branch, the static structs are still there for 99%er 
> devices.  I have no immediate plans of removing them.

Right, when looking at your serial examples, I saw that there are
actually some of them left. This first series doesn't have any of them.

I think the pattern may be that it's only children and links that are
spread across the code and "primitive types" generally still use the
declarative approach. Is there a reason not to include children/links
there as well?

I also think in the serial example there was quite some boilerplate code
related to such things, that could probably be common code for most
devices that can be described statically in tables. But I think I'll get
to that once you post these patches, maybe I'll understand the reasons
better by then.

Kevin

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2011-12-13 13:46 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-02 20:20 [Qemu-devel] [PATCH v2 00/18] qom: dynamic properties and composition tree (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 01/18] qom: add a reference count to qdev objects Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 02/18] qom: add new dynamic property infrastructure based on Visitors (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 03/18] qom: register legacy properties as new style properties (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 04/18] qom: introduce root device Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 05/18] qdev: provide an interface to return canonical path from root (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 06/18] qdev: provide a path resolution (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 07/18] qom: add child properties (composition) (v2) Anthony Liguori
2011-12-08 15:38   ` Kevin Wolf
2011-12-08 16:45     ` Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 08/18] qom: add link properties (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 09/18] qapi: allow a 'gen' key to suppress code generation Anthony Liguori
2011-12-08 16:04   ` Kevin Wolf
2011-12-08 16:45     ` Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 10/18] qmp: add qom-list command Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 11/18] qom: qom_{get, set} monitor commands (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 12/18] qdev: add explicitly named devices to the root complex Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 13/18] dev: add an anonymous peripheral container Anthony Liguori
2011-12-08 16:27   ` Kevin Wolf
2011-12-08 16:44     ` Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 14/18] rtc: make piix3 set the rtc as a child (v2) Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 15/18] rtc: add a dynamic property for retrieving the date Anthony Liguori
2011-12-09 11:26   ` Kevin Wolf
2011-12-09 13:08     ` Anthony Liguori
2011-12-09 14:04       ` Kevin Wolf
2011-12-09 14:25         ` Anthony Liguori
2011-12-13  9:27           ` Kevin Wolf
2011-12-13  9:48             ` Gerd Hoffmann
2011-12-13 13:33               ` Anthony Liguori
2011-12-13 13:31             ` Anthony Liguori
2011-12-13 13:49               ` Kevin Wolf
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 16/18] qom: optimize qdev_get_canonical_path using a parent link Anthony Liguori
2011-12-09 11:13   ` Kevin Wolf
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 17/18] qmp: make qmp.py easier to use Anthony Liguori
2011-12-02 20:20 ` [Qemu-devel] [PATCH v2 18/18] qom: add test tools (v2) Anthony Liguori
2011-12-09 11:19   ` Kevin Wolf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.