]>
Commit | Line | Data |
---|---|---|
dc01aad8 SS |
1 | --- |
2 | libmultipath/config.h | 4 + | |
3 | libmultipath/configure.c | 3 + | |
4 | libmultipath/dict.c | 102 +++++++++++++++++++++++++++++++++++++++++++++ | |
5 | libmultipath/discovery.c | 37 ++++++++++++++++ | |
6 | libmultipath/discovery.h | 1 | |
7 | libmultipath/propsel.c | 42 ++++++++++++++++++ | |
8 | libmultipath/propsel.h | 2 | |
9 | libmultipath/structs.h | 2 | |
10 | libmultipath/sysfs.c | 56 ++++++++++++++++++++++++ | |
11 | libmultipath/sysfs.h | 3 - | |
12 | multipath.conf.annotated | 38 ++++++++++++++++ | |
13 | multipath/multipath.conf.5 | 15 ++++++ | |
14 | 12 files changed, 303 insertions(+), 2 deletions(-) | |
15 | ||
16 | Index: multipath-tools-091020/multipath.conf.annotated | |
17 | =================================================================== | |
18 | --- multipath-tools-091020.orig/multipath.conf.annotated | |
19 | +++ multipath-tools-091020/multipath.conf.annotated | |
20 | @@ -191,6 +191,25 @@ | |
21 | # # default : determined by the process | |
22 | # gid disk | |
23 | # | |
24 | +# # | |
25 | +# # name : fast_io_fail_tmo | |
26 | +# # scope : multipath & multipathd | |
27 | +# # desc : The number of seconds the scsi layer will wait after a | |
28 | +# # problem has been detected on a FC remote port before failing | |
29 | +# # IO to devices on that remote port. | |
30 | +# # values : off | n >= 0 (smaller than dev_loss_tmo) | |
31 | +# # default : determined by the OS | |
32 | +# fast_io_fail_tmo 5 | |
33 | +# | |
34 | +# # | |
35 | +# # name : dev_loss_tmo | |
36 | +# # scope : multipath & multipathd | |
37 | +# # desc : The number of seconds the scsi layer will wait after a | |
38 | +# # problem has been detected on a FC remote port before | |
39 | +# # removing it from the system. | |
40 | +# # values : n > 0 | |
41 | +# # default : determined by the OS | |
42 | +# dev_loss_tmo 600 | |
43 | #} | |
44 | # | |
45 | ## | |
46 | @@ -504,7 +523,6 @@ | |
47 | # # desc : If set to "yes", multipathd will disable queueing | |
48 | # # when the last path to a device has been deleted. | |
49 | # # values : yes|no | |
50 | -# # default : no | |
51 | # # | |
52 | # flush_on_last_del yes | |
53 | # | |
54 | @@ -514,6 +532,24 @@ | |
55 | # # desc : product strings to blacklist for this vendor | |
56 | # # | |
57 | # product_blacklist LUN_Z | |
58 | +# | |
59 | +# # | |
60 | +# # name : fast_io_fail_tmo | |
61 | +# # scope : multipath & multipathd | |
62 | +# # desc : The number of seconds the scsi layer will wait after | |
63 | +# # a problem has been detected on a FC remote port | |
64 | +# # before failing IO to devices on that remote port. | |
65 | +# # values : off | n >= 0 (smaller than dev_loss_tmo) | |
66 | +# fast_io_fail_tmo 5 | |
67 | +# | |
68 | +# # | |
69 | +# # name : dev_loss_tmo | |
70 | +# # scope : multipath & multipathd | |
71 | +# # desc : The number of seconds the scsi layer will wait after | |
72 | +# # a problem has been detected on a FC remote port | |
73 | +# # before removing it from the system. | |
74 | +# # values : n > 0 | |
75 | +# dev_loss_tmo 600 | |
76 | # } | |
77 | # device { | |
78 | # vendor "COMPAQ " | |
79 | Index: multipath-tools-091020/multipath/multipath.conf.5 | |
80 | =================================================================== | |
81 | --- multipath-tools-091020.orig/multipath/multipath.conf.5 | |
82 | +++ multipath-tools-091020/multipath/multipath.conf.5 | |
83 | @@ -240,6 +240,17 @@ this to the system limit from /proc/sys/ | |
84 | maximum number of open fds is taken from the calling process. It is usually | |
85 | 1024. To be safe, this should be set to the maximum number of paths plus 32, | |
86 | if that number is greated than 1024. | |
87 | +.TP | |
88 | +.B fast_io_fail_tmo | |
89 | +Specify the number of seconds the scsi layer will wait after a problem has been | |
90 | +detected on a FC remote port before failing IO to devices on that remote port. | |
91 | +This should be smaller than dev_loss_tmo. Setting this to | |
92 | +.I off | |
93 | +will disable the timeout. | |
94 | +.TP | |
95 | +.B dev_loss_tmo | |
96 | +Specify the number of seconds the scsi layer will wait after a problem has | |
97 | +been detected on a FC remote port before removing it from the system. | |
98 | . | |
99 | .SH "blacklist section" | |
100 | The | |
101 | @@ -384,6 +395,10 @@ section: | |
102 | .B no_path_retry | |
103 | .TP | |
104 | .B rr_min_io | |
105 | +.TP | |
106 | +.B fast_io_fail_tmo | |
107 | +.TP | |
108 | +.B dev_loss_tmo | |
109 | .RE | |
110 | .PD | |
111 | .LP | |
112 | Index: multipath-tools-091020/libmultipath/dict.c | |
113 | =================================================================== | |
114 | --- multipath-tools-091020.orig/libmultipath/dict.c | |
115 | +++ multipath-tools-091020/libmultipath/dict.c | |
116 | @@ -37,6 +37,35 @@ polling_interval_handler(vector strvec) | |
117 | } | |
118 | ||
119 | static int | |
120 | +def_fast_io_fail_handler(vector strvec) | |
121 | +{ | |
122 | + char * buff; | |
123 | + | |
124 | + buff = set_value(strvec); | |
125 | + if (strlen(buff) == 3 && !strcmp(buff, "off")) | |
126 | + conf->fast_io_fail = -1; | |
127 | + else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 || | |
128 | + conf->fast_io_fail < -1) | |
129 | + conf->fast_io_fail = 0; | |
130 | + | |
131 | + FREE(buff); | |
132 | + return 0; | |
133 | +} | |
134 | + | |
135 | +static int | |
136 | +def_dev_loss_handler(vector strvec) | |
137 | +{ | |
138 | + char * buff; | |
139 | + | |
140 | + buff = set_value(strvec); | |
141 | + if (sscanf(buff, "%u", &conf->dev_loss) != 1) | |
142 | + conf->dev_loss = 0; | |
143 | + | |
144 | + FREE(buff); | |
145 | + return 0; | |
146 | +} | |
147 | + | |
148 | +static int | |
149 | verbosity_handler(vector strvec) | |
150 | { | |
151 | char * buff; | |
152 | @@ -628,6 +657,37 @@ bl_product_handler(vector strvec) | |
153 | } | |
154 | ||
155 | static int | |
156 | +hw_fast_io_fail_handler(vector strvec) | |
157 | +{ | |
158 | + char * buff; | |
159 | + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); | |
160 | + | |
161 | + buff = set_value(strvec); | |
162 | + if (strlen(buff) == 3 && !strcmp(buff, "off")) | |
163 | + hwe->fast_io_fail = -1; | |
164 | + else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 || | |
165 | + hwe->fast_io_fail < -1) | |
166 | + hwe->fast_io_fail = 0; | |
167 | + | |
168 | + FREE(buff); | |
169 | + return 0; | |
170 | +} | |
171 | + | |
172 | +static int | |
173 | +hw_dev_loss_handler(vector strvec) | |
174 | +{ | |
175 | + char * buff; | |
176 | + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); | |
177 | + | |
178 | + buff = set_value(strvec); | |
179 | + if (sscanf(buff, "%u", &hwe->dev_loss) != 1) | |
180 | + hwe->dev_loss = 0; | |
181 | + | |
182 | + FREE(buff); | |
183 | + return 0; | |
184 | +} | |
185 | + | |
186 | +static int | |
187 | hw_pgpolicy_handler(vector strvec) | |
188 | { | |
189 | char * buff; | |
190 | @@ -1390,6 +1450,26 @@ snprint_mp_flush_on_last_del (char * buf | |
191 | } | |
192 | ||
193 | static int | |
194 | +snprint_hw_fast_io_fail(char * buff, int len, void * data) | |
195 | +{ | |
196 | + struct hwentry * hwe = (struct hwentry *)data; | |
197 | + if (!hwe->fast_io_fail) | |
198 | + return 0; | |
199 | + if (hwe->fast_io_fail == -1) | |
200 | + return snprintf(buff, len, "off"); | |
201 | + return snprintf(buff, len, "%d", hwe->fast_io_fail); | |
202 | +} | |
203 | + | |
204 | +static int | |
205 | +snprint_hw_dev_loss(char * buff, int len, void * data) | |
206 | +{ | |
207 | + struct hwentry * hwe = (struct hwentry *)data; | |
208 | + if (!hwe->dev_loss) | |
209 | + return 0; | |
210 | + return snprintf(buff, len, "%u", hwe->dev_loss); | |
211 | +} | |
212 | + | |
213 | +static int | |
214 | snprint_hw_vendor (char * buff, int len, void * data) | |
215 | { | |
216 | struct hwentry * hwe = (struct hwentry *)data; | |
217 | @@ -1640,6 +1720,24 @@ snprint_def_polling_interval (char * buf | |
218 | } | |
219 | ||
220 | static int | |
221 | +snprint_def_fast_io_fail(char * buff, int len, void * data) | |
222 | +{ | |
223 | + if (!conf->fast_io_fail) | |
224 | + return 0; | |
225 | + if (conf->fast_io_fail == -1) | |
226 | + return snprintf(buff, len, "off"); | |
227 | + return snprintf(buff, len, "%d", conf->fast_io_fail); | |
228 | +} | |
229 | + | |
230 | +static int | |
231 | +snprint_def_dev_loss(char * buff, int len, void * data) | |
232 | +{ | |
233 | + if (!conf->dev_loss) | |
234 | + return 0; | |
235 | + return snprintf(buff, len, "%u", conf->dev_loss); | |
236 | +} | |
237 | + | |
238 | +static int | |
239 | snprint_def_verbosity (char * buff, int len, void * data) | |
240 | { | |
241 | if (conf->checkint == DEFAULT_VERBOSITY) | |
242 | @@ -1937,6 +2035,8 @@ init_keywords(void) | |
243 | install_keyword("mode", &def_mode_handler, &snprint_def_mode); | |
244 | install_keyword("uid", &def_uid_handler, &snprint_def_uid); | |
245 | install_keyword("gid", &def_gid_handler, &snprint_def_gid); | |
246 | + install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); | |
247 | + install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); | |
248 | __deprecated install_keyword("default_selector", &def_selector_handler, NULL); | |
249 | __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); | |
250 | __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL); | |
251 | @@ -1991,6 +2091,8 @@ init_keywords(void) | |
252 | install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io); | |
253 | install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout); | |
254 | install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); | |
255 | + install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); | |
256 | + install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); | |
257 | install_sublevel_end(); | |
258 | ||
259 | install_keyword_root("multipaths", &multipaths_handler); | |
260 | Index: multipath-tools-091020/libmultipath/config.h | |
261 | =================================================================== | |
262 | --- multipath-tools-091020.orig/libmultipath/config.h | |
263 | +++ multipath-tools-091020/libmultipath/config.h | |
264 | @@ -31,6 +31,8 @@ struct hwentry { | |
265 | int minio; | |
266 | int pg_timeout; | |
267 | int flush_on_last_del; | |
268 | + int fast_io_fail; | |
269 | + unsigned int dev_loss; | |
270 | char * bl_product; | |
271 | }; | |
272 | ||
273 | @@ -75,6 +77,8 @@ struct config { | |
274 | int daemon; | |
275 | int flush_on_last_del; | |
276 | int attribute_flags; | |
277 | + int fast_io_fail; | |
278 | + unsigned int dev_loss; | |
279 | uid_t uid; | |
280 | gid_t gid; | |
281 | mode_t mode; | |
282 | Index: multipath-tools-091020/libmultipath/propsel.c | |
283 | =================================================================== | |
284 | --- multipath-tools-091020.orig/libmultipath/propsel.c | |
285 | +++ multipath-tools-091020/libmultipath/propsel.c | |
286 | @@ -428,6 +428,48 @@ select_pg_timeout(struct multipath *mp) | |
287 | } | |
288 | ||
289 | extern int | |
290 | +select_fast_io_fail(struct multipath *mp) | |
291 | +{ | |
292 | + if (mp->hwe && mp->hwe->fast_io_fail) { | |
293 | + mp->fast_io_fail = mp->hwe->fast_io_fail; | |
294 | + if (mp->fast_io_fail == -1) | |
295 | + condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias); | |
296 | + else | |
297 | + condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias, mp->fast_io_fail); | |
298 | + return 0; | |
299 | + } | |
300 | + if (conf->fast_io_fail) { | |
301 | + mp->fast_io_fail = conf->fast_io_fail; | |
302 | + if (mp->fast_io_fail == -1) | |
303 | + condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias); | |
304 | + else | |
305 | + condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias, mp->fast_io_fail); | |
306 | + return 0; | |
307 | + } | |
308 | + mp->fast_io_fail = 0; | |
309 | + return 0; | |
310 | +} | |
311 | + | |
312 | +extern int | |
313 | +select_dev_loss(struct multipath *mp) | |
314 | +{ | |
315 | + if (mp->hwe && mp->hwe->dev_loss) { | |
316 | + mp->dev_loss = mp->hwe->dev_loss; | |
317 | + condlog(3, "%s: dev_loss_tmo = %u (controller default)", | |
318 | + mp->alias, mp->dev_loss); | |
319 | + return 0; | |
320 | + } | |
321 | + if (conf->dev_loss) { | |
322 | + mp->dev_loss = conf->dev_loss; | |
323 | + condlog(3, "%s: dev_loss_tmo = %u (config file default)", | |
324 | + mp->alias, mp->dev_loss); | |
325 | + return 0; | |
326 | + } | |
327 | + mp->dev_loss = 0; | |
328 | + return 0; | |
329 | +} | |
330 | + | |
331 | +extern int | |
332 | select_flush_on_last_del(struct multipath *mp) | |
333 | { | |
334 | if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) | |
335 | Index: multipath-tools-091020/libmultipath/structs.h | |
336 | =================================================================== | |
337 | --- multipath-tools-091020.orig/libmultipath/structs.h | |
338 | +++ multipath-tools-091020/libmultipath/structs.h | |
339 | @@ -166,6 +166,8 @@ struct multipath { | |
340 | int pg_timeout; | |
341 | int flush_on_last_del; | |
342 | int attribute_flags; | |
343 | + int fast_io_fail; | |
344 | + unsigned int dev_loss; | |
345 | uid_t uid; | |
346 | gid_t gid; | |
347 | mode_t mode; | |
348 | Index: multipath-tools-091020/libmultipath/configure.c | |
349 | =================================================================== | |
350 | --- multipath-tools-091020.orig/libmultipath/configure.c | |
351 | +++ multipath-tools-091020/libmultipath/configure.c | |
352 | @@ -70,7 +70,10 @@ setup_map (struct multipath * mpp) | |
353 | select_mode(mpp); | |
354 | select_uid(mpp); | |
355 | select_gid(mpp); | |
356 | + select_fast_io_fail(mpp); | |
357 | + select_dev_loss(mpp); | |
358 | ||
359 | + sysfs_set_scsi_tmo(mpp); | |
360 | /* | |
361 | * assign paths to path groups -- start with no groups and all paths | |
362 | * in mpp->paths | |
363 | Index: multipath-tools-091020/libmultipath/discovery.c | |
364 | =================================================================== | |
365 | --- multipath-tools-091020.orig/libmultipath/discovery.c | |
366 | +++ multipath-tools-091020/libmultipath/discovery.c | |
367 | @@ -204,6 +204,43 @@ sysfs_get_fc_nodename (struct sysfs_devi | |
368 | return 1; | |
369 | } | |
370 | ||
371 | +int | |
372 | +sysfs_set_scsi_tmo (struct multipath *mpp) | |
373 | +{ | |
374 | + char attr_path[SYSFS_PATH_SIZE]; | |
375 | + struct path *pp; | |
376 | + int i; | |
377 | + char value[11]; | |
378 | + | |
379 | + if (!mpp->dev_loss && !mpp->fast_io_fail) | |
380 | + return 0; | |
381 | + vector_foreach_slot(mpp->paths, pp, i) { | |
382 | + if (safe_snprintf(attr_path, SYSFS_PATH_SIZE, | |
383 | + "/class/fc_remote_ports/rport-%d:%d-%d", | |
384 | + pp->sg_id.host_no, pp->sg_id.channel, | |
385 | + pp->sg_id.scsi_id)) { | |
386 | + condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id); | |
387 | + return 1; | |
388 | + } | |
389 | + if (mpp->dev_loss){ | |
390 | + snprintf(value, 11, "%u", mpp->dev_loss); | |
391 | + if (sysfs_attr_set_value(attr_path, "dev_loss_tmo", | |
392 | + value)) | |
393 | + return 1; | |
394 | + } | |
395 | + if (mpp->fast_io_fail){ | |
396 | + if (mpp->fast_io_fail == -1) | |
397 | + sprintf(value, "off"); | |
398 | + else | |
399 | + snprintf(value, 11, "%u", mpp->fast_io_fail); | |
400 | + if (sysfs_attr_set_value(attr_path, "fast_io_fail", | |
401 | + value)) | |
402 | + return 1; | |
403 | + } | |
404 | + } | |
405 | + return 0; | |
406 | +} | |
407 | + | |
408 | static int | |
409 | opennode (char * dev, int mode) | |
410 | { | |
411 | Index: multipath-tools-091020/libmultipath/propsel.h | |
412 | =================================================================== | |
413 | --- multipath-tools-091020.orig/libmultipath/propsel.h | |
414 | +++ multipath-tools-091020/libmultipath/propsel.h | |
415 | @@ -15,3 +15,5 @@ int select_minio(struct multipath *mp); | |
416 | int select_mode(struct multipath *mp); | |
417 | int select_uid(struct multipath *mp); | |
418 | int select_gid(struct multipath *mp); | |
419 | +int select_fast_io_fail(struct multipath *mp); | |
420 | +int select_dev_loss(struct multipath *mp); | |
421 | Index: multipath-tools-091020/libmultipath/discovery.h | |
422 | =================================================================== | |
423 | --- multipath-tools-091020.orig/libmultipath/discovery.h | |
424 | +++ multipath-tools-091020/libmultipath/discovery.h | |
425 | @@ -33,6 +33,7 @@ int path_offline (struct path *); | |
426 | int pathinfo (struct path *, vector hwtable, int mask); | |
427 | struct path * store_pathinfo (vector pathvec, vector hwtable, | |
428 | char * devname, int flag); | |
429 | +int sysfs_set_scsi_tmo (struct multipath *mpp); | |
430 | ||
431 | /* | |
432 | * discovery bitmask | |
433 | Index: multipath-tools-091020/libmultipath/sysfs.c | |
434 | =================================================================== | |
435 | --- multipath-tools-091020.orig/libmultipath/sysfs.c | |
436 | +++ multipath-tools-091020/libmultipath/sysfs.c | |
437 | @@ -356,6 +356,62 @@ void sysfs_device_put(struct sysfs_devic | |
438 | return; | |
439 | } | |
440 | ||
441 | +int | |
442 | +sysfs_attr_set_value(const char *devpath, const char *attr_name, | |
443 | + const char *value) | |
444 | +{ | |
445 | + char path_full[PATH_SIZE]; | |
446 | + int sysfs_len; | |
447 | + struct stat statbuf; | |
448 | + int fd, value_len, ret = -1; | |
449 | + | |
450 | + dbg("open '%s'/'%s'", devpath, attr_name); | |
451 | + sysfs_len = snprintf(path_full, PATH_SIZE, "%s%s/%s", sysfs_path, | |
452 | + devpath, attr_name); | |
453 | + if (sysfs_len >= PATH_SIZE || sysfs_len < 0) { | |
454 | + if (sysfs_len < 0) | |
455 | + dbg("cannot copy sysfs path %s%s/%s : %s", sysfs_path, | |
456 | + devpath, attr_name, strerror(errno)); | |
457 | + else | |
458 | + dbg("sysfs_path %s%s/%s too large", sysfs_path, | |
459 | + devpath, attr_name); | |
460 | + goto out; | |
461 | + } | |
462 | + | |
463 | + if (stat(path_full, &statbuf) != 0) { | |
464 | + dbg("stat '%s' failed: %s" path_full, strerror(errno)); | |
465 | + goto out; | |
466 | + } | |
467 | + | |
468 | + /* skip directories */ | |
469 | + if (S_ISDIR(statbuf.st_mode)) | |
470 | + goto out; | |
471 | + | |
472 | + if ((statbuf.st_mode & S_IWUSR) == 0) | |
473 | + goto out; | |
474 | + | |
475 | + fd = open(path_full, O_WRONLY); | |
476 | + if (fd < 0) { | |
477 | + dbg("attribute '%s' can not be opened: %s", | |
478 | + path_full, strerror(errno)); | |
479 | + goto out; | |
480 | + } | |
481 | + value_len = strlen(value) + 1; | |
482 | + ret = write(fd, value, value_len); | |
483 | + if (ret == value_len) | |
484 | + ret = 0; | |
485 | + else if (ret < 0) | |
486 | + dbg("write to %s failed: %s", path_full, strerror(errno)); | |
487 | + else { | |
488 | + dbg("tried to write %d to %s. Wrote %d\n", value_len, | |
489 | + path_full, ret); | |
490 | + ret = -1; | |
491 | + } | |
492 | +out: | |
493 | + return ret; | |
494 | +} | |
495 | + | |
496 | + | |
497 | char *sysfs_attr_get_value(const char *devpath, const char *attr_name) | |
498 | { | |
499 | char path_full[PATH_SIZE]; | |
500 | Index: multipath-tools-091020/libmultipath/sysfs.h | |
501 | =================================================================== | |
502 | --- multipath-tools-091020.orig/libmultipath/sysfs.h | |
503 | +++ multipath-tools-091020/libmultipath/sysfs.h | |
504 | @@ -22,5 +22,6 @@ void sysfs_device_put(struct sysfs_devic | |
505 | char *sysfs_attr_get_value(const char *devpath, const char *attr_name); | |
506 | int sysfs_resolve_link(char *path, size_t size); | |
507 | int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size); | |
508 | - | |
509 | +int sysfs_attr_set_value(const char *devpath, const char *attr_name, | |
510 | + const char *value); | |
511 | #endif |