The qemuBuildHostNetStr() function which is responsible for
generating command line for a network interface needs to be aware
of multiqueue network interface as we are required to use:
- fd=%d in case of one FD
- fds=%d:%d:%d:...:%d in case of multiple FDs
These two approaches can't be mixed. Same applies for vhost FDs.
---
src/qemu/qemu_command.c | 46 +++++++++++++++++++++++++++++++++++++---------
src/qemu/qemu_command.h | 6 ++++--
src/qemu/qemu_hotplug.c | 10 ++++++----
3 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4af2d04..b5374e0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3748,14 +3748,17 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps,
char type_sep,
int vlan,
- const char *tapfd,
- const char *vhostfd)
+ char **tapfd,
+ int tapfdSize,
+ char **vhostfd,
+ int vhostfdSize)
{
bool is_tap = false;
virBuffer buf = VIR_BUFFER_INITIALIZER;
enum virDomainNetType netType = virDomainNetGetActualType(net);
const char *brname = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ int i;
if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -3782,7 +3785,19 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
}
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
- virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd);
+ virBufferAsprintf(&buf, "tap%c", type_sep);
+ /* for one tapfd 'fd=' shall be used,
+ * for more than one 'fds=' is the right choice */
+ if (tapfdSize == 1) {
+ virBufferAsprintf(&buf, "fd=%s", tapfd[0]);
+ } else {
+ virBufferAddLit(&buf, "fds=");
+ for (i = 0; i < tapfdSize; i++) {
+ if (i)
+ virBufferAddChar(&buf, ':');
+ virBufferAdd(&buf, tapfd[i], -1);
+ }
+ }
type_sep = ',';
is_tap = true;
break;
@@ -3842,8 +3857,19 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
}
if (is_tap) {
- if (vhostfd && *vhostfd)
- virBufferAsprintf(&buf, ",vhost=on,vhostfd=%s", vhostfd);
+ if (vhostfdSize) {
+ virBufferAddLit(&buf, ",vhost=on,");
+ if (vhostfdSize == 1) {
+ virBufferAsprintf(&buf, "vhostfd=%s", vhostfd[0]);
+ } else {
+ virBufferAddLit(&buf, "vhostfds=");
+ for (i = 0; i < vhostfdSize; i++) {
+ if (i)
+ virBufferAddChar(&buf, ':');
+ virBufferAdd(&buf, vhostfd[i], -1);
+ }
+ }
+ }
if (net->tune.sndbuf_specified)
virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
}
@@ -5882,8 +5908,9 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
- ',', vlan, tapfdName,
- vhostfdName)))
+ ',', vlan,
+ &tapfdName, tapfdName ? 1 : 0,
+ &vhostfdName, vhostfdName ? 1 : 0)))
goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL);
}
@@ -5899,8 +5926,9 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
- ',', vlan, tapfdName,
- vhostfdName)))
+ ',', vlan,
+ &tapfdName, tapfdName ? 1 : 0,
+ &vhostfdName, vhostfdName ? 1 : 0)))
goto cleanup;
virCommandAddArgList(cmd, "-net", host, NULL);
}
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 1789c20..d1ae325 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -74,8 +74,10 @@ char * qemuBuildHostNetStr(virDomainNetDefPtr net,
virQEMUCapsPtr qemuCaps,
char type_sep,
int vlan,
- const char *tapfd,
- const char *vhostfd);
+ char **tapfd,
+ int tapfdSize,
+ char **vhostfd,
+ int vhostfdSize);
/* Legacy, pre device support */
char * qemuBuildNicStr(virDomainNetDefPtr net,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d1347c6..26b91bc 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -807,13 +807,15 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
- ',', -1, tapfd_name,
- vhostfd_name)))
+ ',', -1,
+ &tapfd_name, tapfd_name ? 1 : 0,
+ &vhostfd_name, vhostfd_name ? 1 : 0)))
goto cleanup;
} else {
if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
- ' ', vlan, tapfd_name,
- vhostfd_name)))
+ ' ', vlan,
+ &tapfd_name, tapfd_name ? 1 : 0,
+ &vhostfd_name, vhostfd_name ? 1 : 0)))
goto cleanup;
}
--
1.8.1.5