Do not automatically fall back to vpd uid generation
[multipath-tools/.git] / libmultipath / discovery.c
1 /*
2  * Copyright (c) 2004, 2005, 2006 Christophe Varoqui
3  * Copyright (c) 2005 Stefan Bader, IBM
4  * Copyright (c) 2005 Mike Anderson
5  */
6 #include <stdio.h>
7 #include <ctype.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <sys/ioctl.h>
11 #include <sys/stat.h>
12 #include <dirent.h>
13 #include <errno.h>
14 #include <libgen.h>
15 #include <libudev.h>
16
17 #include "checkers.h"
18 #include "vector.h"
19 #include "memory.h"
20 #include "util.h"
21 #include "structs.h"
22 #include "config.h"
23 #include "blacklist.h"
24 #include "callout.h"
25 #include "debug.h"
26 #include "propsel.h"
27 #include "sg_include.h"
28 #include "sysfs.h"
29 #include "discovery.h"
30 #include "prio.h"
31 #include "defaults.h"
32
33 int
34 alloc_path_with_pathinfo (vector hwtable, struct udev_device *udevice,
35                           int flag, struct path **pp_ptr)
36 {
37         int err = PATHINFO_FAILED;
38         struct path * pp;
39         const char * devname;
40
41         if (pp_ptr)
42                 *pp_ptr = NULL;
43
44         devname = udev_device_get_sysname(udevice);
45         if (!devname)
46                 return PATHINFO_FAILED;
47
48         pp = alloc_path();
49
50         if (!pp)
51                 return PATHINFO_FAILED;
52
53         if (safe_sprintf(pp->dev, "%s", devname)) {
54                 condlog(0, "pp->dev too small");
55         } else {
56                 pp->udev = udev_device_ref(udevice);
57                 err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
58         }
59
60         if (err)
61                 free_path(pp);
62         else if (pp_ptr)
63                 *pp_ptr = pp;
64         return err;
65 }
66
67 int
68 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
69                 int flag, struct path **pp_ptr)
70 {
71         int err = PATHINFO_FAILED;
72         struct path * pp;
73         const char * devname;
74
75         if (pp_ptr)
76                 *pp_ptr = NULL;
77
78         devname = udev_device_get_sysname(udevice);
79         if (!devname)
80                 return PATHINFO_FAILED;
81
82         pp = alloc_path();
83
84         if (!pp)
85                 return PATHINFO_FAILED;
86
87         if(safe_sprintf(pp->dev, "%s", devname)) {
88                 condlog(0, "pp->dev too small");
89                 goto out;
90         }
91         pp->udev = udev_device_ref(udevice);
92         err = pathinfo(pp, hwtable,
93                        (conf->cmd == CMD_REMOVE_WWID)? flag :
94                                                        (flag | DI_BLACKLIST));
95         if (err)
96                 goto out;
97
98         err = store_path(pathvec, pp);
99         if (err)
100                 goto out;
101
102 out:
103         if (err)
104                 free_path(pp);
105         else if (pp_ptr)
106                 *pp_ptr = pp;
107         return err;
108 }
109
110 static int
111 path_discover (vector pathvec, struct config * conf,
112                struct udev_device *udevice, int flag)
113 {
114         struct path * pp;
115         const char * devname;
116
117         devname = udev_device_get_sysname(udevice);
118         if (!devname)
119                 return PATHINFO_FAILED;
120
121         if (filter_property(conf, udevice) > 0)
122                 return PATHINFO_SKIPPED;
123
124         if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
125                            (char *)devname) > 0)
126                 return PATHINFO_SKIPPED;
127
128         pp = find_path_by_dev(pathvec, (char *)devname);
129         if (!pp) {
130                 return store_pathinfo(pathvec, conf->hwtable,
131                                       udevice, flag, NULL);
132         }
133         return pathinfo(pp, conf->hwtable, flag);
134 }
135
136 int
137 path_discovery (vector pathvec, struct config * conf, int flag)
138 {
139         struct udev_enumerate *udev_iter;
140         struct udev_list_entry *entry;
141         struct udev_device *udevice;
142         const char *devpath;
143         int num_paths = 0, total_paths = 0;
144
145         udev_iter = udev_enumerate_new(conf->udev);
146         if (!udev_iter)
147                 return -ENOMEM;
148
149         udev_enumerate_add_match_subsystem(udev_iter, "block");
150         udev_enumerate_scan_devices(udev_iter);
151
152         udev_list_entry_foreach(entry,
153                                 udev_enumerate_get_list_entry(udev_iter)) {
154                 const char *devtype;
155                 devpath = udev_list_entry_get_name(entry);
156                 condlog(4, "Discover device %s", devpath);
157                 udevice = udev_device_new_from_syspath(conf->udev, devpath);
158                 if (!udevice) {
159                         condlog(4, "%s: no udev information", devpath);
160                         continue;
161                 }
162                 devtype = udev_device_get_devtype(udevice);
163                 if(devtype && !strncmp(devtype, "disk", 4)) {
164                         total_paths++;
165                         if (path_discover(pathvec, conf,
166                                           udevice, flag) == PATHINFO_OK)
167                                 num_paths++;
168                 }
169                 udev_device_unref(udevice);
170         }
171         udev_enumerate_unref(udev_iter);
172         condlog(4, "Discovered %d/%d paths", num_paths, total_paths);
173         return (total_paths - num_paths);
174 }
175
176 #define declare_sysfs_get_str(fname)                                    \
177 extern ssize_t                                                          \
178 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len)  \
179 {                                                                       \
180         int l;                                                  \
181         const char * attr;                                              \
182         const char * devname;                                           \
183                                                                         \
184         if (!udev)                                                      \
185                 return -ENOSYS;                                         \
186                                                                         \
187         devname = udev_device_get_sysname(udev);                        \
188                                                                         \
189         attr = udev_device_get_sysattr_value(udev, #fname);             \
190         if (!attr) {                                                    \
191                 condlog(3, "%s: attribute %s not found in sysfs",       \
192                         devname, #fname);                               \
193                 return -ENXIO;                                          \
194         }                                                               \
195         for (l = strlen(attr); l >= 1 && isspace(attr[l-1]); l--);      \
196         if (l > len) {                                                  \
197                 condlog(3, "%s: overflow in attribute %s",              \
198                         devname, #fname);                               \
199                 return -EINVAL;                                         \
200         }                                                               \
201         strlcpy(buff, attr, len);                                       \
202         return strchop(buff);                                           \
203 }
204
205 declare_sysfs_get_str(devtype);
206 declare_sysfs_get_str(vendor);
207 declare_sysfs_get_str(model);
208 declare_sysfs_get_str(rev);
209
210 ssize_t
211 sysfs_get_vpd (struct udev_device * udev, int pg,
212                unsigned char * buff, size_t len)
213 {
214         ssize_t attr_len;
215         char attrname[9];
216         const char * devname;
217
218         if (!udev) {
219                 condlog(3, "No udev device given\n");
220                 return -ENOSYS;
221         }
222
223         devname = udev_device_get_sysname(udev);
224         sprintf(attrname, "vpd_pg%02x", pg);
225         attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len);
226         if (attr_len < 0) {
227                 condlog(3, "%s: attribute %s not found in sysfs",
228                         devname, attrname);
229                 return attr_len;
230         }
231         return attr_len;
232 }
233
234 int
235 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
236 {
237         const char *attr = NULL;
238         const char *subsys;
239         struct udev_device *parent;
240         int r;
241         unsigned int t;
242
243         if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
244                 return -ENOSYS;
245
246         parent = pp->udev;
247         while (parent) {
248                 subsys = udev_device_get_subsystem(parent);
249                 attr = udev_device_get_sysattr_value(parent, "timeout");
250                 if (subsys && attr)
251                         break;
252                 parent = udev_device_get_parent(parent);
253         }
254         if (!attr) {
255                 condlog(3, "%s: No timeout value in sysfs", pp->dev);
256                 return -ENXIO;
257         }
258
259         r = sscanf(attr, "%u\n", &t);
260
261         if (r != 1) {
262                 condlog(3, "%s: Cannot parse timeout attribute '%s'",
263                         pp->dev, attr);
264                 return -EINVAL;
265         }
266
267         *timeout = t;
268
269         return 0;
270 }
271
272 int
273 sysfs_get_tgt_nodename (struct path *pp, char * node)
274 {
275         const char *tgtname, *value;
276         struct udev_device *parent, *tgtdev;
277         int host, channel, tgtid = -1;
278
279         parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
280         if (!parent)
281                 return 1;
282         /* Check for SAS */
283         value = udev_device_get_sysattr_value(parent, "sas_address");
284         if (value) {
285                 tgtdev = udev_device_get_parent(parent);
286                 while (tgtdev) {
287                         tgtname = udev_device_get_sysname(tgtdev);
288                         if (sscanf(tgtname, "end_device-%d:%d",
289                                    &host, &tgtid) == 2)
290                                 break;
291                         tgtdev = udev_device_get_parent(tgtdev);
292                         tgtid = -1;
293                 }
294                 if (tgtid >= 0) {
295                         pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
296                         pp->sg_id.transport_id = tgtid;
297                         strncpy(node, value, NODE_NAME_SIZE);
298                         return 0;
299                 }
300         }
301
302         /* Check for USB */
303         tgtdev = udev_device_get_parent(parent);
304         while (tgtdev) {
305                 value = udev_device_get_subsystem(tgtdev);
306                 if (value && !strcmp(value, "usb")) {
307                         pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
308                         tgtname = udev_device_get_sysname(tgtdev);
309                         strncpy(node, tgtname, strlen(tgtname));
310                         condlog(3, "%s: skip USB device %s", pp->dev, node);
311                         return 1;
312                 }
313                 tgtdev = udev_device_get_parent(tgtdev);
314         }
315         parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
316         if (!parent)
317                 return 1;
318         /* Check for FibreChannel */
319         tgtdev = udev_device_get_parent(parent);
320         value = udev_device_get_sysname(tgtdev);
321         if (sscanf(value, "rport-%d:%d-%d",
322                    &host, &channel, &tgtid) == 3) {
323                 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
324                                 "fc_remote_ports", value);
325                 if (tgtdev) {
326                         condlog(3, "SCSI target %d:%d:%d -> "
327                                 "FC rport %d:%d-%d",
328                                 pp->sg_id.host_no, pp->sg_id.channel,
329                                 pp->sg_id.scsi_id, host, channel,
330                                 tgtid);
331                         value = udev_device_get_sysattr_value(tgtdev,
332                                                               "node_name");
333                         if (value) {
334                                 pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
335                                 pp->sg_id.transport_id = tgtid;
336                                 strncpy(node, value, NODE_NAME_SIZE);
337                                 udev_device_unref(tgtdev);
338                                 return 0;
339                         } else
340                                 udev_device_unref(tgtdev);
341                 }
342         }
343
344         /* Check for iSCSI */
345         parent = pp->udev;
346         tgtname = NULL;
347         while (parent) {
348                 tgtname = udev_device_get_sysname(parent);
349                 if (tgtname && sscanf(tgtname , "session%d", &tgtid) == 1)
350                         break;
351                 parent = udev_device_get_parent(parent);
352                 tgtname = NULL;
353                 tgtid = -1;
354         }
355         if (parent && tgtname) {
356                 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
357                                 "iscsi_session", tgtname);
358                 if (tgtdev) {
359                         const char *value;
360
361                         value = udev_device_get_sysattr_value(tgtdev, "targetname");
362                         if (value) {
363                                 pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
364                                 pp->sg_id.transport_id = tgtid;
365                                 strncpy(node, value, NODE_NAME_SIZE);
366                                 udev_device_unref(tgtdev);
367                                 return 0;
368                         }
369                         else
370                                 udev_device_unref(tgtdev);
371                 }
372         }
373         /* Check for libata */
374         parent = pp->udev;
375         tgtname = NULL;
376         while (parent) {
377                 tgtname = udev_device_get_sysname(parent);
378                 if (tgtname && sscanf(tgtname, "ata%d", &tgtid) == 1)
379                         break;
380                 parent = udev_device_get_parent(parent);
381                 tgtname = NULL;
382         }
383         if (tgtname) {
384                 pp->sg_id.proto_id = SCSI_PROTOCOL_ATA;
385                 pp->sg_id.transport_id = tgtid;
386                 snprintf(node, NODE_NAME_SIZE, "ata-%d.00", tgtid);
387                 return 0;
388         }
389         /* Unknown SCSI transport. Keep fingers crossed */
390         pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
391         return 0;
392 }
393
394 int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name)
395 {
396         int proto_id;
397
398         if (!pp || !adapter_name)
399                 return 1;
400
401         proto_id = pp->sg_id.proto_id;
402
403         if (proto_id != SCSI_PROTOCOL_FCP &&
404             proto_id != SCSI_PROTOCOL_SAS &&
405             proto_id != SCSI_PROTOCOL_ISCSI &&
406             proto_id != SCSI_PROTOCOL_SRP) {
407                 return 1;
408         }
409         /* iscsi doesn't have adapter info in sysfs
410          * get ip_address for grouping paths
411          */
412         if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
413                 return sysfs_get_iscsi_ip_address(pp, adapter_name);
414
415         /* fetch adapter pci name for other protocols
416          */
417         return sysfs_get_host_pci_name(pp, adapter_name);
418 }
419
420 int sysfs_get_host_pci_name(struct path *pp, char *pci_name)
421 {
422         struct udev_device *hostdev, *parent;
423         char host_name[HOST_NAME_LEN];
424         const char *driver_name, *value;
425
426         if (!pp || !pci_name)
427                 return 1;
428
429         sprintf(host_name, "host%d", pp->sg_id.host_no);
430         hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
431                         "scsi_host", host_name);
432         if (!hostdev)
433                 return 1;
434
435         parent = udev_device_get_parent(hostdev);
436         while (parent) {
437                 driver_name = udev_device_get_driver(parent);
438                 if (!driver_name) {
439                         parent = udev_device_get_parent(parent);
440                         continue;
441                 }
442                 if (!strcmp(driver_name, "pcieport"))
443                         break;
444                 parent = udev_device_get_parent(parent);
445         }
446         if (parent) {
447                 /* pci_device found
448                  */
449                 value = udev_device_get_sysname(parent);
450
451                 strncpy(pci_name, value, SLOT_NAME_SIZE);
452                 udev_device_unref(hostdev);
453                 return 0;
454         }
455         udev_device_unref(hostdev);
456         return 1;
457 }
458
459 int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address)
460 {
461         struct udev_device *hostdev;
462         char host_name[HOST_NAME_LEN];
463         const char *value;
464
465         sprintf(host_name, "host%d", pp->sg_id.host_no);
466         hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
467                         "iscsi_host", host_name);
468         if (hostdev) {
469                 value = udev_device_get_sysattr_value(hostdev,
470                                 "ipaddress");
471                 if (value) {
472                         strncpy(ip_address, value, SLOT_NAME_SIZE);
473                         udev_device_unref(hostdev);
474                         return 0;
475                 } else
476                         udev_device_unref(hostdev);
477         }
478         return 1;
479 }
480
481 static void
482 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
483 {
484         struct udev_device *rport_dev = NULL;
485         char value[16];
486         char rport_id[32];
487         unsigned long long tmo = 0;
488         int ret;
489
490         sprintf(rport_id, "rport-%d:%d-%d",
491                 pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
492         rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
493                                 "fc_remote_ports", rport_id);
494         if (!rport_dev) {
495                 condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
496                         rport_id);
497                 return;
498         }
499         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
500                 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
501
502         /*
503          * This is tricky.
504          * dev_loss_tmo will be limited to 600 if fast_io_fail
505          * is _not_ set.
506          * fast_io_fail will be limited by the current dev_loss_tmo
507          * setting.
508          * So to get everything right we first need to increase
509          * dev_loss_tmo to the fast_io_fail setting (if present),
510          * then set fast_io_fail, and _then_ set dev_loss_tmo
511          * to the correct value.
512          */
513         memset(value, 0, 16);
514         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET &&
515             mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO &&
516             mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) {
517                 /* Check if we need to temporarily increase dev_loss_tmo */
518                 ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
519                                            value, 16);
520                 if (ret <= 0) {
521                         condlog(0, "%s: failed to read dev_loss_tmo value, "
522                                 "error %d", rport_id, -ret);
523                         goto out;
524                 }
525                 if (sscanf(value, "%llu\n", &tmo) != 1) {
526                         condlog(0, "%s: Cannot parse dev_loss_tmo "
527                                 "attribute '%s'", rport_id, value);
528                         goto out;
529                 }
530                 if (mpp->fast_io_fail >= tmo) {
531                         snprintf(value, 16, "%u", mpp->fast_io_fail + 1);
532                 }
533         } else if (mpp->dev_loss > 600) {
534                 condlog(3, "%s: limiting dev_loss_tmo to 600, since "
535                         "fast_io_fail is not set", rport_id);
536                 snprintf(value, 16, "%u", 600);
537         } else {
538                 snprintf(value, 16, "%u", mpp->dev_loss);
539         }
540         if (strlen(value)) {
541                 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
542                                            value, strlen(value));
543                 if (ret <= 0) {
544                         if (ret == -EBUSY)
545                                 condlog(3, "%s: rport blocked", rport_id);
546                         else
547                                 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
548                                         rport_id, value, -ret);
549                         goto out;
550                 }
551         }
552         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
553                 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
554                         sprintf(value, "off");
555                 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
556                         sprintf(value, "0");
557                 else
558                         snprintf(value, 16, "%u", mpp->fast_io_fail);
559                 ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
560                                            value, strlen(value));
561                 if (ret <= 0) {
562                         if (ret == -EBUSY)
563                                 condlog(3, "%s: rport blocked", rport_id);
564                         else
565                                 condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
566                                         rport_id, value, -ret);
567                 }
568         }
569         if (tmo > 0) {
570                 snprintf(value, 16, "%u", mpp->dev_loss);
571                 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
572                                            value, strlen(value));
573                 if (ret <= 0) {
574                         if (ret == -EBUSY)
575                                 condlog(3, "%s: rport blocked", rport_id);
576                         else
577                                 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
578                                         rport_id, value, -ret);
579                 }
580         }
581 out:
582         udev_device_unref(rport_dev);
583 }
584
585 static void
586 sysfs_set_session_tmo(struct multipath *mpp, struct path *pp)
587 {
588         struct udev_device *session_dev = NULL;
589         char session_id[64];
590         char value[11];
591
592         sprintf(session_id, "session%d", pp->sg_id.transport_id);
593         session_dev = udev_device_new_from_subsystem_sysname(conf->udev,
594                                 "iscsi_session", session_id);
595         if (!session_dev) {
596                 condlog(1, "%s: No iscsi session for '%s'", pp->dev,
597                         session_id);
598                 return;
599         }
600         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
601                 pp->sg_id.channel, pp->sg_id.scsi_id, session_id);
602
603         if (mpp->dev_loss) {
604                 condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev);
605         }
606         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
607                 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) {
608                         condlog(3, "%s: can't switch off fast_io_fail_tmo "
609                                 "on iSCSI", pp->dev);
610                 } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) {
611                         condlog(3, "%s: can't set fast_io_fail_tmo to '0'"
612                                 "on iSCSI", pp->dev);
613                 } else {
614                         snprintf(value, 11, "%u", mpp->fast_io_fail);
615                         if (sysfs_attr_set_value(session_dev, "recovery_tmo",
616                                                  value, 11) <= 0) {
617                                 condlog(3, "%s: Failed to set recovery_tmo, "
618                                         " error %d", pp->dev, errno);
619                         }
620                 }
621         }
622         udev_device_unref(session_dev);
623         return;
624 }
625
626 static void
627 sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp)
628 {
629         struct udev_device *sas_dev = NULL;
630         char end_dev_id[64];
631         char value[11];
632
633         sprintf(end_dev_id, "end_device-%d:%d",
634                 pp->sg_id.host_no, pp->sg_id.transport_id);
635         sas_dev = udev_device_new_from_subsystem_sysname(conf->udev,
636                                 "sas_end_device", end_dev_id);
637         if (!sas_dev) {
638                 condlog(1, "%s: No SAS end device for '%s'", pp->dev,
639                         end_dev_id);
640                 return;
641         }
642         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
643                 pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id);
644
645         if (mpp->dev_loss) {
646                 snprintf(value, 11, "%u", mpp->dev_loss);
647                 if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout",
648                                          value, 11) <= 0)
649                         condlog(3, "%s: failed to update "
650                                 "I_T Nexus loss timeout, error %d",
651                                 pp->dev, errno);
652         }
653         udev_device_unref(sas_dev);
654         return;
655 }
656
657 int
658 sysfs_set_scsi_tmo (struct multipath *mpp)
659 {
660         struct path *pp;
661         int i;
662         int dev_loss_tmo = mpp->dev_loss;
663
664         if (mpp->no_path_retry > 0) {
665                 int no_path_retry_tmo = mpp->no_path_retry * conf->checkint;
666
667                 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
668                         no_path_retry_tmo = MAX_DEV_LOSS_TMO;
669                 if (no_path_retry_tmo > dev_loss_tmo)
670                         dev_loss_tmo = no_path_retry_tmo;
671                 condlog(3, "%s: update dev_loss_tmo to %d",
672                         mpp->alias, dev_loss_tmo);
673         } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
674                 dev_loss_tmo = MAX_DEV_LOSS_TMO;
675                 condlog(3, "%s: update dev_loss_tmo to %d",
676                         mpp->alias, dev_loss_tmo);
677         }
678         mpp->dev_loss = dev_loss_tmo;
679         if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
680                 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
681                         mpp->alias, mpp->fast_io_fail);
682                 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
683         }
684         if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
685                 return 0;
686
687         vector_foreach_slot(mpp->paths, pp, i) {
688                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
689                         sysfs_set_rport_tmo(mpp, pp);
690                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
691                         sysfs_set_session_tmo(mpp, pp);
692                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
693                         sysfs_set_nexus_loss_tmo(mpp, pp);
694         }
695         return 0;
696 }
697
698 int
699 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
700        void *resp, int mx_resp_len)
701 {
702         unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
703                 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
704         unsigned char sense_b[SENSE_BUFF_LEN];
705         struct sg_io_hdr io_hdr;
706
707         if (cmddt)
708                 inqCmdBlk[1] |= 2;
709         if (evpd)
710                 inqCmdBlk[1] |= 1;
711         inqCmdBlk[2] = (unsigned char) pg_op;
712         inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
713         inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
714         memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
715         memset(sense_b, 0, SENSE_BUFF_LEN);
716         io_hdr.interface_id = 'S';
717         io_hdr.cmd_len = sizeof (inqCmdBlk);
718         io_hdr.mx_sb_len = sizeof (sense_b);
719         io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
720         io_hdr.dxfer_len = mx_resp_len;
721         io_hdr.dxferp = resp;
722         io_hdr.cmdp = inqCmdBlk;
723         io_hdr.sbp = sense_b;
724         io_hdr.timeout = DEF_TIMEOUT;
725
726         if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
727                 return -1;
728
729         /* treat SG_ERR here to get rid of sg_err.[ch] */
730         io_hdr.status &= 0x7e;
731         if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
732             (0 == io_hdr.driver_status))
733                 return 0;
734         if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
735             (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
736             (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
737                 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
738                         int sense_key;
739                         unsigned char * sense_buffer = io_hdr.sbp;
740                         if (sense_buffer[0] & 0x2)
741                                 sense_key = sense_buffer[1] & 0xf;
742                         else
743                                 sense_key = sense_buffer[2] & 0xf;
744                         if(RECOVERED_ERROR == sense_key)
745                                 return 0;
746                 }
747         }
748         return -1;
749 }
750
751 static int
752 get_serial (char * str, int maxlen, int fd)
753 {
754         int len = 0;
755         char buff[MX_ALLOC_LEN + 1] = {0};
756
757         if (fd < 0)
758                 return 1;
759
760         if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
761                 len = buff[3];
762                 if (len >= maxlen)
763                         return 1;
764                 if (len > 0) {
765                         memcpy(str, buff + 4, len);
766                         str[len] = '\0';
767                 }
768                 return 0;
769         }
770         return 1;
771 }
772
773 #define DEFAULT_SGIO_LEN 254
774
775 static int
776 sgio_get_vpd (unsigned char * buff, int maxlen, int fd)
777 {
778         int len = DEFAULT_SGIO_LEN;
779
780         if (fd < 0) {
781                 errno = EBADF;
782                 return -1;
783         }
784 retry:
785         if (0 == do_inq(fd, 0, 1, 0x83, buff, len)) {
786                 len = buff[3] + (buff[2] << 8);
787                 if (len >= maxlen)
788                         return len;
789                 if (len > DEFAULT_SGIO_LEN)
790                         goto retry;
791                 return 0;
792         }
793         return -1;
794 }
795
796 static int
797 get_geometry(struct path *pp)
798 {
799         if (pp->fd < 0)
800                 return 1;
801
802         if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
803                 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
804                 memset(&pp->geom, 0, sizeof(pp->geom));
805                 return 1;
806         }
807         condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
808                 pp->dev, pp->geom.cylinders, pp->geom.heads,
809                 pp->geom.sectors, pp->geom.start);
810         return 0;
811 }
812
813 static int
814 parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len)
815 {
816         char *p = NULL;
817         int len = in[3] + (in[2] << 8);
818
819         if (len >= out_len) {
820                 condlog(2, "vpd pg80 overflow, %d/%d bytes required",
821                         len, (int)out_len);
822                 len = out_len;
823         }
824         if (len > 0) {
825                 memcpy(out, in + 4, len);
826                 out[len] = '\0';
827         }
828         /*
829          * Strip trailing whitspaces
830          */
831         p = out + len - 1;
832         while (p > out && *p == ' ') {
833                 *p = '\0';
834                 p--;
835                 len --;
836         }
837         return len;
838 }
839
840 static int
841 parse_vpd_pg83(const unsigned char *in, size_t in_len,
842                char *out, size_t out_len)
843 {
844         unsigned char *d;
845         unsigned char *vpd = NULL;
846         int len = -ENODATA, vpd_type, vpd_len, prio = -1, i, naa_prio;
847
848         d = (unsigned char *)in + 4;
849         while (d < (unsigned char *)in + in_len) {
850                 /* Select 'association: LUN' */
851                 if ((d[1] & 0x30) != 0) {
852                         d += d[3] + 4;
853                         continue;
854                 }
855                 switch (d[1] & 0xf) {
856                 case 0x3:
857                         /* NAA: Prio 5 */
858                         switch (d[4] >> 4) {
859                         case 6:
860                                 /* IEEE Registered Extended: Prio 8 */
861                                 naa_prio = 8;
862                                 break;
863                         case 5:
864                                 /* IEEE Registered: Prio 7 */
865                                 naa_prio = 7;
866                                 break;
867                         case 2:
868                                 /* IEEE Extended: Prio 6 */
869                                 naa_prio = 6;
870                                 break;
871                         case 3:
872                                 /* IEEE Locally assigned: Prio 1 */
873                                 naa_prio = 1;
874                                 break;
875                         default:
876                                 /* Default: no priority */
877                                 naa_prio = -1;
878                                 break;
879                         }
880                         if (prio < naa_prio) {
881                                 prio = naa_prio;
882                                 vpd = d;
883                         }
884                         break;
885                 case 0x8:
886                         /* SCSI Name: Prio 4 */
887                         if (memcmp(d + 4, "eui.", 4) &&
888                             memcmp(d + 4, "naa.", 4) &&
889                             memcmp(d + 4, "iqn.", 4))
890                                 continue;
891                         if (prio < 4) {
892                                 prio = 4;
893                                 vpd = d;
894                         }
895                         break;
896                 case 0x2:
897                         /* EUI-64: Prio 3 */
898                         if (prio < 3) {
899                                 prio = 3;
900                                 vpd = d;
901                         }
902                         break;
903                 case 0x1:
904                         /* T-10 Vendor ID: Prio 2 */
905                         if (prio < 2) {
906                                 prio = 2;
907                                 vpd = d;
908                         }
909                         break;
910                 }
911                 d += d[3] + 4;
912         }
913         if (prio > 0) {
914                 vpd_type = vpd[1] & 0xf;
915                 vpd_len = vpd[3];
916                 vpd += 4;
917                 if (vpd_type == 0x2 || vpd_type == 0x3) {
918                         int i;
919
920                         len = sprintf(out, "%d", vpd_type);
921                         for (i = 0; i < vpd_len; i++) {
922                                 len += sprintf(out + len,
923                                                "%02x", vpd[i]);
924                                 if (len >= out_len)
925                                         break;
926                         }
927                 } else if (vpd_type == 0x8) {
928                         if (!memcmp("eui.", vpd, 4)) {
929                                 out[0] =  '2';
930                                 len = 1;
931                                 vpd += 4;
932                                 vpd_len -= 4;
933                                 for (i = 0; i < vpd_len; i++) {
934                                         len += sprintf(out + len, "%c",
935                                                        tolower(vpd[i]));
936                                         if (len >= out_len)
937                                                 break;
938                                 }
939                                 len = vpd_len + 1;
940                                 out[len] = '\0';
941                         } else if (!memcmp("naa.", vpd, 4)) {
942                                 out[0] = '3';
943                                 len = 1;
944                                 vpd += 4;
945                                 vpd_len -= 4;
946                                 for (i = 0; i < vpd_len; i++) {
947                                         len += sprintf(out + len, "%c",
948                                                        tolower(vpd[i]));
949                                         if (len >= out_len)
950                                                 break;
951                                 }
952                                 len = vpd_len + 1;
953                                 out[len] = '\0';
954                         } else {
955                                 out[0] = '8';
956                                 len = 1;
957                                 vpd += 4;
958                                 vpd_len -= 4;
959                                 if (vpd_len > out_len + 2)
960                                         vpd_len = out_len - 2;
961                                 memcpy(out, vpd, vpd_len);
962                                 len = vpd_len + 1;
963                                 out[len] = '\0';
964                         }
965                 } else if (vpd_type == 0x1) {
966                         unsigned char *p;
967                         int p_len;
968
969                         out[0] = '1';
970                         len = 1;
971                         p = vpd;
972                         while ((p = memchr(vpd, ' ', vpd_len))) {
973                                 p_len = p - vpd;
974                                 if (len + p_len > out_len - 1)
975                                         p_len = out_len - len - 2;
976                                 memcpy(out + len, vpd, p_len);
977                                 len += p_len;
978                                 if (len >= out_len - 1) {
979                                         out[len] = '\0';
980                                         break;
981                                 }
982                                 out[len] = '_';
983                                 len ++;
984                                 vpd = p;
985                                 vpd_len -= p_len;
986                                 while (vpd && *vpd == ' ') {
987                                         vpd++;
988                                         vpd_len --;
989                                 }
990                         }
991                         if (len > 1 && out[len - 1] == '_') {
992                                 out[len - 1] = '\0';
993                                 len--;
994                         }
995                 }
996         }
997         return len;
998 }
999
1000 static int
1001 get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
1002 {
1003         int len, buff_len;
1004         unsigned char buff[4096];
1005
1006         memset(buff, 0x0, 4096);
1007         if (!parent || sysfs_get_vpd(parent, pg, buff, 4096) <= 0) {
1008                 condlog(3, "failed to read sysfs vpd pg%02x", pg);
1009                 return -EINVAL;
1010         }
1011
1012         if (buff[1] != pg) {
1013                 condlog(3, "vpd pg%02x error, invalid vpd page %02x",
1014                         pg, buff[1]);
1015                 return -ENODATA;
1016         }
1017         buff_len = (buff[2] << 8) + buff[3] + 4;
1018         if (buff_len > 4096)
1019                 condlog(3, "vpd pg%02x page truncated", pg);
1020
1021         if (pg == 0x80)
1022                 len = parse_vpd_pg80(buff, str, maxlen);
1023         else if (pg == 0x83)
1024                 len = parse_vpd_pg83(buff, buff_len, str, maxlen);
1025         else
1026                 len = -ENOSYS;
1027
1028         return len;
1029 }
1030
1031 static int
1032 get_vpd_sgio (int fd, int pg, char * str, int maxlen)
1033 {
1034         int len, buff_len;
1035         unsigned char buff[4096];
1036
1037         memset(buff, 0x0, 4096);
1038         if (sgio_get_vpd(buff, 4096, fd) <= 0) {
1039                 condlog(3, "failed to issue vpd inquiry for pg%02x",
1040                         pg);
1041                 return -errno;
1042         }
1043
1044         if (buff[1] != pg) {
1045                 condlog(3, "vpd pg%02x error, invalid vpd page %02x",
1046                         pg, buff[1]);
1047                 return -ENODATA;
1048         }
1049         buff_len = (buff[2] << 8) + buff[3] + 4;
1050         if (buff_len > 4096)
1051                 condlog(3, "vpd pg%02x page truncated", pg);
1052
1053         if (pg == 0x80)
1054                 len = parse_vpd_pg80(buff, str, maxlen);
1055         else if (pg == 0x83)
1056                 len = parse_vpd_pg83(buff, buff_len, str, maxlen);
1057         else
1058                 len = -ENOSYS;
1059
1060         return len;
1061 }
1062
1063 static int
1064 scsi_sysfs_pathinfo (struct path * pp)
1065 {
1066         struct udev_device *parent;
1067         const char *attr_path = NULL;
1068
1069         parent = pp->udev;
1070         while (parent) {
1071                 const char *subsys = udev_device_get_subsystem(parent);
1072                 if (subsys && !strncmp(subsys, "scsi", 4)) {
1073                         attr_path = udev_device_get_sysname(parent);
1074                         if (!attr_path)
1075                                 break;
1076                         if (sscanf(attr_path, "%i:%i:%i:%i",
1077                                    &pp->sg_id.host_no,
1078                                    &pp->sg_id.channel,
1079                                    &pp->sg_id.scsi_id,
1080                                    &pp->sg_id.lun) == 4)
1081                                 break;
1082                 }
1083                 parent = udev_device_get_parent(parent);
1084         }
1085         if (!attr_path || pp->sg_id.host_no == -1)
1086                 return 1;
1087
1088         if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
1089                 return 1;
1090
1091         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1092
1093         if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE) <= 0)
1094                 return 1;
1095
1096         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1097
1098         if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE) <= 0)
1099                 return 1;
1100
1101         condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1102
1103         /*
1104          * set the hwe configlet pointer
1105          */
1106         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
1107
1108         /*
1109          * host / bus / target / lun
1110          */
1111         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1112                         pp->dev,
1113                         pp->sg_id.host_no,
1114                         pp->sg_id.channel,
1115                         pp->sg_id.scsi_id,
1116                         pp->sg_id.lun);
1117
1118         /*
1119          * target node name
1120          */
1121         if(sysfs_get_tgt_nodename(pp, pp->tgt_node_name))
1122                 return 1;
1123
1124         condlog(3, "%s: tgt_node_name = %s",
1125                 pp->dev, pp->tgt_node_name);
1126
1127         return 0;
1128 }
1129
1130 static int
1131 ccw_sysfs_pathinfo (struct path * pp)
1132 {
1133         struct udev_device *parent;
1134         char attr_buff[NAME_SIZE];
1135         const char *attr_path;
1136
1137         parent = pp->udev;
1138         while (parent) {
1139                 const char *subsys = udev_device_get_subsystem(parent);
1140                 if (subsys && !strncmp(subsys, "ccw", 3))
1141                         break;
1142                 parent = udev_device_get_parent(parent);
1143         }
1144         if (!parent)
1145                 return 1;
1146
1147         sprintf(pp->vendor_id, "IBM");
1148
1149         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1150
1151         if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE) <= 0)
1152                 return 1;
1153
1154         if (!strncmp(attr_buff, "3370", 4)) {
1155                 sprintf(pp->product_id,"S/390 DASD FBA");
1156         } else if (!strncmp(attr_buff, "9336", 4)) {
1157                 sprintf(pp->product_id,"S/390 DASD FBA");
1158         } else {
1159                 sprintf(pp->product_id,"S/390 DASD ECKD");
1160         }
1161
1162         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1163
1164         /*
1165          * set the hwe configlet pointer
1166          */
1167         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, NULL);
1168
1169         /*
1170          * host / bus / target / lun
1171          */
1172         attr_path = udev_device_get_sysname(parent);
1173         pp->sg_id.lun = 0;
1174         sscanf(attr_path, "%i.%i.%x",
1175                         &pp->sg_id.host_no,
1176                         &pp->sg_id.channel,
1177                         &pp->sg_id.scsi_id);
1178         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1179                         pp->dev,
1180                         pp->sg_id.host_no,
1181                         pp->sg_id.channel,
1182                         pp->sg_id.scsi_id,
1183                         pp->sg_id.lun);
1184
1185         return 0;
1186 }
1187
1188 static int
1189 cciss_sysfs_pathinfo (struct path * pp)
1190 {
1191         const char * attr_path = NULL;
1192         struct udev_device *parent;
1193
1194         parent = pp->udev;
1195         while (parent) {
1196                 const char *subsys = udev_device_get_subsystem(parent);
1197                 if (subsys && !strncmp(subsys, "cciss", 5)) {
1198                         attr_path = udev_device_get_sysname(parent);
1199                         if (!attr_path)
1200                                 break;
1201                         if (sscanf(attr_path, "c%id%i",
1202                                    &pp->sg_id.host_no,
1203                                    &pp->sg_id.scsi_id) == 2)
1204                                 break;
1205                 }
1206                 parent = udev_device_get_parent(parent);
1207         }
1208         if (!attr_path || pp->sg_id.host_no == -1)
1209                 return 1;
1210
1211         if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
1212                 return 1;
1213
1214         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1215
1216         if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE) <= 0)
1217                 return 1;
1218
1219         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1220
1221         if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE) <= 0)
1222                 return 1;
1223
1224         condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1225
1226         /*
1227          * set the hwe configlet pointer
1228          */
1229         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
1230
1231         /*
1232          * host / bus / target / lun
1233          */
1234         pp->sg_id.lun = 0;
1235         pp->sg_id.channel = 0;
1236         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1237                 pp->dev,
1238                 pp->sg_id.host_no,
1239                 pp->sg_id.channel,
1240                 pp->sg_id.scsi_id,
1241                 pp->sg_id.lun);
1242         return 0;
1243 }
1244
1245 static int
1246 common_sysfs_pathinfo (struct path * pp)
1247 {
1248         dev_t devt;
1249
1250         if (!pp)
1251                 return 1;
1252
1253         if (!pp->udev) {
1254                 condlog(4, "%s: udev not initialised", pp->dev);
1255                 return 1;
1256         }
1257         devt = udev_device_get_devnum(pp->udev);
1258         snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt));
1259
1260         condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
1261
1262         if (sysfs_get_size(pp, &pp->size))
1263                 return 1;
1264
1265         condlog(3, "%s: size = %llu", pp->dev, pp->size);
1266
1267         return 0;
1268 }
1269
1270 int
1271 path_offline (struct path * pp)
1272 {
1273         struct udev_device * parent;
1274         char buff[SCSI_STATE_SIZE];
1275         int err;
1276
1277         if (pp->bus != SYSFS_BUS_SCSI)
1278                 return PATH_UP;
1279
1280         parent = pp->udev;
1281         while (parent) {
1282                 const char *subsys = udev_device_get_subsystem(parent);
1283                 if (subsys && !strncmp(subsys, "scsi", 4))
1284                         break;
1285                 parent = udev_device_get_parent(parent);
1286         }
1287
1288         if (!parent) {
1289                 condlog(1, "%s: failed to get sysfs information", pp->dev);
1290                 return PATH_REMOVED;
1291         }
1292
1293         memset(buff, 0x0, SCSI_STATE_SIZE);
1294         err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE);
1295         if (err <= 0) {
1296                 if (err == -ENXIO)
1297                         return PATH_REMOVED;
1298                 else
1299                         return PATH_DOWN;
1300         }
1301
1302
1303         condlog(3, "%s: path state = %s", pp->dev, buff);
1304
1305         if (!strncmp(buff, "offline", 7)) {
1306                 pp->offline = 1;
1307                 return PATH_DOWN;
1308         }
1309         pp->offline = 0;
1310         if (!strncmp(buff, "blocked", 7) || !strncmp(buff, "quiesce", 7))
1311                 return PATH_PENDING;
1312         else if (!strncmp(buff, "running", 7))
1313                 return PATH_UP;
1314
1315         return PATH_DOWN;
1316 }
1317
1318 int
1319 sysfs_pathinfo(struct path * pp)
1320 {
1321         if (common_sysfs_pathinfo(pp))
1322                 return 1;
1323
1324         pp->bus = SYSFS_BUS_UNDEF;
1325         if (!strncmp(pp->dev,"cciss",5))
1326                 pp->bus = SYSFS_BUS_CCISS;
1327         if (!strncmp(pp->dev,"dasd", 4))
1328                 pp->bus = SYSFS_BUS_CCW;
1329         if (!strncmp(pp->dev,"sd", 2))
1330                 pp->bus = SYSFS_BUS_SCSI;
1331
1332         if (pp->bus == SYSFS_BUS_UNDEF)
1333                 return 0;
1334         else if (pp->bus == SYSFS_BUS_SCSI) {
1335                 if (scsi_sysfs_pathinfo(pp))
1336                         return 1;
1337         } else if (pp->bus == SYSFS_BUS_CCW) {
1338                 if (ccw_sysfs_pathinfo(pp))
1339                         return 1;
1340         } else if (pp->bus == SYSFS_BUS_CCISS) {
1341                 if (cciss_sysfs_pathinfo(pp))
1342                         return 1;
1343         }
1344         return 0;
1345 }
1346
1347 static int
1348 scsi_ioctl_pathinfo (struct path * pp, int mask)
1349 {
1350         struct udev_device *parent;
1351         const char *attr_path = NULL;
1352
1353         if (!(mask & DI_SERIAL))
1354                 return 0;
1355
1356         parent = pp->udev;
1357         while (parent) {
1358                 const char *subsys = udev_device_get_subsystem(parent);
1359                 if (subsys && !strncmp(subsys, "scsi", 4)) {
1360                         attr_path = udev_device_get_sysname(parent);
1361                         if (!attr_path)
1362                                 break;
1363                         if (sscanf(attr_path, "%i:%i:%i:%i",
1364                                    &pp->sg_id.host_no,
1365                                    &pp->sg_id.channel,
1366                                    &pp->sg_id.scsi_id,
1367                                    &pp->sg_id.lun) == 4)
1368                                 break;
1369                 }
1370                 parent = udev_device_get_parent(parent);
1371         }
1372         if (!attr_path || pp->sg_id.host_no == -1)
1373                 return -ENODEV;
1374
1375         if (get_vpd_sysfs(parent, 0x80, pp->serial, SERIAL_SIZE) > 0)
1376                 condlog(3, "%s: serial = %s",
1377                         pp->dev, pp->serial);
1378
1379         return strlen(pp->serial) ? 0 : -EIO;
1380 }
1381
1382 static int
1383 cciss_ioctl_pathinfo (struct path * pp, int mask)
1384 {
1385         if (mask & DI_SERIAL) {
1386                 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
1387                 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1388         }
1389         return 0;
1390 }
1391
1392 int
1393 get_state (struct path * pp, int daemon)
1394 {
1395         struct checker * c = &pp->checker;
1396         int state;
1397
1398         condlog(3, "%s: get_state", pp->dev);
1399
1400         if (!checker_selected(c)) {
1401                 if (daemon) {
1402                         if (pathinfo(pp, conf->hwtable, DI_SYSFS) != PATHINFO_OK) {
1403                                 condlog(3, "%s: couldn't get sysfs pathinfo",
1404                                         pp->dev);
1405                                 return PATH_UNCHECKED;
1406                         }
1407                 }
1408                 select_checker(pp);
1409                 if (!checker_selected(c)) {
1410                         condlog(3, "%s: No checker selected", pp->dev);
1411                         return PATH_UNCHECKED;
1412                 }
1413                 checker_set_fd(c, pp->fd);
1414                 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
1415                         memset(c, 0x0, sizeof(struct checker));
1416                         condlog(3, "%s: checker init failed", pp->dev);
1417                         return PATH_UNCHECKED;
1418                 }
1419         }
1420         checker_clear_message(c);
1421         if (daemon) {
1422                 if (conf->force_sync == 0)
1423                         checker_set_async(c);
1424                 else
1425                         checker_set_sync(c);
1426         }
1427         if (!conf->checker_timeout &&
1428             sysfs_get_timeout(pp, &(c->timeout)) <= 0)
1429                 c->timeout = DEF_TIMEOUT;
1430         state = checker_check(c);
1431         condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
1432         if (state != PATH_UP && state != PATH_GHOST &&
1433             strlen(checker_message(c)))
1434                 condlog(3, "%s: checker msg is \"%s\"",
1435                         pp->dev, checker_message(c));
1436         return state;
1437 }
1438
1439 static int
1440 get_prio (struct path * pp)
1441 {
1442         if (!pp)
1443                 return 0;
1444
1445         struct prio * p = &pp->prio;
1446
1447         if (!prio_selected(p)) {
1448                 select_detect_prio(pp);
1449                 select_prio(pp);
1450                 if (!prio_selected(p)) {
1451                         condlog(3, "%s: no prio selected", pp->dev);
1452                         pp->priority = PRIO_UNDEF;
1453                         return 1;
1454                 }
1455         }
1456         pp->priority = prio_getprio(p, pp);
1457         if (pp->priority < 0) {
1458                 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
1459                 pp->priority = PRIO_UNDEF;
1460                 return 1;
1461         }
1462         condlog(3, "%s: %s prio = %u",
1463                 pp->dev, prio_name(p), pp->priority);
1464         return 0;
1465 }
1466
1467 static int
1468 get_udev_uid(struct path * pp, char *uid_attribute)
1469 {
1470         ssize_t len;
1471         const char *value;
1472
1473         value = udev_device_get_property_value(pp->udev,
1474                                                uid_attribute);
1475         if ((!value || strlen(value) == 0) && conf->cmd == CMD_VALID_PATH)
1476                 value = getenv(uid_attribute);
1477         if (value && strlen(value)) {
1478                 if (strlen(value) + 1 > WWID_SIZE) {
1479                         condlog(0, "%s: wwid overflow", pp->dev);
1480                         len = WWID_SIZE;
1481                 } else {
1482                         len = strlen(value);
1483                 }
1484                 strncpy(pp->wwid, value, len);
1485         } else {
1486                 condlog(3, "%s: no %s attribute", pp->dev,
1487                         uid_attribute);
1488                 len = -EINVAL;
1489         }
1490         return len;
1491 }
1492
1493 static int
1494 get_vpd_uid(struct path * pp)
1495 {
1496         struct udev_device *parent = pp->udev;
1497
1498         while (parent) {
1499                 const char *subsys = udev_device_get_subsystem(parent);
1500                 if (subsys && !strncmp(subsys, "scsi", 4))
1501                         break;
1502                 parent = udev_device_get_parent(parent);
1503         }
1504
1505         return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE);
1506 }
1507
1508 static int
1509 get_uid (struct path * pp)
1510 {
1511         char *c;
1512         const char *origin = "unknown";
1513         ssize_t len = 0;
1514
1515         if (!pp->uid_attribute && !pp->getuid)
1516                 select_getuid(pp);
1517
1518         if (!pp->udev) {
1519                 condlog(1, "%s: no udev information", pp->dev);
1520                 return 1;
1521         }
1522
1523         memset(pp->wwid, 0, WWID_SIZE);
1524         if (pp->getuid) {
1525                 char buff[CALLOUT_MAX_SIZE];
1526
1527                 /* Use 'getuid' callout, deprecated */
1528                 condlog(1, "%s: using deprecated getuid callout", pp->dev);
1529                 if (apply_format(pp->getuid, &buff[0], pp)) {
1530                         condlog(0, "error formatting uid callout command");
1531                         memset(pp->wwid, 0, WWID_SIZE);
1532                         len = -EINVAL;
1533                 } else if (execute_program(buff, pp->wwid, WWID_SIZE)) {
1534                         condlog(3, "error calling out %s", buff);
1535                         memset(pp->wwid, 0, WWID_SIZE);
1536                         len = -EIO;
1537                 } else
1538                         len = strlen(pp->wwid);
1539                 origin = "callout";
1540         } else {
1541                 if (pp->uid_attribute) {
1542                         len = get_udev_uid(pp, pp->uid_attribute);
1543                         origin = "udev";
1544                         if (len <= 0)
1545                                 condlog(1,
1546                                         "%s: failed to get udev uid: %s",
1547                                         pp->dev, strerror(-len));
1548
1549                 }
1550                 if (len <= 0 &&
1551                     !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
1552                         len = get_vpd_uid(pp);
1553                         origin = "sysfs";
1554                         pp->uid_attribute = NULL;
1555                         if (len < 0) {
1556                                 condlog(1, "%s: failed to get sysfs uid: %s",
1557                                         pp->dev, strerror(-len));
1558                                 len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
1559                                                    WWID_SIZE);
1560                                 origin = "sgio";
1561                         }
1562                 }
1563         }
1564         if ( len < 0 ) {
1565                 condlog(1, "%s: failed to get %s uid: %s",
1566                         pp->dev, origin, strerror(-len));
1567                 memset(pp->wwid, 0x0, WWID_SIZE);
1568         } else {
1569                 /* Strip any trailing blanks */
1570                 c = strchr(pp->wwid, '\0');
1571                 c--;
1572                 while (c && c >= pp->wwid && *c == ' ') {
1573                         *c = '\0';
1574                         c--;
1575                 }
1576         }
1577         condlog(3, "%s: uid = %s (%s)", pp->dev,
1578                 *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
1579         return 0;
1580 }
1581
1582 extern int
1583 pathinfo (struct path *pp, vector hwtable, int mask)
1584 {
1585         int path_state;
1586
1587         if (!pp)
1588                 return PATHINFO_FAILED;
1589
1590         condlog(3, "%s: mask = 0x%x", pp->dev, mask);
1591
1592         /*
1593          * fetch info available in sysfs
1594          */
1595         if (mask & DI_SYSFS && sysfs_pathinfo(pp))
1596                 return PATHINFO_FAILED;
1597
1598         if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
1599                 if (filter_device(conf->blist_device, conf->elist_device,
1600                                   pp->vendor_id, pp->product_id) > 0) {
1601                         return PATHINFO_SKIPPED;
1602                 }
1603         }
1604
1605         path_state = path_offline(pp);
1606         if (path_state == PATH_REMOVED)
1607                 goto blank;
1608
1609         /*
1610          * fetch info not available through sysfs
1611          */
1612         if (pp->fd < 0)
1613                 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1614
1615         if (pp->fd < 0) {
1616                 condlog(4, "Couldn't open node for %s: %s",
1617                         pp->dev, strerror(errno));
1618                 goto blank;
1619         }
1620
1621         if (mask & DI_SERIAL)
1622                 get_geometry(pp);
1623
1624         if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1625             scsi_ioctl_pathinfo(pp, mask))
1626                 goto blank;
1627
1628         if (pp->bus == SYSFS_BUS_CCISS &&
1629             cciss_ioctl_pathinfo(pp, mask))
1630                 goto blank;
1631
1632         if (mask & DI_CHECKER) {
1633                 if (path_state == PATH_UP) {
1634                         pp->chkrstate = pp->state = get_state(pp, 0);
1635                         if (pp->state == PATH_UNCHECKED ||
1636                             pp->state == PATH_WILD)
1637                                 goto blank;
1638                         if (pp->state == PATH_TIMEOUT)
1639                                 pp->state = PATH_DOWN;
1640                         if (pp->state == PATH_UP && !pp->size) {
1641                                 condlog(3, "%s: device size is 0, "
1642                                         "path unuseable", pp->dev);
1643                                 pp->state = PATH_GHOST;
1644                         }
1645                 } else {
1646                         condlog(3, "%s: path inaccessible", pp->dev);
1647                         pp->chkrstate = pp->state = path_state;
1648                         if (path_state == PATH_PENDING ||
1649                             path_state == PATH_DOWN)
1650                                 pp->priority = 0;
1651                 }
1652         }
1653
1654         if ((mask & DI_WWID) && !strlen(pp->wwid))
1655                 get_uid(pp);
1656         if (mask & DI_BLACKLIST && mask & DI_WWID) {
1657                 if (!strlen(pp->wwid) ||
1658                     filter_wwid(conf->blist_wwid, conf->elist_wwid,
1659                                 pp->wwid, pp->dev) > 0) {
1660                         return PATHINFO_SKIPPED;
1661                 }
1662         }
1663
1664          /*
1665           * Retrieve path priority, even for PATH_DOWN paths if it has never
1666           * been successfully obtained before.
1667           */
1668         if ((mask & DI_PRIO) && path_state == PATH_UP) {
1669                 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1670                         if (!strlen(pp->wwid))
1671                                 get_uid(pp);
1672                         if (!strlen(pp->wwid))
1673                                 return PATHINFO_SKIPPED;
1674                         get_prio(pp);
1675                 }
1676         }
1677
1678         pp->initialized = 1;
1679         return PATHINFO_OK;
1680
1681 blank:
1682         /*
1683          * Recoverable error, for example faulty or offline path
1684          */
1685         memset(pp->wwid, 0, WWID_SIZE);
1686         pp->chkrstate = pp->state = PATH_DOWN;
1687         pp->initialized = 0;
1688
1689         return 0;
1690 }