[libmultipath] discovery too fast for sysfs_get_bus
authorChristophe Varoqui <root@xa-s05.(none)>
Wed, 23 Nov 2005 00:38:38 +0000 (01:38 +0100)
committerChristophe Varoqui <root@xa-s05.(none)>
Wed, 23 Nov 2005 00:38:38 +0000 (01:38 +0100)
discovery.c:sysfs_get_bus() is unreliable in the following code path :

uev_add_path
-> store_pathinfo
-> pathinfo

Example trace :

### sdb: sdev = 539720
### sdb: attr_path = /sys/block/sdb/device
### sdb: attr_buff = /sys/devices/platform/host3/target3:0:0/3:0:0:1
### sdb: sdev->bus =

For whatever reason sysfs_open_device_path() can silently fails to
produce a usable ->bus.

As a consequence,
pp->hwe is NULL
-> mpp->hwe inherits this pp->hwe == NULL through add_map_with_path
-> the prop selectors fails to detect hardware settings

So this patch adds a sleep there.

libmultipath/discovery.c

index 41ad512..d51e402 100644 (file)
@@ -379,12 +379,24 @@ sysfs_get_bus (char * sysfs_path, struct path * curpath)
        if (0 > sysfs_get_link(attr_path, attr_buff, sizeof(attr_buff)))
                return 1;
 
-       sdev = sysfs_open_device_path(attr_buff);
+       int loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND;
+
+       while (loop--) {
+               sdev = sysfs_open_device_path(attr_buff);
+
+               if (strlen(sdev->bus))
+                       break;
+
+               sysfs_close_device(sdev);
+               usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
+       }
 
        if (!strncmp(sdev->bus, "scsi", 4))
                curpath->bus = SYSFS_BUS_SCSI;
        else if (!strncmp(sdev->bus, "ide", 3))
                curpath->bus = SYSFS_BUS_IDE;
+       else
+               return 1;
 
        sysfs_close_device(sdev);
 
@@ -599,6 +611,11 @@ pathinfo (struct path *pp, vector hwtable, int mask)
                return 1;
 
        /*
+        * get and store hwe configlet pointer
+        */
+       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id);
+
+       /*
         * fetch info not available through sysfs
         */
        if (pp->fd < 0)
@@ -611,9 +628,6 @@ pathinfo (struct path *pp, vector hwtable, int mask)
            scsi_ioctl_pathinfo(pp, mask))
                goto out;
 
-       /* get and store hwe pointer */
-       pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id);
-
        /*
         * get path state, no message collection, no context
         */