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