
On 8/2/11 6:46 AM, "Stefan Berger" <stefanb@linux.vnet.ibm.com> wrote:
On 08/02/2011 08:46 AM, Roopa Prabhu wrote:
On 8/1/11 6:10 PM, "Stefan Berger"<stefanb@linux.vnet.ibm.com> wrote:
From: Roopa Prabhu<roprabhu@cisco.com>
This patch adds helper functions to derive the PF/VF relationship of an sriov network device
Signed-off-by: Roopa Prabhu<roprabhu@cisco.com> Signed-off-by: Christian Benvenuti<benve@cisco.com> Signed-off-by: David Wang<dwang2@cisco.com> --- 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? The PF device sysfs directory has links with the name "virtfn<vf_index>"
On 08/01/2011 07:57 PM, Roopa Prabhu wrote: pointing to the VF's pci device.
Example: # ls -l virtfn* lrwxrwxrwx. 1 root root 0 Jul 27 11:09 virtfn0 -> ../0000:1e:00.1 lrwxrwxrwx. 1 root root 0 Jul 27 11:09 virtfn1 -> ../0000:1e:00.2 lrwxrwxrwx. 1 root root 0 Jul 27 11:09 virtfn10 -> ../0000:1e:01.3 lrwxrwxrwx. 1 root root 0 Jul 27 11:09 virtfn11 -> ../0000:1e:01.4 lrwxrwxrwx. 1 root root 0 Jul 27 11:09 virtfn12 -> ../0000:1e:01.5
I see if the virt function link is pointing to the pci device of the VF I am looking for. If it is, then I try to get the vf index from the virtual function link name (I just need the number in "virtfn<vf_index>". This is one way to get the vf index. The other way is to get it by reading the pci config space of the PF, which the node device driver uses.
In that case I'd suggest to use 'if (sscanf(entry->d_name, "virtfn%u", &vf_index) != 1) { error }'
Ok sounds good. Thanks.