qemu: support vhost in attach-interface

* 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.
This commit is contained in:
Eric Blake 2011-03-08 21:43:33 -07:00
parent 346236fea9
commit 5d09151341
3 changed files with 40 additions and 7 deletions

View File

@ -303,12 +303,11 @@ cleanup:
} }
static int int
qemuOpenVhostNet(virDomainNetDefPtr net, qemuOpenVhostNet(virDomainNetDefPtr net,
virBitmapPtr qemuCaps, virBitmapPtr qemuCaps,
int *vhostfd) int *vhostfd)
{ {
*vhostfd = -1; /* assume we won't use vhost */ *vhostfd = -1; /* assume we won't use vhost */
/* If the config says explicitly to not use vhost, return now */ /* If the config says explicitly to not use vhost, return now */

View File

@ -129,6 +129,10 @@ int qemuPhysIfaceConnect(virConnectPtr conn,
const unsigned char *vmuuid, const unsigned char *vmuuid,
enum virVMOperationType vmop); enum virVMOperationType vmop);
int qemuOpenVhostNet(virDomainNetDefPtr net,
virBitmapPtr qemuCaps,
int *vhostfd);
int qemudCanonicalizeMachine(struct qemud_driver *driver, int qemudCanonicalizeMachine(struct qemud_driver *driver,
virDomainDefPtr def); virDomainDefPtr def);

View File

@ -552,6 +552,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
char *tapfd_name = NULL; char *tapfd_name = NULL;
int tapfd = -1; int tapfd = -1;
char *vhostfd_name = NULL;
int vhostfd = -1;
char *nicstr = NULL; char *nicstr = NULL;
char *netstr = NULL; char *netstr = NULL;
int ret = -1; int ret = -1;
@ -576,6 +578,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
if ((tapfd = qemuNetworkIfaceConnect(conn, driver, net, qemuCaps)) < 0) if ((tapfd = qemuNetworkIfaceConnect(conn, driver, net, qemuCaps)) < 0)
return -1; return -1;
if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0)
goto cleanup;
} else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@ -590,6 +594,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
vm->def->uuid, vm->def->uuid,
VIR_VM_OP_CREATE)) < 0) VIR_VM_OP_CREATE)) < 0)
return -1; return -1;
if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0)
goto cleanup;
} }
if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
@ -636,15 +642,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) && if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
if (!(netstr = qemuBuildHostNetStr(net, ',', if (!(netstr = qemuBuildHostNetStr(net, ',',
-1, tapfd_name, 0))) -1, tapfd_name, vhostfd_name)))
goto try_tapfd_close; goto try_tapfd_close;
} else { } else {
if (!(netstr = qemuBuildHostNetStr(net, ' ', if (!(netstr = qemuBuildHostNetStr(net, ' ',
vlan, tapfd_name, 0))) vlan, tapfd_name, vhostfd_name)))
goto try_tapfd_close; goto try_tapfd_close;
} }
@ -666,6 +689,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
qemuDomainObjExitMonitorWithDriver(driver, vm); qemuDomainObjExitMonitorWithDriver(driver, vm);
VIR_FORCE_CLOSE(tapfd); VIR_FORCE_CLOSE(tapfd);
VIR_FORCE_CLOSE(vhostfd);
if (!virDomainObjIsActive(vm)) { if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -720,6 +744,8 @@ cleanup:
VIR_FREE(netstr); VIR_FREE(netstr);
VIR_FREE(tapfd_name); VIR_FREE(tapfd_name);
VIR_FORCE_CLOSE(tapfd); VIR_FORCE_CLOSE(tapfd);
VIR_FREE(vhostfd_name);
VIR_FORCE_CLOSE(vhostfd);
return ret; return ret;
@ -759,10 +785,14 @@ try_tapfd_close:
if (!virDomainObjIsActive(vm)) if (!virDomainObjIsActive(vm))
goto cleanup; goto cleanup;
if (tapfd_name) { if (tapfd_name || vhostfd_name) {
qemuDomainObjEnterMonitorWithDriver(driver, vm); 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); 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); qemuDomainObjExitMonitorWithDriver(driver, vm);
} }