diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2015-03-11 20:40:47 -0500 |
---|---|---|
committer | Benjamin Marzinski <bmarzins@redhat.com> | 2015-03-11 20:40:47 -0500 |
commit | 3f562fdb0bfab54f4c6bf1982c7384401fbc16e6 (patch) | |
tree | 1b81d123c80b0531f93463b2876bc39da7f74d8c | |
parent | f3b1b79f2b68ffadf9d2d0cbda5660caacf7fb64 (diff) | |
download | device-mapper-multipath-3f562fdb0bfab54f4c6bf1982c7384401fbc16e6.tar.gz device-mapper-multipath-3f562fdb0bfab54f4c6bf1982c7384401fbc16e6.tar.xz device-mapper-multipath-3f562fdb0bfab54f4c6bf1982c7384401fbc16e6.zip |
device-mapper-multipath-0.4.9-75
Add 0111-RH-dont-show-pg-timeout.patch
* The kernel doesn't support pg_timeout, so multipath shouldn't
bother to display it
Add 0112-RHBZ-1194917-add-config_dir-option.patch
* multipath will now also read its configuration from files with
the .conf suffix in the directory specified by config_dir
which defaults to /etc/multipath/conf.d
Add 0113-RHBZ-1194917-cleanup.patch
* cleanup some unnecessary code
Add 0114-RHBZ-1196394-delayed-reintegration.patch
* Add "delay_watch_checks" and "delay_wait_checks" options to delay
reintegration of flakey paths.
Add 0115-RHBZ-1198418-fix-double-free.patch
* multipath was freeing the multipath alias twice if it failed to create the
multipath device.
Add 0116-UPBZ-1188179-dell-36xxi.patch
* new builtin configurations.
Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch
* configure multipath to automatically detect alua settings on clariion
devices.
-rw-r--r-- | 0111-RH-dont-show-pg-timeout.patch | 147 | ||||
-rw-r--r-- | 0112-RHBZ-1194917-add-config_dir-option.patch | 616 | ||||
-rw-r--r-- | 0113-RHBZ-1194917-cleanup.patch | 185 | ||||
-rw-r--r-- | 0114-RHBZ-1196394-delayed-reintegration.patch | 744 | ||||
-rw-r--r-- | 0115-RHBZ-1198418-fix-double-free.patch | 28 | ||||
-rw-r--r-- | 0116-UPBZ-1188179-dell-36xxi.patch | 83 | ||||
-rw-r--r-- | 0117-RHBZ-1198424-autodetect-clariion-alua.patch | 31 | ||||
-rw-r--r-- | device-mapper-multipath.spec | 38 |
8 files changed, 1871 insertions, 1 deletions
diff --git a/0111-RH-dont-show-pg-timeout.patch b/0111-RH-dont-show-pg-timeout.patch new file mode 100644 index 0000000..f545cc5 --- /dev/null +++ b/0111-RH-dont-show-pg-timeout.patch @@ -0,0 +1,147 @@ +--- + libmultipath/dict.c | 97 ---------------------------------------------------- + 1 file changed, 97 deletions(-) + +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -473,26 +473,6 @@ def_checker_timeout_handler(vector strve + static int + def_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- char * buff; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- conf->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- conf->pg_timeout = -PGTIMEOUT_NONE; +- else +- conf->pg_timeout = pg_timeout; +- } +- else +- conf->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -1358,30 +1338,6 @@ hw_minio_rq_handler(vector strvec) + static int + hw_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); +- char *buff; +- +- if (!hwe) +- return 1; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- hwe->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- hwe->pg_timeout = -PGTIMEOUT_NONE; +- else +- hwe->pg_timeout = pg_timeout; +- } +- else +- hwe->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -1819,29 +1775,6 @@ mp_minio_rq_handler(vector strvec) + static int + mp_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); +- char *buff; +- +- if (!mpe) +- return 1; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- mpe->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- mpe->pg_timeout = -PGTIMEOUT_NONE; +- else +- mpe->pg_timeout = pg_timeout; +- } +- else +- mpe->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -2180,16 +2113,6 @@ snprint_mp_rr_min_io_rq (char * buff, in + static int + snprint_mp_pg_timeout (char * buff, int len, void * data) + { +- struct mpentry * mpe = (struct mpentry *)data; +- +- switch (mpe->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- break; +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", mpe->pg_timeout); +- } + return 0; + } + +@@ -2551,19 +2474,6 @@ snprint_hw_rr_min_io_rq (char * buff, in + static int + snprint_hw_pg_timeout (char * buff, int len, void * data) + { +- struct hwentry * hwe = (struct hwentry *)data; +- +- if (!hwe->pg_timeout) +- return 0; +- +- switch (hwe->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- break; +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", hwe->pg_timeout); +- } + return 0; + } + +@@ -2895,13 +2805,6 @@ snprint_def_checker_timeout (char *buff, + static int + snprint_def_pg_timeout (char * buff, int len, void * data) + { +- switch (conf->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", conf->pg_timeout); +- } + return 0; + } + diff --git a/0112-RHBZ-1194917-add-config_dir-option.patch b/0112-RHBZ-1194917-add-config_dir-option.patch new file mode 100644 index 0000000..e322614 --- /dev/null +++ b/0112-RHBZ-1194917-add-config_dir-option.patch @@ -0,0 +1,616 @@ +--- + libmultipath/config.c | 56 +++++++++++++++++++++++++++++++- + libmultipath/config.h | 2 + + libmultipath/defaults.h | 1 + libmultipath/dict.c | 69 +++++++++++++++++++++++++++++++++++---- + libmultipath/parser.c | 78 +++++++++++++++++++++++---------------------- + libmultipath/parser.h | 3 - + multipath.conf.annotated | 10 +++++ + multipath.conf.defaults | 1 + multipath/multipath.conf.5 | 7 ++++ + 9 files changed, 179 insertions(+), 48 deletions(-) + +Index: multipath-tools-130222/libmultipath/parser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.c ++++ multipath-tools-130222/libmultipath/parser.c +@@ -18,6 +18,7 @@ + */ + + #include <syslog.h> ++#include <errno.h> + + #include "parser.h" + #include "memory.h" +@@ -453,14 +454,15 @@ set_value(vector strvec) + /* non-recursive configuration stream handler */ + static int kw_level = 0; + +-int warn_on_duplicates(vector uniques, char *str) ++int warn_on_duplicates(vector uniques, char *str, char *file) + { + char *tmp; + int i; + + vector_foreach_slot(uniques, tmp, i) { + if (!strcmp(str, tmp)) { +- condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str); ++ condlog(1, "%s line %d, duplicate keyword: %s", ++ file, line_nr, str); + return 0; + } + } +@@ -496,65 +498,70 @@ is_sublevel_keyword(char *str) + } + + int +-validate_config_strvec(vector strvec) ++validate_config_strvec(vector strvec, char *file) + { + char *str; + int i; + + str = VECTOR_SLOT(strvec, 0); + if (str == NULL) { +- condlog(0, "can't parse option on line %d of config file", +- line_nr); ++ condlog(0, "can't parse option on line %d of %s", ++ line_nr, file); + return -1; + } + if (*str == '}') { + if (VECTOR_SIZE(strvec) > 1) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 1), line_nr, file); + return 0; + } + if (*str == '{') { +- condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr); ++ condlog(0, "invalid keyword '%s' on line %d of %s", ++ str, line_nr, file); + return -1; + } + if (is_sublevel_keyword(str)) { + str = VECTOR_SLOT(strvec, 1); + if (str == NULL) +- condlog(0, "missing '{' on line %d of config file", line_nr); ++ condlog(0, "missing '{' on line %d of %s", ++ line_nr, file); + else if (*str != '{') +- condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str); ++ condlog(0, "expecting '{' on line %d of %s. found '%s'", ++ line_nr, file, str); + else if (VECTOR_SIZE(strvec) > 2) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file); + return 0; + } + str = VECTOR_SLOT(strvec, 1); + if (str == NULL) { +- condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr); ++ condlog(0, "missing value for option '%s' on line %d of %s", ++ (char *)VECTOR_SLOT(strvec, 0), line_nr, file); + return -1; + } + if (*str != '"') { + if (VECTOR_SIZE(strvec) > 2) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file); + return 0; + } + for (i = 2; i < VECTOR_SIZE(strvec); i++) { + str = VECTOR_SLOT(strvec, i); + if (str == NULL) { +- condlog(0, "can't parse value on line %d of config file", line_nr); ++ condlog(0, "can't parse value on line %d of %s", ++ line_nr, file); + return -1; + } + if (*str == '"') { + if (VECTOR_SIZE(strvec) > i + 1) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file); + return 0; + } + } +- condlog(0, "missing closing quotes on line %d of config file", +- line_nr); ++ condlog(0, "missing closing quotes on line %d of %s", ++ line_nr, file); + return 0; + } + +-int +-process_stream(vector keywords) ++static int ++process_stream(vector keywords, char *file) + { + int i; + int r = 0; +@@ -583,7 +590,7 @@ process_stream(vector keywords) + if (!strvec) + continue; + +- if (validate_config_strvec(strvec) != 0) { ++ if (validate_config_strvec(strvec, file) != 0) { + free_strvec(strvec); + continue; + } +@@ -595,8 +602,8 @@ process_stream(vector keywords) + free_strvec(strvec); + break; + } +- condlog(0, "unmatched '%s' at line %d of config file", +- EOB, line_nr); ++ condlog(0, "unmatched '%s' at line %d of %s", ++ EOB, line_nr, file); + } + + for (i = 0; i < VECTOR_SIZE(keywords); i++) { +@@ -604,7 +611,7 @@ process_stream(vector keywords) + + if (!strcmp(keyword->string, str)) { + if (keyword->unique && +- warn_on_duplicates(uniques, str)) { ++ warn_on_duplicates(uniques, str, file)) { + r = 1; + free_strvec(strvec); + goto out; +@@ -614,15 +621,15 @@ process_stream(vector keywords) + + if (keyword->sub) { + kw_level++; +- r += process_stream(keyword->sub); ++ r += process_stream(keyword->sub, file); + kw_level--; + } + break; + } + } + if (i >= VECTOR_SIZE(keywords)) +- condlog(1, "multipath.conf +%d, invalid keyword: %s", +- line_nr, str); ++ condlog(1, "%s line %d, invalid keyword: %s", ++ file, line_nr, str); + + free_strvec(strvec); + } +@@ -646,27 +653,24 @@ int alloc_keywords(void) + + /* Data initialization */ + int +-init_data(char *conf_file, void (*init_keywords) (void)) ++process_file(char *file) + { + int r; + +- stream = fopen(conf_file, "r"); ++ if (!keywords) { ++ condlog(0, "No keywords alocated"); ++ return 1; ++ } ++ stream = fopen(file, "r"); + if (!stream) { +- syslog(LOG_WARNING, "Configuration file open problem"); ++ condlog(0, "couldn't open configuration file '%s': %s", ++ file, strerror(errno)); + return 1; + } + +- /* Init Keywords structure */ +- (*init_keywords) (); +- +-/* Dump configuration * +- vector_dump(keywords); +- dump_keywords(keywords, 0); +-*/ +- + /* Stream handling */ + line_nr = 0; +- r = process_stream(keywords); ++ r = process_stream(keywords, file); + fclose(stream); + //free_keywords(keywords); + +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -117,6 +117,8 @@ reassign_maps_handler(vector strvec) + static int + multipath_dir_handler(vector strvec) + { ++ if (conf->multipath_dir) ++ FREE(conf->multipath_dir); + conf->multipath_dir = set_value(strvec); + + if (!conf->multipath_dir) +@@ -128,6 +130,8 @@ multipath_dir_handler(vector strvec) + static int + def_selector_handler(vector strvec) + { ++ if (conf->selector) ++ FREE(conf->selector); + conf->selector = set_value(strvec); + + if (!conf->selector) +@@ -155,6 +159,8 @@ def_pgpolicy_handler(vector strvec) + static int + def_uid_attribute_handler(vector strvec) + { ++ if (conf->uid_attribute) ++ FREE(conf->uid_attribute); + conf->uid_attribute = set_value(strvec); + + if (!conf->uid_attribute) +@@ -166,6 +172,8 @@ def_uid_attribute_handler(vector strvec) + static int + def_prio_handler(vector strvec) + { ++ if (conf->prio_name) ++ FREE(conf->prio_name); + conf->prio_name = set_value(strvec); + + if (!conf->prio_name) +@@ -177,6 +185,8 @@ def_prio_handler(vector strvec) + static int + def_alias_prefix_handler(vector strvec) + { ++ if (conf->alias_prefix) ++ FREE(conf->alias_prefix); + conf->alias_prefix = set_value(strvec); + + if (!conf->alias_prefix) +@@ -188,6 +198,8 @@ def_alias_prefix_handler(vector strvec) + static int + def_prio_args_handler(vector strvec) + { ++ if (conf->prio_args) ++ FREE(conf->prio_args); + conf->prio_args = set_value(strvec); + + if (!conf->prio_args) +@@ -199,6 +211,8 @@ def_prio_args_handler(vector strvec) + static int + def_features_handler(vector strvec) + { ++ if (conf->features) ++ FREE(conf->features); + conf->features = set_value(strvec); + + if (!conf->features) +@@ -210,6 +224,8 @@ def_features_handler(vector strvec) + static int + def_path_checker_handler(vector strvec) + { ++ if (conf->checker_name) ++ FREE(conf->checker_name); + conf->checker_name = set_value(strvec); + + if (!conf->checker_name) +@@ -432,6 +448,23 @@ def_no_path_retry_handler(vector strvec) + return 0; + } + ++ ++static int ++def_config_dir_handler(vector strvec) ++{ ++ /* this is only valid in the main config file */ ++ if (conf->processed_main_config) ++ return 0; ++ if (conf->config_dir) ++ FREE(conf->config_dir); ++ conf->config_dir = set_value(strvec); ++ ++ if (!conf->config_dir) ++ return 1; ++ ++ return 0; ++} ++ + static int + def_queue_without_daemon(vector strvec) + { +@@ -611,6 +644,8 @@ def_names_handler(vector strvec) + static int + bindings_file_handler(vector strvec) + { ++ if (conf->bindings_file) ++ FREE(conf->bindings_file); + conf->bindings_file = set_value(strvec); + + if (!conf->bindings_file) +@@ -622,6 +657,8 @@ bindings_file_handler(vector strvec) + static int + wwids_file_handler(vector strvec) + { ++ if (conf->wwids_file) ++ FREE(conf->wwids_file); + conf->wwids_file = set_value(strvec); + + if (!conf->wwids_file) +@@ -770,9 +807,12 @@ def_ignore_new_boot_devs_handler(vector + static int + blacklist_handler(vector strvec) + { +- conf->blist_devnode = vector_alloc(); +- conf->blist_wwid = vector_alloc(); +- conf->blist_device = vector_alloc(); ++ if (!conf->blist_devnode) ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_wwid) ++ conf->blist_wwid = vector_alloc(); ++ if (!conf->blist_device) ++ conf->blist_device = vector_alloc(); + + if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device) + return 1; +@@ -783,9 +823,12 @@ blacklist_handler(vector strvec) + static int + blacklist_exceptions_handler(vector strvec) + { +- conf->elist_devnode = vector_alloc(); +- conf->elist_wwid = vector_alloc(); +- conf->elist_device = vector_alloc(); ++ if (!conf->elist_devnode) ++ conf->elist_devnode = vector_alloc(); ++ if (!conf->elist_wwid) ++ conf->elist_wwid = vector_alloc(); ++ if (!conf->elist_device) ++ conf->elist_device = vector_alloc(); + + if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device) + return 1; +@@ -1480,7 +1523,8 @@ hw_deferred_remove_handler(vector strvec + static int + multipaths_handler(vector strvec) + { +- conf->mptable = vector_alloc(); ++ if (!conf->mptable) ++ conf->mptable = vector_alloc(); + + if (!conf->mptable) + return 1; +@@ -2945,6 +2989,16 @@ snprint_def_ignore_new_boot_devs(char * + return snprintf(buff, len, "no"); + } + ++ ++static int ++snprint_def_config_dir (char * buff, int len, void * data) ++{ ++ if (!conf->config_dir) ++ return 0; ++ ++ return snprintf(buff, len, "\"%s\"", conf->config_dir); ++} ++ + static int + snprint_ble_simple (char * buff, int len, void * data) + { +@@ -3016,6 +3070,7 @@ init_keywords(void) + install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync); + install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove); + install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); ++ install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +Index: multipath-tools-130222/libmultipath/parser.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.h ++++ multipath-tools-130222/libmultipath/parser.h +@@ -76,9 +76,8 @@ extern int read_line(char *buf, int size + extern vector read_value_block(void); + extern int alloc_value_block(vector strvec, void (*alloc_func) (vector)); + extern void *set_value(vector strvec); +-extern int process_stream(vector keywords); + extern int alloc_keywords(void); +-extern int init_data(char *conf_file, void (*init_keywords) (void)); ++extern int process_file(char *conf_file); + extern struct keyword * find_keyword(vector v, char * name); + void set_current_keywords (vector *k); + int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -6,6 +6,9 @@ + #include <stdio.h> + #include <string.h> + #include <libudev.h> ++#include <dirent.h> ++#include <limits.h> ++#include <errno.h> + + #include "checkers.h" + #include "memory.h" +@@ -556,6 +559,7 @@ free_config (struct config * conf) + + if (conf->wwids_file) + FREE(conf->wwids_file); ++ + if (conf->prio_name) + FREE(conf->prio_name); + +@@ -567,6 +571,10 @@ free_config (struct config * conf) + + if (conf->checker_name) + FREE(conf->checker_name); ++ ++ if (conf->config_dir) ++ FREE(conf->config_dir); ++ + if (conf->reservation_key) + FREE(conf->reservation_key); + +@@ -584,6 +592,43 @@ free_config (struct config * conf) + FREE(conf); + } + ++/* if multipath fails to process the config directory, it should continue, ++ * with just a warning message */ ++static void ++process_config_dir(vector keywords, char *dir) ++{ ++ struct dirent **namelist; ++ int i, n; ++ char path[LINE_MAX]; ++ int old_hwtable_size; ++ ++ if (dir[0] != '/') { ++ condlog(1, "config_dir '%s' must be a fully qualified path", ++ dir); ++ return; ++ } ++ n = scandir(dir, &namelist, NULL, alphasort); ++ if (n < 0) { ++ if (errno == ENOENT) ++ condlog(3, "No configuration dir '%s'", dir); ++ else ++ condlog(0, "couldn't open configuration dir '%s': %s", ++ dir, strerror(errno)); ++ return; ++ } ++ for (i = 0; i < n; i++) { ++ if (!strstr(namelist[i]->d_name, ".conf")) ++ continue; ++ old_hwtable_size = VECTOR_SIZE(conf->hwtable); ++ snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name); ++ path[LINE_MAX-1] = '\0'; ++ process_file(path); ++ if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size) ++ factorize_hwtable(conf->hwtable, old_hwtable_size); ++ ++ } ++} ++ + int + load_config (char * file, struct udev *udev) + { +@@ -623,6 +668,7 @@ load_config (char * file, struct udev *u + conf->hw_strmatch = 0; + conf->force_sync = 0; + conf->ignore_new_boot_devs = 0; ++ conf->processed_main_config = 0; + + /* + * preload default hwtable +@@ -641,11 +687,12 @@ load_config (char * file, struct udev *u + */ + set_current_keywords(&conf->keywords); + alloc_keywords(); ++ init_keywords(); + if (filepresent(file)) { + int builtin_hwtable_size; + + builtin_hwtable_size = VECTOR_SIZE(conf->hwtable); +- if (init_data(file, init_keywords)) { ++ if (process_file(file)) { + condlog(0, "error parsing config file"); + goto out; + } +@@ -658,7 +705,6 @@ load_config (char * file, struct udev *u + } + + } else { +- init_keywords(); + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "A default multipath.conf file is located at"); + condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); +@@ -677,6 +723,12 @@ load_config (char * file, struct udev *u + } + } + ++ conf->processed_main_config = 1; ++ if (conf->config_dir == NULL) ++ conf->config_dir = set_default(DEFAULT_CONFIG_DIR); ++ if (conf->config_dir && conf->config_dir[0] != '\0') ++ process_config_dir(conf->keywords, conf->config_dir); ++ + /* + * fill the voids left in the config file + */ +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -132,6 +132,7 @@ struct config { + int force_sync; + int deferred_remove; + int ignore_new_boot_devs; ++ int processed_main_config; + unsigned int version[3]; + + char * dev; +@@ -147,6 +148,7 @@ struct config { + char * prio_args; + char * checker_name; + char * alias_prefix; ++ char * config_dir; + unsigned char * reservation_key; + + vector keywords; +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -31,5 +31,6 @@ + #define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" + #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" ++#define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d" + + char * set_default (char * str); +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -232,6 +232,16 @@ + # # values : yes|no + # # default : no + # force_sync yes ++# ++# # ++# # name : config_dir ++# # scope : multipath & multipathd ++# # desc : If not set to an empty string, multipath will search ++# # this directory alphabetically for files ending in ".conf" ++# # and it will read configuration information from these ++# # files, just as if it was in /etc/multipath.conf ++# # values : "" or a fully qualified pathname ++# # default : "/etc/multipath/conf.d" + #} + # + ## +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -26,6 +26,7 @@ + # log_checker_err always + # retain_attached_hw_handler no + # detect_prio no ++# config_dir "/etc/multipath/conf.d" + #} + #blacklist { + # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -430,6 +430,13 @@ still in use, it will be freed when the + to the multipath device before the last user closes it, the deferred remove + will be canceled. Default is + .I no ++.TP ++.B config_dir ++If set to anything other than "", multipath will search this directory ++alphabetically for file ending in ".conf" and it will read configuration ++information from them, just as if it was in /etc/multipath.conf. config_dir ++must either be "" or a fully qualified directory name. Default is ++.I "/etc/multipath/conf.d" + . + .SH "blacklist section" + The diff --git a/0113-RHBZ-1194917-cleanup.patch b/0113-RHBZ-1194917-cleanup.patch new file mode 100644 index 0000000..cf95c98 --- /dev/null +++ b/0113-RHBZ-1194917-cleanup.patch @@ -0,0 +1,185 @@ +--- + libmultipath/parser.c | 103 +++----------------------------------------------- + libmultipath/parser.h | 6 -- + 2 files changed, 8 insertions(+), 101 deletions(-) + +Index: multipath-tools-130222/libmultipath/parser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.c ++++ multipath-tools-130222/libmultipath/parser.c +@@ -280,8 +280,8 @@ out: + return NULL; + } + +-int +-read_line(char *buf, int size) ++static int ++read_line(FILE *stream, char *buf, int size) + { + int ch; + int count = 0; +@@ -297,95 +297,6 @@ read_line(char *buf, int size) + return (ch == EOF) ? 0 : 1; + } + +-vector +-read_value_block(void) +-{ +- char *buf; +- int i; +- char *str = NULL; +- char *dup; +- vector vec = NULL; +- vector elements = vector_alloc(); +- +- if (!elements) +- return NULL; +- +- buf = (char *) MALLOC(MAXBUF); +- +- if (!buf) { +- vector_free(elements); +- return NULL; +- } +- +- while (read_line(buf, MAXBUF)) { +- vec = alloc_strvec(buf); +- if (vec) { +- str = VECTOR_SLOT(vec, 0); +- if (!strcmp(str, EOB)) { +- free_strvec(vec); +- break; +- } +- +- for (i = 0; i < VECTOR_SIZE(vec); i++) { +- str = VECTOR_SLOT(vec, i); +- dup = (char *) MALLOC(strlen(str) + 1); +- if (!dup) +- goto out; +- memcpy(dup, str, strlen(str)); +- +- if (!vector_alloc_slot(elements)) { +- free_strvec(vec); +- goto out1; +- } +- +- vector_set_slot(elements, dup); +- } +- free_strvec(vec); +- } +- memset(buf, 0, MAXBUF); +- } +- FREE(buf); +- return elements; +-out1: +- FREE(dup); +-out: +- FREE(buf); +- vector_free(elements); +- return NULL; +-} +- +-int +-alloc_value_block(vector strvec, void (*alloc_func) (vector)) +-{ +- char *buf; +- char *str = NULL; +- vector vec = NULL; +- +- buf = (char *) MALLOC(MAXBUF); +- +- if (!buf) +- return 1; +- +- while (read_line(buf, MAXBUF)) { +- vec = alloc_strvec(buf); +- if (vec) { +- str = VECTOR_SLOT(vec, 0); +- if (!strcmp(str, EOB)) { +- free_strvec(vec); +- break; +- } +- +- if (VECTOR_SIZE(vec)) +- (*alloc_func) (vec); +- +- free_strvec(vec); +- } +- memset(buf, 0, MAXBUF); +- } +- FREE(buf); +- return 0; +-} +- + void * + set_value(vector strvec) + { +@@ -561,7 +472,7 @@ validate_config_strvec(vector strvec, ch + } + + static int +-process_stream(vector keywords, char *file) ++process_stream(FILE *stream, vector keywords, char *file) + { + int i; + int r = 0; +@@ -582,7 +493,7 @@ process_stream(vector keywords, char *fi + return 1; + } + +- while (read_line(buf, MAXBUF)) { ++ while (read_line(stream, buf, MAXBUF)) { + line_nr++; + strvec = alloc_strvec(buf); + memset(buf,0, MAXBUF); +@@ -621,7 +532,8 @@ process_stream(vector keywords, char *fi + + if (keyword->sub) { + kw_level++; +- r += process_stream(keyword->sub, file); ++ r += process_stream(stream, ++ keyword->sub, file); + kw_level--; + } + break; +@@ -656,6 +568,7 @@ int + process_file(char *file) + { + int r; ++ FILE *stream; + + if (!keywords) { + condlog(0, "No keywords alocated"); +@@ -670,7 +583,7 @@ process_file(char *file) + + /* Stream handling */ + line_nr = 0; +- r = process_stream(keywords, file); ++ r = process_stream(stream, keywords, file); + fclose(stream); + //free_keywords(keywords); + +Index: multipath-tools-130222/libmultipath/parser.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.h ++++ multipath-tools-130222/libmultipath/parser.h +@@ -47,9 +47,6 @@ struct keyword { + int unique; + }; + +-/* global var exported */ +-FILE *stream; +- + /* Reloading helpers */ + #define SET_RELOAD (reload = 1) + #define UNSET_RELOAD (reload = 0) +@@ -72,9 +69,6 @@ extern int _install_keyword(char *string + extern void dump_keywords(vector keydump, int level); + extern void free_keywords(vector keywords); + extern vector alloc_strvec(char *string); +-extern int read_line(char *buf, int size); +-extern vector read_value_block(void); +-extern int alloc_value_block(vector strvec, void (*alloc_func) (vector)); + extern void *set_value(vector strvec); + extern int alloc_keywords(void); + extern int process_file(char *conf_file); diff --git a/0114-RHBZ-1196394-delayed-reintegration.patch b/0114-RHBZ-1196394-delayed-reintegration.patch new file mode 100644 index 0000000..78e43ee --- /dev/null +++ b/0114-RHBZ-1196394-delayed-reintegration.patch @@ -0,0 +1,744 @@ +--- + libmultipath/checkers.c | 3 + libmultipath/checkers.h | 9 + + libmultipath/config.c | 4 + libmultipath/config.h | 6 + + libmultipath/configure.c | 2 + libmultipath/defaults.h | 1 + libmultipath/dict.c | 204 ++++++++++++++++++++++++++++++++++++++++++++- + libmultipath/print.c | 2 + libmultipath/propsel.c | 52 +++++++++++ + libmultipath/propsel.h | 2 + libmultipath/structs.h | 9 + + multipath.conf.annotated | 40 ++++++++ + multipath.conf.defaults | 2 + multipath/multipath.conf.5 | 27 +++++ + multipathd/main.c | 34 ++++++- + 15 files changed, 388 insertions(+), 9 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -62,6 +62,8 @@ struct hwentry { + int retain_hwhandler; + int detect_prio; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + char * bl_product; + }; + +@@ -86,6 +88,8 @@ struct mpentry { + int attribute_flags; + int user_friendly_names; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + uid_t uid; + gid_t gid; + mode_t mode; +@@ -133,6 +137,8 @@ struct config { + int deferred_remove; + int ignore_new_boot_devs; + int processed_main_config; ++ int delay_watch_checks; ++ int delay_wait_checks; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -134,6 +134,11 @@ enum scsi_protocol { + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ + }; + ++enum delay_checks_states { ++ DELAY_CHECKS_OFF = -1, ++ DELAY_CHECKS_UNDEF = 0, ++}; ++ + struct sg_id { + int host_no; + int channel; +@@ -180,6 +185,8 @@ struct path { + int priority; + int pgindex; + int detect_prio; ++ int watch_checks; ++ int wait_checks; + char * uid_attribute; + struct prio prio; + char * prio_args; +@@ -215,6 +222,8 @@ struct multipath { + int fast_io_fail; + int retain_hwhandler; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + unsigned int dev_loss; + uid_t uid; + gid_t gid; +Index: multipath-tools-130222/libmultipath/checkers.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/checkers.h ++++ multipath-tools-130222/libmultipath/checkers.h +@@ -46,6 +46,14 @@ + * PATH_PENDING: + * - Use: All async checkers + * - Description: Indicates a check IO is in flight. ++ * ++ * PATH_DELAYED: ++ * - Use: None of the checkers (returned if the path is being delayed before ++ * reintegration. ++ * - Description: If a path fails after being up for less than ++ * delay_watch_checks checks, when it comes back up again, it will not ++ * be marked as up until it has been up for delay_wait_checks checks. ++ * During this time, it is marked as "delayed" + */ + enum path_check_state { + PATH_WILD, +@@ -55,6 +63,7 @@ enum path_check_state { + PATH_SHAKY, + PATH_GHOST, + PATH_PENDING, ++ PATH_DELAYED, + PATH_MAX_STATE + }; + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -291,6 +291,8 @@ setup_map (struct multipath * mpp, char + select_reservation_key(mpp); + select_retain_hwhandler(mpp); + select_deferred_remove(mpp); ++ select_delay_watch_checks(mpp); ++ select_delay_wait_checks(mpp); + + sysfs_set_scsi_tmo(mpp); + /* +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -20,6 +20,7 @@ + #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF + #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF + #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF ++#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF + + #define DEFAULT_CHECKINT 5 + #define MAX_CHECKINT(a) (a << 2) +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -801,6 +801,44 @@ def_ignore_new_boot_devs_handler(vector + return 0; + } + ++static int ++def_delay_watch_checks_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((conf->delay_watch_checks = atoi(buff)) < 1) ++ conf->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++def_delay_wait_checks_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((conf->delay_wait_checks = atoi(buff)) < 1) ++ conf->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -1517,6 +1555,52 @@ hw_deferred_remove_handler(vector strvec + return 0; + } + ++static int ++hw_delay_watch_checks_handler(vector strvec) ++{ ++ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ char * buff; ++ ++ if (!hwe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ hwe->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((hwe->delay_watch_checks = atoi(buff)) < 1) ++ hwe->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++hw_delay_wait_checks_handler(vector strvec) ++{ ++ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ char * buff; ++ ++ if (!hwe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ hwe->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((hwe->delay_wait_checks = atoi(buff)) < 1) ++ hwe->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * multipaths block handlers + */ +@@ -1996,6 +2080,52 @@ mp_deferred_remove_handler(vector strvec + return 0; + } + ++static int ++mp_delay_watch_checks_handler(vector strvec) ++{ ++ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); ++ char * buff; ++ ++ if (!mpe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ mpe->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((mpe->delay_watch_checks = atoi(buff)) < 1) ++ mpe->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++mp_delay_wait_checks_handler(vector strvec) ++{ ++ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); ++ char * buff; ++ ++ if (!mpe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ mpe->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((mpe->delay_wait_checks = atoi(buff)) < 1) ++ mpe->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * config file keywords printing + */ +@@ -2258,6 +2388,30 @@ snprint_mp_deferred_remove (char * buff, + } + + static int ++snprint_mp_delay_watch_checks(char * buff, int len, void * data) ++{ ++ struct mpentry * mpe = (struct mpentry *)data; ++ ++ if (mpe->delay_watch_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (mpe->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", mpe->delay_watch_checks); ++} ++ ++static int ++snprint_mp_delay_wait_checks(char * buff, int len, void * data) ++{ ++ struct mpentry * mpe = (struct mpentry *)data; ++ ++ if (mpe->delay_wait_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (mpe->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", mpe->delay_wait_checks); ++} ++ ++static int + snprint_hw_fast_io_fail(char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -2586,6 +2740,30 @@ snprint_hw_deferred_remove(char * buff, + } + + static int ++snprint_hw_delay_watch_checks(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (hwe->delay_watch_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (hwe->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", hwe->delay_watch_checks); ++} ++ ++static int ++snprint_hw_delay_wait_checks(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (hwe->delay_wait_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (hwe->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", hwe->delay_wait_checks); ++} ++ ++static int + snprint_detect_prio(char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -2883,7 +3061,6 @@ snprint_def_find_multipaths (char * buff + return snprintf(buff, len, "yes"); + } + +- + static int + snprint_def_user_friendly_names (char * buff, int len, void * data) + { +@@ -2989,7 +3166,6 @@ snprint_def_ignore_new_boot_devs(char * + return snprintf(buff, len, "no"); + } + +- + static int + snprint_def_config_dir (char * buff, int len, void * data) + { +@@ -3000,6 +3176,24 @@ snprint_def_config_dir (char * buff, int + } + + static int ++snprint_def_delay_watch_checks(char * buff, int len, void * data) ++{ ++ if (conf->delay_watch_checks == DELAY_CHECKS_UNDEF || ++ conf->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", conf->delay_watch_checks); ++} ++ ++static int ++snprint_def_delay_wait_checks(char * buff, int len, void * data) ++{ ++ if (conf->delay_wait_checks == DELAY_CHECKS_UNDEF || ++ conf->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", conf->delay_wait_checks); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -3071,6 +3265,8 @@ init_keywords(void) + install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove); + install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); + install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir); ++ install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks); ++ install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +@@ -3136,6 +3332,8 @@ init_keywords(void) + install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler); + install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio); + install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove); ++ install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks); ++ install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks); + install_sublevel_end(); + + install_keyword_root("multipaths", &multipaths_handler); +@@ -3161,5 +3359,7 @@ init_keywords(void) + install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key); + install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names); + install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove); ++ install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks); ++ install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks); + install_sublevel_end(); + } +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -336,6 +336,8 @@ snprint_chk_state (char * buff, size_t l + return snprintf(buff, len, "shaky"); + case PATH_GHOST: + return snprintf(buff, len, "ghost"); ++ case PATH_DELAYED: ++ return snprintf(buff, len, "delayed"); + default: + return snprintf(buff, len, "undef"); + } +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -788,3 +788,55 @@ select_detect_prio (struct path * pp) + condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio); + return 0; + } ++ ++extern int ++select_delay_watch_checks (struct multipath * mp) ++{ ++ if (mp->mpe && mp->mpe->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = mp->mpe->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (multipath setting)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ if (mp->hwe && mp->hwe->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = mp->hwe->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (controler setting)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ if (conf->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = conf->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (config file default)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ mp->delay_watch_checks = DEFAULT_DELAY_CHECKS; ++ condlog(3, "delay_watch_checks = DISABLED (internal default)"); ++ return 0; ++} ++ ++extern int ++select_delay_wait_checks (struct multipath * mp) ++{ ++ if (mp->mpe && mp->mpe->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = mp->mpe->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (multipath setting)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ if (mp->hwe && mp->hwe->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = mp->hwe->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (controler setting)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ if (conf->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = conf->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (config file default)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ mp->delay_wait_checks = DEFAULT_DELAY_CHECKS; ++ condlog(3, "delay_wait_checks = DISABLED (internal default)"); ++ return 0; ++} +Index: multipath-tools-130222/libmultipath/propsel.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.h ++++ multipath-tools-130222/libmultipath/propsel.h +@@ -21,3 +21,5 @@ int select_reservation_key(struct multip + int select_retain_hwhandler (struct multipath * mp); + int select_detect_prio(struct path * pp); + int select_deferred_remove(struct multipath *mp); ++int select_delay_watch_checks (struct multipath * mp); ++int select_delay_wait_checks (struct multipath * mp); +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -188,7 +188,8 @@ sync_map_state(struct multipath *mpp) + vector_foreach_slot (mpp->pg, pgp, i){ + vector_foreach_slot (pgp->paths, pp, j){ + if (pp->state == PATH_UNCHECKED || +- pp->state == PATH_WILD) ++ pp->state == PATH_WILD || ++ pp->state == PATH_DELAYED) + continue; + if ((pp->dmstate == PSTATE_FAILED || + pp->dmstate == PSTATE_UNDEF) && +@@ -1165,6 +1166,16 @@ check_path (struct vectors * vecs, struc + if (!pp->mpp) + return; + ++ if ((newstate == PATH_UP || newstate == PATH_GHOST) && ++ pp->wait_checks > 0) { ++ if (pp->mpp && pp->mpp->nr_active > 0) { ++ pp->state = PATH_DELAYED; ++ pp->wait_checks--; ++ return; ++ } else ++ pp->wait_checks = 0; ++ } ++ + pp->chkrstate = newstate; + if (newstate != pp->state) { + int oldstate = pp->state; +@@ -1182,9 +1193,14 @@ check_path (struct vectors * vecs, struc + * proactively fail path in the DM + */ + if (oldstate == PATH_UP || +- oldstate == PATH_GHOST) ++ oldstate == PATH_GHOST) { + fail_path(pp, 1); +- else ++ if (pp->mpp->delay_wait_checks > 0 && ++ pp->watch_checks > 0) { ++ pp->wait_checks = pp->mpp->delay_wait_checks; ++ pp->watch_checks = 0; ++ } ++ }else + fail_path(pp, 0); + + /* +@@ -1211,11 +1227,15 @@ check_path (struct vectors * vecs, struc + * reinstate this path + */ + if (oldstate != PATH_UP && +- oldstate != PATH_GHOST) ++ oldstate != PATH_GHOST) { ++ if (pp->mpp->delay_watch_checks > 0) ++ pp->watch_checks = pp->mpp->delay_watch_checks; + reinstate_path(pp, 1); +- else ++ } else { ++ if (pp->watch_checks > 0) ++ pp->watch_checks--; + reinstate_path(pp, 0); +- ++ } + new_path_up = 1; + + if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) +@@ -1245,6 +1265,8 @@ check_path (struct vectors * vecs, struc + else + pp->checkint = conf->max_checkint; + } ++ if (pp->watch_checks > 0) ++ pp->watch_checks--; + pp->tick = pp->checkint; + condlog(4, "%s: delay next check %is", + pp->dev_t, pp->tick); +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -242,6 +242,30 @@ + # # files, just as if it was in /etc/multipath.conf + # # values : "" or a fully qualified pathname + # # default : "/etc/multipath/conf.d" ++# ++# # ++# # name : delay_watch_checks ++# # scope : multipathd ++# # desc : If set to a value greater than 0, multipathd will watch ++# # paths that have recently become valid for this many ++# # checks. If they fail again while they are being watched, ++# # when they next become valid, they will not be used until ++# # they have stayed up for delay_wait_checks checks. ++# # values : no|<n> > 0 ++# # default : no ++# delay_watch_checks 12 ++# ++# # ++# # name : delay_wait_checks ++# # scope : multipathd ++# # desc : If set to a value greater than 0, when a device that has ++# # recently come back online fails again within ++# # delay_watch_checks checks, the next time it comes back ++# # online, it will marked and delayed, and not used until ++# # it has passed delay_wait_checks checks. ++# # values : no|<n> > 0 ++# # default : no ++# delay_wait_checks 12 + #} + # + ## +@@ -383,6 +407,13 @@ + # # + # flush_on_last_del yes + # ++# # ++# # name : delay_watch_checks ++# # See defualts section for information. ++# ++# # ++# # name : delay_wait_checks ++# # See defualts section for information. + # } + # multipath { + # wwid 1DEC_____321816758474 +@@ -566,6 +597,15 @@ + # # before removing it from the system. + # # values : n > 0 + # dev_loss_tmo 600 ++# ++# # ++# # name : delay_watch_checks ++# # See defaults section for information. ++# ++# # ++# # name : delay_wait_checks ++# # See defaults section for information. ++# + # } + # device { + # vendor "COMPAQ " +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -27,6 +27,8 @@ + # retain_attached_hw_handler no + # detect_prio no + # config_dir "/etc/multipath/conf.d" ++# delay_watch_checks no ++# delay_wait_checks no + #} + #blacklist { + # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -437,6 +437,25 @@ alphabetically for file ending in ".conf + information from them, just as if it was in /etc/multipath.conf. config_dir + must either be "" or a fully qualified directory name. Default is + .I "/etc/multipath/conf.d" ++.TP ++.B delay_watch_checks ++If set to a value greater than 0, multipathd will watch paths that have ++recently become valid for this many checks. If they fail again while they are ++being watched, when they next become valid, they will not be used until they ++have stayed up for ++.I delay_wait_checks ++checks. Default is ++.I no ++.TP ++.B delay_wait_checks ++If set to a value greater than 0, when a device that has recently come back ++online fails again within ++.I delay_watch_checks ++checks, the next time it comes back online, it will marked and delayed, and not ++used until it has passed ++.I delay_wait_checks ++checks. Default is ++.I no + . + .SH "blacklist section" + The +@@ -540,6 +559,10 @@ section: + .B reservation_key + .TP + .B deferred_remove ++.TP ++.B delay_watch_checks ++.TP ++.B delay_wait_checks + .RE + .PD + .LP +@@ -632,6 +655,10 @@ section: + .B detect_prio + .TP + .B deferred_remove ++.TP ++.B delay_watch_checks ++.TP ++.B delay_wait_checks + .RE + .PD + .LP +Index: multipath-tools-130222/libmultipath/checkers.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/checkers.c ++++ multipath-tools-130222/libmultipath/checkers.c +@@ -16,7 +16,8 @@ char *checker_state_names[] = { + "up", + "shaky", + "ghost", +- "pending" ++ "pending", ++ "delayed" + }; + + static LIST_HEAD(checkers); +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -341,6 +341,8 @@ merge_hwe (struct hwentry * dst, struct + merge_num(retain_hwhandler); + merge_num(detect_prio); + merge_num(deferred_remove); ++ merge_num(delay_watch_checks); ++ merge_num(delay_wait_checks); + + /* + * Make sure features is consistent with +@@ -399,6 +401,8 @@ overwrite_hwe (struct hwentry * dst, str + overwrite_num(retain_hwhandler); + overwrite_num(detect_prio); + overwrite_num(deferred_remove); ++ overwrite_num(delay_watch_checks); ++ overwrite_num(delay_wait_checks); + + /* + * Make sure features is consistent with diff --git a/0115-RHBZ-1198418-fix-double-free.patch b/0115-RHBZ-1198418-fix-double-free.patch new file mode 100644 index 0000000..a403760 --- /dev/null +++ b/0115-RHBZ-1198418-fix-double-free.patch @@ -0,0 +1,28 @@ +--- + multipathd/main.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -310,10 +310,15 @@ ev_add_map (char * dev, char * alias, st + /* + * now we can register the map + */ +- if (map_present && (mpp = add_map_without_path(vecs, alias))) { +- sync_map_state(mpp); +- condlog(2, "%s: devmap %s registered", alias, dev); +- return 0; ++ if (map_present) { ++ if ((mpp = add_map_without_path(vecs, alias))) { ++ sync_map_state(mpp); ++ condlog(2, "%s: devmap %s registered", alias, dev); ++ return 0; ++ } else { ++ condlog(2, "%s: uev_add_map failed", dev); ++ return 1; ++ } + } + r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid); + diff --git a/0116-UPBZ-1188179-dell-36xxi.patch b/0116-UPBZ-1188179-dell-36xxi.patch new file mode 100644 index 0000000..e32118b --- /dev/null +++ b/0116-UPBZ-1188179-dell-36xxi.patch @@ -0,0 +1,83 @@ +--- + libmultipath/hwtable.c | 30 ++++++++++++++++++++++++++++++ + multipath.conf.defaults | 26 ++++++++++++++++++++++++++ + 2 files changed, 56 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -772,6 +772,36 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_RDAC, + .prio_args = NULL, + }, ++ { ++ /* DELL MD36xxi */ ++ .vendor = "DELL", ++ .product = "MD36xxi", ++ .bl_product = "Universal Xport", ++ .features = "2 pg_init_retries 50", ++ .hwhandler = "1 rdac", ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = 15, ++ .checker_name = RDAC, ++ .prio_name = PRIO_RDAC, ++ .prio_args = NULL, ++ }, ++ { ++ /* DELL MD36xxf */ ++ .vendor = "DELL", ++ .product = "MD36xxf", ++ .bl_product = "Universal Xport", ++ .features = "2 pg_init_retries 50", ++ .hwhandler = "1 rdac", ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = 15, ++ .checker_name = RDAC, ++ .prio_name = PRIO_RDAC, ++ .prio_args = NULL, ++ }, + /* + * NETAPP controller family + * +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -655,6 +655,32 @@ + # no_path_retry 15 + # } + # device { ++# vendor "DELL" ++# product "MD36xxi" ++# product_blacklist "Universal Xport" ++# path_grouping_policy "group_by_prio" ++# path_checker "rdac" ++# features "2 pg_init_retries 50" ++# hardware_handler "1 rdac" ++# prio "rdac" ++# failback "immediate" ++# rr_weight "uniform" ++# no_path_retry 15 ++# } ++# device { ++# vendor "DELL" ++# product "MD36xxf" ++# product_blacklist "Universal Xport" ++# path_grouping_policy "group_by_prio" ++# path_checker "rdac" ++# features "2 pg_init_retries 50" ++# hardware_handler "1 rdac" ++# prio "rdac" ++# failback "immediate" ++# rr_weight "uniform" ++# no_path_retry 15 ++# } ++# device { + # vendor "NETAPP" + # product "LUN.*" + # path_grouping_policy "group_by_prio" diff --git a/0117-RHBZ-1198424-autodetect-clariion-alua.patch b/0117-RHBZ-1198424-autodetect-clariion-alua.patch new file mode 100644 index 0000000..64a302d --- /dev/null +++ b/0117-RHBZ-1198424-autodetect-clariion-alua.patch @@ -0,0 +1,31 @@ +--- + libmultipath/hwtable.c | 2 ++ + multipath.conf.defaults | 2 ++ + 2 files changed, 4 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -272,6 +272,8 @@ static struct hwentry default_hw[] = { + .checker_name = EMC_CLARIION, + .prio_name = PRIO_EMC, + .prio_args = NULL, ++ .retain_hwhandler = RETAIN_HWHANDLER_ON, ++ .detect_prio = DETECT_PRIO_ON, + }, + { + .vendor = "EMC", +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -261,6 +261,8 @@ + # failback immediate + # rr_weight "uniform" + # no_path_retry 60 ++# retain_attached_hw_handler yes ++# detect_prio yes + # } + # device { + # vendor "EMC" diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 882259d..7c219e3 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 74%{?dist} +Release: 75%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -118,6 +118,13 @@ Patch0107: 0107-RHBZ-1169935-no-new-devs.patch Patch0108: 0108-RHBZ-1153832-kpartx-remove-devs.patch Patch0109: 0109-RH-read-only-bindings.patch Patch0110: 0110-RHBZ-blacklist-vd-devs.patch +Patch0111: 0111-RH-dont-show-pg-timeout.patch +Patch0112: 0112-RHBZ-1194917-add-config_dir-option.patch +Patch0113: 0113-RHBZ-1194917-cleanup.patch +Patch0114: 0114-RHBZ-1196394-delayed-reintegration.patch +Patch0115: 0115-RHBZ-1198418-fix-double-free.patch +Patch0116: 0116-UPBZ-1188179-dell-36xxi.patch +Patch0117: 0117-RHBZ-1198424-autodetect-clariion-alua.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -281,6 +288,13 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0108 -p1 %patch0109 -p1 %patch0110 -p1 +%patch0111 -p1 +%patch0112 -p1 +%patch0113 -p1 +%patch0114 -p1 +%patch0115 -p1 +%patch0116 -p1 +%patch0117 -p1 cp %{SOURCE1} . %build @@ -388,6 +402,28 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||: %{_mandir}/man8/kpartx.8.gz %changelog +* Wed Mar 11 2015 Benjamin Marzinski <bmarzins@redhat.com> 0.4.9-75 +- Add 0111-RH-dont-show-pg-timeout.patch + * The kernel doesn't support pg_timeout, so multipath shouldn't + bother to display it +- Add 0112-RHBZ-1194917-add-config_dir-option.patch + * multipath will now also read its configuration from files with + the .conf suffix in the directory specified by config_dir + which defaults to /etc/multipath/conf.d +- Add 0113-RHBZ-1194917-cleanup.patch + * cleanup some unnecessary code +- Add 0114-RHBZ-1196394-delayed-reintegration.patch + * Add "delay_watch_checks" and "delay_wait_checks" options to delay + reintegration of flakey paths. +- Add 0115-RHBZ-1198418-fix-double-free.patch + * multipath was freeing the multipath alias twice if it failed to create the + multipath device. +- Add 0116-UPBZ-1188179-dell-36xxi.patch + * new builtin configurations. +- Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch + * configure multipath to automatically detect alua settings on clariion + devices. + * Thu Mar 05 2015 Adam Jackson <ajax@redhat.com> 0.4.9-74 - Drop sysvinit subpackage from F23+ |