mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
util: make virPCIGetNetName() more versatile
A single PCI device may have multiple netdevs associated with it. Each of those netdevs will have a different phys_port_id entry in sysfs. This patch modifies virPCIGetNetName() to allow selecting one of the potential many netdevs in two different ways: 1) by setting the "idx" argument, the caller can select the 1st (0), 2nd (1), etc. netdev from the PCI device's net subdirectory. 2) If the physPortID arg is set (to a null-terminated string) then virPCIGetNetName() returns the netdev that has that phys_port_id in the sysfs file of the same name in the netdev's directory.
This commit is contained in:
parent
0dc67e6d2d
commit
b3b5aa75ed
@ -326,7 +326,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
|
||||
* type='hostdev'>, and it is only those devices that should
|
||||
* end up calling this function.
|
||||
*/
|
||||
if (virPCIGetNetName(sysfs_path, linkdev) < 0)
|
||||
if (virPCIGetNetName(sysfs_path, 0, NULL, linkdev) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!linkdev) {
|
||||
|
@ -1262,8 +1262,10 @@ virNetDevGetVirtualFunctions(const char *pfname,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0)
|
||||
if (virPCIGetNetName(pci_sysfs_device_link, 0,
|
||||
NULL, &((*vfname)[i])) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(*vfname)[i])
|
||||
VIR_INFO("VF does not have an interface name");
|
||||
@ -1362,7 +1364,8 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
|
||||
if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
|
||||
return ret;
|
||||
|
||||
if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0)
|
||||
if (virPCIGetNetName(physfn_sysfs_path, 0,
|
||||
NULL, pfname) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!*pfname) {
|
||||
@ -1422,7 +1425,7 @@ virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
|
||||
* isn't bound to a netdev driver, it won't have a netdev name,
|
||||
* and vfname will be NULL).
|
||||
*/
|
||||
ret = virPCIGetNetName(virtfnSysfsPath, vfname);
|
||||
ret = virPCIGetNetName(virtfnSysfsPath, 0, NULL, vfname);
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(virtfnName);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "virpci.h"
|
||||
#include "virnetdev.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
@ -2853,16 +2854,30 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the network device name of a pci device
|
||||
/**
|
||||
* virPCIGetNetName:
|
||||
* @device_link_sysfs_path: sysfs path to the PCI device
|
||||
* @idx: used to choose which netdev when there are several
|
||||
* (ignored if physPortID is set)
|
||||
* @physPortID: match this string in the netdev's phys_port_id
|
||||
* (or NULL to ignore and use idx instead)
|
||||
* @netname: used to return the name of the netdev
|
||||
* (set to NULL (but returns success) if there is no netdev)
|
||||
*
|
||||
* Returns 0 on success, -1 on error (error has been logged)
|
||||
*/
|
||||
int
|
||||
virPCIGetNetName(const char *device_link_sysfs_path, char **netname)
|
||||
virPCIGetNetName(const char *device_link_sysfs_path,
|
||||
size_t idx,
|
||||
char *physPortID,
|
||||
char **netname)
|
||||
{
|
||||
char *pcidev_sysfs_net_path = NULL;
|
||||
int ret = -1;
|
||||
DIR *dir = NULL;
|
||||
struct dirent *entry = NULL;
|
||||
char *thisPhysPortID = NULL;
|
||||
size_t i = 0;
|
||||
|
||||
if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
|
||||
"net") == -1) {
|
||||
@ -2873,21 +2888,48 @@ virPCIGetNetName(const char *device_link_sysfs_path, char **netname)
|
||||
if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) {
|
||||
/* this *isn't* an error - caller needs to check for netname == NULL */
|
||||
ret = 0;
|
||||
goto out;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
|
||||
/* Assume a single directory entry */
|
||||
if (VIR_STRDUP(*netname, entry->d_name) > 0)
|
||||
ret = 0;
|
||||
/* if the caller sent a physPortID, compare it to the
|
||||
* physportID of this netdev. If not, look for entry[idx].
|
||||
*/
|
||||
if (physPortID) {
|
||||
if (virNetDevGetPhysPortID(entry->d_name, &thisPhysPortID) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* if this one doesn't match, keep looking */
|
||||
if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) {
|
||||
VIR_FREE(thisPhysPortID);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (i++ < idx)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (VIR_STRDUP(*netname, entry->d_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (physPortID) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Could not find network device with "
|
||||
"phys_port_id '%s' under PCI device at %s"),
|
||||
physPortID, device_link_sysfs_path);
|
||||
} else {
|
||||
ret = 0; /* no netdev at the given index is *not* an error */
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
VIR_DIR_CLOSE(dir);
|
||||
|
||||
out:
|
||||
VIR_FREE(pcidev_sysfs_net_path);
|
||||
|
||||
VIR_FREE(thisPhysPortID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2915,7 +2957,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0)
|
||||
if (virPCIGetNetName(pf_sysfs_device_path, 0, NULL, pfname) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!*pfname) {
|
||||
@ -2992,6 +3034,8 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr dev ATTRIBUTE_UNUSED,
|
||||
|
||||
int
|
||||
virPCIGetNetName(const char *device_link_sysfs_path ATTRIBUTE_UNUSED,
|
||||
size_t idx ATTRIBUTE_UNUSED,
|
||||
char *physPortID ATTRIBUTE_UNUSED,
|
||||
char **netname ATTRIBUTE_UNUSED)
|
||||
{
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
|
||||
|
@ -207,7 +207,10 @@ int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
|
||||
int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
|
||||
char **pci_sysfs_device_link);
|
||||
|
||||
int virPCIGetNetName(const char *device_link_sysfs_path, char **netname);
|
||||
int virPCIGetNetName(const char *device_link_sysfs_path,
|
||||
size_t idx,
|
||||
char *physPortID,
|
||||
char **netname);
|
||||
|
||||
int virPCIGetSysfsFile(char *virPCIDeviceName,
|
||||
char **pci_sysfs_device_link)
|
||||
|
Loading…
x
Reference in New Issue
Block a user