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

[libvirt] [PATCH] 2/4 Add conf parsing and freeing



 This lacks the saving of the smbios data, should not be hard really,
and the parsing is rather trivial, the data structures follow the XML
format:

Daniel

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5499f28..9dff0f7 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -606,6 +606,29 @@ struct _virDomainMemballoonDef {
 };
 
 
+
+typedef struct _virSmbiosEntry virSmbiosEntry;
+typedef virSmbiosEntry *virSmbiosEntryPtr;
+struct _virSmbiosEntry {
+    virSmbiosEntryPtr next;
+    char *name;
+    char *value;
+};
+
+typedef struct _virSmbiosBlock virSmbiosBlock;
+typedef virSmbiosBlock *virSmbiosBlockPtr;
+struct _virSmbiosBlock {
+    unsigned int type;
+    virSmbiosEntryPtr entries;
+};
+
+typedef struct _virSmbiosDef virSmbiosDef;
+typedef virSmbiosDef *virSmbiosDefPtr;
+struct _virSmbiosDef {
+    unsigned int nbblocks;
+    virSmbiosBlockPtr *blocks;
+};
+
 /* Flags for the 'type' field in next struct */
 enum virDomainDeviceType {
     VIR_DOMAIN_DEVICE_DISK,
@@ -943,6 +966,7 @@ struct _virDomainDef {
     virDomainWatchdogDefPtr watchdog;
     virDomainMemballoonDefPtr memballoon;
     virCPUDefPtr cpu;
+    virSmbiosDefPtr smbios;
 
     void *namespaceData;
     virDomainXMLNamespace ns;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a997e06..fd85398 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -712,6 +712,48 @@ virDomainClockDefClear(virDomainClockDefPtr def)
     VIR_FREE(def->timers);
 }
 
+static void virSmbiosEntriesFree(virSmbiosEntryPtr cur)
+{
+    virSmbiosEntryPtr next;
+
+    if (cur == NULL)
+        return;
+
+    while (cur != NULL) {
+        next = cur->next;
+
+        VIR_FREE(cur->name);
+        VIR_FREE(cur->value);
+        VIR_FREE(cur);
+
+        cur = next;
+    }
+}
+
+static void virSmbiosBlockFree(virSmbiosBlockPtr block)
+{
+    if (block == NULL)
+        return;
+
+    virSmbiosEntriesFree(block->entries);
+    VIR_FREE(block);
+}
+
+static void virSmbiosDefFree(virSmbiosDefPtr def)
+{
+    unsigned int i;
+
+    if (def == NULL)
+        return;
+
+    if (def->blocks != NULL) {
+        for (i = 0;i < def->nbblocks;i++)
+            virSmbiosBlockFree(def->blocks[i]);
+        VIR_FREE(def->blocks);
+    }
+    VIR_FREE(def);
+}
+
 void virDomainDefFree(virDomainDefPtr def)
 {
     unsigned int i;
@@ -796,6 +838,8 @@ void virDomainDefFree(virDomainDefPtr def)
 
     virCPUDefFree(def->cpu);
 
+    virSmbiosDefFree(def->smbios);
+
     if (def->namespaceData && def->ns.free)
         (def->ns.free)(def->namespaceData);
 
@@ -3341,6 +3385,150 @@ error:
     goto cleanup;
 }
 
+static virSmbiosEntryPtr
+virSmbiosEntryParseXML(xmlXPathContextPtr ctxt)
+{
+    char *name, *value;
+    virSmbiosEntryPtr def;
+
+    name = virXPathString("string(./@name)", ctxt);
+    if (name == NULL) {
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+                  _("XML element 'entry' requires a 'name' attrbute"));
+        return(NULL);
+    }
+    value = virXPathString("string(.)", ctxt);
+    if (value == NULL) {
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+                  _("failed to get content of element 'entry'"));
+        VIR_FREE(name);
+        return(NULL);
+    }
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        VIR_FREE(name);
+        VIR_FREE(value);
+        return(NULL);
+    }
+    def->name = name;
+    def->value = value;
+    def->next = NULL;
+
+    return(def);
+}
+
+static virSmbiosBlockPtr
+virSmbiosBlockParseXML(xmlXPathContextPtr ctxt)
+{
+    virSmbiosBlockPtr def;
+    virSmbiosEntryPtr cur, next;
+    xmlNodePtr *nodes = NULL;
+    int n;
+    unsigned int i;
+    long type;
+
+    if (virXPathLong("string(./@type)", ctxt, &type) < 0) {
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+                  _("XML element 'table' requires a numeric 'type' attrbute"));
+        return(NULL);
+    }
+    if ((type < 0) || (type > 32)) {
+        virDomainReportError(VIR_ERR_XML_ERROR,
+              _("XML 'type' attribute on 'table' out of 0..32 range got %ld"),
+                type);
+        return(NULL);
+    }
+    n = virXPathNodeSet("./entry", ctxt, &nodes);
+    if (n <= 0)
+        return(NULL);
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        goto error;
+    }
+    def->type = (unsigned int) type;
+    def->entries = NULL;
+    cur = NULL;
+
+    for (i = 0;i < n;i++) {
+        if (nodes[i] != NULL) {
+            ctxt->node = nodes[i];
+            next = virSmbiosEntryParseXML(ctxt);
+            if (next == NULL)
+                goto error;
+            if (cur == NULL) {
+                def->entries = next;
+                cur = next;
+            } else {
+                cur->next = next;
+                cur = next;
+            }
+            cur->next = NULL;
+        }
+    }
+
+cleanup:
+    xmlFree(nodes);
+    return(def);
+
+error:
+    virSmbiosBlockFree(def);
+    def = NULL;
+    goto cleanup;
+}
+
+static virSmbiosDefPtr
+virSmbiosParseXML(const xmlNodePtr node,
+                  xmlXPathContextPtr ctxt)
+{
+    virSmbiosDefPtr def;
+    virSmbiosBlockPtr block;
+    xmlNodePtr *nodes = NULL;
+    int n;
+    unsigned int i, j;
+
+    if (!xmlStrEqual(node->name, BAD_CAST "smbios")) {
+        virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+                          _("XML does not contain expected 'smbios' element"));
+        return(NULL);
+    }
+
+    n = virXPathNodeSet("./table", ctxt, &nodes);
+    if (n <= 0)
+        return(NULL);
+
+    if (VIR_ALLOC(def) < 0) {
+        virReportOOMError();
+        goto error;
+    }
+    if (VIR_ALLOC_N(def->blocks, n) < 0) {
+        virReportOOMError();
+        goto error;
+    }
+
+    for (i = 0, j = 0;i < n;i++) {
+        if (nodes[i] != NULL) {
+            ctxt->node = nodes[i];
+            block = virSmbiosBlockParseXML(ctxt);
+            if (block != NULL)
+                def->blocks[j++] = block;
+            else
+                goto error;
+            def->nbblocks = j;
+        }
+    }
+
+
+cleanup:
+    xmlFree(nodes);
+    return(def);
+
+error:
+    virSmbiosDefFree(def);
+    def = NULL;
+    goto cleanup;
+}
 
 int
 virDomainVideoDefaultRAM(virDomainDefPtr def,
@@ -4970,6 +5158,16 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
             goto error;
     }
 
+    if ((node = virXPathNode("./smbios[1]", ctxt)) != NULL) {
+        xmlNodePtr oldnode = ctxt->node;
+        ctxt->node = node;
+        def->smbios = virSmbiosParseXML(node, ctxt);
+        ctxt->node = oldnode;
+
+        if (def->smbios == NULL)
+            goto error;
+    }
+
     /* we have to make a copy of all of the callback pointers here since
      * we won't have the virCaps structure available during free
      */

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel veillard com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/


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