network: return netdev name or pci addr of the VF in actualDevice

The network pool should be able to keep track of both network device
names and PCI addresses, and return the appropriate one in the
actualDevice when networkAllocateActualDevice is called.

Signed-off-by: Shradha Shah <sshah@solarflare.com>
This commit is contained in:
Shradha Shah 2012-08-16 16:41:58 +01:00 committed by Laine Stump
parent 1446003419
commit 2b51a63bab
3 changed files with 49 additions and 39 deletions

View File

@ -59,6 +59,7 @@
#include "dnsmasq.h" #include "dnsmasq.h"
#include "configmake.h" #include "configmake.h"
#include "virnetdev.h" #include "virnetdev.h"
#include "pci.h"
#include "virnetdevbridge.h" #include "virnetdevbridge.h"
#include "virnetdevtap.h" #include "virnetdevtap.h"
#include "virnetdevvportprofile.h" #include "virnetdevvportprofile.h"
@ -2780,10 +2781,11 @@ static int
networkCreateInterfacePool(virNetworkDefPtr netdef) { networkCreateInterfacePool(virNetworkDefPtr netdef) {
unsigned int num_virt_fns = 0; unsigned int num_virt_fns = 0;
char **vfname = NULL; char **vfname = NULL;
struct pci_config_address **virt_fns;
int ret = -1, ii = 0; int ret = -1, ii = 0;
if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev, if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
&vfname, &num_virt_fns)) < 0) { &vfname, &virt_fns, &num_virt_fns)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not get Virtual functions on %s"), _("Could not get Virtual functions on %s"),
netdef->forwardPfs->dev); netdef->forwardPfs->dev);
@ -2805,18 +2807,34 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) {
netdef->nForwardIfs = num_virt_fns; netdef->nForwardIfs = num_virt_fns;
for (ii = 0; ii < netdef->nForwardIfs; ii++) { for (ii = 0; ii < netdef->nForwardIfs; ii++) {
netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]); if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
if (!netdef->forwardIfs[ii].device.dev) { (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
virReportOOMError(); (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
goto finish; (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
if(vfname[ii]) {
netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
if (!netdef->forwardIfs[ii].device.dev) {
virReportOOMError();
goto finish;
}
}
else {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Direct mode types requires interface names"));
goto finish;
}
} }
} }
ret = 0; ret = 0;
finish: finish:
for (ii = 0; ii < num_virt_fns; ii++) for (ii = 0; ii < num_virt_fns; ii++) {
VIR_FREE(vfname[ii]); VIR_FREE(vfname[ii]);
VIR_FREE(virt_fns[ii]);
}
VIR_FREE(vfname); VIR_FREE(vfname);
VIR_FREE(virt_fns);
return ret; return ret;
} }
@ -3008,31 +3026,22 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
} else { } else {
/* pick an interface from the pool */ /* pick an interface from the pool */
if (netdef->nForwardPfs > 0 && netdef->nForwardIfs == 0 &&
networkCreateInterfacePool(netdef) < 0) {
goto error;
}
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
* require exclusive access to a device, so current * require exclusive access to a device, so current
* connections count must be 0. Other modes can share, so * connections count must be 0. Other modes can share, so
* just search for the one with the lowest number of * just search for the one with the lowest number of
* connections. * connections.
*/ */
if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) { if ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs <= 0)) { ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
if ((networkCreateInterfacePool(netdef)) < 0) { iface->data.network.actual->virtPortProfile &&
goto error; (iface->data.network.actual->virtPortProfile->virtPortType
} == VIR_NETDEV_VPORT_PROFILE_8021QBH))) {
}
/* pick first dev with 0 connections */
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
if (netdef->forwardIfs[ii].connections == 0) {
dev = &netdef->forwardIfs[ii];
break;
}
}
} else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
iface->data.network.actual->virtPortProfile &&
(iface->data.network.actual->virtPortProfile->virtPortType
== VIR_NETDEV_VPORT_PROFILE_8021QBH)) {
/* pick first dev with 0 connections */ /* pick first dev with 0 connections */
for (ii = 0; ii < netdef->nForwardIfs; ii++) { for (ii = 0; ii < netdef->nForwardIfs; ii++) {

View File

@ -29,6 +29,7 @@
#include "command.h" #include "command.h"
#include "memory.h" #include "memory.h"
#include "pci.h" #include "pci.h"
#include "logging.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
@ -981,18 +982,18 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname,
int int
virNetDevGetVirtualFunctions(const char *pfname, virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname, char ***vfname,
struct pci_config_address ***virt_fns,
unsigned int *n_vfname) unsigned int *n_vfname)
{ {
int ret = -1, i; int ret = -1, i;
char *pf_sysfs_device_link = NULL; char *pf_sysfs_device_link = NULL;
char *pci_sysfs_device_link = NULL; char *pci_sysfs_device_link = NULL;
struct pci_config_address **virt_fns;
char *pciConfigAddr; char *pciConfigAddr;
if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0) if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
return ret; return ret;
if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns, if (pciGetVirtualFunctions(pf_sysfs_device_link, virt_fns,
n_vfname) < 0) n_vfname) < 0)
goto cleanup; goto cleanup;
@ -1003,10 +1004,10 @@ virNetDevGetVirtualFunctions(const char *pfname,
for (i = 0; i < *n_vfname; i++) for (i = 0; i < *n_vfname; i++)
{ {
if (pciGetDeviceAddrString(virt_fns[i]->domain, if (pciGetDeviceAddrString((*virt_fns)[i]->domain,
virt_fns[i]->bus, (*virt_fns)[i]->bus,
virt_fns[i]->slot, (*virt_fns)[i]->slot,
virt_fns[i]->function, (*virt_fns)[i]->function,
&pciConfigAddr) < 0) { &pciConfigAddr) < 0) {
virReportSystemError(ENOSYS, "%s", virReportSystemError(ENOSYS, "%s",
_("Failed to get PCI Config Address String")); _("Failed to get PCI Config Address String"));
@ -1019,20 +1020,17 @@ virNetDevGetVirtualFunctions(const char *pfname,
} }
if (pciDeviceNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) { if (pciDeviceNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) {
virReportSystemError(ENOSYS, "%s", VIR_INFO("VF does not have an interface name");
_("Failed to get interface name of the VF"));
goto cleanup;
} }
} }
ret = 0; ret = 0;
cleanup: cleanup:
if (ret < 0) if (ret < 0) {
VIR_FREE(*vfname); VIR_FREE(*vfname);
for (i = 0; i < *n_vfname; i++) VIR_FREE(*virt_fns);
VIR_FREE(virt_fns[i]); }
VIR_FREE(virt_fns);
VIR_FREE(pf_sysfs_device_link); VIR_FREE(pf_sysfs_device_link);
VIR_FREE(pci_sysfs_device_link); VIR_FREE(pci_sysfs_device_link);
VIR_FREE(pciConfigAddr); VIR_FREE(pciConfigAddr);
@ -1169,6 +1167,7 @@ cleanup:
int int
virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED, virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
char ***vfname ATTRIBUTE_UNUSED, char ***vfname ATTRIBUTE_UNUSED,
struct pci_config_address ***virt_fns ATTRIBUTE_UNUSED,
unsigned int *n_vfname ATTRIBUTE_UNUSED) unsigned int *n_vfname ATTRIBUTE_UNUSED)
{ {
virReportSystemError(ENOSYS, "%s", virReportSystemError(ENOSYS, "%s",

View File

@ -26,6 +26,7 @@
# include "virsocketaddr.h" # include "virsocketaddr.h"
# include "virnetlink.h" # include "virnetlink.h"
# include "virmacaddr.h" # include "virmacaddr.h"
# include "pci.h"
int virNetDevExists(const char *brname) int virNetDevExists(const char *brname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
@ -103,9 +104,10 @@ int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
int virNetDevGetVirtualFunctions(const char *pfname, int virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname, char ***vfname,
struct pci_config_address ***virt_fns,
unsigned int *n_vfname) unsigned int *n_vfname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
int virNetDevLinkDump(const char *ifname, int ifindex, int virNetDevLinkDump(const char *ifname, int ifindex,
struct nlattr **tb, struct nlattr **tb,