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