mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-15 09:53:44 -06:00
Support vhost-net mode at qemu startup for virtio network devices
Attempt to turn on vhost-net mode for devices of type NETWORK, BRIDGE, and DIRECT (macvtap). * src/qemu/qemu_conf.h: add vhostfd to qemuBuildHostNetStr prototype add qemudOpenVhostNet prototype new flag to set when :,vhost=" found in qemu help * src/qemu/qemu_conf.c: * set QEMUD_CMD_FLAG_VNET_HOST is ",vhost=" found in qemu help - qemudOpenVhostNet - opens /dev/vhost-net to pass to qemu if everything is in place to use it. - qemuBuildHostNetStr - add vhostfd to commandline if it's not empty (higher levels decide whether or not to fill it in) - qemudBuildCommandLine - if /dev/vhost-net is successfully opened, add its fd to tapfds array so it isn't closed on qemu exec, and populate vhostfd_name to be passed in to commandline builder. * src/qemu/qemu_driver.c: add filler 0 for new arg to qemuBuildHostNetStr, along with a note that this must be implemented in order for hot-plug of vhost-net virtio devices to work properly (once qemu "netdev_add" monitor command is implemented).
This commit is contained in:
parent
caad0a8783
commit
598a0c00dc
@ -1183,6 +1183,10 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
|
||||
if (is_kvm && (version >= 10000 || kvm_version >= 74))
|
||||
flags |= QEMUD_CMD_FLAG_VNET_HDR;
|
||||
|
||||
if (is_kvm && strstr(help, ",vhost=")) {
|
||||
flags |= QEMUD_CMD_FLAG_VNET_HOST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling of -incoming arg with varying features
|
||||
* -incoming tcp (kvm >= 79, qemu >= 0.10.0)
|
||||
@ -1597,6 +1601,27 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemudOpenVhostNet(virDomainNetDefPtr net,
|
||||
unsigned long long qemuCmdFlags)
|
||||
{
|
||||
|
||||
/* If qemu supports vhost-net mode (including the -netdev command
|
||||
* option), the nic model is virtio, and we can open
|
||||
* /dev/vhost_net, assume that vhost-net mode is available and
|
||||
* return the fd to /dev/vhost_net. Otherwise, return -1.
|
||||
*/
|
||||
|
||||
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_VNET_HOST &&
|
||||
qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV &&
|
||||
qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE &&
|
||||
net->model && STREQ(net->model, "virtio")))
|
||||
return -1;
|
||||
|
||||
return open("/dev/vhost-net", O_RDWR, 0);
|
||||
}
|
||||
|
||||
|
||||
static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info,
|
||||
const char *prefix)
|
||||
{
|
||||
@ -2611,7 +2636,8 @@ char *
|
||||
qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||
char type_sep,
|
||||
int vlan,
|
||||
const char *tapfd)
|
||||
const char *tapfd,
|
||||
const char *vhostfd)
|
||||
{
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
@ -2680,6 +2706,10 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||
type_sep, net->info.alias);
|
||||
}
|
||||
|
||||
if (vhostfd && *vhostfd) {
|
||||
virBufferVSprintf(&buf, ",vhost=on,vhostfd=%s", vhostfd);
|
||||
}
|
||||
|
||||
if (virBufferError(&buf)) {
|
||||
virBufferFreeAndReset(&buf);
|
||||
virReportOOMError();
|
||||
@ -3828,6 +3858,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
virDomainNetDefPtr net = def->nets[i];
|
||||
char *nic, *host;
|
||||
char tapfd_name[50];
|
||||
char vhostfd_name[50] = "";
|
||||
int vlan;
|
||||
|
||||
/* VLANs are not used with -netdev, so don't record them */
|
||||
@ -3871,6 +3902,24 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
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 */
|
||||
int vhostfd = qemudOpenVhostNet(net, qemuCmdFlags);
|
||||
if (vhostfd >= 0) {
|
||||
if (VIR_REALLOC_N(*tapfds, (*ntapfds)+1) < 0) {
|
||||
close(vhostfd);
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
(*tapfds)[(*ntapfds)++] = vhostfd;
|
||||
if (snprintf(vhostfd_name, sizeof(vhostfd_name), "%d", vhostfd)
|
||||
>= sizeof(vhostfd_name))
|
||||
goto no_memory;
|
||||
}
|
||||
}
|
||||
/* Possible combinations:
|
||||
*
|
||||
* 1. Old way: -net nic,model=e1000,vlan=1 -net tap,vlan=1
|
||||
@ -3882,8 +3931,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
if ((qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV) &&
|
||||
(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
|
||||
ADD_ARG_LIT("-netdev");
|
||||
if (!(host = qemuBuildHostNetStr(net, ',',
|
||||
vlan, tapfd_name)))
|
||||
if (!(host = qemuBuildHostNetStr(net, ',', vlan,
|
||||
tapfd_name, vhostfd_name)))
|
||||
goto error;
|
||||
ADD_ARG(host);
|
||||
}
|
||||
@ -3901,8 +3950,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||
if (!((qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV) &&
|
||||
(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))) {
|
||||
ADD_ARG_LIT("-net");
|
||||
if (!(host = qemuBuildHostNetStr(net, ',',
|
||||
vlan, tapfd_name)))
|
||||
if (!(host = qemuBuildHostNetStr(net, ',', vlan,
|
||||
tapfd_name, vhostfd_name)))
|
||||
goto error;
|
||||
ADD_ARG(host);
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ enum qemud_cmd_flags {
|
||||
QEMUD_CMD_FLAG_SMP_TOPOLOGY = (1 << 28), /* Is sockets=s,cores=c,threads=t available for -smp? */
|
||||
QEMUD_CMD_FLAG_NETDEV = (1 << 29), /* The -netdev flag & netdev_add/remove monitor commands */
|
||||
QEMUD_CMD_FLAG_RTC = (1 << 30), /* The -rtc flag for clock options */
|
||||
QEMUD_CMD_FLAG_VNET_HOST = (1 << 31), /* vnet-host support is available in qemu */
|
||||
};
|
||||
|
||||
/* Main driver state */
|
||||
@ -200,7 +201,8 @@ int qemudBuildCommandLine (virConnectPtr conn,
|
||||
char * qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||
char type_sep,
|
||||
int vlan,
|
||||
const char *tapfd);
|
||||
const char *tapfd,
|
||||
const char *vhostfd);
|
||||
|
||||
/* Legacy, pre device support */
|
||||
char * qemuBuildNicStr(virDomainNetDefPtr net,
|
||||
@ -252,6 +254,10 @@ int qemudNetworkIfaceConnect (virConnectPtr conn,
|
||||
unsigned long long qemuCmdFlags)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
int
|
||||
qemudOpenVhostNet(virDomainNetDefPtr net,
|
||||
unsigned long long qemuCmdFlags);
|
||||
|
||||
int qemudPhysIfaceConnect(virConnectPtr conn,
|
||||
struct qemud_driver *driver,
|
||||
virDomainNetDefPtr net,
|
||||
|
@ -6373,8 +6373,9 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
|
||||
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||
}
|
||||
|
||||
/* FIXME - need to support vhost-net here (5th arg) */
|
||||
if (!(netstr = qemuBuildHostNetStr(net, ' ',
|
||||
vlan, tapfd_name)))
|
||||
vlan, tapfd_name, 0)))
|
||||
goto try_tapfd_close;
|
||||
|
||||
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||
|
Loading…
Reference in New Issue
Block a user