Blame SOURCES/0231-RHBZ-1458852-delay-readying.patch

4728c8
---
4728c8
 libmultipath/config.c      |    4 +
4728c8
 libmultipath/config.h      |    3 +
4728c8
 libmultipath/defaults.h    |    1 
4728c8
 libmultipath/devmapper.c   |   19 ++++++--
4728c8
 libmultipath/dict.c        |  104 +++++++++++++++++++++++++++++++++++++++++++++
4728c8
 libmultipath/propsel.c     |   26 +++++++++++
4728c8
 libmultipath/propsel.h     |    1 
4728c8
 libmultipath/structs.h     |    7 +++
4728c8
 multipath/multipath.conf.5 |   13 +++++
4728c8
 multipath/multipath.rules  |    1 
4728c8
 multipathd/main.c          |   27 +++++++++++
4728c8
 11 files changed, 202 insertions(+), 4 deletions(-)
4728c8
4728c8
Index: multipath-tools-130222/libmultipath/config.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.c
4728c8
+++ multipath-tools-130222/libmultipath/config.c
4728c8
@@ -348,6 +348,7 @@ merge_hwe (struct hwentry * dst, struct
4728c8
 	merge_num(skip_kpartx);
4728c8
 	merge_num(max_sectors_kb);
4728c8
 	merge_num(unpriv_sgio);
4728c8
+	merge_num(ghost_delay);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -412,6 +413,7 @@ overwrite_hwe (struct hwentry * dst, str
4728c8
 	overwrite_num(skip_kpartx);
4728c8
 	overwrite_num(max_sectors_kb);
4728c8
 	overwrite_num(unpriv_sgio);
4728c8
+	overwrite_num(ghost_delay);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -482,6 +484,7 @@ store_hwe (vector hwtable, struct hwentr
4728c8
 	hwe->retain_hwhandler = dhwe->retain_hwhandler;
4728c8
 	hwe->detect_prio = dhwe->detect_prio;
4728c8
 	hwe->detect_checker = dhwe->detect_checker;
4728c8
+	hwe->ghost_delay = dhwe->ghost_delay;
4728c8
 
4728c8
 	if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
4728c8
 		goto out;
4728c8
@@ -694,6 +697,7 @@ load_config (char * file, struct udev *u
4728c8
 	conf->disable_changed_wwids = 0;
4728c8
 	conf->max_sectors_kb = DEFAULT_MAX_SECTORS_KB;
4728c8
 	conf->unpriv_sgio = DEFAULT_UNPRIV_SGIO;
4728c8
+	conf->ghost_delay = DEFAULT_GHOST_DELAY;
4728c8
 
4728c8
 	/*
4728c8
 	 * preload default hwtable
4728c8
Index: multipath-tools-130222/libmultipath/config.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.h
4728c8
+++ multipath-tools-130222/libmultipath/config.h
4728c8
@@ -70,6 +70,7 @@ struct hwentry {
4728c8
 	int skip_kpartx;
4728c8
 	int max_sectors_kb;
4728c8
 	int unpriv_sgio;
4728c8
+	int ghost_delay;
4728c8
 	char * bl_product;
4728c8
 };
4728c8
 
4728c8
@@ -100,6 +101,7 @@ struct mpentry {
4728c8
 	int skip_kpartx;
4728c8
 	int max_sectors_kb;
4728c8
 	int unpriv_sgio;
4728c8
+	int ghost_delay;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
 	mode_t mode;
4728c8
@@ -159,6 +161,7 @@ struct config {
4728c8
 	int disable_changed_wwids;
4728c8
 	int max_sectors_kb;
4728c8
 	int unpriv_sgio;
4728c8
+	int ghost_delay;
4728c8
 	unsigned int version[3];
4728c8
 
4728c8
 	char * dev;
4728c8
Index: multipath-tools-130222/libmultipath/defaults.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/defaults.h
4728c8
+++ multipath-tools-130222/libmultipath/defaults.h
4728c8
@@ -28,6 +28,7 @@
4728c8
 #define DEFAULT_SKIP_KPARTX SKIP_KPARTX_OFF
4728c8
 #define DEFAULT_MAX_SECTORS_KB	MAX_SECTORS_KB_UNDEF
4728c8
 #define DEFAULT_UNPRIV_SGIO UNPRIV_SGIO_OFF
4728c8
+#define DEFAULT_GHOST_DELAY GHOST_DELAY_OFF
4728c8
 
4728c8
 #define DEFAULT_CHECKINT	5
4728c8
 #define MAX_CHECKINT(a)		(a << 2)
4728c8
Index: multipath-tools-130222/libmultipath/devmapper.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/devmapper.c
4728c8
+++ multipath-tools-130222/libmultipath/devmapper.c
4728c8
@@ -23,6 +23,7 @@
4728c8
 #include "sysfs.h"
4728c8
 #include "discovery.h"
4728c8
 #include "log_pthread.h"
4728c8
+#include "propsel.h"
4728c8
 #include <sys/types.h>
4728c8
 #include <time.h>
4728c8
 
4728c8
@@ -334,7 +335,7 @@ static uint16_t build_udev_flags(const s
4728c8
 	/* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */
4728c8
 	return  (mpp->skip_kpartx == SKIP_KPARTX_ON ?
4728c8
 		 MPATH_UDEV_NO_KPARTX_FLAG : 0) |
4728c8
-		(mpp->nr_active == 0 ?
4728c8
+		((mpp->nr_active == 0 || mpp->ghost_delay_tick > 0)?
4728c8
 		 MPATH_UDEV_NO_PATHS_FLAG : 0) |
4728c8
 		(reload && !mpp->force_udev_reload ?
4728c8
 		 MPATH_UDEV_RELOAD_FLAG : 0);
4728c8
@@ -343,8 +344,16 @@ static uint16_t build_udev_flags(const s
4728c8
 extern int
4728c8
 dm_addmap_create (struct multipath *mpp, char * params) {
4728c8
 	int ro;
4728c8
-	uint16_t udev_flags = build_udev_flags(mpp, 0);
4728c8
+	uint16_t udev_flags;
4728c8
 
4728c8
+	select_ghost_delay(mpp);
4728c8
+	if (conf->daemon && mpp->ghost_delay > 0 && mpp->nr_active &&
4728c8
+	    pathcount(mpp, PATH_GHOST) == mpp->nr_active)
4728c8
+		mpp->ghost_delay_tick = mpp->ghost_delay;
4728c8
+	else
4728c8
+		mpp->ghost_delay = 0;
4728c8
+
4728c8
+	udev_flags = build_udev_flags(mpp, 0);
4728c8
 	sysfs_set_max_sectors_kb(mpp, 0);
4728c8
 	for (ro = 0; ro <= 1; ro++) {
4728c8
 		int err;
4728c8
@@ -373,7 +382,11 @@ dm_addmap_create (struct multipath *mpp,
4728c8
 extern int
4728c8
 dm_addmap_reload (struct multipath *mpp, char *params, int flush) {
4728c8
 	int r = 0;
4728c8
-	uint16_t udev_flags = build_udev_flags(mpp, 1);
4728c8
+	uint16_t udev_flags;
4728c8
+
4728c8
+	if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP))
4728c8
+		mpp->ghost_delay_tick = mpp->ghost_delay = 0;
4728c8
+	udev_flags = build_udev_flags(mpp, 1);
4728c8
 
4728c8
 	sysfs_set_max_sectors_kb(mpp, 1);
4728c8
 	if (!mpp->force_readonly)
4728c8
Index: multipath-tools-130222/libmultipath/dict.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/dict.c
4728c8
+++ multipath-tools-130222/libmultipath/dict.c
4728c8
@@ -1032,6 +1032,25 @@ def_unpriv_sgio_handler(vector strvec)
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+def_ghost_delay_handler(vector strvec)
4728c8
+{
4728c8
+	char * buff;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		conf->ghost_delay = GHOST_DELAY_OFF;
4728c8
+	if ((conf->ghost_delay = atoi(buff)) < 0)
4728c8
+		conf->ghost_delay = DEFAULT_GHOST_DELAY;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * blacklist block handlers
4728c8
  */
4728c8
@@ -1895,6 +1914,29 @@ hw_unpriv_sgio_handler(vector strvec)
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+hw_ghost_delay_handler(vector strvec)
4728c8
+{
4728c8
+	struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!hwe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		hwe->ghost_delay = GHOST_DELAY_OFF;
4728c8
+	if ((hwe->ghost_delay = atoi(buff)) < 0)
4728c8
+		hwe->ghost_delay = DEFAULT_GHOST_DELAY;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * multipaths block handlers
4728c8
  */
4728c8
@@ -2474,6 +2516,29 @@ mp_unpriv_sgio_handler(vector strvec)
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+static int
4728c8
+mp_ghost_delay_handler(vector strvec)
4728c8
+{
4728c8
+	struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!mpe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		mpe->ghost_delay = GHOST_DELAY_OFF;
4728c8
+	if ((mpe->ghost_delay = atoi(buff)) < 0)
4728c8
+		mpe->ghost_delay = DEFAULT_GHOST_DELAY;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 /*
4728c8
  * config file keywords printing
4728c8
  */
4728c8
@@ -2788,6 +2853,19 @@ snprint_mp_unpriv_sgio (char * buff, int
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_mp_ghost_delay (char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct mpentry * mpe = (struct mpentry *)data;
4728c8
+
4728c8
+	if (mpe->ghost_delay == GHOST_DELAY_UNDEF)
4728c8
+		return 0;
4728c8
+	else if (mpe->ghost_delay == GHOST_DELAY_OFF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "%d", mpe->ghost_delay);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_hw_fast_io_fail(char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct hwentry * hwe = (struct hwentry *)data;
4728c8
@@ -3202,6 +3280,19 @@ snprint_hw_unpriv_sgio(char * buff, int
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_hw_ghost_delay (char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct hwentry * hwe = (struct hwentry *)data;
4728c8
+
4728c8
+	if (hwe->ghost_delay == GHOST_DELAY_UNDEF)
4728c8
+		return 0;
4728c8
+	else if (hwe->ghost_delay == GHOST_DELAY_OFF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "%d", hwe->ghost_delay);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_def_polling_interval (char * buff, int len, void * data)
4728c8
 {
4728c8
 	return snprintf(buff, len, "%i", conf->checkint);
4728c8
@@ -3696,6 +3787,16 @@ snprint_def_unpriv_sgio(char * buff, int
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_def_ghost_delay (char * buff, int len, void * data)
4728c8
+{
4728c8
+	if (conf->ghost_delay == GHOST_DELAY_OFF ||
4728c8
+	    conf->ghost_delay == GHOST_DELAY_UNDEF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "%d", conf->ghost_delay);
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_ble_simple (char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct blentry * ble = (struct blentry *)data;
4728c8
@@ -3792,6 +3893,7 @@ init_keywords(void)
4728c8
 	install_keyword("disable_changed_wwids", &def_disable_changed_wwids_handler, &snprint_def_disable_changed_wwids);
4728c8
 	install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb);
4728c8
 	install_keyword("unpriv_sgio", &def_unpriv_sgio_handler, &snprint_def_unpriv_sgio);
4728c8
+	install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay);
4728c8
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
4728c8
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
4728c8
 	__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
4728c8
@@ -3863,6 +3965,7 @@ init_keywords(void)
4728c8
 	install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx);
4728c8
 	install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb);
4728c8
 	install_keyword("unpriv_sgio", &hw_unpriv_sgio_handler, &snprint_hw_unpriv_sgio);
4728c8
+	install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay);
4728c8
 	install_sublevel_end();
4728c8
 
4728c8
 	install_keyword_root("overrides", &nop_handler);
4728c8
@@ -3923,5 +4026,6 @@ init_keywords(void)
4728c8
 	install_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx);
4728c8
 	install_keyword("max_sectors_kb", &mp_max_sectors_kb_handler, &snprint_mp_max_sectors_kb);
4728c8
 	install_keyword("unpriv_sgio", &mp_unpriv_sgio_handler, &snprint_mp_unpriv_sgio);
4728c8
+	install_keyword("ghost_delay", &mp_ghost_delay_handler, &snprint_mp_ghost_delay);
4728c8
 	install_sublevel_end();
4728c8
 }
4728c8
Index: multipath-tools-130222/libmultipath/propsel.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.c
4728c8
+++ multipath-tools-130222/libmultipath/propsel.c
4728c8
@@ -966,3 +966,29 @@ select_unpriv_sgio (struct multipath * m
4728c8
 	condlog(3, "unpriv_sgio = DISABLED (internal default)");
4728c8
 	return 0;
4728c8
 }
4728c8
+
4728c8
+extern int
4728c8
+select_ghost_delay (struct multipath * mp)
4728c8
+{
4728c8
+	if (mp->mpe && mp->mpe->ghost_delay != GHOST_DELAY_UNDEF) {
4728c8
+		mp->ghost_delay = mp->mpe->ghost_delay;
4728c8
+		condlog(3, "ghost_delay = %i (multipath setting)",
4728c8
+				mp->ghost_delay);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (mp->hwe && mp->hwe->ghost_delay != GHOST_DELAY_UNDEF) {
4728c8
+		mp->ghost_delay = mp->hwe->ghost_delay;
4728c8
+		condlog(3, "ghost_delay = %i (controler setting)",
4728c8
+				mp->ghost_delay);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (conf->ghost_delay != GHOST_DELAY_UNDEF) {
4728c8
+		mp->ghost_delay = conf->ghost_delay;
4728c8
+		condlog(3, "ghost_delay = %i (config file default)",
4728c8
+				mp->ghost_delay);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	mp->ghost_delay = DEFAULT_GHOST_DELAY;
4728c8
+	condlog(3, "ghost_delay = DISABLED (internal default)");
4728c8
+	return 0;
4728c8
+}
4728c8
Index: multipath-tools-130222/libmultipath/propsel.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.h
4728c8
+++ multipath-tools-130222/libmultipath/propsel.h
4728c8
@@ -27,3 +27,4 @@ int select_delay_wait_checks (struct mul
4728c8
 int select_skip_kpartx (struct multipath * mp);
4728c8
 int select_max_sectors_kb (struct multipath * mp);
4728c8
 int select_unpriv_sgio (struct multipath * mp);
4728c8
+int select_ghost_delay (struct multipath * mp);
4728c8
Index: multipath-tools-130222/libmultipath/structs.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/structs.h
4728c8
+++ multipath-tools-130222/libmultipath/structs.h
4728c8
@@ -176,6 +176,11 @@ enum prkey_sources {
4728c8
 	PRKEY_SOURCE_FILE,
4728c8
 };
4728c8
 
4728c8
+enum ghost_delay_states {
4728c8
+	GHOST_DELAY_OFF = -1,
4728c8
+	GHOST_DELAY_UNDEF = 0,
4728c8
+};
4728c8
+
4728c8
 struct sg_id {
4728c8
 	int host_no;
4728c8
 	int channel;
4728c8
@@ -273,6 +278,8 @@ struct multipath {
4728c8
 	int max_sectors_kb;
4728c8
 	int force_readonly;
4728c8
 	int unpriv_sgio;
4728c8
+	int ghost_delay;
4728c8
+	int ghost_delay_tick;
4728c8
 	unsigned int dev_loss;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
Index: multipath-tools-130222/multipathd/main.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipathd/main.c
4728c8
+++ multipath-tools-130222/multipathd/main.c
4728c8
@@ -195,6 +195,8 @@ sync_map_state(struct multipath *mpp)
4728c8
 			    pp->state == PATH_WILD ||
4728c8
 			    pp->state == PATH_DELAYED)
4728c8
 				continue;
4728c8
+			if (mpp->ghost_delay_tick > 0)
4728c8
+				continue;
4728c8
 			if ((pp->dmstate == PSTATE_FAILED ||
4728c8
 			     pp->dmstate == PSTATE_UNDEF) &&
4728c8
 			    (pp->state == PATH_UP || pp->state == PATH_GHOST))
4728c8
@@ -535,7 +537,7 @@ ev_add_path (struct path * pp, struct ve
4728c8
 	if (mpp && mpp->wait_for_udev) {
4728c8
 		if (pathcount(mpp, PATH_UP) == 0 &&
4728c8
 		    (pathcount(mpp, PATH_GHOST) == 0 ||
4728c8
-		     pp->tpgs == TPGS_IMPLICIT))
4728c8
+		     mpp->ghost_delay_tick > 0 || pp->tpgs == TPGS_IMPLICIT))
4728c8
 			mpp->force_udev_reload = 1;
4728c8
 		else {
4728c8
 			condlog(2, "%s [%s]: delaying path addition until %s is fully initialized", pp->dev, pp->dev_t, mpp->alias);
4728c8
@@ -1215,6 +1217,28 @@ missing_uev_wait_tick(struct vectors *ve
4728c8
 }
4728c8
 
4728c8
 static void
4728c8
+ghost_delay_tick(struct vectors *vecs)
4728c8
+{
4728c8
+	struct multipath * mpp;
4728c8
+	unsigned int i;
4728c8
+
4728c8
+	vector_foreach_slot (vecs->mpvec, mpp, i) {
4728c8
+		if (mpp->ghost_delay_tick <= 0)
4728c8
+			continue;
4728c8
+		if (--mpp->ghost_delay_tick <= 0) {
4728c8
+			condlog(0, "%s: timed out waiting for active path",
4728c8
+				mpp->alias);
4728c8
+			if (update_map(mpp, vecs) != 0) {
4728c8
+				/* update_map removed map */
4728c8
+				i--;
4728c8
+				continue;
4728c8
+			}
4728c8
+			mpp->ghost_delay = mpp->ghost_delay_tick = 0;
4728c8
+		}
4728c8
+	}
4728c8
+}
4728c8
+
4728c8
+static void
4728c8
 defered_failback_tick (vector mpvec)
4728c8
 {
4728c8
 	struct multipath * mpp;
4728c8
@@ -1560,6 +1584,7 @@ checkerloop (void *ap)
4728c8
 			defered_failback_tick(vecs->mpvec);
4728c8
 			retry_count_tick(vecs->mpvec);
4728c8
 			missing_uev_wait_tick(vecs);
4728c8
+			ghost_delay_tick(vecs);
4728c8
 		}
4728c8
 		if (count)
4728c8
 			count--;
4728c8
Index: multipath-tools-130222/multipath/multipath.rules
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.rules
4728c8
+++ multipath-tools-130222/multipath/multipath.rules
4728c8
@@ -55,6 +55,7 @@ ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO=
4728c8
 ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPATH_NEED_KPARTX}="1"
4728c8
 ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
4728c8
 ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
4728c8
+ENV{DM_NOSCAN}=="1", GOTO="end_mpath"
4728c8
 ENV{DM_ACTIVATION}!="1", ENV{DM_MULTIPATH_NEED_KPARTX}!="1", GOTO="end_mpath"
4728c8
 RUN+="$env{MPATH_SBIN_PATH}/kpartx -an $tempnode", \
4728c8
 	ENV{DM_MULTIPATH_NEED_KPARTX}=""
4728c8
Index: multipath-tools-130222/multipath/multipath.conf.5
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.conf.5
4728c8
+++ multipath-tools-130222/multipath/multipath.conf.5
4728c8
@@ -601,6 +601,15 @@ device to the specified value. Default i
4728c8
 If set to \fIyes\fR, multipath will set upriv_sgio on the multipath device and
4728c8
 all its paths, when it is created or reloaded. The default is
4728c8
 .I no
4728c8
+.TP
4728c8
+.B ghost_delay
4728c8
+Sets the number of seconds that multipath will wait after creating a device
4728c8
+with only ghost paths before marking it ready for use in systemd. This gives
4728c8
+the active paths time to appear before the multipath runs the hardware handler
4728c8
+to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIoff\fR
4728c8
+makes multipath immediately mark a device with only ghost paths as ready. The
4728c8
+default is
4728c8
+.I off
4728c8
 .
4728c8
 .SH "blacklist section"
4728c8
 The
4728c8
@@ -716,6 +725,8 @@ section:
4728c8
 .B max_sectors_kb
4728c8
 .TP
4728c8
 .B unpriv_sgio
4728c8
+.TP
4728c8
+.B ghost_delay
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP
4728c8
@@ -820,6 +831,8 @@ section:
4728c8
 .B max_sectors_kb
4728c8
 .TP
4728c8
 .B unpriv_sgio
4728c8
+.TP
4728c8
+.B ghost_delay
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP