mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
virPCIGetVirtualFunctions: Fetch also network interface name if needed
'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>
This commit is contained in:
parent
7ef618f30a
commit
795e9e05c3
@ -3012,6 +3012,7 @@ virPCIGetPhysicalFunction;
|
||||
virPCIGetVirtualFunctionIndex;
|
||||
virPCIGetVirtualFunctionInfo;
|
||||
virPCIGetVirtualFunctions;
|
||||
virPCIGetVirtualFunctionsFull;
|
||||
virPCIHeaderTypeFromString;
|
||||
virPCIHeaderTypeToString;
|
||||
virPCIIsVirtualFunction;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user