[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]