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

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



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:
>> 
>>> On 08/01/2011 07:57 PM, Roopa Prabhu 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>"
>> 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.


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