--- src/qemu/qemu_command.c | 85 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d466725..cdca2db 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6425,12 +6425,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 actualType = virDomainNetGetActualType(net); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + int i; if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) { /* NET_TYPE_HOSTDEV devices are really hostdev devices, so @@ -6445,12 +6449,24 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || actualType == VIR_DOMAIN_NET_TYPE_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; } @@ -6458,30 +6474,41 @@ 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 (VIR_ALLOC(vhostfd) < 0 || VIR_ALLOC(vhostfdName)) { + virReportOOMError(); + goto cleanup; + } + vhostfdSize = 1; + + useVhost = qemuOpenVhostNet(def, net, qemuCaps, vhostfd, vhostfdSize); + if (useVhost < 0) + goto cleanup; + if (useVhost > 0) + vhostfdSize = 0; + } - if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd, 1) < 0) + for (i = 0; i < tapfdSize; i++) { + if (virAsprintf(&tapfdName[i], "%d", tapfd[i]) < 0) { + virReportOOMError(); goto cleanup; - if (vhostfd >= 0) { - virCommandTransferFD(cmd, vhostfd); + } + virCommandTransferFD(cmd, tapfd[i]); + } + + for (i = 0; i < vhostfdSize; i++) { + if (vhostfd[i] >= 0) { + virCommandTransferFD(cmd, vhostfd[i]); - if (virAsprintf(&vhostfdName, "%d", vhostfd) < 0) { + if (virAsprintf(&vhostfdName[i], "%d", vhostfd[i]) < 0) { virReportOOMError(); goto cleanup; } } } - if (tapfd >= 0) { - if (virAsprintf(&tapfdName, "%d", tapfd) < 0) { - virReportOOMError(); - goto cleanup; - } - virCommandTransferFD(cmd, tapfd); - } - /* Possible combinations: * * 1. Old way: -net nic,model=e1000,vlan=1 -net tap,vlan=1 @@ -6494,8 +6521,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { if (!(host = qemuBuildHostNetStr(net, driver, ',', vlan, - &tapfdName, tapfdName ? 1 : 0, - &vhostfdName, vhostfdName ? 1 : 0))) + tapfdName, tapfdSize, + vhostfdName, vhostfdSize))) goto cleanup; virCommandAddArgList(cmd, "-netdev", host, NULL); } @@ -6512,8 +6539,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd, virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) { if (!(host = qemuBuildHostNetStr(net, driver, ',', vlan, - &tapfdName, tapfdName ? 1 : 0, - &vhostfdName, vhostfdName ? 1 : 0))) + tapfdName, tapfdSize, + vhostfdName, vhostfdSize))) goto cleanup; virCommandAddArgList(cmd, "-net", host, NULL); } @@ -6522,6 +6549,18 @@ 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(tapfd); + VIR_FREE(vhostfd); VIR_FREE(nic); VIR_FREE(host); VIR_FREE(tapfdName); -- 1.8.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list