提交 b3b5aa75 编写于 作者: L Laine Stump

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.
上级 0dc67e6d
...@@ -326,7 +326,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev, ...@@ -326,7 +326,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
* type='hostdev'>, and it is only those devices that should * type='hostdev'>, and it is only those devices that should
* end up calling this function. * end up calling this function.
*/ */
if (virPCIGetNetName(sysfs_path, linkdev) < 0) if (virPCIGetNetName(sysfs_path, 0, NULL, linkdev) < 0)
goto cleanup; goto cleanup;
if (!linkdev) { if (!linkdev) {
......
...@@ -1262,8 +1262,10 @@ virNetDevGetVirtualFunctions(const char *pfname, ...@@ -1262,8 +1262,10 @@ virNetDevGetVirtualFunctions(const char *pfname,
goto cleanup; goto cleanup;
} }
if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) if (virPCIGetNetName(pci_sysfs_device_link, 0,
NULL, &((*vfname)[i])) < 0) {
goto cleanup; goto cleanup;
}
if (!(*vfname)[i]) if (!(*vfname)[i])
VIR_INFO("VF does not have an interface name"); VIR_INFO("VF does not have an interface name");
...@@ -1362,7 +1364,8 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname) ...@@ -1362,7 +1364,8 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
return ret; return ret;
if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0) if (virPCIGetNetName(physfn_sysfs_path, 0,
NULL, pfname) < 0)
goto cleanup; goto cleanup;
if (!*pfname) { if (!*pfname) {
...@@ -1422,7 +1425,7 @@ virNetDevPFGetVF(const char *pfname, int vf, char **vfname) ...@@ -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, * isn't bound to a netdev driver, it won't have a netdev name,
* and vfname will be NULL). * and vfname will be NULL).
*/ */
ret = virPCIGetNetName(virtfnSysfsPath, vfname); ret = virPCIGetNetName(virtfnSysfsPath, 0, NULL, vfname);
cleanup: cleanup:
VIR_FREE(virtfnName); VIR_FREE(virtfnName);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <config.h> #include <config.h>
#include "virpci.h" #include "virpci.h"
#include "virnetdev.h"
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -2853,16 +2854,30 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr, ...@@ -2853,16 +2854,30 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
return 0; 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 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; char *pcidev_sysfs_net_path = NULL;
int ret = -1; int ret = -1;
DIR *dir = NULL; DIR *dir = NULL;
struct dirent *entry = NULL; struct dirent *entry = NULL;
char *thisPhysPortID = NULL;
size_t i = 0;
if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path, if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path,
"net") == -1) { "net") == -1) {
...@@ -2873,21 +2888,48 @@ virPCIGetNetName(const char *device_link_sysfs_path, char **netname) ...@@ -2873,21 +2888,48 @@ virPCIGetNetName(const char *device_link_sysfs_path, char **netname)
if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) { if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) {
/* this *isn't* an error - caller needs to check for netname == NULL */ /* this *isn't* an error - caller needs to check for netname == NULL */
ret = 0; ret = 0;
goto out; goto cleanup;
} }
while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) { while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
/* Assume a single directory entry */ /* if the caller sent a physPortID, compare it to the
if (VIR_STRDUP(*netname, entry->d_name) > 0) * physportID of this netdev. If not, look for entry[idx].
ret = 0; */
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; 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); VIR_DIR_CLOSE(dir);
out:
VIR_FREE(pcidev_sysfs_net_path); VIR_FREE(pcidev_sysfs_net_path);
VIR_FREE(thisPhysPortID);
return ret; return ret;
} }
...@@ -2915,7 +2957,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path, ...@@ -2915,7 +2957,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
goto cleanup; goto cleanup;
} }
if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0) if (virPCIGetNetName(pf_sysfs_device_path, 0, NULL, pfname) < 0)
goto cleanup; goto cleanup;
if (!*pfname) { if (!*pfname) {
...@@ -2992,6 +3034,8 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr dev ATTRIBUTE_UNUSED, ...@@ -2992,6 +3034,8 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr dev ATTRIBUTE_UNUSED,
int int
virPCIGetNetName(const char *device_link_sysfs_path ATTRIBUTE_UNUSED, virPCIGetNetName(const char *device_link_sysfs_path ATTRIBUTE_UNUSED,
size_t idx ATTRIBUTE_UNUSED,
char *physPortID ATTRIBUTE_UNUSED,
char **netname ATTRIBUTE_UNUSED) char **netname ATTRIBUTE_UNUSED)
{ {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
......
...@@ -207,7 +207,10 @@ int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link, ...@@ -207,7 +207,10 @@ int virPCIGetVirtualFunctionIndex(const char *pf_sysfs_device_link,
int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr, int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
char **pci_sysfs_device_link); 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, int virPCIGetSysfsFile(char *virPCIDeviceName,
char **pci_sysfs_device_link) char **pci_sysfs_device_link)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册