]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blame - multipath-tools/patches/0013-RH-add-weighted_prio-prioritizer.patch
ulogd2: Fix syntax error in makefile.
[people/amarx/ipfire-3.x.git] / multipath-tools / patches / 0013-RH-add-weighted_prio-prioritizer.patch
CommitLineData
dc01aad8
SS
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
14Index: 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);
49Index: 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;
78Index: 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 }
234Index: 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:
322Index: 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
334Index: 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
348Index: 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+}
492Index: 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;
522Index: 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;
534Index: 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