Signed-off-by: Kristina Hanicova <khanicov(a)redhat.com>
---
src/conf/domain_conf.c | 190 ++++++++++++++++++++---------------------
1 file changed, 94 insertions(+), 96 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5ac15fe9e8..c5b13783f3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11350,112 +11350,112 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDef *def,
virDomainChrDef *chr_def,
xmlXPathContextPtr ctxt)
{
- bool logParsed = false;
- bool protocolParsed = false;
- int sourceParsed = 0;
+ xmlNodePtr log = NULL;
+ xmlNodePtr protocol = NULL;
+ g_autofree xmlNodePtr *source = NULL;
+ int n = 0;
+ VIR_XPATH_NODE_AUTORESTORE(ctxt)
- for (; cur; cur = cur->next) {
- if (cur->type != XML_ELEMENT_NODE)
- continue;
+ ctxt->node = cur;
- if (virXMLNodeNameEqual(cur, "source")) {
- /* Parse only the first source element since only one is used
- * for chardev devices, the only exception is UDP type, where
- * user can specify two source elements. */
- if (sourceParsed >= 1 && def->type != VIR_DOMAIN_CHR_TYPE_UDP)
{
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("only one source element is allowed for "
- "character device"));
- goto error;
- } else if (sourceParsed >= 2) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("only two source elements are allowed for "
- "character device"));
- goto error;
- }
- sourceParsed++;
+ if ((n = virXPathNodeSet("./source", ctxt, &source)) > 0) {
+ /* Parse only the first source element since only one is used
+ * for chardev devices, the only exception is UDP type, where
+ * user can specify two source elements. */
+ if (n > 1 && def->type != VIR_DOMAIN_CHR_TYPE_UDP) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one source element is allowed for "
+ "character device"));
+ goto error;
+ } else if (n > 2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only two source elements are allowed for "
+ "character device"));
+ goto error;
+ }
- switch ((virDomainChrType) def->type) {
- case VIR_DOMAIN_CHR_TYPE_FILE:
- if (virDomainChrSourceDefParseFile(def, cur) < 0)
- goto error;
- break;
+ switch ((virDomainChrType) def->type) {
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ if (virDomainChrSourceDefParseFile(def, source[0]) < 0)
+ goto error;
+ break;
- case VIR_DOMAIN_CHR_TYPE_PTY:
- /* PTY path is only parsed from live xml. */
- if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
- def->data.file.path = virXMLPropString(cur, "path");
- break;
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ /* PTY path is only parsed from live xml. */
+ if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
+ def->data.file.path =
virXPathString("string(./source/@path)", ctxt);
+ break;
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- def->data.file.path = virXMLPropString(cur, "path");
- break;
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ def->data.file.path = virXPathString("string(./source/@path)",
ctxt);
+ break;
- case VIR_DOMAIN_CHR_TYPE_UNIX:
- if (virDomainChrSourceDefParseUnix(def, cur, ctxt) < 0)
- goto error;
- break;
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ if (virDomainChrSourceDefParseUnix(def, source[0], ctxt) < 0)
+ goto error;
+ break;
- case VIR_DOMAIN_CHR_TYPE_UDP:
- if (virDomainChrSourceDefParseUDP(def, cur) < 0)
+ case VIR_DOMAIN_CHR_TYPE_UDP:
+ if ((virDomainChrSourceDefParseUDP(def, source[0]) < 0) ||
+ (source[1] && virDomainChrSourceDefParseUDP(def, source[1]) <
0))
goto error;
- break;
+ break;
- case VIR_DOMAIN_CHR_TYPE_TCP:
- if (virDomainChrSourceDefParseTCP(def, cur, ctxt, flags) < 0)
- goto error;
- break;
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ if (virDomainChrSourceDefParseTCP(def, source[0], ctxt, flags) < 0)
+ goto error;
+ break;
- case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
- def->data.spiceport.channel = virXMLPropString(cur,
"channel");
- break;
+ case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
+ def->data.spiceport.channel =
virXPathString("string(./source/@channel)", ctxt);
+ break;
- case VIR_DOMAIN_CHR_TYPE_NMDM:
- def->data.nmdm.master = virXMLPropString(cur, "master");
- def->data.nmdm.slave = virXMLPropString(cur, "slave");
- break;
+ case VIR_DOMAIN_CHR_TYPE_NMDM:
+ def->data.nmdm.master =
virXPathString("string(./source/@master)", ctxt);
+ def->data.nmdm.slave = virXPathString("string(./source/@slave)",
ctxt);
+ break;
- case VIR_DOMAIN_CHR_TYPE_LAST:
- case VIR_DOMAIN_CHR_TYPE_NULL:
- case VIR_DOMAIN_CHR_TYPE_VC:
- case VIR_DOMAIN_CHR_TYPE_STDIO:
- case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
- break;
- }
+ case VIR_DOMAIN_CHR_TYPE_LAST:
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+ break;
+ }
- /* Check for an optional seclabel override in <source/>. */
- if (chr_def) {
- VIR_XPATH_NODE_AUTORESTORE(ctxt)
- ctxt->node = cur;
- if (virSecurityDeviceLabelDefParseXML(&def->seclabels,
- &def->nseclabels,
- ctxt,
- flags) < 0) {
- goto error;
- }
- }
- } else if (virXMLNodeNameEqual(cur, "log")) {
- if (logParsed) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("only one protocol element is allowed for "
- "character device"));
- goto error;
- }
- logParsed = true;
- if (virDomainChrSourceDefParseLog(def, cur) < 0)
- goto error;
- } else if (virXMLNodeNameEqual(cur, "protocol")) {
- if (protocolParsed) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("only one log element is allowed for "
- "character device"));
+ /* Check for an optional seclabel override in <source/>. */
+ if (chr_def) {
+ xmlNodePtr tmp = ctxt->node;
+ ctxt->node = source[0];
+ if (virSecurityDeviceLabelDefParseXML(&def->seclabels,
&def->nseclabels,
+ ctxt, flags) < 0) {
goto error;
}
- protocolParsed = true;
- if (virDomainChrSourceDefParseProtocol(def, cur) < 0)
- goto error;
+ ctxt->node = tmp;
+ }
+ }
+
+ if ((log = virXPathNode("./log", ctxt))) {
+ if (virXPathBoolean("boolean(count(./log) > 1)", ctxt)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one log element is allowed for "
+ "character device"));
+ goto error;
+ }
+ if (virDomainChrSourceDefParseLog(def, log) < 0)
+ goto error;
+ }
+
+ if ((protocol = virXPathNode("./protocol", ctxt))) {
+ if (virXPathBoolean("boolean(count(./protocol) > 1)", ctxt)) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one protocol element is allowed for "
+ "character device"));
+ goto error;
}
+ if (virDomainChrSourceDefParseProtocol(def, protocol) < 0)
+ goto error;
}
return 0;
@@ -11609,7 +11609,7 @@ virDomainChrDefParseXML(virDomainXMLOption *xmlopt,
((def->targetType = virDomainChrDefaultTargetType(def->deviceType)) <
0))
goto error;
- if (virDomainChrSourceDefParseXML(def->source, node->children, flags, def,
+ if (virDomainChrSourceDefParseXML(def->source, node, flags, def,
ctxt) < 0)
goto error;
@@ -11733,7 +11733,7 @@ virDomainSmartcardDefParseXML(virDomainXMLOption *xmlopt,
}
cur = node->children;
- if (virDomainChrSourceDefParseXML(def->data.passthru, cur, flags,
+ if (virDomainChrSourceDefParseXML(def->data.passthru, node, flags,
NULL, ctxt) < 0)
return NULL;
@@ -13686,7 +13686,7 @@ virDomainRNGDefParseXML(virDomainXMLOption *xmlopt,
}
if (virDomainChrSourceDefParseXML(def->source.chardev,
- backends[0]->children, flags,
+ backends[0], flags,
NULL, ctxt) < 0)
goto error;
break;
@@ -14693,7 +14693,6 @@ virDomainRedirdevDefParseXML(virDomainXMLOption *xmlopt,
xmlXPathContextPtr ctxt,
unsigned int flags)
{
- xmlNodePtr cur;
virDomainRedirdevDef *def;
g_autofree char *bus = NULL;
g_autofree char *type = NULL;
@@ -14727,10 +14726,9 @@ virDomainRedirdevDefParseXML(virDomainXMLOption *xmlopt,
goto error;
}
- cur = node->children;
/* boot gets parsed in virDomainDeviceInfoParseXML
* source gets parsed in virDomainChrSourceDefParseXML */
- if (virDomainChrSourceDefParseXML(def->source, cur, flags,
+ if (virDomainChrSourceDefParseXML(def->source, node, flags,
NULL, ctxt) < 0)
goto error;
--
2.30.2