rpms/device-mapper-multipath/devel 0002-for-upstream-add-tmo-config-options.patch, NONE, 1.1 0013-RH-add-weighted_prio-prioritizer.patch, NONE, 1.1 0014-RH-add-hp_tur-checker.patch, NONE, 1.1 0015-RH-add-multipathd-count-paths-cmd.patch, NONE, 1.1 multipath.conf, NONE, 1.1 device-mapper-multipath.spec, 1.63, 1.64 multipath.conf.redhat, 1.1, NONE

Benjamin Marzinski bmarzins at fedoraproject.org
Tue Nov 17 06:33:07 UTC 2009


Author: bmarzins

Update of /cvs/pkgs/rpms/device-mapper-multipath/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12518

Modified Files:
	device-mapper-multipath.spec 
Added Files:
	0002-for-upstream-add-tmo-config-options.patch 
	0013-RH-add-weighted_prio-prioritizer.patch 
	0014-RH-add-hp_tur-checker.patch 
	0015-RH-add-multipathd-count-paths-cmd.patch multipath.conf 
Removed Files:
	multipath.conf.redhat 
Log Message:
- Add 0002-for-upstream-add-tmo-config-options.patch
  * Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options
- Add 0013-RH-add-weighted_prio-prioritizer.patch
- Add 0014-RH-add-hp_tur-checker.patch
- Add 0015-RH-add-multipathd-count-paths-cmd.patch
- rename multipath.conf.redhat to multipath.conf, and remove the default
  blacklist


0002-for-upstream-add-tmo-config-options.patch:
 libmultipath/config.h      |    4 +
 libmultipath/configure.c   |    3 +
 libmultipath/dict.c        |  102 +++++++++++++++++++++++++++++++++++++++++++++
 libmultipath/discovery.c   |   37 ++++++++++++++++
 libmultipath/discovery.h   |    1 
 libmultipath/propsel.c     |   42 ++++++++++++++++++
 libmultipath/propsel.h     |    2 
 libmultipath/structs.h     |    2 
 libmultipath/sysfs.c       |   56 ++++++++++++++++++++++++
 libmultipath/sysfs.h       |    3 -
 multipath.conf.annotated   |   38 ++++++++++++++++
 multipath/multipath.conf.5 |   15 ++++++
 12 files changed, 303 insertions(+), 2 deletions(-)

--- NEW FILE 0002-for-upstream-add-tmo-config-options.patch ---
---
 libmultipath/config.h      |    4 +
 libmultipath/configure.c   |    3 +
 libmultipath/dict.c        |  102 +++++++++++++++++++++++++++++++++++++++++++++
 libmultipath/discovery.c   |   37 ++++++++++++++++
 libmultipath/discovery.h   |    1 
 libmultipath/propsel.c     |   42 ++++++++++++++++++
 libmultipath/propsel.h     |    2 
 libmultipath/structs.h     |    2 
 libmultipath/sysfs.c       |   56 ++++++++++++++++++++++++
 libmultipath/sysfs.h       |    3 -
 multipath.conf.annotated   |   38 ++++++++++++++++
 multipath/multipath.conf.5 |   15 ++++++
 12 files changed, 303 insertions(+), 2 deletions(-)

Index: multipath-tools-091020/multipath.conf.annotated
===================================================================
--- multipath-tools-091020.orig/multipath.conf.annotated
+++ multipath-tools-091020/multipath.conf.annotated
@@ -191,6 +191,25 @@
 #	# default : determined by the process
 #	gid disk
 #
+#	#
+#	# name    : fast_io_fail_tmo
+#	# scope   : multipath & multipathd
+#	# desc    : The number of seconds the scsi layer will wait after a
+#	#           problem has been detected on a FC remote port before failing
+#	#           IO to devices on that remote port.
+#	# values  : off | n >= 0 (smaller than dev_loss_tmo)
+#	# default : determined by the OS
+#	fast_io_fail_tmo 5
+#
+#	#
+#	# name    : dev_loss_tmo
+#	# scope   : multipath & multipathd
+#	# desc    : The number of seconds the scsi layer will wait after a
+#	#           problem has been detected on a FC remote port before
+#	#           removing it from the system.
+#	# values  : n > 0
+#	# default : determined by the OS
+#	dev_loss_tmo 600
 #}
 #	
 ##
@@ -504,7 +523,6 @@
 #		# desc    : If set to "yes", multipathd will disable queueing
 #		#           when the last path to a device has been deleted.
 #		# values  : yes|no
-#		# default : no
 #		#
 #		flush_on_last_del       yes
 #
@@ -514,6 +532,24 @@
 #		# desc    : product strings to blacklist for this vendor
 #		#
 #		product_blacklist	LUN_Z
+#
+#		#
+#		# name    : fast_io_fail_tmo
+#		# scope   : multipath & multipathd
+#		# desc    : The number of seconds the scsi layer will wait after
+#		#           a problem has been detected on a FC remote port
+#		#           before failing IO to devices on that remote port.
+#		# values  : off | n >= 0 (smaller than dev_loss_tmo)
+#		fast_io_fail_tmo 5
+#
+#		#
+#		# name    : dev_loss_tmo
+#		# scope   : multipath & multipathd
+#		# desc    : The number of seconds the scsi layer will wait after
+#		#           a problem has been detected on a FC remote port
+#		#           before removing it from the system.
+#		# values  : n > 0
+#		dev_loss_tmo 600
 #	}
 #	device {
 #		vendor			"COMPAQ  "
Index: multipath-tools-091020/multipath/multipath.conf.5
===================================================================
--- multipath-tools-091020.orig/multipath/multipath.conf.5
+++ multipath-tools-091020/multipath/multipath.conf.5
@@ -240,6 +240,17 @@ this to the system limit from /proc/sys/
 maximum number of open fds is taken from the calling process. It is usually
 1024. To be safe, this should be set to the maximum number of paths plus 32,
 if that number is greated than 1024.
+.TP
+.B fast_io_fail_tmo
+Specify the number of seconds the scsi layer will wait after a problem has been
+detected on a FC remote port before failing IO to devices on that remote port.
+This should be smaller than dev_loss_tmo. Setting this to
+.I off
+will disable the timeout.
+.TP
+.B dev_loss_tmo
+Specify the number of seconds the scsi layer will wait after a problem has
+been detected on a FC remote port before removing it from the system.
 .
 .SH "blacklist section"
 The
@@ -384,6 +395,10 @@ section:
 .B no_path_retry
 .TP
 .B rr_min_io
+.TP
+.B fast_io_fail_tmo
+.TP
+.B dev_loss_tmo
 .RE
 .PD
 .LP
Index: multipath-tools-091020/libmultipath/dict.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/dict.c
+++ multipath-tools-091020/libmultipath/dict.c
@@ -37,6 +37,35 @@ polling_interval_handler(vector strvec)
 }
 
 static int
+def_fast_io_fail_handler(vector strvec)
+{
+	char * buff;
+
+	buff = set_value(strvec);
+	if (strlen(buff) == 3 && !strcmp(buff, "off"))
+		conf->fast_io_fail = -1;
+	else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 ||
+		 conf->fast_io_fail < -1)
+		conf->fast_io_fail = 0;
+
+	FREE(buff);
+	return 0;
+}
+
+static int
+def_dev_loss_handler(vector strvec)
+{
+	char * buff;
+
+	buff = set_value(strvec);
+	if (sscanf(buff, "%u", &conf->dev_loss) != 1)
+		conf->dev_loss = 0;
+
+	FREE(buff);
+	return 0;
+}
+
+static int
 verbosity_handler(vector strvec)
 {
 	char * buff;
@@ -628,6 +657,37 @@ bl_product_handler(vector strvec)
 }
 
 static int
+hw_fast_io_fail_handler(vector strvec)
+{
+	char * buff;
+	struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+
+	buff = set_value(strvec);
+	if (strlen(buff) == 3 && !strcmp(buff, "off"))
+		hwe->fast_io_fail = -1;
+	else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 ||
+		 hwe->fast_io_fail < -1)
+		hwe->fast_io_fail = 0;
+
+	FREE(buff);
+	return 0;
+}
+
+static int
+hw_dev_loss_handler(vector strvec)
+{
+	char * buff;
+	struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+
+	buff = set_value(strvec);
+	if (sscanf(buff, "%u", &hwe->dev_loss) != 1)
+		hwe->dev_loss = 0;
+
+	FREE(buff);
+	return 0;
+}
+
+static int
 hw_pgpolicy_handler(vector strvec)
 {
 	char * buff;
@@ -1390,6 +1450,26 @@ snprint_mp_flush_on_last_del (char * buf
 }
 
 static int
+snprint_hw_fast_io_fail(char * buff, int len, void * data)
+{
+	struct hwentry * hwe = (struct hwentry *)data;
+	if (!hwe->fast_io_fail)
+		return 0;
+	if (hwe->fast_io_fail == -1)
+		return snprintf(buff, len, "off");
+	return snprintf(buff, len, "%d", hwe->fast_io_fail);
+}
+
+static int
+snprint_hw_dev_loss(char * buff, int len, void * data)
+{
+	struct hwentry * hwe = (struct hwentry *)data;
+	if (!hwe->dev_loss)
+		return 0;
+	return snprintf(buff, len, "%u", hwe->dev_loss);
+}
+
+static int
 snprint_hw_vendor (char * buff, int len, void * data)
 {
 	struct hwentry * hwe = (struct hwentry *)data;
@@ -1640,6 +1720,24 @@ snprint_def_polling_interval (char * buf
 }
 
 static int
+snprint_def_fast_io_fail(char * buff, int len, void * data)
+{
+	if (!conf->fast_io_fail)
+		return 0;
+	if (conf->fast_io_fail == -1)
+		return snprintf(buff, len, "off");
+	return snprintf(buff, len, "%d", conf->fast_io_fail);
+}
+
+static int
+snprint_def_dev_loss(char * buff, int len, void * data)
+{
+	if (!conf->dev_loss)
+		return 0;
+	return snprintf(buff, len, "%u", conf->dev_loss);
+}
+
+static int
 snprint_def_verbosity (char * buff, int len, void * data)
 {
 	if (conf->checkint == DEFAULT_VERBOSITY)
@@ -1937,6 +2035,8 @@ init_keywords(void)
 	install_keyword("mode", &def_mode_handler, &snprint_def_mode);
 	install_keyword("uid", &def_uid_handler, &snprint_def_uid);
 	install_keyword("gid", &def_gid_handler, &snprint_def_gid);
+	install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
+	install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
 	__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
@@ -1991,6 +2091,8 @@ init_keywords(void)
 	install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io);
 	install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout);
 	install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
+	install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
+	install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
 	install_sublevel_end();
 
 	install_keyword_root("multipaths", &multipaths_handler);
Index: multipath-tools-091020/libmultipath/config.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/config.h
+++ multipath-tools-091020/libmultipath/config.h
@@ -31,6 +31,8 @@ struct hwentry {
 	int minio;
 	int pg_timeout;
 	int flush_on_last_del;
+	int fast_io_fail;
+	unsigned int dev_loss;
 	char * bl_product;
 };
 
@@ -75,6 +77,8 @@ struct config {
 	int daemon;
 	int flush_on_last_del;
 	int attribute_flags;
+	int fast_io_fail;
+	unsigned int dev_loss;
 	uid_t uid;
 	gid_t gid;
 	mode_t mode;
Index: multipath-tools-091020/libmultipath/propsel.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/propsel.c
+++ multipath-tools-091020/libmultipath/propsel.c
@@ -428,6 +428,48 @@ select_pg_timeout(struct multipath *mp)
 }
 
 extern int
+select_fast_io_fail(struct multipath *mp)
+{
+	if (mp->hwe && mp->hwe->fast_io_fail) {
+		mp->fast_io_fail = mp->hwe->fast_io_fail;
+		if (mp->fast_io_fail == -1)
+			condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias);
+		else
+			condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias, mp->fast_io_fail);
+		return 0;
+	}
+	if (conf->fast_io_fail) {
+		mp->fast_io_fail = conf->fast_io_fail;
+		if (mp->fast_io_fail == -1)
+			condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias);
+		else
+			condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias, mp->fast_io_fail);
+		return 0;
+	}
+	mp->fast_io_fail = 0;
+	return 0;
+}
+
+extern int
+select_dev_loss(struct multipath *mp)
+{
+	if (mp->hwe && mp->hwe->dev_loss) {
+		mp->dev_loss = mp->hwe->dev_loss;
+		condlog(3, "%s: dev_loss_tmo = %u (controller default)",
+			mp->alias, mp->dev_loss);
+		return 0;
+	}
+	if (conf->dev_loss) {
+		mp->dev_loss = conf->dev_loss;
+		condlog(3, "%s: dev_loss_tmo = %u (config file default)",
+			mp->alias, mp->dev_loss);
+		return 0;
+	}
+	mp->dev_loss = 0;
+	return 0;
+}
+
+extern int
 select_flush_on_last_del(struct multipath *mp)
 {
 	if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
Index: multipath-tools-091020/libmultipath/structs.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/structs.h
+++ multipath-tools-091020/libmultipath/structs.h
@@ -166,6 +166,8 @@ struct multipath {
 	int pg_timeout;
 	int flush_on_last_del;
 	int attribute_flags;
+	int fast_io_fail;
+	unsigned int dev_loss;
 	uid_t uid;
 	gid_t gid;
 	mode_t mode;
Index: multipath-tools-091020/libmultipath/configure.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/configure.c
+++ multipath-tools-091020/libmultipath/configure.c
@@ -70,7 +70,10 @@ setup_map (struct multipath * mpp)
 	select_mode(mpp);
 	select_uid(mpp);
 	select_gid(mpp);
+	select_fast_io_fail(mpp);
+	select_dev_loss(mpp);
 
+	sysfs_set_scsi_tmo(mpp);
 	/*
 	 * assign paths to path groups -- start with no groups and all paths
 	 * in mpp->paths
Index: multipath-tools-091020/libmultipath/discovery.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/discovery.c
+++ multipath-tools-091020/libmultipath/discovery.c
@@ -204,6 +204,43 @@ sysfs_get_fc_nodename (struct sysfs_devi
 	return 1;
 }
 
+int
+sysfs_set_scsi_tmo (struct multipath *mpp)
+{
+	char attr_path[SYSFS_PATH_SIZE];
+	struct path *pp;
+	int i;
+	char value[11];
+
+	if (!mpp->dev_loss && !mpp->fast_io_fail)
+		return 0;
+	vector_foreach_slot(mpp->paths, pp, i) {
+		if (safe_snprintf(attr_path, SYSFS_PATH_SIZE,
+	        	          "/class/fc_remote_ports/rport-%d:%d-%d",
+				  pp->sg_id.host_no, pp->sg_id.channel,
+				  pp->sg_id.scsi_id)) {
+			condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id);
+			return 1;
+		}
+		if (mpp->dev_loss){
+			snprintf(value, 11, "%u", mpp->dev_loss);
+ 			if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
+						 value))
+				return 1;
+		}
+		if (mpp->fast_io_fail){
+			if (mpp->fast_io_fail == -1)
+				sprintf(value, "off");
+			else
+				snprintf(value, 11, "%u", mpp->fast_io_fail);
+			if (sysfs_attr_set_value(attr_path, "fast_io_fail",
+						 value))
+				return 1;
+		}
+	}
+	return 0;
+}
+
 static int
 opennode (char * dev, int mode)
 {
Index: multipath-tools-091020/libmultipath/propsel.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/propsel.h
+++ multipath-tools-091020/libmultipath/propsel.h
@@ -15,3 +15,5 @@ int select_minio(struct multipath *mp);
 int select_mode(struct multipath *mp);
 int select_uid(struct multipath *mp);
 int select_gid(struct multipath *mp);
+int select_fast_io_fail(struct multipath *mp);
+int select_dev_loss(struct multipath *mp);
Index: multipath-tools-091020/libmultipath/discovery.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/discovery.h
+++ multipath-tools-091020/libmultipath/discovery.h
@@ -33,6 +33,7 @@ int path_offline (struct path *);
 int pathinfo (struct path *, vector hwtable, int mask);
 struct path * store_pathinfo (vector pathvec, vector hwtable,
 			      char * devname, int flag);
+int sysfs_set_scsi_tmo (struct multipath *mpp);
 
 /*
  * discovery bitmask
Index: multipath-tools-091020/libmultipath/sysfs.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/sysfs.c
+++ multipath-tools-091020/libmultipath/sysfs.c
@@ -356,6 +356,62 @@ void sysfs_device_put(struct sysfs_devic
 	return;
 }
 
+int
+sysfs_attr_set_value(const char *devpath, const char *attr_name,
+		     const char *value)
+{
+	char path_full[PATH_SIZE];
+	int sysfs_len;
+	struct stat statbuf;
+	int fd, value_len, ret = -1;
+
+	dbg("open '%s'/'%s'", devpath, attr_name);
+	sysfs_len = snprintf(path_full, PATH_SIZE, "%s%s/%s", sysfs_path,
+			     devpath, attr_name);
+	if (sysfs_len >= PATH_SIZE || sysfs_len < 0) {
+		if (sysfs_len < 0)
+			dbg("cannot copy sysfs path %s%s/%s : %s", sysfs_path,
+			    devpath, attr_name, strerror(errno));
+		else
+			dbg("sysfs_path %s%s/%s too large", sysfs_path,
+			    devpath, attr_name);
+		goto out;
+	}
+
+	if (stat(path_full, &statbuf) != 0) {
+		dbg("stat '%s' failed: %s" path_full, strerror(errno));
+		goto out;
+	}
+
+	/* skip directories */
+        if (S_ISDIR(statbuf.st_mode))
+                goto out;
+
+	if ((statbuf.st_mode & S_IWUSR) == 0)
+		goto out;
+
+	fd = open(path_full, O_WRONLY);
+	if (fd < 0) {
+		dbg("attribute '%s' can not be opened: %s",
+		    path_full, strerror(errno));
+		goto out;
+	}
+	value_len = strlen(value) + 1;
+	ret = write(fd, value, value_len);
+	if (ret == value_len)
+		ret = 0;
+	else if (ret < 0)
+		dbg("write to %s failed: %s", path_full, strerror(errno));
+	else {
+		dbg("tried to write %d to %s. Wrote %d\n", value_len,
+		    path_full, ret);
+		ret = -1;
+	}
+out:
+	return ret;
+}
+
+
 char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
 {
 	char path_full[PATH_SIZE];
Index: multipath-tools-091020/libmultipath/sysfs.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/sysfs.h
+++ multipath-tools-091020/libmultipath/sysfs.h
@@ -22,5 +22,6 @@ void sysfs_device_put(struct sysfs_devic
 char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
 int sysfs_resolve_link(char *path, size_t size);
 int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size);
-
+int sysfs_attr_set_value(const char *devpath, const char *attr_name,
+			 const char *value);
 #endif

0013-RH-add-weighted_prio-prioritizer.patch:
 config.c                |   10 +++
 config.h                |    4 +
 dict.c                  |   92 +++++++++++++++++++++++++++----
 discovery.c             |   56 ++++++++++---------
 prio.h                  |    1 
 prioritizers/Makefile   |    3 -
 prioritizers/weighted.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++
 prioritizers/weighted.h |    8 ++
 propsel.c               |   11 +++
 structs.h               |    1 
 10 files changed, 286 insertions(+), 39 deletions(-)

--- NEW FILE 0013-RH-add-weighted_prio-prioritizer.patch ---
Index: multipath-tools-091020/libmultipath/config.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/config.c
+++ multipath-tools-091020/libmultipath/config.c
@@ -156,6 +156,9 @@ free_hwe (struct hwentry * hwe)
 	if (hwe->prio_name)
 		FREE(hwe->prio_name);
 
+	if (hwe->prio_args)
+		FREE(hwe->prio_args);
+
 	if (hwe->bl_product)
 		FREE(hwe->bl_product);
 
@@ -195,6 +198,12 @@ free_mpe (struct mpentry * mpe)
 	if (mpe->alias)
 		FREE(mpe->alias);
 
+	if (mpe->prio_name)
+		FREE(mpe->prio_name);
+
+	if (mpe->prio_args)
+		FREE(mpe->prio_args);
+
 	FREE(mpe);
 }
 
@@ -279,6 +288,7 @@ merge_hwe (struct hwentry * hwe1, struct
 	merge_str(selector);
 	merge_str(checker_name);
 	merge_str(prio_name);
+	merge_str(prio_args);
 	merge_str(bl_product);
 	merge_num(pgpolicy);
 	merge_num(pgfailback);
Index: multipath-tools-091020/libmultipath/config.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/config.h
+++ multipath-tools-091020/libmultipath/config.h
@@ -24,6 +24,7 @@ struct hwentry {
 	char * selector;
 	char * checker_name;
 	char * prio_name;
+	char * prio_args;
 
 	int pgpolicy;
 	int pgfailback;
@@ -42,6 +43,8 @@ struct mpentry {
 	char * alias;
 	char * getuid;
 	char * selector;
+	char * prio_name;
+	char * prio_args;
 
 	int pgpolicy;
 	int pgfailback;
@@ -95,6 +98,7 @@ struct config {
 	char * hwhandler;
 	char * bindings_file;
 	char * prio_name;
+	char * prio_args;
 	char * checker_name;
 
 	vector keywords;
Index: multipath-tools-091020/libmultipath/dict.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/dict.c
+++ multipath-tools-091020/libmultipath/dict.c
@@ -139,11 +139,23 @@ def_getuid_callout_handler(vector strvec
 static int
 def_prio_handler(vector strvec)
 {
-	conf->prio_name = set_value(strvec);
+	char *name, *args;
 
-	if (!conf->prio_name)
+	name = set_value(strvec);
+	if (!name)
 		return 1;
 
+	args = strpbrk(name, " \t");
+	if (args) {
+		*args = 0;
+		while(*++args && isblank(*args)); /* Do nothing */
+	}
+
+	conf->prio_name = STRDUP(name);
+	if (args && *args)
+		conf->prio_args = STRDUP(args);
+
+	FREE(name);
 	return 0;
 }
 
@@ -806,16 +818,27 @@ hw_handler_handler(vector strvec)
 static int
 hw_prio_handler(vector strvec)
 {
+	char *name, *args;
 	struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
 
 	if (!hwe)
 		return 1;
 
-	hwe->prio_name = set_value(strvec);
-
-	if (!hwe->prio_name)
+	name = set_value(strvec);
+	if (!name)
 		return 1;
 
+	args = strpbrk(name, " \t");
+	if (args) {
+		*args = 0;
+		while(*++args && isblank(*args)); /* Do nothing */
+	}
+
+	hwe->prio_name = STRDUP(name);
+	if (args && *args)
+		hwe->prio_args = STRDUP(args);
+
+	FREE(name);
 	return 0;
 }
 
@@ -1293,6 +1316,33 @@ mp_flush_on_last_del_handler(vector strv
 	return 0;
 }
 
+static int
+mp_prio_handler(vector strvec)
+{
+	char *name, *args;
+	struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+
+	if (!mpe)
+		return 1;
+
+	name = set_value(strvec);
+	if (!name)
+		return 1;
+
+	args = strpbrk(name, " \t");
+	if (args) {
+		*args = 0;
+		while(*++args && isblank(*args)); /* Do nothing */
+	}
+
+	mpe->prio_name = STRDUP(name);
+	if (args && *args)
+		mpe->prio_args = STRDUP(args);
+
+	FREE(name);
+	return 0;
+}
+
 /*
  * config file keywords printing
  */
@@ -1472,6 +1522,20 @@ snprint_mp_flush_on_last_del (char * buf
 }
 
 static int
+snprint_mp_prio (char * buff, int len, void * data)
+{
+	struct mpentry * mpe = (struct mpentry *)data;
+
+	if (!mpe->prio_name)
+		return 0;
+	if (!strcmp(mpe->prio_name, conf->prio_name) && !mpe->prio_args)
+		return 0;
+	if (!mpe->prio_args)
+		return snprintf(buff, len, "%s", mpe->prio_name);
+	return snprintf(buff, len, "%s %s", mpe->prio_name, mpe->prio_args);
+}
+
+static int
 snprint_hw_fast_io_fail(char * buff, int len, void * data)
 {
 	struct hwentry * hwe = (struct hwentry *)data;
@@ -1545,10 +1609,11 @@ snprint_hw_prio (char * buff, int len, v
 
 	if (!hwe->prio_name)
 		return 0;
-	if (!strcmp(hwe->prio_name, conf->prio_name))
+	if (!strcmp(hwe->prio_name, conf->prio_name) && !hwe->prio_args)
 		return 0;
-	
-	return snprintf(buff, len, "%s", hwe->prio_name);
+	if (!hwe->prio_args)
+		return snprintf(buff, len, "%s", hwe->prio_name);
+	return snprintf(buff, len, "%s %s", hwe->prio_name, hwe->prio_args);
 }
 
 static int
@@ -1837,10 +1902,14 @@ snprint_def_prio (char * buff, int len, 
 		return 0;
 
 	if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
-	    !strcmp(conf->prio_name, DEFAULT_PRIO))
+	    !strcmp(conf->prio_name, DEFAULT_PRIO) && !conf->prio_args)
 		return 0;
-	
-	return snprintf(buff, len, "%s", conf->prio_name);
+
+	if (!conf->prio_args)
+		return snprintf(buff, len, "%s", conf->prio_name);
+	else
+		return snprintf(buff, len, "%s %s", conf->prio_name,
+				conf->prio_args);
 }
 
 static int
@@ -2146,5 +2215,6 @@ init_keywords(void)
 	install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
 	install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
 	install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
+	install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
 	install_sublevel_end();
 }
Index: multipath-tools-091020/libmultipath/discovery.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/discovery.c
+++ multipath-tools-091020/libmultipath/discovery.c
@@ -800,30 +800,6 @@ get_state (struct path * pp, int daemon)
 }
 
 static int
-get_prio (struct path * pp)
-{
-	if (!pp)
-		return 0;
-
-	if (!pp->prio) {
-		select_prio(pp);
-		if (!pp->prio) {
-			condlog(3, "%s: no prio selected", pp->dev);
-			return 1;
-		}
-	}
-	pp->priority = prio_getprio(pp->prio, pp);
-	if (pp->priority < 0) {
-		condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
-		pp->priority = PRIO_UNDEF;
-		return 1;
-	}
-	condlog(3, "%s: %s prio = %u",
-		pp->dev, prio_name(pp->prio), pp->priority);
-	return 0;
-}
-
-static int
 get_uid (struct path * pp)
 {
 	char buff[CALLOUT_MAX_SIZE];
@@ -850,6 +826,32 @@ get_uid (struct path * pp)
 	return 0;
 }
 
+static int
+get_prio (struct path * pp)
+{
+	if (!pp)
+		return 0;
+
+	if (!pp->prio) {
+		if (!strlen(pp->wwid))
+			get_uid(pp);
+		select_prio(pp);
+		if (!pp->prio) {
+			condlog(3, "%s: no prio selected", pp->dev);
+			return 1;
+		}
+	}
+	pp->priority = prio_getprio(pp->prio, pp);
+	if (pp->priority < 0) {
+		condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
+		pp->priority = PRIO_UNDEF;
+		return 1;
+	}
+	condlog(3, "%s: %s prio = %u",
+		pp->dev, prio_name(pp->prio), pp->priority);
+	return 0;
+}
+
 extern int
 pathinfo (struct path *pp, vector hwtable, int mask)
 {
@@ -887,6 +889,9 @@ pathinfo (struct path *pp, vector hwtabl
 			goto blank;
 	}
 
+	if (mask & DI_WWID && !strlen(pp->wwid))
+		get_uid(pp);
+
 	 /*
 	  * Retrieve path priority, even for PATH_DOWN paths if it has never
 	  * been successfully obtained before.
@@ -895,9 +900,6 @@ pathinfo (struct path *pp, vector hwtabl
 	    (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
 		get_prio(pp);
 
-	if (mask & DI_WWID && !strlen(pp->wwid))
-		get_uid(pp);
-
 	return 0;
 
 blank:
Index: multipath-tools-091020/libmultipath/prio.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/prio.h
+++ multipath-tools-091020/libmultipath/prio.h
@@ -24,6 +24,7 @@
 #define PRIO_NETAPP "netapp"
 #define PRIO_RANDOM "random"
 #define PRIO_RDAC "rdac"
+#define PRIO_WEIGHTED "weighted"
 
 /*
  * Value used to mark the fact prio was not defined
Index: multipath-tools-091020/libmultipath/prioritizers/Makefile
===================================================================
--- multipath-tools-091020.orig/libmultipath/prioritizers/Makefile
+++ multipath-tools-091020/libmultipath/prioritizers/Makefile
@@ -13,7 +13,8 @@ LIBS = \
 	libprioalua.so \
 	libpriotpg_pref.so \
 	libprionetapp.so \
-	libpriohds.so
+	libpriohds.so \
+	libprioweighted.so \
 
 CFLAGS += -I..
 
Index: multipath-tools-091020/libmultipath/prioritizers/weighted.c
===================================================================
--- /dev/null
+++ multipath-tools-091020/libmultipath/prioritizers/weighted.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2009 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+/* This prioritizer is based on a path's device name or its H:T:B:L. Both of
+ * these can change when the node is rebooted, and can differ from node to
+ * node. (i.e. there is no guarantee that sda will point to the same device
+ * after a reboot) If you use this prioritizer, it may be necessary to
+ * manually edit /etc/multipath.conf after any reboot
+ *
+ * Format:
+ * prio		"weighted hbtl <regex> <prio> [<regex> <prio>]
+ * prio		"weighted devname <regex> <prio> [<regex> <prio>]
+ *
+ * Examples:
+ * prio		"weighted hbtl 4:* 2 3:.:.:. 1"
+ * prio		"weighted devname sda 2 sde 1"
+ *
+ */
+
+#include <string.h>
+#include <prio.h>
+#include <debug.h>
+#include <regex.h>
+
+#include "weighted.h"
+
+#define DEFAULT_WEIGHTED_PRIO 0
+
+#define pp_weighted_log(prio, fmt, args...) \
+	condlog(prio, "%s: weighted prio: " fmt, dev, ##args)
+
+static char *
+next_str(char **str)
+{
+	char *next;
+
+	do {
+		next = strsep(str, " \t");
+	} while (next && strcmp(next, "") == 0);
+	return next;
+}
+
+
+static int
+match (char *dev, char *target, char *regex_str, char *prio_str,
+       unsigned int *prio)
+{
+
+	regex_t regex;
+	int err, ret = 0;
+	char *errbuf;
+	size_t errbuf_size;
+	unsigned int prio_match;
+
+	if (sscanf(prio_str, "%u", &prio_match) != 1) {
+		condlog(0, "%s: weighted prio: invalid prio '%s'", dev,
+			prio_str);
+		return 0;
+	}
+	err = regcomp(&regex, regex_str, REG_EXTENDED|REG_NOSUB);
+	if (err) {
+		errbuf_size = regerror(err, &regex, NULL, 0);
+		errbuf = malloc(errbuf_size);
+		regerror(err, &regex, errbuf, errbuf_size);
+		condlog(0, "%s: weighted prio: cannot compile regex '%s' : %s",
+			dev, regex_str, errbuf);
+		free(errbuf);
+		return 0;
+	}
+	if (regexec(&regex, target, 0, NULL, 0) == 0) {
+		*prio = prio_match;
+		ret = 1;
+	}
+
+	regfree(&regex);
+	return ret;
+}
+
+int
+prio_weighted(struct path * pp)
+{
+	char target[FILE_NAME_SIZE];
+	char *buff, *args, *ptr, *prio_str;
+	unsigned int prio = DEFAULT_WEIGHTED_PRIO;
+	char *regex_str = NULL;
+	int regex_size = 0;
+
+	if (!pp->prio_args)
+		return DEFAULT_WEIGHTED_PRIO;
+	buff = args = strdup(pp->prio_args);
+	ptr = next_str(&args);
+
+	if (strcasecmp(ptr, "hbtl") == 0)
+		sprintf(target, "%d:%d:%d:%d", pp->sg_id.host_no,
+			pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
+	else if (strcasecmp(ptr, "devname") == 0)
+		strcpy(target, pp->dev);
+	else {
+		condlog(0, "%s: weighted prio: invalid argument. Want 'hbtl' or 'devname'. Got '%s'", pp->dev, ptr);
+		goto out;
+	}
+
+	while ((ptr = next_str(&args)) != NULL) {
+
+		prio_str = next_str(&args);
+		if (!prio_str) {
+			condlog(0, "%s weighted prio: missing prio for regex '%s'", pp->dev, ptr);
+			goto out;
+		}
+		if (!regex_str || regex_size < strlen(ptr) + 3){
+			regex_size = strlen(ptr) + 3;
+			regex_str = realloc(regex_str, regex_size);
+		}
+		sprintf(regex_str, "%s%s%s", (ptr[0] == '^')? "" : "^",
+			ptr, (ptr[strlen(ptr)-1] == '$')? "" : "$");
+		if (match(pp->dev, target, regex_str, prio_str, &prio))
+			break;
+	}
+out:
+	free(buff);
+	if (regex_str)
+		free(regex_str);
+	return prio;
+}
+
+int
+getprio(struct path * pp)
+{
+	return prio_weighted(pp);
+}
Index: multipath-tools-091020/libmultipath/propsel.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/propsel.c
+++ multipath-tools-091020/libmultipath/propsel.c
@@ -312,14 +312,25 @@ select_getuid (struct path * pp)
 extern int
 select_prio (struct path * pp)
 {
+	struct mpentry * mpe;
+
+	if ((mpe = find_mpe(pp->wwid)) && mpe->prio_name) {
+		pp->prio = prio_lookup(mpe->prio_name);
+		pp->prio_args = mpe->prio_args;
+		condlog(3, "%s: prio = %s (LUN setting)",
+			pp->dev, mpe->prio_name);
+		return 0;
+	}
 	if (pp->hwe && pp->hwe->prio_name) {
 		pp->prio = prio_lookup(pp->hwe->prio_name);
+		pp->prio_args = pp->hwe->prio_args;
 		condlog(3, "%s: prio = %s (controller setting)",
 			pp->dev, pp->hwe->prio_name);
 		return 0;
 	}
 	if (conf->prio_name) {
 		pp->prio = prio_lookup(conf->prio_name);
+		pp->prio_args = conf->prio_args;
 		condlog(3, "%s: prio = %s (config file default)",
 			pp->dev, conf->prio_name);
 		return 0;
Index: multipath-tools-091020/libmultipath/structs.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/structs.h
+++ multipath-tools-091020/libmultipath/structs.h
@@ -142,6 +142,7 @@ struct path {
 	int priority;
 	int pgindex;
 	char * getuid;
+	char * prio_args;
 	struct prio * prio;
 	struct checker checker;
 	struct multipath * mpp;
Index: multipath-tools-091020/libmultipath/prioritizers/weighted.h
===================================================================
--- /dev/null
+++ multipath-tools-091020/libmultipath/prioritizers/weighted.h
@@ -0,0 +1,8 @@
+#ifndef _WEIGHTED_H
+#define _WEIGHTED_H
+
+#define PRIO_WEIGHTED  "weighted"
+
+int prio_weighted(struct path *pp);
+
+#endif

0014-RH-add-hp_tur-checker.patch:
 checkers.h        |    3 +
 checkers/Makefile |    4 +
 checkers/tur.c    |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)

--- NEW FILE 0014-RH-add-hp_tur-checker.patch ---
---
 libmultipath/checkers.h        |    3 +
 libmultipath/checkers/Makefile |    4 +
 libmultipath/checkers/tur.c    |  110 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

Index: multipath-tools/libmultipath/checkers.h
===================================================================
--- multipath-tools.orig/libmultipath/checkers.h
+++ multipath-tools/libmultipath/checkers.h
@@ -60,6 +60,7 @@ enum path_check_state {
 
 #define DIRECTIO     "directio"
 #define TUR          "tur"
+#define HP_TUR       "hp_tur"
 #define HP_SW        "hp_sw"
 #define RDAC         "rdac"
 #define EMC_CLARIION "emc_clariion"
@@ -91,6 +92,7 @@ enum path_check_state {
 #define CHECKER_MSG_LEN 256
 #define CHECKER_DEV_LEN 256
 #define LIB_CHECKER_NAMELEN 256
+#define WWID_SIZE 128
 
 struct checker {
 	struct list_head node;
@@ -99,6 +101,7 @@ struct checker {
 	int disable;
 	char name[CHECKER_NAME_LEN];
 	char message[CHECKER_MSG_LEN];       /* comm with callers */
+	char wwid[WWID_SIZE];                /* LUN wwid */
 	void * context;                      /* store for persistent data */
 	void ** mpcontext;                   /* store for persistent data shared
 						multipath-wide. Use MALLOC if
Index: multipath-tools/libmultipath/checkers/Makefile
===================================================================
--- multipath-tools.orig/libmultipath/checkers/Makefile
+++ multipath-tools/libmultipath/checkers/Makefile
@@ -8,6 +8,7 @@ LIBS= \
 	libcheckcciss_tur.so \
 	libcheckreadsector0.so \
 	libchecktur.so \
+	libcheckhp_tur.so \
 	libcheckdirectio.so \
 	libcheckemc_clariion.so \
 	libcheckhp_sw.so \
@@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o
 libcheck%.so: libsg.o %.o
 	$(CC) $(SHARED_FLAGS) -o $@ $^
 
+hp_tur.o: tur.c
+	$(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $<
+
 install:
 	$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir)
 
Index: multipath-tools/libmultipath/checkers/tur.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/tur.c
+++ multipath-tools/libmultipath/checkers/tur.c
@@ -15,14 +15,101 @@
 
 #include "checkers.h"
 
+#include "../libmultipath/debug.h"
 #include "../libmultipath/sg_include.h"
 
 #define TUR_CMD_LEN 6
 #define HEAVY_CHECK_COUNT       10
 
+#ifdef CHECK_WWID
+#define MSG_TUR_UP	"HP tur checker reports path is up"
+#define MSG_TUR_DOWN	"HP tur checker reports path is down"
+#define MSG_TUR_GHOST	"HP tur checker reports path is in standby state"
+#define EVPD            0x01
+#define PAGE_83         0x83
+#define INQUIRY_CMD     0x12
+#define INQUIRY_CMDLEN  6
+#define SCSI_INQ_BUFF_LEN 96
+#else
 #define MSG_TUR_UP	"tur checker reports path is up"
 #define MSG_TUR_DOWN	"tur checker reports path is down"
 #define MSG_TUR_GHOST	"tur checker reports path is in standby state"
+#endif
+
+#ifdef CHECK_WWID
+static int
+do_inq(struct checker * c, char * wwid)
+{
+	int ret = -1;
+	unsigned char inq_cmd[INQUIRY_CMDLEN] =
+	{INQUIRY_CMD, EVPD, PAGE_83, 0, SCSI_INQ_BUFF_LEN, 0 };
+	unsigned char sense_buffer[32];
+	unsigned char resp_buffer[SCSI_INQ_BUFF_LEN];
+	char *pbuff;
+
+	int m,k;
+	int retry_tur = 5;
+	struct sg_io_hdr io_hdr;
+
+retry:
+	memset(resp_buffer, 0, sizeof(resp_buffer));
+	memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+
+	io_hdr.interface_id = 'S';
+	io_hdr.cmd_len = sizeof(inq_cmd);
+	io_hdr.mx_sb_len = sizeof(sense_buffer);
+	io_hdr.dxfer_direction = -3; // Data transfer from the device.
+	io_hdr.dxfer_len = sizeof(resp_buffer);
+	io_hdr.dxferp = (unsigned char *)resp_buffer;
+	io_hdr.cmdp = inq_cmd;
+	io_hdr.sbp = sense_buffer;
+	io_hdr.timeout = 60; // IOCTL timeout value.
+
+	if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
+		condlog(0, "SG_IO ioctl failed: %s", strerror(errno));
+		return ret;
+	}
+	if (io_hdr.info & SG_INFO_OK_MASK){
+		int key = 0, asc, ascq;
+
+		if (io_hdr.host_status == DID_BUS_BUSY ||
+				io_hdr.host_status == DID_ERROR ||
+				io_hdr.host_status == DID_TRANSPORT_DISRUPTED) {
+			if (--retry_tur)
+				goto retry;
+		}
+		if (io_hdr.sb_len_wr > 3) {
+			if (io_hdr.sbp[0] == 0x72 || io_hdr.sbp[0] == 0x73) {
+				key = io_hdr.sbp[1] & 0x0f;
+				asc = io_hdr.sbp[2];
+				ascq = io_hdr.sbp[3];
+			} else if (io_hdr.sb_len_wr > 13 &&
+					((io_hdr.sbp[0] & 0x7f) == 0x70 ||
+					 (io_hdr.sbp[0] & 0x7f) == 0x71)) {
+				key = io_hdr.sbp[2] & 0x0f;
+				asc = io_hdr.sbp[12];
+				ascq = io_hdr.sbp[13];
+			}
+		}
+		if (key == 0x6) {
+			/* Unit Attention, retry */
+			if (--retry_tur)
+				goto retry;
+		}
+		return ret;
+	}
+
+	pbuff = (char *) resp_buffer;
+
+	wwid[0] = '3';
+	for (m = 8, k = 1; m < 11; ++m, k+=2)
+		sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff);
+	for (m = 11; m < 24; ++m, k+=2)
+		sprintf(&wwid[k], "%02x", (unsigned int)pbuff[m] & 0xff);
+
+	return (ret = 0);
+}
+#endif
 
 struct tur_checker_context {
 	void * dummy;
@@ -30,6 +117,9 @@ struct tur_checker_context {
 
 int libcheck_init (struct checker * c)
 {
+#ifdef CHECK_WWID
+	memset(c->wwid, 0, WWID_SIZE);
+#endif
 	return 0;
 }
 
@@ -45,6 +135,9 @@ libcheck_check (struct checker * c)
 	unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
 	unsigned char sense_buffer[32];
 	int retry_tur = 5;
+#ifdef CHECK_WWID
+	char wwid[WWID_SIZE];
+#endif
 
  retry:
 	memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
@@ -110,6 +203,24 @@ libcheck_check (struct checker * c)
 		MSG(c, MSG_TUR_DOWN);
 		return PATH_DOWN;
 	}
+#ifdef CHECK_WWID
+	if (!do_inq(c, wwid)) {
+
+		if(!strcmp(c->wwid, "\0")) {
+			strcpy(c->wwid, wwid);
+			goto up;
+		}
+
+		if (strcmp(c->wwid , wwid)) {
+			condlog(0,
+				"hp_tur: Lun collided. new_wwid %s old_wwid %s",
+				wwid, c->wwid);
+			MSG(c, MSG_TUR_DOWN);
+			return PATH_DOWN;
+		}
+	}
+up:
+#endif
 	MSG(c, MSG_TUR_UP);
 	return PATH_UP;
 }

0015-RH-add-multipathd-count-paths-cmd.patch:
 libmultipath/uevent.c     |    8 ++++++++
 libmultipath/uevent.h     |    1 +
 multipathd/cli.c          |    2 ++
 multipathd/cli.h          |    2 ++
 multipathd/cli_handlers.c |   33 +++++++++++++++++++++++++++++++++
 multipathd/cli_handlers.h |    1 +
 multipathd/main.c         |    1 +
 7 files changed, 48 insertions(+)

--- NEW FILE 0015-RH-add-multipathd-count-paths-cmd.patch ---
Index: multipath-tools/libmultipath/uevent.c
===================================================================
--- multipath-tools.orig/libmultipath/uevent.c
+++ multipath-tools/libmultipath/uevent.c
@@ -52,6 +52,12 @@ pthread_mutex_t uevc_lock, *uevc_lockp =
 pthread_cond_t  uev_cond,  *uev_condp  = &uev_cond;
 uev_trigger *my_uev_trigger;
 void * my_trigger_data;
+int servicing_uev;
+
+int is_uevent_busy(void)
+{
+	return (uevqhp != NULL || servicing_uev);
+}
 
 static struct uevent * alloc_uevent (void)
 {
@@ -96,7 +102,9 @@ uevq_thread(void * et)
 
 	while (1) {
 		pthread_mutex_lock(uevc_lockp);
+		servicing_uev = 0;
 		pthread_cond_wait(uev_condp, uevc_lockp);
+		servicing_uev = 1;
 		pthread_mutex_unlock(uevc_lockp);
 
 		service_uevq();
Index: multipath-tools/libmultipath/uevent.h
===================================================================
--- multipath-tools.orig/libmultipath/uevent.h
+++ multipath-tools/libmultipath/uevent.h
@@ -17,3 +17,4 @@ struct uevent {
 
 int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data),
 		  void * trigger_data);
+int is_uevent_busy(void);
Index: multipath-tools/multipathd/cli.c
===================================================================
--- multipath-tools.orig/multipathd/cli.c
+++ multipath-tools/multipathd/cli.c
@@ -174,6 +174,7 @@ load_keys (void)
 	r += add_key(keys, "devices", DEVICES, 0);
 	r += add_key(keys, "format", FMT, 1);
 	r += add_key(keys, "wildcards", WILDCARDS, 0);
+	r += add_key(keys, "count", COUNT, 0);
 	r += add_key(keys, "quit", QUIT, 0);
 	r += add_key(keys, "exit", QUIT, 0);
 
@@ -443,6 +444,7 @@ cli_init (void) {
 	add_handler(RESTOREQ+MAPS, NULL);
 	add_handler(REINSTATE+PATH, NULL);
 	add_handler(FAIL+PATH, NULL);
+	add_handler(COUNT+PATHS, NULL);
 	add_handler(QUIT, NULL);
 
 	return 0;
Index: multipath-tools/multipathd/cli_handlers.h
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.h
+++ multipath-tools/multipathd/cli_handlers.h
@@ -25,5 +25,6 @@ int cli_restore_all_queueing(void * v, c
 int cli_suspend(void * v, char ** reply, int * len, void * data);
 int cli_resume(void * v, char ** reply, int * len, void * data);
 int cli_reinstate(void * v, char ** reply, int * len, void * data);
+int cli_count_paths(void * v, char ** reply, int * len, void * data);
 int cli_fail(void * v, char ** reply, int * len, void * data);
 int cli_quit(void * v, char ** reply, int * len, void * data);
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -768,6 +768,7 @@ uxlsnrloop (void * ap)
 	set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
 	set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
 	set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
+	set_handler_callback(COUNT+PATHS, cli_count_paths);
 	set_handler_callback(QUIT, cli_quit);
 
 	umask(077);
Index: multipath-tools/multipathd/cli.h
===================================================================
--- multipath-tools.orig/multipathd/cli.h
+++ multipath-tools/multipathd/cli.h
@@ -23,6 +23,7 @@ enum {
 	__BLACKLIST,
 	__DEVICES,
 	__FMT,
+	__COUNT,
 	__WILDCARDS,
 	__QUIT,
 };
@@ -51,6 +52,7 @@ enum {
 #define BLACKLIST	(1 << __BLACKLIST)
 #define DEVICES  	(1 << __DEVICES)
 #define FMT 	 	(1 << __FMT)
+#define COUNT		(1 << __COUNT)
 #define WILDCARDS	(1 << __WILDCARDS)
 #define QUIT		(1 << __QUIT)
 
Index: multipath-tools/multipathd/cli_handlers.c
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.c
+++ multipath-tools/multipathd/cli_handlers.c
@@ -18,6 +18,29 @@
 
 #include "main.h"
 #include "cli.h"
+#include "uevent.h"
+
+int
+count_paths(char  **r, int *l, struct vectors *vecs)
+{
+	int i, len;
+	struct path *pp;
+	char * reply;
+	unsigned int maxlen = INITIAL_REPLY_LEN;
+	int monitored_count = 0;
+
+	reply = MALLOC(maxlen);
+	if (!reply)
+		return 1;
+	vector_foreach_slot(vecs->pathvec, pp, i)
+		if (pp->fd != -1)
+			monitored_count++;
+	len = sprintf(reply, "Paths: %d\nBusy: %s\n", monitored_count,
+		    is_uevent_busy()? "True" : "False");
+	*r = reply;
+	*l = len + 1;
+	return 0;
+}
 
 int
 show_paths (char ** r, int * len, struct vectors * vecs, char * style)
@@ -176,6 +199,16 @@ cli_list_config (void * v, char ** reply
 }
 
 int
+cli_count_paths (void * v, char ** reply, int * len, void * data)
+{
+	struct vectors * vecs = (struct vectors *)data;
+
+	condlog(3, "count paths (operator)");
+
+	return count_paths(reply, len, vecs);
+}
+
+int
 cli_list_paths (void * v, char ** reply, int * len, void * data)
 {
 	struct vectors * vecs = (struct vectors *)data;


--- NEW FILE multipath.conf ---
# This is a basic configuration file with some examples, for device mapper
# multipath.
# For a complete list of the default configuration values, see
# /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf.defaults
# For a list of configuration options with descriptions, see
# /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf.annotated

## By default, devices with vendor = "IBM" and product = "S/390.*" are
## blacklisted. To enable mulitpathing on these devies, uncomment the
## following lines.
#blacklist_exceptions {
#	device {
#		vendor	"IBM"
#		product	"S/390.*"
#	}
#}

## Use user friendly names, instead of using WWIDs as names.
defaults {
	user_friendly_names yes
}
##
## Here is an example of how to configure some standard options.
##
#
#defaults {
#	udev_dir		/dev
#	polling_interval 	10
#	selector		"round-robin 0"
#	path_grouping_policy	multibus
#	getuid_callout		"/lib/udev/scsi_id --whitelisted --device=/dev/%n"
#	prio			alua
#	path_checker		readsector0
#	rr_min_io		100
#	max_fds			8192
#	rr_weight		priorities
#	failback		immediate
#	no_path_retry		fail
#	user_friendly_names	yes
#}
##
## The wwid line in the following blacklist section is shown as an example
## of how to blacklist devices by wwid.  The 2 devnode lines are the
## compiled in default blacklist. If you want to blacklist entire types
## of devices, such as all scsi devices, you should use a devnode line.
## However, if you want to blacklist specific devices, you should use
## a wwid line.  Since there is no guarantee that a specific device will
## not change names on reboot (from /dev/sda to /dev/sdb for example)
## devnode lines are not recommended for blacklisting specific devices.
##
#blacklist {
#       wwid 26353900f02796769
#	devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
#	devnode "^hd[a-z]"
#}
#multipaths {
#	multipath {
#		wwid			3600508b4000156d700012000000b0000
#		alias			yellow
#		path_grouping_policy	multibus
#		path_checker		readsector0
#		path_selector		"round-robin 0"
#		failback		manual
#		rr_weight		priorities
#		no_path_retry		5
#	}
#	multipath {
#		wwid			1DEC_____321816758474
#		alias			red
#	}
#}
#devices {
#	device {
#		vendor			"COMPAQ  "
#		product			"HSV110 (C)COMPAQ"
#		path_grouping_policy	multibus
#		getuid_callout          "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
#		path_checker		readsector0
#		path_selector		"round-robin 0"
#		hardware_handler	"0"
#		failback		15
#		rr_weight		priorities
#		no_path_retry		queue
#	}
#	device {
#		vendor			"COMPAQ  "
#		product			"MSA1000         "
#		path_grouping_policy	multibus
#	}
#}


Index: device-mapper-multipath.spec
===================================================================
RCS file: /cvs/pkgs/rpms/device-mapper-multipath/devel/device-mapper-multipath.spec,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -p -r1.63 -r1.64
--- device-mapper-multipath.spec	27 Oct 2009 09:58:59 -0000	1.63
+++ device-mapper-multipath.spec	17 Nov 2009 06:33:04 -0000	1.64
@@ -1,15 +1,16 @@
 Summary: Tools to manage multipath devices using device-mapper
 Name: device-mapper-multipath
 Version: 0.4.9
-Release: 10%{?dist}
+Release: 11%{?dist}
 License: GPL+
 Group: System Environment/Base
 URL: http://christophe.varoqui.free.fr/
 
 Source0: multipath-tools-091027.tar.gz
-Source1: multipath.conf.redhat
+Source1: multipath.conf
 # patch that should go upstream
 Patch1: 0001-for-upstream-add-tpg_pref-prioritizer.patch
+Patch2: 0002-for-upstream-add-tmo-config-options.patch
 # local patches
 Patch1001: 0001-RH-queue-without-daemon.patch
 Patch1002: 0002-RH-path-checker.patch
@@ -23,6 +24,9 @@ Patch1009: 0009-RH-multipathd-blacklist-
 Patch1010: 0010-RH-multipath-rules-udev-changes.patch
 Patch1011: 0011-RH-fix-init-script-LSB-headers.patch
 Patch1012: 0012-RH-explicitly-disable-dm-udev-sync-support-in-kpartx.patch
+Patch1013: 0013-RH-add-weighted_prio-prioritizer.patch
+Patch1014: 0014-RH-add-hp_tur-checker.patch
+Patch1015: 0015-RH-add-multipathd-count-paths-cmd.patch
 
 # runtime
 Requires: %{name}-libs = %{version}-%{release}
@@ -67,6 +71,7 @@ kpartx manages partition creation and re
 %prep
 %setup -q -n multipath-tools
 %patch1 -p1
+%patch2 -p1
 %patch1001 -p1
 %patch1002 -p1
 %patch1003 -p1
@@ -79,6 +84,9 @@ kpartx manages partition creation and re
 %patch1010 -p1
 %patch1011 -p1
 %patch1012 -p1
+%patch1013 -p1
+%patch1014 -p1
+%patch1015 -p1
 cp %{SOURCE1} .
 
 %build
@@ -136,7 +144,7 @@ fi
 %{_mandir}/man8/multipathd.8.gz
 %config /etc/udev/rules.d/40-multipath.rules
 %doc AUTHOR COPYING FAQ
-%doc multipath.conf.redhat multipath.conf.annotated
+%doc multipath.conf multipath.conf.annotated
 %doc multipath.conf.defaults multipath.conf.synthetic
 %dir /etc/multipath
 
@@ -157,6 +165,15 @@ fi
 %{_mandir}/man8/kpartx.8.gz
 
 %changelog
+* Mon Nov 16 2009 Benjamin Marzinski <bmarzins at redhat.com> -0.4.9-11
+- Add 0002-for-upstream-add-tmo-config-options.patch
+  * Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options
+- Add 0013-RH-add-weighted_prio-prioritizer.patch
+- Add 0014-RH-add-hp_tur-checker.patch
+- Add 0015-RH-add-multipathd-count-paths-cmd.patch
+- rename multipath.conf.redhat to multipath.conf, and remove the default
+  blacklist.
+
 * Tue Oct 27 2009 Fabio M. Di Nitto <fdinitto at redhat.com> - 0.4.9-10
 - Updated to latest upstream 0.4.9 code : multipath-tools-091027.tar.gz
   (git commit id: a946bd4e2a529e5fba9c9547d03d3f91806618a3)


--- multipath.conf.redhat DELETED ---




More information about the scm-commits mailing list