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(a)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