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)
}
+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)
{
qemuBuildHostNetStr(virDomainNetDefPtr net,
char type_sep,
int vlan,
- const char *tapfd)
+ const char *tapfd,
+ const char *vhostfd)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
type_sep, net->info.alias);
}
+ if (vhostfd && *vhostfd) {
+ virBufferVSprintf(&buf, ",vhost=on,vhostfd=%s", vhostfd);
+ }
+
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
virReportOOMError();
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 */
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
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);
}
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);
}
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 */
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,
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,