---
src/qemu/qemu_hotplug.c | 96 +++++++++++++++++++++++++++++++------------------
1 file changed, 61 insertions(+), 35 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 953339b..695edc7 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -685,10 +685,11 @@ 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;
@@ -700,6 +701,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) {
@@ -735,25 +737,37 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ 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;
- vhostfdSize = 1;
- if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd,
&vhostfdSize) < 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;
- vhostfdSize = 1;
- if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd,
&vhostfdSize) < 0)
+ if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd,
&vhostfdSize) < 0)
goto cleanup;
} else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+ if (VIR_ALLOC(vhostfd) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
vhostfdSize = 1;
- if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd,
&vhostfdSize) < 0)
+ if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd,
&vhostfdSize) < 0)
goto cleanup;
}
@@ -791,13 +805,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 (vhostfdSize > 0) {
- 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;
}
@@ -805,14 +825,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(netstr = qemuBuildHostNetStr(net, driver,
',', -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,
' ', vlan,
- &tapfd_name, tapfd_name ? 1 : 0,
- &vhostfd_name, vhostfd_name ? 1 : 0)))
+ tapfdName, tapfdSize,
+ vhostfdName, vhostfdSize)))
goto cleanup;
}
@@ -820,20 +840,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;
@@ -841,8 +857,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",
@@ -938,10 +956,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.2.1