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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list