[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