[virt-tools-list] [PATCH 29/47] Remove sections from hypervisor device list

Daniel P. Berrange berrange at redhat.com
Wed Aug 25 19:37:24 UTC 2010


Arranging devices in sections against hypervisors duplicates
information already available via the 'class' attribute on
the device object. Removing this unneccessary data simplifies
the code, allowing a pair of GTree maps to be replaced by
a single GList.

* data/libosinfo-dummy-data.xml: Remove hypervisor sections
* osinfo/osinfo_common.h, osinfo/osinfo_dataread.c,
  osinfo/osinfo_hypervisor.c, osinfo/osinfo_hypervisor.h: Model
  hypervisor devices in a GList instead of pair of GTrees
---
 data/libosinfo-dummy-data.xml |   20 ++++-------
 osinfo/osinfo_common.h        |    6 +--
 osinfo/osinfo_dataread.c      |   60 ++++++++++++++++++---------------
 osinfo/osinfo_hypervisor.c    |   73 ++++++++++++++++-------------------------
 osinfo/osinfo_hypervisor.h    |    5 ++-
 5 files changed, 74 insertions(+), 90 deletions(-)

diff --git a/data/libosinfo-dummy-data.xml b/data/libosinfo-dummy-data.xml
index 288f395..602b122 100644
--- a/data/libosinfo-dummy-data.xml
+++ b/data/libosinfo-dummy-data.xml
@@ -45,26 +45,22 @@
   <updates-version>0.10.0</updates-version>
   <updates-version>0.9.0</updates-version>
   <updates-version>0.8.0</updates-version>
-  <section type="audio">
-      <device id="http://pci-ids.ucw.cz/read/PC/1002/4382" />
-      <device id="http://pci-ids.ucw.cz/read/PC/1274/5000" />
-      <device id="http://pci-ids.ucw.cz/read/PC/1274/1371/80864541" />
-  </section>
-  <section type="network">
-      <device id="http://pci-ids.ucw.cz/read/PC/a727/0013" />
-  </section>
+  <devices>
+    <device id="http://pci-ids.ucw.cz/read/PC/1002/4382" />
+    <device id="http://pci-ids.ucw.cz/read/PC/1274/5000" />
+    <device id="http://pci-ids.ucw.cz/read/PC/1274/1371/80864541" />
+    <device id="http://pci-ids.ucw.cz/read/PC/a727/0013" />
+  </devices>
 </hypervisor>
 
 <hypervisor id="http://bits.xensource.com/oss-xen/release/3.4.1">
   <name>Xen</name>
   <version>3.4.1</version>
-  <section type="audio">
+  <devices>
       <device id="http://pci-ids.ucw.cz/read/PC/1002/4382" />
       <device id="http://pci-ids.ucw.cz/read/PC/1274/1371/80864541" />
-  </section>
-  <section type="network">
       <device id="http://pci-ids.ucw.cz/read/PC/a727/0013" />
-  </section>
+  </devices>
 </hypervisor>
 
 <os id="http://fedoraproject.org/fedora-11">
diff --git a/osinfo/osinfo_common.h b/osinfo/osinfo_common.h
index 779ec89..81444f6 100644
--- a/osinfo/osinfo_common.h
+++ b/osinfo/osinfo_common.h
@@ -102,10 +102,8 @@ void osinfo_dup_array(gpointer data, gpointer user_data);
 
 struct _OsinfoHypervisorPrivate
 {
-    // Key: gchar* (device type)
-    // Value: Tree of device_link structs (multiple devices per type)
-    GTree *sections;
-    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
+    // Value: List of device_link structs
+    GList *deviceLinks;
 };
 
 struct _OsinfoOsPrivate
diff --git a/osinfo/osinfo_dataread.c b/osinfo/osinfo_dataread.c
index 2618313..f4e6df3 100644
--- a/osinfo/osinfo_dataread.c
+++ b/osinfo/osinfo_dataread.c
@@ -136,31 +136,13 @@ static gboolean __osinfoFixOsLinks(OsinfoList *list, OsinfoEntity *entity, gpoin
     return FALSE;
 }
 
-static gboolean __osinfoFixHvLinks(OsinfoList *list, OsinfoEntity *entity, gpointer data)
-{
-    g_return_val_if_fail(OSINFO_HYPERVISOR(entity), TRUE);
-
-    struct __osinfoDbRet *dbRet = data;
-    OsinfoHypervisor *hv = OSINFO_HYPERVISOR(entity);
-
-    g_tree_foreach(hv->priv->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*dbRet->err)
-        return TRUE;
-    return FALSE;
-}
-
 static void __osinfoFixObjLinks(OsinfoDb *db, GError **err)
 {
     g_return_if_fail(OSINFO_IS_DB(db));
 
     struct __osinfoDbRet dbRet = {db, err };
-    OsinfoHypervisorList *hypervisors = osinfo_db_get_hypervisor_list(db);
     OsinfoOsList *oses = osinfo_db_get_os_list(db);
 
-    osinfo_list_foreach(OSINFO_LIST(hypervisors), __osinfoFixHvLinks, &dbRet);
-    if (*dbRet.err)
-        return;
-
     osinfo_list_foreach(OSINFO_LIST(oses), __osinfoFixOsLinks, &dbRet);
 }
 
@@ -532,8 +514,8 @@ static int __osinfoProcessHypervisor(OsinfoDb *db,
      */
 
     int empty, node_type, err, ret;
-    gchar* id;
-    const gchar * name;
+    gchar *id, *key, *driver;
+    const gchar *name;
     OsinfoHypervisor *hv;
     OsinfoHypervisorList *hypervisors = osinfo_db_get_hypervisor_list(db);
 
@@ -594,13 +576,37 @@ static int __osinfoProcessHypervisor(OsinfoDb *db,
         if (node_type != ELEMENT_NODE)
             continue;
 
-        if (strcmp(name, "section") == 0) {
-            /* Node is start of device section for hv */
-            err = __osinfoProcessDevSection(reader, (OSINFO_HYPERVISOR(hv))->priv->sections, (OSINFO_HYPERVISOR(hv))->priv->sectionsAsList);
-            if (err != 0)
-                goto cleanup_error;
-        }
-        else {
+        /* Element within section needs to be of type device */
+        if (strcmp(name, "device") == 0) {
+	    id = (gchar *)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
+	    empty = xmlTextReaderIsEmptyElement(reader);
+
+	    if (!id) {
+	      fprintf(stderr, "no id\n");
+	        err = -EINVAL;
+		goto cleanup_error;
+	    }
+
+	    if (!empty) {
+	        err = __osinfoProcessTag(reader, &key, &driver);
+		if (err != 0 || !key || !driver)
+		    goto cleanup_error;
+		free(key);
+		key = NULL; /* In case the next malloc fails, avoid a double free */
+	    }
+
+	    // Alright, we have the id and driver
+	    OsinfoDevice *dev = osinfo_db_get_device(db, id);
+	    if (!dev) {
+	        err = -ENOENT;
+		goto cleanup_error;
+	    }
+	    osinfo_hypervisor_add_device(hv, dev, driver);
+	    free (driver);
+	    driver = NULL;
+	    free (id);
+	    id = NULL;
+        } else {
             /* Node is start of element of known name */
             char *key = NULL, *val = NULL;
             err = __osinfoProcessTag(reader, &key, &val);
diff --git a/osinfo/osinfo_hypervisor.c b/osinfo/osinfo_hypervisor.c
index 06dc2ae..d58e704 100644
--- a/osinfo/osinfo_hypervisor.c
+++ b/osinfo/osinfo_hypervisor.c
@@ -6,13 +6,18 @@ G_DEFINE_TYPE (OsinfoHypervisor, osinfo_hypervisor, OSINFO_TYPE_ENTITY);
 
 static void osinfo_hypervisor_finalize (GObject *object);
 
+static void osinfo_device_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED)
+{
+    __osinfoFreeDeviceLink(data);
+}
+
 static void
 osinfo_hypervisor_finalize (GObject *object)
 {
     OsinfoHypervisor *self = OSINFO_HYPERVISOR (object);
 
-    g_tree_destroy (self->priv->sections);
-    g_tree_destroy (self->priv->sectionsAsList);
+    g_list_foreach(self->priv->deviceLinks, osinfo_device_link_free, NULL);
+    g_list_free(self->priv->deviceLinks);
 
     /* Chain up to the parent class */
     G_OBJECT_CLASS (osinfo_hypervisor_parent_class)->finalize (object);
@@ -34,8 +39,7 @@ osinfo_hypervisor_init (OsinfoHypervisor *self)
     OsinfoHypervisorPrivate *priv;
     self->priv = priv = OSINFO_HYPERVISOR_GET_PRIVATE(self);
 
-    self->priv->sections = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceSection);
-    self->priv->sectionsAsList = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreePtrArray);
+    self->priv->deviceLinks = NULL;
 }
 
 OsinfoHypervisor *osinfo_hypervisor_new(const gchar *id)
@@ -46,56 +50,35 @@ OsinfoHypervisor *osinfo_hypervisor_new(const gchar *id)
 }
 
 
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver)
-{
-    if( !OSINFO_IS_HYPERVISOR(self) || !section || !id || !driver)
-        return -EINVAL;
-
-    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section)
+OsinfoDeviceList *osinfo_hypervisor_get_devices(OsinfoHypervisor *self, OsinfoFilter *filter)
 {
-    if (!OSINFO_IS_HYPERVISOR(self) || !section)
-        return;
+    g_return_val_if_fail(OSINFO_IS_HYPERVISOR(self), NULL);
+    g_return_val_if_fail(OSINFO_IS_FILTER(filter), NULL);
 
-    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
+    OsinfoDeviceList *newList = osinfo_devicelist_new();
+    GList *tmp = self->priv->deviceLinks;
 
-GPtrArray *osinfo_hypervisor_get_device_types(OsinfoHypervisor *self)
-{
-    g_return_val_if_fail(OSINFO_IS_HYPERVISOR(self), NULL);
+    while (tmp) {
+        struct __osinfoDeviceLink *link = tmp->data;
 
-    GPtrArray *deviceTypes = g_ptr_array_sized_new(g_tree_nnodes(self->priv->sections));
+        if (osinfo_entity_matches_filter(OSINFO_ENTITY(link->dev), filter))
+	    osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(link->dev));
+    }
 
-    // For each key in our tree of device sections, dup and add to the array
-    g_tree_foreach(self->priv->sections, osinfo_get_keys, deviceTypes);
-    return deviceTypes;
+    return newList;
 }
 
-OsinfoDeviceList *osinfo_hypervisor_get_devices_by_type(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter)
+void osinfo_hypervisor_add_device(OsinfoHypervisor *self, OsinfoDevice *dev, const gchar *driver)
 {
-    g_return_val_if_fail(OSINFO_IS_HYPERVISOR(self), NULL);
-    g_return_val_if_fail(OSINFO_IS_FILTER(filter), NULL);
-    g_return_val_if_fail(devType != NULL, NULL);
+    g_return_if_fail(OSINFO_IS_HYPERVISOR(self));
+    g_return_if_fail(OSINFO_IS_DEVICE(dev));
+    g_return_if_fail(driver != NULL);
 
-    // Create our device list
-    OsinfoDeviceList *newList = osinfo_devicelist_new();
+    struct __osinfoDeviceLink *link = g_new0(struct __osinfoDeviceLink, 1);
 
-    // If section does not exist, return empty list
-    GPtrArray *sectionList = NULL;
-    sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-    if (!sectionList)
-        return newList;
-
-    // For each device in section list, apply filter. If filter passes, add device to list.
-    int i;
-    struct __osinfoDeviceLink *deviceLink;
-    for (i = 0; i < sectionList->len; i++) {
-        deviceLink = g_ptr_array_index(sectionList, i);
-        if (osinfo_entity_matches_filter(OSINFO_ENTITY(deviceLink->dev), filter))
-	    osinfo_list_add(OSINFO_LIST (newList), OSINFO_ENTITY (deviceLink->dev));
-    }
+    g_object_ref(dev);
+    link->dev = dev;
+    link->driver = g_strdup(driver);
 
-    return newList;
+    self->priv->deviceLinks = g_list_prepend(self->priv->deviceLinks, link);
 }
diff --git a/osinfo/osinfo_hypervisor.h b/osinfo/osinfo_hypervisor.h
index d8f893f..15f45cc 100644
--- a/osinfo/osinfo_hypervisor.h
+++ b/osinfo/osinfo_hypervisor.h
@@ -50,7 +50,8 @@ GType osinfo_hypervisor_get_type(void);
 
 OsinfoHypervisor *osinfo_hypervisor_new(const gchar *id);
 
-GPtrArray *osinfo_hypervisor_get_device_types(OsinfoHypervisor *self);
-OsinfoDeviceList *osinfo_hypervisor_get_devices_by_type(OsinfoHypervisor *self, gchar *devType, OsinfoFilter *filter);
+OsinfoDeviceList *osinfo_hypervisor_get_devices(OsinfoHypervisor *hv, OsinfoFilter *filter);
+
+void osinfo_hypervisor_add_device(OsinfoHypervisor *hv, OsinfoDevice *dev, const gchar *driver);
 
 #endif /* __OSINFO_HYPERVISOR_H__ */
-- 
1.7.2.1




More information about the virt-tools-list mailing list