[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