2 * Copyright (c) 2004, 2005, 2006 Christophe Varoqui
3 * Copyright (c) 2005 Stefan Bader, IBM
4 * Copyright (c) 2005 Mike Anderson
11 #include <sys/ioctl.h>
24 #include "blacklist.h"
28 #include "sg_include.h"
30 #include "discovery.h"
33 #include "unaligned.h"
34 #include "prioritizers/alua_rtpg.h"
38 alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice,
39 const char *wwid, int flag, struct path **pp_ptr)
41 int err = PATHINFO_FAILED;
48 devname = udev_device_get_sysname(udevice);
50 return PATHINFO_FAILED;
55 return PATHINFO_FAILED;
58 strlcpy(pp->wwid, wwid, sizeof(pp->wwid));
60 if (safe_sprintf(pp->dev, "%s", devname)) {
61 condlog(0, "pp->dev too small");
63 pp->udev = udev_device_ref(udevice);
64 err = pathinfo(pp, conf, flag | DI_BLACKLIST);
75 store_pathinfo (vector pathvec, struct config *conf,
76 struct udev_device *udevice, int flag, struct path **pp_ptr)
78 int err = PATHINFO_FAILED;
85 devname = udev_device_get_sysname(udevice);
87 return PATHINFO_FAILED;
92 return PATHINFO_FAILED;
94 if(safe_sprintf(pp->dev, "%s", devname)) {
95 condlog(0, "pp->dev too small");
98 pp->udev = udev_device_ref(udevice);
99 err = pathinfo(pp, conf, flag);
103 err = store_path(pathvec, pp);
116 path_discover (vector pathvec, struct config * conf,
117 struct udev_device *udevice, int flag)
120 const char * devname;
122 devname = udev_device_get_sysname(udevice);
124 return PATHINFO_FAILED;
126 pp = find_path_by_dev(pathvec, devname);
128 char devt[BLK_DEV_SIZE];
129 dev_t devnum = udev_device_get_devnum(udevice);
131 snprintf(devt, BLK_DEV_SIZE, "%d:%d",
132 major(devnum), minor(devnum));
133 pp = find_path_by_devt(pathvec, devt);
135 return store_pathinfo(pathvec, conf,
136 udevice, flag, NULL);
138 return pathinfo(pp, conf, flag);
142 path_discovery (vector pathvec, int flag)
144 struct udev_enumerate *udev_iter;
145 struct udev_list_entry *entry;
146 struct udev_device *udevice;
149 int num_paths = 0, total_paths = 0;
151 udev_iter = udev_enumerate_new(udev);
155 udev_enumerate_add_match_subsystem(udev_iter, "block");
156 udev_enumerate_add_match_is_initialized(udev_iter);
157 udev_enumerate_scan_devices(udev_iter);
159 udev_list_entry_foreach(entry,
160 udev_enumerate_get_list_entry(udev_iter)) {
162 devpath = udev_list_entry_get_name(entry);
163 condlog(4, "Discover device %s", devpath);
164 udevice = udev_device_new_from_syspath(udev, devpath);
166 condlog(4, "%s: no udev information", devpath);
169 devtype = udev_device_get_devtype(udevice);
170 if(devtype && !strncmp(devtype, "disk", 4)) {
172 conf = get_multipath_config();
173 pthread_cleanup_push(put_multipath_config, conf);
174 if (path_discover(pathvec, conf,
175 udevice, flag) == PATHINFO_OK)
177 pthread_cleanup_pop(1);
179 udev_device_unref(udevice);
181 udev_enumerate_unref(udev_iter);
182 condlog(4, "Discovered %d/%d paths", num_paths, total_paths);
183 return (total_paths - num_paths);
186 #define declare_sysfs_get_str(fname) \
188 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len) \
192 const char * devname; \
197 devname = udev_device_get_sysname(udev); \
199 attr = udev_device_get_sysattr_value(udev, #fname); \
201 condlog(3, "%s: attribute %s not found in sysfs", \
205 for (l = strlen(attr); l >= 1 && isspace(attr[l-1]); l--); \
207 condlog(3, "%s: overflow in attribute %s", \
211 strlcpy(buff, attr, len); \
212 return strchop(buff); \
215 declare_sysfs_get_str(devtype);
216 declare_sysfs_get_str(vendor);
217 declare_sysfs_get_str(model);
218 declare_sysfs_get_str(rev);
221 sysfs_get_vpd (struct udev_device * udev, int pg,
222 unsigned char * buff, size_t len)
226 const char * devname;
229 condlog(3, "No udev device given\n");
233 devname = udev_device_get_sysname(udev);
234 sprintf(attrname, "vpd_pg%02x", pg);
235 attr_len = sysfs_bin_attr_get_value(udev, attrname, buff, len);
237 condlog(3, "%s: attribute %s not found in sysfs",
245 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
247 const char *attr = NULL;
249 struct udev_device *parent;
253 if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
258 subsys = udev_device_get_subsystem(parent);
259 attr = udev_device_get_sysattr_value(parent, "timeout");
262 parent = udev_device_get_parent(parent);
265 condlog(3, "%s: No timeout value in sysfs", pp->dev);
269 t = strtoul(attr, &eptr, 0);
270 if (attr == eptr || t == ULONG_MAX) {
271 condlog(3, "%s: Cannot parse timeout attribute '%s'",
276 condlog(3, "%s: Overflow in timeout value '%s'",
286 sysfs_get_tgt_nodename (struct path *pp, char * node)
288 const char *tgtname, *value;
289 struct udev_device *parent, *tgtdev;
290 int host, channel, tgtid = -1;
292 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
296 value = udev_device_get_sysattr_value(parent, "sas_address");
298 tgtdev = udev_device_get_parent(parent);
300 tgtname = udev_device_get_sysname(tgtdev);
301 if (sscanf(tgtname, "end_device-%d:%d",
304 tgtdev = udev_device_get_parent(tgtdev);
308 pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
309 pp->sg_id.transport_id = tgtid;
310 strncpy(node, value, NODE_NAME_SIZE);
316 tgtdev = udev_device_get_parent(parent);
318 value = udev_device_get_subsystem(tgtdev);
319 if (value && !strcmp(value, "usb")) {
320 pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
321 tgtname = udev_device_get_sysname(tgtdev);
322 strncpy(node, tgtname, strlen(tgtname));
323 condlog(3, "%s: skip USB device %s", pp->dev, node);
326 tgtdev = udev_device_get_parent(tgtdev);
328 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
331 /* Check for FibreChannel */
332 tgtdev = udev_device_get_parent(parent);
333 value = udev_device_get_sysname(tgtdev);
334 if (sscanf(value, "rport-%d:%d-%d",
335 &host, &channel, &tgtid) == 3) {
336 tgtdev = udev_device_new_from_subsystem_sysname(udev,
337 "fc_remote_ports", value);
339 condlog(3, "SCSI target %d:%d:%d -> "
341 pp->sg_id.host_no, pp->sg_id.channel,
342 pp->sg_id.scsi_id, host, channel,
344 value = udev_device_get_sysattr_value(tgtdev,
347 pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
348 pp->sg_id.transport_id = tgtid;
349 strncpy(node, value, NODE_NAME_SIZE);
350 udev_device_unref(tgtdev);
353 udev_device_unref(tgtdev);
357 /* Check for iSCSI */
361 tgtname = udev_device_get_sysname(parent);
362 if (tgtname && sscanf(tgtname , "session%d", &tgtid) == 1)
364 parent = udev_device_get_parent(parent);
368 if (parent && tgtname) {
369 tgtdev = udev_device_new_from_subsystem_sysname(udev,
370 "iscsi_session", tgtname);
374 value = udev_device_get_sysattr_value(tgtdev, "targetname");
376 pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
377 pp->sg_id.transport_id = tgtid;
378 strncpy(node, value, NODE_NAME_SIZE);
379 udev_device_unref(tgtdev);
383 udev_device_unref(tgtdev);
386 /* Check for libata */
390 tgtname = udev_device_get_sysname(parent);
391 if (tgtname && sscanf(tgtname, "ata%d", &tgtid) == 1)
393 parent = udev_device_get_parent(parent);
397 pp->sg_id.proto_id = SCSI_PROTOCOL_ATA;
398 pp->sg_id.transport_id = tgtid;
399 snprintf(node, NODE_NAME_SIZE, "ata-%d.00", tgtid);
402 /* Unknown SCSI transport. Keep fingers crossed */
403 pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
407 int sysfs_get_host_adapter_name(const struct path *pp, char *adapter_name)
411 if (!pp || !adapter_name)
414 proto_id = pp->sg_id.proto_id;
416 if (proto_id != SCSI_PROTOCOL_FCP &&
417 proto_id != SCSI_PROTOCOL_SAS &&
418 proto_id != SCSI_PROTOCOL_ISCSI &&
419 proto_id != SCSI_PROTOCOL_SRP) {
422 /* iscsi doesn't have adapter info in sysfs
423 * get ip_address for grouping paths
425 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
426 return sysfs_get_iscsi_ip_address(pp, adapter_name);
428 /* fetch adapter pci name for other protocols
430 return sysfs_get_host_pci_name(pp, adapter_name);
433 int sysfs_get_host_pci_name(const struct path *pp, char *pci_name)
435 struct udev_device *hostdev, *parent;
436 char host_name[HOST_NAME_LEN];
437 const char *driver_name, *value;
439 if (!pp || !pci_name)
442 sprintf(host_name, "host%d", pp->sg_id.host_no);
443 hostdev = udev_device_new_from_subsystem_sysname(udev,
444 "scsi_host", host_name);
448 parent = udev_device_get_parent(hostdev);
450 driver_name = udev_device_get_driver(parent);
452 parent = udev_device_get_parent(parent);
455 if (!strcmp(driver_name, "pcieport"))
457 parent = udev_device_get_parent(parent);
462 value = udev_device_get_sysname(parent);
464 strncpy(pci_name, value, SLOT_NAME_SIZE);
465 udev_device_unref(hostdev);
468 udev_device_unref(hostdev);
472 int sysfs_get_iscsi_ip_address(const struct path *pp, char *ip_address)
474 struct udev_device *hostdev;
475 char host_name[HOST_NAME_LEN];
478 sprintf(host_name, "host%d", pp->sg_id.host_no);
479 hostdev = udev_device_new_from_subsystem_sysname(udev,
480 "iscsi_host", host_name);
482 value = udev_device_get_sysattr_value(hostdev,
485 strncpy(ip_address, value, SLOT_NAME_SIZE);
486 udev_device_unref(hostdev);
489 udev_device_unref(hostdev);
495 sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen)
497 struct udev_device *parent = pp->udev;
498 char value[16], *eptr;
499 unsigned long preferred;
502 const char *subsys = udev_device_get_subsystem(parent);
503 if (subsys && !strncmp(subsys, "scsi", 4))
505 parent = udev_device_get_parent(parent);
511 if (sysfs_attr_get_value(parent, "access_state", buff, buflen) <= 0)
514 if (sysfs_attr_get_value(parent, "preferred_path", value, 16) <= 0)
517 preferred = strtoul(value, &eptr, 0);
518 if (value == eptr || preferred == ULONG_MAX) {
519 /* Parse error, ignore */
526 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
528 struct udev_device *rport_dev = NULL;
529 char value[16], *eptr;
531 unsigned long long tmo = 0;
534 sprintf(rport_id, "rport-%d:%d-%d",
535 pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
536 rport_dev = udev_device_new_from_subsystem_sysname(udev,
537 "fc_remote_ports", rport_id);
539 condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
543 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
544 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
547 * read the current dev_loss_tmo value from sysfs
549 ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16);
551 condlog(0, "%s: failed to read dev_loss_tmo value, "
552 "error %d", rport_id, -ret);
555 tmo = strtoull(value, &eptr, 0);
556 if (value == eptr || tmo == ULLONG_MAX) {
557 condlog(0, "%s: Cannot parse dev_loss_tmo "
558 "attribute '%s'", rport_id, value);
564 * dev_loss_tmo will be limited to 600 if fast_io_fail
566 * fast_io_fail will be limited by the current dev_loss_tmo
568 * So to get everything right we first need to increase
569 * dev_loss_tmo to the fast_io_fail setting (if present),
570 * then set fast_io_fail, and _then_ set dev_loss_tmo
571 * to the correct value.
573 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET &&
574 mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO &&
575 mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) {
576 /* Check if we need to temporarily increase dev_loss_tmo */
577 if (mpp->fast_io_fail >= tmo) {
578 /* Increase dev_loss_tmo temporarily */
579 snprintf(value, 16, "%u", mpp->fast_io_fail + 1);
580 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
581 value, strlen(value));
584 condlog(3, "%s: rport blocked",
587 condlog(0, "%s: failed to set "
588 "dev_loss_tmo to %s, error %d",
589 rport_id, value, -ret);
593 } else if (mpp->dev_loss > DEFAULT_DEV_LOSS_TMO &&
594 mpp->no_path_retry != NO_PATH_RETRY_QUEUE) {
595 condlog(3, "%s: limiting dev_loss_tmo to %d, since "
596 "fast_io_fail is not set",
597 rport_id, DEFAULT_DEV_LOSS_TMO);
598 mpp->dev_loss = DEFAULT_DEV_LOSS_TMO;
600 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
601 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
602 sprintf(value, "off");
603 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
606 snprintf(value, 16, "%u", mpp->fast_io_fail);
607 ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
608 value, strlen(value));
611 condlog(3, "%s: rport blocked", rport_id);
613 condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
614 rport_id, value, -ret);
617 if (mpp->dev_loss > 0) {
618 snprintf(value, 16, "%u", mpp->dev_loss);
619 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
620 value, strlen(value));
623 condlog(3, "%s: rport blocked", rport_id);
625 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
626 rport_id, value, -ret);
630 udev_device_unref(rport_dev);
634 sysfs_set_session_tmo(struct multipath *mpp, struct path *pp)
636 struct udev_device *session_dev = NULL;
640 sprintf(session_id, "session%d", pp->sg_id.transport_id);
641 session_dev = udev_device_new_from_subsystem_sysname(udev,
642 "iscsi_session", session_id);
644 condlog(1, "%s: No iscsi session for '%s'", pp->dev,
648 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
649 pp->sg_id.channel, pp->sg_id.scsi_id, session_id);
652 condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev);
654 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
655 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) {
656 condlog(3, "%s: can't switch off fast_io_fail_tmo "
657 "on iSCSI", pp->dev);
658 } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) {
659 condlog(3, "%s: can't set fast_io_fail_tmo to '0'"
660 "on iSCSI", pp->dev);
662 snprintf(value, 11, "%u", mpp->fast_io_fail);
663 if (sysfs_attr_set_value(session_dev, "recovery_tmo",
665 condlog(3, "%s: Failed to set recovery_tmo, "
666 " error %d", pp->dev, errno);
670 udev_device_unref(session_dev);
675 sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp)
677 struct udev_device *sas_dev = NULL;
681 sprintf(end_dev_id, "end_device-%d:%d",
682 pp->sg_id.host_no, pp->sg_id.transport_id);
683 sas_dev = udev_device_new_from_subsystem_sysname(udev,
684 "sas_end_device", end_dev_id);
686 condlog(1, "%s: No SAS end device for '%s'", pp->dev,
690 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
691 pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id);
694 snprintf(value, 11, "%u", mpp->dev_loss);
695 if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout",
697 condlog(3, "%s: failed to update "
698 "I_T Nexus loss timeout, error %d",
701 udev_device_unref(sas_dev);
706 sysfs_set_scsi_tmo (struct multipath *mpp, int checkint)
710 int dev_loss_tmo = mpp->dev_loss;
712 if (mpp->no_path_retry > 0) {
713 uint64_t no_path_retry_tmo = mpp->no_path_retry * checkint;
715 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
716 no_path_retry_tmo = MAX_DEV_LOSS_TMO;
717 if (no_path_retry_tmo > dev_loss_tmo)
718 dev_loss_tmo = no_path_retry_tmo;
719 condlog(3, "%s: update dev_loss_tmo to %u",
720 mpp->alias, dev_loss_tmo);
721 } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
722 dev_loss_tmo = MAX_DEV_LOSS_TMO;
723 condlog(3, "%s: update dev_loss_tmo to %u",
724 mpp->alias, dev_loss_tmo);
726 mpp->dev_loss = dev_loss_tmo;
727 if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
728 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
729 mpp->alias, mpp->fast_io_fail);
730 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
732 if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
735 vector_foreach_slot(mpp->paths, pp, i) {
736 if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
737 sysfs_set_rport_tmo(mpp, pp);
738 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
739 sysfs_set_session_tmo(mpp, pp);
740 if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
741 sysfs_set_nexus_loss_tmo(mpp, pp);
747 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
748 void *resp, int mx_resp_len)
750 unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
751 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
752 unsigned char sense_b[SENSE_BUFF_LEN];
753 struct sg_io_hdr io_hdr;
759 inqCmdBlk[2] = (unsigned char) pg_op;
760 inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
761 inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
762 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
763 memset(sense_b, 0, SENSE_BUFF_LEN);
764 io_hdr.interface_id = 'S';
765 io_hdr.cmd_len = sizeof (inqCmdBlk);
766 io_hdr.mx_sb_len = sizeof (sense_b);
767 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
768 io_hdr.dxfer_len = mx_resp_len;
769 io_hdr.dxferp = resp;
770 io_hdr.cmdp = inqCmdBlk;
771 io_hdr.sbp = sense_b;
772 io_hdr.timeout = DEF_TIMEOUT * 1000;
774 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
777 /* treat SG_ERR here to get rid of sg_err.[ch] */
778 io_hdr.status &= 0x7e;
779 if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
780 (0 == io_hdr.driver_status))
782 if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
783 (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
784 (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
785 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
787 unsigned char * sense_buffer = io_hdr.sbp;
788 if (sense_buffer[0] & 0x2)
789 sense_key = sense_buffer[1] & 0xf;
791 sense_key = sense_buffer[2] & 0xf;
792 if(RECOVERED_ERROR == sense_key)
800 get_serial (char * str, int maxlen, int fd)
803 char buff[MX_ALLOC_LEN + 1] = {0};
808 if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
813 memcpy(str, buff + 4, len);
822 detect_alua(struct path * pp, struct config *conf)
826 unsigned int timeout = conf->checker_timeout;
828 if ((tpgs = get_target_port_group_support(pp->fd, timeout)) <= 0) {
829 pp->tpgs = TPGS_NONE;
832 ret = get_target_port_group(pp, timeout);
833 if (ret < 0 || get_asymmetric_access_state(pp->fd, ret, timeout) < 0) {
834 pp->tpgs = TPGS_NONE;
840 #define DEFAULT_SGIO_LEN 254
842 /* Query VPD page @pg. Returns number of INQUIRY bytes
843 upon success and -1 upon failure. */
845 sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg)
847 int len = DEFAULT_SGIO_LEN;
854 if (0 == do_inq(fd, 0, 1, pg, buff, len)) {
855 len = get_unaligned_be16(&buff[2]) + 4;
858 if (len > DEFAULT_SGIO_LEN)
866 get_geometry(struct path *pp)
871 if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
872 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
873 memset(&pp->geom, 0, sizeof(pp->geom));
876 condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
877 pp->dev, pp->geom.cylinders, pp->geom.heads,
878 pp->geom.sectors, pp->geom.start);
883 parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len)
886 int len = get_unaligned_be16(&in[2]);
888 if (len >= out_len) {
889 condlog(2, "vpd pg80 overflow, %d/%d bytes required",
894 memcpy(out, in + 4, len);
898 * Strip trailing whitspaces
901 while (p > out && *p == ' ') {
910 parse_vpd_pg83(const unsigned char *in, size_t in_len,
911 char *out, size_t out_len)
913 const unsigned char *d;
914 const unsigned char *vpd = NULL;
915 int len = -ENODATA, vpd_type, vpd_len, prio = -1, i, naa_prio;
918 while (d < in + in_len) {
919 /* Select 'association: LUN' */
920 if ((d[1] & 0x30) != 0) {
924 switch (d[1] & 0xf) {
929 /* IEEE Registered Extended: Prio 8 */
933 /* IEEE Registered: Prio 7 */
937 /* IEEE Extended: Prio 6 */
941 /* IEEE Locally assigned: Prio 1 */
945 /* Default: no priority */
949 if (prio < naa_prio) {
955 /* SCSI Name: Prio 4 */
956 if (memcmp(d + 4, "eui.", 4) &&
957 memcmp(d + 4, "naa.", 4) &&
958 memcmp(d + 4, "iqn.", 4))
973 /* T-10 Vendor ID: Prio 2 */
983 vpd_type = vpd[1] & 0xf;
986 if (vpd_type == 0x2 || vpd_type == 0x3) {
989 len = sprintf(out, "%d", vpd_type);
990 for (i = 0; i < vpd_len; i++) {
991 len += sprintf(out + len,
996 } else if (vpd_type == 0x8) {
997 if (!memcmp("eui.", vpd, 4)) {
1002 for (i = 0; i < vpd_len; i++) {
1003 len += sprintf(out + len, "%c",
1010 } else if (!memcmp("naa.", vpd, 4)) {
1015 for (i = 0; i < vpd_len; i++) {
1016 len += sprintf(out + len, "%c",
1028 if (vpd_len > out_len + 2)
1029 vpd_len = out_len - 2;
1030 memcpy(out, vpd, vpd_len);
1034 } else if (vpd_type == 0x1) {
1035 const unsigned char *p;
1041 while ((p = memchr(vpd, ' ', vpd_len))) {
1043 if (len + p_len > out_len - 1)
1044 p_len = out_len - len - 2;
1045 memcpy(out + len, vpd, p_len);
1047 if (len >= out_len - 1) {
1055 while (vpd && *vpd == ' ') {
1060 if (len > 1 && out[len - 1] == '_') {
1061 out[len - 1] = '\0';
1070 get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
1073 unsigned char buff[4096];
1075 memset(buff, 0x0, 4096);
1076 if (!parent || sysfs_get_vpd(parent, pg, buff, 4096) <= 0) {
1077 condlog(3, "failed to read sysfs vpd pg%02x", pg);
1081 if (buff[1] != pg) {
1082 condlog(3, "vpd pg%02x error, invalid vpd page %02x",
1086 buff_len = get_unaligned_be16(&buff[2]) + 4;
1087 if (buff_len > 4096)
1088 condlog(3, "vpd pg%02x page truncated", pg);
1091 len = parse_vpd_pg80(buff, str, maxlen);
1092 else if (pg == 0x83)
1093 len = parse_vpd_pg83(buff, buff_len, str, maxlen);
1101 get_vpd_sgio (int fd, int pg, char * str, int maxlen)
1104 unsigned char buff[4096];
1106 memset(buff, 0x0, 4096);
1107 if (sgio_get_vpd(buff, 4096, fd, pg) < 0) {
1108 condlog(3, "failed to issue vpd inquiry for pg%02x",
1113 if (buff[1] != pg) {
1114 condlog(3, "vpd pg%02x error, invalid vpd page %02x",
1118 buff_len = get_unaligned_be16(&buff[2]) + 4;
1119 if (buff_len > 4096)
1120 condlog(3, "vpd pg%02x page truncated", pg);
1123 len = parse_vpd_pg80(buff, str, maxlen);
1124 else if (pg == 0x83)
1125 len = parse_vpd_pg83(buff, buff_len, str, maxlen);
1126 else if (pg == 0xc9 && maxlen >= 8) {
1127 len = buff_len < 8 ? -ENODATA :
1128 (buff_len <= maxlen ? buff_len : maxlen);
1129 memcpy (str, buff, len);
1137 scsi_sysfs_pathinfo (struct path * pp, vector hwtable)
1139 struct udev_device *parent;
1140 const char *attr_path = NULL;
1144 const char *subsys = udev_device_get_subsystem(parent);
1145 if (subsys && !strncmp(subsys, "scsi", 4)) {
1146 attr_path = udev_device_get_sysname(parent);
1149 if (sscanf(attr_path, "%i:%i:%i:%i",
1153 &pp->sg_id.lun) == 4)
1156 parent = udev_device_get_parent(parent);
1158 if (!attr_path || pp->sg_id.host_no == -1)
1161 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
1164 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1166 if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0)
1169 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1171 if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) < 0)
1174 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1177 * set the hwe configlet pointer
1179 find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev, pp->hwe);
1182 * host / bus / target / lun
1184 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1194 if(sysfs_get_tgt_nodename(pp, pp->tgt_node_name))
1197 condlog(3, "%s: tgt_node_name = %s",
1198 pp->dev, pp->tgt_node_name);
1204 nvme_sysfs_pathinfo (struct path * pp, vector hwtable)
1206 struct udev_device *parent;
1207 const char *attr_path = NULL;
1210 attr_path = udev_device_get_sysname(pp->udev);
1214 if (sscanf(attr_path, "nvme%dn%d",
1216 &pp->sg_id.scsi_id) != 2)
1219 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev,
1224 attr = udev_device_get_sysattr_value(pp->udev, "nsid");
1225 pp->sg_id.lun = attr ? atoi(attr) : 0;
1227 attr = udev_device_get_sysattr_value(parent, "cntlid");
1228 pp->sg_id.channel = attr ? atoi(attr) : 0;
1230 snprintf(pp->vendor_id, SCSI_VENDOR_SIZE, "NVME");
1231 snprintf(pp->product_id, PATH_PRODUCT_SIZE, "%s",
1232 udev_device_get_sysattr_value(parent, "model"));
1233 snprintf(pp->serial, SERIAL_SIZE, "%s",
1234 udev_device_get_sysattr_value(parent, "serial"));
1235 snprintf(pp->rev, PATH_REV_SIZE, "%s",
1236 udev_device_get_sysattr_value(parent, "firmware_rev"));
1238 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1239 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1240 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1241 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1243 find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL, pp->hwe);
1249 ccw_sysfs_pathinfo (struct path * pp, vector hwtable)
1251 struct udev_device *parent;
1252 char attr_buff[NAME_SIZE];
1253 const char *attr_path;
1257 const char *subsys = udev_device_get_subsystem(parent);
1258 if (subsys && !strncmp(subsys, "ccw", 3))
1260 parent = udev_device_get_parent(parent);
1265 sprintf(pp->vendor_id, "IBM");
1267 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1269 if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE) <= 0)
1272 if (!strncmp(attr_buff, "3370", 4)) {
1273 sprintf(pp->product_id,"S/390 DASD FBA");
1274 } else if (!strncmp(attr_buff, "9336", 4)) {
1275 sprintf(pp->product_id,"S/390 DASD FBA");
1277 sprintf(pp->product_id,"S/390 DASD ECKD");
1280 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1283 * set the hwe configlet pointer
1285 find_hwe(hwtable, pp->vendor_id, pp->product_id, NULL, pp->hwe);
1288 * host / bus / target / lun
1290 attr_path = udev_device_get_sysname(parent);
1292 if (sscanf(attr_path, "%i.%i.%x",
1295 &pp->sg_id.scsi_id) == 3) {
1296 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1308 cciss_sysfs_pathinfo (struct path * pp, vector hwtable)
1310 const char * attr_path = NULL;
1311 struct udev_device *parent;
1315 const char *subsys = udev_device_get_subsystem(parent);
1316 if (subsys && !strncmp(subsys, "cciss", 5)) {
1317 attr_path = udev_device_get_sysname(parent);
1320 if (sscanf(attr_path, "c%id%i",
1322 &pp->sg_id.scsi_id) == 2)
1325 parent = udev_device_get_parent(parent);
1327 if (!attr_path || pp->sg_id.host_no == -1)
1330 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE) <= 0)
1333 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
1335 if (sysfs_get_model(parent, pp->product_id, PATH_PRODUCT_SIZE) <= 0)
1338 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
1340 if (sysfs_get_rev(parent, pp->rev, PATH_REV_SIZE) <= 0)
1343 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
1346 * set the hwe configlet pointer
1348 find_hwe(hwtable, pp->vendor_id, pp->product_id, pp->rev, pp->hwe);
1351 * host / bus / target / lun
1354 pp->sg_id.channel = 0;
1355 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
1365 common_sysfs_pathinfo (struct path * pp)
1373 condlog(4, "%s: udev not initialised", pp->dev);
1376 devt = udev_device_get_devnum(pp->udev);
1377 snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), minor(devt));
1379 condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
1381 if (sysfs_get_size(pp, &pp->size))
1384 condlog(3, "%s: size = %llu", pp->dev, pp->size);
1390 path_offline (struct path * pp)
1392 struct udev_device * parent;
1393 char buff[SCSI_STATE_SIZE];
1395 const char *subsys_type;
1397 if (pp->bus == SYSFS_BUS_SCSI) {
1398 subsys_type = "scsi";
1400 else if (pp->bus == SYSFS_BUS_NVME) {
1401 subsys_type = "nvme";
1409 const char *subsys = udev_device_get_subsystem(parent);
1410 if (subsys && !strncmp(subsys, subsys_type, 4))
1412 parent = udev_device_get_parent(parent);
1416 condlog(1, "%s: failed to get sysfs information", pp->dev);
1417 return PATH_REMOVED;
1420 memset(buff, 0x0, SCSI_STATE_SIZE);
1421 err = sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE);
1424 return PATH_REMOVED;
1430 condlog(3, "%s: path state = %s", pp->dev, buff);
1432 if (pp->bus == SYSFS_BUS_SCSI) {
1433 if (!strncmp(buff, "offline", 7)) {
1438 if (!strncmp(buff, "blocked", 7) ||
1439 !strncmp(buff, "quiesce", 7))
1440 return PATH_PENDING;
1441 else if (!strncmp(buff, "running", 7))
1445 else if (pp->bus == SYSFS_BUS_NVME) {
1446 if (!strncmp(buff, "dead", 4)) {
1451 if (!strncmp(buff, "new", 3) ||
1452 !strncmp(buff, "deleting", 8))
1453 return PATH_PENDING;
1454 else if (!strncmp(buff, "live", 4))
1462 sysfs_pathinfo(struct path * pp, vector hwtable)
1464 if (common_sysfs_pathinfo(pp))
1467 pp->bus = SYSFS_BUS_UNDEF;
1468 if (!strncmp(pp->dev,"cciss",5))
1469 pp->bus = SYSFS_BUS_CCISS;
1470 if (!strncmp(pp->dev,"dasd", 4))
1471 pp->bus = SYSFS_BUS_CCW;
1472 if (!strncmp(pp->dev,"sd", 2))
1473 pp->bus = SYSFS_BUS_SCSI;
1474 if (!strncmp(pp->dev,"nvme", 4))
1475 pp->bus = SYSFS_BUS_NVME;
1477 if (pp->bus == SYSFS_BUS_UNDEF)
1479 else if (pp->bus == SYSFS_BUS_SCSI) {
1480 if (scsi_sysfs_pathinfo(pp, hwtable))
1482 } else if (pp->bus == SYSFS_BUS_CCW) {
1483 if (ccw_sysfs_pathinfo(pp, hwtable))
1485 } else if (pp->bus == SYSFS_BUS_CCISS) {
1486 if (cciss_sysfs_pathinfo(pp, hwtable))
1488 } else if (pp->bus == SYSFS_BUS_NVME) {
1489 if (nvme_sysfs_pathinfo(pp, hwtable))
1496 scsi_ioctl_pathinfo (struct path * pp, struct config *conf, int mask)
1498 struct udev_device *parent;
1499 const char *attr_path = NULL;
1501 if (pp->tpgs == TPGS_UNDEF)
1502 detect_alua(pp, conf);
1504 if (!(mask & DI_SERIAL))
1509 const char *subsys = udev_device_get_subsystem(parent);
1510 if (subsys && !strncmp(subsys, "scsi", 4)) {
1511 attr_path = udev_device_get_sysname(parent);
1514 if (sscanf(attr_path, "%i:%i:%i:%i",
1518 &pp->sg_id.lun) == 4)
1521 parent = udev_device_get_parent(parent);
1523 if (!attr_path || pp->sg_id.host_no == -1)
1526 if (get_vpd_sysfs(parent, 0x80, pp->serial, SERIAL_SIZE) <= 0) {
1527 if (get_serial(pp->serial, SERIAL_SIZE, pp->fd)) {
1528 condlog(2, "%s: fail to get serial", pp->dev);
1533 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1538 cciss_ioctl_pathinfo (struct path * pp, int mask)
1540 if (mask & DI_SERIAL) {
1541 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
1542 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
1548 get_state (struct path * pp, struct config *conf, int daemon, int oldstate)
1550 struct checker * c = &pp->checker;
1553 condlog(3, "%s: get_state", pp->dev);
1555 if (!checker_selected(c)) {
1557 if (pathinfo(pp, conf, DI_SYSFS) != PATHINFO_OK) {
1558 condlog(3, "%s: couldn't get sysfs pathinfo",
1560 return PATH_UNCHECKED;
1563 select_detect_checker(conf, pp);
1564 select_checker(conf, pp);
1565 if (!checker_selected(c)) {
1566 condlog(3, "%s: No checker selected", pp->dev);
1567 return PATH_UNCHECKED;
1569 checker_set_fd(c, pp->fd);
1570 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
1572 condlog(3, "%s: checker init failed", pp->dev);
1573 return PATH_UNCHECKED;
1576 checker_clear_message(c);
1578 if (conf->force_sync == 0)
1579 checker_set_async(c);
1581 checker_set_sync(c);
1583 if (!conf->checker_timeout &&
1584 sysfs_get_timeout(pp, &(c->timeout)) <= 0)
1585 c->timeout = DEF_TIMEOUT;
1586 state = checker_check(c, oldstate);
1587 condlog(3, "%s: %s state = %s", pp->dev,
1588 checker_name(c), checker_state_name(state));
1589 if (state != PATH_UP && state != PATH_GHOST &&
1590 strlen(checker_message(c)))
1591 condlog(3, "%s: checker msg is \"%s\"",
1592 pp->dev, checker_message(c));
1597 get_prio (struct path * pp)
1600 struct config *conf;
1601 int checker_timeout;
1607 if (!prio_selected(p)) {
1608 conf = get_multipath_config();
1609 pthread_cleanup_push(put_multipath_config, conf);
1610 select_detect_prio(conf, pp);
1611 select_prio(conf, pp);
1612 pthread_cleanup_pop(1);
1613 if (!prio_selected(p)) {
1614 condlog(3, "%s: no prio selected", pp->dev);
1615 pp->priority = PRIO_UNDEF;
1619 conf = get_multipath_config();
1620 checker_timeout = conf->checker_timeout;
1621 put_multipath_config(conf);
1622 pp->priority = prio_getprio(p, pp, checker_timeout);
1623 if (pp->priority < 0) {
1624 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
1625 pp->priority = PRIO_UNDEF;
1628 condlog(3, "%s: %s prio = %u",
1629 pp->dev, prio_name(p), pp->priority);
1634 * Mangle string of length *len starting at start
1635 * by removing character sequence "00" (hex for a 0 byte),
1636 * starting at end, backwards.
1637 * Changes the value of *len if characters were removed.
1638 * Returns a pointer to the position where "end" was moved to.
1641 *skip_zeroes_backward(char* start, int *len, char *end)
1645 while (p >= start + 2 && *(p - 1) == '0' && *(p - 2) == '0')
1651 memmove(p, end, start + *len + 1 - end);
1658 * Fix for NVME wwids looking like this:
1659 * nvme.0000-3163653363666438366239656630386200-4c696e75780000000000000000000000000000000000000000000000000000000000000000000000-00000002
1660 * which are encountered in some combinations of Linux NVME host and target.
1661 * The '00' are hex-encoded 0-bytes which are forbidden in the serial (SN)
1662 * and model (MN) fields. Discard them.
1663 * If a WWID of the above type is found, sets pp->wwid and returns a value > 0.
1664 * Otherwise, returns 0.
1667 fix_broken_nvme_wwid(struct path *pp, const char *value, int size)
1669 static const char _nvme[] = "nvme.";
1674 len = strlen(value);
1675 if (len >= sizeof(mangled))
1678 /* Check that value starts with "nvme.%04x-" */
1679 if (memcmp(value, _nvme, sizeof(_nvme) - 1) || value[9] != '-')
1681 for (i = 5; i < 9; i++)
1682 if (!isxdigit(value[i]))
1685 memcpy(mangled, value, len + 1);
1687 /* search end of "model" part and strip trailing '00' */
1688 p = memrchr(mangled, '-', len);
1692 p = skip_zeroes_backward(mangled, &len, p);
1694 /* search end of "serial" part */
1695 p = memrchr(mangled, '-', p - mangled);
1696 if (p == NULL || memrchr(mangled, '-', p - mangled) != mangled + 9)
1697 /* We expect exactly 3 '-' in the value */
1700 p = skip_zeroes_backward(mangled, &len, p);
1704 memcpy(pp->wwid, mangled, len + 1);
1705 condlog(2, "%s: over-long WWID shortened to %s", pp->dev, pp->wwid);
1710 get_udev_uid(struct path * pp, char *uid_attribute, struct udev_device *udev)
1715 value = udev_device_get_property_value(udev, uid_attribute);
1716 if (!value || strlen(value) == 0)
1717 value = getenv(uid_attribute);
1718 if (value && strlen(value)) {
1719 len = strlcpy(pp->wwid, value, WWID_SIZE);
1720 if (len >= WWID_SIZE) {
1721 len = fix_broken_nvme_wwid(pp, value, WWID_SIZE);
1724 condlog(0, "%s: wwid overflow", pp->dev);
1728 condlog(3, "%s: no %s attribute", pp->dev,
1736 get_vpd_uid(struct path * pp)
1738 struct udev_device *parent = pp->udev;
1741 const char *subsys = udev_device_get_subsystem(parent);
1742 if (subsys && !strncmp(subsys, "scsi", 4))
1744 parent = udev_device_get_parent(parent);
1750 return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE);
1753 static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
1754 const char **origin)
1758 struct config *conf;
1760 conf = get_multipath_config();
1761 retrigger = conf->retrigger_tries;
1762 put_multipath_config(conf);
1763 if (pp->retriggers >= retrigger &&
1764 !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
1765 len = get_vpd_uid(pp);
1767 pp->uid_attribute = NULL;
1768 if (len < 0 && path_state == PATH_UP) {
1769 condlog(1, "%s: failed to get sysfs uid: %s",
1770 pp->dev, strerror(-len));
1771 len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
1780 get_uid (struct path * pp, int path_state, struct udev_device *udev)
1783 const char *origin = "unknown";
1785 struct config *conf;
1787 if (!pp->uid_attribute && !pp->getuid) {
1788 conf = get_multipath_config();
1789 pthread_cleanup_push(put_multipath_config, conf);
1790 select_getuid(conf, pp);
1791 pthread_cleanup_pop(1);
1794 memset(pp->wwid, 0, WWID_SIZE);
1796 char buff[CALLOUT_MAX_SIZE];
1798 /* Use 'getuid' callout, deprecated */
1799 condlog(1, "%s: using deprecated getuid callout", pp->dev);
1800 if (path_state != PATH_UP) {
1801 condlog(3, "%s: path inaccessible", pp->dev);
1803 } else if (apply_format(pp->getuid, &buff[0], pp)) {
1804 condlog(0, "error formatting uid callout command");
1806 } else if (execute_program(buff, pp->wwid, WWID_SIZE)) {
1807 condlog(3, "error calling out %s", buff);
1810 len = strlen(pp->wwid);
1814 if (udev && pp->uid_attribute) {
1815 len = get_udev_uid(pp, pp->uid_attribute, udev);
1819 "%s: failed to get udev uid: %s",
1820 pp->dev, strerror(-len));
1822 } else if (pp->bus == SYSFS_BUS_SCSI) {
1823 len = get_vpd_uid(pp);
1826 if (len <= 0 && pp->bus == SYSFS_BUS_SCSI)
1827 len = scsi_uid_fallback(pp, path_state, &origin);
1830 condlog(1, "%s: failed to get %s uid: %s",
1831 pp->dev, origin, strerror(-len));
1832 memset(pp->wwid, 0x0, WWID_SIZE);
1835 /* Strip any trailing blanks */
1836 c = strchr(pp->wwid, '\0');
1838 while (c && c >= pp->wwid && *c == ' ') {
1843 condlog(3, "%s: uid = %s (%s)", pp->dev,
1844 *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
1848 int pathinfo(struct path *pp, struct config *conf, int mask)
1853 return PATHINFO_FAILED;
1856 * For behavior backward-compatibility with multipathd,
1857 * the blacklisting by filter_property|devnode() is not
1858 * limited by DI_BLACKLIST and occurs before this debug
1859 * message with the mask value.
1862 const char *hidden =
1863 udev_device_get_sysattr_value(pp->udev, "hidden");
1865 if (hidden && !strcmp(hidden, "1")) {
1866 condlog(3, "%s: hidden", pp->dev);
1867 return PATHINFO_SKIPPED;
1869 if (is_claimed_by_foreign(pp->udev) ||
1870 filter_property(conf, pp->udev) > 0)
1871 return PATHINFO_SKIPPED;
1874 if (filter_devnode(conf->blist_devnode,
1875 conf->elist_devnode,
1877 return PATHINFO_SKIPPED;
1879 condlog(3, "%s: mask = 0x%x", pp->dev, mask);
1882 * Sanity check: we need the device number to
1883 * avoid inconsistent information in
1884 * find_path_by_dev()/find_path_by_devt()
1886 if (!strlen(pp->dev_t) && !(mask & DI_SYSFS)) {
1887 condlog(1, "%s: empty device number", pp->dev);
1892 * fetch info available in sysfs
1894 if (mask & DI_SYSFS && sysfs_pathinfo(pp, conf->hwtable))
1895 return PATHINFO_FAILED;
1897 if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
1898 if (filter_device(conf->blist_device, conf->elist_device,
1899 pp->vendor_id, pp->product_id, pp->dev) > 0 ||
1900 filter_protocol(conf->blist_protocol, conf->elist_protocol,
1902 return PATHINFO_SKIPPED;
1905 path_state = path_offline(pp);
1906 if (path_state == PATH_REMOVED)
1908 else if (mask & DI_NOIO) {
1910 * Avoid any IO on the device itself.
1911 * Behave like DI_CHECKER in the "path unavailable" case.
1913 pp->chkrstate = pp->state = path_state;
1918 * fetch info not available through sysfs
1921 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1924 condlog(4, "Couldn't open node for %s: %s",
1925 pp->dev, strerror(errno));
1929 if (mask & DI_SERIAL)
1932 if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1933 scsi_ioctl_pathinfo(pp, conf, mask))
1936 if (pp->bus == SYSFS_BUS_CCISS &&
1937 cciss_ioctl_pathinfo(pp, mask))
1940 if (mask & DI_CHECKER) {
1941 if (path_state == PATH_UP) {
1942 pp->chkrstate = pp->state = get_state(pp, conf, 0,
1944 if (pp->state == PATH_UNCHECKED ||
1945 pp->state == PATH_WILD)
1947 if (pp->state == PATH_TIMEOUT)
1948 pp->state = PATH_DOWN;
1949 if (pp->state == PATH_UP && !pp->size) {
1950 condlog(3, "%s: device size is 0, "
1951 "path unusable", pp->dev);
1952 pp->state = PATH_GHOST;
1955 condlog(3, "%s: path inaccessible", pp->dev);
1956 pp->chkrstate = pp->state = path_state;
1957 if (path_state == PATH_PENDING ||
1958 path_state == PATH_DOWN)
1963 if ((mask & DI_WWID) && !strlen(pp->wwid)) {
1964 get_uid(pp, path_state, pp->udev);
1965 if (!strlen(pp->wwid)) {
1966 pp->initialized = INIT_MISSING_UDEV;
1967 pp->tick = conf->retrigger_delay;
1974 if (mask & DI_BLACKLIST && mask & DI_WWID) {
1975 if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1976 pp->wwid, pp->dev) > 0) {
1977 return PATHINFO_SKIPPED;
1982 * Retrieve path priority, even for PATH_DOWN paths if it has never
1983 * been successfully obtained before.
1985 if ((mask & DI_PRIO) && path_state == PATH_UP && strlen(pp->wwid)) {
1986 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1991 if ((mask & DI_ALL) == DI_ALL)
1992 pp->initialized = INIT_OK;
1997 * Recoverable error, for example faulty or offline path
1999 memset(pp->wwid, 0, WWID_SIZE);
2000 pp->chkrstate = pp->state = PATH_DOWN;
2001 pp->initialized = INIT_FAILED;