--- readsector0.c.orig 2006-11-20 23:52:30.000000000 -0600 +++ readsector0.c 2006-11-20 23:54:05.000000000 -0600 @@ -10,14 +10,14 @@ #include #include #include #include "checkers.h" +#include "readsector0.h" #include "../libmultipath/sg_include.h" - -#define SENSE_BUFF_LEN 32 +#include "../libmultipath/debug.h" #define MSG_READSECTOR0_UP "readsector0 checker reports path is up" #define MSG_READSECTOR0_DOWN "readsector0 checker reports path is down" struct readsector0_checker_context { @@ -49,14 +49,16 @@ int bs = 512; int cdbsz = 10; int * diop = NULL; unsigned char rdCmd[cdbsz]; + unsigned char *sbb = senseBuff; struct sg_io_hdr io_hdr; int res; int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88}; int sz_ind; + int retry_count=3; memset(rdCmd, 0, cdbsz); sz_ind = 1; rdCmd[0] = rd_opcode[sz_ind]; rdCmd[2] = (unsigned char)((start_block >> 24) & 0xff); @@ -78,10 +80,12 @@ io_hdr.timeout = DEF_TIMEOUT; io_hdr.pack_id = (int)start_block; if (diop && *diop) io_hdr.flags |= SG_FLAG_DIRECT_IO; +retry: + memset(senseBuff, 0, SENSE_BUFF_LEN); while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) && (EINTR == errno)); if (res < 0) { if (ENOMEM == errno) { return PATH_UP; @@ -92,19 +96,29 @@ if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && (0 == io_hdr.driver_status)) { return PATH_UP; } else { + /* + * Retry if UNIT_ATTENTION check condition. + */ + if ((sbb[2]&0xf) == 6) { + condlog(4, "readsector0_checker: Read error. " + "Sense data are 0x%x/0x%x/0x%x.", + sbb[2]&0xf, sbb[12], sbb[13]); + if (--retry_count) + goto retry; + } return PATH_DOWN; } } extern int readsector0 (struct checker * c) { - unsigned char buf[512]; unsigned char sbuf[SENSE_BUFF_LEN]; + unsigned char buf[512]; int ret; ret = sg_read(c->fd, &buf[0], &sbuf[0]); int * toto = *c->mpcontext; (*toto)++;