For vhost-user ports, Open vSwitch acts as the server and QEMU the client.
When OVS crashes or restarts, the QEMU process should be reconnected to
OVS.
Signed-off-by: ZhiPeng Lu <lu.zhipeng(a)zte.com.cn>
---
docs/schemas/domaincommon.rng | 26 ++++++++------
src/conf/domain_conf.c | 40 ++++++++++++++++++----
src/conf/domain_conf.h | 10 +++---
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_monitor_json.c | 2 +-
.../qemuxml2argv-net-vhostuser-multiq.args | 4 +--
.../qemuxml2argv-net-vhostuser-multiq.xml | 8 +++--
8 files changed, 65 insertions(+), 29 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 76852ab..3f4ed82 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2327,6 +2327,18 @@
</attribute>
</optional>
</define>
+ <define name="reconnect">
+ <element name="reconnect">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ <optional>
+ <attribute name="timeout">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
<!--
An interface description can either be of type bridge in which case
@@ -2388,6 +2400,9 @@
<value>client</value>
</choice>
</attribute>
+ <optional>
+ <ref name="reconnect"/>
+ </optional>
<empty/>
</element>
<ref name="interface-options"/>
@@ -3636,16 +3651,7 @@
</attribute>
</optional>
<optional>
- <element name="reconnect">
- <attribute name="enabled">
- <ref name="virYesNo"/>
- </attribute>
- <optional>
- <attribute name="timeout">
- <ref name="unsignedInt"/>
- </attribute>
- </optional>
- </element>
+ <ref name="reconnect"/>
</optional>
<zeroOrMore>
<ref name='devSeclabel'/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cc5e79b..b7fc3a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -83,6 +83,13 @@ struct _virDomainXMLOption {
/* Private data for save image stored in snapshot XML */
virSaveCookieCallbacks saveCookie;
};
+static int
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt);
+static void
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+ virDomainDeviceSourceReconnectDefPtr def);
#define VIR_DOMAIN_DEF_FORMAT_COMMON_FLAGS \
(VIR_DOMAIN_DEF_FORMAT_SECURE | \
@@ -10245,6 +10252,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
virNWFilterHashTablePtr filterparams = NULL;
virDomainActualNetDefPtr actual = NULL;
xmlNodePtr oldnode = ctxt->node;
+ virDomainDeviceSourceReconnectDef reconnect = {0};
int rv, val;
if (VIR_ALLOC(def) < 0)
@@ -10331,6 +10339,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
vhostuser_type = virXMLPropString(cur, "type");
vhostuser_path = virXMLPropString(cur, "path");
vhostuser_mode = virXMLPropString(cur, "mode");
+ if (virDomainDeviceSourceReconnectDefParseXML(&reconnect, cur, ctxt)
< 0)
+ goto error;
} else if (!def->virtPortProfile
&& virXMLNodeNameEqual(cur, "virtualport")) {
if (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -10552,8 +10562,17 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
if (STREQ(vhostuser_mode, "server")) {
def->data.vhostuser->data.nix.listen = true;
+ if (reconnect.enabled != VIR_TRISTATE_BOOL_ABSENT) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("'reconnect' attribute unsupported "
+ "'server' mode for <interface
type='vhostuser'>"));
+ goto error;
+ }
} else if (STREQ(vhostuser_mode, "client")) {
def->data.vhostuser->data.nix.listen = false;
+ def->data.vhostuser->data.nix.reconnect.enabled = reconnect.enabled;
+ def->data.vhostuser->data.nix.reconnect.timeout = reconnect.timeout;
+ reconnect.enabled = VIR_TRISTATE_BOOL_ABSENT;
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Wrong <source> 'mode' attribute "
@@ -11216,7 +11235,7 @@ virDomainChrDefParseTargetXML(virDomainChrDefPtr def,
}
static int
-virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def,
+virDomainDeviceSourceReconnectDefParseXML(virDomainDeviceSourceReconnectDefPtr def,
xmlNodePtr node,
xmlXPathContextPtr ctxt)
{
@@ -11338,7 +11357,7 @@ virDomainChrSourceDefParseTCP(virDomainChrSourceDefPtr def,
VIR_FREE(tmp);
}
- if (virDomainChrSourceReconnectDefParseXML(&def->data.tcp.reconnect,
+ if (virDomainDeviceSourceReconnectDefParseXML(&def->data.tcp.reconnect,
source,
ctxt) < 0) {
goto error;
@@ -11389,7 +11408,7 @@ virDomainChrSourceDefParseUnix(virDomainChrSourceDefPtr def,
def->data.nix.listen = mode == VIR_DOMAIN_CHR_SOURCE_MODE_BIND;
def->data.nix.path = virXMLPropString(source, "path");
- if (virDomainChrSourceReconnectDefParseXML(&def->data.nix.reconnect,
+ if (virDomainDeviceSourceReconnectDefParseXML(&def->data.nix.reconnect,
source,
ctxt) < 0) {
return -1;
@@ -22984,6 +23003,13 @@ virDomainNetDefFormat(virBufferPtr buf,
def->data.vhostuser->data.nix.listen ?
"server" : "client");
sourceLines++;
+ if (def->data.vhostuser->data.nix.reconnect.enabled !=
VIR_TRISTATE_BOOL_ABSENT) {
+ virBufferAddLit(buf, ">\n");
+ sourceLines++;
+ virBufferAdjustIndent(buf, 2);
+ virDomainDeviceSourceReconnectDefFormat(buf,
&def->data.vhostuser->data.nix.reconnect);
+ virBufferAdjustIndent(buf, -2);
+ }
}
break;
@@ -23218,8 +23244,8 @@ virDomainChrAttrsDefFormat(virBufferPtr buf,
static void
-virDomainChrSourceReconnectDefFormat(virBufferPtr buf,
- virDomainChrSourceReconnectDefPtr def)
+virDomainDeviceSourceReconnectDefFormat(virBufferPtr buf,
+ virDomainDeviceSourceReconnectDefPtr def)
{
if (def->enabled == VIR_TRISTATE_BOOL_ABSENT)
return;
@@ -23314,7 +23340,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
virBufferAsprintf(&attrBuf, " tlsFromConfig='%d'",
def->data.tcp.tlsFromConfig);
- virDomainChrSourceReconnectDefFormat(&childBuf,
+ virDomainDeviceSourceReconnectDefFormat(&childBuf,
&def->data.tcp.reconnect);
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf)
< 0)
@@ -23333,7 +23359,7 @@ virDomainChrSourceDefFormat(virBufferPtr buf,
virDomainSourceDefFormatSeclabel(&childBuf, def->nseclabels,
def->seclabels, flags);
- virDomainChrSourceReconnectDefFormat(&childBuf,
+ virDomainDeviceSourceReconnectDefFormat(&childBuf,
&def->data.nix.reconnect);
if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf)
< 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bb3b6f0..909f60d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1138,12 +1138,12 @@ typedef enum {
} virDomainChrSpicevmcName;
-struct _virDomainChrSourceReconnectDef {
+struct _virDomainDeviceSourceReconnectDef {
virTristateBool enabled;
unsigned int timeout;
};
-typedef struct _virDomainChrSourceReconnectDef virDomainChrSourceReconnectDef;
-typedef virDomainChrSourceReconnectDef *virDomainChrSourceReconnectDefPtr;
+typedef struct _virDomainDeviceSourceReconnectDef virDomainDeviceSourceReconnectDef;
+typedef virDomainDeviceSourceReconnectDef *virDomainDeviceSourceReconnectDefPtr;
/* The host side information for a character device. */
@@ -1168,7 +1168,7 @@ struct _virDomainChrSourceDef {
bool tlscreds;
int haveTLS; /* enum virTristateBool */
bool tlsFromConfig;
- virDomainChrSourceReconnectDef reconnect;
+ virDomainDeviceSourceReconnectDef reconnect;
} tcp;
struct {
char *bindHost;
@@ -1179,7 +1179,7 @@ struct _virDomainChrSourceDef {
struct {
char *path;
bool listen;
- virDomainChrSourceReconnectDef reconnect;
+ virDomainDeviceSourceReconnectDef reconnect;
} nix;
int spicevmc;
struct {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9b3e3fc..4640ce8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5094,7 +5094,7 @@ qemuBuildChrChardevFileStr(virLogManagerPtr logManager,
static void
qemuBuildChrChardevReconnectStr(virBufferPtr buf,
- const virDomainChrSourceReconnectDef *def)
+ const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled == VIR_TRISTATE_BOOL_YES) {
virBufferAsprintf(buf, ",reconnect=%u", def->timeout);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 50b536e..4ea0727 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3244,7 +3244,7 @@ qemuDomainNetSupportsCoalesce(virDomainNetType type)
static int
-qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def)
+qemuDomainChrSourceReconnectDefValidate(const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled == VIR_TRISTATE_BOOL_YES &&
def->timeout == 0) {
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 63b8559..b3d572e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6443,7 +6443,7 @@ int qemuMonitorJSONGetTPMTypes(qemuMonitorPtr mon,
static int
qemuMonitorJSONBuildChrChardevReconnect(virJSONValuePtr object,
- const virDomainChrSourceReconnectDef *def)
+ const virDomainDeviceSourceReconnectDef *def)
{
if (def->enabled != VIR_TRISTATE_BOOL_YES)
return 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
index b69ebd8..0b08f44 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.args
@@ -25,14 +25,14 @@ server,nowait \
-netdev vhost-user,chardev=charnet0,id=hostnet0 \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ee:96:6b,bus=pci.0,\
addr=0x3 \
--chardev socket,id=charnet1,path=/tmp/vhost1.sock \
+-chardev socket,id=charnet1,path=/tmp/vhost1.sock,reconnect=10 \
-netdev vhost-user,chardev=charnet1,id=hostnet1 \
-device virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:ee:96:6c,bus=pci.0,\
addr=0x4 \
-netdev socket,listen=:2015,id=hostnet2 \
-device rtl8139,netdev=hostnet2,id=net2,mac=52:54:00:95:db:c0,bus=pci.0,\
addr=0x5 \
--chardev socket,id=charnet3,path=/tmp/vhost2.sock \
+-chardev socket,id=charnet3,path=/tmp/vhost2.sock,reconnect=0 \
-netdev vhost-user,chardev=charnet3,queues=4,id=hostnet3 \
-device virtio-net-pci,mq=on,vectors=10,netdev=hostnet3,id=net3,\
mac=52:54:00:ee:96:6d,bus=pci.0,addr=0x6
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
index d5c42fe..2fadb1c 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser-multiq.xml
@@ -30,7 +30,9 @@
</interface>
<interface type='vhostuser'>
<mac address='52:54:00:ee:96:6c'/>
- <source type='unix' path='/tmp/vhost1.sock'
mode='client'/>
+ <source type='unix' path='/tmp/vhost1.sock'
mode='client'>
+ <reconnect enabled='yes' timeout='10'/>
+ </source>
<model type='virtio'/>
</interface>
<interface type='server'>
@@ -40,7 +42,9 @@
</interface>
<interface type='vhostuser'>
<mac address='52:54:00:ee:96:6d'/>
- <source type='unix' path='/tmp/vhost2.sock'
mode='client'/>
+ <source type='unix' path='/tmp/vhost2.sock'
mode='client'>
+ <reconnect enabled='no'/>
+ </source>
<model type='virtio'/>
<driver queues='4'/>
</interface>
--
1.8.3.1