From 803929adb51de2e33cc4bc59b22e2fc29233016c Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 17 Nov 2009 06:33:04 +0000 Subject: [PATCH] - Add 0002-for-upstream-add-tmo-config-options.patch Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options - Add 0013-RH-add-weighted_prio-prioritizer.patch - Add 0014-RH-add-hp_tur-checker.patch - Add 0015-RH-add-multipathd-count-paths-cmd.patch - rename multipath.conf.redhat to multipath.conf, and remove the default blacklist --- ...-for-upstream-add-tmo-config-options.patch | 511 +++++++++++++++++ 0013-RH-add-weighted_prio-prioritizer.patch | 533 ++++++++++++++++++ 0014-RH-add-hp_tur-checker.patch | 207 +++++++ 0015-RH-add-multipathd-count-paths-cmd.patch | 150 +++++ device-mapper-multipath.spec | 23 +- multipath.conf.redhat => multipath.conf | 7 - 6 files changed, 1421 insertions(+), 10 deletions(-) create mode 100644 0002-for-upstream-add-tmo-config-options.patch create mode 100644 0013-RH-add-weighted_prio-prioritizer.patch create mode 100644 0014-RH-add-hp_tur-checker.patch create mode 100644 0015-RH-add-multipathd-count-paths-cmd.patch rename multipath.conf.redhat => multipath.conf (95%) diff --git a/0002-for-upstream-add-tmo-config-options.patch b/0002-for-upstream-add-tmo-config-options.patch new file mode 100644 index 0000000..dba3659 --- /dev/null +++ b/0002-for-upstream-add-tmo-config-options.patch @@ -0,0 +1,511 @@ +--- + libmultipath/config.h | 4 + + libmultipath/configure.c | 3 + + libmultipath/dict.c | 102 +++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/discovery.c | 37 ++++++++++++++++ + libmultipath/discovery.h | 1 + libmultipath/propsel.c | 42 ++++++++++++++++++ + libmultipath/propsel.h | 2 + libmultipath/structs.h | 2 + libmultipath/sysfs.c | 56 ++++++++++++++++++++++++ + libmultipath/sysfs.h | 3 - + multipath.conf.annotated | 38 ++++++++++++++++ + multipath/multipath.conf.5 | 15 ++++++ + 12 files changed, 303 insertions(+), 2 deletions(-) + +Index: multipath-tools-091020/multipath.conf.annotated +=================================================================== +--- multipath-tools-091020.orig/multipath.conf.annotated ++++ multipath-tools-091020/multipath.conf.annotated +@@ -191,6 +191,25 @@ + # # default : determined by the process + # gid disk + # ++# # ++# # name : fast_io_fail_tmo ++# # scope : multipath & multipathd ++# # desc : The number of seconds the scsi layer will wait after a ++# # problem has been detected on a FC remote port before failing ++# # IO to devices on that remote port. ++# # values : off | n >= 0 (smaller than dev_loss_tmo) ++# # default : determined by the OS ++# fast_io_fail_tmo 5 ++# ++# # ++# # name : dev_loss_tmo ++# # scope : multipath & multipathd ++# # desc : The number of seconds the scsi layer will wait after a ++# # problem has been detected on a FC remote port before ++# # removing it from the system. ++# # values : n > 0 ++# # default : determined by the OS ++# dev_loss_tmo 600 + #} + # + ## +@@ -504,7 +523,6 @@ + # # desc : If set to "yes", multipathd will disable queueing + # # when the last path to a device has been deleted. + # # values : yes|no +-# # default : no + # # + # flush_on_last_del yes + # +@@ -514,6 +532,24 @@ + # # desc : product strings to blacklist for this vendor + # # + # product_blacklist LUN_Z ++# ++# # ++# # name : fast_io_fail_tmo ++# # scope : multipath & multipathd ++# # desc : The number of seconds the scsi layer will wait after ++# # a problem has been detected on a FC remote port ++# # before failing IO to devices on that remote port. ++# # values : off | n >= 0 (smaller than dev_loss_tmo) ++# fast_io_fail_tmo 5 ++# ++# # ++# # name : dev_loss_tmo ++# # scope : multipath & multipathd ++# # desc : The number of seconds the scsi layer will wait after ++# # a problem has been detected on a FC remote port ++# # before removing it from the system. ++# # values : n > 0 ++# dev_loss_tmo 600 + # } + # device { + # vendor "COMPAQ " +Index: multipath-tools-091020/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-091020.orig/multipath/multipath.conf.5 ++++ multipath-tools-091020/multipath/multipath.conf.5 +@@ -240,6 +240,17 @@ this to the system limit from /proc/sys/ + maximum number of open fds is taken from the calling process. It is usually + 1024. To be safe, this should be set to the maximum number of paths plus 32, + if that number is greated than 1024. ++.TP ++.B fast_io_fail_tmo ++Specify the number of seconds the scsi layer will wait after a problem has been ++detected on a FC remote port before failing IO to devices on that remote port. ++This should be smaller than dev_loss_tmo. Setting this to ++.I off ++will disable the timeout. ++.TP ++.B dev_loss_tmo ++Specify the number of seconds the scsi layer will wait after a problem has ++been detected on a FC remote port before removing it from the system. + . + .SH "blacklist section" + The +@@ -384,6 +395,10 @@ section: + .B no_path_retry + .TP + .B rr_min_io ++.TP ++.B fast_io_fail_tmo ++.TP ++.B dev_loss_tmo + .RE + .PD + .LP +Index: multipath-tools-091020/libmultipath/dict.c +=================================================================== +--- multipath-tools-091020.orig/libmultipath/dict.c ++++ multipath-tools-091020/libmultipath/dict.c +@@ -37,6 +37,35 @@ polling_interval_handler(vector strvec) + } + + static int ++def_fast_io_fail_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (strlen(buff) == 3 && !strcmp(buff, "off")) ++ conf->fast_io_fail = -1; ++ else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 || ++ conf->fast_io_fail < -1) ++ conf->fast_io_fail = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++def_dev_loss_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (sscanf(buff, "%u", &conf->dev_loss) != 1) ++ conf->dev_loss = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + verbosity_handler(vector strvec) + { + char * buff; +@@ -628,6 +657,37 @@ bl_product_handler(vector strvec) + } + + static int ++hw_fast_io_fail_handler(vector strvec) ++{ ++ char * buff; ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ ++ buff = set_value(strvec); ++ if (strlen(buff) == 3 && !strcmp(buff, "off")) ++ hwe->fast_io_fail = -1; ++ else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 || ++ hwe->fast_io_fail < -1) ++ hwe->fast_io_fail = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++hw_dev_loss_handler(vector strvec) ++{ ++ char * buff; ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ ++ buff = set_value(strvec); ++ if (sscanf(buff, "%u", &hwe->dev_loss) != 1) ++ hwe->dev_loss = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + hw_pgpolicy_handler(vector strvec) + { + char * buff; +@@ -1390,6 +1450,26 @@ snprint_mp_flush_on_last_del (char * buf + } + + static int ++snprint_hw_fast_io_fail(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ if (!hwe->fast_io_fail) ++ return 0; ++ if (hwe->fast_io_fail == -1) ++ return snprintf(buff, len, "off"); ++ return snprintf(buff, len, "%d", hwe->fast_io_fail); ++} ++ ++static int ++snprint_hw_dev_loss(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ if (!hwe->dev_loss) ++ return 0; ++ return snprintf(buff, len, "%u", hwe->dev_loss); ++} ++ ++static int + snprint_hw_vendor (char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -1640,6 +1720,24 @@ snprint_def_polling_interval (char * buf + } + + static int ++snprint_def_fast_io_fail(char * buff, int len, void * data) ++{ ++ if (!conf->fast_io_fail) ++ return 0; ++ if (conf->fast_io_fail == -1) ++ return snprintf(buff, len, "off"); ++ return snprintf(buff, len, "%d", conf->fast_io_fail); ++} ++ ++static int ++snprint_def_dev_loss(char * buff, int len, void * data) ++{ ++ if (!conf->dev_loss) ++ return 0; ++ return snprintf(buff, len, "%u", conf->dev_loss); ++} ++ ++static int + snprint_def_verbosity (char * buff, int len, void * data) + { + if (conf->checkint == DEFAULT_VERBOSITY) +@@ -1937,6 +2035,8 @@ init_keywords(void) + install_keyword("mode", &def_mode_handler, &snprint_def_mode); + install_keyword("uid", &def_uid_handler, &snprint_def_uid); + install_keyword("gid", &def_gid_handler, &snprint_def_gid); ++ install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); ++ install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL); +@@ -1991,6 +2091,8 @@ init_keywords(void) + install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io); + install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout); + install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); ++ install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); ++ install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); + install_sublevel_end(); + + install_keyword_root("multipaths", &multipaths_handler); +Index: multipath-tools-091020/libmultipath/config.h +=================================================================== +--- multipath-tools-091020.orig/libmultipath/config.h ++++ multipath-tools-091020/libmultipath/config.h +@@ -31,6 +31,8 @@ struct hwentry { + int minio; + int pg_timeout; + int flush_on_last_del; ++ int fast_io_fail; ++ unsigned int dev_loss; + char * bl_product; + }; + +@@ -75,6 +77,8 @@ struct config { + int daemon; + int flush_on_last_del; + int attribute_flags; ++ int fast_io_fail; ++ unsigned int dev_loss; + uid_t uid; + gid_t gid; + mode_t mode; +Index: multipath-tools-091020/libmultipath/propsel.c +=================================================================== +--- multipath-tools-091020.orig/libmultipath/propsel.c ++++ multipath-tools-091020/libmultipath/propsel.c +@@ -428,6 +428,48 @@ select_pg_timeout(struct multipath *mp) + } + + extern int ++select_fast_io_fail(struct multipath *mp) ++{ ++ if (mp->hwe && mp->hwe->fast_io_fail) { ++ mp->fast_io_fail = mp->hwe->fast_io_fail; ++ if (mp->fast_io_fail == -1) ++ condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias); ++ else ++ condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias, mp->fast_io_fail); ++ return 0; ++ } ++ if (conf->fast_io_fail) { ++ mp->fast_io_fail = conf->fast_io_fail; ++ if (mp->fast_io_fail == -1) ++ condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias); ++ else ++ condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias, mp->fast_io_fail); ++ return 0; ++ } ++ mp->fast_io_fail = 0; ++ return 0; ++} ++ ++extern int ++select_dev_loss(struct multipath *mp) ++{ ++ if (mp->hwe && mp->hwe->dev_loss) { ++ mp->dev_loss = mp->hwe->dev_loss; ++ condlog(3, "%s: dev_loss_tmo = %u (controller default)", ++ mp->alias, mp->dev_loss); ++ return 0; ++ } ++ if (conf->dev_loss) { ++ mp->dev_loss = conf->dev_loss; ++ condlog(3, "%s: dev_loss_tmo = %u (config file default)", ++ mp->alias, mp->dev_loss); ++ return 0; ++ } ++ mp->dev_loss = 0; ++ return 0; ++} ++ ++extern int + select_flush_on_last_del(struct multipath *mp) + { + if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) +Index: multipath-tools-091020/libmultipath/structs.h +=================================================================== +--- multipath-tools-091020.orig/libmultipath/structs.h ++++ multipath-tools-091020/libmultipath/structs.h +@@ -166,6 +166,8 @@ struct multipath { + int pg_timeout; + int flush_on_last_del; + int attribute_flags; ++ int fast_io_fail; ++ unsigned int dev_loss; + uid_t uid; + gid_t gid; + mode_t mode; +Index: multipath-tools-091020/libmultipath/configure.c +=================================================================== +--- multipath-tools-091020.orig/libmultipath/configure.c ++++ multipath-tools-091020/libmultipath/configure.c +@@ -70,7 +70,10 @@ setup_map (struct multipath * mpp) + select_mode(mpp); + select_uid(mpp); + select_gid(mpp); ++ select_fast_io_fail(mpp); ++ select_dev_loss(mpp); + ++ sysfs_set_scsi_tmo(mpp); + /* + * assign paths to path groups -- start with no groups and all paths + * in mpp->paths +Index: multipath-tools-091020/libmultipath/discovery.c +=================================================================== +--- multipath-tools-091020.orig/libmultipath/discovery.c ++++ multipath-tools-091020/libmultipath/discovery.c +@@ -204,6 +204,43 @@ sysfs_get_fc_nodename (struct sysfs_devi + return 1; + } + ++int ++sysfs_set_scsi_tmo (struct multipath *mpp) ++{ ++ char attr_path[SYSFS_PATH_SIZE]; ++ struct path *pp; ++ int i; ++ char value[11]; ++ ++ if (!mpp->dev_loss && !mpp->fast_io_fail) ++ return 0; ++ vector_foreach_slot(mpp->paths, pp, i) { ++ if (safe_snprintf(attr_path, SYSFS_PATH_SIZE, ++ "/class/fc_remote_ports/rport-%d:%d-%d", ++ pp->sg_id.host_no, pp->sg_id.channel, ++ pp->sg_id.scsi_id)) { ++ condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id); ++ return 1; ++ } ++ if (mpp->dev_loss){ ++ snprintf(value, 11, "%u", mpp->dev_loss); ++ if (sysfs_attr_set_value(attr_path, "dev_loss_tmo", ++ value)) ++ return 1; ++ } ++ if (mpp->fast_io_fail){ ++ if (mpp->fast_io_fail == -1) ++ sprintf(value, "off"); ++ else ++ snprintf(value, 11, "%u", mpp->fast_io_fail); ++ if (sysfs_attr_set_value(attr_path, "fast_io_fail", ++ value)) ++ return 1; ++ } ++ } ++ return 0; ++} ++ + static int + opennode (char * dev, int mode) + { +Index: multipath-tools-091020/libmultipath/propsel.h +=================================================================== +--- multipath-tools-091020.orig/libmultipath/propsel.h ++++ multipath-tools-091020/libmultipath/propsel.h +@@ -15,3 +15,5 @@ int select_minio(struct multipath *mp); + int select_mode(struct multipath *mp); + int select_uid(struct multipath *mp); + int select_gid(struct multipath *mp); ++int select_fast_io_fail(struct multipath *mp); ++int select_dev_loss(struct multipath *mp); +Index: multipath-tools-091020/libmultipath/discovery.h +=================================================================== +--- multipath-tools-091020.orig/libmultipath/discovery.h ++++ multipath-tools-091020/libmultipath/discovery.h +@@ -33,6 +33,7 @@ int path_offline (struct path *); + int pathinfo (struct path *, vector hwtable, int mask); + struct path * store_pathinfo (vector pathvec, vector hwtable, + char * devname, int flag); ++int sysfs_set_scsi_tmo (struct multipath *mpp); + + /* + * discovery bitmask +Index: multipath-tools-091020/libmultipath/sysfs.c +=================================================================== +--- multipath-tools-091020.orig/libmultipath/sysfs.c ++++ multipath-tools-091020/libmultipath/sysfs.c +@@ -356,6 +356,62 @@ void sysfs_device_put(struct sysfs_devic + return; + } + ++int ++sysfs_attr_set_value(const char *devpath, const char *attr_name, ++ const char *value) ++{ ++ char path_full[PATH_SIZE]; ++ int sysfs_len; ++ struct stat statbuf; ++ int fd, value_len, ret = -1; ++ ++ dbg("open '%s'/'%s'", devpath, attr_name); ++ sysfs_len = snprintf(path_full, PATH_SIZE, "%s%s/%s", sysfs_path, ++ devpath, attr_name); ++ if (sysfs_len >= PATH_SIZE || sysfs_len < 0) { ++ if (sysfs_len < 0) ++ dbg("cannot copy sysfs path %s%s/%s : %s", sysfs_path, ++ devpath, attr_name, strerror(errno)); ++ else ++ dbg("sysfs_path %s%s/%s too large", sysfs_path, ++ devpath, attr_name); ++ goto out; ++ } ++ ++ if (stat(path_full, &statbuf) != 0) { ++ dbg("stat '%s' failed: %s" path_full, strerror(errno)); ++ goto out; ++ } ++ ++ /* skip directories */ ++ if (S_ISDIR(statbuf.st_mode)) ++ goto out; ++ ++ if ((statbuf.st_mode & S_IWUSR) == 0) ++ goto out; ++ ++ fd = open(path_full, O_WRONLY); ++ if (fd < 0) { ++ dbg("attribute '%s' can not be opened: %s", ++ path_full, strerror(errno)); ++ goto out; ++ } ++ value_len = strlen(value) + 1; ++ ret = write(fd, value, value_len); ++ if (ret == value_len) ++ ret = 0; ++ else if (ret < 0) ++ dbg("write to %s failed: %s", path_full, strerror(errno)); ++ else { ++ dbg("tried to write %d to %s. Wrote %d\n", value_len, ++ path_full, ret); ++ ret = -1; ++ } ++out: ++ return ret; ++} ++ ++ + char *sysfs_attr_get_value(const char *devpath, const char *attr_name) + { + char path_full[PATH_SIZE]; +Index: multipath-tools-091020/libmultipath/sysfs.h +=================================================================== +--- multipath-tools-091020.orig/libmultipath/sysfs.h ++++ multipath-tools-091020/libmultipath/sysfs.h +@@ -22,5 +22,6 @@ void sysfs_device_put(struct sysfs_devic + char *sysfs_attr_get_value(const char *devpath, const char *attr_name); + int sysfs_resolve_link(char *path, size_t size); + int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size); +- ++int sysfs_attr_set_value(const char *devpath, const char *attr_name, ++ const char *value); + #endif diff --git a/0013-RH-add-weighted_prio-prioritizer.patch b/0013-RH-add-weighted_prio-prioritizer.patch new file mode 100644 index 0000000..2d2fc2f --- /dev/null +++ b/0013-RH-add-weighted_prio-prioritizer.patch @@ -0,0 +1,533 @@ +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 [ ] ++ * prio "weighted devname [ ] ++ * ++ * Examples: ++ * prio "weighted hbtl 4:* 2 3:.:.:. 1" ++ * prio "weighted devname sda 2 sde 1" ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#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 diff --git a/0014-RH-add-hp_tur-checker.patch b/0014-RH-add-hp_tur-checker.patch new file mode 100644 index 0000000..36bf136 --- /dev/null +++ b/0014-RH-add-hp_tur-checker.patch @@ -0,0 +1,207 @@ +--- + libmultipath/checkers.h | 3 + + libmultipath/checkers/Makefile | 4 + + libmultipath/checkers/tur.c | 110 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 117 insertions(+) + +Index: multipath-tools/libmultipath/checkers.h +=================================================================== +--- multipath-tools.orig/libmultipath/checkers.h ++++ multipath-tools/libmultipath/checkers.h +@@ -60,6 +60,7 @@ enum path_check_state { + + #define DIRECTIO "directio" + #define TUR "tur" ++#define HP_TUR "hp_tur" + #define HP_SW "hp_sw" + #define RDAC "rdac" + #define EMC_CLARIION "emc_clariion" +@@ -91,6 +92,7 @@ enum path_check_state { + #define CHECKER_MSG_LEN 256 + #define CHECKER_DEV_LEN 256 + #define LIB_CHECKER_NAMELEN 256 ++#define WWID_SIZE 128 + + struct checker { + struct list_head node; +@@ -99,6 +101,7 @@ struct checker { + int disable; + char name[CHECKER_NAME_LEN]; + char message[CHECKER_MSG_LEN]; /* comm with callers */ ++ char wwid[WWID_SIZE]; /* LUN wwid */ + void * context; /* store for persistent data */ + void ** mpcontext; /* store for persistent data shared + multipath-wide. Use MALLOC if +Index: multipath-tools/libmultipath/checkers/Makefile +=================================================================== +--- multipath-tools.orig/libmultipath/checkers/Makefile ++++ multipath-tools/libmultipath/checkers/Makefile +@@ -8,6 +8,7 @@ LIBS= \ + libcheckcciss_tur.so \ + libcheckreadsector0.so \ + libchecktur.so \ ++ libcheckhp_tur.so \ + libcheckdirectio.so \ + libcheckemc_clariion.so \ + libcheckhp_sw.so \ +@@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o + libcheck%.so: libsg.o %.o + $(CC) $(SHARED_FLAGS) -o $@ $^ + ++hp_tur.o: tur.c ++ $(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $< ++ + install: + $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) + +Index: multipath-tools/libmultipath/checkers/tur.c +=================================================================== +--- multipath-tools.orig/libmultipath/checkers/tur.c ++++ multipath-tools/libmultipath/checkers/tur.c +@@ -15,14 +15,101 @@ + + #include "checkers.h" + ++#include "../libmultipath/debug.h" + #include "../libmultipath/sg_include.h" + + #define TUR_CMD_LEN 6 + #define HEAVY_CHECK_COUNT 10 + ++#ifdef CHECK_WWID ++#define MSG_TUR_UP "HP tur checker reports path is up" ++#define MSG_TUR_DOWN "HP tur checker reports path is down" ++#define MSG_TUR_GHOST "HP tur checker reports path is in standby state" ++#define EVPD 0x01 ++#define PAGE_83 0x83 ++#define INQUIRY_CMD 0x12 ++#define INQUIRY_CMDLEN 6 ++#define SCSI_INQ_BUFF_LEN 96 ++#else + #define MSG_TUR_UP "tur checker reports path is up" + #define MSG_TUR_DOWN "tur checker reports path is down" + #define MSG_TUR_GHOST "tur checker reports path is in standby state" ++#endif ++ ++#ifdef CHECK_WWID ++static int ++do_inq(struct checker * c, char * wwid) ++{ ++ int ret = -1; ++ unsigned char inq_cmd[INQUIRY_CMDLEN] = ++ {INQUIRY_CMD, EVPD, PAGE_83, 0, SCSI_INQ_BUFF_LEN, 0 }; ++ unsigned char sense_buffer[32]; ++ unsigned char resp_buffer[SCSI_INQ_BUFF_LEN]; ++ char *pbuff; ++ ++ int m,k; ++ int retry_tur = 5; ++ struct sg_io_hdr io_hdr; ++ ++retry: ++ memset(resp_buffer, 0, sizeof(resp_buffer)); ++ memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); ++ ++ io_hdr.interface_id = 'S'; ++ io_hdr.cmd_len = sizeof(inq_cmd); ++ io_hdr.mx_sb_len = sizeof(sense_buffer); ++ io_hdr.dxfer_direction = -3; // Data transfer from the device. ++ io_hdr.dxfer_len = sizeof(resp_buffer); ++ io_hdr.dxferp = (unsigned char *)resp_buffer; ++ io_hdr.cmdp = inq_cmd; ++ io_hdr.sbp = sense_buffer; ++ io_hdr.timeout = 60; // IOCTL timeout value. ++ ++ if (ioctl(c->fd, SG_IO, &io_hdr) < 0) { ++ condlog(0, "SG_IO ioctl failed: %s", strerror(errno)); ++ return ret; ++ } ++ if (io_hdr.info & SG_INFO_OK_MASK){ ++ int key = 0, asc, ascq; ++ ++ if (io_hdr.host_status == DID_BUS_BUSY || ++ io_hdr.host_status == DID_ERROR || ++ io_hdr.host_status == DID_TRANSPORT_DISRUPTED) { ++ if (--retry_tur) ++ goto retry; ++ } ++ if (io_hdr.sb_len_wr > 3) { ++ if (io_hdr.sbp[0] == 0x72 || io_hdr.sbp[0] == 0x73) { ++ key = io_hdr.sbp[1] & 0x0f; ++ asc = io_hdr.sbp[2]; ++ ascq = io_hdr.sbp[3]; ++ } else if (io_hdr.sb_len_wr > 13 && ++ ((io_hdr.sbp[0] & 0x7f) == 0x70 || ++ (io_hdr.sbp[0] & 0x7f) == 0x71)) { ++ key = io_hdr.sbp[2] & 0x0f; ++ asc = io_hdr.sbp[12]; ++ ascq = io_hdr.sbp[13]; ++ } ++ } ++ if (key == 0x6) { ++ /* Unit Attention, retry */ ++ if (--retry_tur) ++ goto retry; ++ } ++ return ret; ++ } ++ ++ pbuff = (char *) resp_buffer; ++ ++ wwid[0] = '3'; ++ for (m = 8, k = 1; m < 11; ++m, k+=2) ++ sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff); ++ for (m = 11; m < 24; ++m, k+=2) ++ sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff); ++ ++ return (ret = 0); ++} ++#endif + + struct tur_checker_context { + void * dummy; +@@ -30,6 +117,9 @@ struct tur_checker_context { + + int libcheck_init (struct checker * c) + { ++#ifdef CHECK_WWID ++ memset(c->wwid, 0, WWID_SIZE); ++#endif + return 0; + } + +@@ -45,6 +135,9 @@ libcheck_check (struct checker * c) + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + unsigned char sense_buffer[32]; + int retry_tur = 5; ++#ifdef CHECK_WWID ++ char wwid[WWID_SIZE]; ++#endif + + retry: + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); +@@ -110,6 +203,24 @@ libcheck_check (struct checker * c) + MSG(c, MSG_TUR_DOWN); + return PATH_DOWN; + } ++#ifdef CHECK_WWID ++ if (!do_inq(c, wwid)) { ++ ++ if(!strcmp(c->wwid, "\0")) { ++ strcpy(c->wwid, wwid); ++ goto up; ++ } ++ ++ if (strcmp(c->wwid , wwid)) { ++ condlog(0, ++ "hp_tur: Lun collided. new_wwid %s old_wwid %s", ++ wwid, c->wwid); ++ MSG(c, MSG_TUR_DOWN); ++ return PATH_DOWN; ++ } ++ } ++up: ++#endif + MSG(c, MSG_TUR_UP); + return PATH_UP; + } diff --git a/0015-RH-add-multipathd-count-paths-cmd.patch b/0015-RH-add-multipathd-count-paths-cmd.patch new file mode 100644 index 0000000..87826ef --- /dev/null +++ b/0015-RH-add-multipathd-count-paths-cmd.patch @@ -0,0 +1,150 @@ +Index: multipath-tools/libmultipath/uevent.c +=================================================================== +--- multipath-tools.orig/libmultipath/uevent.c ++++ multipath-tools/libmultipath/uevent.c +@@ -52,6 +52,12 @@ pthread_mutex_t uevc_lock, *uevc_lockp = + pthread_cond_t uev_cond, *uev_condp = &uev_cond; + uev_trigger *my_uev_trigger; + void * my_trigger_data; ++int servicing_uev; ++ ++int is_uevent_busy(void) ++{ ++ return (uevqhp != NULL || servicing_uev); ++} + + static struct uevent * alloc_uevent (void) + { +@@ -96,7 +102,9 @@ uevq_thread(void * et) + + while (1) { + pthread_mutex_lock(uevc_lockp); ++ servicing_uev = 0; + pthread_cond_wait(uev_condp, uevc_lockp); ++ servicing_uev = 1; + pthread_mutex_unlock(uevc_lockp); + + service_uevq(); +Index: multipath-tools/libmultipath/uevent.h +=================================================================== +--- multipath-tools.orig/libmultipath/uevent.h ++++ multipath-tools/libmultipath/uevent.h +@@ -17,3 +17,4 @@ struct uevent { + + int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data), + void * trigger_data); ++int is_uevent_busy(void); +Index: multipath-tools/multipathd/cli.c +=================================================================== +--- multipath-tools.orig/multipathd/cli.c ++++ multipath-tools/multipathd/cli.c +@@ -174,6 +174,7 @@ load_keys (void) + r += add_key(keys, "devices", DEVICES, 0); + r += add_key(keys, "format", FMT, 1); + r += add_key(keys, "wildcards", WILDCARDS, 0); ++ r += add_key(keys, "count", COUNT, 0); + r += add_key(keys, "quit", QUIT, 0); + r += add_key(keys, "exit", QUIT, 0); + +@@ -443,6 +444,7 @@ cli_init (void) { + add_handler(RESTOREQ+MAPS, NULL); + add_handler(REINSTATE+PATH, NULL); + add_handler(FAIL+PATH, NULL); ++ add_handler(COUNT+PATHS, NULL); + add_handler(QUIT, NULL); + + return 0; +Index: multipath-tools/multipathd/cli_handlers.h +=================================================================== +--- multipath-tools.orig/multipathd/cli_handlers.h ++++ multipath-tools/multipathd/cli_handlers.h +@@ -25,5 +25,6 @@ int cli_restore_all_queueing(void * v, c + int cli_suspend(void * v, char ** reply, int * len, void * data); + int cli_resume(void * v, char ** reply, int * len, void * data); + int cli_reinstate(void * v, char ** reply, int * len, void * data); ++int cli_count_paths(void * v, char ** reply, int * len, void * data); + int cli_fail(void * v, char ** reply, int * len, void * data); + int cli_quit(void * v, char ** reply, int * len, void * data); +Index: multipath-tools/multipathd/main.c +=================================================================== +--- multipath-tools.orig/multipathd/main.c ++++ multipath-tools/multipathd/main.c +@@ -768,6 +768,7 @@ uxlsnrloop (void * ap) + set_handler_callback(RESTOREQ+MAP, cli_restore_queueing); + set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing); + set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing); ++ set_handler_callback(COUNT+PATHS, cli_count_paths); + set_handler_callback(QUIT, cli_quit); + + umask(077); +Index: multipath-tools/multipathd/cli.h +=================================================================== +--- multipath-tools.orig/multipathd/cli.h ++++ multipath-tools/multipathd/cli.h +@@ -23,6 +23,7 @@ enum { + __BLACKLIST, + __DEVICES, + __FMT, ++ __COUNT, + __WILDCARDS, + __QUIT, + }; +@@ -51,6 +52,7 @@ enum { + #define BLACKLIST (1 << __BLACKLIST) + #define DEVICES (1 << __DEVICES) + #define FMT (1 << __FMT) ++#define COUNT (1 << __COUNT) + #define WILDCARDS (1 << __WILDCARDS) + #define QUIT (1 << __QUIT) + +Index: multipath-tools/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools.orig/multipathd/cli_handlers.c ++++ multipath-tools/multipathd/cli_handlers.c +@@ -18,6 +18,29 @@ + + #include "main.h" + #include "cli.h" ++#include "uevent.h" ++ ++int ++count_paths(char **r, int *l, struct vectors *vecs) ++{ ++ int i, len; ++ struct path *pp; ++ char * reply; ++ unsigned int maxlen = INITIAL_REPLY_LEN; ++ int monitored_count = 0; ++ ++ reply = MALLOC(maxlen); ++ if (!reply) ++ return 1; ++ vector_foreach_slot(vecs->pathvec, pp, i) ++ if (pp->fd != -1) ++ monitored_count++; ++ len = sprintf(reply, "Paths: %d\nBusy: %s\n", monitored_count, ++ is_uevent_busy()? "True" : "False"); ++ *r = reply; ++ *l = len + 1; ++ return 0; ++} + + int + show_paths (char ** r, int * len, struct vectors * vecs, char * style) +@@ -176,6 +199,16 @@ cli_list_config (void * v, char ** reply + } + + int ++cli_count_paths (void * v, char ** reply, int * len, void * data) ++{ ++ struct vectors * vecs = (struct vectors *)data; ++ ++ condlog(3, "count paths (operator)"); ++ ++ return count_paths(reply, len, vecs); ++} ++ ++int + cli_list_paths (void * v, char ** reply, int * len, void * data) + { + struct vectors * vecs = (struct vectors *)data; diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 83d760b..f97e3af 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,15 +1,16 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 10%{?dist} +Release: 11%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ Source0: multipath-tools-091027.tar.gz -Source1: multipath.conf.redhat +Source1: multipath.conf # patch that should go upstream Patch1: 0001-for-upstream-add-tpg_pref-prioritizer.patch +Patch2: 0002-for-upstream-add-tmo-config-options.patch # local patches Patch1001: 0001-RH-queue-without-daemon.patch Patch1002: 0002-RH-path-checker.patch @@ -23,6 +24,9 @@ Patch1009: 0009-RH-multipathd-blacklist-all-by-default.patch Patch1010: 0010-RH-multipath-rules-udev-changes.patch Patch1011: 0011-RH-fix-init-script-LSB-headers.patch Patch1012: 0012-RH-explicitly-disable-dm-udev-sync-support-in-kpartx.patch +Patch1013: 0013-RH-add-weighted_prio-prioritizer.patch +Patch1014: 0014-RH-add-hp_tur-checker.patch +Patch1015: 0015-RH-add-multipathd-count-paths-cmd.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -67,6 +71,7 @@ kpartx manages partition creation and removal for device-mapper devices. %prep %setup -q -n multipath-tools %patch1 -p1 +%patch2 -p1 %patch1001 -p1 %patch1002 -p1 %patch1003 -p1 @@ -79,6 +84,9 @@ kpartx manages partition creation and removal for device-mapper devices. %patch1010 -p1 %patch1011 -p1 %patch1012 -p1 +%patch1013 -p1 +%patch1014 -p1 +%patch1015 -p1 cp %{SOURCE1} . %build @@ -136,7 +144,7 @@ fi %{_mandir}/man8/multipathd.8.gz %config /etc/udev/rules.d/40-multipath.rules %doc AUTHOR COPYING FAQ -%doc multipath.conf.redhat multipath.conf.annotated +%doc multipath.conf multipath.conf.annotated %doc multipath.conf.defaults multipath.conf.synthetic %dir /etc/multipath @@ -157,6 +165,15 @@ fi %{_mandir}/man8/kpartx.8.gz %changelog +* Mon Nov 16 2009 Benjamin Marzinski -0.4.9-11 +- Add 0002-for-upstream-add-tmo-config-options.patch + * Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options +- Add 0013-RH-add-weighted_prio-prioritizer.patch +- Add 0014-RH-add-hp_tur-checker.patch +- Add 0015-RH-add-multipathd-count-paths-cmd.patch +- rename multipath.conf.redhat to multipath.conf, and remove the default + blacklist. + * Tue Oct 27 2009 Fabio M. Di Nitto - 0.4.9-10 - Updated to latest upstream 0.4.9 code : multipath-tools-091027.tar.gz (git commit id: a946bd4e2a529e5fba9c9547d03d3f91806618a3) diff --git a/multipath.conf.redhat b/multipath.conf similarity index 95% rename from multipath.conf.redhat rename to multipath.conf index 312915a..6bbeadb 100644 --- a/multipath.conf.redhat +++ b/multipath.conf @@ -5,13 +5,6 @@ # For a list of configuration options with descriptions, see # /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf.annotated - -# Blacklist all devices by default. Remove this to enable multipathing -# on the default devices. -blacklist { - devnode "*" -} - ## By default, devices with vendor = "IBM" and product = "S/390.*" are ## blacklisted. To enable mulitpathing on these devies, uncomment the ## following lines.