[libvirt] [PATCH 3/5] Adding functions virNetDevGetVirtualFunctions and virNetDevGetNetName virNetDevGetVirtualFunctions: Gets the BDF of all the Virtual Functions given a physical function virNetDevGetNetName: Gets the interface name of the PCI Device.

Daniel P. Berrange berrange at redhat.com
Tue Nov 29 20:01:18 UTC 2011


On Tue, Nov 29, 2011 at 03:49:05PM +0000, Shradha Shah wrote:
> ---
>  src/util/virnetdev.c |   89 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virnetdev.h |   10 ++++++
>  2 files changed, 99 insertions(+), 0 deletions(-)
> 
> diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
> index 86196a1..d07d8fa 100644
> --- a/src/util/virnetdev.c
> +++ b/src/util/virnetdev.c
> @@ -968,6 +968,76 @@ virNetDevSysfsDeviceFile(char **pf_sysfs_device_link, const char *ifname,
>  }
>  
>  /**
> + * virNetDevGetVirtualFunctions:
> + *
> + * @pfname : name of the physical function interface name
> + * @virt_fns: array that will hold the pointers to the virtual_functions
> + * @num_virt_fns: number of virtual functions
> + *
> + * Returns 0 on success and -1 on failure
> + */
> +
> +int
> +virNetDevGetVirtualFunctions(const char *pfname, 
> +                         struct pci_config_address ***virt_fns,
> +                         unsigned int *num_virt_fns)
> +{
> +    int ret = -1;
> +    char *pf_sysfs_device_link = NULL;
> +    
> +    
> +    if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
> +        return ret;
> +    
> +    if (pciGetVirtualFunctions(pf_sysfs_device_link, virt_fns,
> +                               num_virt_fns) < 0) 
> +        goto out;
> +    ret = 0;
> +    
> +out:
> +    VIR_FREE(pf_sysfs_device_link);
> +    return ret;
> +}
> +
> +/**
> + * virNetDevGetNetName:
> + *
> + * @vf : pci address (BDF) of the Virtual Function
> + * @vfname: interface name of the virtual function returned by this function
> + *
> + * Returns 0 on success and -1 on failure
> + */
> +
> +int 
> +virNetDevGetNetName(struct pci_config_address *vf, char **vfname)
> +{
> +    int ret = -1;
> +    pciDevice *dev = NULL;
> +    char *pci_sysfs_device_link = NULL;
> +    
> +    dev = pciGetDevice(vf->domain, vf->bus, vf->slot, vf->function);
> +    if (dev != NULL) {
> +        if (pciSysfsFile(&pci_sysfs_device_link, dev->name) < 0) {
> +            virReportSystemError(ENOSYS, "%s",
> +                         _("Failed to get PCI SYSFS file"));
> +            goto out;
> +        } 
> +        
> +        if (pciDeviceNetName(pci_sysfs_device_link, vfname) < 0) {
> +            virReportSystemError(ENOSYS, "%s",
> +                         _("Failed to get interface name of the VF"));
> +            goto out;
> +        }
> +    }
> +    ret = 0;
> +    
> +out:
> +    VIR_FREE(pci_sysfs_device_link);
> +    pciFreeDevice(dev);
> +    return ret;
> +}
> +
> +/**
>   * virNetDevIsVirtualFunction:
>   * @ifname : name of the interface
>   *
> @@ -1055,6 +1125,25 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
>  }
>  #else /* !__linux__ */
>  int
> +virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED, 
> +                         struct pci_config_address ***virt_fns ATTRIBUTE_UNUSED,
> +                         unsigned int *num_virt_fns ATTRIBUTE_UNUSED)
> +{
> +    virReportSystemError(ENOSYS, "%s",
> +                         _("Unable to get virtual functions on this platfornm"));
> +    return -1;
> +}
> +
> +int 
> +virNetDevGetNetName(struct pci_config_address *vf ATTRIBUTE_UNUSED,
> +                    char **vfname ATTRIBUTE_UNUSED)
> +{
> +    virReportSystemError(ENOSYS, "%s",
> +                         _("Unable to get Device name on this platfornm"));
> +    return -1;
> +}
> +
> +int
>  virNetDevIsVirtualFunction(const char *ifname ATTRIBUTE_UNUSED)
>  {
>      virReportSystemError(ENOSYS, "%s",
> diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
> index 13ba1da..4d1573a 100644
> --- a/src/util/virnetdev.h
> +++ b/src/util/virnetdev.h
> @@ -24,6 +24,7 @@
>  # define __VIR_NETDEV_H__
>  
>  # include "virsocketaddr.h"
> +# include "pci.h"
>  
>  int virNetDevExists(const char *brname)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
> @@ -99,4 +100,13 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
>  int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
>  
> +int virNetDevGetVirtualFunctions(const char *pfname, 
> +                             struct pci_config_address ***virt_fns,
> +                             unsigned int *num_virt_fns)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
> +    ATTRIBUTE_RETURN_CHECK;
> +
> +int virNetDevGetNetName(struct pci_config_address *vf, char **vfname)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
> +

Rather than expose the 'struct pci_config_address' in the virnetdev.h
header file, I think it would be desirable to merge the virNetDevGetNameName
code into virNetDevGetVirtualFunctions, so that it just directly returns the
list of VF devices. eg

  int virNetDevGetVirtualFunctions(const char *pfname, 
                                   char **vfnames,
                                   unsigned int *nvfnames)

The callers all seem to call virNetDevGetNetName on the results of
virNetDevGetVirtualFunctions, so this merge would simplify code in
the callers somewhat.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list