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