[libvirt] [PATCHv3 07/11] qemu: Allow multiple vhost-net openings
Laine Stump
laine at laine.org
Fri May 17 18:32:48 UTC 2013
On 05/16/2013 08:49 AM, Michal Privoznik wrote:
> With multiqueue network feature, we are advised to pass multiple
> vhost-net FDs as well. The ratio should be 1:1. Therefore we must
> alter the qemuOpenVhostNet function to allow that.
> ---
> src/qemu/qemu_command.c | 60 ++++++++++++++++++++++++++++++++++++-------------
> src/qemu/qemu_command.h | 3 ++-
> src/qemu/qemu_hotplug.c | 12 ++++++----
> 3 files changed, 54 insertions(+), 21 deletions(-)
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index a053d49..ec66a33 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -405,17 +405,34 @@ cleanup:
> }
>
>
> +/**
> + * qemuOpenVhostNet:
> + * @def: domain definition
> + * @net: network definition
> + * @qemuCaps: qemu binary capabilities
> + * @vhostfd: array of opened vhost-net device
> + * @vhostfdSize: size of @vhostfd array
"number of file descriptors in ..."
(since "size" might be mistaken as "size in bytes". I agree that
wouldn't make sense to me, but...)
> + *
> + * 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
> qemuOpenVhostNet(virDomainDefPtr def,
> virDomainNetDefPtr net,
> virQEMUCapsPtr qemuCaps,
> - int *vhostfd)
> + int *vhostfd,
> + int *vhostfdSize)
> {
> - *vhostfd = -1; /* assume we won't use vhost */
> + int i;
>
> /* If the config says explicitly to not use vhost, return now */
> if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_QEMU) {
> - return 0;
> + *vhostfdSize = 0;
> + return 0;
> }
>
> /* If qemu doesn't support vhost-net mode (including the -netdev command
> @@ -430,6 +447,7 @@ qemuOpenVhostNet(virDomainDefPtr def,
> "this QEMU binary"));
> return -1;
> }
> + *vhostfdSize = 0;
> return 0;
> }
>
> @@ -441,23 +459,32 @@ qemuOpenVhostNet(virDomainDefPtr def,
> "virtio network interfaces"));
> return -1;
> }
> + *vhostfdSize = 0;
> return 0;
> }
>
> - *vhostfd = open("/dev/vhost-net", O_RDWR);
> - virDomainAuditNetDevice(def, net, "/dev/vhost-net", *vhostfd >= 0);
> + for (i = 0; i < *vhostfdSize; i++) {
> + vhostfd[i] = open("/dev/vhost-net", O_RDWR);
> + virDomainAuditNetDevice(def, net, "/dev/vhost-net", vhostfd[i] >= 0);
>
> - /* If the config says explicitly to use vhost and we couldn't open it,
> - * report an error.
> - */
> - if ((*vhostfd < 0) &&
> - (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"));
> - return -1;
> + /* If the config says explicitly to use vhost and we couldn't open it,
> + * report an error.
> + */
> + if (vhostfd[i] < 0 &&
> + 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 0;
> +
> +error:
> + while (i--)
> + VIR_FORCE_CLOSE(vhostfd[i]);
> +
> + return -1;
> }
>
> int
> @@ -6477,10 +6504,11 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
> /* Attempt to use vhost-net mode for these types of
> network device */
> int vhostfd;
> + int vhostfdSize = 1;
>
> - if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd) < 0)
> + if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd, &vhostfdSize) < 0)
> goto cleanup;
> - if (vhostfd >= 0) {
> + if (vhostfdSize > 0) {
> virCommandTransferFD(cmd, vhostfd);
> if (virAsprintf(&vhostfdName, "%d", vhostfd) < 0) {
> virReportOOMError();
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index 6765c3a..c87b754 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -170,7 +170,8 @@ int qemuPhysIfaceConnect(virDomainDefPtr def,
> int qemuOpenVhostNet(virDomainDefPtr def,
> virDomainNetDefPtr net,
> virQEMUCapsPtr qemuCaps,
> - int *vhostfd);
> + int *vhostfd,
> + int *vhostfdSize);
>
> int qemuNetworkPrepareDevices(virDomainDefPtr def);
>
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 0a1845a..fdc4b24 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -689,6 +689,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> int tapfd = -1;
> char *vhostfd_name = NULL;
> int vhostfd = -1;
> + int vhostfdSize = 0;
> char *nicstr = NULL;
> char *netstr = NULL;
> virNetDevVPortProfilePtr vport = NULL;
> @@ -738,7 +739,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> priv->qemuCaps)) < 0)
> goto cleanup;
> iface_connected = true;
> - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
> + vhostfdSize = 1;
> + 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,
> @@ -746,10 +748,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
> goto cleanup;
> iface_connected = true;
> - if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
> + vhostfdSize = 1;
> + 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) < 0)
> + vhostfdSize = 1;
> + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd, &vhostfdSize) < 0)
> goto cleanup;
> }
>
> @@ -792,7 +796,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
> goto no_memory;
> }
>
> - if (vhostfd != -1) {
> + if (vhostfdSize > 0) {
> if (virAsprintf(&vhostfd_name, "vhostfd-%s", net->info.alias) < 0)
> goto no_memory;
> }
ACK.
More information about the libvir-list
mailing list