[libvirt] [PATCH v4 1/8] Add namespace callback hooks to domain_conf.

Chris Lalancette clalance at redhat.com
Wed Jul 7 21:33:26 UTC 2010


This patch adds namespace XML parsers to be hooked into
the main domain parser.  This allows for individual hypervisor
drivers to add per-namespace XML into the main domain XML.

Changes since v1:
 - Use a statically declared table for caps->ns, removing the need to
   allocate/free it.

Changes since v2:
 - None

Changes since v3:
 - None

Signed-off-by: Chris Lalancette <clalance at redhat.com>
---
 src/conf/capabilities.h |   17 +++++++++++++++++
 src/conf/domain_conf.c  |   38 +++++++++++++++++++++++++++++++-------
 src/conf/domain_conf.h  |    3 +++
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 9290c82..83bd3b7 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -115,6 +115,21 @@ struct _virCapsHost {
     unsigned char host_uuid[VIR_UUID_BUFLEN];
 };
 
+typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr,
+                                          xmlXPathContextPtr, void **);
+typedef void (*virDomainDefNamespaceFree)(void *);
+typedef int (*virDomainDefNamespaceXMLFormat)(virBufferPtr, void *);
+typedef const char *(*virDomainDefNamespaceHref)(void);
+
+typedef struct _virDomainXMLNamespace virDomainXMLNamespace;
+typedef virDomainXMLNamespace *virDomainXMLNamespacePtr;
+struct _virDomainXMLNamespace {
+    virDomainDefNamespaceParse parse;
+    virDomainDefNamespaceFree free;
+    virDomainDefNamespaceXMLFormat format;
+    virDomainDefNamespaceHref href;
+};
+
 typedef struct _virCaps virCaps;
 typedef virCaps* virCapsPtr;
 struct _virCaps {
@@ -128,6 +143,8 @@ struct _virCaps {
     int (*privateDataXMLFormat)(virBufferPtr, void *);
     int (*privateDataXMLParse)(xmlXPathContextPtr, void *);
     bool hasWideScsiBus;
+
+    virDomainXMLNamespace ns;
 };
 
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 378c06e..653faf4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -738,6 +738,9 @@ void virDomainDefFree(virDomainDefPtr def)
 
     virCPUDefFree(def->cpu);
 
+    if (def->namespaceData && def->ns.free)
+        (def->ns.free)(def->namespaceData);
+
     VIR_FREE(def);
 }
 
@@ -3965,7 +3968,10 @@ static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
 }
 
 static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
-                                            xmlXPathContextPtr ctxt, int flags)
+                                            xmlDocPtr xml,
+                                            xmlNodePtr root,
+                                            xmlXPathContextPtr ctxt,
+                                            int flags)
 {
     xmlNodePtr *nodes = NULL, node = NULL;
     char *tmp = NULL;
@@ -4633,6 +4639,16 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
             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
+     */
+    def->ns = caps->ns;
+
+    if (def->ns.parse) {
+        if ((def->ns.parse)(xml, root, ctxt, &def->namespaceData) < 0)
+            goto error;
+    }
+
     /* Auto-add any implied controllers which aren't present
      */
     if (virDomainDefAddImplicitControllers(def) < 0)
@@ -4653,6 +4669,7 @@ no_memory:
 
 
 static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps,
+                                            xmlDocPtr xml,
                                             xmlXPathContextPtr ctxt)
 {
     char *tmp = NULL;
@@ -4672,7 +4689,7 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps,
 
     oldnode = ctxt->node;
     ctxt->node = config;
-    obj->def = virDomainDefParseXML(caps, ctxt,
+    obj->def = virDomainDefParseXML(caps, xml, config, ctxt,
                                     VIR_DOMAIN_XML_INTERNAL_STATUS);
     ctxt->node = oldnode;
     if (!obj->def)
@@ -4763,7 +4780,7 @@ virDomainDefPtr virDomainDefParseNode(virCapsPtr caps,
     }
 
     ctxt->node = root;
-    def = virDomainDefParseXML(caps, ctxt, flags);
+    def = virDomainDefParseXML(caps, xml, root, ctxt, flags);
 
 cleanup:
     xmlXPathFreeContext(ctxt);
@@ -4806,7 +4823,7 @@ virDomainObjPtr virDomainObjParseNode(virCapsPtr caps,
     }
 
     ctxt->node = root;
-    obj = virDomainObjParseXML(caps, ctxt);
+    obj = virDomainObjParseXML(caps, xml, ctxt);
 
 cleanup:
     xmlXPathFreeContext(ctxt);
@@ -6029,10 +6046,12 @@ char *virDomainDefFormat(virDomainDefPtr def,
     if (def->id == -1)
         flags |= VIR_DOMAIN_XML_INACTIVE;
 
+    virBufferVSprintf(&buf, "<domain type='%s'", type);
     if (!(flags & VIR_DOMAIN_XML_INACTIVE))
-        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, def->id);
-    else
-        virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
+        virBufferVSprintf(&buf, " id='%d'", def->id);
+    if (def->namespaceData && def->ns.href)
+        virBufferVSprintf(&buf, " %s", (def->ns.href)());
+    virBufferAddLit(&buf, ">\n");
 
     virBufferEscapeString(&buf, "  <name>%s</name>\n", def->name);
 
@@ -6289,6 +6308,11 @@ char *virDomainDefFormat(virDomainDefPtr def,
         }
     }
 
+    if (def->namespaceData && def->ns.format) {
+        if ((def->ns.format)(&buf, def->namespaceData) < 0)
+            goto cleanup;
+    }
+
     virBufferAddLit(&buf, "</domain>\n");
 
     if (virBufferError(&buf))
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 01da17e..39bb9a8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -872,6 +872,9 @@ struct _virDomainDef {
     virSecurityLabelDef seclabel;
     virDomainWatchdogDefPtr watchdog;
     virCPUDefPtr cpu;
+
+    void *namespaceData;
+    virDomainXMLNamespace ns;
 };
 
 /* Guest VM runtime state */
-- 
1.6.6.1




More information about the libvir-list mailing list