2 * Copyright (c) 2004, 2005, 2006 Christophe Varoqui
3 * Copyright (c) 2005 Stefan Bader, IBM
4 * Copyright (c) 2005 Mike Anderson
22 #include "blacklist.h"
26 #include "sg_include.h"
28 #include "discovery.h"
33 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
34 int flag, struct path **pp_ptr)
43 devname = udev_device_get_sysname(udevice);
52 if(safe_sprintf(pp->dev, "%s", devname)) {
53 condlog(0, "pp->dev too small");
56 pp->udev = udev_device_ref(udevice);
57 err = pathinfo(pp, hwtable,
58 (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
62 err = store_path(pathvec, pp);
75 path_discover (vector pathvec, struct config * conf,
76 struct udev_device *udevice, int flag)
81 devname = udev_device_get_sysname(udevice);
85 if (filter_property(conf, udevice) > 0)
88 if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
92 pp = find_path_by_dev(pathvec, (char *)devname);
94 if (store_pathinfo(pathvec, conf->hwtable,
95 udevice, flag, NULL) != 1)
100 return pathinfo(pp, conf->hwtable, flag);
104 path_discovery (vector pathvec, struct config * conf, int flag)
106 struct udev_enumerate *udev_iter;
107 struct udev_list_entry *entry;
108 struct udev_device *udevice;
112 udev_iter = udev_enumerate_new(conf->udev);
116 udev_enumerate_add_match_subsystem(udev_iter, "block");
117 udev_enumerate_scan_devices(udev_iter);
119 udev_list_entry_foreach(entry,
120 udev_enumerate_get_list_entry(udev_iter)) {
122 devpath = udev_list_entry_get_name(entry);
123 condlog(4, "Discover device %s", devpath);
124 udevice = udev_device_new_from_syspath(conf->udev, devpath);
126 condlog(4, "%s: no udev information", devpath);
130 devtype = udev_device_get_devtype(udevice);
131 if(devtype && !strncmp(devtype, "disk", 4)) {
132 r += path_discover(pathvec, conf,
135 udev_device_unref(udevice);
137 udev_enumerate_unref(udev_iter);
138 condlog(4, "Discovery status %d", r);
142 #define declare_sysfs_get_str(fname) \
144 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len) \
147 const char * devname; \
149 devname = udev_device_get_sysname(udev); \
151 attr = udev_device_get_sysattr_value(udev, #fname); \
153 condlog(3, "%s: attribute %s not found in sysfs", \
157 if (strlen(attr) > len) { \
158 condlog(3, "%s: overflow in attribute %s", \
162 strlcpy(buff, attr, len); \
166 declare_sysfs_get_str(devtype);
167 declare_sysfs_get_str(cutype);
168 declare_sysfs_get_str(vendor);
169 declare_sysfs_get_str(model);
170 declare_sysfs_get_str(rev);
171 declare_sysfs_get_str(dev);
174 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
176 const char *attr = NULL;
178 struct udev_device *parent;
182 if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
187 subsys = udev_device_get_subsystem(parent);
188 attr = udev_device_get_sysattr_value(parent, "timeout");
191 parent = udev_device_get_parent(parent);
194 condlog(3, "%s: No timeout value in sysfs", pp->dev);
198 r = sscanf(attr, "%u\n", &t);
201 condlog(3, "%s: Cannot parse timeout attribute '%s'",
212 sysfs_get_tgt_nodename (struct path *pp, char * node)
214 const char *tgtname, *value;
215 struct udev_device *parent, *tgtdev;
216 int host, channel, tgtid = -1;
218 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
222 value = udev_device_get_sysattr_value(parent, "sas_address");
224 tgtdev = udev_device_get_parent(parent);
226 tgtname = udev_device_get_sysname(tgtdev);
227 if (sscanf(tgtname, "end_device-%d:%d",
230 tgtdev = udev_device_get_parent(tgtdev);
234 pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
235 pp->sg_id.transport_id = tgtid;
236 strncpy(node, value, NODE_NAME_SIZE);
241 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
244 /* Check for FibreChannel */
245 tgtdev = udev_device_get_parent(parent);
246 value = udev_device_get_sysname(tgtdev);
247 if (sscanf(value, "rport-%d:%d-%d",
248 &host, &channel, &tgtid) == 3) {
249 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
250 "fc_remote_ports", value);
252 condlog(3, "SCSI target %d:%d:%d -> "
254 pp->sg_id.host_no, pp->sg_id.channel,
255 pp->sg_id.scsi_id, host, channel,
257 value = udev_device_get_sysattr_value(tgtdev,
260 pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
261 pp->sg_id.transport_id = tgtid;
262 strncpy(node, value, NODE_NAME_SIZE);
263 udev_device_unref(tgtdev);
266 udev_device_unref(tgtdev);
270 /* Check for iSCSI */
274 tgtname = udev_device_get_sysname(parent);
275 if (tgtname && sscanf(tgtname , "session%d", &tgtid) == 1)
277 parent = udev_device_get_parent(parent);
281 if (parent && tgtname) {
282 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
283 "iscsi_session", tgtname);
287 value = udev_device_get_sysattr_value(tgtdev, "tgtname");
289 pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
290 pp->sg_id.transport_id = tgtid;
291 strncpy(node, value, NODE_NAME_SIZE);
292 udev_device_unref(tgtdev);
296 udev_device_unref(tgtdev);
299 /* Check for libata */
303 tgtname = udev_device_get_sysname(parent);
304 if (tgtname && sscanf(tgtname, "ata%d", &tgtid) == 1)
306 parent = udev_device_get_parent(parent);
310 pp->sg_id.proto_id = SCSI_PROTOCOL_ATA;
311 pp->sg_id.transport_id = tgtid;
312 snprintf(node, NODE_NAME_SIZE, "ata-%d.00", tgtid);
315 pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
320 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
322 struct udev_device *rport_dev = NULL;
325 unsigned long long tmo = 0;
328 sprintf(rport_id, "rport-%d:%d-%d",
329 pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
330 rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
331 "fc_remote_ports", rport_id);
333 condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
337 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
338 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
342 * dev_loss_tmo will be limited to 600 if fast_io_fail
344 * fast_io_fail will be limited by the current dev_loss_tmo
346 * So to get everything right we first need to increase
347 * dev_loss_tmo to the fast_io_fail setting (if present),
348 * then set fast_io_fail, and _then_ set dev_loss_tmo
349 * to the correct value.
351 memset(value, 0, 16);
352 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET &&
353 mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO &&
354 mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) {
355 /* Check if we need to temporarily increase dev_loss_tmo */
356 ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
359 condlog(0, "%s: failed to read dev_loss_tmo value, "
360 "error %d", rport_id, -ret);
363 if (sscanf(value, "%llu\n", &tmo) != 1) {
364 condlog(0, "%s: Cannot parse dev_loss_tmo "
365 "attribute '%s'", rport_id, value);
368 if (mpp->fast_io_fail >= tmo) {
369 snprintf(value, 16, "%u", mpp->fast_io_fail);
371 } else if (mpp->dev_loss > 600) {
372 condlog(3, "%s: limiting dev_loss_tmo to 600, since "
373 "fast_io_fail is not set", rport_id);
374 snprintf(value, 16, "%u", 600);
376 snprintf(value, 16, "%u", mpp->dev_loss);
379 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
380 value, strlen(value));
383 condlog(3, "%s: rport blocked", rport_id);
385 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
386 rport_id, value, -ret);
390 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
391 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
392 sprintf(value, "off");
393 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
396 snprintf(value, 16, "%u", mpp->fast_io_fail);
397 ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
398 value, strlen(value));
401 condlog(3, "%s: rport blocked", rport_id);
403 condlog(0, "%s: failed to set fast_io_fail_tmo to %s, error %d",
404 rport_id, value, -ret);
408 snprintf(value, 16, "%u", mpp->dev_loss);
409 ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
410 value, strlen(value));
413 condlog(3, "%s: rport blocked", rport_id);
415 condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
416 rport_id, value, -ret);
420 udev_device_unref(rport_dev);
424 sysfs_set_session_tmo(struct multipath *mpp, struct path *pp)
426 struct udev_device *session_dev = NULL;
430 sprintf(session_id, "session%d", pp->sg_id.transport_id);
431 session_dev = udev_device_new_from_subsystem_sysname(conf->udev,
432 "iscsi_session", session_id);
434 condlog(1, "%s: No iscsi session for '%s'", pp->dev,
438 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
439 pp->sg_id.channel, pp->sg_id.scsi_id, session_id);
442 condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev);
444 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
445 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) {
446 condlog(3, "%s: can't switch off fast_io_fail_tmo "
447 "on iSCSI", pp->dev);
448 } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) {
449 condlog(3, "%s: can't set fast_io_fail_tmo to '0'"
450 "on iSCSI", pp->dev);
452 snprintf(value, 11, "%u", mpp->fast_io_fail);
453 if (sysfs_attr_set_value(session_dev, "recovery_tmo",
455 condlog(3, "%s: Failed to set recovery_tmo, "
456 " error %d", pp->dev, errno);
460 udev_device_unref(session_dev);
465 sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp)
467 struct udev_device *sas_dev = NULL;
471 sprintf(end_dev_id, "end_device-%d:%d",
472 pp->sg_id.host_no, pp->sg_id.transport_id);
473 sas_dev = udev_device_new_from_subsystem_sysname(conf->udev,
474 "sas_end_device", end_dev_id);
476 condlog(1, "%s: No SAS end device for '%s'", pp->dev,
480 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
481 pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id);
484 snprintf(value, 11, "%u", mpp->dev_loss);
485 if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout",
487 condlog(3, "%s: failed to update "
488 "I_T Nexus loss timeout, error %d",
491 udev_device_unref(sas_dev);
496 sysfs_set_scsi_tmo (struct multipath *mpp)
500 int dev_loss_tmo = mpp->dev_loss;
502 if (mpp->no_path_retry > 0) {
503 int no_path_retry_tmo = mpp->no_path_retry * conf->checkint;
505 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
506 no_path_retry_tmo = MAX_DEV_LOSS_TMO;
507 if (no_path_retry_tmo > dev_loss_tmo)
508 dev_loss_tmo = no_path_retry_tmo;
509 condlog(3, "%s: update dev_loss_tmo to %d",
510 mpp->alias, dev_loss_tmo);
511 } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
512 dev_loss_tmo = MAX_DEV_LOSS_TMO;
513 condlog(3, "%s: update dev_loss_tmo to %d",
514 mpp->alias, dev_loss_tmo);
516 mpp->dev_loss = dev_loss_tmo;
517 if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
518 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
519 mpp->alias, mpp->fast_io_fail);
520 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
522 if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
525 vector_foreach_slot(mpp->paths, pp, i) {
526 if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
527 sysfs_set_rport_tmo(mpp, pp);
528 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
529 sysfs_set_session_tmo(mpp, pp);
530 if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
531 sysfs_set_nexus_loss_tmo(mpp, pp);
537 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
538 void *resp, int mx_resp_len)
540 unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
541 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
542 unsigned char sense_b[SENSE_BUFF_LEN];
543 struct sg_io_hdr io_hdr;
549 inqCmdBlk[2] = (unsigned char) pg_op;
550 inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
551 inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
552 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
553 memset(sense_b, 0, SENSE_BUFF_LEN);
554 io_hdr.interface_id = 'S';
555 io_hdr.cmd_len = sizeof (inqCmdBlk);
556 io_hdr.mx_sb_len = sizeof (sense_b);
557 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
558 io_hdr.dxfer_len = mx_resp_len;
559 io_hdr.dxferp = resp;
560 io_hdr.cmdp = inqCmdBlk;
561 io_hdr.sbp = sense_b;
562 io_hdr.timeout = DEF_TIMEOUT;
564 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
567 /* treat SG_ERR here to get rid of sg_err.[ch] */
568 io_hdr.status &= 0x7e;
569 if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
570 (0 == io_hdr.driver_status))
572 if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
573 (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
574 (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
575 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
577 unsigned char * sense_buffer = io_hdr.sbp;
578 if (sense_buffer[0] & 0x2)
579 sense_key = sense_buffer[1] & 0xf;
581 sense_key = sense_buffer[2] & 0xf;
582 if(RECOVERED_ERROR == sense_key)
590 get_serial (char * str, int maxlen, int fd)
593 char buff[MX_ALLOC_LEN + 1] = {0};
598 if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
603 memcpy(str, buff + 4, len);
612 get_geometry(struct path *pp)
617 if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
618 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
619 memset(&pp->geom, 0, sizeof(pp->geom));
622 condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
623 pp->dev, pp->geom.cylinders, pp->geom.heads,
624 pp->geom.sectors, pp->geom.start);
629 scsi_sysfs_pathinfo (struct path * pp)
631 struct udev_device *parent;
632 const char *attr_path = NULL;
636 const char *subsys = udev_device_get_subsystem(parent);
637 if (subsys && !strncmp(subsys, "scsi", 4)) {
638 attr_path = udev_device_get_sysname(parent);
641 if (sscanf(attr_path, "%i:%i:%i:%i",
645 &pp->sg_id.lun) == 4)
648 parent = udev_device_get_parent(parent);
650 if (!attr_path || pp->sg_id.host_no == -1)
653 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
656 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
658 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
661 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
663 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
666 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
669 * set the hwe configlet pointer
671 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
674 * host / bus / target / lun
676 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
686 if(!sysfs_get_tgt_nodename(pp, pp->tgt_node_name)) {
687 condlog(3, "%s: tgt_node_name = %s",
688 pp->dev, pp->tgt_node_name);
695 ccw_sysfs_pathinfo (struct path * pp)
697 struct udev_device *parent;
698 char attr_buff[NAME_SIZE];
699 const char *attr_path;
703 const char *subsys = udev_device_get_subsystem(parent);
704 if (subsys && !strncmp(subsys, "ccw", 3))
706 parent = udev_device_get_parent(parent);
711 sprintf(pp->vendor_id, "IBM");
713 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
715 if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE))
718 if (!strncmp(attr_buff, "3370", 4)) {
719 sprintf(pp->product_id,"S/390 DASD FBA");
720 } else if (!strncmp(attr_buff, "9336", 4)) {
721 sprintf(pp->product_id,"S/390 DASD FBA");
723 sprintf(pp->product_id,"S/390 DASD ECKD");
726 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
729 * set the hwe configlet pointer
731 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, NULL);
734 * host / bus / target / lun
736 attr_path = udev_device_get_sysname(parent);
738 sscanf(attr_path, "%i.%i.%x",
742 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
753 cciss_sysfs_pathinfo (struct path * pp)
755 const char * attr_path = NULL;
756 struct udev_device *parent;
760 const char *subsys = udev_device_get_subsystem(parent);
761 if (subsys && !strncmp(subsys, "cciss", 5)) {
762 attr_path = udev_device_get_sysname(parent);
765 if (sscanf(attr_path, "c%id%i",
767 &pp->sg_id.scsi_id) == 2)
770 parent = udev_device_get_parent(parent);
772 if (!attr_path || pp->sg_id.host_no == -1)
775 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
778 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
780 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
783 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
785 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
788 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
791 * set the hwe configlet pointer
793 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
796 * host / bus / target / lun
799 pp->sg_id.channel = 0;
800 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
810 common_sysfs_pathinfo (struct path * pp)
816 condlog(4, "%s: udev not initialised", pp->dev);
819 if (sysfs_get_dev(pp->udev, pp->dev_t, BLK_DEV_SIZE)) {
820 condlog(3, "%s: no 'dev' attribute in sysfs", pp->dev);
824 condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
826 if (sysfs_get_size(pp, &pp->size))
829 condlog(3, "%s: size = %llu", pp->dev, pp->size);
835 path_offline (struct path * pp)
837 struct udev_device * parent;
838 char buff[SCSI_STATE_SIZE];
840 if (pp->bus != SYSFS_BUS_SCSI)
845 const char *subsys = udev_device_get_subsystem(parent);
846 if (subsys && !strncmp(subsys, "scsi", 4))
848 parent = udev_device_get_parent(parent);
852 condlog(1, "%s: failed to get sysfs information", pp->dev);
856 memset(buff, 0x0, SCSI_STATE_SIZE);
857 if (sysfs_attr_get_value(parent, "state", buff, SCSI_STATE_SIZE) <= 0)
860 condlog(3, "%s: path state = %s", pp->dev, buff);
862 if (!strncmp(buff, "offline", 7) ||
863 !strncmp(buff, "quiesce", 7) ||
864 !strncmp(buff, "transport-offline", 17)) {
869 if (!strncmp(buff, "blocked", 7) || !strncmp(buff, "quiesce", 7))
871 else if (!strncmp(buff, "running", 7))
878 sysfs_pathinfo(struct path * pp)
880 if (common_sysfs_pathinfo(pp))
883 pp->bus = SYSFS_BUS_UNDEF;
884 if (!strncmp(pp->dev,"cciss",5))
885 pp->bus = SYSFS_BUS_CCISS;
886 if (!strncmp(pp->dev,"dasd", 4))
887 pp->bus = SYSFS_BUS_CCW;
888 if (!strncmp(pp->dev,"sd", 2))
889 pp->bus = SYSFS_BUS_SCSI;
891 if (pp->bus == SYSFS_BUS_UNDEF)
893 else if (pp->bus == SYSFS_BUS_SCSI) {
894 if (scsi_sysfs_pathinfo(pp))
896 } else if (pp->bus == SYSFS_BUS_CCW) {
897 if (ccw_sysfs_pathinfo(pp))
899 } else if (pp->bus == SYSFS_BUS_CCISS) {
900 if (cciss_sysfs_pathinfo(pp))
907 scsi_ioctl_pathinfo (struct path * pp, int mask)
909 if (mask & DI_SERIAL) {
910 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
911 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
918 cciss_ioctl_pathinfo (struct path * pp, int mask)
920 if (mask & DI_SERIAL) {
921 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
922 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
928 get_state (struct path * pp, int daemon)
930 struct checker * c = &pp->checker;
933 condlog(3, "%s: get_state", pp->dev);
935 if (!checker_selected(c)) {
937 if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
938 condlog(3, "%s: couldn't get sysfs pathinfo",
940 return PATH_UNCHECKED;
944 if (!checker_selected(c)) {
945 condlog(3, "%s: No checker selected", pp->dev);
946 return PATH_UNCHECKED;
948 checker_set_fd(c, pp->fd);
949 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
950 memset(c, 0x0, sizeof(struct checker));
951 condlog(3, "%s: checker init failed", pp->dev);
952 return PATH_UNCHECKED;
955 checker_clear_message(c);
957 checker_set_async(c);
958 if (!conf->checker_timeout &&
959 (pp->bus != SYSFS_BUS_SCSI ||
960 sysfs_get_timeout(pp, &(c->timeout))))
961 c->timeout = DEF_TIMEOUT;
962 state = checker_check(c);
963 condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
964 if (state != PATH_UP && state != PATH_GHOST &&
965 strlen(checker_message(c)))
966 condlog(3, "%s: checker msg is \"%s\"",
967 pp->dev, checker_message(c));
972 get_prio (struct path * pp)
977 struct prio * p = &pp->prio;
979 if (!prio_selected(p)) {
980 select_detect_prio(pp);
982 if (!prio_selected(p)) {
983 condlog(3, "%s: no prio selected", pp->dev);
984 pp->priority = PRIO_UNDEF;
988 pp->priority = prio_getprio(p, pp);
989 if (pp->priority < 0) {
990 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
991 pp->priority = PRIO_UNDEF;
994 condlog(3, "%s: %s prio = %u",
995 pp->dev, prio_name(p), pp->priority);
1000 get_uid (struct path * pp)
1005 if (!pp->uid_attribute && !pp->getuid)
1009 condlog(1, "%s: no udev information", pp->dev);
1013 memset(pp->wwid, 0, WWID_SIZE);
1015 char buff[CALLOUT_MAX_SIZE];
1017 /* Use 'getuid' callout, deprecated */
1018 condlog(1, "%s: using deprecated getuid callout", pp->dev);
1019 if (apply_format(pp->getuid, &buff[0], pp)) {
1020 condlog(0, "error formatting uid callout command");
1021 memset(pp->wwid, 0, WWID_SIZE);
1022 } else if (execute_program(buff, pp->wwid, WWID_SIZE)) {
1023 condlog(3, "error calling out %s", buff);
1024 memset(pp->wwid, 0, WWID_SIZE);
1030 value = udev_device_get_property_value(pp->udev,
1032 if ((!value || strlen(value) == 0) && conf->dry_run == 2)
1033 value = getenv(pp->uid_attribute);
1034 if (value && strlen(value)) {
1035 size_t len = WWID_SIZE;
1037 if (strlen(value) + 1 > WWID_SIZE) {
1038 condlog(0, "%s: wwid overflow", pp->dev);
1040 len = strlen(value);
1042 strncpy(pp->wwid, value, len);
1044 condlog(3, "%s: no %s attribute", pp->dev,
1049 /* Strip any trailing blanks */
1050 c = strchr(pp->wwid, '\0');
1052 while (c && c >= pp->wwid && *c == ' ') {
1056 condlog(3, "%s: uid = %s (%s)", pp->dev,
1057 *pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
1062 pathinfo (struct path *pp, vector hwtable, int mask)
1069 condlog(3, "%s: mask = 0x%x", pp->dev, mask);
1072 * fetch info available in sysfs
1074 if (mask & DI_SYSFS && sysfs_pathinfo(pp))
1077 if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
1078 if (filter_device(conf->blist_device, conf->elist_device,
1079 pp->vendor_id, pp->product_id) > 0) {
1084 path_state = path_offline(pp);
1087 * fetch info not available through sysfs
1090 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1093 condlog(4, "Couldn't open node for %s: %s",
1094 pp->dev, strerror(errno));
1098 if (mask & DI_SERIAL)
1101 if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1102 scsi_ioctl_pathinfo(pp, mask))
1105 if (pp->bus == SYSFS_BUS_CCISS &&
1106 cciss_ioctl_pathinfo(pp, mask))
1109 if (mask & DI_CHECKER) {
1110 if (path_state == PATH_UP) {
1111 pp->chkrstate = pp->state = get_state(pp, 0);
1112 if (pp->state == PATH_UNCHECKED ||
1113 pp->state == PATH_WILD)
1115 if (pp->state == PATH_TIMEOUT)
1116 pp->state = PATH_DOWN;
1118 condlog(3, "%s: path inaccessible", pp->dev);
1119 pp->chkrstate = pp->state = path_state;
1123 if ((mask & DI_WWID) && !strlen(pp->wwid))
1125 if (mask & DI_BLACKLIST && mask & DI_WWID) {
1126 if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1133 * Retrieve path priority, even for PATH_DOWN paths if it has never
1134 * been successfully obtained before.
1136 if ((mask & DI_PRIO) && path_state == PATH_UP) {
1137 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1138 if (!strlen(pp->wwid))
1142 pp->priority = PRIO_UNDEF;
1150 * Recoverable error, for example faulty or offline path
1152 memset(pp->wwid, 0, WWID_SIZE);
1153 pp->chkrstate = pp->state = PATH_DOWN;