[libvirt] [PATCH 2/3] util: support matching a phys_port_id in virPCIGetNetName()

Laine Stump laine at laine.org
Fri Aug 4 03:36:43 UTC 2017


A single PCI device may have multiple netdevs associated with it. Each
of those netdevs will have a different phys_port_id entry in
sysfs. This patch modifies virPCIGetNetName() to allow matching the
netdev for a PCI device that has the same phys_port_id that the caller
wants.
---
 src/util/virhostdev.c |  2 +-
 src/util/virnetdev.c  |  6 +++---
 src/util/virpci.c     | 49 ++++++++++++++++++++++++++++++++++++++++---------
 src/util/virpci.h     |  4 +++-
 4 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 579563c3f..fcefebd07 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -326,7 +326,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
          * type='hostdev'>, and it is only those devices that should
          * end up calling this function.
          */
-        if (virPCIGetNetName(sysfs_path, linkdev) < 0)
+        if (virPCIGetNetName(sysfs_path, NULL, linkdev) < 0)
             goto cleanup;
 
         if (!linkdev) {
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index a2664de78..1c150b7d7 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1262,7 +1262,7 @@ virNetDevGetVirtualFunctions(const char *pfname,
             goto cleanup;
         }
 
-        if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0)
+        if (virPCIGetNetName(pci_sysfs_device_link, NULL, &((*vfname)[i])) < 0)
             goto cleanup;
 
         if (!(*vfname)[i])
@@ -1362,7 +1362,7 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
         return ret;
 
-    if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0)
+    if (virPCIGetNetName(physfn_sysfs_path, NULL, pfname) < 0)
         goto cleanup;
 
     if (!*pfname) {
@@ -1422,7 +1422,7 @@ virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
      * isn't bound to a netdev driver, it won't have a netdev name,
      * and vfname will be NULL).
      */
-    ret = virPCIGetNetName(virtfnSysfsPath, vfname);
+    ret = virPCIGetNetName(virtfnSysfsPath, NULL, vfname);
 
  cleanup:
     VIR_FREE(virtfnName);
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 2c1b75855..5d811ada6 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -24,6 +24,7 @@
 #include <config.h>
 
 #include "virpci.h"
+#include "virnetdev.h"
 
 #include <dirent.h>
 #include <fcntl.h>
@@ -2857,12 +2858,15 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
  * Returns the network device name of a pci device
  */
 int
-virPCIGetNetName(char *device_link_sysfs_path, char **netname)
+virPCIGetNetName(char *device_link_sysfs_path,
+                 char *physPortID,
+                 char **netname)
 {
     char *pcidev_sysfs_net_path = NULL;
     int ret = -1;
     DIR *dir = NULL;
     struct dirent *entry = NULL;
+    char *thisPhysPortID = NULL;
 
     if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
                      "net") == -1) {
@@ -2873,21 +2877,47 @@ virPCIGetNetName(char *device_link_sysfs_path, char **netname)
     if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) {
         /* this *isn't* an error - caller needs to check for netname == NULL */
         ret = 0;
-        goto out;
+        goto cleanup;
     }
 
     while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
-        /* Assume a single directory entry */
-        if (VIR_STRDUP(*netname, entry->d_name) > 0)
-            ret = 0;
+        /* if the caller sent a physPortID, compare it to the
+         * physportID of this netdev. If not, accept the first netdev
+         */
+        if (physPortID) {
+            if (virNetDevGetPhysPortID(entry->d_name, &thisPhysPortID) < 0)
+                goto cleanup;
+
+            /* if this one doesn't match, keep looking */
+            if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) {
+                VIR_FREE(thisPhysPortID);
+                continue;
+            }
+        }
+        if (VIR_STRDUP(*netname, entry->d_name) < 0)
+            goto cleanup;
+
+        ret = 0;
         break;
     }
 
+    if (ret < 0) {
+        if (physPortID) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Could not find network device with "
+                             "phys_port_id '%s' under PCI device at %s"),
+                           physPortID, device_link_sysfs_path);
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("PCI device at %s had a net directory, "
+                             "but it was empty"),
+                           device_link_sysfs_path);
+        }
+    }
+ cleanup:
     VIR_DIR_CLOSE(dir);
-
- out:
     VIR_FREE(pcidev_sysfs_net_path);
-
+    VIR_FREE(thisPhysPortID);
     return ret;
 }
 
@@ -2915,7 +2945,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
         goto cleanup;
     }
 
-    if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0)
+    if (virPCIGetNetName(pf_sysfs_device_path, NULL, pfname) < 0)
         goto cleanup;
 
     if (!*pfname) {
@@ -2992,6 +3022,7 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr dev ATTRIBUTE_UNUSED,
 
 int
 virPCIGetNetName(char *device_link_sysfs_path ATTRIBUTE_UNUSED,
+                 char *physPortID ATTRIBUTE_UNUSED,
                  char **netname ATTRIBUTE_UNUSED)
 {
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 570684e75..c0e54d785 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -207,7 +207,9 @@ int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
 int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
                                     char **pci_sysfs_device_link);
 
-int virPCIGetNetName(char *device_link_sysfs_path, char **netname);
+int virPCIGetNetName(char *device_link_sysfs_path,
+                     char *physPortID,
+                     char **netname);
 
 int virPCIGetSysfsFile(char *virPCIDeviceName,
                              char **pci_sysfs_device_link)
-- 
2.13.3




More information about the libvir-list mailing list