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);