network: support <driver name='vfio'/> in network definitions

I remembered to document this bit, but somehow forgot to implement it.

This adds <driver name='kvm|vfio'/> as a subelement to the <forward>
element of a network (this puts it parallel to the match between
mode='hostdev' attribute in a network and type='hostdev' in an
<interface>).

Since it's already documented, only the parser, formatter, backend
driver recognition (it just translates/moves the flag into the
<interface> at the appropriate time), and a test case were needed.

(I used a separate enum for the values both because the original is
defined in domain_conf.h, which is unavailable from network_conf.h,
and because in the future it's possible that we may want to support
other non-hostdev oriented driver names in the network parser; this
makes sure that one can be expanded without the other).
This commit is contained in:
Laine Stump 2013-04-26 16:23:27 -04:00
parent 2d80fbb14d
commit d64e114f14
5 changed files with 79 additions and 2 deletions

View File

@ -60,6 +60,12 @@ VIR_ENUM_IMPL(virNetworkForwardHostdevDevice,
VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
"none", "pci", "netdev")
VIR_ENUM_IMPL(virNetworkForwardDriverName,
VIR_NETWORK_FORWARD_DRIVER_NAME_LAST,
"default",
"kvm",
"vfio")
virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjListPtr nets,
const unsigned char *uuid)
{
@ -1443,6 +1449,7 @@ virNetworkForwardDefParseXML(const char *networkName,
int nForwardIfs, nForwardAddrs, nForwardPfs, nForwardNats;
char *forwardDev = NULL;
char *forwardManaged = NULL;
char *forwardDriverName = NULL;
char *type = NULL;
xmlNodePtr save = ctxt->node;
@ -1465,6 +1472,21 @@ virNetworkForwardDefParseXML(const char *networkName,
def->managed = true;
}
forwardDriverName = virXPathString("string(./driver/@name)", ctxt);
if (forwardDriverName) {
int driverName
= virNetworkForwardDriverNameTypeFromString(forwardDriverName);
if (driverName <= 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown forward <driver name='%s'/> "
"in network %s"),
forwardDriverName, networkName);
goto cleanup;
}
def->driverName = driverName;
}
/* bridge and hostdev modes can use a pool of physical interfaces */
nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
if (nForwardIfs < 0) {
@ -1646,6 +1668,7 @@ cleanup:
VIR_FREE(type);
VIR_FREE(forwardDev);
VIR_FREE(forwardManaged);
VIR_FREE(forwardDriverName);
VIR_FREE(forwardPfNodes);
VIR_FREE(forwardIfNodes);
VIR_FREE(forwardAddrNodes);
@ -2230,10 +2253,24 @@ virNetworkDefFormatInternal(virBufferPtr buf,
|| VIR_SOCKET_ADDR_VALID(&def->forward.addr.start)
|| VIR_SOCKET_ADDR_VALID(&def->forward.addr.end)
|| def->forward.port.start
|| def->forward.port.end);
|| def->forward.port.end
|| (def->forward.driverName
!= VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT));
virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
virBufferAdjustIndent(buf, 2);
if (def->forward.driverName
!= VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT) {
const char *driverName
= virNetworkForwardDriverNameTypeToString(def->forward.driverName);
if (!driverName) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected hostdev driver name type %d "),
def->forward.driverName);
goto error;
}
virBufferAsprintf(buf, "<driver name='%s'/>\n", driverName);
}
if (def->forward.type == VIR_NETWORK_FORWARD_NAT) {
if (virNetworkForwardNatDefFormat(buf, &def->forward) < 0)
goto error;

View File

@ -1,7 +1,7 @@
/*
* network_conf.h: network XML handling
*
* Copyright (C) 2006-2008, 2012 Red Hat, Inc.
* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -62,6 +62,20 @@ enum virNetworkForwardHostdevDeviceType {
VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
};
/* The backend driver used for devices from the pool. Currently used
* only for PCI devices (vfio vs. kvm), but could be used for other
* device types in the future.
*/
typedef enum {
VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT, /* kvm now, could change */
VIR_NETWORK_FORWARD_DRIVER_NAME_KVM, /* force legacy kvm style */
VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO, /* force vfio */
VIR_NETWORK_FORWARD_DRIVER_NAME_LAST
} virNetworkForwardDriverNameType;
VIR_ENUM_DECL(virNetworkForwardDriverName)
typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef;
typedef virNetworkDHCPHostDef *virNetworkDHCPHostDefPtr;
struct _virNetworkDHCPHostDef {
@ -159,6 +173,7 @@ typedef virNetworkForwardDef *virNetworkForwardDefPtr;
struct _virNetworkForwardDef {
int type; /* One of virNetworkForwardType constants */
bool managed; /* managed attribute for hostdev mode */
int driverName; /* enum virNetworkForwardDriverNameType */
/* If there are multiple forward devices (i.e. a pool of
* interfaces), they will be listed here.

View File

@ -3859,6 +3859,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
virDomainHostdevSubsysPciBackendType backend;
if (!iface->data.network.actual
&& (VIR_ALLOC(iface->data.network.actual) < 0)) {
virReportOOMError();
@ -3893,6 +3895,27 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
iface->data.network.actual->data.hostdev.def.source.subsys.type = dev->type;
iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.addr = dev->device.pci;
switch (netdef->forward.driverName)
{
case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT:
backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT;
break;
case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_KVM;
break;
case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO:
backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO;
break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unrecognized driver name value %d "
" in network '%s'"),
netdef->forward.driverName, netdef->name);
goto error;
}
iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
= backend;
/* merge virtualports from interface, network, and portgroup to
* arrive at actual virtualport to use
*/

View File

@ -2,6 +2,7 @@
<name>hostdev</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='hostdev' managed='yes'>
<driver name='vfio'/>
<pf dev='eth2'/>
</forward>
</network>

View File

@ -2,6 +2,7 @@
<name>hostdev</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='hostdev' managed='yes'>
<driver name='vfio'/>
<pf dev='eth2'/>
</forward>
</network>