534 lines
14 KiB
Diff
534 lines
14 KiB
Diff
|
Index: multipath-tools-091020/libmultipath/config.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/config.c
|
||
|
+++ multipath-tools-091020/libmultipath/config.c
|
||
|
@@ -156,6 +156,9 @@ free_hwe (struct hwentry * hwe)
|
||
|
if (hwe->prio_name)
|
||
|
FREE(hwe->prio_name);
|
||
|
|
||
|
+ if (hwe->prio_args)
|
||
|
+ FREE(hwe->prio_args);
|
||
|
+
|
||
|
if (hwe->bl_product)
|
||
|
FREE(hwe->bl_product);
|
||
|
|
||
|
@@ -195,6 +198,12 @@ free_mpe (struct mpentry * mpe)
|
||
|
if (mpe->alias)
|
||
|
FREE(mpe->alias);
|
||
|
|
||
|
+ if (mpe->prio_name)
|
||
|
+ FREE(mpe->prio_name);
|
||
|
+
|
||
|
+ if (mpe->prio_args)
|
||
|
+ FREE(mpe->prio_args);
|
||
|
+
|
||
|
FREE(mpe);
|
||
|
}
|
||
|
|
||
|
@@ -279,6 +288,7 @@ merge_hwe (struct hwentry * hwe1, struct
|
||
|
merge_str(selector);
|
||
|
merge_str(checker_name);
|
||
|
merge_str(prio_name);
|
||
|
+ merge_str(prio_args);
|
||
|
merge_str(bl_product);
|
||
|
merge_num(pgpolicy);
|
||
|
merge_num(pgfailback);
|
||
|
Index: multipath-tools-091020/libmultipath/config.h
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/config.h
|
||
|
+++ multipath-tools-091020/libmultipath/config.h
|
||
|
@@ -24,6 +24,7 @@ struct hwentry {
|
||
|
char * selector;
|
||
|
char * checker_name;
|
||
|
char * prio_name;
|
||
|
+ char * prio_args;
|
||
|
|
||
|
int pgpolicy;
|
||
|
int pgfailback;
|
||
|
@@ -42,6 +43,8 @@ struct mpentry {
|
||
|
char * alias;
|
||
|
char * getuid;
|
||
|
char * selector;
|
||
|
+ char * prio_name;
|
||
|
+ char * prio_args;
|
||
|
|
||
|
int pgpolicy;
|
||
|
int pgfailback;
|
||
|
@@ -95,6 +98,7 @@ struct config {
|
||
|
char * hwhandler;
|
||
|
char * bindings_file;
|
||
|
char * prio_name;
|
||
|
+ char * prio_args;
|
||
|
char * checker_name;
|
||
|
|
||
|
vector keywords;
|
||
|
Index: multipath-tools-091020/libmultipath/dict.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/dict.c
|
||
|
+++ multipath-tools-091020/libmultipath/dict.c
|
||
|
@@ -139,11 +139,23 @@ def_getuid_callout_handler(vector strvec
|
||
|
static int
|
||
|
def_prio_handler(vector strvec)
|
||
|
{
|
||
|
- conf->prio_name = set_value(strvec);
|
||
|
+ char *name, *args;
|
||
|
|
||
|
- if (!conf->prio_name)
|
||
|
+ name = set_value(strvec);
|
||
|
+ if (!name)
|
||
|
return 1;
|
||
|
|
||
|
+ args = strpbrk(name, " \t");
|
||
|
+ if (args) {
|
||
|
+ *args = 0;
|
||
|
+ while(*++args && isblank(*args)); /* Do nothing */
|
||
|
+ }
|
||
|
+
|
||
|
+ conf->prio_name = STRDUP(name);
|
||
|
+ if (args && *args)
|
||
|
+ conf->prio_args = STRDUP(args);
|
||
|
+
|
||
|
+ FREE(name);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -806,16 +818,27 @@ hw_handler_handler(vector strvec)
|
||
|
static int
|
||
|
hw_prio_handler(vector strvec)
|
||
|
{
|
||
|
+ char *name, *args;
|
||
|
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
||
|
|
||
|
if (!hwe)
|
||
|
return 1;
|
||
|
|
||
|
- hwe->prio_name = set_value(strvec);
|
||
|
-
|
||
|
- if (!hwe->prio_name)
|
||
|
+ name = set_value(strvec);
|
||
|
+ if (!name)
|
||
|
return 1;
|
||
|
|
||
|
+ args = strpbrk(name, " \t");
|
||
|
+ if (args) {
|
||
|
+ *args = 0;
|
||
|
+ while(*++args && isblank(*args)); /* Do nothing */
|
||
|
+ }
|
||
|
+
|
||
|
+ hwe->prio_name = STRDUP(name);
|
||
|
+ if (args && *args)
|
||
|
+ hwe->prio_args = STRDUP(args);
|
||
|
+
|
||
|
+ FREE(name);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -1293,6 +1316,33 @@ mp_flush_on_last_del_handler(vector strv
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+mp_prio_handler(vector strvec)
|
||
|
+{
|
||
|
+ char *name, *args;
|
||
|
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
|
||
|
+
|
||
|
+ if (!mpe)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ name = set_value(strvec);
|
||
|
+ if (!name)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ args = strpbrk(name, " \t");
|
||
|
+ if (args) {
|
||
|
+ *args = 0;
|
||
|
+ while(*++args && isblank(*args)); /* Do nothing */
|
||
|
+ }
|
||
|
+
|
||
|
+ mpe->prio_name = STRDUP(name);
|
||
|
+ if (args && *args)
|
||
|
+ mpe->prio_args = STRDUP(args);
|
||
|
+
|
||
|
+ FREE(name);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* config file keywords printing
|
||
|
*/
|
||
|
@@ -1472,6 +1522,20 @@ snprint_mp_flush_on_last_del (char * buf
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
+snprint_mp_prio (char * buff, int len, void * data)
|
||
|
+{
|
||
|
+ struct mpentry * mpe = (struct mpentry *)data;
|
||
|
+
|
||
|
+ if (!mpe->prio_name)
|
||
|
+ return 0;
|
||
|
+ if (!strcmp(mpe->prio_name, conf->prio_name) && !mpe->prio_args)
|
||
|
+ return 0;
|
||
|
+ if (!mpe->prio_args)
|
||
|
+ return snprintf(buff, len, "%s", mpe->prio_name);
|
||
|
+ return snprintf(buff, len, "%s %s", mpe->prio_name, mpe->prio_args);
|
||
|
+}
|
||
|
+
|
||
|
+static int
|
||
|
snprint_hw_fast_io_fail(char * buff, int len, void * data)
|
||
|
{
|
||
|
struct hwentry * hwe = (struct hwentry *)data;
|
||
|
@@ -1545,10 +1609,11 @@ snprint_hw_prio (char * buff, int len, v
|
||
|
|
||
|
if (!hwe->prio_name)
|
||
|
return 0;
|
||
|
- if (!strcmp(hwe->prio_name, conf->prio_name))
|
||
|
+ if (!strcmp(hwe->prio_name, conf->prio_name) && !hwe->prio_args)
|
||
|
return 0;
|
||
|
-
|
||
|
- return snprintf(buff, len, "%s", hwe->prio_name);
|
||
|
+ if (!hwe->prio_args)
|
||
|
+ return snprintf(buff, len, "%s", hwe->prio_name);
|
||
|
+ return snprintf(buff, len, "%s %s", hwe->prio_name, hwe->prio_args);
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -1837,10 +1902,14 @@ snprint_def_prio (char * buff, int len,
|
||
|
return 0;
|
||
|
|
||
|
if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
|
||
|
- !strcmp(conf->prio_name, DEFAULT_PRIO))
|
||
|
+ !strcmp(conf->prio_name, DEFAULT_PRIO) && !conf->prio_args)
|
||
|
return 0;
|
||
|
-
|
||
|
- return snprintf(buff, len, "%s", conf->prio_name);
|
||
|
+
|
||
|
+ if (!conf->prio_args)
|
||
|
+ return snprintf(buff, len, "%s", conf->prio_name);
|
||
|
+ else
|
||
|
+ return snprintf(buff, len, "%s %s", conf->prio_name,
|
||
|
+ conf->prio_args);
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -2146,5 +2215,6 @@ init_keywords(void)
|
||
|
install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
|
||
|
install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
|
||
|
install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
|
||
|
+ install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
|
||
|
install_sublevel_end();
|
||
|
}
|
||
|
Index: multipath-tools-091020/libmultipath/discovery.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/discovery.c
|
||
|
+++ multipath-tools-091020/libmultipath/discovery.c
|
||
|
@@ -800,30 +800,6 @@ get_state (struct path * pp, int daemon)
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
-get_prio (struct path * pp)
|
||
|
-{
|
||
|
- if (!pp)
|
||
|
- return 0;
|
||
|
-
|
||
|
- if (!pp->prio) {
|
||
|
- select_prio(pp);
|
||
|
- if (!pp->prio) {
|
||
|
- condlog(3, "%s: no prio selected", pp->dev);
|
||
|
- return 1;
|
||
|
- }
|
||
|
- }
|
||
|
- pp->priority = prio_getprio(pp->prio, pp);
|
||
|
- if (pp->priority < 0) {
|
||
|
- condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
|
||
|
- pp->priority = PRIO_UNDEF;
|
||
|
- return 1;
|
||
|
- }
|
||
|
- condlog(3, "%s: %s prio = %u",
|
||
|
- pp->dev, prio_name(pp->prio), pp->priority);
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-static int
|
||
|
get_uid (struct path * pp)
|
||
|
{
|
||
|
char buff[CALLOUT_MAX_SIZE];
|
||
|
@@ -850,6 +826,32 @@ get_uid (struct path * pp)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+get_prio (struct path * pp)
|
||
|
+{
|
||
|
+ if (!pp)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ if (!pp->prio) {
|
||
|
+ if (!strlen(pp->wwid))
|
||
|
+ get_uid(pp);
|
||
|
+ select_prio(pp);
|
||
|
+ if (!pp->prio) {
|
||
|
+ condlog(3, "%s: no prio selected", pp->dev);
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ pp->priority = prio_getprio(pp->prio, pp);
|
||
|
+ if (pp->priority < 0) {
|
||
|
+ condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
|
||
|
+ pp->priority = PRIO_UNDEF;
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
+ condlog(3, "%s: %s prio = %u",
|
||
|
+ pp->dev, prio_name(pp->prio), pp->priority);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
extern int
|
||
|
pathinfo (struct path *pp, vector hwtable, int mask)
|
||
|
{
|
||
|
@@ -887,6 +889,9 @@ pathinfo (struct path *pp, vector hwtabl
|
||
|
goto blank;
|
||
|
}
|
||
|
|
||
|
+ if (mask & DI_WWID && !strlen(pp->wwid))
|
||
|
+ get_uid(pp);
|
||
|
+
|
||
|
/*
|
||
|
* Retrieve path priority, even for PATH_DOWN paths if it has never
|
||
|
* been successfully obtained before.
|
||
|
@@ -895,9 +900,6 @@ pathinfo (struct path *pp, vector hwtabl
|
||
|
(pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
|
||
|
get_prio(pp);
|
||
|
|
||
|
- if (mask & DI_WWID && !strlen(pp->wwid))
|
||
|
- get_uid(pp);
|
||
|
-
|
||
|
return 0;
|
||
|
|
||
|
blank:
|
||
|
Index: multipath-tools-091020/libmultipath/prio.h
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/prio.h
|
||
|
+++ multipath-tools-091020/libmultipath/prio.h
|
||
|
@@ -24,6 +24,7 @@
|
||
|
#define PRIO_NETAPP "netapp"
|
||
|
#define PRIO_RANDOM "random"
|
||
|
#define PRIO_RDAC "rdac"
|
||
|
+#define PRIO_WEIGHTED "weighted"
|
||
|
|
||
|
/*
|
||
|
* Value used to mark the fact prio was not defined
|
||
|
Index: multipath-tools-091020/libmultipath/prioritizers/Makefile
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/prioritizers/Makefile
|
||
|
+++ multipath-tools-091020/libmultipath/prioritizers/Makefile
|
||
|
@@ -13,7 +13,8 @@ LIBS = \
|
||
|
libprioalua.so \
|
||
|
libpriotpg_pref.so \
|
||
|
libprionetapp.so \
|
||
|
- libpriohds.so
|
||
|
+ libpriohds.so \
|
||
|
+ libprioweighted.so \
|
||
|
|
||
|
CFLAGS += -I..
|
||
|
|
||
|
Index: multipath-tools-091020/libmultipath/prioritizers/weighted.c
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ multipath-tools-091020/libmultipath/prioritizers/weighted.c
|
||
|
@@ -0,0 +1,139 @@
|
||
|
+/******************************************************************************
|
||
|
+*******************************************************************************
|
||
|
+**
|
||
|
+** Copyright (C) 2009 Red Hat, Inc. All rights reserved.
|
||
|
+**
|
||
|
+** This copyrighted material is made available to anyone wishing to use,
|
||
|
+** modify, copy, or redistribute it subject to the terms and conditions
|
||
|
+** of the GNU General Public License v.2.
|
||
|
+**
|
||
|
+*******************************************************************************
|
||
|
+******************************************************************************/
|
||
|
+
|
||
|
+/* This prioritizer is based on a path's device name or its H:T:B:L. Both of
|
||
|
+ * these can change when the node is rebooted, and can differ from node to
|
||
|
+ * node. (i.e. there is no guarantee that sda will point to the same device
|
||
|
+ * after a reboot) If you use this prioritizer, it may be necessary to
|
||
|
+ * manually edit /etc/multipath.conf after any reboot
|
||
|
+ *
|
||
|
+ * Format:
|
||
|
+ * prio "weighted hbtl <regex> <prio> [<regex> <prio>]
|
||
|
+ * prio "weighted devname <regex> <prio> [<regex> <prio>]
|
||
|
+ *
|
||
|
+ * Examples:
|
||
|
+ * prio "weighted hbtl 4:* 2 3:.:.:. 1"
|
||
|
+ * prio "weighted devname sda 2 sde 1"
|
||
|
+ *
|
||
|
+ */
|
||
|
+
|
||
|
+#include <string.h>
|
||
|
+#include <prio.h>
|
||
|
+#include <debug.h>
|
||
|
+#include <regex.h>
|
||
|
+
|
||
|
+#include "weighted.h"
|
||
|
+
|
||
|
+#define DEFAULT_WEIGHTED_PRIO 0
|
||
|
+
|
||
|
+#define pp_weighted_log(prio, fmt, args...) \
|
||
|
+ condlog(prio, "%s: weighted prio: " fmt, dev, ##args)
|
||
|
+
|
||
|
+static char *
|
||
|
+next_str(char **str)
|
||
|
+{
|
||
|
+ char *next;
|
||
|
+
|
||
|
+ do {
|
||
|
+ next = strsep(str, " \t");
|
||
|
+ } while (next && strcmp(next, "") == 0);
|
||
|
+ return next;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static int
|
||
|
+match (char *dev, char *target, char *regex_str, char *prio_str,
|
||
|
+ unsigned int *prio)
|
||
|
+{
|
||
|
+
|
||
|
+ regex_t regex;
|
||
|
+ int err, ret = 0;
|
||
|
+ char *errbuf;
|
||
|
+ size_t errbuf_size;
|
||
|
+ unsigned int prio_match;
|
||
|
+
|
||
|
+ if (sscanf(prio_str, "%u", &prio_match) != 1) {
|
||
|
+ condlog(0, "%s: weighted prio: invalid prio '%s'", dev,
|
||
|
+ prio_str);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ err = regcomp(®ex, regex_str, REG_EXTENDED|REG_NOSUB);
|
||
|
+ if (err) {
|
||
|
+ errbuf_size = regerror(err, ®ex, NULL, 0);
|
||
|
+ errbuf = malloc(errbuf_size);
|
||
|
+ regerror(err, ®ex, errbuf, errbuf_size);
|
||
|
+ condlog(0, "%s: weighted prio: cannot compile regex '%s' : %s",
|
||
|
+ dev, regex_str, errbuf);
|
||
|
+ free(errbuf);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ if (regexec(®ex, target, 0, NULL, 0) == 0) {
|
||
|
+ *prio = prio_match;
|
||
|
+ ret = 1;
|
||
|
+ }
|
||
|
+
|
||
|
+ regfree(®ex);
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+prio_weighted(struct path * pp)
|
||
|
+{
|
||
|
+ char target[FILE_NAME_SIZE];
|
||
|
+ char *buff, *args, *ptr, *prio_str;
|
||
|
+ unsigned int prio = DEFAULT_WEIGHTED_PRIO;
|
||
|
+ char *regex_str = NULL;
|
||
|
+ int regex_size = 0;
|
||
|
+
|
||
|
+ if (!pp->prio_args)
|
||
|
+ return DEFAULT_WEIGHTED_PRIO;
|
||
|
+ buff = args = strdup(pp->prio_args);
|
||
|
+ ptr = next_str(&args);
|
||
|
+
|
||
|
+ if (strcasecmp(ptr, "hbtl") == 0)
|
||
|
+ sprintf(target, "%d:%d:%d:%d", pp->sg_id.host_no,
|
||
|
+ pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
|
||
|
+ else if (strcasecmp(ptr, "devname") == 0)
|
||
|
+ strcpy(target, pp->dev);
|
||
|
+ else {
|
||
|
+ condlog(0, "%s: weighted prio: invalid argument. Want 'hbtl' or 'devname'. Got '%s'", pp->dev, ptr);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ while ((ptr = next_str(&args)) != NULL) {
|
||
|
+
|
||
|
+ prio_str = next_str(&args);
|
||
|
+ if (!prio_str) {
|
||
|
+ condlog(0, "%s weighted prio: missing prio for regex '%s'", pp->dev, ptr);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ if (!regex_str || regex_size < strlen(ptr) + 3){
|
||
|
+ regex_size = strlen(ptr) + 3;
|
||
|
+ regex_str = realloc(regex_str, regex_size);
|
||
|
+ }
|
||
|
+ sprintf(regex_str, "%s%s%s", (ptr[0] == '^')? "" : "^",
|
||
|
+ ptr, (ptr[strlen(ptr)-1] == '$')? "" : "$");
|
||
|
+ if (match(pp->dev, target, regex_str, prio_str, &prio))
|
||
|
+ break;
|
||
|
+ }
|
||
|
+out:
|
||
|
+ free(buff);
|
||
|
+ if (regex_str)
|
||
|
+ free(regex_str);
|
||
|
+ return prio;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
+getprio(struct path * pp)
|
||
|
+{
|
||
|
+ return prio_weighted(pp);
|
||
|
+}
|
||
|
Index: multipath-tools-091020/libmultipath/propsel.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/propsel.c
|
||
|
+++ multipath-tools-091020/libmultipath/propsel.c
|
||
|
@@ -312,14 +312,25 @@ select_getuid (struct path * pp)
|
||
|
extern int
|
||
|
select_prio (struct path * pp)
|
||
|
{
|
||
|
+ struct mpentry * mpe;
|
||
|
+
|
||
|
+ if ((mpe = find_mpe(pp->wwid)) && mpe->prio_name) {
|
||
|
+ pp->prio = prio_lookup(mpe->prio_name);
|
||
|
+ pp->prio_args = mpe->prio_args;
|
||
|
+ condlog(3, "%s: prio = %s (LUN setting)",
|
||
|
+ pp->dev, mpe->prio_name);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
if (pp->hwe && pp->hwe->prio_name) {
|
||
|
pp->prio = prio_lookup(pp->hwe->prio_name);
|
||
|
+ pp->prio_args = pp->hwe->prio_args;
|
||
|
condlog(3, "%s: prio = %s (controller setting)",
|
||
|
pp->dev, pp->hwe->prio_name);
|
||
|
return 0;
|
||
|
}
|
||
|
if (conf->prio_name) {
|
||
|
pp->prio = prio_lookup(conf->prio_name);
|
||
|
+ pp->prio_args = conf->prio_args;
|
||
|
condlog(3, "%s: prio = %s (config file default)",
|
||
|
pp->dev, conf->prio_name);
|
||
|
return 0;
|
||
|
Index: multipath-tools-091020/libmultipath/structs.h
|
||
|
===================================================================
|
||
|
--- multipath-tools-091020.orig/libmultipath/structs.h
|
||
|
+++ multipath-tools-091020/libmultipath/structs.h
|
||
|
@@ -142,6 +142,7 @@ struct path {
|
||
|
int priority;
|
||
|
int pgindex;
|
||
|
char * getuid;
|
||
|
+ char * prio_args;
|
||
|
struct prio * prio;
|
||
|
struct checker checker;
|
||
|
struct multipath * mpp;
|
||
|
Index: multipath-tools-091020/libmultipath/prioritizers/weighted.h
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ multipath-tools-091020/libmultipath/prioritizers/weighted.h
|
||
|
@@ -0,0 +1,8 @@
|
||
|
+#ifndef _WEIGHTED_H
|
||
|
+#define _WEIGHTED_H
|
||
|
+
|
||
|
+#define PRIO_WEIGHTED "weighted"
|
||
|
+
|
||
|
+int prio_weighted(struct path *pp);
|
||
|
+
|
||
|
+#endif
|