--- src/qemu/qemu_hotplug.c | 96 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3505c52..3a00811 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -683,10 +683,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, virDomainNetDefPtr net) { qemuDomainObjPrivatePtr priv = vm->privateData; - char *tapfd_name = NULL; - int tapfd = -1; - char *vhostfd_name = NULL; - int vhostfd = -1; + char **tapfdName = NULL; + int *tapfd = NULL; + int tapfdSize = 0; + char **vhostfdName = NULL; + int *vhostfd = NULL; + int vhostfdSize = 0; char *nicstr = NULL; char *netstr = NULL; virNetDevVPortProfilePtr vport = NULL; @@ -697,6 +699,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, bool iface_connected = false; int actualType; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + int i; /* preallocate new slot for device */ if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) { @@ -740,23 +743,38 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || cfg->privileged || (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) { + if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(vhostfd) < 0) { + virReportOOMError(); + goto cleanup; + } + tapfdSize = vhostfdSize = 1; if (qemuNetworkIfaceConnect(vm->def, conn, driver, net, - priv->qemuCaps, &tapfd, 1) < 0) + priv->qemuCaps, tapfd, tapfdSize) < 0) goto cleanup; iface_connected = true; - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd, 1) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, vhostfdSize) < 0) goto cleanup; } } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) { - if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net, - priv->qemuCaps, - VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0) + if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(vhostfd) < 0) { + virReportOOMError(); + goto cleanup; + } + tapfdSize = vhostfdSize = 1; + if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net, + priv->qemuCaps, + VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0) goto cleanup; iface_connected = true; - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd, 1) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, vhostfdSize) < 0) goto cleanup; } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) { - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd, 1) < 0) + if (VIR_ALLOC(vhostfd) < 0) { + virReportOOMError(); + goto cleanup; + } + vhostfdSize = 1; + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, vhostfdSize) < 0) goto cleanup; } @@ -794,13 +812,19 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } } - if (tapfd != -1) { - if (virAsprintf(&tapfd_name, "fd-%s", net->info.alias) < 0) + if (VIR_ALLOC_N(tapfdName, tapfdSize) < 0 || + VIR_ALLOC_N(vhostfdName, vhostfdSize) < 0) { + virReportOOMError(); + goto cleanup; + } + + for (i = 0; i < tapfdSize; i++) { + if (virAsprintf(&tapfdName[i], "fd-%s%d", net->info.alias, i) < 0) goto no_memory; } - if (vhostfd != -1) { - if (virAsprintf(&vhostfd_name, "vhostfd-%s", net->info.alias) < 0) + for (i = 0; i < vhostfdSize; i++) { + if (virAsprintf(&vhostfdName[i], "vhostfd-%s%d", net->info.alias, i) < 0) goto no_memory; } @@ -808,14 +832,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps, ',', -1, - &tapfd_name, tapfd_name ? 1 : 0, - &vhostfd_name, vhostfd_name ? 1 : 0))) + tapfdName, tapfdSize, + vhostfdName, vhostfdSize))) goto cleanup; } else { if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps, ' ', vlan, - &tapfd_name, tapfd_name ? 1 : 0, - &vhostfd_name, vhostfd_name ? 1 : 0))) + tapfdName, tapfdSize, + vhostfdName, vhostfdSize))) goto cleanup; } @@ -823,20 +847,16 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorAddNetdev(priv->mon, netstr, - &tapfd, &tapfd_name, - tapfd_name ? 1 : 0, - &vhostfd, &vhostfd_name, - vhostfd_name ? 1 : 0) < 0) { + tapfd, tapfdName, tapfdSize, + vhostfd, vhostfdName, vhostfdSize) < 0) { qemuDomainObjExitMonitor(driver, vm); virDomainAuditNet(vm, NULL, net, "attach", false); goto cleanup; } } else { if (qemuMonitorAddHostNetwork(priv->mon, netstr, - &tapfd, &tapfd_name, - tapfd_name ? 1 : 0, - &vhostfd, &vhostfd_name, - vhostfd_name ? 1 : 0) < 0) { + tapfd, tapfdName, tapfdSize, + vhostfd, vhostfdName, vhostfdSize) < 0) { qemuDomainObjExitMonitor(driver, vm); virDomainAuditNet(vm, NULL, net, "attach", false); goto cleanup; @@ -844,8 +864,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjExitMonitor(driver, vm); - VIR_FORCE_CLOSE(tapfd); - VIR_FORCE_CLOSE(vhostfd); + for (i = 0; i < tapfdSize; i++) + VIR_FORCE_CLOSE(tapfd[i]); + for (i = 0; i < vhostfdSize; i++) + VIR_FORCE_CLOSE(vhostfd[i]); if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -941,10 +963,18 @@ cleanup: VIR_FREE(nicstr); VIR_FREE(netstr); - VIR_FREE(tapfd_name); - VIR_FORCE_CLOSE(tapfd); - VIR_FREE(vhostfd_name); - VIR_FORCE_CLOSE(vhostfd); + for (i = 0; i < tapfdSize; i++) { + VIR_FORCE_CLOSE(tapfd[i]); + VIR_FREE(tapfdName[i]); + } + VIR_FREE(tapfd); + VIR_FREE(tapfdName); + for (i = 0; i < vhostfdSize; i++) { + VIR_FORCE_CLOSE(vhostfd[i]); + VIR_FREE(vhostfdName[i]); + } + VIR_FREE(vhostfd); + VIR_FREE(vhostfdName); virObjectUnref(cfg); return ret; -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list