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");
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) {
* 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);
#include <config.h>
#include "virpci.h"
+#include "virnetdev.h"
#include <dirent.h>
#include <fcntl.h>
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) {
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;
}
goto cleanup;
}
- if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0)
+ if (virPCIGetNetName(pf_sysfs_device_path, 0, NULL, pfname) < 0)
goto cleanup;
if (!*pfname) {
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));