d1aec31ea0f8399ced6c4be3bd2254c6cf291783
[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 rbd_sysfs_pathinfo (struct path * pp, vector hwtable)
1191 {
1192         sprintf(pp->vendor_id, "Ceph");
1193         sprintf(pp->product_id, "RBD");
1194
1195         condlog(3, "%s: vendor = %s product = %s", pp->dev, pp->vendor_id,
1196                 pp->product_id);
1197         /*
1198          * set the hwe configlet pointer
1199          */
1200         pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
1201         return 0;
1202 }
1203
1204 static int
1205 ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
1206 {
1207         struct udev_device *parent;
1208         char attr_buff[NAME_SIZE];
1209         const char *attr_path;
1210
1211         parent = pp->udev;
1212         while (parent) {
1213                 const char *subsys = udev_device_get_subsystem(parent);
1214                 if (subsys && !strncmp(subsys, "ccw", 3))
1215                         break;
1216                 parent = udev_device_get_parent(parent);
1217         }
1218         if (!parent)
1219                 return 1;
1220
1221         sprintf(pp->vendor_id, "IBM");
1222
1223         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1224
1225         if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE) <= 0)
1226                 return 1;
1227
1228         if (!strncmp(attr_buff, "3370", 4)) {
1229                 sprintf(pp->product_id,"S/390 DASD FBA");
1230         } else if (!strncmp(attr_buff, "9336", 4)) {
1231                 sprintf(pp->product_id,"S/390 DASD FBA");
1232         } else {
1233                 sprintf(pp->product_id,"S/390 DASD ECKD");
1234         }
1235
1236         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1237
1238         /*
1239          * set the hwe configlet pointer
1240          */
1241         pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL);
1242
1243         /*
1244          * host / bus / target / lun
1245          */
1246         attr_path = udev_device_get_sysname(parent);
1247         pp->sg_id.lun = 0;
1248         if (sscanf(attr_path, "%i.%i.%x",
1249                    &pp->sg_id.host_no,
1250                    &pp->sg_id.channel,
1251                    &pp->sg_id.scsi_id) == 3) {
1252                 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1253                         pp->dev,
1254                         pp->sg_id.host_no,
1255                         pp->sg_id.channel,
1256                         pp->sg_id.scsi_id,
1257                         pp->sg_id.lun);
1258         }
1259
1260         return 0;
1261 }
1262
1263 static int
1264 cciss_sysfs_pathinfo (struct path * pp, vector hwtable)
1265 {
1266         const char * attr_path = NULL;
1267         struct udev_device *parent;
1268
1269         parent = pp->udev;
1270         while (parent) {
1271                 const char *subsys = udev_device_get_subsystem(parent);
1272                 if (subsys && !strncmp(subsys, "cciss", 5)) {
1273                         attr_path = udev_device_get_sysname(parent);
1274                         if (!attr_path)
1275                                 break;
1276                         if (sscanf(attr_path, "c%id%i",
1277                                    &pp->sg_id.host_no,
1278                                    &pp->sg_id.scsi_id) == 2)
1279                                 break;
1280                 }
1281                 parent = udev_device_get_parent(parent);
1282         }
1283         if (!attr_path || pp->sg_id.host_no == -1)
1284                 return 1;
1285
1286         if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
1287                 return 1;
1288
1289         condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1290
1291         if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE) <= 0)
1292                 return 1;
1293
1294         condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1295
1296         if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE) <= 0)
1297                 return 1;
1298
1299         condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1300
1301         /*
1302          * set the hwe configlet pointer
1303          */
1304         pp->hwe = find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev);
1305
1306         /*
1307          * host / bus / target / lun
1308          */
1309         pp->sg_id.lun = 0;
1310         pp->sg_id.channel = 0;
1311         condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1312                 pp->dev,
1313                 pp->sg_id.host_no,
1314                 pp->sg_id.channel,
1315                 pp->sg_id.scsi_id,
1316                 pp->sg_id.lun);
1317         return 0;
1318 }
1319
1320 static int
1321 common_sysfs_pathinfo (struct path * pp)
1322 {
1323         dev_t devt;
1324
1325         if (!pp)
1326                 return 1;
1327
1328         if (!pp->udev) {
1329                 condlog(4, "%s: udev not initialised", pp->dev);
1330                 return 1;
1331         }
1332         devt = udev_device_get_devnum(pp->udev);
1333         snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt));
1334
1335         condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
1336
1337         if (sysfs_get_size(pp, &pp->size))
1338                 return 1;
1339
1340         condlog(3, "%s: size = %llu", pp->dev, pp->size);
1341
1342         return 0;
1343 }
1344
1345 int
1346 path_offline (struct path * pp)
1347 {
1348         struct udev_device * parent;
1349         char buff[SCSI_STATE_SIZE];
1350         int err;
1351
1352         if (pp->bus != SYSFS_BUS_SCSI)
1353                 return PATH_UP;
1354
1355         parent = pp->udev;
1356         while (parent) {
1357                 const char *subsys = udev_device_get_subsystem(parent);
1358                 if (subsys && !strncmp(subsys, "scsi", 4))
1359                         break;
1360                 parent = udev_device_get_parent(parent);
1361         }
1362
1363         if (!parent) {
1364                 condlog(1, "%s: failed to get sysfs information", pp->dev);
1365                 return PATH_REMOVED;
1366         }
1367
1368         memset(buff, 0x0, SCSI_STATE_SIZE);
1369         err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE);
1370         if (err <= 0) {
1371                 if (err == -ENXIO)
1372                         return PATH_REMOVED;
1373                 else
1374                         return PATH_DOWN;
1375         }
1376
1377
1378         condlog(3, "%s: path state = %s", pp->dev, buff);
1379
1380         if (!strncmp(buff, "offline", 7)) {
1381                 pp->offline = 1;
1382                 return PATH_DOWN;
1383         }
1384         pp->offline = 0;
1385         if (!strncmp(buff, "blocked", 7) || !strncmp(buff, "quiesce", 7))
1386                 return PATH_PENDING;
1387         else if (!strncmp(buff, "running", 7))
1388                 return PATH_UP;
1389
1390         return PATH_DOWN;
1391 }
1392
1393 int
1394 sysfs_pathinfo(struct path * pp, vector hwtable)
1395 {
1396         if (common_sysfs_pathinfo(pp))
1397                 return 1;
1398
1399         pp->bus = SYSFS_BUS_UNDEF;
1400         if (!strncmp(pp->dev,"cciss",5))
1401                 pp->bus = SYSFS_BUS_CCISS;
1402         if (!strncmp(pp->dev,"dasd", 4))
1403                 pp->bus = SYSFS_BUS_CCW;
1404         if (!strncmp(pp->dev,"sd", 2))
1405                 pp->bus = SYSFS_BUS_SCSI;
1406         if (!strncmp(pp->dev,"rbd", 3))
1407                 pp->bus = SYSFS_BUS_RBD;
1408
1409         if (pp->bus == SYSFS_BUS_UNDEF)
1410                 return 0;
1411         else if (pp->bus == SYSFS_BUS_SCSI) {
1412                 if (scsi_sysfs_pathinfo(pp, hwtable))
1413                         return 1;
1414         } else if (pp->bus == SYSFS_BUS_CCW) {
1415                 if (ccw_sysfs_pathinfo(pp, hwtable))
1416                         return 1;
1417         } else if (pp->bus == SYSFS_BUS_CCISS) {
1418                 if (cciss_sysfs_pathinfo(pp, hwtable))
1419                         return 1;
1420         } else if (pp->bus == SYSFS_BUS_RBD) {
1421                 if (rbd_sysfs_pathinfo(pp, hwtable))
1422                         return 1;
1423         }
1424         return 0;
1425 }
1426
1427 static int
1428 scsi_ioctl_pathinfo (struct path * pp, int mask)
1429 {
1430         struct udev_device *parent;
1431         const char *attr_path = NULL;
1432
1433         if (!(mask & DI_SERIAL))
1434                 return 0;
1435
1436         parent = pp->udev;
1437         while (parent) {
1438                 const char *subsys = udev_device_get_subsystem(parent);
1439                 if (subsys && !strncmp(subsys, "scsi", 4)) {
1440                         attr_path = udev_device_get_sysname(parent);
1441                         if (!attr_path)
1442                                 break;
1443                         if (sscanf(attr_path, "%i:%i:%i:%i",
1444                                    &pp->sg_id.host_no,
1445                                    &pp->sg_id.channel,
1446                                    &pp->sg_id.scsi_id,
1447                                    &pp->sg_id.lun) == 4)
1448                                 break;
1449                 }
1450                 parent = udev_device_get_parent(parent);
1451         }
1452         if (!attr_path || pp->sg_id.host_no == -1)
1453                 return 0;
1454
1455         if (get_vpd_sysfs(parent, 0x80, pp->serial, SERIAL_SIZE) <= 0) {
1456                 if (get_serial(pp->serial, SERIAL_SIZE, pp->fd)) {
1457                         condlog(2, "%s: fail to get serial", pp->dev);
1458                         return 0;
1459                 }
1460         }
1461
1462         condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1463         return 0;
1464 }
1465
1466 static int
1467 cciss_ioctl_pathinfo (struct path * pp, int mask)
1468 {
1469         if (mask & DI_SERIAL) {
1470                 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
1471                 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1472         }
1473         return 0;
1474 }
1475
1476 int
1477 get_state (struct path * pp, struct config *conf, int daemon)
1478 {
1479         struct checker * c = &pp->checker;
1480         int state;
1481
1482         condlog(3, "%s: get_state", pp->dev);
1483
1484         if (!checker_selected(c)) {
1485                 if (daemon) {
1486                         if (pathinfo(pp, conf, DI_SYSFS) != PATHINFO_OK) {
1487                                 condlog(3, "%s: couldn't get sysfs pathinfo",
1488                                         pp->dev);
1489                                 return PATH_UNCHECKED;
1490                         }
1491                 }
1492                 select_checker(conf, pp);
1493                 if (!checker_selected(c)) {
1494                         condlog(3, "%s: No checker selected", pp->dev);
1495                         return PATH_UNCHECKED;
1496                 }
1497                 checker_set_fd(c, pp->fd);
1498                 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
1499                         memset(c, 0x0, sizeof(struct checker));
1500                         condlog(3, "%s: checker init failed", pp->dev);
1501                         return PATH_UNCHECKED;
1502                 }
1503         }
1504         checker_clear_message(c);
1505         if (daemon) {
1506                 if (conf->force_sync == 0)
1507                         checker_set_async(c);
1508                 else
1509                         checker_set_sync(c);
1510         }
1511         if (!conf->checker_timeout &&
1512             sysfs_get_timeout(pp, &(c->timeout)) <= 0)
1513                 c->timeout = DEF_TIMEOUT;
1514         state = checker_check(c);
1515         condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
1516         if (state != PATH_UP && state != PATH_GHOST &&
1517             strlen(checker_message(c)))
1518                 condlog(3, "%s: checker msg is \"%s\"",
1519                         pp->dev, checker_message(c));
1520         return state;
1521 }
1522
1523 static int
1524 get_prio (struct path * pp)
1525 {
1526         struct prio * p;
1527         struct config *conf;
1528
1529         if (!pp)
1530                 return 0;
1531
1532         p = &pp->prio;
1533         if (!prio_selected(p)) {
1534                 conf = get_multipath_config();
1535                 select_detect_prio(conf, pp);
1536                 select_prio(conf, pp);
1537                 put_multipath_config(conf);
1538                 if (!prio_selected(p)) {
1539                         condlog(3, "%s: no prio selected", pp->dev);
1540                         pp->priority = PRIO_UNDEF;
1541                         return 1;
1542                 }
1543         }
1544         conf = get_multipath_config();
1545         pp->priority = prio_getprio(p, pp, conf->checker_timeout);
1546         put_multipath_config(conf);
1547         if (pp->priority < 0) {
1548                 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
1549                 pp->priority = PRIO_UNDEF;
1550                 return 1;
1551         }
1552         condlog(3, "%s: %s prio = %u",
1553                 pp->dev, prio_name(p), pp->priority);
1554         return 0;
1555 }
1556
1557 static int
1558 get_udev_uid(struct path * pp, char *uid_attribute, struct udev_device *udev)
1559 {
1560         ssize_t len;
1561         const char *value;
1562
1563         value = udev_device_get_property_value(udev, uid_attribute);
1564         if (!value || strlen(value) == 0)
1565                 value = getenv(uid_attribute);
1566         if (value && strlen(value)) {
1567                 if (strlen(value) + 1 > WWID_SIZE) {
1568                         condlog(0, "%s: wwid overflow", pp->dev);
1569                         len = WWID_SIZE;
1570                 } else {
1571                         len = strlen(value);
1572                 }
1573                 strncpy(pp->wwid, value, len);
1574         } else {
1575                 condlog(3, "%s: no %s attribute", pp->dev,
1576                         uid_attribute);
1577                 len = -EINVAL;
1578         }
1579         return len;
1580 }
1581
1582 static int
1583 get_rbd_uid(struct path * pp)
1584 {
1585         struct udev_device *rbd_bus_dev;
1586         int ret, rbd_bus_id;
1587         const char *pool, *image, *snap;
1588         char sysfs_path[PATH_SIZE];
1589         uint64_t snap_id, max_snap_id = -3;
1590
1591         ret = sscanf(pp->dev, "rbd%d", &rbd_bus_id);
1592         if (ret != 1)
1593                 return -EINVAL;
1594
1595         snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/rbd/devices/%d",
1596                  rbd_bus_id);
1597         rbd_bus_dev = udev_device_new_from_syspath(udev, sysfs_path);
1598         if (!rbd_bus_dev)
1599                 return -ENODEV;
1600
1601         ret = -EINVAL;
1602         pool = udev_device_get_sysattr_value(rbd_bus_dev, "pool_id");
1603         if (!pool)
1604                 goto free_dev;
1605
1606         image = udev_device_get_sysattr_value(rbd_bus_dev, "image_id");
1607         if (!image)
1608                 goto free_dev;
1609
1610         snap = udev_device_get_sysattr_value(rbd_bus_dev, "snap_id");
1611         if (!snap)
1612                 goto free_dev;
1613         snap_id = strtoull(snap, NULL, 19);
1614         if (snap_id >= max_snap_id)
1615                 ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s", pool, image);
1616         else
1617                 ret = snprintf(pp->wwid, WWID_SIZE, "%s-%s-%s", pool,
1618                                image, snap);
1619         if (ret >= WWID_SIZE) {
1620                 condlog(0, "%s: wwid overflow", pp->dev);
1621                 ret = -EOVERFLOW;
1622         }
1623
1624 free_dev:
1625         udev_device_unref(rbd_bus_dev);
1626         return ret;
1627 }
1628
1629 static int
1630 get_vpd_uid(struct path * pp)
1631 {
1632         struct udev_device *parent = pp->udev;
1633
1634         while (parent) {
1635                 const char *subsys = udev_device_get_subsystem(parent);
1636                 if (subsys && !strncmp(subsys, "scsi", 4))
1637                         break;
1638                 parent = udev_device_get_parent(parent);
1639         }
1640
1641         return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE);
1642 }
1643
1644 int
1645 get_uid (struct path * pp, int path_state, struct udev_device *udev)
1646 {
1647         char *c;
1648         const char *origin = "unknown";
1649         ssize_t len = 0;
1650         struct config *conf;
1651
1652         if (!pp->uid_attribute && !pp->getuid) {
1653                 conf = get_multipath_config();
1654                 select_getuid(conf, pp);
1655                 put_multipath_config(conf);
1656         }
1657
1658         if (!udev) {
1659                 condlog(1, "%s: no udev information", pp->dev);
1660                 return 1;
1661         }
1662
1663         memset(pp->wwid, 0, WWID_SIZE);
1664         if (pp->getuid) {
1665                 char buff[CALLOUT_MAX_SIZE];
1666
1667                 /* Use 'getuid' callout, deprecated */
1668                 condlog(1, "%s: using deprecated getuid callout", pp->dev);
1669                 if (path_state != PATH_UP) {
1670                         condlog(3, "%s: path inaccessible", pp->dev);
1671                         len = -EWOULDBLOCK;
1672                 } else if (apply_format(pp->getuid, &buff[0], pp)) {
1673                         condlog(0, "error formatting uid callout command");
1674                         len = -EINVAL;
1675                 } else if (execute_program(buff, pp->wwid, WWID_SIZE)) {
1676                         condlog(3, "error calling out %s", buff);
1677                         len = -EIO;
1678                 } else
1679                         len = strlen(pp->wwid);
1680                 origin = "callout";
1681         } else if (pp->bus == SYSFS_BUS_RBD) {
1682                 len = get_rbd_uid(pp);
1683                 origin = "sysfs";
1684         } else {
1685                 int retrigger;
1686
1687                 if (pp->uid_attribute) {
1688                         len = get_udev_uid(pp, pp->uid_attribute, udev);
1689                         origin = "udev";
1690                         if (len <= 0)
1691                                 condlog(1,
1692                                         "%s: failed to get udev uid: %s",
1693                                         pp->dev, strerror(-len));
1694
1695                 } else {
1696                         len = get_vpd_uid(pp);
1697                         origin = "sysfs";
1698                 }
1699                 conf = get_multipath_config();
1700                 retrigger = conf->retrigger_tries;
1701                 put_multipath_config(conf);
1702                 if (len <= 0 && pp->retriggers >= retrigger &&
1703                     !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
1704                         len = get_vpd_uid(pp);
1705                         origin = "sysfs";
1706                         pp->uid_attribute = NULL;
1707                         if (len < 0 && path_state == PATH_UP) {
1708                                 condlog(1, "%s: failed to get sysfs uid: %s",
1709                                         pp->dev, strerror(-len));
1710                                 len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
1711                                                    WWID_SIZE);
1712                                 origin = "sgio";
1713                         }
1714                 }
1715         }
1716         if ( len < 0 ) {
1717                 condlog(1, "%s: failed to get %s uid: %s",
1718                         pp->dev, origin, strerror(-len));
1719                 memset(pp->wwid, 0x0, WWID_SIZE);
1720         } else {
1721                 /* Strip any trailing blanks */
1722                 c = strchr(pp->wwid, '\0');
1723                 c--;
1724                 while (c && c >= pp->wwid && *c == ' ') {
1725                         *c = '\0';
1726                         c--;
1727                 }
1728         }
1729         condlog(3, "%s: uid = %s (%s)", pp->dev,
1730                 *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
1731         return 0;
1732 }
1733
1734 int pathinfo(struct path *pp, struct config *conf, int mask)
1735 {
1736         int path_state;
1737
1738         if (!pp)
1739                 return PATHINFO_FAILED;
1740
1741         /*
1742          * For behavior backward-compatibility with multipathd,
1743          * the blacklisting by filter_property|devnode() is not
1744          * limited by DI_BLACKLIST and occurs before this debug
1745          * message with the mask value.
1746          */
1747         if (pp->udev && filter_property(conf, pp->udev) > 0)
1748                 return PATHINFO_SKIPPED;
1749
1750         if (filter_devnode(conf->blist_devnode,
1751                            conf->elist_devnode,
1752                            pp->dev) > 0)
1753                 return PATHINFO_SKIPPED;
1754
1755         condlog(3, "%s: mask = 0x%x", pp->dev, mask);
1756
1757         /*
1758          * Sanity check: we need the device number to
1759          * avoid inconsistent information in
1760          * find_path_by_dev()/find_path_by_devt()
1761          */
1762         if (!strlen(pp->dev_t) && !(mask & DI_SYSFS)) {
1763                 condlog(1, "%s: empty device number", pp->dev);
1764                 mask |= DI_SYSFS;
1765         }
1766
1767         /*
1768          * fetch info available in sysfs
1769          */
1770         if (mask & DI_SYSFS && sysfs_pathinfo(pp, conf->hwtable))
1771                 return PATHINFO_FAILED;
1772
1773         if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
1774                 if (filter_device(conf->blist_device, conf->elist_device,
1775                                   pp->vendor_id, pp->product_id) > 0) {
1776                         return PATHINFO_SKIPPED;
1777                 }
1778         }
1779
1780         path_state = path_offline(pp);
1781         if (path_state == PATH_REMOVED)
1782                 goto blank;
1783
1784         /*
1785          * fetch info not available through sysfs
1786          */
1787         if (pp->fd < 0)
1788                 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1789
1790         if (pp->fd < 0) {
1791                 condlog(4, "Couldn't open node for %s: %s",
1792                         pp->dev, strerror(errno));
1793                 goto blank;
1794         }
1795
1796         if (mask & DI_SERIAL)
1797                 get_geometry(pp);
1798
1799         if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1800             scsi_ioctl_pathinfo(pp, mask))
1801                 goto blank;
1802
1803         if (pp->bus == SYSFS_BUS_CCISS &&
1804             cciss_ioctl_pathinfo(pp, mask))
1805                 goto blank;
1806
1807         if (mask & DI_CHECKER) {
1808                 if (path_state == PATH_UP) {
1809                         pp->chkrstate = pp->state = get_state(pp, conf, 0);
1810                         if (pp->state == PATH_UNCHECKED ||
1811                             pp->state == PATH_WILD)
1812                                 goto blank;
1813                         if (pp->state == PATH_TIMEOUT)
1814                                 pp->state = PATH_DOWN;
1815                         if (pp->state == PATH_UP && !pp->size) {
1816                                 condlog(3, "%s: device size is 0, "
1817                                         "path unusable", pp->dev);
1818                                 pp->state = PATH_GHOST;
1819                         }
1820                 } else {
1821                         condlog(3, "%s: path inaccessible", pp->dev);
1822                         pp->chkrstate = pp->state = path_state;
1823                         if (path_state == PATH_PENDING ||
1824                             path_state == PATH_DOWN)
1825                                 pp->priority = 0;
1826                 }
1827         }
1828
1829         if ((mask & DI_WWID) && !strlen(pp->wwid)) {
1830                 get_uid(pp, path_state, pp->udev);
1831                 if (!strlen(pp->wwid)) {
1832                         pp->initialized = INIT_MISSING_UDEV;
1833                         pp->tick = conf->retrigger_delay;
1834                         return PATHINFO_OK;
1835                 }
1836                 else
1837                         pp->tick = 1;
1838         }
1839
1840         if (mask & DI_BLACKLIST && mask & DI_WWID) {
1841                 if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1842                                 pp->wwid, pp->dev) > 0) {
1843                         return PATHINFO_SKIPPED;
1844                 }
1845         }
1846
1847          /*
1848           * Retrieve path priority, even for PATH_DOWN paths if it has never
1849           * been successfully obtained before.
1850           */
1851         if ((mask & DI_PRIO) && path_state == PATH_UP && strlen(pp->wwid)) {
1852                 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1853                         get_prio(pp);
1854                 }
1855         }
1856
1857         if ((mask & DI_ALL) == DI_ALL)
1858                 pp->initialized = INIT_OK;
1859         return PATHINFO_OK;
1860
1861 blank:
1862         /*
1863          * Recoverable error, for example faulty or offline path
1864          */
1865         memset(pp->wwid, 0, WWID_SIZE);
1866         pp->chkrstate = pp->state = PATH_DOWN;
1867         pp->initialized = INIT_FAILED;
1868
1869         return PATHINFO_OK;
1870 }