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@xxxxxx> Sakshi Chaitanya Veni <sakshi-chaitanya.veni@xxxxxx> Vijayakumar Balasubramanian <vijayakumar@xxxxxx> 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
Attachment:
multipath-tools-add-weightedpath.patch
Description: multipath-tools-add-weightedpath.patch
-- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel