Use the new infrastructure which stores the fds inside 'qemuFDPass' objects in the private data. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- 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