---
src/qemu/qemu_command.c | 88 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 64 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index dfcfedc..60873c7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5816,12 +5816,16 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
enum virNetDevVPortProfileOp vmop)
{
int ret = -1;
- int tapfd = -1;
char *nic = NULL, *host = NULL;
- char *tapfdName = NULL;
- char *vhostfdName = NULL;
+ int *tapfd = NULL;
+ int tapfdSize = 0;
+ int *vhostfd = NULL;
+ int vhostfdSize = 0;
+ char **tapfdName = NULL;
+ char **vhostfdName = NULL;
int bootindex = bootNet;
int actualType;
+ int i;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
if (!bootindex)
@@ -5883,14 +5887,25 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
cfg->privileged ||
(!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
+ if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ tapfdSize = 1;
if (qemuNetworkIfaceConnect(def, conn, driver, net,
- qemuCaps, &tapfd, 1) < 0)
+ qemuCaps, tapfd, tapfdSize) < 0)
goto cleanup;
}
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
- tapfd = qemuPhysIfaceConnect(def, driver, net,
- qemuCaps, vmop);
- if (tapfd < 0)
+ if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ tapfdSize = 1;
+ tapfd[0] = qemuPhysIfaceConnect(def, driver, net,
+ qemuCaps, vmop);
+ if (tapfd[0] < 0)
goto cleanup;
}
@@ -5898,31 +5913,42 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
+ int useVhost;
/* Attempt to use vhost-net mode for these types of
network device */
- int vhostfd;
-
- if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd, 1) < 0)
+ if (VIR_ALLOC(vhostfd) < 0 || VIR_ALLOC(vhostfdName)) {
+ virReportOOMError();
goto cleanup;
- if (vhostfd >= 0) {
- virCommandTransferFD(cmd, vhostfd);
-
- if (virAsprintf(&vhostfdName, "%d", vhostfd) < 0) {
- virReportOOMError();
- goto cleanup;
- }
}
+ vhostfdSize = 1;
+
+ useVhost = qemuOpenVhostNet(def, net, qemuCaps, vhostfd, vhostfdSize);
+ if (useVhost < 0)
+ goto cleanup;
+ if (useVhost > 0)
+ vhostfdSize = 0;
}
- if (tapfd >= 0) {
- virCommandTransferFD(cmd, tapfd);
+ for (i = 0; i < tapfdSize; i++) {
+ virCommandTransferFD(cmd, tapfd[i]);
- if (virAsprintf(&tapfdName, "%d", tapfd) < 0) {
+ if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0) {
virReportOOMError();
goto cleanup;
}
}
+ for (i = 0; i < vhostfdSize; i++) {
+ if (vhostfd[i] >= 0) {
+ virCommandTransferFD(cmd, vhostfd[i]);
+
+ if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ }
+
/* Possible combinations:
*
* 1. Old way: -net nic,model=e1000,vlan=1 -net tap,vlan=1
@@ -5935,8 +5961,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
',', vlan,
- &tapfdName, tapfdName ? 1 : 0,
- &vhostfdName, vhostfdName ? 1 : 0)))
+ tapfdName, tapfdSize,
+ vhostfdName, vhostfdSize)))
goto cleanup;
virCommandAddArgList(cmd, "-netdev", host, NULL);
}
@@ -5953,8 +5979,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
',', vlan,
- &tapfdName, tapfdName ? 1 : 0,
- &vhostfdName, vhostfdName ? 1 : 0)))
+ tapfdName, tapfdSize,
+ vhostfdName, vhostfdSize)))
goto cleanup;
virCommandAddArgList(cmd, "-net", host, NULL);
}
@@ -5963,6 +5989,20 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
cleanup:
if (ret < 0)
virDomainConfNWFilterTeardown(net);
+ for (i = 0; i < tapfdSize; i++) {
+ if (ret < 0)
+ VIR_FORCE_CLOSE(tapfd[i]);
+ VIR_FREE(tapfdName[i]);
+ }
+ for (i = 0; i < vhostfdSize; i++) {
+ if (ret < 0)
+ VIR_FORCE_CLOSE(vhostfd[i]);
+ VIR_FREE(vhostfdName[i]);
+ }
+ VIR_FREE(tapfdName);
+ VIR_FREE(tapfd);
+ VIR_FREE(vhostfdName);
+ VIR_FREE(vhostfd);
VIR_FREE(nic);
VIR_FREE(host);
VIR_FREE(tapfdName);
--
1.8.1.5