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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list