]> xenbits.xensource.com Git - libvirt.git/commitdiff
virPCIGetVirtualFunctions: Fetch also network interface name if needed
authorPeter Krempa <pkrempa@redhat.com>
Wed, 4 Aug 2021 15:37:44 +0000 (17:37 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 9 Aug 2021 08:09:00 +0000 (10:09 +0200)
'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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/util/virnetdev.c
src/util/virpci.c
src/util/virpci.h

index ea989d1547d4fa7f63a2a08ae27da3d5c78f671e..ea895c987d6362f84ee33d21727e90ab21aed9ad 100644 (file)
@@ -3012,6 +3012,7 @@ virPCIGetPhysicalFunction;
 virPCIGetVirtualFunctionIndex;
 virPCIGetVirtualFunctionInfo;
 virPCIGetVirtualFunctions;
+virPCIGetVirtualFunctionsFull;
 virPCIHeaderTypeFromString;
 virPCIHeaderTypeToString;
 virPCIIsVirtualFunction;
index ea5aba7116587a2b208b8f9d57803c9522fdb82a..4db3b255f668c8f6c9d7415cf4bad7d4b8c9b73f 100644 (file)
@@ -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;
 }
 
 /**
index 7dbca5f3ff6b3a847ec1aa2e702df750a6cc6ee1..915a4903cab8d608388e2abe008620a9a37c4da5 100644 (file)
@@ -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;
index 60f93fa87d09e07b57dc51de710ae56868d92bae..9a3db6c6d8d5669a4f45facdbeee8675eda8f004 100644 (file)
@@ -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);