Re: [PATCH 2/3 RFC] Add functions to get sriov PF/VF relationship of a network interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 08/01/2011 07:57 PM, Roopa Prabhu wrote:
From: Roopa Prabhu<roprabhu@xxxxxxxxx>

This patch adds helper functions to derive the PF/VF relationship of an sriov
network device

Signed-off-by: Roopa Prabhu<roprabhu@xxxxxxxxx>
Signed-off-by: Christian Benvenuti<benve@xxxxxxxxx>
Signed-off-by: David Wang<dwang2@xxxxxxxxx>
---
  src/util/interface.c |  122 ++++++++++++++++++++++++++++++++++++++++++++++++++
  src/util/interface.h |    8 +++
  2 files changed, 130 insertions(+), 0 deletions(-)


diff --git a/src/util/interface.c b/src/util/interface.c
index f5eecfb..5ee5703 100644
--- a/src/util/interface.c
+++ b/src/util/interface.c
@@ -30,6 +30,7 @@
  #include<sys/ioctl.h>
  #include<fcntl.h>
  #include<netinet/in.h>
+#include<dirent.h>

  #ifdef __linux__
  # include<linux/if.h>
@@ -45,6 +46,8 @@
  #include "virfile.h"
  #include "memory.h"
  #include "netlink.h"
+#include "pci.h"
+#include "logging.h"

  #define VIR_FROM_THIS VIR_FROM_NET

@@ -1197,3 +1200,122 @@ ifaceRestoreMacAddress(const char *linkdev,

      return rc;
  }
+
+int ifaceIsVF(const char *ifname)
+{
+    char *if_sysfs_device_link = NULL;
+    int ret;
+
+    if (virAsprintf(&if_sysfs_device_link, NET_SYSFS "%s/device/physfn",
+        ifname)<  0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    ret = virFileExists(if_sysfs_device_link);
+
+    VIR_FREE(if_sysfs_device_link);
+
+    return ret;
+}
+
+int ifaceGetVFIndex(const char *pfname, const char *vfname,
+                    int *vf_index)
+{
+    int ret = -1;
+    DIR *dir = NULL;
+    struct dirent *entry = NULL;
+    char *pf_sysfs_device_link = NULL, *vf_sysfs_device_link = NULL;
+    char *vf_sysfs_device = NULL;
+    char errbuf[64];
+
+    if (virAsprintf(&pf_sysfs_device_link, NET_SYSFS "%s/device",
+        pfname)<  0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    if (virAsprintf(&vf_sysfs_device_link, NET_SYSFS "%s/device",
+        vfname)<  0) {
+        VIR_FREE(pf_sysfs_device_link);
+        virReportOOMError();
+        return -1;
+    }
+
+    vf_sysfs_device = canonicalize_file_name(vf_sysfs_device_link);
+    if (vf_sysfs_device == NULL) {
+        memset(errbuf, '\0', sizeof(errbuf));
+        VIR_ERROR(_("Failed to resolve device link '%s': '%s'"),
+                  vf_sysfs_device_link,
+                  virStrerror(errno, errbuf, sizeof(errbuf)));
+        VIR_FREE(pf_sysfs_device_link);
+        VIR_FREE(vf_sysfs_device_link);
+        return -1;
+    }
+
+    dir = opendir(pf_sysfs_device_link);
+    if (dir == NULL)
+        goto out;
+
+    while ((entry = readdir(dir))) {
+        if (STRPREFIX(entry->d_name, "virtfn")) {
+            char *device_link, *device_path;
+
+            if (virBuildPath(&device_link, pf_sysfs_device_link,
+                entry->d_name) == -1) {
+                virReportOOMError();
+                goto out;
+            }
+
+            device_path = canonicalize_file_name(device_link);
+            if (device_path == NULL) {
+                memset(errbuf, '\0', sizeof(errbuf));
+                VIR_ERROR(_("Failed to resolve device link '%s': '%s'"),
+                          device_link, virStrerror(errno, errbuf,
+                          sizeof(errbuf)));
+                VIR_FREE(device_link);
+                goto out;
+            }
+
+            if (!strcmp(vf_sysfs_device, device_path)) {
+                *vf_index = atoi(entry->d_name + strlen("virtfn"));
This looks odd. Can you explain?
+                ret = 0;
+            }
+
+            VIR_FREE(device_link);
+            VIR_FREE(device_path);
+
+            if ( ret == 0 )
+                break;
+        }
+    }
+
+    if (dir)
+        closedir(dir);

In this case the above test should be after the 'out:' label not to cause a memory leak with the goto's above.

+
+out:
+
+    VIR_FREE(pf_sysfs_device_link);
+    VIR_FREE(vf_sysfs_device_link);
+    VIR_FREE(vf_sysfs_device);
+
+    return ret;
+}
+
+int ifaceGetPFName(const char *ifname, char **pfname)
+{
+    char *physfn_sysfs_path = NULL;
+    int ret = -1;
+
+    if (virAsprintf(&physfn_sysfs_path, NET_SYSFS "%s/device/physfn",
+        ifname)<  0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    ret = pciDeviceGetNetName(physfn_sysfs_path, pfname);
+
+    VIR_FREE(physfn_sysfs_path);
+
+    return ret;
+}
diff --git a/src/util/interface.h b/src/util/interface.h
index 9647653..f2c84f8 100644
--- a/src/util/interface.h
+++ b/src/util/interface.h
@@ -26,6 +26,8 @@ struct nlattr;
  # include "datatypes.h"
  # include "network.h"

+#define NET_SYSFS "/sys/class/net/"
+
  int ifaceGetFlags(const char *name, short *flags);
  int ifaceIsUp(const char *name, bool *up);

@@ -76,4 +78,10 @@ int ifaceReplaceMacAddress(const unsigned char *macaddress,
  int ifaceRestoreMacAddress(const char *linkdev,
                             const char *stateDir);

+int ifaceIsVF(const char *ifname);
+
+int ifaceGetVFIndex(const char *pfname, const char *vfname, int *vf_index);
+
+int ifaceGetPFName(const char *ifname, char **pfname);
+
  #endif /* __VIR_INTERFACE_H__ */

   Stefan

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]