[device-mapper-multipath] device-mapper-multipath-0.4.9-75

Benjamin Marzinski bmarzins at fedoraproject.org
Thu Mar 12 01:44:15 UTC 2015


commit 3f562fdb0bfab54f4c6bf1982c7384401fbc16e6
Author: Benjamin Marzinski <bmarzins at redhat.com>
Date:   Wed Mar 11 20:40:47 2015 -0500

    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.

 0111-RH-dont-show-pg-timeout.patch               | 147 +++++
 0112-RHBZ-1194917-add-config_dir-option.patch    | 616 +++++++++++++++++++
 0113-RHBZ-1194917-cleanup.patch                  | 185 ++++++
 0114-RHBZ-1196394-delayed-reintegration.patch    | 744 +++++++++++++++++++++++
 0115-RHBZ-1198418-fix-double-free.patch          |  28 +
 0116-UPBZ-1188179-dell-36xxi.patch               |  83 +++
 0117-RHBZ-1198424-autodetect-clariion-alua.patch |  31 +
 device-mapper-multipath.spec                     |  38 +-
 8 files changed, 1871 insertions(+), 1 deletion(-)
---
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 at 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 at redhat.com> 0.4.9-74
 - Drop sysvinit subpackage from F23+
 


More information about the scm-commits mailing list