From 795e9e05c3b6b9ef3abe6f6078a6373a136ec23b Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 4 Aug 2021 17:37:44 +0200 Subject: [PATCH] virPCIGetVirtualFunctions: Fetch also network interface name if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit '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 Reviewed-by: Ján Tomko --- 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 ea989d1547..ea895c987d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3012,6 +3012,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);