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