* src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Honor vhost designations, similar to qemu_command code paths. * src/qemu/qemu_command.h (qemuOpenVhostNet): New prototype. * src/qemu/qemu_command.c (qemuOpenVhostNet): Export. --- Hmm, I just realized that it might be nice to have a --driver-name flag in the virsh attach-interface wrapper command. Oh well, that can be a separate patch. src/qemu/qemu_command.c | 3 +- src/qemu/qemu_command.h | 4 +++ src/qemu/qemu_hotplug.c | 54 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 198a4e2..8cf1737 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -303,12 +303,11 @@ cleanup: } -static int +int qemuOpenVhostNet(virDomainNetDefPtr net, virBitmapPtr qemuCaps, int *vhostfd) { - *vhostfd = -1; /* assume we won't use vhost */ /* If the config says explicitly to not use vhost, return now */ diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 1902472..2ae364c 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -129,6 +129,10 @@ int qemuPhysIfaceConnect(virConnectPtr conn, const unsigned char *vmuuid, enum virVMOperationType vmop); +int qemuOpenVhostNet(virDomainNetDefPtr net, + virBitmapPtr qemuCaps, + int *vhostfd); + int qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 7895062..e8567ad 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -552,6 +552,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, qemuDomainObjPrivatePtr priv = vm->privateData; char *tapfd_name = NULL; int tapfd = -1; + char *vhostfd_name = NULL; + int vhostfd = -1; char *nicstr = NULL; char *netstr = NULL; int ret = -1; @@ -592,6 +594,24 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, return -1; } + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK || + net->type == VIR_DOMAIN_NET_TYPE_BRIDGE || + net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + /* Attempt to use vhost-net mode for these types of + network device */ + if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0) + goto cleanup; + + if (vhostfd >= 0 && + priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("network device type '%s' cannot be attached: " + "qemu is not using a unix socket monitor"), + virDomainNetTypeToString(net->type)); + goto cleanup; + } + } + if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) goto no_memory; @@ -636,15 +656,32 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } } - /* FIXME - need to support vhost-net here (5th arg) */ + if (vhostfd != -1) { + if (virAsprintf(&vhostfd_name, "vhostfd-%s", net->info.alias) < 0) + goto no_memory; + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + if (qemuMonitorSendFileHandle(priv->mon, vhostfd_name, vhostfd) < 0) { + qemuDomainObjExitMonitorWithDriver(driver, vm); + goto try_tapfd_close; + } + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (!virDomainObjIsActive(vm)) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("guest unexpectedly quit")); + goto cleanup; + } + } + if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { if (!(netstr = qemuBuildHostNetStr(net, ',', - -1, tapfd_name, 0))) + -1, tapfd_name, vhostfd_name))) goto try_tapfd_close; } else { if (!(netstr = qemuBuildHostNetStr(net, ' ', - vlan, tapfd_name, 0))) + vlan, tapfd_name, vhostfd_name))) goto try_tapfd_close; } @@ -666,6 +703,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, qemuDomainObjExitMonitorWithDriver(driver, vm); VIR_FORCE_CLOSE(tapfd); + VIR_FORCE_CLOSE(vhostfd); if (!virDomainObjIsActive(vm)) { qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -720,6 +758,8 @@ cleanup: VIR_FREE(netstr); VIR_FREE(tapfd_name); VIR_FORCE_CLOSE(tapfd); + VIR_FREE(vhostfd_name); + VIR_FORCE_CLOSE(vhostfd); return ret; @@ -759,10 +799,14 @@ try_tapfd_close: if (!virDomainObjIsActive(vm)) goto cleanup; - if (tapfd_name) { + if (tapfd_name || vhostfd_name) { qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuMonitorCloseFileHandle(priv->mon, tapfd_name) < 0) + if (tapfd_name && + qemuMonitorCloseFileHandle(priv->mon, tapfd_name) < 0) VIR_WARN("Failed to close tapfd with '%s'", tapfd_name); + if (vhostfd_name && + qemuMonitorCloseFileHandle(priv->mon, vhostfd_name) < 0) + VIR_WARN("Failed to close vhostfd with '%s'", vhostfd_name); qemuDomainObjExitMonitorWithDriver(driver, vm); } -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list