[virt-tools-list] [PATCH 30/47] Remove sections from OS device list

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


Arranging devices in sections against operating systems 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 os sections
* osinfo/osinfo_common.h, osinfo/osinfo_dataread.c,
  osinfo/osinfo_os.c, osinfo/osinfo_os.h: Model
  hypervisor devices in a GList instead of pair of GTrees
* osinfo/osinfo_device.c, osinfo/osinfo_device.h,
  osinfo/osinfo_hypervisor.c: Update for API changes
---
 data/libosinfo-dummy-data.xml |   20 ++--
 osinfo/osinfo_common.c        |   70 -------------
 osinfo/osinfo_common.h        |   32 +------
 osinfo/osinfo_dataread.c      |  225 ++++++++++++-----------------------------
 osinfo/osinfo_device.c        |   38 -------
 osinfo/osinfo_device.h        |    2 -
 osinfo/osinfo_hypervisor.c    |    2 +
 osinfo/osinfo_os.c            |  201 +++++++++++++-----------------------
 osinfo/osinfo_os.h            |    8 +-
 9 files changed, 158 insertions(+), 440 deletions(-)

diff --git a/data/libosinfo-dummy-data.xml b/data/libosinfo-dummy-data.xml
index 602b122..8c8f2e3 100644
--- a/data/libosinfo-dummy-data.xml
+++ b/data/libosinfo-dummy-data.xml
@@ -71,21 +71,19 @@
   <vendor>Red Hat</vendor>
 
   <hypervisor id="http://qemu.org/qemu-kvm-0.11.0">
-      <section type="audio">
+      <devices>
           <device id="http://pci-ids.ucw.cz/read/PC/1274/5000">es1370</device>
           <device id="http://pci-ids.ucw.cz/read/PC/1002/4382">ac97</device>
           <device id="http://pci-ids.ucw.cz/read/PC/1274/1371/80864541">es1371</device>
-      </section>
-      <section type="network">
           <device id="http://pci-ids.ucw.cz/read/PC/a727/0013">3com</device>
-      </section>
+      </devices>
   </hypervisor>
 
   <!-- Device support for unspecified hypervisor -->
-  <section type="audio">
+  <devices>
     <device id="http://pci-ids.ucw.cz/read/PC/1002/4382">es1391</device>
     <device id="http://pci-ids.ucw.cz/read/PC/1274/5000">ac97+</device>
-  </section>
+  </devices>
 </os>
 
 <os id="http://fedoraproject.org/fedora-10">
@@ -94,20 +92,18 @@
   <vendor>Fedora Project</vendor>
 
   <hypervisor id="http://qemu.org/qemu-kvm-0.11.0">
-      <section type="audio">
+      <devices>
           <device id="http://pci-ids.ucw.cz/read/PC/1002/4382">ac97</device>
           <device id="http://pci-ids.ucw.cz/read/PC/1274/5000">ES1370</device>
-      </section>
-      <section type="network">
           <device id="http://pci-ids.ucw.cz/read/PC/a727/0013">3com</device>
-      </section>
+      </devices>
   </hypervisor>
 
   <!-- Device support for unspecified hypervisor -->
-  <section type="audio">
+  <devices>
     <device id="http://pci-ids.ucw.cz/read/PC/1274/5000">ac97</device>
     <device id="http://pci-ids.ucw.cz/read/PC/1002/4382">es1391</device>
-  </section>
+  </devices>
 </os>
 
 <os id="http://software.opensuse.org/112">
diff --git a/osinfo/osinfo_common.c b/osinfo/osinfo_common.c
index 3db1073..1e3e3b3 100644
--- a/osinfo/osinfo_common.c
+++ b/osinfo/osinfo_common.c
@@ -1,75 +1,5 @@
 #include <osinfo/osinfo.h>
 
-static int __osinfoAddDeviceToList(GTree *allSectionsAsList,
-                                   gchar *sectionName,
-                                   struct __osinfoDeviceLink *deviceLink)
-{
-    if (!allSectionsAsList || !sectionName || !deviceLink)
-        return -EINVAL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    GPtrArray *sectionList;
-    gchar *sectionNameDup = NULL;
-
-    found = g_tree_lookup_extended(allSectionsAsList, sectionName, &origKey, &foundValue);
-    if (!found) {
-        sectionList = g_ptr_array_new();
-        sectionNameDup = g_strdup(sectionName);
-        g_tree_insert(allSectionsAsList, sectionNameDup, sectionList);
-    }
-    else
-        sectionList = (GPtrArray *) foundValue;
-
-    g_ptr_array_add(sectionList, deviceLink);
-    return 0;
-}
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver)
-{
-    if (!allSections || !sectionName || !id)
-        return -EINVAL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    gchar *sectionNameDup = NULL, *idDup = NULL, *driverDup = NULL;
-    GTree *section;
-    struct __osinfoDeviceLink *deviceLink;
-    int ret;
-
-    idDup = g_strdup(id);
-    driverDup = g_strdup(driver);
-    deviceLink = g_new0(struct __osinfoDeviceLink, 1);
-
-    found = g_tree_lookup_extended(allSections, sectionName, &origKey, &foundValue);
-    if (!found) {
-        section = g_tree_new_full(__osinfoStringCompare, NULL, g_free, __osinfoFreeDeviceLink);
-        sectionNameDup = g_strdup(sectionName);
-
-        g_tree_insert(allSections, sectionNameDup, section);
-    }
-    else
-        section = (GTree *) foundValue;
-
-    deviceLink->driver = driverDup;
-    g_tree_insert(section, idDup, deviceLink);
-
-    ret = 0;
-    if (allSectionsAsList)
-        ret = __osinfoAddDeviceToList(allSectionsAsList, sectionName, deviceLink);
-
-    return ret;
-}
-
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section)
-{
-    if (!allSections || !section)
-        return;
-
-    g_tree_remove(allSections, section);
-    g_tree_remove(allSectionsAsList, section);
-}
-
 void __osinfoFreeDeviceLink(gpointer ptr)
 {
     if (!ptr)
diff --git a/osinfo/osinfo_common.h b/osinfo/osinfo_common.h
index 81444f6..c660a73 100644
--- a/osinfo/osinfo_common.h
+++ b/osinfo/osinfo_common.h
@@ -41,14 +41,6 @@ struct __osinfoDeviceLink {
     gchar *driver;
 };
 
-struct __osinfoHvSection {
-    OsinfoHypervisor *hv;
-    OsinfoOs *os;
-
-    GTree *sections; // Mapping GString key (device type) to GTree of deviceLink structs
-    GTree *sectionsAsList; // Mapping GString key (device type) to Array of deviceLink structs
-};
-
 struct __osinfoOsLink {
     /* <subject_os> 'verbs' <direct_object_os>
      * fedora11 upgrades fedora10
@@ -88,11 +80,6 @@ void __osinfoFreeDeviceSection(gpointer tree);
 void __osinfoFreeDeviceLink(gpointer ptr);
 void __osinfoFreeOsLink(gpointer ptr);
 
-void __osinfoListAdd(OsinfoList *self, OsinfoEntity *entity);
-
-int __osinfoAddDeviceToSection(GTree *allSections, GTree *allSectionsAsList, gchar *sectionName, gchar *id, gchar *driver);
-void __osinfoClearDeviceSection(GTree *allSections, GTree *allSectionsAsList, gchar *section);
-
 gboolean osinfo_get_keys(gpointer key, gpointer value, gpointer data);
 void osinfo_dup_array(gpointer data, gpointer user_data);
 
@@ -110,13 +97,11 @@ struct _OsinfoOsPrivate
 {
     // OS-Hypervisor specific information
     // Key: gchar* (hypervisor id)
-    // Value: __osinfoHvSection struct
+    // Value: GList: Element Value: List of device_link structs
     GHashTable *hypervisors;
 
-    // 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;
 
     // OS-OS relationships
     // Key: gchar* (other os id)
@@ -140,18 +125,7 @@ struct _OsinfoEntityPrivate
  *      Private Methods
  ******************************************************************************/
 
-// Private
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section);
-
 int __osinfoAddOsRelationship (OsinfoOs *self, gchar *otherOsId, osinfoRelationship rel);
 void __osinfoClearOsRelationships (OsinfoOs *self, gchar *otherOsId);
 
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId);
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId);
-
-// Private
-int __osinfoAddDeviceToSectionHv(OsinfoHypervisor *self, gchar *section, gchar *id, gchar *driver);
-void __osinfoClearDeviceSectionHv(OsinfoHypervisor *self, gchar *section);
-
 #endif /* __OSINFO_OBJECTS_H__ */
diff --git a/osinfo/osinfo_dataread.c b/osinfo/osinfo_dataread.c
index f4e6df3..9d92c49 100644
--- a/osinfo/osinfo_dataread.c
+++ b/osinfo/osinfo_dataread.c
@@ -42,58 +42,6 @@ struct __osinfoDbRet {
 #define OSINFO_ERROR(err, msg) \
   g_set_error_literal((err), g_quark_from_static_string("libosinfo"), 0, (msg));
 
-static gboolean __osinfoResolveDeviceLink(gpointer key, gpointer value, gpointer data)
-{
-    gchar *id = (gchar *) key;
-    struct __osinfoDeviceLink *devLink = (struct __osinfoDeviceLink *) value;
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    OsinfoDeviceList *devices = osinfo_db_get_device_list(db);
-
-    OsinfoDevice *dev = OSINFO_DEVICE(osinfo_list_find_by_id(OSINFO_LIST(devices), id));
-    if (!dev) {
-        OSINFO_ERROR(dbRet->err, "missing device");
-	return TRUE;
-    }
-
-    devLink->dev = dev;
-    return FALSE;
-}
-
-static gboolean __osinfoResolveSectionDevices(gpointer key, gpointer value, gpointer data)
-{
-    g_return_val_if_fail(value != NULL, TRUE);
-
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    GTree *section = value;
-
-    g_tree_foreach(section, __osinfoResolveDeviceLink, dbRet);
-    if (*dbRet->err)
-        return TRUE;
-    return FALSE;
-}
-
-static void __osinfoResolveHvLink(gpointer key, gpointer value, gpointer data)
-{
-    gchar *hvId = (gchar *) key;
-    struct __osinfoDbRet *dbRet = (struct __osinfoDbRet *) data;
-    OsinfoDb *db = dbRet->db;
-    struct __osinfoHvSection *hvSection = (struct __osinfoHvSection *) value;
-    OsinfoHypervisor *hv;
-    OsinfoHypervisorList *hypervisors = osinfo_db_get_hypervisor_list(db);
-
-    g_tree_foreach(hvSection->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*dbRet->err)
-        return;
-
-    hv = OSINFO_HYPERVISOR(osinfo_list_find_by_id(OSINFO_LIST(hypervisors), hvId));
-    if (!hv) {
-        OSINFO_ERROR(dbRet->err, "missing hypervisor");
-        return;
-    }
-
-    hvSection->hv = hv;
-}
 
 static gboolean __osinfoResolveOsLink(gpointer key, gpointer value, gpointer data)
 {
@@ -121,18 +69,10 @@ static gboolean __osinfoFixOsLinks(OsinfoList *list, OsinfoEntity *entity, gpoin
     struct __osinfoDbRet *dbRet = data;
     OsinfoOs *os = OSINFO_OS(entity);
 
-    g_tree_foreach(os->priv->sections, __osinfoResolveSectionDevices, dbRet);
-    if (*dbRet->err)
-        return TRUE;
-
     g_tree_foreach(os->priv->relationshipsByOs, __osinfoResolveOsLink, dbRet);
     if (*dbRet->err)
         return TRUE;
 
-    g_hash_table_foreach(os->priv->hypervisors, __osinfoResolveHvLink, dbRet);
-    if (*dbRet->err)
-        return TRUE;
-
     return FALSE;
 }
 
@@ -205,89 +145,9 @@ error:
     return err;
 }
 
-static int __osinfoProcessDevSection(xmlTextReaderPtr reader,
-                                     GTree *section, GTree *sectionAsList)
-{
-    int err, empty, node_type;
-    gchar * sectionType, * id, * key = NULL, * driver = NULL;
-    const gchar * name;
-
-    if (!section)
-        return -EINVAL;
-
-    sectionType = (gchar *)xmlTextReaderGetAttribute(reader, BAD_CAST "type");
-    empty = xmlTextReaderIsEmptyElement(reader);
-
-    if (!sectionType)
-        return -EINVAL;
-
-    /* If no devices in section then we are done */
-    if (empty)
-        return 0;
-
-    /* Otherwise, read in devices and add to section */
-    for (;;) {
-        /* Advance to next node */
-        err = xmlTextReaderRead(reader);
-        if (err != 1) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        node_type = xmlTextReaderNodeType(reader);
-        name = (const gchar *)xmlTextReaderConstName(reader);
-
-        /* If end of section, break */
-        if (node_type == END_NODE && strcmp(name, "section") == 0)
-            break;
-
-        /* If node is not start of an element, continue */
-        if (node_type != ELEMENT_NODE)
-            continue;
-
-        /* Element within section needs to be of type device */
-        if (strcmp(name, "device") != 0) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        id = (gchar *)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
-        empty = xmlTextReaderIsEmptyElement(reader);
-
-        if (!id) {
-            err = -EINVAL;
-            goto error;
-        }
-
-        if (!empty) {
-            err = __osinfoProcessTag(reader, &key, &driver);
-            if (err != 0 || !key || !driver)
-                goto error;
-            free(key);
-            key = NULL; /* In case the next malloc fails, avoid a double free */
-        }
-
-        // Alright, we have the id and driver
-        err = __osinfoAddDeviceToSection(section, sectionAsList, sectionType, id, driver);
-        free (driver);
-        driver = NULL;
-        free (id);
-        id = NULL;
-        if (err != 0)
-            goto error;
-    }
-    free(sectionType);
-
-    return 0;
-
-error:
-    free(sectionType);
-    free(key);
-    free(driver);
-    return err;
-}
 
 static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
+				   OsinfoDb *db,
                                    OsinfoOs *os)
 {
     /*
@@ -302,9 +162,9 @@ static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
      * On success add hv_link to os
      */
     int empty, node_type, err;
-    char* id;
+    char *id, *key, *driver;
     const gchar* name;
-    struct __osinfoHvSection *hvSection;
+    OsinfoHypervisor *hv;
 
     id = (gchar *)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
     empty = xmlTextReaderIsEmptyElement(reader);
@@ -312,9 +172,8 @@ static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
     if (!id)
         return -EINVAL;
 
-    hvSection = __osinfoAddHypervisorSectionToOs(os, id);
-    free(id);
-    if (!hvSection)
+    hv = osinfo_db_get_hypervisor(db, id);
+    if (!hv)
         return -EINVAL;
 
     if (empty)
@@ -343,16 +202,40 @@ static int __osinfoProcessOsHvLink(xmlTextReaderPtr reader,
         if (node_type != ELEMENT_NODE)
             continue;
 
-        /* Ensure it is element node of type 'section' else fail */
-        if (strcmp(name, "section") != 0) {
+        /* Ensure it is element node of type 'device' else fail */
+        if (strcmp(name, "device") != 0) {
             err = -EINVAL;
             goto error;
         }
 
-        /* Process device type info for this <os, hv> combination */
-        err = __osinfoProcessDevSection(reader, hvSection->sections, hvSection->sectionsAsList);
-        if (err != 0)
-            goto error;
+	id = (gchar *)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
+	empty = xmlTextReaderIsEmptyElement(reader);
+
+	if (!id) {
+	    fprintf(stderr, "no id\n");
+	    err = -EINVAL;
+	    goto error;
+	}
+
+	if (!empty) {
+	    err = __osinfoProcessTag(reader, &key, &driver);
+	    if (err != 0 || !key || !driver)
+	        goto 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 error;
+	}
+	osinfo_os_add_device(os, hv, dev, driver);
+	free (driver);
+	driver = NULL;
+	free (id);
+	id = NULL;
     }
 
 finished:
@@ -394,7 +277,7 @@ static int __osinfoProcessOs(OsinfoDb *db,
      */
 
     int empty, node_type, err, ret;
-    gchar* id, * key = NULL, * val = NULL;
+    gchar* id, * key = NULL, * val = NULL, *driver;
     const gchar* name;
     OsinfoOs *os;
     OsinfoOsList *oses = osinfo_db_get_os_list(db);
@@ -448,14 +331,38 @@ static int __osinfoProcessOs(OsinfoDb *db,
         if (node_type != ELEMENT_NODE)
             continue;
 
-        if (strcmp(name, "section") == 0) {
-            /* Node is start of device section for os */
-            err = __osinfoProcessDevSection(reader, (OSINFO_OS(os))->priv->sections, (OSINFO_OS(os))->priv->sectionsAsList);
-            if (err != 0)
-                goto cleanup_error;
+        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_os_add_device(os, NULL, dev, driver);
+	    free (driver);
+	    driver = NULL;
+	    free (id);
+	    id = NULL;
         }
         else if (strcmp(name, "hypervisor") == 0) {
-            err = __osinfoProcessOsHvLink(reader, os);
+	    err = __osinfoProcessOsHvLink(reader, db, os);
             if (err != 0)
                 goto cleanup_error;
         }
diff --git a/osinfo/osinfo_device.c b/osinfo/osinfo_device.c
index b7d4cd5..0384064 100644
--- a/osinfo/osinfo_device.c
+++ b/osinfo/osinfo_device.c
@@ -42,41 +42,3 @@ OsinfoDevice *osinfo_device_new(const gchar *id)
 			"id", id,
 			NULL);
 }
-
-gchar *osinfo_device_get_driver(OsinfoDevice *self,
-				gchar *devType,
-				OsinfoOs *os,
-				OsinfoHypervisor *hv)
-{
-    g_return_val_if_fail(OSINFO_IS_DEVICE(self), NULL);
-    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
-    g_return_val_if_fail(OSINFO_IS_HYPERVISOR(hv), NULL);
-    g_return_val_if_fail(devType != NULL, NULL);
-
-    gchar *driver = NULL;
-
-    // For os, get hypervisor specific info. If not present, return NULL.
-    struct __osinfoHvSection *hvSection = NULL;
-    hvSection = g_hash_table_lookup(os->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-    if (!hvSection)
-        return NULL;
-
-    // Check for info for type of devices in <os,hv>. If not found, return NULL.
-    GTree *section = NULL;
-    section = g_tree_lookup(hvSection->sections, devType);
-    if (!section)
-        return NULL;
-
-    // Check device section for device. If not found, return NULL.
-    struct __osinfoDeviceLink *deviceLink = NULL;
-    deviceLink = g_tree_lookup(section, (OSINFO_ENTITY(self))->priv->id);
-    if (!deviceLink)
-        return NULL;
-
-    if (!deviceLink->driver)
-        return NULL;
-
-    driver = g_strdup(deviceLink->driver);
-
-    return driver;
-}
diff --git a/osinfo/osinfo_device.h b/osinfo/osinfo_device.h
index cdd8fc3..555950a 100644
--- a/osinfo/osinfo_device.h
+++ b/osinfo/osinfo_device.h
@@ -48,6 +48,4 @@ GType osinfo_device_get_type(void);
 
 OsinfoDevice *osinfo_device_new(const gchar *id);
 
-gchar *osinfo_device_get_driver(OsinfoDevice *self, gchar *devType, OsinfoOs *os, OsinfoHypervisor *hv);
-
 #endif /* __OSINFO_DEVICE_H__ */
diff --git a/osinfo/osinfo_hypervisor.c b/osinfo/osinfo_hypervisor.c
index d58e704..3f20b56 100644
--- a/osinfo/osinfo_hypervisor.c
+++ b/osinfo/osinfo_hypervisor.c
@@ -63,6 +63,8 @@ OsinfoDeviceList *osinfo_hypervisor_get_devices(OsinfoHypervisor *self, OsinfoFi
 
         if (osinfo_entity_matches_filter(OSINFO_ENTITY(link->dev), filter))
 	    osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(link->dev));
+
+	tmp = tmp->next;
     }
 
     return newList;
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index 8cf4615..dc27c6d 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -6,13 +6,19 @@ G_DEFINE_TYPE (OsinfoOs, osinfo_os, OSINFO_TYPE_ENTITY);
 
 static void osinfo_os_finalize (GObject *object);
 
+static void osinfo_device_link_free(gpointer data, gpointer opaque G_GNUC_UNUSED)
+{
+    __osinfoFreeDeviceLink(data);
+}
+
+
 static void
 osinfo_os_finalize (GObject *object)
 {
     OsinfoOs *self = OSINFO_OS (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);
     g_hash_table_unref(self->priv->hypervisors);
     g_tree_destroy (self->priv->relationshipsByOs);
     g_tree_destroy (self->priv->relationshipsByType);
@@ -31,14 +37,13 @@ osinfo_os_class_init (OsinfoOsClass *klass)
     g_type_class_add_private (klass, sizeof (OsinfoOsPrivate));
 }
 
-static void osinfo_hv_section_free(gpointer value)
+static void
+osinfo_os_hypervisor_devices_free(gpointer opaque)
 {
-    struct __osinfoHvSection * hvSection = value;
-    if (!hvSection)
-        return;
-    g_tree_destroy(hvSection->sections);
-    g_tree_destroy(hvSection->sectionsAsList);
-    g_free(hvSection);
+    GList *deviceLinks = opaque;
+
+    g_list_foreach(deviceLinks, osinfo_device_link_free, NULL);
+    g_list_free(deviceLinks);
 }
 
 static void
@@ -47,15 +52,7 @@ osinfo_os_init (OsinfoOs *self)
     OsinfoOsPrivate *priv;
     self->priv = priv = OSINFO_OS_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;
 
     self->priv->relationshipsByOs = g_tree_new_full(__osinfoStringCompare,
                                                 NULL,
@@ -66,7 +63,7 @@ osinfo_os_init (OsinfoOs *self)
     self->priv->hypervisors = g_hash_table_new_full(g_str_hash,
 						    g_str_equal,
 						    g_free,
-						    osinfo_hv_section_free);
+						    osinfo_os_hypervisor_devices_free);
 }
 
 OsinfoOs *osinfo_os_new(const gchar *id)
@@ -176,66 +173,9 @@ error_free:
     return ret;
 }
 
-int __osinfoAddDeviceToSectionOs(OsinfoOs *self, gchar *section, gchar *id, gchar *driver)
-{
-    if( !OSINFO_IS_OS(self) || !section || !id || !driver)
-        return -EINVAL;
-
-    return __osinfoAddDeviceToSection(self->priv->sections, self->priv->sectionsAsList, section, id, driver);
-}
-
-void __osinfoClearDeviceSectionOs(OsinfoOs *self, gchar *section)
-{
-    if (!OSINFO_IS_OS(self) || !section)
-        return;
-
-    __osinfoClearDeviceSection(self->priv->sections, self->priv->sectionsAsList, section);
-}
-
-struct __osinfoHvSection *__osinfoAddHypervisorSectionToOs(OsinfoOs *self, gchar *hvId)
-{
-    if (!OSINFO_IS_OS(self) || !hvId)
-        return NULL;
-
-    gboolean found;
-    gpointer origKey, foundValue;
-    struct __osinfoHvSection *hvSection = NULL;
-    GTree *deviceSections;
-    GTree *deviceSectionsAsList;
 
-    found = g_hash_table_lookup_extended(self->priv->hypervisors, hvId, &origKey, &foundValue);
-    if (!found) {
-        hvSection = g_malloc(sizeof(*hvSection));
-        deviceSections = g_tree_new_full(__osinfoStringCompare,
-                                        NULL,
-                                        g_free,
-                                        __osinfoFreeDeviceSection);
-
-
-        deviceSectionsAsList = g_tree_new_full(__osinfoStringCompare,
-                                               NULL,
-                                               g_free,
-                                               __osinfoFreePtrArray);
-
-        hvSection->os = self;
-        // Will set hv link later
-        hvSection->sections = deviceSections;
-        hvSection->sectionsAsList = deviceSectionsAsList;
-
-        g_hash_table_insert(self->priv->hypervisors,
-			    g_strdup(hvId), hvSection);
-        return hvSection;
-    }
-    else
-        return (struct __osinfoHvSection *) foundValue;
-}
-
-void __osinfoRemoveHvSectionFromOs(OsinfoOs *self, gchar *hvId)
-{
-    g_hash_table_remove(self->priv->hypervisors, hvId);
-}
-
-OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter)
+OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter,
+					     const gchar **driver)
 {
     g_return_val_if_fail(OSINFO_IS_OS(self), NULL);
     g_return_val_if_fail(OSINFO_IS_HYPERVISOR(hv), NULL);
@@ -243,34 +183,25 @@ OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *h
     g_return_val_if_fail(devType != NULL, NULL);
     // Check if device type info present for <os,hv>, else return NULL.
 
-    GPtrArray *sectionList = NULL;
-    if (hv) {
-        // Check if hypervisor specific info present for Os, else return NULL.
-        struct __osinfoHvSection *hvSection = NULL;
-        hvSection = g_hash_table_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-        if (!hvSection)
-            return NULL;
-
-        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
-        if (!sectionList)
-            return NULL;
-    }
-    else {
-        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-        if (!sectionList)
-            return NULL;
-    }
+    GList *tmp;
+    if (hv)
+        tmp = g_hash_table_lookup(self->priv->hypervisors,
+				  osinfo_entity_get_id(OSINFO_ENTITY(hv)));
+    else
+        tmp = self->priv->deviceLinks;
 
     // For each device in section list, apply filter. If filter passes, return device.
-    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))
-	    return deviceLink->dev;
+    while (tmp) {
+        struct __osinfoDeviceLink *link = tmp->data;
+
+        if (osinfo_entity_matches_filter(OSINFO_ENTITY(link->dev), filter)) {
+	    *driver = link->driver;
+	    return link->dev;
+	}
     }
 
     // If no devices pass filter, return NULL.
+    *driver= NULL;
     return NULL;
 }
 
@@ -295,42 +226,56 @@ OsinfoOsList *osinfo_os_get_related(OsinfoOs *self, osinfoRelationship relshp)
     return newList;
 }
 
-OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter)
+OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoFilter *filter)
 {
     g_return_val_if_fail(OSINFO_IS_OS(self), NULL);
     g_return_val_if_fail(OSINFO_IS_HYPERVISOR(hv), NULL);
     g_return_val_if_fail(OSINFO_IS_FILTER(filter), NULL);
-    g_return_val_if_fail(devType != NULL, NULL);
-
-    GPtrArray *sectionList = NULL;
 
-    // Create our device list
     OsinfoDeviceList *newList = osinfo_devicelist_new();
+    GList *tmp = NULL;
 
-    if (hv) {
-        struct __osinfoHvSection *hvSection = NULL;
-        hvSection = g_hash_table_lookup(self->priv->hypervisors, (OSINFO_ENTITY(hv))->priv->id);
-        if (!hvSection)
-            return newList;
-
-        sectionList = g_tree_lookup(hvSection->sectionsAsList, devType);
-        if (!sectionList)
-            return newList;
-    }
-    else {
-        sectionList = g_tree_lookup(self->priv->sectionsAsList, devType);
-        if (!sectionList)
-            return newList;
-    }
+    if (hv)
+        tmp = g_hash_table_lookup(self->priv->hypervisors,
+				  osinfo_entity_get_id(OSINFO_ENTITY(hv)));
+    else
+        tmp = self->priv->deviceLinks;
 
-    // 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));
+    while (tmp) {
+        struct __osinfoDeviceLink *link = tmp->data;
+
+        if (osinfo_entity_matches_filter(OSINFO_ENTITY(link->dev), filter))
+	    osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(link->dev));
+
+	tmp = tmp->next;
     }
 
     return NULL;
 }
+
+
+void osinfo_os_add_device(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoDevice *dev, const gchar *driver)
+{
+    g_return_if_fail(OSINFO_IS_HYPERVISOR(self));
+    g_return_if_fail(OSINFO_IS_DEVICE(dev));
+    g_return_if_fail(driver != NULL);
+
+    struct __osinfoDeviceLink *link = g_new0(struct __osinfoDeviceLink, 1);
+
+    g_object_ref(dev);
+    link->dev = dev;
+    link->driver = g_strdup(driver);
+
+    if (hv) {
+        GList *tmp = g_hash_table_lookup(self->priv->hypervisors,
+					 osinfo_entity_get_id(OSINFO_ENTITY(hv)));
+	g_hash_table_steal(self->priv->hypervisors,
+			   osinfo_entity_get_id(OSINFO_ENTITY(hv)));
+	tmp = g_list_prepend(tmp, link);
+	g_hash_table_insert(self->priv->hypervisors,
+			    osinfo_entity_get_id(OSINFO_ENTITY(hv)), tmp);
+    } else {
+        self->priv->deviceLinks = g_list_prepend(self->priv->deviceLinks, link);
+    }
+}
+
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
index 62b5da4..033bdf4 100644
--- a/osinfo/osinfo_os.h
+++ b/osinfo/osinfo_os.h
@@ -52,8 +52,12 @@ GType osinfo_os_get_type(void);
 
 OsinfoOs *osinfo_os_new(const gchar *id);
 
-OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter);
+OsinfoDevice *osinfo_os_get_preferred_device(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter,
+					     const gchar **driver);
 OsinfoOsList *osinfo_os_get_related(OsinfoOs *self, osinfoRelationship relshp);
-OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *self, OsinfoHypervisor *hv, gchar *devType, OsinfoFilter *filter);
+
+OsinfoDeviceList *osinfo_os_get_devices(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoFilter *filter);
+
+void osinfo_os_add_device(OsinfoOs *self, OsinfoHypervisor *hv, OsinfoDevice *dev, const gchar *driver);
 
 #endif /* __OSINFO_OS_H__ */
-- 
1.7.2.1




More information about the virt-tools-list mailing list