diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f260c42883..b6f02677e7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10648,18 +10648,36 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node, return 0; } + +/** + * virDomainGraphicsListenDefParseXML: + * @def: listen def pointer to be filled + * @node: xml node of element + * @parent: xml node of element + * @flags: bit-wise or of VIR_DOMAIN_DEF_PARSE_* + * + * Parses current element from @node to @def. For backward + * compatibility the @parent element should contain node of element + * for the first element in order to validate attributes from both + * elements. + */ static int virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, xmlNodePtr node, + xmlNodePtr parent, unsigned int flags) { int ret = -1; - char *type = virXMLPropString(node, "type"); - char *address = virXMLPropString(node, "address"); - char *network = virXMLPropString(node, "network"); + char *type = virXMLPropString(node, "type"); + char *address = virXMLPropString(node, "address"); + char *network = virXMLPropString(node, "network"); char *fromConfig = virXMLPropString(node, "fromConfig"); + char *addressCompat = NULL; int tmp, typeVal; + if (parent) + addressCompat = virXMLPropString(parent, "listen"); + if (!type) { virReportError(VIR_ERR_XML_ERROR, "%s", _("graphics listen type must be specified")); @@ -10673,9 +10691,21 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, } def->type = typeVal; - /* address is recognized if either type='address', or if - * type='network' and we're looking at live XML (i.e. *not* - * inactive). It is otherwise ignored. */ + if (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) { + if (address && addressCompat && STRNEQ(address, addressCompat)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("graphics 'listen' attribute '%s' must match " + "'address' attribute of first listen element " + "(found '%s')"), addressCompat, address); + goto error; + } + + if (!address) { + address = addressCompat; + addressCompat = NULL; + } + } + if (address && address[0] && (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS || (def->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK && @@ -10715,6 +10745,7 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, VIR_FREE(address); VIR_FREE(network); VIR_FREE(fromConfig); + VIR_FREE(addressCompat); return ret; } @@ -10727,8 +10758,7 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def, { xmlNodePtr *listenNodes = NULL; xmlNodePtr save = ctxt->node; - virDomainGraphicsListenDefPtr address = NULL; - char *listenAddr = NULL; + virDomainGraphicsListenDef newListen = {0}; char *socketPath = NULL; int nListens; int ret = -1; @@ -10755,44 +10785,31 @@ virDomainGraphicsListensParseXML(virDomainGraphicsDefPtr def, for (i = 0; i < nListens; i++) { if (virDomainGraphicsListenDefParseXML(&def->listens[i], listenNodes[i], + i == 0 ? node : NULL, flags) < 0) goto error; - if (!address && - def->listens[i].type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) - address = &def->listens[i]; - def->nListens++; } VIR_FREE(listenNodes); + } else { + /* If no element was found in XML for backward compatibility + * we should try to parse 'listen' attribute from element. */ + newListen.type = VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS; + newListen.address = virXMLPropString(node, "listen"); + if (STREQ_NULLABLE(newListen.address, "")) + VIR_FREE(newListen.address); + + if (newListen.address && + VIR_APPEND_ELEMENT(def->listens, def->nListens, newListen) < 0) + goto error; } - /* listen attribute of is also supported by these, - * but must match the 'address' attribute of the first listen - * that is type='address' (if present) */ - listenAddr = virXMLPropString(node, "listen"); - if (STREQ_NULLABLE(listenAddr, "")) - VIR_FREE(listenAddr); - - if (address && listenAddr && - STRNEQ_NULLABLE(address->address, listenAddr)) { - virReportError(VIR_ERR_XML_ERROR, - _("graphics listen attribute %s must match address " - "attribute of first listen element (found %s)"), - listenAddr, address->address); - goto error; - } - - /* There were no elements, so we can just - * directly set listenAddr as listens[0]->address */ - if (listenAddr && def->nListens == 0 && - virDomainGraphicsListenAppendAddress(def, listenAddr) < 0) - goto error; - ret = 0; error: + if (ret < 0) + virDomainGraphicsListenDefClear(&newListen); VIR_FREE(listenNodes); - VIR_FREE(listenAddr); VIR_FREE(socketPath); ctxt->node = save; return ret;