[PATCH 5/6] virPCIGetVirtualFunctions: Fetch also network interface name if needed

Peter Krempa pkrempa at redhat.com
Thu Aug 5 14:13:09 UTC 2021


'virNetDevGetVirtualFunctions' calls 'virPCIGetVirtualFunctions' and
then re-iterates the returned list to fetch the interface names for the
returned virtual functions.

If we move the fetching of the interface name into
virPCIGetVirtualFunctions we can simplify the code and remove a bunch of
impossible error states.

To accomplish this the function is renamed to
'virPCIGetVirtualFunctionsFull' while keeping a wrapper with original
name and if the physical port ID is passed the interface name is fetched
too without the need to re-convert the address into a sysfs link.

For now 'virNetDevGetVirtualFunctions' still converts the returned data
into two lists.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virnetdev.c     | 44 ++++++----------------------------------
 src/util/virpci.c        | 39 ++++++++++++++++++++++++++++-------
 src/util/virpci.h        |  4 ++++
 4 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 20e74dd5d5..fd02b27c51 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3011,6 +3011,7 @@ virPCIGetPhysicalFunction;
 virPCIGetVirtualFunctionIndex;
 virPCIGetVirtualFunctionInfo;
 virPCIGetVirtualFunctions;
+virPCIGetVirtualFunctionsFull;
 virPCIHeaderTypeFromString;
 virPCIHeaderTypeToString;
 virPCIIsVirtualFunction;
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index ea5aba7116..4db3b255f6 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1227,62 +1227,30 @@ virNetDevGetVirtualFunctions(const char *pfname,
                              virPCIDeviceAddress ***virt_fns,
                              size_t *n_vfname)
 {
-    int ret = -1;
     size_t i;
     g_autofree char *pf_sysfs_device_link = NULL;
     g_autofree char *pfPhysPortID = NULL;
     g_autoptr(virPCIVirtualFunctionList) vfs = NULL;

-    *virt_fns = NULL;
-    *n_vfname = 0;
-
     if (virNetDevGetPhysPortID(pfname, &pfPhysPortID) < 0)
-        goto cleanup;
+        return -1;

     if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
-        goto cleanup;
+        return -1;

-    if (virPCIGetVirtualFunctions(pf_sysfs_device_link, &vfs) < 0)
-        goto cleanup;
+    if (virPCIGetVirtualFunctionsFull(pf_sysfs_device_link, &vfs, pfPhysPortID) < 0)
+        return -1;

     *vfname = g_new0(char *, vfs->nfunctions);
     *virt_fns = g_new0(virPCIDeviceAddress *, vfs->nfunctions);
     *n_vfname = vfs->nfunctions;

     for (i = 0; i < *n_vfname; i++) {
-        g_autofree char *pci_sysfs_device_link = NULL;
-
         virt_fns[i] = g_steal_pointer(&vfs->functions[i].addr);
-
-        if (virPCIDeviceAddressGetSysfsFile((*virt_fns)[i],
-                                            &pci_sysfs_device_link) < 0) {
-            virReportSystemError(ENOSYS, "%s",
-                                 _("Failed to get PCI SYSFS file"));
-            goto cleanup;
-        }
-
-        if (virPCIGetNetName(pci_sysfs_device_link, 0,
-                             pfPhysPortID, &((*vfname)[i])) < 0) {
-            goto cleanup;
-        }
-
-        if (!(*vfname)[i])
-            VIR_INFO("VF does not have an interface name");
+        vfname[i] = g_steal_pointer(&vfs->functions[i].ifname);
     }

-    ret = 0;
-
- cleanup:
-    if (ret < 0) {
-        virStringListFreeCount(*vfname, *n_vfname);
-
-        for (i = 0; i < *n_vfname; i++)
-            VIR_FREE((*virt_fns)[i]);
-        VIR_FREE(*virt_fns);
-        *vfname = NULL;
-        *n_vfname = 0;
-    }
-    return ret;
+    return 0;
 }

 /**
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 7dbca5f3ff..915a4903ca 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2257,12 +2257,21 @@ virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list)

     for (i = 0; i < list->nfunctions; i++) {
         g_free(list->functions[i].addr);
+        g_free(list->functions[i].ifname);
     }

     g_free(list);
 }


+int
+virPCIGetVirtualFunctions(const char *sysfs_path,
+                          virPCIVirtualFunctionList **vfs)
+{
+    return virPCIGetVirtualFunctionsFull(sysfs_path, vfs, NULL);
+}
+
+
 #ifdef __linux__

 virPCIDeviceAddress *
@@ -2332,12 +2341,20 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path,
 }


-/*
- * Returns virtual functions of a physical function
+/**
+ * virPCIGetVirtualFunctionsFull:
+ * @sysfs_path: path to physical function sysfs entry
+ * @vfs: filled with the virtual function data
+ * @pfPhysPortID: Optional physical port id. If provided the network interface
+ *                name of the VFs is queried too.
+ *
+ *
+ * Returns virtual functions of a physical function.
  */
 int
-virPCIGetVirtualFunctions(const char *sysfs_path,
-                          virPCIVirtualFunctionList **vfs)
+virPCIGetVirtualFunctionsFull(const char *sysfs_path,
+                              virPCIVirtualFunctionList **vfs,
+                              const char *pfPhysPortID)
 {
     g_autofree char *totalvfs_file = NULL;
     g_autofree char *totalvfs_str = NULL;
@@ -2363,7 +2380,7 @@ virPCIGetVirtualFunctions(const char *sysfs_path,

     do {
         g_autofree char *device_link = NULL;
-        struct virPCIVirtualFunction fnc = { NULL };
+        struct virPCIVirtualFunction fnc = { NULL, NULL };

         /* look for virtfn%d links until one isn't found */
         device_link = g_strdup_printf("%s/virtfn%zu", sysfs_path, list->nfunctions);
@@ -2378,6 +2395,13 @@ virPCIGetVirtualFunctions(const char *sysfs_path,
             return -1;
         }

+        if (pfPhysPortID) {
+            if (virPCIGetNetName(device_link, 0, pfPhysPortID, &fnc.ifname) < 0) {
+                g_free(fnc.addr);
+                return -1;
+            }
+        }
+
         VIR_APPEND_ELEMENT(list->functions, list->nfunctions, fnc);
     } while (1);

@@ -2636,8 +2660,9 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path G_GNUC_UNUSED,
 }

 int
-virPCIGetVirtualFunctions(const char *sysfs_path G_GNUC_UNUSED,
-                          virPCIVirtualFunctionList **vfs G_GNUC_UNUSED)
+virPCIGetVirtualFunctionsFull(const char *sysfs_path G_GNUC_UNUSED,
+                              virPCIVirtualFunctionList **vfs G_GNUC_UNUSED,
+                              const char *pfPhysPortID G_GNUC_UNUSED)
 {
     virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
     return -1;
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 60f93fa87d..9a3db6c6d8 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -214,6 +214,7 @@ int virPCIGetPhysicalFunction(const char *vf_sysfs_path,

 struct virPCIVirtualFunction {
     virPCIDeviceAddress *addr;
+    char *ifname;
 };

 struct _virPCIVirtualFunctionList {
@@ -226,6 +227,9 @@ typedef struct _virPCIVirtualFunctionList virPCIVirtualFunctionList;
 void virPCIVirtualFunctionListFree(virPCIVirtualFunctionList *list);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIVirtualFunctionList, virPCIVirtualFunctionListFree);

+int virPCIGetVirtualFunctionsFull(const char *sysfs_path,
+                                  virPCIVirtualFunctionList **vfs,
+                                  const char *pfPhysPortID);
 int virPCIGetVirtualFunctions(const char *sysfs_path,
                               virPCIVirtualFunctionList **vfs);

-- 
2.31.1




More information about the libvir-list mailing list