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