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