_("Missing source service attribute for char device"));
return -1;
}
+
+ if (def->data.tcp.listen && def->data.tcp.reconnect.enabled) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("chardev reconnect is possible only for connect mode"));
+ return -1;
+ }
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
_("Missing source path attribute for char device"));
return -1;
}
+
+ if (def->data.nix.listen && def->data.nix.reconnect.enabled) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("chardev reconnect is possible only for connect mode"));
+ return -1;
+ }
break;
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
return ret;
}
+static int
+virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt)
+{
+ int ret = -1;
+ int tmpVal;
+ char *tmp = NULL;
+ xmlNodePtr saveNode = ctxt->node;
+ xmlNodePtr cur;
+
+ ctxt->node = node;
+
+ if ((cur = virXPathNode("./reconnect", ctxt))) {
+ if ((tmp = virXMLPropString(cur, "enabled"))) {
+ if ((tmpVal = virTristateBoolTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid reconnect enabled value: '%s'"),
+ tmp);
+ goto cleanup;
+ }
+ def->enabled = tmpVal;
+ VIR_FREE(tmp);
+ }
+
+ if (def->enabled == VIR_TRISTATE_BOOL_YES) {
+ if ((tmp = virXMLPropString(cur, "timeout"))) {
+ if (virStrToLong_ui(tmp, NULL, 10, &def->timeout) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid reconnect timeout value: '%s'"),
+ tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+ } else {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing timeout for chardev with "
+ "reconnect enabled"));
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ ctxt->node = saveNode;
+ VIR_FREE(tmp);
+ return ret;
+}
+
typedef enum {
VIR_DOMAIN_CHR_SOURCE_MODE_CONNECT,
static int
virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
xmlNodePtr source,
+ xmlXPathContextPtr ctxt,
unsigned int flags)
{
int mode;
VIR_FREE(tmp);
}
+ if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect,
+ source,
+ ctxt) < 0) {
+ goto error;
+ }
+
return 0;
error:
static int
virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
- xmlNodePtr source)
+ xmlNodePtr source,
+ xmlXPathContextPtr ctxt)
{
int mode;
def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND;
def->data.nix.path = virXMLPropString(source, "path");
+ if (virDomainChrSourceReconnectDefParseXML(&def->data.nix.reconnect,
+ source,
+ ctxt) < 0) {
+ return -1;
+ }
+
return 0;
}
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
- if (virDomainChrSourceDefParseUnix(def, cur) < 0)
+ if (virDomainChrSourceDefParseUnix(def, cur, ctxt) < 0)
goto error;
break;
break;
case VIR_DOMAIN_CHR_TYPE_TCP:
- if (virDomainChrSourceDefParseTCP(def, cur, flags) < 0)
+ if (virDomainChrSourceDefParseTCP(def, cur, ctxt, flags) < 0)
goto error;
break;
static virDomainSmartcardDefPtr
virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt,
xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
unsigned int flags)
{
xmlNodePtr cur;
cur = node->children;
if (virDomainChrSourceDefParseXML(def->data.passthru, cur, flags,
- NULL, NULL, NULL, 0) < 0)
+ NULL, ctxt, NULL, 0) < 0)
goto error;
if (def->data.passthru->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
static virDomainRedirdevDefPtr
virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt,
xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
virHashTablePtr bootHash,
unsigned int flags)
{
/* boot gets parsed in virDomainDeviceInfoParseXML
* source gets parsed in virDomainChrSourceDefParseXML */
if (virDomainChrSourceDefParseXML(def->source, cur, flags,
- NULL, NULL, NULL, 0) < 0)
+ NULL, ctxt, NULL, 0) < 0)
goto error;
if (def->source->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC)
break;
case VIR_DOMAIN_DEVICE_REDIRDEV:
if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(xmlopt, node,
- NULL, flags)))
+ ctxt, NULL, flags)))
goto error;
break;
case VIR_DOMAIN_DEVICE_RNG:
break;
case VIR_DOMAIN_DEVICE_SMARTCARD:
if (!(dev->data.smartcard = virDomainSmartcardDefParseXML(xmlopt, node,
- flags)))
+ ctxt, flags)))
goto error;
break;
case VIR_DOMAIN_DEVICE_MEMBALLOON:
for (i = 0; i < n; i++) {
virDomainSmartcardDefPtr card = virDomainSmartcardDefParseXML(xmlopt,
nodes[i],
+ ctxt,
flags);
if (!card)
goto error;
goto error;
for (i = 0; i < n; i++) {
virDomainRedirdevDefPtr redirdev =
- virDomainRedirdevDefParseXML(xmlopt, nodes[i], bootHash, flags);
+ virDomainRedirdevDefParseXML(xmlopt, nodes[i], ctxt, bootHash, flags);
if (!redirdev)
goto error;
return 0;
}
+
+static void
+virDomainChrSourceReconnectDefFormat(virBufferPtr buf,
+ virDomainChrSourceReconnectDefPtr def)
+{
+ if (def->enabled == VIR_TRISTATE_BOOL_ABSENT)
+ return;
+
+ virBufferAsprintf(buf, "<reconnect enabled='%s'",
+ virTristateBoolTypeToString(def->enabled));
+
+ if (def->enabled == VIR_TRISTATE_BOOL_YES)
+ virBufferAsprintf(buf, " timeout='%u'", def->timeout);
+
+ virBufferAddLit(buf, "/>\n");
+}
+
+
static int
virDomainChrSourceDefFormat(virBufferPtr buf,
virDomainChrSourceDefPtr def,
virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
def->data.tcp.tlsFromConfig);
+ virDomainChrSourceReconnectDefFormat(&childBuf,
+ &def->data.tcp.reconnect);
+
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
goto error;
virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
def->seclabels, flags);
+ virDomainChrSourceReconnectDefFormat(&childBuf,
+ &def->data.nix.reconnect);
+
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
goto error;
}