src/qemu/qemu_command.c | 41 ++++++++++++++++++++++++++---------------
src/qemu/qemu_command.h | 2 ++
src/qemu/qemu_hotplug.c | 16 +++++++++-------
3 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index d1ef4ab..821204e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -212,17 +212,21 @@ qemuVirCommandGetDevSet(virCommandPtr cmd, int fd)
* @def: the definition of the VM (needed by 802.1Qbh and audit)
* @driver: pointer to the driver instance
* @net: pointer to the VM's interface description with direct device type
+ * @tapfd: array of file descriptor return value for the new device
+ * @tapfdSize: number of file descriptors in @tapfd
* @vmop: VM operation type
*
- * Returns a filedescriptor on success or -1 in case of error.
+ * Returns 0 on success or -1 in case of error.
*/
int
qemuPhysIfaceConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
+ int *tapfd,
+ size_t tapfdSize,
virNetDevVPortProfileOp vmop)
{
- int rc;
+ int ret = -1;
char *res_ifname = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
@@ -238,18 +242,18 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
virDomainNetGetActualVirtPortProfile(net),
&res_ifname,
vmop, cfg->stateDir,
- &rc, 1,
+ tapfd, tapfdSize,
macvlan_create_flags) < 0)
- return -1;
+ goto cleanup;
- if (rc >= 0) {
- virDomainAuditNetDevice(def, net, res_ifname, true);
- VIR_FREE(net->ifname);
- net->ifname = res_ifname;
- }
+ virDomainAuditNetDevice(def, net, res_ifname, true);
+ VIR_FREE(net->ifname);
+ net->ifname = res_ifname;
+ ret = 0;
+ cleanup:
virObjectUnref(cfg);
- return rc;
+ return ret;
}
@@ -8746,7 +8750,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
/* Currently nothing besides TAP devices supports multiqueue. */
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -8791,11 +8796,17 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
tapfd, &tapfdSize) < 0)
goto cleanup;
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
- if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0)
+ tapfdSize = net->driver.virtio.queues;
+ if (!tapfdSize)
+ tapfdSize = 1;
+
+ if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
+ VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
goto cleanup;
- tapfdSize = 1;
- tapfd[0] = qemuPhysIfaceConnect(def, driver, net, vmop);
- if (tapfd[0] < 0)
+
+ memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
+
+ if (qemuPhysIfaceConnect(def, driver, net, tapfd, tapfdSize, vmop) < 0)
goto cleanup;
}
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index bebdd27..f0d6900 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -232,6 +232,8 @@ int qemuNetworkIfaceConnect(virDomainDefPtr def,
int qemuPhysIfaceConnect(virDomainDefPtr def,
virQEMUDriverPtr driver,
virDomainNetDefPtr net,
+ int *tapfd,
+ size_t tapfdSize,
virNetDevVPortProfileOp vmop);
int qemuOpenVhostNet(virDomainDefPtr def,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 8804d3d..1a3b278 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -947,15 +947,17 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
goto cleanup;
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
- tapfdSize = vhostfdSize = 1;
- if (VIR_ALLOC(tapfd) < 0)
+ tapfdSize = vhostfdSize = net->driver.virtio.queues;
+ if (!tapfdSize)
+ tapfdSize = vhostfdSize = 1;
+ if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
goto cleanup;
- *tapfd = -1;
- if (VIR_ALLOC(vhostfd) < 0)
+ memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
+ if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
goto cleanup;
- *vhostfd = -1;
- if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
- VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
+ memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
+ if (qemuPhysIfaceConnect(vm->def, driver, net, tapfd, tapfdSize,
+ VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
goto cleanup;
iface_connected = true;
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)