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