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,
57 (conf->dry_run == 3)? flag : (flag | DI_BLACKLIST));
61 err = store_path(pathvec, pp);
74 path_discover (vector pathvec, struct config * conf,
75 struct udev_device *udevice, int flag)
80 devname = udev_device_get_sysname(udevice);
84 if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
88 pp = find_path_by_dev(pathvec, (char *)devname);
90 if (store_pathinfo(pathvec, conf->hwtable,
91 udevice, flag, NULL) != 1)
96 return pathinfo(pp, conf->hwtable, flag);
100 path_discovery (vector pathvec, struct config * conf, int flag)
102 struct udev_enumerate *udev_iter;
103 struct udev_list_entry *entry;
104 struct udev_device *udevice;
108 udev_iter = udev_enumerate_new(conf->udev);
112 udev_enumerate_add_match_subsystem(udev_iter, "block");
113 udev_enumerate_scan_devices(udev_iter);
115 udev_list_entry_foreach(entry,
116 udev_enumerate_get_list_entry(udev_iter)) {
118 devpath = udev_list_entry_get_name(entry);
119 condlog(4, "Discover device %s", devpath);
120 udevice = udev_device_new_from_syspath(conf->udev, devpath);
122 condlog(4, "%s: no udev information", devpath);
126 devtype = udev_device_get_devtype(udevice);
127 if(devtype && !strncmp(devtype, "disk", 4))
128 r += path_discover(pathvec, conf, udevice, flag);
129 udev_device_unref(udevice);
131 udev_enumerate_unref(udev_iter);
132 condlog(4, "Discovery status %d", r);
136 #define declare_sysfs_get_str(fname) \
138 sysfs_get_##fname (struct udev_device * udev, char * buff, size_t len) \
141 const char * devname; \
143 devname = udev_device_get_sysname(udev); \
145 attr = udev_device_get_sysattr_value(udev, #fname); \
147 condlog(3, "%s: attribute %s not found in sysfs", \
151 if (strlen(attr) > len) { \
152 condlog(3, "%s: overflow in attribute %s", \
156 strlcpy(buff, attr, len); \
160 declare_sysfs_get_str(devtype);
161 declare_sysfs_get_str(cutype);
162 declare_sysfs_get_str(vendor);
163 declare_sysfs_get_str(model);
164 declare_sysfs_get_str(rev);
165 declare_sysfs_get_str(state);
166 declare_sysfs_get_str(dev);
169 sysfs_get_timeout(struct path *pp, unsigned int *timeout)
171 const char *attr = NULL;
173 struct udev_device *parent;
177 if (!pp->udev || pp->bus != SYSFS_BUS_SCSI)
182 subsys = udev_device_get_subsystem(parent);
183 attr = udev_device_get_sysattr_value(parent, "timeout");
186 parent = udev_device_get_parent(parent);
189 condlog(3, "%s: No timeout value in sysfs", pp->dev);
193 r = sscanf(attr, "%u\n", &t);
196 condlog(3, "%s: Cannot parse timeout attribute '%s'",
207 sysfs_get_tgt_nodename (struct path *pp, char * node)
209 const char *tgtname, *value;
210 struct udev_device *parent, *tgtdev;
211 int host, channel, tgtid = -1;
213 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_device");
217 value = udev_device_get_sysattr_value(parent, "sas_address");
219 tgtdev = udev_device_get_parent(parent);
221 tgtname = udev_device_get_sysname(tgtdev);
222 if (sscanf(tgtname, "end_device-%d:%d",
225 tgtdev = udev_device_get_parent(tgtdev);
229 pp->sg_id.proto_id = SCSI_PROTOCOL_SAS;
230 pp->sg_id.transport_id = tgtid;
231 strncpy(node, value, NODE_NAME_SIZE);
236 parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "scsi", "scsi_target");
239 /* Check for FibreChannel */
240 tgtdev = udev_device_get_parent(parent);
241 value = udev_device_get_sysname(tgtdev);
242 if (sscanf(value, "rport-%d:%d-%d",
243 &host, &channel, &tgtid) == 3) {
244 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
245 "fc_remote_ports", value);
247 condlog(3, "SCSI target %d:%d:%d -> "
249 pp->sg_id.host_no, pp->sg_id.channel,
250 pp->sg_id.scsi_id, host, channel,
252 value = udev_device_get_sysattr_value(tgtdev,
255 pp->sg_id.proto_id = SCSI_PROTOCOL_FCP;
256 pp->sg_id.transport_id = tgtid;
257 strncpy(node, value, NODE_NAME_SIZE);
258 udev_device_unref(tgtdev);
261 udev_device_unref(tgtdev);
265 /* Check for iSCSI */
269 tgtname = udev_device_get_sysname(parent);
270 if (tgtname && sscanf(tgtname , "session%d", &tgtid) == 1)
272 parent = udev_device_get_parent(parent);
276 if (parent && tgtname) {
277 tgtdev = udev_device_new_from_subsystem_sysname(conf->udev,
278 "iscsi_session", tgtname);
282 value = udev_device_get_sysattr_value(tgtdev, "tgtname");
284 pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI;
285 pp->sg_id.transport_id = tgtid;
286 strncpy(node, value, NODE_NAME_SIZE);
287 udev_device_unref(tgtdev);
291 udev_device_unref(tgtdev);
294 /* Check for libata */
298 tgtname = udev_device_get_sysname(parent);
299 if (tgtname && sscanf(tgtname, "ata%d", &tgtid) == 1)
301 parent = udev_device_get_parent(parent);
305 pp->sg_id.proto_id = SCSI_PROTOCOL_ATA;
306 pp->sg_id.transport_id = tgtid;
307 snprintf(node, NODE_NAME_SIZE, "ata-%d.00", tgtid);
310 pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC;
315 sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
317 struct udev_device *rport_dev = NULL;
321 sprintf(rport_id, "rport-%d:%d-%d",
322 pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id);
323 rport_dev = udev_device_new_from_subsystem_sysname(conf->udev,
324 "fc_remote_ports", rport_id);
326 condlog(1, "%s: No fc_remote_port device for '%s'", pp->dev,
330 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
331 pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
333 snprintf(value, 11, "%u", mpp->dev_loss);
335 sysfs_attr_set_value(rport_dev, "dev_loss_tmo", value, 11) <= 0) {
336 if ((mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET ||
337 mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
338 && mpp->dev_loss > 600) {
339 condlog(3, "%s: limiting dev_loss_tmo to 600, since "
340 "fast_io_fail is not set", mpp->alias);
341 snprintf(value, 11, "%u", 600);
342 if (sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
344 condlog(0, "%s failed to set dev_loss_tmo",
349 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET){
350 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
351 sprintf(value, "off");
352 else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
355 snprintf(value, 11, "%u", mpp->fast_io_fail);
356 if (sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo",
358 condlog(0, "%s failed to set fast_io_fail_tmo",
363 udev_device_unref(rport_dev);
367 sysfs_set_session_tmo(struct multipath *mpp, struct path *pp)
369 struct udev_device *session_dev = NULL;
373 sprintf(session_id, "session%d", pp->sg_id.transport_id);
374 session_dev = udev_device_new_from_subsystem_sysname(conf->udev,
375 "iscsi_session", session_id);
377 condlog(1, "%s: No iscsi session for '%s'", pp->dev,
381 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
382 pp->sg_id.channel, pp->sg_id.scsi_id, session_id);
385 condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev);
387 if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
388 if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) {
389 condlog(3, "%s: can't switch off fast_io_fail_tmo "
390 "on iSCSI", pp->dev);
391 } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) {
392 condlog(3, "%s: can't set fast_io_fail_tmo to '0'"
393 "on iSCSI", pp->dev);
395 snprintf(value, 11, "%u", mpp->fast_io_fail);
396 if (sysfs_attr_set_value(session_dev, "recovery_tmo",
398 condlog(3, "%s: Failed to set recovery_tmo, "
399 " error %d", pp->dev, errno);
403 udev_device_unref(session_dev);
408 sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp)
410 struct udev_device *sas_dev = NULL;
414 sprintf(end_dev_id, "end_device-%d:%d",
415 pp->sg_id.host_no, pp->sg_id.transport_id);
416 sas_dev = udev_device_new_from_subsystem_sysname(conf->udev,
417 "sas_end_device", end_dev_id);
419 condlog(1, "%s: No SAS end device for '%s'", pp->dev,
423 condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no,
424 pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id);
427 snprintf(value, 11, "%u", mpp->dev_loss);
428 if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout",
430 condlog(3, "%s: failed to update "
431 "I_T Nexus loss timeout, error %d",
434 udev_device_unref(sas_dev);
439 sysfs_set_scsi_tmo (struct multipath *mpp)
443 int dev_loss_tmo = mpp->dev_loss;
445 if (mpp->no_path_retry > 0) {
446 int no_path_retry_tmo = mpp->no_path_retry * conf->checkint;
448 if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
449 no_path_retry_tmo = MAX_DEV_LOSS_TMO;
450 if (no_path_retry_tmo > dev_loss_tmo)
451 dev_loss_tmo = no_path_retry_tmo;
452 condlog(3, "%s: update dev_loss_tmo to %d",
453 mpp->alias, dev_loss_tmo);
454 } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
455 dev_loss_tmo = MAX_DEV_LOSS_TMO;
456 condlog(3, "%s: update dev_loss_tmo to %d",
457 mpp->alias, dev_loss_tmo);
459 mpp->dev_loss = dev_loss_tmo;
460 if (mpp->dev_loss && mpp->fast_io_fail >= (int)mpp->dev_loss) {
461 condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)",
462 mpp->alias, mpp->fast_io_fail);
463 mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
465 if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
468 vector_foreach_slot(mpp->paths, pp, i) {
469 if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
470 sysfs_set_rport_tmo(mpp, pp);
471 if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
472 sysfs_set_session_tmo(mpp, pp);
473 if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
474 sysfs_set_nexus_loss_tmo(mpp, pp);
480 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
481 void *resp, int mx_resp_len)
483 unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
484 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
485 unsigned char sense_b[SENSE_BUFF_LEN];
486 struct sg_io_hdr io_hdr;
492 inqCmdBlk[2] = (unsigned char) pg_op;
493 inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
494 inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
495 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
496 memset(sense_b, 0, SENSE_BUFF_LEN);
497 io_hdr.interface_id = 'S';
498 io_hdr.cmd_len = sizeof (inqCmdBlk);
499 io_hdr.mx_sb_len = sizeof (sense_b);
500 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
501 io_hdr.dxfer_len = mx_resp_len;
502 io_hdr.dxferp = resp;
503 io_hdr.cmdp = inqCmdBlk;
504 io_hdr.sbp = sense_b;
505 io_hdr.timeout = DEF_TIMEOUT;
507 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
510 /* treat SG_ERR here to get rid of sg_err.[ch] */
511 io_hdr.status &= 0x7e;
512 if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
513 (0 == io_hdr.driver_status))
515 if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
516 (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
517 (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
518 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
520 unsigned char * sense_buffer = io_hdr.sbp;
521 if (sense_buffer[0] & 0x2)
522 sense_key = sense_buffer[1] & 0xf;
524 sense_key = sense_buffer[2] & 0xf;
525 if(RECOVERED_ERROR == sense_key)
533 get_serial (char * str, int maxlen, int fd)
536 char buff[MX_ALLOC_LEN + 1] = {0};
541 if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN)) {
546 memcpy(str, buff + 4, len);
555 get_geometry(struct path *pp)
560 if (ioctl(pp->fd, HDIO_GETGEO, &pp->geom)) {
561 condlog(2, "%s: HDIO_GETGEO failed with %d", pp->dev, errno);
562 memset(&pp->geom, 0, sizeof(pp->geom));
565 condlog(3, "%s: %u cyl, %u heads, %u sectors/track, start at %lu",
566 pp->dev, pp->geom.cylinders, pp->geom.heads,
567 pp->geom.sectors, pp->geom.start);
572 scsi_sysfs_pathinfo (struct path * pp)
574 struct udev_device *parent;
575 const char *attr_path = NULL;
579 const char *subsys = udev_device_get_subsystem(parent);
580 if (subsys && !strncmp(subsys, "scsi", 4)) {
581 attr_path = udev_device_get_sysname(parent);
584 if (sscanf(attr_path, "%i:%i:%i:%i",
588 &pp->sg_id.lun) == 4)
591 parent = udev_device_get_parent(parent);
593 if (!attr_path || pp->sg_id.host_no == -1)
596 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
599 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
601 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
604 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
606 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
609 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
612 * set the hwe configlet pointer
614 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
617 * host / bus / target / lun
619 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
629 if(!sysfs_get_tgt_nodename(pp, pp->tgt_node_name)) {
630 condlog(3, "%s: tgt_node_name = %s",
631 pp->dev, pp->tgt_node_name);
638 ccw_sysfs_pathinfo (struct path * pp)
640 struct udev_device *parent;
641 char attr_buff[NAME_SIZE];
642 const char *attr_path;
646 const char *subsys = udev_device_get_subsystem(parent);
647 if (subsys && !strncmp(subsys, "ccw", 3))
649 parent = udev_device_get_parent(parent);
654 sprintf(pp->vendor_id, "IBM");
656 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
658 if (sysfs_get_devtype(parent, attr_buff, FILE_NAME_SIZE))
661 if (!strncmp(attr_buff, "3370", 4)) {
662 sprintf(pp->product_id,"S/390 DASD FBA");
663 } else if (!strncmp(attr_buff, "9336", 4)) {
664 sprintf(pp->product_id,"S/390 DASD FBA");
666 sprintf(pp->product_id,"S/390 DASD ECKD");
669 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
672 * set the hwe configlet pointer
674 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, NULL);
677 * host / bus / target / lun
679 attr_path = udev_device_get_sysname(parent);
681 sscanf(attr_path, "%i.%i.%x",
685 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
696 cciss_sysfs_pathinfo (struct path * pp)
698 const char * attr_path = NULL;
699 struct udev_device *parent;
703 const char *subsys = udev_device_get_subsystem(parent);
704 if (subsys && !strncmp(subsys, "cciss", 5)) {
705 attr_path = udev_device_get_sysname(parent);
708 if (sscanf(attr_path, "c%id%i",
710 &pp->sg_id.scsi_id) == 2)
713 parent = udev_device_get_parent(parent);
715 if (!attr_path || pp->sg_id.host_no == -1)
718 if (sysfs_get_vendor(parent, pp->vendor_id, SCSI_VENDOR_SIZE))
721 condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
723 if (sysfs_get_model(parent, pp->product_id, SCSI_PRODUCT_SIZE))
726 condlog(3, "%s: product = %s", pp->dev, pp->product_id);
728 if (sysfs_get_rev(parent, pp->rev, SCSI_REV_SIZE))
731 condlog(3, "%s: rev = %s", pp->dev, pp->rev);
734 * set the hwe configlet pointer
736 pp->hwe = find_hwe(conf->hwtable, pp->vendor_id, pp->product_id, pp->rev);
739 * host / bus / target / lun
742 pp->sg_id.channel = 0;
743 condlog(3, "%s: h:b:t:l = %i:%i:%i:%i",
753 common_sysfs_pathinfo (struct path * pp)
756 condlog(4, "%s: udev not initialised", pp->dev);
759 if (sysfs_get_dev(pp->udev, pp->dev_t, BLK_DEV_SIZE)) {
760 condlog(3, "%s: no 'dev' attribute in sysfs", pp->dev);
764 condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
766 if (sysfs_get_size(pp, &pp->size))
769 condlog(3, "%s: size = %llu", pp->dev, pp->size);
775 path_offline (struct path * pp)
777 struct udev_device * parent;
778 char buff[SCSI_STATE_SIZE];
780 if (pp->bus != SYSFS_BUS_SCSI)
785 const char *subsys = udev_device_get_subsystem(parent);
786 if (subsys && !strncmp(subsys, "scsi", 4))
788 parent = udev_device_get_parent(parent);
792 condlog(1, "%s: failed to get sysfs information", pp->dev);
796 if (sysfs_get_state(parent, buff, SCSI_STATE_SIZE))
799 condlog(3, "%s: path state = %s", pp->dev, buff);
801 if (!strncmp(buff, "offline", 7) ||
802 !strncmp(buff, "transport-offline", 17)) {
807 if (!strncmp(buff, "blocked", 7) || !strncmp(buff, "quiesce", 7))
809 else if (!strncmp(buff, "running", 7))
816 sysfs_pathinfo(struct path * pp)
818 if (common_sysfs_pathinfo(pp))
821 pp->bus = SYSFS_BUS_UNDEF;
822 if (!strncmp(pp->dev,"cciss",5))
823 pp->bus = SYSFS_BUS_CCISS;
824 if (!strncmp(pp->dev,"dasd", 4))
825 pp->bus = SYSFS_BUS_CCW;
826 if (!strncmp(pp->dev,"sd", 2))
827 pp->bus = SYSFS_BUS_SCSI;
829 if (pp->bus == SYSFS_BUS_UNDEF)
831 else if (pp->bus == SYSFS_BUS_SCSI) {
832 if (scsi_sysfs_pathinfo(pp))
834 } else if (pp->bus == SYSFS_BUS_CCW) {
835 if (ccw_sysfs_pathinfo(pp))
837 } else if (pp->bus == SYSFS_BUS_CCISS) {
838 if (cciss_sysfs_pathinfo(pp))
845 scsi_ioctl_pathinfo (struct path * pp, int mask)
847 if (mask & DI_SERIAL) {
848 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
849 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
856 cciss_ioctl_pathinfo (struct path * pp, int mask)
858 if (mask & DI_SERIAL) {
859 get_serial(pp->serial, SERIAL_SIZE, pp->fd);
860 condlog(3, "%s: serial = %s", pp->dev, pp->serial);
866 get_state (struct path * pp, int daemon)
868 struct checker * c = &pp->checker;
871 condlog(3, "%s: get_state", pp->dev);
873 if (!checker_selected(c)) {
875 if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
876 condlog(3, "%s: couldn't get sysfs pathinfo",
878 return PATH_UNCHECKED;
882 if (!checker_selected(c)) {
883 condlog(3, "%s: No checker selected", pp->dev);
884 return PATH_UNCHECKED;
886 checker_set_fd(c, pp->fd);
887 if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
888 memset(c, 0x0, sizeof(struct checker));
889 condlog(3, "%s: checker init failed", pp->dev);
890 return PATH_UNCHECKED;
893 checker_clear_message(c);
895 checker_set_async(c);
896 if (!conf->checker_timeout &&
897 (pp->bus != SYSFS_BUS_SCSI ||
898 sysfs_get_timeout(pp, &(c->timeout))))
899 c->timeout = DEF_TIMEOUT;
900 state = checker_check(c);
901 condlog(3, "%s: state = %s", pp->dev, checker_state_name(state));
902 if (state != PATH_UP && state != PATH_GHOST &&
903 strlen(checker_message(c)))
904 condlog(3, "%s: checker msg is \"%s\"",
905 pp->dev, checker_message(c));
910 get_prio (struct path * pp)
915 struct prio * p = &pp->prio;
917 if (!prio_selected(p)) {
918 select_detect_prio(pp);
920 if (!prio_selected(p)) {
921 condlog(3, "%s: no prio selected", pp->dev);
925 pp->priority = prio_getprio(p, pp);
926 if (pp->priority < 0) {
927 condlog(3, "%s: %s prio error", pp->dev, prio_name(p));
928 pp->priority = PRIO_UNDEF;
931 condlog(3, "%s: %s prio = %u",
932 pp->dev, prio_name(p), pp->priority);
937 get_uid (struct path * pp)
942 if (!pp->uid_attribute)
946 condlog(1, "%s: no udev information", pp->dev);
950 memset(pp->wwid, 0, WWID_SIZE);
951 value = udev_device_get_property_value(pp->udev, pp->uid_attribute);
952 if ((!value || strlen(value) == 0) && conf->dry_run == 2)
953 value = getenv(pp->uid_attribute);
954 if (value && strlen(value)) {
955 size_t len = WWID_SIZE;
957 if (strlen(value) + 1 > WWID_SIZE) {
958 condlog(0, "%s: wwid overflow", pp->dev);
962 strncpy(pp->wwid, value, len);
964 condlog(3, "%s: no %s attribute", pp->dev,
968 /* Strip any trailing blanks */
969 c = strchr(pp->wwid, '\0');
971 while (c && c >= pp->wwid && *c == ' ') {
975 condlog(3, "%s: uid = %s (udev)", pp->dev,
976 *pp->wwid == '\0' ? "<empty>" : pp->wwid);
981 pathinfo (struct path *pp, vector hwtable, int mask)
985 condlog(3, "%s: mask = 0x%x", pp->dev, mask);
988 * fetch info available in sysfs
990 if (mask & DI_SYSFS && sysfs_pathinfo(pp))
993 if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
994 if (filter_device(conf->blist_device, conf->elist_device,
995 pp->vendor_id, pp->product_id) > 0) {
1000 path_state = path_offline(pp);
1003 * fetch info not available through sysfs
1006 pp->fd = open(udev_device_get_devnode(pp->udev), O_RDONLY);
1009 condlog(4, "Couldn't open node for %s: %s",
1010 pp->dev, strerror(errno));
1014 if (mask & DI_SERIAL)
1017 if (path_state == PATH_UP && pp->bus == SYSFS_BUS_SCSI &&
1018 scsi_ioctl_pathinfo(pp, mask))
1021 if (pp->bus == SYSFS_BUS_CCISS &&
1022 cciss_ioctl_pathinfo(pp, mask))
1025 if (mask & DI_CHECKER) {
1026 if (path_state == PATH_UP) {
1027 pp->chkrstate = pp->state = get_state(pp, 0);
1028 if (pp->state == PATH_UNCHECKED ||
1029 pp->state == PATH_WILD)
1032 condlog(3, "%s: path inaccessible", pp->dev);
1033 pp->chkrstate = pp->state = path_state;
1037 if (path_state == PATH_UP && (mask & DI_WWID) && !strlen(pp->wwid))
1039 if (mask & DI_BLACKLIST && mask & DI_WWID) {
1040 if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
1047 * Retrieve path priority, even for PATH_DOWN paths if it has never
1048 * been successfully obtained before.
1050 if ((mask & DI_PRIO) && path_state == PATH_UP) {
1051 if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) {
1052 if (!strlen(pp->wwid))
1056 pp->priority = PRIO_UNDEF;
1064 * Recoverable error, for example faulty or offline path
1066 memset(pp->wwid, 0, WWID_SIZE);
1067 pp->chkrstate = pp->state = PATH_DOWN;