Skip USB devices during discovery
[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 <fcntl.h>
10 #include <sys/ioctl.h>
11 #include <sys/stat.h>
12 #include <dirent.h>
13 #include <errno.h>
14 #include <libgen.h>
15 #include <libudev.h>
16
17 #include "checkers.h"
18 #include "vector.h"
19 #include "memory.h"
20 #include "util.h"
21 #include "structs.h"
22 #include "config.h"
23 #include "blacklist.h"
24 #include "callout.h"
25 #include "debug.h"
26 #include "propsel.h"
27 #include "sg_include.h"
28 #include "sysfs.h"
29 #include "discovery.h"
30 #include "prio.h"
31 #include "defaults.h"
32
33 int
34 alloc_path_with_pathinfo (vector hwtable, struct udev_device *udevice,
35                           int flag, struct path **pp_ptr)
36 {
37         int err = PATHINFO_FAILED;
38         struct path * pp;
39         const char * devname;
40
41         if (pp_ptr)
42                 *pp_ptr = NULL;
43
44         devname = udev_device_get_sysname(udevice);
45         if (!devname)
46                 return PATHINFO_FAILED;
47
48         pp = alloc_path();
49
50         if (!pp)
51                 return PATHINFO_FAILED;
52
53         if (safe_sprintf(pp->dev, "%s", devname)) {
54                 condlog(0, "pp->dev too small");
55         } else {
56                 pp->udev = udev_device_ref(udevice);
57                 err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
58         }
59
60         if (err)
61                 free_path(pp);
62         else if (pp_ptr)
63                 *pp_ptr = pp;
64         return err;
65 }
66
67 int
68 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
69                 int flag, struct path **pp_ptr)
70 {
71         int err = PATHINFO_FAILED;
72         struct path * pp;
73         const char * devname;
74
75         if (pp_ptr)
76                 *pp_ptr = NULL;
77
78         devname = udev_device_get_sysname(udevice);
79         if (!devname)
80                 return PATHINFO_FAILED;
81
82         pp = alloc_path();
83
84         if (!pp)
85                 return PATHINFO_FAILED;
86
87         if(safe_sprintf(pp->dev, "%s", devname)) {
88                 condlog(0, "pp->dev too small");
89                 goto out;
90         }
91         pp->udev = udev_device_ref(udevice);
92         err = pathinfo(pp, hwtable,
93                        (conf->cmd == CMD_REMOVE_WWID)? flag :
94                                                        (flag | DI_BLACKLIST));
95         if (err)
96                 goto out;
97
98         err = store_path(pathvec, pp);
99         if (err)
100                 goto out;
101
102 out:
103         if (err)
104                 free_path(pp);
105         else if (pp_ptr)
106                 *pp_ptr = pp;
107         return err;
108 }
109
110 static int
111 path_discover (vector pathvec, struct config * conf,
112                struct udev_device *udevice, int flag)
113 {
114         struct path * pp;
115         const char * devname;
116
117         devname = udev_device_get_sysname(udevice);
118         if (!devname)
119                 return PATHINFO_FAILED;
120
121         if (filter_property(conf, udevice) > 0)
122                 return PATHINFO_SKIPPED;
123
124         if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
125                            (char *)devname) > 0)
126                 return PATHINFO_SKIPPED;
127
128         pp = find_path_by_dev(pathvec, (char *)devname);
129         if (!pp) {
130                 return store_pathinfo(pathvec, conf->hwtable,
131                                       udevice, flag, NULL);
132         }
133         return pathinfo(pp, conf->hwtable, flag);
134 }
135
136 int
137 path_discovery (vector pathvec, struct config * conf, int flag)
138 {
139         struct udev_enumerate *udev_iter;
140         struct udev_list_entry *entry;
141         struct udev_device *udevice;
142         const char *devpath;
143         int num_paths = 0, total_paths = 0;
144
145         udev_iter = udev_enumerate_new(conf->udev);
146         if (!udev_iter)
147                 return -ENOMEM;
148
149         udev_enumerate_add_match_subsystem(udev_iter, "block");
150         udev_enumerate_scan_devices(udev_iter);
151
152         udev_list_entry_foreach(entry,
153                                 udev_enumerate_get_list_entry(udev_iter)) {
154                 const char *devtype;
155                 devpath = udev_list_entry_get_name(entry);
156                 condlog(4, "Discover device %s", devpath);
157                 udevice = udev_device_new_from_syspath(conf->udev, devpath);
158                 if (!udevice) {
159                         condlog(4, "%s: no udev information", devpath);
160                         continue;
161                 }
162                 devtype = udev_device_get_devtype(udevice);
163                 if(devtype && !strncmp(devtype, "disk", 4)) {
164                         total_paths++;
165                         if (path_discover(pathvec, conf,
166                                           udevice, flag) == PATHINFO_OK)
167                                 num_paths++;
168                 }
169                 udev_device_unref(udevice);
170         }
171         udev_enumerate_unref(udev_iter);
172         condlog(4, "Discovered %d/%d paths", num_paths, total_paths);
173         return (total_paths - num_paths);
174 }
175
176 #define declare_sysfs_get_str(fname)                                    \
177 extern ssize_t                                                          \
178 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len)  \
179 {                                                                       \
180         int l;                                                  \
181         const char * attr;                                              \
182         const char * devname;                                           \
183                                                                         \
184         if (!udev)                                                      \
185                 return -ENOSYS;                                         \
186                                                                         \
187         devname = udev_device_get_sysname(udev);                        \
188                                                                         \
189         attr = udev_device_get_sysattr_value(udev, #fname);             \
190         if (!attr) {                                                    \
191                 condlog(3, "%s: attribute %s not found in sysfs",       \
192                         devname, #fname);                               \
193                 return -ENXIO;                                          \
194         }                                                               \
195         for (l = strlen(attr); l >= 1 && isspace(attr[l-1]); l--);      \
196         if (l > len) {                                                  \
197                 condlog(3, "%s: overflow in attribute %s",              \
198                         devname, #fname);                               \
199                 return -EINVAL;                                         \
200         }                                                               \
201         strlcpy(buff, attr, len);                                       \
202         return strchop(buff);                                           \
203 }
204
205 declare_sysfs_get_str(devtype);
206 declare_sysfs_get_str(vendor);
207 declare_sysfs_get_str(model);
208 declare_sysfs_get_str(rev);
209
210 int
211 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
212 {
213         const char *attr = NULL;
214         const char *subsys;
215         struct udev_device *parent;
216         int r;
217         unsigned int t;
218
219         if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
220                 return -ENOSYS;
221
222         parent = pp->udev;
223         while (parent) {
224                 subsys = udev_device_get_subsystem(parent);
225                 attr = udev_device_get_sysattr_value(parent, "timeout");
226                 if (subsys && attr)
227                         break;
228                 parent = udev_device_get_parent(parent);
229         }
230         if (!attr) {
231                 condlog(3, "%s: No timeout value in sysfs", pp->dev);
232                 return -ENXIO;
233         }
234
235         r = sscanf(attr, "%u\n", &t);
236
237         if (r != 1) {
238                 condlog(3, "%s: Cannot parse timeout attribute '%s'",
239                         pp->dev, attr);
240                 return -EINVAL;
241         }
242
243         *timeout = t;
244
245         return 0;
246 }
247
248 int
249 sysfs_get_tgt_nodename (struct path *pp, char * node)
250 {
251         const char *tgtname, *value;
252         struct udev_device *parent, *tgtdev;
253         int host, channel, tgtid = -1;
254
255         parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
256         if (!parent)
257                 return 1;
258         /* Check for SAS */
259         value = udev_device_get_sysattr_value(parent, "sas_address");
260         if (value) {
261                 tgtdev = udev_device_get_parent(parent);
262                 while (tgtdev) {
263                         tgtname = udev_device_get_sysname(tgtdev);
264                         if (sscanf(tgtname, "end_device-%d:%d",
265                                    &host, &tgtid) == 2)
266                                 break;
267                         tgtdev = udev_device_get_parent(tgtdev);
268                         tgtid = -1;
269                 }
270                 if (tgtid >= 0) {
271                         pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
272                         pp->sg_id.transport_id = tgtid;
273                         strncpy(node, value, NODE_NAME_SIZE);
274                         return 0;
275                 }
276         }
277
278         /* Check for USB */
279         tgtdev = udev_device_get_parent(parent);
280         while (tgtdev) {
281                 value = udev_device_get_subsystem(tgtdev);
282                 if (value && !strcmp(value, "usb")) {
283                         pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
284                         tgtname = udev_device_get_sysname(tgtdev);
285                         strncpy(node, tgtname, strlen(tgtname));
286                         condlog(3, "%s: skip USB device %s", pp->dev, node);
287                         return 1;
288                 }
289                 tgtdev = udev_device_get_parent(tgtdev);
290         }
291         parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
292         if (!parent)
293                 return 1;
294         /* Check for FibreChannel */
295         tgtdev = udev_device_get_parent(parent);
296         value = udev_device_get_sysname(tgtdev);
297         if (sscanf(value, "rport-%d:%d-%d",
298                    &host, &channel, &tgtid) == 3) {
299                 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
300                                 "fc_remote_ports", value);
301                 if (tgtdev) {
302                         condlog(3, "SCSI target %d:%d:%d -> "
303                                 "FC rport %d:%d-%d",
304                                 pp->sg_id.host_no, pp->sg_id.channel,
305                                 pp->sg_id.scsi_id, host, channel,
306                                 tgtid);
307                         value = udev_device_get_sysattr_value(tgtdev,
308                                                               "node_name");
309                         if (value) {
310                                 pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
311                                 pp->sg_id.transport_id = tgtid;
312                                 strncpy(node, value, NODE_NAME_SIZE);
313                                 udev_device_unref(tgtdev);
314                                 return 0;
315                         } else
316                                 udev_device_unref(tgtdev);
317                 }
318         }
319
320         /* Check for iSCSI */
321         parent = pp->udev;
322         tgtname = NULL;
323         while (parent) {
324                 tgtname = udev_device_get_sysname(parent);
325                 if (tgtname && sscanf(tgtname , "session%d", &tgtid) == 1)
326                         break;
327                 parent = udev_device_get_parent(parent);
328                 tgtname = NULL;
329                 tgtid = -1;
330         }
331         if (parent && tgtname) {
332                 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
333                                 "iscsi_session", tgtname);
334                 if (tgtdev) {
335                         const char *value;
336
337                         value = udev_device_get_sysattr_value(tgtdev, "targetname");
338                         if (value) {
339                                 pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
340                                 pp->sg_id.transport_id = tgtid;
341                                 strncpy(node, value, NODE_NAME_SIZE);
342                                 udev_device_unref(tgtdev);
343                                 return 0;
344                         }
345                         else
346                                 udev_device_unref(tgtdev);
347                 }
348         }
349         /* Check for libata */
350         parent = pp->udev;
351         tgtname = NULL;
352         while (parent) {
353                 tgtname = udev_device_get_sysname(parent);
354                 if (tgtname && sscanf(tgtname, "ata%d", &tgtid) == 1)
355                         break;
356                 parent = udev_device_get_parent(parent);
357                 tgtname = NULL;
358         }
359         if (tgtname) {
360                 pp->sg_id.proto_id = SCSI_PROTOCOL_ATA;
361                 pp->sg_id.transport_id = tgtid;
362                 snprintf(node, NODE_NAME_SIZE, "ata-%d.00", tgtid);
363                 return 0;
364         }
365         /* Unknown SCSI transport. Keep fingers crossed */
366         pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
367         return 0;
368 }
369
370 int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name)
371 {
372         int proto_id;
373
374         if (!pp || !adapter_name)
375                 return 1;
376
377         proto_id = pp->sg_id.proto_id;
378
379         if (proto_id != SCSI_PROTOCOL_FCP &&
380             proto_id != SCSI_PROTOCOL_SAS &&
381             proto_id != SCSI_PROTOCOL_ISCSI &&
382             proto_id != SCSI_PROTOCOL_SRP) {
383                 return 1;
384         }
385         /* iscsi doesn't have adapter info in sysfs
386          * get ip_address for grouping paths
387          */
388         if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
389                 return sysfs_get_iscsi_ip_address(pp, adapter_name);
390
391         /* fetch adapter pci name for other protocols
392          */
393         return sysfs_get_host_pci_name(pp, adapter_name);
394 }
395
396 int sysfs_get_host_pci_name(struct path *pp, char *pci_name)
397 {
398         struct udev_device *hostdev, *parent;
399         char host_name[HOST_NAME_LEN];
400         const char *driver_name, *value;
401
402         if (!pp || !pci_name)
403                 return 1;
404
405         sprintf(host_name, "host%d", pp->sg_id.host_no);
406         hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
407                         "scsi_host", host_name);
408         if (!hostdev)
409                 return 1;
410
411         parent = udev_device_get_parent(hostdev);
412         while (parent) {
413                 driver_name = udev_device_get_driver(parent);
414                 if (!driver_name) {
415                         parent = udev_device_get_parent(parent);
416                         continue;
417                 }
418                 if (!strcmp(driver_name, "pcieport"))
419                         break;
420                 parent = udev_device_get_parent(parent);
421         }
422         if (parent) {
423                 /* pci_device found
424                  */
425                 value = udev_device_get_sysname(parent);
426
427                 strncpy(pci_name, value, SLOT_NAME_SIZE);
428                 udev_device_unref(hostdev);
429                 return 0;
430         }
431         udev_device_unref(hostdev);
432         return 1;
433 }
434
435 int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address)
436 {
437         struct udev_device *hostdev;
438         char host_name[HOST_NAME_LEN];
439         const char *value;
440
441         sprintf(host_name, "host%d", pp->sg_id.host_no);
442         hostdev = udev_device_new_from_subsystem_sysname(conf->udev,
443                         "iscsi_host", host_name);
444         if (hostdev) {
445                 value = udev_device_get_sysattr_value(hostdev,
446                                 "ipaddress");
447                 if (value) {
448                         strncpy(ip_address, value, SLOT_NAME_SIZE);
449                         udev_device_unref(hostdev);
450                         return 0;
451                 } else
452                         udev_device_unref(hostdev);
453         }
454         return 1;
455 }
456
457 static void
458 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
459 {
460         struct udev_device *rport_dev = NULL;
461         char value[16];
462         char rport_id[32];
463         unsigned long long tmo = 0;
464         int ret;
465
466         sprintf(rport_id, "rport-%d:%d-%d",
467                 pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
468         rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
469                                 "fc_remote_ports", rport_id);
470         if (!rport_dev) {
471                 condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
472                         rport_id);
473                 return;
474         }
475         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
476                 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
477
478         /*
479          * This is tricky.
480          * dev_loss_tmo will be limited to 600 if fast_io_fail
481          * is _not_ set.
482          * fast_io_fail will be limited by the current dev_loss_tmo
483          * setting.
484          * So to get everything right we first need to increase
485          * dev_loss_tmo to the fast_io_fail setting (if present),
486          * then set fast_io_fail, and _then_ set dev_loss_tmo
487          * to the correct value.
488          */
489         memset(value, 0, 16);
490         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET &&
491             mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO &&
492             mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) {
493                 /* Check if we need to temporarily increase dev_loss_tmo */
494                 ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
495                                            value, 16);
496                 if (ret <= 0) {
497                         condlog(0, "%s: failed to read dev_loss_tmo value, "
498                                 "error %d", rport_id, -ret);
499                         goto out;
500                 }
501                 if (sscanf(value, "%llu\n", &tmo) != 1) {
502                         condlog(0, "%s: Cannot parse dev_loss_tmo "
503                                 "attribute '%s'", rport_id, value);
504                         goto out;
505                 }
506                 if (mpp->fast_io_fail >= tmo) {
507                         snprintf(value, 16, "%u", mpp->fast_io_fail + 1);
508                 }
509         } else if (mpp->dev_loss > 600) {
510                 condlog(3, "%s: limiting dev_loss_tmo to 600, since "
511                         "fast_io_fail is not set", rport_id);
512                 snprintf(value, 16, "%u", 600);
513         } else {
514                 snprintf(value, 16, "%u", mpp->dev_loss);
515         }
516         if (strlen(value)) {
517                 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
518                                            value, strlen(value));
519                 if (ret <= 0) {
520                         if (ret == -EBUSY)
521                                 condlog(3, "%s: rport blocked", rport_id);
522                         else
523                                 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
524                                         rport_id, value, -ret);
525                         goto out;
526                 }
527         }
528         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
529                 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
530                         sprintf(value, "off");
531                 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
532                         sprintf(value, "0");
533                 else
534                         snprintf(value, 16, "%u", mpp->fast_io_fail);
535                 ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
536                                            value, strlen(value));
537                 if (ret <= 0) {
538                         if (ret == -EBUSY)
539                                 condlog(3, "%s: rport blocked", rport_id);
540                         else
541                                 condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
542                                         rport_id, value, -ret);
543                 }
544         }
545         if (tmo > 0) {
546                 snprintf(value, 16, "%u", mpp->dev_loss);
547                 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
548                                            value, strlen(value));
549                 if (ret <= 0) {
550                         if (ret == -EBUSY)
551                                 condlog(3, "%s: rport blocked", rport_id);
552                         else
553                                 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
554                                         rport_id, value, -ret);
555                 }
556         }
557 out:
558         udev_device_unref(rport_dev);
559 }
560
561 static void
562 sysfs_set_session_tmo(struct multipath *mpp, struct path *pp)
563 {
564         struct udev_device *session_dev = NULL;
565         char session_id[64];
566         char value[11];
567
568         sprintf(session_id, "session%d", pp->sg_id.transport_id);
569         session_dev = udev_device_new_from_subsystem_sysname(conf->udev,
570                                 "iscsi_session", session_id);
571         if (!session_dev) {
572                 condlog(1, "%s: No iscsi session for '%s'", pp->dev,
573                         session_id);
574                 return;
575         }
576         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
577                 pp->sg_id.channel, pp->sg_id.scsi_id, session_id);
578
579         if (mpp->dev_loss) {
580                 condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev);
581         }
582         if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
583                 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) {
584                         condlog(3, "%s: can't switch off fast_io_fail_tmo "
585                                 "on iSCSI", pp->dev);
586                 } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) {
587                         condlog(3, "%s: can't set fast_io_fail_tmo to '0'"
588                                 "on iSCSI", pp->dev);
589                 } else {
590                         snprintf(value, 11, "%u", mpp->fast_io_fail);
591                         if (sysfs_attr_set_value(session_dev, "recovery_tmo",
592                                                  value, 11) <= 0) {
593                                 condlog(3, "%s: Failed to set recovery_tmo, "
594                                         " error %d", pp->dev, errno);
595                         }
596                 }
597         }
598         udev_device_unref(session_dev);
599         return;
600 }
601
602 static void
603 sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp)
604 {
605         struct udev_device *sas_dev = NULL;
606         char end_dev_id[64];
607         char value[11];
608
609         sprintf(end_dev_id, "end_device-%d:%d",
610                 pp->sg_id.host_no, pp->sg_id.transport_id);
611         sas_dev = udev_device_new_from_subsystem_sysname(conf->udev,
612                                 "sas_end_device", end_dev_id);
613         if (!sas_dev) {
614                 condlog(1, "%s: No SAS end device for '%s'", pp->dev,
615                         end_dev_id);
616                 return;
617         }
618         condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
619                 pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id);
620
621         if (mpp->dev_loss) {
622                 snprintf(value, 11, "%u", mpp->dev_loss);
623                 if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout",
624                                          value, 11) <= 0)
625                         condlog(3, "%s: failed to update "
626                                 "I_T Nexus loss timeout, error %d",
627                                 pp->dev, errno);
628         }
629         udev_device_unref(sas_dev);
630         return;
631 }
632
633 int
634 sysfs_set_scsi_tmo (struct multipath *mpp)
635 {
636         struct path *pp;
637         int i;
638         int dev_loss_tmo = mpp->dev_loss;
639
640         if (mpp->no_path_retry > 0) {
641                 int no_path_retry_tmo = mpp->no_path_retry * conf->checkint;
642
643                 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
644                         no_path_retry_tmo = MAX_DEV_LOSS_TMO;
645                 if (no_path_retry_tmo > dev_loss_tmo)
646                         dev_loss_tmo = no_path_retry_tmo;
647                 condlog(3, "%s: update dev_loss_tmo to %d",
648                         mpp->alias, dev_loss_tmo);
649         } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
650                 dev_loss_tmo = MAX_DEV_LOSS_TMO;
651                 condlog(3, "%s: update dev_loss_tmo to %d",
652                         mpp->alias, dev_loss_tmo);
653         }
654         mpp->dev_loss = dev_loss_tmo;
655         if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
656                 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
657                         mpp->alias, mpp->fast_io_fail);
658                 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
659         }
660         if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
661                 return 0;
662
663         vector_foreach_slot(mpp->paths, pp, i) {
664                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
665                         sysfs_set_rport_tmo(mpp, pp);
666                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
667                         sysfs_set_session_tmo(mpp, pp);
668                 if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
669                         sysfs_set_nexus_loss_tmo(mpp, pp);
670         }
671         return 0;
672 }
673
674 int
675 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
676        void *resp, int mx_resp_len)
677 {
678         unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
679                 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
680         unsigned char sense_b[SENSE_BUFF_LEN];
681         struct sg_io_hdr io_hdr;
682
683         if (cmddt)
684                 inqCmdBlk[1] |= 2;
685         if (evpd)
686                 inqCmdBlk[1] |= 1;
687         inqCmdBlk[2] = (unsigned char) pg_op;
688         inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
689         inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
690         memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
691         memset(sense_b, 0, SENSE_BUFF_LEN);
692         io_hdr.interface_id = 'S';
693         io_hdr.cmd_len = sizeof (inqCmdBlk);
694         io_hdr.mx_sb_len = sizeof (sense_b);
695         io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
696         io_hdr.dxfer_len = mx_resp_len;
697         io_hdr.dxferp = resp;
698         io_hdr.cmdp = inqCmdBlk;
699         io_hdr.sbp = sense_b;
700         io_hdr.timeout = DEF_TIMEOUT;
701
702         if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
703                 return -1;
704
705         /* treat SG_ERR here to get rid of sg_err.[ch] */
706         io_hdr.status &= 0x7e;
707         if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
708             (0 == io_hdr.driver_status))
709                 return 0;
710         if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
711             (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
712             (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
713                 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
714                         int sense_key;
715                         unsigned char * sense_buffer = io_hdr.sbp;
716                         if (sense_buffer[0] & 0x2)
717                                 sense_key = sense_buffer[1] & 0xf;
718                         else
719                                 sense_key = sense_buffer[2] & 0xf;
720                         if(RECOVERED_ERROR == sense_key)
721                                 return 0;
722                 }
723         }
724         return -1;
725 }
726
727 static int
728 get_serial (char * str, int maxlen, int fd)
729 {
730         int len = 0;
731         char buff[MX_ALLOC_LEN + 1] = {0};
732
733         if (fd < 0)
734                 return 1;
735
736         if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
737                 len = buff[3];
738                 if (len >= maxlen)
739                         return 1;
740                 if (len > 0) {
741                         memcpy(str, buff + 4, len);
742                         str[len] = '\0';
743                 }
744                 return 0;
745         }
746         return 1;
747 }
748
749 static int
750 get_geometry(struct path *pp)
751 {
752         if (pp->fd < 0)
753                 return 1;
754
755         if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
756                 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
757                 memset(&pp->geom, 0, sizeof(pp->geom));
758                 return 1;
759         }
760         condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
761                 pp->dev, pp->geom.cylinders, pp->geom.heads,
762                 pp->geom.sectors, pp->geom.start);
763         return 0;
764 }
765
766 static int
767 scsi_sysfs_pathinfo (struct path * pp)
768 {
769         struct udev_device *parent;
770         const char *attr_path = NULL;
771
772         parent = pp->udev;
773         while (parent) {
774                 const char *subsys = udev_device_get_subsystem(parent);
775                 if (subsys && !strncmp(subsys, "scsi", 4)) {
776                         attr_path = udev_device_get_sysname(parent);
777                         if (!attr_path)
778                                 break;
779                         if (sscanf(attr_path, "%i:%i:%i:%i",
780                                    &pp->sg_id.host_no,
781                                    &pp->sg_id.channel,
782                                    &pp->sg_id.scsi_id,
783                                    &pp->sg_id.lun) == 4)
784                                 break;
785                 }
786                 parent = udev_device_get_parent(parent);
787         }
788         if (!attr_path || pp->sg_id.host_no == -1)
789                 return 1;
790
791         if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
792                 return 1;
793
794         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
795
796         if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE) <= 0)
797                 return 1;
798
799         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
800
801         if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE) <= 0)
802                 return 1;
803
804         condlog(3, "%s: rev = %s", pp->dev, pp->rev);
805
806         /*
807          * set the hwe configlet pointer
808          */
809         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
810
811         /*
812          * host / bus / target / lun
813          */
814         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
815                         pp->dev,
816                         pp->sg_id.host_no,
817                         pp->sg_id.channel,
818                         pp->sg_id.scsi_id,
819                         pp->sg_id.lun);
820
821         /*
822          * target node name
823          */
824         if(sysfs_get_tgt_nodename(pp, pp->tgt_node_name))
825                 return 1;
826
827         condlog(3, "%s: tgt_node_name = %s",
828                 pp->dev, pp->tgt_node_name);
829
830         return 0;
831 }
832
833 static int
834 ccw_sysfs_pathinfo (struct path * pp)
835 {
836         struct udev_device *parent;
837         char attr_buff[NAME_SIZE];
838         const char *attr_path;
839
840         parent = pp->udev;
841         while (parent) {
842                 const char *subsys = udev_device_get_subsystem(parent);
843                 if (subsys && !strncmp(subsys, "ccw", 3))
844                         break;
845                 parent = udev_device_get_parent(parent);
846         }
847         if (!parent)
848                 return 1;
849
850         sprintf(pp->vendor_id, "IBM");
851
852         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
853
854         if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE) <= 0)
855                 return 1;
856
857         if (!strncmp(attr_buff, "3370", 4)) {
858                 sprintf(pp->product_id,"S/390 DASD FBA");
859         } else if (!strncmp(attr_buff, "9336", 4)) {
860                 sprintf(pp->product_id,"S/390 DASD FBA");
861         } else {
862                 sprintf(pp->product_id,"S/390 DASD ECKD");
863         }
864
865         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
866
867         /*
868          * set the hwe configlet pointer
869          */
870         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, NULL);
871
872         /*
873          * host / bus / target / lun
874          */
875         attr_path = udev_device_get_sysname(parent);
876         pp->sg_id.lun = 0;
877         sscanf(attr_path, "%i.%i.%x",
878                         &pp->sg_id.host_no,
879                         &pp->sg_id.channel,
880                         &pp->sg_id.scsi_id);
881         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
882                         pp->dev,
883                         pp->sg_id.host_no,
884                         pp->sg_id.channel,
885                         pp->sg_id.scsi_id,
886                         pp->sg_id.lun);
887
888         return 0;
889 }
890
891 static int
892 cciss_sysfs_pathinfo (struct path * pp)
893 {
894         const char * attr_path = NULL;
895         struct udev_device *parent;
896
897         parent = pp->udev;
898         while (parent) {
899                 const char *subsys = udev_device_get_subsystem(parent);
900                 if (subsys && !strncmp(subsys, "cciss", 5)) {
901                         attr_path = udev_device_get_sysname(parent);
902                         if (!attr_path)
903                                 break;
904                         if (sscanf(attr_path, "c%id%i",
905                                    &pp->sg_id.host_no,
906                                    &pp->sg_id.scsi_id) == 2)
907                                 break;
908                 }
909                 parent = udev_device_get_parent(parent);
910         }
911         if (!attr_path || pp->sg_id.host_no == -1)
912                 return 1;
913
914         if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
915                 return 1;
916
917         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
918
919         if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE) <= 0)
920                 return 1;
921
922         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
923
924         if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE) <= 0)
925                 return 1;
926
927         condlog(3, "%s: rev = %s", pp->dev, pp->rev);
928
929         /*
930          * set the hwe configlet pointer
931          */
932         pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
933
934         /*
935          * host / bus / target / lun
936          */
937         pp->sg_id.lun = 0;
938         pp->sg_id.channel = 0;
939         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
940                 pp->dev,
941                 pp->sg_id.host_no,
942                 pp->sg_id.channel,
943                 pp->sg_id.scsi_id,
944                 pp->sg_id.lun);
945         return 0;
946 }
947
948 static int
949 common_sysfs_pathinfo (struct path * pp)
950 {
951         dev_t devt;
952
953         if (!pp)
954                 return 1;
955
956         if (!pp->udev) {
957                 condlog(4, "%s: udev not initialised", pp->dev);
958                 return 1;
959         }
960         devt = udev_device_get_devnum(pp->udev);
961         snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt));
962
963         condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
964
965         if (sysfs_get_size(pp, &pp->size))
966                 return 1;
967
968         condlog(3, "%s: size = %llu", pp->dev, pp->size);
969
970         return 0;
971 }
972
973 int
974 path_offline (struct path * pp)
975 {
976         struct udev_device * parent;
977         char buff[SCSI_STATE_SIZE];
978         int err;
979
980         if (pp->bus != SYSFS_BUS_SCSI)
981                 return PATH_UP;
982
983         parent = pp->udev;
984         while (parent) {
985                 const char *subsys = udev_device_get_subsystem(parent);
986                 if (subsys && !strncmp(subsys, "scsi", 4))
987                         break;
988                 parent = udev_device_get_parent(parent);
989         }
990
991         if (!parent) {
992                 condlog(1, "%s: failed to get sysfs information", pp->dev);
993                 return PATH_REMOVED;
994         }
995
996         memset(buff, 0x0, SCSI_STATE_SIZE);
997         err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE);
998         if (err <= 0) {
999                 if (err == -ENXIO)
1000                         return PATH_REMOVED;
1001                 else
1002                         return PATH_DOWN;
1003         }
1004
1005
1006         condlog(3, "%s: path state = %s", pp->dev, buff);
1007
1008         if (!strncmp(buff, "offline", 7)) {
1009                 pp->offline = 1;
1010                 return PATH_DOWN;
1011         }
1012         pp->offline = 0;
1013         if (!strncmp(buff, "blocked", 7) || !strncmp(buff, "quiesce", 7))
1014                 return PATH_PENDING;
1015         else if (!strncmp(buff, "running", 7))
1016                 return PATH_UP;
1017
1018         return PATH_DOWN;
1019 }
1020
1021 int
1022 sysfs_pathinfo(struct path * pp)
1023 {
1024         if (common_sysfs_pathinfo(pp))
1025                 return 1;
1026
1027         pp->bus = SYSFS_BUS_UNDEF;
1028         if (!strncmp(pp->dev,"cciss",5))
1029                 pp->bus = SYSFS_BUS_CCISS;
1030         if (!strncmp(pp->dev,"dasd", 4))
1031                 pp->bus = SYSFS_BUS_CCW;
1032         if (!strncmp(pp->dev,"sd", 2))
1033                 pp->bus = SYSFS_BUS_SCSI;
1034
1035         if (pp->bus == SYSFS_BUS_UNDEF)
1036                 return 0;
1037         else if (pp->bus == SYSFS_BUS_SCSI) {
1038                 if (scsi_sysfs_pathinfo(pp))
1039                         return 1;
1040         } else if (pp->bus == SYSFS_BUS_CCW) {
1041                 if (ccw_sysfs_pathinfo(pp))
1042                         return 1;
1043         } else if (pp->bus == SYSFS_BUS_CCISS) {
1044                 if (cciss_sysfs_pathinfo(pp))
1045                         return 1;
1046         }
1047         return 0;
1048 }
1049
1050 static int
1051 scsi_ioctl_pathinfo (struct path * pp, int mask)
1052 {
1053         if (mask & DI_SERIAL) {
1054                 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
1055                 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1056         }
1057
1058         return 0;
1059 }
1060
1061 static int
1062 cciss_ioctl_pathinfo (struct path * pp, int mask)
1063 {
1064         if (mask & DI_SERIAL) {
1065                 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
1066                 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1067         }
1068         return 0;
1069 }
1070
1071 int
1072 get_state (struct path * pp, int daemon)
1073 {
1074         struct checker * c = &pp->checker;
1075         int state;
1076
1077         condlog(3, "%s: get_state", pp->dev);
1078
1079         if (!checker_selected(c)) {
1080                 if (daemon) {
1081                         if (pathinfo(pp, conf->hwtable, DI_SYSFS) != PATHINFO_OK) {
1082                                 condlog(3, "%s: couldn't get sysfs pathinfo",
1083                                         pp->dev);
1084                                 return PATH_UNCHECKED;
1085                         }
1086                 }
1087                 select_checker(pp);
1088                 if (!checker_selected(c)) {
1089                         condlog(3, "%s: No checker selected", pp->dev);
1090                         return PATH_UNCHECKED;
1091                 }
1092                 checker_set_fd(c, pp->fd);
1093                 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
1094                         memset(c, 0x0, sizeof(struct checker));
1095                         condlog(3, "%s: checker init failed", pp->dev);
1096                         return PATH_UNCHECKED;
1097                 }
1098         }
1099         checker_clear_message(c);
1100         if (daemon) {
1101                 if (conf->force_sync == 0)
1102                         checker_set_async(c);
1103                 else
1104                         checker_set_sync(c);
1105         }
1106         if (!conf->checker_timeout &&
1107             sysfs_get_timeout(pp, &(c->timeout)) <= 0)
1108                 c->timeout = DEF_TIMEOUT;
1109         state = checker_check(c);
1110         condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
1111         if (state != PATH_UP && state != PATH_GHOST &&
1112             strlen(checker_message(c)))
1113                 condlog(3, "%s: checker msg is \"%s\"",
1114                         pp->dev, checker_message(c));
1115         return state;
1116 }
1117
1118 static int
1119 get_prio (struct path * pp)
1120 {
1121         if (!pp)
1122                 return 0;
1123
1124         struct prio * p = &pp->prio;
1125
1126         if (!prio_selected(p)) {
1127                 select_detect_prio(pp);
1128                 select_prio(pp);
1129                 if (!prio_selected(p)) {
1130                         condlog(3, "%s: no prio selected", pp->dev);
1131                         pp->priority = PRIO_UNDEF;
1132                         return 1;
1133                 }
1134         }
1135         pp->priority = prio_getprio(p, pp);
1136         if (pp->priority < 0) {
1137                 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
1138                 pp->priority = PRIO_UNDEF;
1139                 return 1;
1140         }
1141         condlog(3, "%s: %s prio = %u",
1142                 pp->dev, prio_name(p), pp->priority);
1143         return 0;
1144 }
1145
1146 static int
1147 get_uid (struct path * pp)
1148 {
1149         char *c;
1150         const char *origin;
1151
1152         if (!pp->uid_attribute && !pp->getuid)
1153                 select_getuid(pp);
1154
1155         if (!pp->udev) {
1156                 condlog(1, "%s: no udev information", pp->dev);
1157                 return 1;
1158         }
1159
1160         memset(pp->wwid, 0, WWID_SIZE);
1161         if (pp->getuid) {
1162                 char buff[CALLOUT_MAX_SIZE];
1163
1164                 /* Use 'getuid' callout, deprecated */
1165                 condlog(1, "%s: using deprecated getuid callout", pp->dev);
1166                 if (apply_format(pp->getuid, &buff[0], pp)) {
1167                         condlog(0, "error formatting uid callout command");
1168                         memset(pp->wwid, 0, WWID_SIZE);
1169                 } else if (execute_program(buff, pp->wwid, WWID_SIZE)) {
1170                         condlog(3, "error calling out %s", buff);
1171                         memset(pp->wwid, 0, WWID_SIZE);
1172                 }
1173                 origin = "callout";
1174         } else {
1175                 const char *value;
1176
1177                 value = udev_device_get_property_value(pp->udev,
1178                                                        pp->uid_attribute);
1179                 if ((!value || strlen(value) == 0) &&
1180                     conf->cmd == CMD_VALID_PATH)
1181                         value = getenv(pp->uid_attribute);
1182                 if (value && strlen(value)) {
1183                         size_t len = WWID_SIZE;
1184
1185                         if (strlen(value) + 1 > WWID_SIZE) {
1186                                 condlog(0, "%s: wwid overflow", pp->dev);
1187                         } else {
1188                                 len = strlen(value);
1189                         }
1190                         strncpy(pp->wwid, value, len);
1191                 } else {
1192                         condlog(3, "%s: no %s attribute", pp->dev,
1193                                 pp->uid_attribute);
1194                 }
1195                 origin = "udev";
1196         }
1197         /* Strip any trailing blanks */
1198         c = strchr(pp->wwid, '\0');
1199         c--;
1200         while (c && c >= pp->wwid && *c == ' ') {
1201                 *c = '\0';
1202                 c--;
1203         }
1204         condlog(3, "%s: uid = %s (%s)", pp->dev,
1205                 *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
1206         return 0;
1207 }
1208
1209 extern int
1210 pathinfo (struct path *pp, vector hwtable, int mask)
1211 {
1212         int path_state;
1213
1214         if (!pp)
1215                 return PATHINFO_FAILED;
1216
1217         condlog(3, "%s: mask = 0x%x", pp->dev, mask);
1218
1219         /*
1220          * fetch info available in sysfs
1221          */
1222         if (mask & DI_SYSFS && sysfs_pathinfo(pp))
1223                 return PATHINFO_FAILED;
1224
1225         if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
1226                 if (filter_device(conf->blist_device, conf->elist_device,
1227                                   pp->vendor_id, pp->product_id) > 0) {
1228                         return PATHINFO_SKIPPED;
1229                 }
1230         }
1231
1232         path_state = path_offline(pp);
1233         if (path_state == PATH_REMOVED)
1234                 goto blank;
1235
1236         /*
1237          * fetch info not available through sysfs
1238          */
1239         if (pp->fd < 0)
1240                 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1241
1242         if (pp->fd < 0) {
1243                 condlog(4, "Couldn't open node for %s: %s",
1244                         pp->dev, strerror(errno));
1245                 goto blank;
1246         }
1247
1248         if (mask & DI_SERIAL)
1249                 get_geometry(pp);
1250
1251         if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1252             scsi_ioctl_pathinfo(pp, mask))
1253                 goto blank;
1254
1255         if (pp->bus == SYSFS_BUS_CCISS &&
1256             cciss_ioctl_pathinfo(pp, mask))
1257                 goto blank;
1258
1259         if (mask & DI_CHECKER) {
1260                 if (path_state == PATH_UP) {
1261                         pp->chkrstate = pp->state = get_state(pp, 0);
1262                         if (pp->state == PATH_UNCHECKED ||
1263                             pp->state == PATH_WILD)
1264                                 goto blank;
1265                         if (pp->state == PATH_TIMEOUT)
1266                                 pp->state = PATH_DOWN;
1267                         if (pp->state == PATH_UP && !pp->size) {
1268                                 condlog(3, "%s: device size is 0, "
1269                                         "path unuseable", pp->dev);
1270                                 pp->state = PATH_GHOST;
1271                         }
1272                 } else {
1273                         condlog(3, "%s: path inaccessible", pp->dev);
1274                         pp->chkrstate = pp->state = path_state;
1275                         if (path_state == PATH_PENDING ||
1276                             path_state == PATH_DOWN)
1277                                 pp->priority = 0;
1278                 }
1279         }
1280
1281         if ((mask & DI_WWID) && !strlen(pp->wwid))
1282                 get_uid(pp);
1283         if (mask & DI_BLACKLIST && mask & DI_WWID) {
1284                 if (!strlen(pp->wwid) ||
1285                     filter_wwid(conf->blist_wwid, conf->elist_wwid,
1286                                 pp->wwid, pp->dev) > 0) {
1287                         return PATHINFO_SKIPPED;
1288                 }
1289         }
1290
1291          /*
1292           * Retrieve path priority, even for PATH_DOWN paths if it has never
1293           * been successfully obtained before.
1294           */
1295         if ((mask & DI_PRIO) && path_state == PATH_UP) {
1296                 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1297                         if (!strlen(pp->wwid))
1298                                 get_uid(pp);
1299                         if (!strlen(pp->wwid))
1300                                 return PATHINFO_SKIPPED;
1301                         get_prio(pp);
1302                 }
1303         }
1304
1305         pp->initialized = 1;
1306         return PATHINFO_OK;
1307
1308 blank:
1309         /*
1310          * Recoverable error, for example faulty or offline path
1311          */
1312         memset(pp->wwid, 0, WWID_SIZE);
1313         pp->chkrstate = pp->state = PATH_DOWN;
1314         pp->initialized = 0;
1315
1316         return 0;
1317 }