[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/18] qdev: provide a path resolution
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] [PATCH 05/18] qdev: provide a path resolution |
Date: |
Wed, 30 Nov 2011 15:03:35 -0600 |
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 <address@hidden>
---
hw/qdev.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 28 +++++++++++++++++
2 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index 6b2b194..5bffbb7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1204,3 +1204,103 @@ 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;
+ GSList *i;
+
+ dev = qdev_resolve_abs_path(parent, parts, 0);
+
+ for (i = parent->properties; i; i = i->next) {
+ DeviceProperty *prop = i->data;
+ 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) {
+ return qdev_get_root();
+ }
+
+ if (strcmp(parts[0], "") == 0) {
+ partial_path = false;
+ }
+
+ if (partial_path) {
+ 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 82e6d95..b8b62f5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -471,4 +471,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
prefix
+ * 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
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.
+ */
+DeviceState *qdev_resolve_path(const char *path, bool *ambiguous);
+
#endif
--
1.7.4.1
- [Qemu-devel] [PATCH 00/18] qom: dynamic properties and composition tree, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 03/18] qom: introduce root device, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 04/18] qdev: provide an interface to return canonical path from root, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 05/18] qdev: provide a path resolution,
Anthony Liguori <=
- [Qemu-devel] [PATCH 01/18] qom: add new dynamic property infrastructure based on Visitors, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 07/18] qom: add link properties, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 06/18] qom: add child properties (composition), Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 02/18] qom: register legacy properties as new style properties, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 08/18] qapi: allow a 'gen' key to suppress code generation, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 10/18] qom: qom_{get,set} monitor commands, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 11/18] qdev: add explicitly named devices to the root complex, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 17/18] Add test tools, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 16/18] Make qmp.py easier to use, Anthony Liguori, 2011/11/30
- [Qemu-devel] [PATCH 18/18] qdev: split out QOM functions to separate files, Anthony Liguori, 2011/11/30