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"
25 #include "sg_include.h"
27 #include "discovery.h"
32 store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
33 int flag, struct path **pp_ptr)
42 devname = udev_device_get_sysname(udevice);
51 if(safe_sprintf(pp->dev, "%s", devname)) {
52 condlog(0, "pp->dev too small");
55 pp->udev = udev_device_ref(udevice);
56 err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
60 err = store_path(pathvec, pp);
73 path_discover (vector pathvec, struct config * conf,
74 struct udev_device *udevice, int flag)
79 devname = udev_device_get_sysname(udevice);
83 if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
87 pp = find_path_by_dev(pathvec, (char *)devname);
89 if (store_pathinfo(pathvec, conf->hwtable,
90 udevice, flag, NULL) != 1)
95 return pathinfo(pp, conf->hwtable, flag);
99 path_discovery (vector pathvec, struct config * conf, int flag)
101 struct udev_enumerate *udev_iter;
102 struct udev_list_entry *entry;
103 struct udev_device *udevice;
107 udev_iter = udev_enumerate_new(conf->udev);
111 udev_enumerate_add_match_subsystem(udev_iter, "block");
112 udev_enumerate_scan_devices(udev_iter);
114 udev_list_entry_foreach(entry,
115 udev_enumerate_get_list_entry(udev_iter)) {
117 devpath = udev_list_entry_get_name(entry);
118 condlog(4, "Discover device %s", devpath);
119 udevice = udev_device_new_from_syspath(conf->udev, devpath);
121 condlog(4, "%s: no udev information", devpath);
125 devtype = udev_device_get_devtype(udevice);
126 if(devtype && !strncmp(devtype, "disk", 4))
127 r += path_discover(pathvec, conf, udevice, flag);
128 udev_device_unref(udevice);
130 udev_enumerate_unref(udev_iter);
131 condlog(4, "Discovery status %d", r);
135 #define declare_sysfs_get_str(fname) \
137 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len) \
140 const char * devname; \
142 devname = udev_device_get_sysname(udev); \
144 attr = udev_device_get_sysattr_value(udev, #fname); \
146 condlog(3, "%s: attribute %s not found in sysfs", \
150 if (strlen(attr) > len) { \
151 condlog(3, "%s: overflow in attribute %s", \
155 strlcpy(buff, attr, len); \
159 declare_sysfs_get_str(devtype);
160 declare_sysfs_get_str(cutype);
161 declare_sysfs_get_str(vendor);
162 declare_sysfs_get_str(model);
163 declare_sysfs_get_str(rev);
164 declare_sysfs_get_str(state);
165 declare_sysfs_get_str(dev);
168 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
170 const char *attr = NULL;
172 struct udev_device *parent;
176 if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
181 subsys = udev_device_get_subsystem(parent);
182 attr = udev_device_get_sysattr_value(parent, "timeout");
185 parent = udev_device_get_parent(parent);
188 condlog(3, "%s: No timeout value in sysfs", pp->dev);
192 r = sscanf(attr, "%u\n", &t);
195 condlog(3, "%s: Cannot parse timeout attribute '%s'",
206 sysfs_get_tgt_nodename (struct path *pp, char * node)
208 const char *targetid, *value;
209 struct udev_device *parent, *tgtdev;
211 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
215 value = udev_device_get_sysattr_value(parent, "sas_address");
217 strncpy(node, value, NODE_NAME_SIZE);
221 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
224 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_transport", udev_device_get_sysname(parent));
225 /* Check if it's FibreChannel */
229 value = udev_device_get_sysattr_value(tgtdev, "node_name");
231 strncpy(node, value, NODE_NAME_SIZE);
232 udev_device_unref(tgtdev);
236 udev_device_unref(tgtdev);
239 /* Check for iSCSI */
243 targetid = udev_device_get_sysname(parent);
244 if (!strncmp(targetid , "session", 6))
246 parent = udev_device_get_parent(parent);
250 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev, "iscsi_session", targetid);
254 value = udev_device_get_sysattr_value(tgtdev, "targetname");
256 strncpy(node, value, NODE_NAME_SIZE);
257 udev_device_unref(tgtdev);
261 udev_device_unref(tgtdev);
268 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
270 struct udev_device *parent = pp->udev;
271 struct udev_device *rport_dev = NULL;
273 const char *rport_id = NULL;
276 rport_id = udev_device_get_sysname(parent);
277 if (!strncmp(rport_id, "rport-", 6))
279 parent = udev_device_get_parent(parent);
282 if (!parent || !rport_id) {
283 condlog(0, "%s: rport id not found", pp->dev);
286 rport_dev = udev_device_new_from_subsystem_sysname(conf->udev, "fc_remote_ports", rport_id);
288 condlog(3, "%s: No fc_remote_port device for '%s'", pp->dev,
292 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
293 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
295 snprintf(value, 11, "%u", mpp->dev_loss);
297 sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, 11) <= 0) {
298 if ((mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET ||
299 mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
300 && mpp->dev_loss > 600) {
301 condlog(3, "%s: limiting dev_loss_tmo to 600, since "
302 "fast_io_fail is not set", mpp->alias);
303 snprintf(value, 11, "%u", 600);
304 if (sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
306 condlog(0, "%s failed to set dev_loss_tmo",
311 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET){
312 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
313 sprintf(value, "off");
314 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
317 snprintf(value, 11, "%u", mpp->fast_io_fail);
318 if (sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
320 condlog(0, "%s failed to set fast_io_fail_tmo",
325 udev_device_unref(rport_dev);
329 sysfs_set_scsi_tmo (struct multipath *mpp)
333 int dev_loss_tmo = mpp->dev_loss;
335 if (mpp->no_path_retry > 0) {
336 int no_path_retry_tmo = mpp->no_path_retry * conf->checkint;
338 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
339 no_path_retry_tmo = MAX_DEV_LOSS_TMO;
340 if (no_path_retry_tmo > dev_loss_tmo)
341 dev_loss_tmo = no_path_retry_tmo;
342 condlog(3, "%s: update dev_loss_tmo to %d",
343 mpp->alias, dev_loss_tmo);
344 } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
345 dev_loss_tmo = MAX_DEV_LOSS_TMO;
346 condlog(3, "%s: update dev_loss_tmo to %d",
347 mpp->alias, dev_loss_tmo);
349 mpp->dev_loss = dev_loss_tmo;
350 if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
351 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
352 mpp->alias, mpp->fast_io_fail);
353 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
355 if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
358 vector_foreach_slot(mpp->paths, pp, i) {
359 sysfs_set_rport_tmo(mpp, pp);
365 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
366 void *resp, int mx_resp_len)
368 unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
369 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
370 unsigned char sense_b[SENSE_BUFF_LEN];
371 struct sg_io_hdr io_hdr;
377 inqCmdBlk[2] = (unsigned char) pg_op;
378 inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
379 inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
380 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
381 memset(sense_b, 0, SENSE_BUFF_LEN);
382 io_hdr.interface_id = 'S';
383 io_hdr.cmd_len = sizeof (inqCmdBlk);
384 io_hdr.mx_sb_len = sizeof (sense_b);
385 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
386 io_hdr.dxfer_len = mx_resp_len;
387 io_hdr.dxferp = resp;
388 io_hdr.cmdp = inqCmdBlk;
389 io_hdr.sbp = sense_b;
390 io_hdr.timeout = DEF_TIMEOUT;
392 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
395 /* treat SG_ERR here to get rid of sg_err.[ch] */
396 io_hdr.status &= 0x7e;
397 if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
398 (0 == io_hdr.driver_status))
400 if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
401 (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
402 (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
403 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
405 unsigned char * sense_buffer = io_hdr.sbp;
406 if (sense_buffer[0] & 0x2)
407 sense_key = sense_buffer[1] & 0xf;
409 sense_key = sense_buffer[2] & 0xf;
410 if(RECOVERED_ERROR == sense_key)
418 get_serial (char * str, int maxlen, int fd)
421 char buff[MX_ALLOC_LEN + 1] = {0};
426 if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
431 memcpy(str, buff + 4, len);
440 get_geometry(struct path *pp)
445 if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
446 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
447 memset(&pp->geom, 0, sizeof(pp->geom));
450 condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
451 pp->dev, pp->geom.cylinders, pp->geom.heads,
452 pp->geom.sectors, pp->geom.start);
457 scsi_sysfs_pathinfo (struct path * pp)
459 struct udev_device *parent;
460 const char *attr_path = NULL;
464 const char *subsys = udev_device_get_subsystem(parent);
465 if (subsys && !strncmp(subsys, "scsi", 4)) {
466 attr_path = udev_device_get_sysname(parent);
469 if (sscanf(attr_path, "%i:%i:%i:%i",
473 &pp->sg_id.lun) == 4)
476 parent = udev_device_get_parent(parent);
478 if (!attr_path || pp->sg_id.host_no == -1)
481 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
484 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
486 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
489 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
491 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
494 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
497 * set the hwe configlet pointer
499 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
502 * host / bus / target / lun
504 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
514 if(!sysfs_get_tgt_nodename(pp, pp->tgt_node_name)) {
515 condlog(3, "%s: tgt_node_name = %s",
516 pp->dev, pp->tgt_node_name);
523 ccw_sysfs_pathinfo (struct path * pp)
525 struct udev_device *parent;
526 char attr_buff[NAME_SIZE];
527 const char *attr_path;
531 const char *subsys = udev_device_get_subsystem(parent);
532 if (subsys && !strncmp(subsys, "ccw", 3))
534 parent = udev_device_get_parent(parent);
539 sprintf(pp->vendor_id, "IBM");
541 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
543 if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE))
546 if (!strncmp(attr_buff, "3370", 4)) {
547 sprintf(pp->product_id,"S/390 DASD FBA");
548 } else if (!strncmp(attr_buff, "9336", 4)) {
549 sprintf(pp->product_id,"S/390 DASD FBA");
551 sprintf(pp->product_id,"S/390 DASD ECKD");
554 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
557 * set the hwe configlet pointer
559 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, NULL);
562 * host / bus / target / lun
564 attr_path = udev_device_get_sysname(parent);
566 sscanf(attr_path, "%i.%i.%x",
570 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
581 cciss_sysfs_pathinfo (struct path * pp)
583 const char * attr_path = NULL;
584 struct udev_device *parent;
588 const char *subsys = udev_device_get_subsystem(parent);
589 if (subsys && !strncmp(subsys, "cciss", 5)) {
590 attr_path = udev_device_get_sysname(parent);
593 if (sscanf(attr_path, "c%id%i",
595 &pp->sg_id.scsi_id) == 2)
598 parent = udev_device_get_parent(parent);
600 if (!attr_path || pp->sg_id.host_no == -1)
603 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
606 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
608 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
611 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
613 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
616 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
619 * set the hwe configlet pointer
621 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
624 * host / bus / target / lun
627 pp->sg_id.channel = 0;
628 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
638 common_sysfs_pathinfo (struct path * pp)
641 condlog(4, "%s: udev not initialised", pp->dev);
644 if (sysfs_get_dev(pp->udev, pp->dev_t, BLK_DEV_SIZE)) {
645 condlog(3, "%s: no 'dev' attribute in sysfs", pp->dev);
649 condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
651 if (sysfs_get_size(pp, &pp->size))
654 condlog(3, "%s: size = %llu", pp->dev, pp->size);
660 path_offline (struct path * pp)
662 struct udev_device * parent;
663 char buff[SCSI_STATE_SIZE];
665 if (pp->bus != SYSFS_BUS_SCSI)
670 const char *subsys = udev_device_get_subsystem(parent);
671 if (subsys && !strncmp(subsys, "scsi", 4))
673 parent = udev_device_get_parent(parent);
677 condlog(1, "%s: failed to get sysfs information", pp->dev);
681 if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
684 condlog(3, "%s: path state = %s", pp->dev, buff);
686 if (!strncmp(buff, "offline", 7)) {
691 if (!strncmp(buff, "blocked", 7))
693 else if (!strncmp(buff, "running", 7))
700 sysfs_pathinfo(struct path * pp)
702 if (common_sysfs_pathinfo(pp))
705 pp->bus = SYSFS_BUS_UNDEF;
706 if (!strncmp(pp->dev,"cciss",5))
707 pp->bus = SYSFS_BUS_CCISS;
708 if (!strncmp(pp->dev,"dasd", 4))
709 pp->bus = SYSFS_BUS_CCW;
710 if (!strncmp(pp->dev,"sd", 2))
711 pp->bus = SYSFS_BUS_SCSI;
713 if (pp->bus == SYSFS_BUS_UNDEF)
715 else if (pp->bus == SYSFS_BUS_SCSI) {
716 if (scsi_sysfs_pathinfo(pp))
718 } else if (pp->bus == SYSFS_BUS_CCW) {
719 if (ccw_sysfs_pathinfo(pp))
721 } else if (pp->bus == SYSFS_BUS_CCISS) {
722 if (cciss_sysfs_pathinfo(pp))
729 scsi_ioctl_pathinfo (struct path * pp, int mask)
731 if (mask & DI_SERIAL) {
732 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
733 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
740 cciss_ioctl_pathinfo (struct path * pp, int mask)
742 if (mask & DI_SERIAL) {
743 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
744 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
750 get_state (struct path * pp, int daemon)
752 struct checker * c = &pp->checker;
755 condlog(3, "%s: get_state", pp->dev);
757 if (!checker_selected(c)) {
759 if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
760 condlog(3, "%s: couldn't get sysfs pathinfo",
762 return PATH_UNCHECKED;
766 if (!checker_selected(c)) {
767 condlog(3, "%s: No checker selected", pp->dev);
768 return PATH_UNCHECKED;
770 checker_set_fd(c, pp->fd);
771 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
772 memset(c, 0x0, sizeof(struct checker));
773 condlog(3, "%s: checker init failed", pp->dev);
774 return PATH_UNCHECKED;
777 checker_clear_message(c);
779 checker_set_async(c);
780 if (!conf->checker_timeout &&
781 (pp->bus != SYSFS_BUS_SCSI ||
782 sysfs_get_timeout(pp, &(c->timeout))))
783 c->timeout = DEF_TIMEOUT;
784 state = checker_check(c);
785 condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
786 if (state != PATH_UP && strlen(checker_message(c)))
787 condlog(3, "%s: checker msg is \"%s\"",
788 pp->dev, checker_message(c));
793 get_prio (struct path * pp)
798 struct prio * p = &pp->prio;
800 if (!prio_selected(p)) {
801 select_detect_prio(pp);
803 if (!prio_selected(p)) {
804 condlog(3, "%s: no prio selected", pp->dev);
808 pp->priority = prio_getprio(p, pp);
809 if (pp->priority < 0) {
810 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
811 pp->priority = PRIO_UNDEF;
814 condlog(3, "%s: %s prio = %u",
815 pp->dev, prio_name(p), pp->priority);
820 get_uid (struct path * pp)
825 if (!pp->uid_attribute)
829 condlog(1, "%s: no udev information", pp->dev);
833 memset(pp->wwid, 0, WWID_SIZE);
834 value = udev_device_get_property_value(pp->udev, pp->uid_attribute);
835 if ((!value || strlen(value) == 0) && conf->dry_run == 2)
836 value = getenv(pp->uid_attribute);
837 if (value && strlen(value)) {
838 size_t len = WWID_SIZE;
840 if (strlen(value) + 1 > WWID_SIZE) {
841 condlog(0, "%s: wwid overflow", pp->dev);
845 strncpy(pp->wwid, value, len);
847 condlog(3, "%s: no %s attribute", pp->dev,
851 /* Strip any trailing blanks */
852 c = strchr(pp->wwid, '\0');
854 while (c && c >= pp->wwid && *c == ' ') {
858 condlog(3, "%s: uid = %s (udev)", pp->dev,
859 *pp->wwid == '\0' ? "<empty>" : pp->wwid);
864 pathinfo (struct path *pp, vector hwtable, int mask)
868 condlog(3, "%s: mask = 0x%x", pp->dev, mask);
871 * fetch info available in sysfs
873 if (mask & DI_SYSFS && sysfs_pathinfo(pp))
876 if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
877 if (filter_device(conf->blist_device, conf->elist_device,
878 pp->vendor_id, pp->product_id) > 0) {
883 path_state = path_offline(pp);
886 * fetch info not available through sysfs
889 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
892 condlog(4, "Couldn't open node for %s: %s",
893 pp->dev, strerror(errno));
897 if (mask & DI_SERIAL)
900 if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
901 scsi_ioctl_pathinfo(pp, mask))
904 if (pp->bus == SYSFS_BUS_CCISS &&
905 cciss_ioctl_pathinfo(pp, mask))
908 if (mask & DI_CHECKER) {
909 if (path_state == PATH_UP) {
910 pp->chkrstate = pp->state = get_state(pp, 0);
911 if (pp->state == PATH_UNCHECKED ||
912 pp->state == PATH_WILD)
915 condlog(3, "%s: path inaccessible", pp->dev);
916 pp->chkrstate = pp->state = path_state;
920 if (path_state == PATH_UP && (mask & DI_WWID) && !strlen(pp->wwid))
922 if (mask & DI_BLACKLIST && mask & DI_WWID) {
923 if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
930 * Retrieve path priority, even for PATH_DOWN paths if it has never
931 * been successfully obtained before.
933 if ((mask & DI_PRIO) && path_state == PATH_UP) {
934 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
935 if (!strlen(pp->wwid))
939 pp->priority = PRIO_UNDEF;
947 * Recoverable error, for example faulty or offline path
949 memset(pp->wwid, 0, WWID_SIZE);
950 pp->chkrstate = pp->state = PATH_DOWN;