Blame SOURCES/0198-RHBZ-1372032-detect-path-checker.patch

4728c8
---
4728c8
 libmultipath/config.c      |    4 ++
4728c8
 libmultipath/config.h      |    2 +
4728c8
 libmultipath/defaults.h    |    1 
4728c8
 libmultipath/dict.c        |   74 +++++++++++++++++++++++++++++++++++++++++++++
4728c8
 libmultipath/discovery.c   |    1 
4728c8
 libmultipath/hwtable.c     |    1 
4728c8
 libmultipath/propsel.c     |   65 +++++++++++++++++++++++++++++++--------
4728c8
 libmultipath/propsel.h     |    1 
4728c8
 libmultipath/structs.h     |    7 ++++
4728c8
 multipath/multipath.conf.5 |    9 +++++
4728c8
 10 files changed, 152 insertions(+), 13 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
@@ -340,6 +340,7 @@ merge_hwe (struct hwentry * dst, struct
4728c8
 	merge_num(user_friendly_names);
4728c8
 	merge_num(retain_hwhandler);
4728c8
 	merge_num(detect_prio);
4728c8
+	merge_num(detect_checker);
4728c8
 	merge_num(deferred_remove);
4728c8
 	merge_num(delay_watch_checks);
4728c8
 	merge_num(delay_wait_checks);
4728c8
@@ -402,6 +403,7 @@ overwrite_hwe (struct hwentry * dst, str
4728c8
 	overwrite_num(user_friendly_names);
4728c8
 	overwrite_num(retain_hwhandler);
4728c8
 	overwrite_num(detect_prio);
4728c8
+	overwrite_num(detect_checker);
4728c8
 	overwrite_num(deferred_remove);
4728c8
 	overwrite_num(delay_watch_checks);
4728c8
 	overwrite_num(delay_wait_checks);
4728c8
@@ -476,6 +478,7 @@ store_hwe (vector hwtable, struct hwentr
4728c8
 	hwe->user_friendly_names = dhwe->user_friendly_names;
4728c8
 	hwe->retain_hwhandler = dhwe->retain_hwhandler;
4728c8
 	hwe->detect_prio = dhwe->detect_prio;
4728c8
+	hwe->detect_checker = dhwe->detect_checker;
4728c8
 
4728c8
 	if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
4728c8
 		goto out;
4728c8
@@ -672,6 +675,7 @@ load_config (char * file, struct udev *u
4728c8
 	conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
4728c8
 	conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
4728c8
 	conf->detect_prio = DEFAULT_DETECT_PRIO;
4728c8
+	conf->detect_checker = DEFAULT_DETECT_CHECKER;
4728c8
 	conf->deferred_remove = DEFAULT_DEFERRED_REMOVE;
4728c8
 	conf->hw_strmatch = 0;
4728c8
 	conf->force_sync = 0;
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
@@ -61,6 +61,7 @@ struct hwentry {
4728c8
 	int user_friendly_names;
4728c8
 	int retain_hwhandler;
4728c8
 	int detect_prio;
4728c8
+	int detect_checker;
4728c8
 	int deferred_remove;
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
@@ -136,6 +137,7 @@ struct config {
4728c8
 	int reassign_maps;
4728c8
 	int retain_hwhandler;
4728c8
 	int detect_prio;
4728c8
+	int detect_checker;
4728c8
 	int force_sync;
4728c8
 	int deferred_remove;
4728c8
 	int ignore_new_boot_devs;
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
@@ -19,6 +19,7 @@
4728c8
 #define DEFAULT_FAST_IO_FAIL	5
4728c8
 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
4728c8
 #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
4728c8
+#define DEFAULT_DETECT_CHECKER DETECT_CHECKER_OFF
4728c8
 #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
4728c8
 #define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
4728c8
 #define DEFAULT_RETRIGGER_DELAY 10
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
@@ -714,6 +714,29 @@ def_detect_prio_handler(vector strvec)
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+def_detect_checker_handler(vector strvec)
4728c8
+{
4728c8
+	char * buff;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		conf->detect_checker = DETECT_CHECKER_OFF;
4728c8
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
4728c8
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
4728c8
+		conf->detect_checker = DETECT_CHECKER_ON;
4728c8
+	else
4728c8
+		conf->detect_checker = DETECT_CHECKER_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 def_hw_strmatch_handler(vector strvec)
4728c8
 {
4728c8
 	char *buff;
4728c8
@@ -1682,6 +1705,33 @@ hw_detect_prio_handler(vector strvec)
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+hw_detect_checker_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
+
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		hwe->detect_checker = DETECT_CHECKER_OFF;
4728c8
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
4728c8
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
4728c8
+		hwe->detect_checker = DETECT_CHECKER_ON;
4728c8
+	else
4728c8
+		hwe->detect_checker = DETECT_CHECKER_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 hw_deferred_remove_handler(vector strvec)
4728c8
 {
4728c8
 	struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
4728c8
@@ -3059,6 +3109,19 @@ snprint_detect_prio(char * buff, int len
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_detect_checker(char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct hwentry * hwe = (struct hwentry *)data;
4728c8
+
4728c8
+	if (hwe->detect_checker == DETECT_CHECKER_ON)
4728c8
+		return snprintf(buff, len, "yes");
4728c8
+	else if (hwe->detect_checker == DETECT_CHECKER_OFF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_hw_max_sectors_kb(char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct hwentry * hwe = (struct hwentry *)data;
4728c8
@@ -3424,6 +3487,15 @@ snprint_def_detect_prio(char * buff, int
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_def_detect_checker(char * buff, int len, void * data)
4728c8
+{
4728c8
+	if (conf->detect_checker == DETECT_PRIO_ON)
4728c8
+		return snprintf(buff, len, "yes");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "no");
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_def_hw_strmatch(char * buff, int len, void * data)
4728c8
 {
4728c8
 	if (conf->hw_strmatch)
4728c8
@@ -3611,6 +3683,7 @@ init_keywords(void)
4728c8
 	install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
4728c8
 	install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
4728c8
 	install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
4728c8
+	install_keyword("detect_path_checker", &def_detect_checker_handler, &snprint_def_detect_checker);
4728c8
 	install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch);
4728c8
 	install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
4728c8
 	install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
4728c8
@@ -3690,6 +3763,7 @@ init_keywords(void)
4728c8
 	install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names);
4728c8
 	install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
4728c8
 	install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
4728c8
+	install_keyword("detect_path_checker", &hw_detect_checker_handler, &snprint_detect_checker);
4728c8
 	install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
4728c8
 	install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
4728c8
Index: multipath-tools-130222/libmultipath/discovery.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/discovery.c
4728c8
+++ multipath-tools-130222/libmultipath/discovery.c
4728c8
@@ -1107,6 +1107,7 @@ get_state (struct path * pp, int daemon)
4728c8
 				return PATH_UNCHECKED;
4728c8
 			}
4728c8
 		}
4728c8
+		select_detect_checker(pp);
4728c8
 		select_checker(pp);
4728c8
 		if (!checker_selected(c)) {
4728c8
 			condlog(3, "%s: No checker selected", pp->dev);
4728c8
Index: multipath-tools-130222/libmultipath/hwtable.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/hwtable.c
4728c8
+++ multipath-tools-130222/libmultipath/hwtable.c
4728c8
@@ -289,6 +289,7 @@ static struct hwentry default_hw[] = {
4728c8
 		.prio_args     = NULL,
4728c8
 		.retain_hwhandler = RETAIN_HWHANDLER_ON,
4728c8
 		.detect_prio   = DETECT_PRIO_ON,
4728c8
+		.detect_checker = DETECT_CHECKER_ON,
4728c8
 	},
4728c8
 	{
4728c8
 		.vendor        = "EMC",
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
@@ -335,11 +335,43 @@ select_hwhandler (struct multipath * mp)
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+int
4728c8
+detect_alua(struct path * pp)
4728c8
+{
4728c8
+	int ret;
4728c8
+	int tpgs = 0;
4728c8
+
4728c8
+	if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
4728c8
+		return 0;
4728c8
+	pp->tpgs = tpgs;
4728c8
+	ret = get_target_port_group(pp->fd, NULL);
4728c8
+	if (ret < 0)
4728c8
+		return 0;
4728c8
+	if (get_asymmetric_access_state(pp->fd, ret, NULL) < 0)
4728c8
+		return 0;
4728c8
+	return 1;
4728c8
+}
4728c8
+
4728c8
+void
4728c8
+detect_checker(struct path * pp)
4728c8
+{
4728c8
+	if (detect_alua(pp))
4728c8
+		checker_get(&pp->checker, TUR);
4728c8
+}
4728c8
+
4728c8
 extern int
4728c8
 select_checker(struct path *pp)
4728c8
 {
4728c8
 	struct checker * c = &pp->checker;
4728c8
 
4728c8
+	if (pp->detect_checker == DETECT_CHECKER_ON) {
4728c8
+		detect_checker(pp);
4728c8
+		if (checker_selected(c)) {
4728c8
+			condlog(3, "%s: path checker = %s (detected setting)",
4728c8
+				pp->dev, checker_name(c));
4728c8
+			goto out;
4728c8
+		}
4728c8
+	}
4728c8
 	if (pp->hwe && pp->hwe->checker_name) {
4728c8
 		checker_get(c, pp->hwe->checker_name);
4728c8
 		condlog(3, "%s: path checker = %s (controller setting)",
4728c8
@@ -396,19 +428,8 @@ select_getuid (struct path * pp)
4728c8
 void
4728c8
 detect_prio(struct path * pp)
4728c8
 {
4728c8
-	int ret;
4728c8
-	struct prio *p = &pp->prio;
4728c8
-	int tpgs = 0;
4728c8
-
4728c8
-	if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
4728c8
-		return;
4728c8
-	pp->tpgs = tpgs;
4728c8
-	ret = get_target_port_group(pp->fd, NULL);
4728c8
-	if (ret < 0)
4728c8
-		return;
4728c8
-	if (get_asymmetric_access_state(pp->fd, ret, NULL) < 0)
4728c8
-		return;
4728c8
-	prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
4728c8
+	if (detect_alua(pp))
4728c8
+		prio_get(&pp->prio, PRIO_ALUA, DEFAULT_PRIO_ARGS);
4728c8
 }
4728c8
 
4728c8
 extern int
4728c8
@@ -803,6 +824,24 @@ select_detect_prio (struct path * pp)
4728c8
 	return 0;
4728c8
 }
4728c8
 
4728c8
+extern int
4728c8
+select_detect_checker (struct path * pp)
4728c8
+{
4728c8
+	if (pp->hwe && pp->hwe->detect_checker) {
4728c8
+		pp->detect_checker = pp->hwe->detect_checker;
4728c8
+		condlog(3, "%s: detect_checker = %d (controller default)", pp->dev, pp->detect_checker);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (conf->detect_checker) {
4728c8
+		pp->detect_checker = conf->detect_checker;
4728c8
+		condlog(3, "%s: detect_checker = %d (config file default)", pp->dev, pp->detect_checker);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	pp->detect_checker = DEFAULT_DETECT_CHECKER;
4728c8
+	condlog(3, "%s: detect_checker = %d (compiled in default)", pp->dev, pp->detect_checker);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
 extern int
4728c8
 select_delay_watch_checks (struct multipath * mp)
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
@@ -20,6 +20,7 @@ int select_dev_loss(struct multipath *mp
4728c8
 int select_reservation_key(struct multipath *mp);
4728c8
 int select_retain_hwhandler (struct multipath * mp);
4728c8
 int select_detect_prio(struct path * pp);
4728c8
+int select_detect_checker(struct path * pp);
4728c8
 int select_deferred_remove(struct multipath *mp);
4728c8
 int select_delay_watch_checks (struct multipath * mp);
4728c8
 int select_delay_wait_checks (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
@@ -115,6 +115,12 @@ enum detect_prio_states {
4728c8
 	DETECT_PRIO_ON,
4728c8
 };
4728c8
 
4728c8
+enum detect_checker_states {
4728c8
+	DETECT_CHECKER_UNDEF,
4728c8
+	DETECT_CHECKER_OFF,
4728c8
+	DETECT_CHECKER_ON,
4728c8
+};
4728c8
+
4728c8
 enum deferred_remove_states {
4728c8
 	DEFERRED_REMOVE_UNDEF,
4728c8
 	DEFERRED_REMOVE_OFF,
4728c8
@@ -204,6 +210,7 @@ struct path {
4728c8
 	int priority;
4728c8
 	int pgindex;
4728c8
 	int detect_prio;
4728c8
+	int detect_checker;
4728c8
 	int watch_checks;
4728c8
 	int wait_checks;
4728c8
 	int tpgs;
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
@@ -448,6 +448,15 @@ will automatically use the
4728c8
 prioritizer. If not, the prioritizer will be selected as usual. Default is
4728c8
 .I no
4728c8
 .TP
4728c8
+.B detect_checker
4728c8
+If set to
4728c8
+.I yes
4728c8
+, multipath will try to detect if the device supports ALUA. If so, the device
4728c8
+will automatically use the
4728c8
+.I tur
4728c8
+checker. If not, the prioritizer will be selected as ususal. Default is
4728c8
+.I no
4728c8
+.TP
4728c8
 .B hw_str_match
4728c8
 If set to
4728c8
 .I yes