[libvirt] [PATCHv2] pci: properly handle out-of-order SRIOV virtual functions

Niilona niilona at gmail.com
Fri Nov 8 07:47:24 UTC 2013


On Thu, Nov 7, 2013 at 5:38 PM, Eric Blake <eblake at redhat.com> wrote:
> On 11/07/2013 07:06 AM, Niilona wrote:
>> Hi forget this as approach works using kernel-patch.
>> Correctly was mentioned that the approach using leading-zeroes was a
>> try to fix something happened in other place.
>> Haven't get intention to libvirt side after that, wrote untested patch
>> for this symptom.
>> It's is not complete - no more error checking's.
>> But it should pre-select only "virtfn" entries to be handled in
>> while-loop, and after that scan through them in increasing numerical
>> order.
>>
>> Still, here it is :
>>
>> < /* routine to select only "virtfn" -entries */
>> < static int
>> < virtfn_select(const struct dirent *entry)
>> < {
>> <     return (strncmp(entry->d_name,"virtfn", 6) == 0) ? 1 : 0;
>> < }
>> <
>> 2401a2395,2396
>>>     DIR *dir = NULL;
>>>     struct dirent *entry = NULL;
>
> Ouch.  This is an ed-script diff, which is practically worthless if we
> don't know what version of the file to apply it to.  Can you please
> resend as a proper context diff?  Also, please don't top-post on
> technical lists.
>
> --
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>

Sorry about behaving inappropriately. This is not a formal git-patch
as download it on tar-package.
Still hope the intention is clear :

diff -rupN libvirt-1.1.3.org/libvirt-1.1.3/src/util/virpci.c
libvirt-1.1.3/src/util/virpci.c
--- libvirt-1.1.3.org/libvirt-1.1.3/src/util/virpci.c 2013-09-18
12:51:27.000000000 +0300
+++ libvirt-1.1.3/src/util/virpci.c 2013-10-25 13:56:47.703067652 +0300
@@ -2382,6 +2382,13 @@ virPCIGetPhysicalFunction(const char *vf
     return ret;
 }

+/* routine to select only "virtfn" -entries */
+static int
+virtfn_select(const struct dirent *entry)
+{
+    return (strncmp(entry->d_name,"virtfn", 6) == 0) ? 1 : 0;
+}
+
 /*
  * Returns virtual functions of a physical function
  */
@@ -2392,10 +2399,11 @@ virPCIGetVirtualFunctions(const char *sy
 {
     int ret = -1;
     size_t i;
-    DIR *dir = NULL;
-    struct dirent *entry = NULL;
     char *device_link = NULL;
     char errbuf[64];
+    struct dirent **namelist;
+    int entry_count = 0;
+    int current_entry = 0;

     VIR_DEBUG("Attempting to get SR IOV virtual functions for device"
               "with sysfs path '%s'", sysfs_path);
@@ -2403,8 +2411,8 @@ virPCIGetVirtualFunctions(const char *sy
     *virtual_functions = NULL;
     *num_virtual_functions = 0;

-    dir = opendir(sysfs_path);
-    if (dir == NULL) {
+    struct stat sb;
+    if ((stat(sysfs_path, &sb) == -1) || ((sb.st_mode & S_IFMT) != S_IFDIR)) {
         memset(errbuf, '\0', sizeof(errbuf));
         virReportSystemError(errno,
                              _("Failed to open dir '%s'"),
@@ -2412,15 +2420,16 @@ virPCIGetVirtualFunctions(const char *sy
         return ret;
     }

-    while ((entry = readdir(dir))) {
-        if (STRPREFIX(entry->d_name, "virtfn")) {
+    entry_count = scandir(sysfs_path, &namelist, virtfn_select, alphasort);
+
+    while ( current_entry < entry_count ) {
             virPCIDeviceAddress *config_addr = NULL;

-            if (virBuildPath(&device_link, sysfs_path, entry->d_name) == -1) {
+            if (virBuildPath(&device_link, sysfs_path, namelist[
current_entry ]->d_name ) == -1) {
                 virReportOOMError();
                 goto error;
             }
-
+            current_entry ++;
             VIR_DEBUG("Number of virtual functions: %d",
                       *num_virtual_functions);

@@ -2442,15 +2451,15 @@ virPCIGetVirtualFunctions(const char *sy
             (*virtual_functions)[*num_virtual_functions] = config_addr;
             (*num_virtual_functions)++;
             VIR_FREE(device_link);
-        }
     }

     ret = 0;

 cleanup:
     VIR_FREE(device_link);
-    if (dir)
-        closedir(dir);
+    for ( i = 0; i < entry_count; i ++)
+      free( namelist[ i ] );
+    free( namelist );
     return ret;

 error:




More information about the libvir-list mailing list