2 * Copyright (c) 2004, 2005 Christophe Varoqui
11 #include <sys/ioctl.h>
14 #include "path_state.h"
17 #include "../libmultipath/sg_include.h"
19 #define SENSE_BUFF_LEN 32
20 #define DEF_TIMEOUT 60000
22 #define MSG_READSECTOR0_UP "readsector0 checker reports path is up"
23 #define MSG_READSECTOR0_DOWN "readsector0 checker reports path is down"
25 struct readsector0_checker_context {
30 sg_read (int sg_fd, unsigned char * buff)
34 long long start_block = 0;
39 unsigned char rdCmd[cdbsz];
40 unsigned char senseBuff[SENSE_BUFF_LEN];
41 struct sg_io_hdr io_hdr;
43 int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
46 memset(rdCmd, 0, cdbsz);
48 rdCmd[0] = rd_opcode[sz_ind];
49 rdCmd[2] = (unsigned char)((start_block >> 24) & 0xff);
50 rdCmd[3] = (unsigned char)((start_block >> 16) & 0xff);
51 rdCmd[4] = (unsigned char)((start_block >> 8) & 0xff);
52 rdCmd[5] = (unsigned char)(start_block & 0xff);
53 rdCmd[7] = (unsigned char)((blocks >> 8) & 0xff);
54 rdCmd[8] = (unsigned char)(blocks & 0xff);
56 memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
57 io_hdr.interface_id = 'S';
58 io_hdr.cmd_len = cdbsz;
60 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
61 io_hdr.dxfer_len = bs * blocks;
63 io_hdr.mx_sb_len = SENSE_BUFF_LEN;
64 io_hdr.sbp = senseBuff;
65 io_hdr.timeout = DEF_TIMEOUT;
66 io_hdr.pack_id = (int)start_block;
68 io_hdr.flags |= SG_FLAG_DIRECT_IO;
70 while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) && (EINTR == errno));
73 if (ENOMEM == errno) {
79 if ((0 == io_hdr.status) &&
80 (0 == io_hdr.host_status) &&
81 (0 == io_hdr.driver_status)) {
89 readsector0 (int fd, char *msg, void **context)
91 unsigned char buf[512];
92 struct readsector0_checker_context * ctxt = NULL;
96 * caller passed in a context : use its address
99 ctxt = (struct readsector0_checker_context *) (*context);
102 * passed in context is uninitialized or volatile context :
106 ctxt = malloc(sizeof(struct readsector0_checker_context));
107 memset(ctxt, 0, sizeof(struct readsector0_checker_context));
110 MSG("cannot allocate context");
121 ret = sg_read(fd, &buf[0]);
126 MSG(MSG_READSECTOR0_DOWN);
129 MSG(MSG_READSECTOR0_UP);
136 * caller told us he doesn't want to keep the context :