mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
conf: introduce reconnect element for chardev source
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
parent
5f7da98b3f
commit
9aa72a6dd5
@ -6298,6 +6298,17 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
slot.
|
slot.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For character device with type <code>unix</code> or <code>tcp</code>
|
||||||
|
the <code>source</code> has an optional element <code>reconnect</code>
|
||||||
|
which configures reconnect timeout if the connection is lost.
|
||||||
|
There are two attributes, <code>enabled</code> where possible
|
||||||
|
values are "yes" and "no" and <code>timeout</code> which is in
|
||||||
|
seconds. The <code>reconnect</code> attribute is valid only
|
||||||
|
for <code>connect</code> mode.
|
||||||
|
<span class="since">Since 3.7.0 (QEMU driver only)</span>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h5><a id="elementsCharGuestInterface">Guest interface</a></h5>
|
<h5><a id="elementsCharGuestInterface">Guest interface</a></h5>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -3634,6 +3634,18 @@
|
|||||||
<ref name="virYesNo"/>
|
<ref name="virYesNo"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
</optional>
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<element name="reconnect">
|
||||||
|
<attribute name="enabled">
|
||||||
|
<ref name="virYesNo"/>
|
||||||
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name="timeout">
|
||||||
|
<ref name="unsignedInt"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<ref name='devSeclabel'/>
|
<ref name='devSeclabel'/>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
|
@ -5130,6 +5130,12 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def,
|
|||||||
_("Missing source service attribute for char device"));
|
_("Missing source service attribute for char device"));
|
||||||
return -1;
|
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;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_UDP:
|
case VIR_DOMAIN_CHR_TYPE_UDP:
|
||||||
@ -5150,6 +5156,12 @@ virDomainChrSourceDefValidate(const virDomainChrSourceDef *def,
|
|||||||
_("Missing source path attribute for char device"));
|
_("Missing source path attribute for char device"));
|
||||||
return -1;
|
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;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
|
case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
|
||||||
@ -11115,6 +11127,56 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
|
|||||||
return ret;
|
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 {
|
typedef enum {
|
||||||
VIR_DOMAIN_CHR_SOURCE_MODE_CONNECT,
|
VIR_DOMAIN_CHR_SOURCE_MODE_CONNECT,
|
||||||
@ -11152,6 +11214,7 @@ virDomainChrSourceDefParseMode(xmlNodePtr source)
|
|||||||
static int
|
static int
|
||||||
virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
|
virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
|
||||||
xmlNodePtr source,
|
xmlNodePtr source,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
int mode;
|
int mode;
|
||||||
@ -11187,6 +11250,12 @@ virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
|
|||||||
VIR_FREE(tmp);
|
VIR_FREE(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect,
|
||||||
|
source,
|
||||||
|
ctxt) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -11220,7 +11289,8 @@ virDomainChrSourceDefParseUDP(virDomainChrSourceDefPtr def,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
|
virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
|
||||||
xmlNodePtr source)
|
xmlNodePtr source,
|
||||||
|
xmlXPathContextPtr ctxt)
|
||||||
{
|
{
|
||||||
|
|
||||||
int mode;
|
int mode;
|
||||||
@ -11231,6 +11301,12 @@ virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
|
|||||||
def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND;
|
def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND;
|
||||||
def->data.nix.path = virXMLPropString(source, "path");
|
def->data.nix.path = virXMLPropString(source, "path");
|
||||||
|
|
||||||
|
if (virDomainChrSourceReconnectDefParseXML(&def->data.nix.reconnect,
|
||||||
|
source,
|
||||||
|
ctxt) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11359,7 +11435,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
case VIR_DOMAIN_CHR_TYPE_UNIX:
|
||||||
if (virDomainChrSourceDefParseUnix(def, cur) < 0)
|
if (virDomainChrSourceDefParseUnix(def, cur, ctxt) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -11369,7 +11445,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_CHR_TYPE_TCP:
|
case VIR_DOMAIN_CHR_TYPE_TCP:
|
||||||
if (virDomainChrSourceDefParseTCP(def, cur, flags) < 0)
|
if (virDomainChrSourceDefParseTCP(def, cur, ctxt, flags) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -11613,6 +11689,7 @@ virDomainChrDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
static virDomainSmartcardDefPtr
|
static virDomainSmartcardDefPtr
|
||||||
virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt,
|
virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
@ -11705,7 +11782,7 @@ virDomainSmartcardDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
|
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
if (virDomainChrSourceDefParseXML(def->data.passthru, cur, flags,
|
if (virDomainChrSourceDefParseXML(def->data.passthru, cur, flags,
|
||||||
NULL, NULL, NULL, 0) < 0)
|
NULL, ctxt, NULL, 0) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (def->data.passthru->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
|
if (def->data.passthru->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC) {
|
||||||
@ -14183,6 +14260,7 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
static virDomainRedirdevDefPtr
|
static virDomainRedirdevDefPtr
|
||||||
virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt,
|
virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt,
|
||||||
xmlNodePtr node,
|
xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
virHashTablePtr bootHash,
|
virHashTablePtr bootHash,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -14224,7 +14302,7 @@ virDomainRedirdevDefParseXML(virDomainXMLOptionPtr xmlopt,
|
|||||||
/* boot gets parsed in virDomainDeviceInfoParseXML
|
/* boot gets parsed in virDomainDeviceInfoParseXML
|
||||||
* source gets parsed in virDomainChrSourceDefParseXML */
|
* source gets parsed in virDomainChrSourceDefParseXML */
|
||||||
if (virDomainChrSourceDefParseXML(def->source, cur, flags,
|
if (virDomainChrSourceDefParseXML(def->source, cur, flags,
|
||||||
NULL, NULL, NULL, 0) < 0)
|
NULL, ctxt, NULL, 0) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (def->source->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC)
|
if (def->source->type == VIR_DOMAIN_CHR_TYPE_SPICEVMC)
|
||||||
@ -14883,7 +14961,7 @@ virDomainDeviceDefParse(const char *xmlStr,
|
|||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
case VIR_DOMAIN_DEVICE_REDIRDEV:
|
||||||
if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(xmlopt, node,
|
if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(xmlopt, node,
|
||||||
NULL, flags)))
|
ctxt, NULL, flags)))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_RNG:
|
case VIR_DOMAIN_DEVICE_RNG:
|
||||||
@ -14902,7 +14980,7 @@ virDomainDeviceDefParse(const char *xmlStr,
|
|||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
case VIR_DOMAIN_DEVICE_SMARTCARD:
|
||||||
if (!(dev->data.smartcard = virDomainSmartcardDefParseXML(xmlopt, node,
|
if (!(dev->data.smartcard = virDomainSmartcardDefParseXML(xmlopt, node,
|
||||||
flags)))
|
ctxt, flags)))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
case VIR_DOMAIN_DEVICE_MEMBALLOON:
|
||||||
@ -18600,6 +18678,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
virDomainSmartcardDefPtr card = virDomainSmartcardDefParseXML(xmlopt,
|
virDomainSmartcardDefPtr card = virDomainSmartcardDefParseXML(xmlopt,
|
||||||
nodes[i],
|
nodes[i],
|
||||||
|
ctxt,
|
||||||
flags);
|
flags);
|
||||||
if (!card)
|
if (!card)
|
||||||
goto error;
|
goto error;
|
||||||
@ -18949,7 +19028,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
goto error;
|
goto error;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
virDomainRedirdevDefPtr redirdev =
|
virDomainRedirdevDefPtr redirdev =
|
||||||
virDomainRedirdevDefParseXML(xmlopt, nodes[i], bootHash, flags);
|
virDomainRedirdevDefParseXML(xmlopt, nodes[i], ctxt, bootHash, flags);
|
||||||
if (!redirdev)
|
if (!redirdev)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -23070,6 +23149,24 @@ virDomainChrAttrsDefFormat(virBufferPtr buf,
|
|||||||
return 0;
|
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
|
static int
|
||||||
virDomainChrSourceDefFormat(virBufferPtr buf,
|
virDomainChrSourceDefFormat(virBufferPtr buf,
|
||||||
virDomainChrSourceDefPtr def,
|
virDomainChrSourceDefPtr def,
|
||||||
@ -23150,6 +23247,9 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
|
|||||||
virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
|
virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
|
||||||
def->data.tcp.tlsFromConfig);
|
def->data.tcp.tlsFromConfig);
|
||||||
|
|
||||||
|
virDomainChrSourceReconnectDefFormat(&childBuf,
|
||||||
|
&def->data.tcp.reconnect);
|
||||||
|
|
||||||
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
|
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -23166,6 +23266,9 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
|
|||||||
virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
|
virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
|
||||||
def->seclabels, flags);
|
def->seclabels, flags);
|
||||||
|
|
||||||
|
virDomainChrSourceReconnectDefFormat(&childBuf,
|
||||||
|
&def->data.nix.reconnect);
|
||||||
|
|
||||||
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
|
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1137,6 +1137,15 @@ typedef enum {
|
|||||||
VIR_DOMAIN_CHR_SPICEVMC_LAST
|
VIR_DOMAIN_CHR_SPICEVMC_LAST
|
||||||
} virDomainChrSpicevmcName;
|
} virDomainChrSpicevmcName;
|
||||||
|
|
||||||
|
|
||||||
|
struct _virDomainChrSourceReconnectDef {
|
||||||
|
virTristateBool enabled;
|
||||||
|
unsigned int timeout;
|
||||||
|
};
|
||||||
|
typedef struct _virDomainChrSourceReconnectDef virDomainChrSourceReconnectDef;
|
||||||
|
typedef virDomainChrSourceReconnectDef *virDomainChrSourceReconnectDefPtr;
|
||||||
|
|
||||||
|
|
||||||
/* The host side information for a character device. */
|
/* The host side information for a character device. */
|
||||||
struct _virDomainChrSourceDef {
|
struct _virDomainChrSourceDef {
|
||||||
int type; /* virDomainChrType */
|
int type; /* virDomainChrType */
|
||||||
@ -1159,6 +1168,7 @@ struct _virDomainChrSourceDef {
|
|||||||
bool tlscreds;
|
bool tlscreds;
|
||||||
int haveTLS; /* enum virTristateBool */
|
int haveTLS; /* enum virTristateBool */
|
||||||
bool tlsFromConfig;
|
bool tlsFromConfig;
|
||||||
|
virDomainChrSourceReconnectDef reconnect;
|
||||||
} tcp;
|
} tcp;
|
||||||
struct {
|
struct {
|
||||||
char *bindHost;
|
char *bindHost;
|
||||||
@ -1169,6 +1179,7 @@ struct _virDomainChrSourceDef {
|
|||||||
struct {
|
struct {
|
||||||
char *path;
|
char *path;
|
||||||
bool listen;
|
bool listen;
|
||||||
|
virDomainChrSourceReconnectDef reconnect;
|
||||||
} nix;
|
} nix;
|
||||||
int spicevmc;
|
int spicevmc;
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user