[libvirt] [PATCH 2/3 RFC] Add functions to get sriov PF/VF relationship of a network interface
Stefan Berger
stefanb at linux.vnet.ibm.com
Tue Aug 2 01:10:22 UTC 2011
On 08/01/2011 07:57 PM, Roopa Prabhu wrote:
> From: Roopa Prabhu<roprabhu at cisco.com>
>
> This patch adds helper functions to derive the PF/VF relationship of an sriov
> network device
>
> Signed-off-by: Roopa Prabhu<roprabhu at cisco.com>
> Signed-off-by: Christian Benvenuti<benve at cisco.com>
> Signed-off-by: David Wang<dwang2 at 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?
> + 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
More information about the libvir-list
mailing list