[dm-devel] [patch] multipath-tools weighted path priority routine

Balasubramanian, Vijayakumar (STSD) vijayakumar at hp.com
Thu Nov 13 17:53:03 UTC 2008


Hi,
'Weighted path' is a new path prioritizer for device mapper multipath, where specific paths and the corresponding priority values can be provided as arguments.
This prioritizer assigns the priority value provided in the configuration file based on the comparison made between the specified paths and the path instance for which this is called. Paths can be specified as a regular expression of devname of the path or as hbtl information of the path.

Syntax:
weightedpath  <hbtl|devname> <regex1> <prio1> <regex2> <prio2> ...

Examples:
prio  "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"   #All paths through SCSI 'H' as '1' will take prio 2 and all paths with SCSI 'H' as 4 will take prio as 4.
prio  "weightedpath devname sda$ 10 sde$ 20"    #Path sda takes prio 10 and path sde takes prio 20. can be provided in multipath section.


This prioritizer allows user to set static load balancing for devices. Useful when user has prior knowledge of path performance difference or unavailability of certain paths.


The below patch
Allows 'prio' parameter to be set in "multipath" section,
Allows 'prio' priority routine to take arguments in multipath.conf file,
Adds 'weightedpath' priority routine.

Can we have this patch included in the source tree?

Thanks,
Vijay


-----------------------------------------------------------------------------------

Patch to implement weighted path priority routine in multipath-tools.

Signed-off-by:
                Veena T S <veena-s.t at hp.com>
                Sakshi Chaitanya Veni <sakshi-chaitanya.veni at hp.com>
                Vijayakumar Balasubramanian <vijayakumar at hp.com>

diff -pNur multipath-tools-0.4.8.org/libmultipath/config.c multipath-tools-0.4.8/libmultipath/config.c
--- multipath-tools-0.4.8.org/libmultipath/config.c     2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/config.c 2008-11-12 10:26:55.000000000 +0530
@@ -201,6 +201,12 @@ free_mpe (struct mpentry * mpe)
        if (mpe->alias)
                FREE(mpe->alias);

+       if (mpe->prio_name)
+               FREE(mpe->prio_name);
+
+       if (mpe->prio_arg)
+               FREE(mpe->prio_arg);
+
        FREE(mpe);
 }

@@ -285,6 +291,7 @@ merge_hwe (struct hwentry * hwe1, struct
        merge_str(selector);
        merge_str(checker_name);
        merge_str(prio_name);
+       merge_str(prio_arg);
        merge_str(bl_product);
        merge_num(pgpolicy);
        merge_num(pgfailback);
@@ -333,6 +340,9 @@ store_hwe (vector hwtable, struct hwentr
        if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
                goto out;

+       if (dhwe->prio_arg && !(hwe->prio_arg = set_param_str(dhwe->prio_arg)))
+               goto out;
+
        hwe->pgpolicy = dhwe->pgpolicy;
        hwe->pgfailback = dhwe->pgfailback;
        hwe->rr_weight = dhwe->rr_weight;
@@ -547,8 +557,10 @@ load_config (char * file)
            !conf->hwhandler || !conf->bindings_file)
                goto out;

-       if (!conf->prio_name)
+       if (!conf->prio_name) {
                conf->prio_name = set_default(DEFAULT_PRIO);
+               conf->prio_arg = NULL;
+       }

        if (!conf->checker_name)
                conf->checker_name = set_default(DEFAULT_CHECKER);
diff -pNur multipath-tools-0.4.8.org/libmultipath/config.h multipath-tools-0.4.8/libmultipath/config.h
--- multipath-tools-0.4.8.org/libmultipath/config.h     2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/config.h 2008-11-12 10:23:28.000000000 +0530
@@ -21,6 +21,7 @@ struct hwentry {
        char * selector;
        char * checker_name;
        char * prio_name;
+       char * prio_arg;

        int pgpolicy;
        int pgfailback;
@@ -37,6 +38,8 @@ struct mpentry {
        char * getuid;
        char * selector;

+       char * prio_name;
+       char * prio_arg;
        int pgpolicy;
        int pgfailback;
        int rr_weight;
@@ -75,6 +78,7 @@ struct config {
        char * hwhandler;
        char * bindings_file;
        char * prio_name;
+       char * prio_arg;
        char * checker_name;

        vector keywords;
diff -pNur multipath-tools-0.4.8.org/libmultipath/dict.c multipath-tools-0.4.8/libmultipath/dict.c
--- multipath-tools-0.4.8.org/libmultipath/dict.c       2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/dict.c   2008-11-13 20:03:10.000000000 +0530
@@ -4,6 +4,7 @@
  * Copyright (c) 2005 Benjamin Marzinski, Redhat
  * Copyright (c) 2005 Kiyoshi Ueda, NEC
  */
+#include <string.h>
 #include "checkers.h"
 #include "vector.h"
 #include "hwtable.h"
@@ -95,11 +96,29 @@ def_getuid_callout_handler(vector strvec
 static int
 def_prio_handler(vector strvec)
 {
-       conf->prio_name = set_value(strvec);
+       char *buff, *result, *temp;
+       char split_char[] = " \t";

-       if (!conf->prio_name)
+       buff = set_value(strvec);
+       if (!buff)
                return 1;
+       temp = buff;
+
+       while (temp) {
+               result = strsep(&temp, split_char);
+               if (strcmp(result, "")) {
+                       if (prio_lookup(result)) {
+                               conf->prio_name = STRDUP(result);
+                               if (temp)
+                                       conf->prio_arg = STRDUP(temp);
+                               else
+                                       conf->prio_arg = NULL;
+                               break;
+                       }
+               }
+       }

+       FREE(buff);
        return 0;
 }

@@ -602,15 +621,32 @@ static int
 hw_prio_handler(vector strvec)
 {
        struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+       char *buff, *result, *temp;
+       char split_char[] = " \t";

        if (!hwe)
                return 1;

-       hwe->prio_name = set_value(strvec);
-
-       if (!hwe->prio_name)
+       buff = set_value(strvec);
+       if (!buff)
                return 1;
+       temp = buff;

+       while (temp) {
+               result = strsep(&temp, split_char);
+               if (strcmp(result, "")) {
+                       if (prio_lookup(result)) {
+                               hwe->prio_name = STRDUP(result);
+                               if (temp)
+                                       hwe->prio_arg = STRDUP(temp);
+                               else
+                                       hwe->prio_arg = NULL;
+                               break;
+                       }
+               }
+       }
+
+       FREE(buff);
        return 0;
 }

@@ -956,6 +992,41 @@ mp_pg_timeout_handler(vector strvec)
        return 0;
 }

+static int
+mp_prio_handler (vector strvec)
+{
+       struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+       char *buff, *result, *temp;
+       char split_char[] = " \t";
+
+       if (!mpe)
+               return 1;
+
+       buff = set_value(strvec);
+
+       if (!buff)
+               return 1;
+
+       temp = buff;
+
+       while (temp) {
+               result = strsep(&temp, split_char);
+               if (strcmp(result, "")) {
+                       if (prio_lookup(result)) {
+                               mpe->prio_name = STRDUP(result);
+                               if (temp)
+                                       mpe->prio_arg = STRDUP(temp);
+                               else
+                                       mpe->prio_arg = NULL;
+                               break;
+                       }
+               }
+       }
+
+       FREE(buff);
+       return 0;
+}
+
 /*
  * config file keywords printing
  */
@@ -1091,6 +1162,17 @@ snprint_mp_pg_timeout (char * buff, int
 }

 static int
+snprint_mp_prio(char * buff, int len, void * data)
+{
+       struct mpentry * mpe = (struct mpentry *)data;
+
+       if (!mpe->prio_name)
+               return 0;
+
+       return snprintf(buff, len, "%s", mpe->prio_name);
+}
+
+static int
 snprint_hw_vendor (char * buff, int len, void * data)
 {
        struct hwentry * hwe = (struct hwentry *)data;
@@ -1652,6 +1734,7 @@ init_keywords(void)
        install_keyword("alias", &alias_handler, &snprint_mp_alias);
        install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_path_grouping_policy);
        install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
+       install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
        install_keyword("failback", &mp_failback_handler, &snprint_mp_failback);
        install_keyword("rr_weight", &mp_weight_handler, &snprint_mp_rr_weight);
        install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
diff -pNur multipath-tools-0.4.8.org/libmultipath/discovery.c multipath-tools-0.4.8/libmultipath/discovery.c
--- multipath-tools-0.4.8.org/libmultipath/discovery.c  2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/discovery.c      2008-11-13 19:43:55.000000000 +0530
@@ -759,8 +759,11 @@ pathinfo (struct path *pp, vector hwtabl
          * been successfully obtained before.
          */
        if (mask & DI_PRIO &&
-           (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
+           (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF)) {
+               if (!strlen(pp->wwid))
+                       get_uid(pp);
                get_prio(pp);
+       }

        if (mask & DI_WWID && !strlen(pp->wwid))
                get_uid(pp);
diff -pNur multipath-tools-0.4.8.org/libmultipath/prio.h multipath-tools-0.4.8/libmultipath/prio.h
--- multipath-tools-0.4.8.org/libmultipath/prio.h       2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/prio.h   2008-11-13 22:41:11.000000000 +0530
@@ -24,6 +24,7 @@
 #define PRIO_ONTAP "ontap"
 #define PRIO_RANDOM "random"
 #define PRIO_RDAC "rdac"
+#define PRIO_WEIGHTED_PATH "weightedpath"

 /*
  * Value used to mark the fact prio was not defined
diff -pNur multipath-tools-0.4.8.org/libmultipath/prioritizers/Makefile multipath-tools-0.4.8/libmultipath/prioritizers/Makefile
--- multipath-tools-0.4.8.org/libmultipath/prioritizers/Makefile        2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/prioritizers/Makefile    2008-11-11 18:11:07.000000000 +0530
@@ -12,7 +12,8 @@ LIBS = \
        libpriordac.so \
        libprioalua.so \
        libprioontap.so \
-       libpriohds.so
+       libpriohds.so \
+       libprioweightedpath.so

 CFLAGS += -I..

diff -pNur multipath-tools-0.4.8.org/libmultipath/prioritizers/weightedpath.c multipath-tools-0.4.8/libmultipath/prioritizers/weightedpath.c
--- multipath-tools-0.4.8.org/libmultipath/prioritizers/weightedpath.c  1970-01-01 05:30:00.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/prioritizers/weightedpath.c      2008-11-13 20:04:47.000000000 +0530
@@ -0,0 +1,99 @@
+/*
+ *
+ *  (C)  Copyright 2008 Hewlett-Packard Development Company, L.P
+ *
+ *  This file is released under the GPL
+ */
+
+/*
+ * Prioritizer for device mapper multipath, where specific paths and the
+ * corresponding priority values are provided as arguments.
+ *
+ * This prioritizer assigns the priority value provided in the configuration
+ * file based on the comparison made between the specified paths and the path
+ * instance for which this is called.
+ * Paths can be specified as a regular expression of devname of the path or
+ * as hbtl information of the path.
+ *
+ * Examples:
+ *     prio            "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
+ *     prio            "weightedpath devname sda 10 sde 20"
+ *
+ * Returns zero as the default priority.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <prio.h>
+#include "weightedpath.h"
+#include <config.h>
+#include <structs.h>
+#include <memory.h>
+#include <debug.h>
+#include <regex.h>
+
+char *get_next_string(char **temp, char *split_char)
+{
+       char *token = NULL;
+       token = strsep(temp, split_char);
+       while (token != NULL && !strcmp(token, ""))
+               token = strsep(temp, split_char);
+       return token;
+}
+
+/* main priority routine */
+int prio_path_weight(struct path *pp)
+{
+       char path[FILE_NAME_SIZE];
+       char *arg;
+       char *temp, *regex, *prio;
+       char split_char[] = " \t";
+       int priority = DEFAULT_PRIORITY, path_found = 0;
+       regex_t pathe;
+
+       /* Return default priority if there is no argument */
+       if (!pp->prio_arg)
+               return priority;
+
+       arg = temp = STRDUP(pp->prio_arg);
+
+       regex = get_next_string(&temp, split_char);
+
+       if (!strcmp(regex, HBTL)) {
+               sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no,
+                       pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
+       } else if (!strcmp(regex, DEV_NAME)) {
+               strcpy(path, pp->dev);
+       } else {
+               condlog(0, "%s: %s - Invalid arguments", pp->dev,
+                       pp->prio->name);
+               return priority;
+       }
+
+       while (!path_found) {
+               if (!temp)
+                       break;
+               if (!(regex = get_next_string(&temp, split_char)))
+                       break;
+               if (!(prio = get_next_string(&temp, split_char)))
+                       break;
+
+               if (!regcomp(&pathe, regex, REG_EXTENDED|REG_NOSUB)) {
+                       if (!regexec(&pathe, path, 0, NULL, 0)) {
+                               path_found = 1;
+                               priority = atoi(prio);
+                       }
+                       regfree(&pathe);
+               }
+       }
+
+       FREE(arg);
+       return priority;
+}
+
+int getprio(struct path *pp)
+{
+       return prio_path_weight(pp);
+}
+
diff -pNur multipath-tools-0.4.8.org/libmultipath/prioritizers/weightedpath.h multipath-tools-0.4.8/libmultipath/prioritizers/weightedpath.h
--- multipath-tools-0.4.8.org/libmultipath/prioritizers/weightedpath.h  1970-01-01 05:30:00.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/prioritizers/weightedpath.h      2008-11-13 19:56:10.000000000 +0530
@@ -0,0 +1,11 @@
+#ifndef _WEIGHTED_PATH_H
+#define _WEIGHTED_PATH_H
+
+#define PRIO_WEIGHTED_PATH "weightedpath"
+#define HBTL "hbtl"
+#define DEV_NAME "devname"
+#define DEFAULT_PRIORITY 0
+
+int prio_path_weight(struct path *pp);
+
+#endif
diff -pNur multipath-tools-0.4.8.org/libmultipath/propsel.c multipath-tools-0.4.8/libmultipath/propsel.c
--- multipath-tools-0.4.8.org/libmultipath/propsel.c    2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/propsel.c        2008-11-13 19:58:58.000000000 +0530
@@ -258,14 +258,28 @@ select_getuid (struct path * pp)
 extern int
 select_prio (struct path * pp)
 {
+       struct mpentry * mpe;
+
+       if ((mpe = find_mpe(pp->wwid))) {
+               if (mpe->prio_name) {
+                       pp->prio = prio_lookup(mpe->prio_name);
+                       pp->prio_arg = mpe->prio_arg;
+                       condlog(3, "%s: prio = %s (LUN setting)",
+                               pp->dev, pp->prio->name);
+                       return 0;
+               }
+       }
+
        if (pp->hwe && pp->hwe->prio_name) {
                pp->prio = prio_lookup(pp->hwe->prio_name);
+               pp->prio_arg = pp->hwe->prio_arg;
                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_arg = conf->prio_arg;
                condlog(3, "%s: prio = %s (config file default)",
                        pp->dev, conf->prio_name);
                return 0;
diff -pNur multipath-tools-0.4.8.org/libmultipath/structs.h multipath-tools-0.4.8/libmultipath/structs.h
--- multipath-tools-0.4.8.org/libmultipath/structs.h    2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/libmultipath/structs.h        2008-11-11 18:11:07.000000000 +0530
@@ -121,6 +121,7 @@ struct path {
        int pgindex;
        char * getuid;
        struct prio * prio;
+       char * prio_arg;
        struct checker checker;
        struct multipath * mpp;
        int fd;
diff -pNur multipath-tools-0.4.8.org/multipath/multipath.conf.5 multipath-tools-0.4.8/multipath/multipath.conf.5
--- multipath-tools-0.4.8.org/multipath/multipath.conf.5        2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/multipath/multipath.conf.5    2008-11-13 22:36:05.000000000 +0530
@@ -146,6 +146,24 @@ Generate the path priority for Hitachi H
 Default value is \fBnone\fR.
 .RE
 .TP
+.B prio
+The default program and args to path priority routine. The specified
+routine should return a numeric value specifying the relative priority
+of this path. Higher number have a higher priority.
+.RS
+.TP 12
+.B alua
+Generate the path priority based on ALUA status of the path.
+.TP 12
+.B weightedpath <hbtl|devname> <regex1> <prio1> <regex2> <prio2> ...
+.I hbtl
+regex can be of SCSI H:B:T:L format  Ex: 1:0:.:. , *:0:0:.
+.I devname
+regex can be of device name format  Ex: sda , sd.e
+Generate the path priority based on the regular expression and the
+priority provided as argument.
+.RE
+.TP
 .B features
 Specify any device-mapper features to be used. Syntax is
 .I num list
@@ -322,6 +340,8 @@ section:
 .TP
 .B path_selector
 .TP
+.B prio
+.TP
 .B failback
 .TP
 .B no_path_retry
@@ -375,6 +395,8 @@ section:
 .TP
 .B path_checker
 .TP
+.B prio
+.TP
 .B features
 .TP
 .B prio_callout
diff -pNur multipath-tools-0.4.8.org/multipath.conf.annotated multipath-tools-0.4.8/multipath.conf.annotated
--- multipath-tools-0.4.8.org/multipath.conf.annotated  2008-11-11 18:11:56.000000000 +0530
+++ multipath-tools-0.4.8/multipath.conf.annotated      2008-11-12 18:29:01.000000000 +0530
@@ -261,6 +261,18 @@
 #              # default : 1000
 #              #
 #              rr_min_io       100
+#
+#              #
+#              #name     : prio
+#              #scope    : multipath
+#              #desc     : the function to call to obtain a path weight.
+#              #           Weights are summed for each path group to
+#              #           determine the next PG to use case of failure.
+#              #default : no callout, all paths equals
+#              # Ex:
+#              # prio  alua
+#              # prio  "weightedpath devname sda 50 sde 10 sdc 50 sdf 10"
+#              prio          "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
 #      }
 #      multipath {
 #              wwid    1DEC_____321816758474
-------------- next part --------------
A non-text attachment was scrubbed...
Name: multipath-tools-add-weightedpath.patch
Type: application/octet-stream
Size: 14467 bytes
Desc: multipath-tools-add-weightedpath.patch
URL: <http://listman.redhat.com/archives/dm-devel/attachments/20081113/8deb1793/attachment.obj>


More information about the dm-devel mailing list