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. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list