]>
Commit | Line | Data |
---|---|---|
dc01aad8 SS |
1 | --- |
2 | libmultipath/checkers.h | 3 + | |
3 | libmultipath/checkers/Makefile | 4 + | |
4 | libmultipath/checkers/tur.c | 111 +++++++++++++++++++++++++++++++++++++++++ | |
5 | multipath.conf.annotated | 5 + | |
6 | 4 files changed, 121 insertions(+), 2 deletions(-) | |
7 | ||
8 | Index: multipath-tools/libmultipath/checkers.h | |
9 | =================================================================== | |
10 | --- multipath-tools.orig/libmultipath/checkers.h | |
11 | +++ multipath-tools/libmultipath/checkers.h | |
12 | @@ -60,6 +60,7 @@ enum path_check_state { | |
13 | ||
14 | #define DIRECTIO "directio" | |
15 | #define TUR "tur" | |
16 | +#define HP_TUR "hp_tur" | |
17 | #define HP_SW "hp_sw" | |
18 | #define RDAC "rdac" | |
19 | #define EMC_CLARIION "emc_clariion" | |
20 | @@ -91,6 +92,7 @@ enum path_check_state { | |
21 | #define CHECKER_MSG_LEN 256 | |
22 | #define CHECKER_DEV_LEN 256 | |
23 | #define LIB_CHECKER_NAMELEN 256 | |
24 | +#define WWID_SIZE 128 | |
25 | ||
26 | struct checker { | |
27 | struct list_head node; | |
28 | @@ -99,6 +101,7 @@ struct checker { | |
29 | int disable; | |
30 | char name[CHECKER_NAME_LEN]; | |
31 | char message[CHECKER_MSG_LEN]; /* comm with callers */ | |
32 | + char wwid[WWID_SIZE]; /* LUN wwid */ | |
33 | void * context; /* store for persistent data */ | |
34 | void ** mpcontext; /* store for persistent data shared | |
35 | multipath-wide. Use MALLOC if | |
36 | Index: multipath-tools/libmultipath/checkers/Makefile | |
37 | =================================================================== | |
38 | --- multipath-tools.orig/libmultipath/checkers/Makefile | |
39 | +++ multipath-tools/libmultipath/checkers/Makefile | |
40 | @@ -8,6 +8,7 @@ LIBS= \ | |
41 | libcheckcciss_tur.so \ | |
42 | libcheckreadsector0.so \ | |
43 | libchecktur.so \ | |
44 | + libcheckhp_tur.so \ | |
45 | libcheckdirectio.so \ | |
46 | libcheckemc_clariion.so \ | |
47 | libcheckhp_sw.so \ | |
48 | @@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o | |
49 | libcheck%.so: libsg.o %.o | |
50 | $(CC) $(SHARED_FLAGS) -o $@ $^ | |
51 | ||
52 | +hp_tur.o: tur.c | |
53 | + $(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $< | |
54 | + | |
55 | install: | |
56 | $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) | |
57 | ||
58 | Index: multipath-tools/libmultipath/checkers/tur.c | |
59 | =================================================================== | |
60 | --- multipath-tools.orig/libmultipath/checkers/tur.c | |
61 | +++ multipath-tools/libmultipath/checkers/tur.c | |
62 | @@ -15,14 +15,101 @@ | |
63 | ||
64 | #include "checkers.h" | |
65 | ||
66 | +#include "../libmultipath/debug.h" | |
67 | #include "../libmultipath/sg_include.h" | |
68 | ||
69 | #define TUR_CMD_LEN 6 | |
70 | #define HEAVY_CHECK_COUNT 10 | |
71 | ||
72 | +#ifdef CHECK_WWID | |
73 | +#define MSG_TUR_UP "HP tur checker reports path is up" | |
74 | +#define MSG_TUR_DOWN "HP tur checker reports path is down" | |
75 | +#define MSG_TUR_GHOST "HP tur checker reports path is in standby state" | |
76 | +#define EVPD 0x01 | |
77 | +#define PAGE_83 0x83 | |
78 | +#define INQUIRY_CMD 0x12 | |
79 | +#define INQUIRY_CMDLEN 6 | |
80 | +#define SCSI_INQ_BUFF_LEN 96 | |
81 | +#else | |
82 | #define MSG_TUR_UP "tur checker reports path is up" | |
83 | #define MSG_TUR_DOWN "tur checker reports path is down" | |
84 | #define MSG_TUR_GHOST "tur checker reports path is in standby state" | |
85 | +#endif | |
86 | + | |
87 | +#ifdef CHECK_WWID | |
88 | +static int | |
89 | +do_inq(struct checker * c, char * wwid) | |
90 | +{ | |
91 | + int ret = -1; | |
92 | + unsigned char inq_cmd[INQUIRY_CMDLEN] = | |
93 | + {INQUIRY_CMD, EVPD, PAGE_83, 0, SCSI_INQ_BUFF_LEN, 0 }; | |
94 | + unsigned char sense_buffer[32]; | |
95 | + unsigned char resp_buffer[SCSI_INQ_BUFF_LEN]; | |
96 | + char *pbuff; | |
97 | + | |
98 | + int m,k; | |
99 | + int retry_tur = 5; | |
100 | + struct sg_io_hdr io_hdr; | |
101 | + | |
102 | +retry: | |
103 | + memset(resp_buffer, 0, sizeof(resp_buffer)); | |
104 | + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); | |
105 | + | |
106 | + io_hdr.interface_id = 'S'; | |
107 | + io_hdr.cmd_len = sizeof(inq_cmd); | |
108 | + io_hdr.mx_sb_len = sizeof(sense_buffer); | |
109 | + io_hdr.dxfer_direction = -3; // Data transfer from the device. | |
110 | + io_hdr.dxfer_len = sizeof(resp_buffer); | |
111 | + io_hdr.dxferp = (unsigned char *)resp_buffer; | |
112 | + io_hdr.cmdp = inq_cmd; | |
113 | + io_hdr.sbp = sense_buffer; | |
114 | + io_hdr.timeout = 60; // IOCTL timeout value. | |
115 | + | |
116 | + if (ioctl(c->fd, SG_IO, &io_hdr) < 0) { | |
117 | + condlog(0, "SG_IO ioctl failed: %s", strerror(errno)); | |
118 | + return ret; | |
119 | + } | |
120 | + if (io_hdr.info & SG_INFO_OK_MASK){ | |
121 | + int key = 0, asc, ascq; | |
122 | + | |
123 | + if (io_hdr.host_status == DID_BUS_BUSY || | |
124 | + io_hdr.host_status == DID_ERROR || | |
125 | + io_hdr.host_status == DID_TRANSPORT_DISRUPTED) { | |
126 | + if (--retry_tur) | |
127 | + goto retry; | |
128 | + } | |
129 | + if (io_hdr.sb_len_wr > 3) { | |
130 | + if (io_hdr.sbp[0] == 0x72 || io_hdr.sbp[0] == 0x73) { | |
131 | + key = io_hdr.sbp[1] & 0x0f; | |
132 | + asc = io_hdr.sbp[2]; | |
133 | + ascq = io_hdr.sbp[3]; | |
134 | + } else if (io_hdr.sb_len_wr > 13 && | |
135 | + ((io_hdr.sbp[0] & 0x7f) == 0x70 || | |
136 | + (io_hdr.sbp[0] & 0x7f) == 0x71)) { | |
137 | + key = io_hdr.sbp[2] & 0x0f; | |
138 | + asc = io_hdr.sbp[12]; | |
139 | + ascq = io_hdr.sbp[13]; | |
140 | + } | |
141 | + } | |
142 | + if (key == 0x6) { | |
143 | + /* Unit Attention, retry */ | |
144 | + if (--retry_tur) | |
145 | + goto retry; | |
146 | + } | |
147 | + return ret; | |
148 | + } | |
149 | + | |
150 | + pbuff = (char *) resp_buffer; | |
151 | + | |
152 | + wwid[0] = '3'; | |
153 | + for (m = 8, k = 1; m < 11; ++m, k+=2) | |
154 | + sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff); | |
155 | + for (m = 11; m < 24; ++m, k+=2) | |
156 | + sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff); | |
157 | + | |
158 | + return (ret = 0); | |
159 | +} | |
160 | +#endif | |
161 | ||
162 | struct tur_checker_context { | |
163 | void * dummy; | |
164 | @@ -30,6 +117,9 @@ struct tur_checker_context { | |
165 | ||
166 | int libcheck_init (struct checker * c) | |
167 | { | |
168 | +#ifdef CHECK_WWID | |
169 | + memset(c->wwid, 0, WWID_SIZE); | |
170 | +#endif | |
171 | return 0; | |
172 | } | |
173 | ||
174 | @@ -45,6 +135,9 @@ libcheck_check (struct checker * c) | |
175 | unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; | |
176 | unsigned char sense_buffer[32]; | |
177 | int retry_tur = 5; | |
178 | +#ifdef CHECK_WWID | |
179 | + char wwid[WWID_SIZE]; | |
180 | +#endif | |
181 | ||
182 | retry: | |
183 | memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); | |
184 | @@ -110,6 +203,24 @@ libcheck_check (struct checker * c) | |
185 | MSG(c, MSG_TUR_DOWN); | |
186 | return PATH_DOWN; | |
187 | } | |
188 | +#ifdef CHECK_WWID | |
189 | + if (!do_inq(c, wwid)) { | |
190 | + | |
191 | + if(!strcmp(c->wwid, "\0")) { | |
192 | + strcpy(c->wwid, wwid); | |
193 | + goto up; | |
194 | + } | |
195 | + | |
196 | + if (strcmp(c->wwid , wwid)) { | |
197 | + condlog(0, | |
198 | + "hp_tur: Lun collided. new_wwid %s old_wwid %s", | |
199 | + wwid, c->wwid); | |
200 | + MSG(c, MSG_TUR_DOWN); | |
201 | + return PATH_DOWN; | |
202 | + } | |
203 | + } | |
204 | +up: | |
205 | +#endif | |
206 | MSG(c, MSG_TUR_UP); | |
207 | return PATH_UP; | |
208 | } | |
209 | Index: multipath-tools/multipath.conf.annotated | |
210 | =================================================================== | |
211 | --- multipath-tools.orig/multipath.conf.annotated | |
212 | +++ multipath-tools/multipath.conf.annotated | |
213 | @@ -86,7 +86,8 @@ | |
214 | # # name : path_checker, checker | |
215 | # # scope : multipath & multipathd | |
216 | # # desc : the default method used to determine the paths' state | |
217 | -# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|cciss_tur | |
218 | +# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac| | |
219 | +# cciss_tur|hp_tur | |
220 | # # default : directio | |
221 | # # | |
222 | # path_checker directio | |
223 | @@ -456,7 +457,7 @@ | |
224 | # # scope : multipathd | |
225 | # # desc : path checking alorithm to use to check path state | |
226 | # # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac| | |
227 | -# # cciss_tur | |
228 | +# # cciss_tur|hp_tur | |
229 | # # | |
230 | # path_checker directio | |
231 | # |