]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
network: return netdev name or pci addr of the VF in actualDevice
authorShradha Shah <sshah@solarflare.com>
Thu, 16 Aug 2012 15:41:58 +0000 (16:41 +0100)
committerLaine Stump <laine@laine.org>
Fri, 17 Aug 2012 19:43:26 +0000 (15:43 -0400)
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>
src/network/bridge_driver.c
src/util/virnetdev.c
src/util/virnetdev.h

index bf809bb31d89237343291261d83e668ee5b8218b..eed13a0579ce59220648d3926dc39f307a7055ff 100644 (file)
@@ -59,6 +59,7 @@
 #include "dnsmasq.h"
 #include "configmake.h"
 #include "virnetdev.h"
+#include "pci.h"
 #include "virnetdevbridge.h"
 #include "virnetdevtap.h"
 #include "virnetdevvportprofile.h"
@@ -2780,10 +2781,11 @@ static int
 networkCreateInterfacePool(virNetworkDefPtr netdef) {
     unsigned int num_virt_fns = 0;
     char **vfname = NULL;
+    struct pci_config_address **virt_fns;
     int ret = -1, ii = 0;
 
     if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
-                                      &vfname, &num_virt_fns)) < 0) {
+                                      &vfname, &virt_fns, &num_virt_fns)) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Could not get Virtual functions on %s"),
                        netdef->forwardPfs->dev);
@@ -2805,18 +2807,34 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) {
     netdef->nForwardIfs = num_virt_fns;
 
     for (ii = 0; ii < netdef->nForwardIfs; ii++) {
-        netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
-        if (!netdef->forwardIfs[ii].device.dev) {
-            virReportOOMError();
-            goto finish;
+        if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
+            (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
+            (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
+            (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;
 finish:
-    for (ii = 0; ii < num_virt_fns; ii++)
+    for (ii = 0; ii < num_virt_fns; ii++) {
         VIR_FREE(vfname[ii]);
+        VIR_FREE(virt_fns[ii]);
+    }
     VIR_FREE(vfname);
+    VIR_FREE(virt_fns);
     return ret;
 }
 
@@ -3008,31 +3026,22 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         } else {
             /* 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
              * require exclusive access to a device, so current
              * connections count must be 0.  Other modes can share, so
              * just search for the one with the lowest number of
              * connections.
              */
-            if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) {
-                if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs <= 0)) {
-                    if ((networkCreateInterfacePool(netdef)) < 0) {
-                        goto error;
-                    }
-                }
-
-                /* 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)) {
+            if ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
+                ((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 */
                 for (ii = 0; ii < netdef->nForwardIfs; ii++) {
index 25bdf01e8ca4a6b16c5575aa858c682bcff4c159..f9eba1afb5682487e8cae332bd2963d130f876f4 100644 (file)
@@ -29,6 +29,7 @@
 #include "command.h"
 #include "memory.h"
 #include "pci.h"
+#include "logging.h"
 
 #include <sys/ioctl.h>
 #ifdef HAVE_NET_IF_H
@@ -981,18 +982,18 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname,
 int
 virNetDevGetVirtualFunctions(const char *pfname,
                              char ***vfname,
+                             struct pci_config_address ***virt_fns,
                              unsigned int *n_vfname)
 {
     int ret = -1, i;
     char *pf_sysfs_device_link = NULL;
     char *pci_sysfs_device_link = NULL;
-    struct pci_config_address **virt_fns;
     char *pciConfigAddr;
 
     if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
         return ret;
 
-    if (pciGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
+    if (pciGetVirtualFunctions(pf_sysfs_device_link, virt_fns,
                                n_vfname) < 0)
         goto cleanup;
 
@@ -1003,10 +1004,10 @@ virNetDevGetVirtualFunctions(const char *pfname,
 
     for (i = 0; i < *n_vfname; i++)
     {
-        if (pciGetDeviceAddrString(virt_fns[i]->domain,
-                                   virt_fns[i]->bus,
-                                   virt_fns[i]->slot,
-                                   virt_fns[i]->function,
+        if (pciGetDeviceAddrString((*virt_fns)[i]->domain,
+                                   (*virt_fns)[i]->bus,
+                                   (*virt_fns)[i]->slot,
+                                   (*virt_fns)[i]->function,
                                    &pciConfigAddr) < 0) {
             virReportSystemError(ENOSYS, "%s",
                                  _("Failed to get PCI Config Address String"));
@@ -1019,20 +1020,17 @@ virNetDevGetVirtualFunctions(const char *pfname,
         }
 
         if (pciDeviceNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) {
-            virReportSystemError(ENOSYS, "%s",
-                                 _("Failed to get interface name of the VF"));
-            goto cleanup;
+            VIR_INFO("VF does not have an interface name");
         }
     }
 
     ret = 0;
 
 cleanup:
-    if (ret < 0)
+    if (ret < 0) {
         VIR_FREE(*vfname);
-    for (i = 0; i < *n_vfname; i++)
-        VIR_FREE(virt_fns[i]);
-    VIR_FREE(virt_fns);
+        VIR_FREE(*virt_fns);
+    }
     VIR_FREE(pf_sysfs_device_link);
     VIR_FREE(pci_sysfs_device_link);
     VIR_FREE(pciConfigAddr);
@@ -1169,6 +1167,7 @@ cleanup:
 int
 virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
                              char ***vfname ATTRIBUTE_UNUSED,
+                             struct pci_config_address ***virt_fns ATTRIBUTE_UNUSED,
                              unsigned int *n_vfname ATTRIBUTE_UNUSED)
 {
     virReportSystemError(ENOSYS, "%s",
index c663e49a8d5854ae075b27835aee8004bef51565..705ad9c4902c2eeb251b3425337e7dc1a6b2837e 100644 (file)
@@ -26,6 +26,7 @@
 # include "virsocketaddr.h"
 # include "virnetlink.h"
 # include "virmacaddr.h"
+# include "pci.h"
 
 int virNetDevExists(const char *brname)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
@@ -103,9 +104,10 @@ int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
 
 int virNetDevGetVirtualFunctions(const char *pfname,
                                  char ***vfname,
+                                 struct pci_config_address ***virt_fns,
                                  unsigned int *n_vfname)
     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,
                       struct nlattr **tb,