]> git.ipfire.org Git - ipfire-3.x.git/blob - multipath-tools/patches/0013-RH-add-weighted_prio-prioritizer.patch
Move all packages to root.
[ipfire-3.x.git] / multipath-tools / patches / 0013-RH-add-weighted_prio-prioritizer.patch
1 ---
2 libmultipath/config.c | 10 ++
3 libmultipath/config.h | 4 +
4 libmultipath/dict.c | 92 ++++++++++++++++++++---
5 libmultipath/discovery.c | 56 +++++++-------
6 libmultipath/prio.h | 1
7 libmultipath/prioritizers/Makefile | 3
8 libmultipath/prioritizers/weighted.c | 139 +++++++++++++++++++++++++++++++++++
9 libmultipath/prioritizers/weighted.h | 8 ++
10 libmultipath/propsel.c | 11 ++
11 libmultipath/structs.h | 1
12 10 files changed, 286 insertions(+), 39 deletions(-)
13
14 Index: multipath-tools/libmultipath/config.c
15 ===================================================================
16 --- multipath-tools.orig/libmultipath/config.c
17 +++ multipath-tools/libmultipath/config.c
18 @@ -156,6 +156,9 @@ free_hwe (struct hwentry * hwe)
19 if (hwe->prio_name)
20 FREE(hwe->prio_name);
21
22 + if (hwe->prio_args)
23 + FREE(hwe->prio_args);
24 +
25 if (hwe->bl_product)
26 FREE(hwe->bl_product);
27
28 @@ -195,6 +198,12 @@ free_mpe (struct mpentry * mpe)
29 if (mpe->alias)
30 FREE(mpe->alias);
31
32 + if (mpe->prio_name)
33 + FREE(mpe->prio_name);
34 +
35 + if (mpe->prio_args)
36 + FREE(mpe->prio_args);
37 +
38 FREE(mpe);
39 }
40
41 @@ -279,6 +288,7 @@ merge_hwe (struct hwentry * hwe1, struct
42 merge_str(selector);
43 merge_str(checker_name);
44 merge_str(prio_name);
45 + merge_str(prio_args);
46 merge_str(bl_product);
47 merge_num(pgpolicy);
48 merge_num(pgfailback);
49 Index: multipath-tools/libmultipath/config.h
50 ===================================================================
51 --- multipath-tools.orig/libmultipath/config.h
52 +++ multipath-tools/libmultipath/config.h
53 @@ -25,6 +25,7 @@ struct hwentry {
54 char * selector;
55 char * checker_name;
56 char * prio_name;
57 + char * prio_args;
58
59 int pgpolicy;
60 int pgfailback;
61 @@ -43,6 +44,8 @@ struct mpentry {
62 char * alias;
63 char * getuid;
64 char * selector;
65 + char * prio_name;
66 + char * prio_args;
67
68 int pgpolicy;
69 int pgfailback;
70 @@ -97,6 +100,7 @@ struct config {
71 char * hwhandler;
72 char * bindings_file;
73 char * prio_name;
74 + char * prio_args;
75 char * checker_name;
76
77 vector keywords;
78 Index: multipath-tools/libmultipath/dict.c
79 ===================================================================
80 --- multipath-tools.orig/libmultipath/dict.c
81 +++ multipath-tools/libmultipath/dict.c
82 @@ -139,11 +139,23 @@ def_getuid_callout_handler(vector strvec
83 static int
84 def_prio_handler(vector strvec)
85 {
86 - conf->prio_name = set_value(strvec);
87 + char *name, *args;
88
89 - if (!conf->prio_name)
90 + name = set_value(strvec);
91 + if (!name)
92 return 1;
93
94 + args = strpbrk(name, " \t");
95 + if (args) {
96 + *args = 0;
97 + while(*++args && isblank(*args)); /* Do nothing */
98 + }
99 +
100 + conf->prio_name = STRDUP(name);
101 + if (args && *args)
102 + conf->prio_args = STRDUP(args);
103 +
104 + FREE(name);
105 return 0;
106 }
107
108 @@ -806,16 +818,27 @@ hw_handler_handler(vector strvec)
109 static int
110 hw_prio_handler(vector strvec)
111 {
112 + char *name, *args;
113 struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
114
115 if (!hwe)
116 return 1;
117
118 - hwe->prio_name = set_value(strvec);
119 -
120 - if (!hwe->prio_name)
121 + name = set_value(strvec);
122 + if (!name)
123 return 1;
124
125 + args = strpbrk(name, " \t");
126 + if (args) {
127 + *args = 0;
128 + while(*++args && isblank(*args)); /* Do nothing */
129 + }
130 +
131 + hwe->prio_name = STRDUP(name);
132 + if (args && *args)
133 + hwe->prio_args = STRDUP(args);
134 +
135 + FREE(name);
136 return 0;
137 }
138
139 @@ -1293,6 +1316,33 @@ mp_flush_on_last_del_handler(vector strv
140 return 0;
141 }
142
143 +static int
144 +mp_prio_handler(vector strvec)
145 +{
146 + char *name, *args;
147 + struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
148 +
149 + if (!mpe)
150 + return 1;
151 +
152 + name = set_value(strvec);
153 + if (!name)
154 + return 1;
155 +
156 + args = strpbrk(name, " \t");
157 + if (args) {
158 + *args = 0;
159 + while(*++args && isblank(*args)); /* Do nothing */
160 + }
161 +
162 + mpe->prio_name = STRDUP(name);
163 + if (args && *args)
164 + mpe->prio_args = STRDUP(args);
165 +
166 + FREE(name);
167 + return 0;
168 +}
169 +
170 /*
171 * config file keywords printing
172 */
173 @@ -1472,6 +1522,20 @@ snprint_mp_flush_on_last_del (char * buf
174 }
175
176 static int
177 +snprint_mp_prio (char * buff, int len, void * data)
178 +{
179 + struct mpentry * mpe = (struct mpentry *)data;
180 +
181 + if (!mpe->prio_name)
182 + return 0;
183 + if (!strcmp(mpe->prio_name, conf->prio_name) && !mpe->prio_args)
184 + return 0;
185 + if (!mpe->prio_args)
186 + return snprintf(buff, len, "%s", mpe->prio_name);
187 + return snprintf(buff, len, "%s %s", mpe->prio_name, mpe->prio_args);
188 +}
189 +
190 +static int
191 snprint_hw_fast_io_fail(char * buff, int len, void * data)
192 {
193 struct hwentry * hwe = (struct hwentry *)data;
194 @@ -1545,10 +1609,11 @@ snprint_hw_prio (char * buff, int len, v
195
196 if (!hwe->prio_name)
197 return 0;
198 - if (!strcmp(hwe->prio_name, conf->prio_name))
199 + if (!strcmp(hwe->prio_name, conf->prio_name) && !hwe->prio_args)
200 return 0;
201 -
202 - return snprintf(buff, len, "%s", hwe->prio_name);
203 + if (!hwe->prio_args)
204 + return snprintf(buff, len, "%s", hwe->prio_name);
205 + return snprintf(buff, len, "%s %s", hwe->prio_name, hwe->prio_args);
206 }
207
208 static int
209 @@ -1837,10 +1902,14 @@ snprint_def_prio (char * buff, int len,
210 return 0;
211
212 if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
213 - !strcmp(conf->prio_name, DEFAULT_PRIO))
214 + !strcmp(conf->prio_name, DEFAULT_PRIO) && !conf->prio_args)
215 return 0;
216 -
217 - return snprintf(buff, len, "%s", conf->prio_name);
218 +
219 + if (!conf->prio_args)
220 + return snprintf(buff, len, "%s", conf->prio_name);
221 + else
222 + return snprintf(buff, len, "%s %s", conf->prio_name,
223 + conf->prio_args);
224 }
225
226 static int
227 @@ -2146,5 +2215,6 @@ init_keywords(void)
228 install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
229 install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
230 install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
231 + install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
232 install_sublevel_end();
233 }
234 Index: multipath-tools/libmultipath/discovery.c
235 ===================================================================
236 --- multipath-tools.orig/libmultipath/discovery.c
237 +++ multipath-tools/libmultipath/discovery.c
238 @@ -800,30 +800,6 @@ get_state (struct path * pp, int daemon)
239 }
240
241 static int
242 -get_prio (struct path * pp)
243 -{
244 - if (!pp)
245 - return 0;
246 -
247 - if (!pp->prio) {
248 - select_prio(pp);
249 - if (!pp->prio) {
250 - condlog(3, "%s: no prio selected", pp->dev);
251 - return 1;
252 - }
253 - }
254 - pp->priority = prio_getprio(pp->prio, pp);
255 - if (pp->priority < 0) {
256 - condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
257 - pp->priority = PRIO_UNDEF;
258 - return 1;
259 - }
260 - condlog(3, "%s: %s prio = %u",
261 - pp->dev, prio_name(pp->prio), pp->priority);
262 - return 0;
263 -}
264 -
265 -static int
266 get_uid (struct path * pp)
267 {
268 char buff[CALLOUT_MAX_SIZE];
269 @@ -850,6 +826,32 @@ get_uid (struct path * pp)
270 return 0;
271 }
272
273 +static int
274 +get_prio (struct path * pp)
275 +{
276 + if (!pp)
277 + return 0;
278 +
279 + if (!pp->prio) {
280 + if (!strlen(pp->wwid))
281 + get_uid(pp);
282 + select_prio(pp);
283 + if (!pp->prio) {
284 + condlog(3, "%s: no prio selected", pp->dev);
285 + return 1;
286 + }
287 + }
288 + pp->priority = prio_getprio(pp->prio, pp);
289 + if (pp->priority < 0) {
290 + condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
291 + pp->priority = PRIO_UNDEF;
292 + return 1;
293 + }
294 + condlog(3, "%s: %s prio = %u",
295 + pp->dev, prio_name(pp->prio), pp->priority);
296 + return 0;
297 +}
298 +
299 extern int
300 pathinfo (struct path *pp, vector hwtable, int mask)
301 {
302 @@ -887,6 +889,9 @@ pathinfo (struct path *pp, vector hwtabl
303 goto blank;
304 }
305
306 + if (mask & DI_WWID && !strlen(pp->wwid))
307 + get_uid(pp);
308 +
309 /*
310 * Retrieve path priority, even for PATH_DOWN paths if it has never
311 * been successfully obtained before.
312 @@ -895,9 +900,6 @@ pathinfo (struct path *pp, vector hwtabl
313 (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
314 get_prio(pp);
315
316 - if (mask & DI_WWID && !strlen(pp->wwid))
317 - get_uid(pp);
318 -
319 return 0;
320
321 blank:
322 Index: multipath-tools/libmultipath/prio.h
323 ===================================================================
324 --- multipath-tools.orig/libmultipath/prio.h
325 +++ multipath-tools/libmultipath/prio.h
326 @@ -24,6 +24,7 @@
327 #define PRIO_NETAPP "netapp"
328 #define PRIO_RANDOM "random"
329 #define PRIO_RDAC "rdac"
330 +#define PRIO_WEIGHTED "weighted"
331
332 /*
333 * Value used to mark the fact prio was not defined
334 Index: multipath-tools/libmultipath/prioritizers/Makefile
335 ===================================================================
336 --- multipath-tools.orig/libmultipath/prioritizers/Makefile
337 +++ multipath-tools/libmultipath/prioritizers/Makefile
338 @@ -13,7 +13,8 @@ LIBS = \
339 libprioalua.so \
340 libpriotpg_pref.so \
341 libprionetapp.so \
342 - libpriohds.so
343 + libpriohds.so \
344 + libprioweighted.so \
345
346 CFLAGS += -I..
347
348 Index: multipath-tools/libmultipath/prioritizers/weighted.c
349 ===================================================================
350 --- /dev/null
351 +++ multipath-tools/libmultipath/prioritizers/weighted.c
352 @@ -0,0 +1,139 @@
353 +/******************************************************************************
354 +*******************************************************************************
355 +**
356 +** Copyright (C) 2009 Red Hat, Inc. All rights reserved.
357 +**
358 +** This copyrighted material is made available to anyone wishing to use,
359 +** modify, copy, or redistribute it subject to the terms and conditions
360 +** of the GNU General Public License v.2.
361 +**
362 +*******************************************************************************
363 +******************************************************************************/
364 +
365 +/* This prioritizer is based on a path's device name or its H:T:B:L. Both of
366 + * these can change when the node is rebooted, and can differ from node to
367 + * node. (i.e. there is no guarantee that sda will point to the same device
368 + * after a reboot) If you use this prioritizer, it may be necessary to
369 + * manually edit /etc/multipath.conf after any reboot
370 + *
371 + * Format:
372 + * prio "weighted hbtl <regex> <prio> [<regex> <prio>]
373 + * prio "weighted devname <regex> <prio> [<regex> <prio>]
374 + *
375 + * Examples:
376 + * prio "weighted hbtl 4:* 2 3:.:.:. 1"
377 + * prio "weighted devname sda 2 sde 1"
378 + *
379 + */
380 +
381 +#include <string.h>
382 +#include <prio.h>
383 +#include <debug.h>
384 +#include <regex.h>
385 +
386 +#include "weighted.h"
387 +
388 +#define DEFAULT_WEIGHTED_PRIO 0
389 +
390 +#define pp_weighted_log(prio, fmt, args...) \
391 + condlog(prio, "%s: weighted prio: " fmt, dev, ##args)
392 +
393 +static char *
394 +next_str(char **str)
395 +{
396 + char *next;
397 +
398 + do {
399 + next = strsep(str, " \t");
400 + } while (next && strcmp(next, "") == 0);
401 + return next;
402 +}
403 +
404 +
405 +static int
406 +match (char *dev, char *target, char *regex_str, char *prio_str,
407 + unsigned int *prio)
408 +{
409 +
410 + regex_t regex;
411 + int err, ret = 0;
412 + char *errbuf;
413 + size_t errbuf_size;
414 + unsigned int prio_match;
415 +
416 + if (sscanf(prio_str, "%u", &prio_match) != 1) {
417 + condlog(0, "%s: weighted prio: invalid prio '%s'", dev,
418 + prio_str);
419 + return 0;
420 + }
421 + err = regcomp(&regex, regex_str, REG_EXTENDED|REG_NOSUB);
422 + if (err) {
423 + errbuf_size = regerror(err, &regex, NULL, 0);
424 + errbuf = malloc(errbuf_size);
425 + regerror(err, &regex, errbuf, errbuf_size);
426 + condlog(0, "%s: weighted prio: cannot compile regex '%s' : %s",
427 + dev, regex_str, errbuf);
428 + free(errbuf);
429 + return 0;
430 + }
431 + if (regexec(&regex, target, 0, NULL, 0) == 0) {
432 + *prio = prio_match;
433 + ret = 1;
434 + }
435 +
436 + regfree(&regex);
437 + return ret;
438 +}
439 +
440 +int
441 +prio_weighted(struct path * pp)
442 +{
443 + char target[FILE_NAME_SIZE];
444 + char *buff, *args, *ptr, *prio_str;
445 + unsigned int prio = DEFAULT_WEIGHTED_PRIO;
446 + char *regex_str = NULL;
447 + int regex_size = 0;
448 +
449 + if (!pp->prio_args)
450 + return DEFAULT_WEIGHTED_PRIO;
451 + buff = args = strdup(pp->prio_args);
452 + ptr = next_str(&args);
453 +
454 + if (strcasecmp(ptr, "hbtl") == 0)
455 + sprintf(target, "%d:%d:%d:%d", pp->sg_id.host_no,
456 + pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
457 + else if (strcasecmp(ptr, "devname") == 0)
458 + strcpy(target, pp->dev);
459 + else {
460 + condlog(0, "%s: weighted prio: invalid argument. Want 'hbtl' or 'devname'. Got '%s'", pp->dev, ptr);
461 + goto out;
462 + }
463 +
464 + while ((ptr = next_str(&args)) != NULL) {
465 +
466 + prio_str = next_str(&args);
467 + if (!prio_str) {
468 + condlog(0, "%s weighted prio: missing prio for regex '%s'", pp->dev, ptr);
469 + goto out;
470 + }
471 + if (!regex_str || regex_size < strlen(ptr) + 3){
472 + regex_size = strlen(ptr) + 3;
473 + regex_str = realloc(regex_str, regex_size);
474 + }
475 + sprintf(regex_str, "%s%s%s", (ptr[0] == '^')? "" : "^",
476 + ptr, (ptr[strlen(ptr)-1] == '$')? "" : "$");
477 + if (match(pp->dev, target, regex_str, prio_str, &prio))
478 + break;
479 + }
480 +out:
481 + free(buff);
482 + if (regex_str)
483 + free(regex_str);
484 + return prio;
485 +}
486 +
487 +int
488 +getprio(struct path * pp)
489 +{
490 + return prio_weighted(pp);
491 +}
492 Index: multipath-tools/libmultipath/propsel.c
493 ===================================================================
494 --- multipath-tools.orig/libmultipath/propsel.c
495 +++ multipath-tools/libmultipath/propsel.c
496 @@ -312,14 +312,25 @@ select_getuid (struct path * pp)
497 extern int
498 select_prio (struct path * pp)
499 {
500 + struct mpentry * mpe;
501 +
502 + if ((mpe = find_mpe(pp->wwid)) && mpe->prio_name) {
503 + pp->prio = prio_lookup(mpe->prio_name);
504 + pp->prio_args = mpe->prio_args;
505 + condlog(3, "%s: prio = %s (LUN setting)",
506 + pp->dev, mpe->prio_name);
507 + return 0;
508 + }
509 if (pp->hwe && pp->hwe->prio_name) {
510 pp->prio = prio_lookup(pp->hwe->prio_name);
511 + pp->prio_args = pp->hwe->prio_args;
512 condlog(3, "%s: prio = %s (controller setting)",
513 pp->dev, pp->hwe->prio_name);
514 return 0;
515 }
516 if (conf->prio_name) {
517 pp->prio = prio_lookup(conf->prio_name);
518 + pp->prio_args = conf->prio_args;
519 condlog(3, "%s: prio = %s (config file default)",
520 pp->dev, conf->prio_name);
521 return 0;
522 Index: multipath-tools/libmultipath/structs.h
523 ===================================================================
524 --- multipath-tools.orig/libmultipath/structs.h
525 +++ multipath-tools/libmultipath/structs.h
526 @@ -142,6 +142,7 @@ struct path {
527 int priority;
528 int pgindex;
529 char * getuid;
530 + char * prio_args;
531 struct prio * prio;
532 struct checker checker;
533 struct multipath * mpp;
534 Index: multipath-tools/libmultipath/prioritizers/weighted.h
535 ===================================================================
536 --- /dev/null
537 +++ multipath-tools/libmultipath/prioritizers/weighted.h
538 @@ -0,0 +1,8 @@
539 +#ifndef _WEIGHTED_H
540 +#define _WEIGHTED_H
541 +
542 +#define PRIO_WEIGHTED "weighted"
543 +
544 +int prio_weighted(struct path *pp);
545 +
546 +#endif