Use the new infrastructure which stores the fds inside 'qemuFDPass'
objects in the private data.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_command.c | 31 +++++++--------------
src/qemu/qemu_hotplug.c | 28 ++++++-------------
src/qemu/qemu_interface.c | 58 ++++++++++++++++++---------------------
src/qemu/qemu_interface.h | 6 ++--
tests/qemuxml2argvmock.c | 28 +++++++++++++------
5 files changed, 67 insertions(+), 84 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 78ea638c26..0b527784c5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8671,23 +8671,27 @@ qemuInterfaceVhostuserConnect(virCommand *cmd,
int
qemuBuildInterfaceConnect(virDomainObj *vm,
virDomainNetDef *net,
- bool standalone G_GNUC_UNUSED)
+ bool standalone)
{
qemuDomainObjPrivate *priv = vm->privateData;
virDomainNetType actualType = virDomainNetGetActualType(net);
qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net);
VIR_AUTOCLOSE vdpafd = -1;
+ bool vhostfd = false;
switch (actualType) {
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ vhostfd = true;
break;
case VIR_DOMAIN_NET_TYPE_DIRECT:
+ vhostfd = true;
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ vhostfd = true;
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@@ -8712,6 +8716,11 @@ qemuBuildInterfaceConnect(virDomainObj *vm,
break;
}
+ if (vhostfd && !standalone) {
+ if (qemuInterfaceOpenVhostNet(vm, net) < 0)
+ return -1;
+ }
+
return 0;
}
@@ -8908,26 +8917,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
virNetDevSetMTU(net->ifname, net->mtu) < 0)
goto cleanup;
- if ((actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
- actualType == VIR_DOMAIN_NET_TYPE_ETHERNET ||
- actualType == VIR_DOMAIN_NET_TYPE_DIRECT) &&
- !standalone) {
- /* Attempt to use vhost-net mode for these types of
- network device */
- vhostfdSize = net->driver.virtio.queues;
- if (!vhostfdSize)
- vhostfdSize = 1;
-
- vhostfd = g_new0(int, vhostfdSize);
- vhostfdName = g_new0(char *, vhostfdSize);
-
- memset(vhostfd, -1, vhostfdSize * sizeof(vhostfd[0]));
-
- if (qemuInterfaceOpenVhostNet(def, net, vhostfd, &vhostfdSize) < 0)
- goto cleanup;
- }
-
slirp = QEMU_DOMAIN_NETWORK_PRIVATE(net)->slirp;
if (slirp && !standalone) {
int slirpfd = qemuSlirpGetFD(slirp);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 90ca35bccf..2bede03e35 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1283,52 +1283,40 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
switch (actualType) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
- tapfdSize = vhostfdSize = net->driver.virtio.queues;
+ tapfdSize = net->driver.virtio.queues;
if (!tapfdSize)
- tapfdSize = vhostfdSize = 1;
+ tapfdSize = 1;
tapfd = g_new0(int, tapfdSize);
memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
- vhostfd = g_new0(int, vhostfdSize);
- memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceBridgeConnect(vm->def, driver, net,
tapfd, &tapfdSize) < 0)
goto cleanup;
iface_connected = true;
- if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) <
0)
- goto cleanup;
break;
case VIR_DOMAIN_NET_TYPE_DIRECT:
- tapfdSize = vhostfdSize = net->driver.virtio.queues;
+ tapfdSize = net->driver.virtio.queues;
if (!tapfdSize)
- tapfdSize = vhostfdSize = 1;
+ tapfdSize = 1;
tapfd = g_new0(int, tapfdSize);
memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
- vhostfd = g_new0(int, vhostfdSize);
- memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceDirectConnect(vm->def, driver, net,
tapfd, tapfdSize,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
goto cleanup;
iface_connected = true;
- if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) <
0)
- goto cleanup;
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
- tapfdSize = vhostfdSize = net->driver.virtio.queues;
+ tapfdSize = net->driver.virtio.queues;
if (!tapfdSize)
- tapfdSize = vhostfdSize = 1;
+ tapfdSize = 1;
tapfd = g_new0(int, tapfdSize);
memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
- vhostfd = g_new0(int, vhostfdSize);
- memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
if (qemuInterfaceEthernetConnect(vm->def, driver, net,
tapfd, tapfdSize) < 0)
goto cleanup;
iface_connected = true;
- if (qemuInterfaceOpenVhostNet(vm->def, net, vhostfd, &vhostfdSize) <
0)
- goto cleanup;
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@@ -1445,7 +1433,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
if (!(netprops = qemuBuildHostNetProps(net,
tapfdName, tapfdSize,
- vhostfdName, vhostfdSize,
+ NULL, 0,
slirpfdName)))
goto cleanup;
@@ -1481,7 +1469,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
if (qemuMonitorAddNetdev(priv->mon, &netprops,
tapfd, tapfdName, tapfdSize,
- vhostfd, vhostfdName, vhostfdSize,
+ NULL, NULL, 0,
slirpfd, slirpfdName) < 0) {
qemuDomainObjExitMonitor(vm);
virDomainAuditNet(vm, NULL, net, "attach", false);
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c
index e6a26e377f..c807be0745 100644
--- a/src/qemu/qemu_interface.c
+++ b/src/qemu/qemu_interface.c
@@ -688,49 +688,46 @@ qemuInterfacePrepareSlirp(virQEMUDriver *driver,
/**
* qemuInterfaceOpenVhostNet:
- * @def: domain definition
+ * @vm: domain object
* @net: network definition
- * @qemuCaps: qemu binary capabilities
- * @vhostfd: array of opened vhost-net device
- * @vhostfdSize: number of file descriptors in @vhostfd array
*
* Open vhost-net, multiple times - if requested.
- * In case, no vhost-net is needed, @vhostfdSize is set to 0
- * and 0 is returned.
*
* Returns: 0 on success
* -1 on failure
*/
int
-qemuInterfaceOpenVhostNet(virDomainDef *def,
- virDomainNetDef *net,
- int *vhostfd,
- size_t *vhostfdSize)
+qemuInterfaceOpenVhostNet(virDomainObj *vm,
+ virDomainNetDef *net)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net);
size_t i;
const char *vhostnet_path = net->backend.vhost;
+ size_t vhostfdSize = net->driver.virtio.queues;
+ g_autofree char *prefix = g_strdup_printf("vhostfd-%s",
net->info.alias);
+
+ if (!vhostfdSize)
+ vhostfdSize = 1;
if (!vhostnet_path)
vhostnet_path = "/dev/vhost-net";
/* If running a plain QEMU guest, or
* if the config says explicitly to not use vhost, return now */
- if (def->virtType != VIR_DOMAIN_VIRT_KVM ||
- net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU) {
- *vhostfdSize = 0;
+ if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM ||
+ net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU)
return 0;
- }
/* If qemu doesn't support vhost-net mode (including the -netdev and
* -device command options), don't try to open the device.
*/
- if (!qemuDomainSupportsNicdev(def, net)) {
+ if (!qemuDomainSupportsNicdev(vm->def, net)) {
if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("vhost-net is not supported with this QEMU
binary"));
return -1;
}
- *vhostfdSize = 0;
return 0;
}
@@ -741,35 +738,34 @@ qemuInterfaceOpenVhostNet(virDomainDef *def,
_("vhost-net is only supported for virtio network
interfaces"));
return -1;
}
- *vhostfdSize = 0;
return 0;
}
- for (i = 0; i < *vhostfdSize; i++) {
- vhostfd[i] = open(vhostnet_path, O_RDWR);
+ for (i = 0; i < vhostfdSize; i++) {
+ VIR_AUTOCLOSE fd = open(vhostnet_path, O_RDWR);
+ g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv);
+ g_autofree char *suffix = g_strdup_printf("%zu", i);
/* If the config says explicitly to use vhost and we couldn't open it,
* report an error.
*/
- if (vhostfd[i] < 0) {
- virDomainAuditNetDevice(def, net, vhostnet_path, false);
+ if (fd < 0) {
+ virDomainAuditNetDevice(vm->def, net, vhostnet_path, false);
if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("vhost-net was requested for an interface, but is
unavailable"));
- goto error;
+ return -1;
}
VIR_WARN("Unable to open vhost-net. Opened so far %zu, requested
%zu",
- i, *vhostfdSize);
- *vhostfdSize = i;
+ i, vhostfdSize);
break;
}
- }
- virDomainAuditNetDevice(def, net, vhostnet_path, *vhostfdSize);
- return 0;
- error:
- while (i--)
- VIR_FORCE_CLOSE(vhostfd[i]);
+ qemuFDPassAddFD(pass, &fd, suffix);
+ netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds,
g_steal_pointer(&pass));
+ }
- return -1;
+ netpriv->vhostfds = g_slist_reverse(netpriv->vhostfds);
+ virDomainAuditNetDevice(vm->def, net, vhostnet_path, vhostfdSize);
+ return 0;
}
diff --git a/src/qemu/qemu_interface.h b/src/qemu/qemu_interface.h
index 438d548065..a566d877b0 100644
--- a/src/qemu/qemu_interface.h
+++ b/src/qemu/qemu_interface.h
@@ -51,10 +51,8 @@ int qemuInterfaceBridgeConnect(virDomainDef *def,
size_t *tapfdSize)
ATTRIBUTE_NONNULL(2);
-int qemuInterfaceOpenVhostNet(virDomainDef *def,
- virDomainNetDef *net,
- int *vhostfd,
- size_t *vhostfdSize) G_GNUC_NO_INLINE;
+int qemuInterfaceOpenVhostNet(virDomainObj *def,
+ virDomainNetDef *net) G_GNUC_NO_INLINE;
int qemuInterfacePrepareSlirp(virQEMUDriver *driver,
virDomainNetDef *net,
diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c
index 08f176667d..aa82ffa2d6 100644
--- a/tests/qemuxml2argvmock.c
+++ b/tests/qemuxml2argvmock.c
@@ -226,20 +226,32 @@ virNetDevOpenvswitchGetVhostuserIfname(const char *path
G_GNUC_UNUSED,
}
int
-qemuInterfaceOpenVhostNet(virDomainDef *def G_GNUC_UNUSED,
- virDomainNetDef *net,
- int *vhostfd,
- size_t *vhostfdSize)
+qemuInterfaceOpenVhostNet(virDomainObj *vm,
+ virDomainNetDef *net)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ qemuDomainNetworkPrivate *netpriv = QEMU_DOMAIN_NETWORK_PRIVATE(net);
+ g_autofree char *prefix = g_strdup_printf("vhostfd-%s",
net->info.alias);
+ size_t vhostfdSize = net->driver.virtio.queues;
size_t i;
- if (!virDomainNetIsVirtioModel(net)) {
- *vhostfdSize = 0;
+ if (!vhostfdSize)
+ vhostfdSize = 1;
+
+ if (!virDomainNetIsVirtioModel(net))
return 0;
+
+ for (i = 0; i < vhostfdSize; i++) {
+ g_autoptr(qemuFDPass) pass = qemuFDPassNewDirect(prefix, priv);
+ g_autofree char *suffix = g_strdup_printf("%zu", i);
+ int fd = STDERR_FILENO + 42 + i;
+
+ qemuFDPassAddFD(pass, &fd, suffix);
+ netpriv->vhostfds = g_slist_prepend(netpriv->vhostfds,
g_steal_pointer(&pass));
}
- for (i = 0; i < *vhostfdSize; i++)
- vhostfd[i] = STDERR_FILENO + 42 + i;
+ netpriv->vhostfds = g_slist_reverse(netpriv->vhostfds);
+
return 0;
}
--
2.35.1