summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2016-04-21 21:27:49 -0500
committerBenjamin Marzinski <bmarzins@redhat.com>2016-04-21 21:27:49 -0500
commit6738b34a0b0aabf1bc8c15d540bafa29ca99c58f (patch)
treecf5a37898b4bacc7fefcc08db661338bfdb9ffec
parentfef216999bec3651f01b934a3ece5a69f6eca598 (diff)
downloaddevice-mapper-multipath-6738b34a0b0aabf1bc8c15d540bafa29ca99c58f.tar.gz
device-mapper-multipath-6738b34a0b0aabf1bc8c15d540bafa29ca99c58f.tar.xz
device-mapper-multipath-6738b34a0b0aabf1bc8c15d540bafa29ca99c58f.zip
device-mapper-multipath-0.4.9-82
- Modify 0005-RH-add-mpathconf.patch * changed warning message - Modify 0102-RHBZ-1160478-mpathconf-template.patch * updated man page - Modify 0104-RHBZ-631009-deferred-remove.patch * refactor code and minor fix - Refresh 0107-RHBZ-1169935-no-new-devs.patch - Refresh 0112-RHBZ-1194917-add-config_dir-option.patch - Refresh 0126-RHBZ-1211383-alias-collision.patch - Add 0133-RHBZ-1296979-fix-define.patch * look for the correct libudev function to set define - Add 0134-RHBZ-1241528-check-mpath-prefix.patch * only touch devices with a "mpath-" dm uuid prefix - Add 0135-RHBZ-1299600-path-dev-uevents.patch * trigger path uevent the first time a path is claimed by multipath - Add 0136-RHBZ-1304687-wait-for-map-add.patch * wait for the device to finish being added before reloading it. - Add 0137-RHBZ-1280524-clear-chkr-msg.patch - Add 0138-RHBZ-1288660-fix-mpathconf-allow.patch * don't remove existing lines from blacklist_exceptions section - Add 0139-RHBZ-1273173-queue-no-daemon-doc.patch - Add 0140-RHBZ-1299647-fix-help.patch - Add 0141-RHBZ-1303953-mpathpersist-typo.patch - Add 0142-RHBZ-1283750-kpartx-fix.patch * only remove devices if their uuid says that they are the correct partition device - Add 0143-RHBZ-1299648-kpartx-sync.patch * default to using udev sync mode - Add 0144-RHBZ-1299652-alua-pref-arg.patch * allow "exclusive_pref_bit" argument to alua prioritizer - Add 0145-UP-resize-help-msg.patch - Add 0146-UPBZ-1299651-raw-output.patch * allow raw format mutipathd show commands, that remove headers and padding - Add 0147-RHBZ-1272620-fail-rm-msg.patch - Add 0148-RHBZ-1292599-verify-before-remove.patch * verify that all partitions are unused before attempting to remove a device - Add 0149-RHBZ-1292599-restore-removed-parts.patch * don't disable kpartx when restoring the first path of a device. - Add 0150-RHBZ-1253913-fix-startup-msg.patch * wait for multipathd daemon to write pidfile before returning - Add 0151-RHBZ-1297456-weighted-fix.patch * add wwn keyword to weighted prioritizer for persistent naming - Add 0152-RHBZ-1269293-fix-blk-unit-file.patch * use "Wants" instead of "Requires" - Add 0153-RH-fix-i686-size-bug.patch * use 64-bit keycodes for multipathd client commands - Add 0154-UPBZ-1291406-disable-reinstate.patch * don't automatically reinstate ghost paths for implicit alua devices - Add 0155-UPBZ-1300415-PURE-config.patch * Add default config for PURE FlashArray - Add 0156-UPBZ-1313324-dont-fail-discovery.patch * don't fail discovery because individual paths failed. - Add 0157-RHBZ-1319853-multipath-c-error-msg.patch * better error reporting for multipath -c - Add 0158-RHBZ-1318581-timestamp-doc-fix.patch * add documentation for -T - Add 0159-UPBZ-1255885-udev-waits.patch * make multipath and kpartx wait after for udev after each command
-rw-r--r--0005-RH-add-mpathconf.patch14
-rw-r--r--0102-RHBZ-1160478-mpathconf-template.patch34
-rw-r--r--0104-RHBZ-631009-deferred-remove.patch79
-rw-r--r--0107-RHBZ-1169935-no-new-devs.patch2
-rw-r--r--0112-RHBZ-1194917-add-config_dir-option.patch6
-rw-r--r--0126-RHBZ-1211383-alias-collision.patch2
-rw-r--r--0133-RHBZ-1296979-fix-define.patch17
-rw-r--r--0134-RHBZ-1241528-check-mpath-prefix.patch168
-rw-r--r--0135-RHBZ-1299600-path-dev-uevents.patch96
-rw-r--r--0136-RHBZ-1304687-wait-for-map-add.patch495
-rw-r--r--0137-RHBZ-1280524-clear-chkr-msg.patch17
-rw-r--r--0138-RHBZ-1288660-fix-mpathconf-allow.patch86
-rw-r--r--0139-RHBZ-1273173-queue-no-daemon-doc.patch162
-rw-r--r--0140-RHBZ-1299647-fix-help.patch16
-rw-r--r--0141-RHBZ-1303953-mpathpersist-typo.patch17
-rw-r--r--0142-RHBZ-1283750-kpartx-fix.patch189
-rw-r--r--0143-RHBZ-1299648-kpartx-sync.patch59
-rw-r--r--0144-RHBZ-1299652-alua-pref-arg.patch136
-rw-r--r--0145-UP-resize-help-msg.patch172
-rw-r--r--0146-UPBZ-1299651-raw-output.patch393
-rw-r--r--0147-RHBZ-1272620-fail-rm-msg.patch60
-rw-r--r--0148-RHBZ-1292599-verify-before-remove.patch142
-rw-r--r--0149-RHBZ-1292599-restore-removed-parts.patch82
-rw-r--r--0150-RHBZ-1253913-fix-startup-msg.patch128
-rw-r--r--0151-RHBZ-1297456-weighted-fix.patch156
-rw-r--r--0152-RHBZ-1269293-fix-blk-unit-file.patch16
-rw-r--r--0153-RH-fix-i686-size-bug.patch156
-rw-r--r--0154-UPBZ-1291406-disable-reinstate.patch154
-rw-r--r--0155-UPBZ-1300415-PURE-config.patch54
-rw-r--r--0156-UPBZ-1313324-dont-fail-discovery.patch236
-rw-r--r--0157-RHBZ-1319853-multipath-c-error-msg.patch63
-rw-r--r--0158-RHBZ-1318581-timestamp-doc-fix.patch26
-rw-r--r--0159-UPBZ-1255885-udev-waits.patch425
-rw-r--r--device-mapper-multipath.spec116
34 files changed, 3927 insertions, 47 deletions
diff --git a/0005-RH-add-mpathconf.patch b/0005-RH-add-mpathconf.patch
index ce1b2c7..89ab3a3 100644
--- a/0005-RH-add-mpathconf.patch
+++ b/0005-RH-add-mpathconf.patch
@@ -1,20 +1,22 @@
---
- libmultipath/config.c | 1
+ libmultipath/config.c | 3
multipath/Makefile | 5
multipath/main.c | 4
multipath/mpathconf | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++
multipath/mpathconf.8 | 103 ++++++++++++++++
- 5 files changed, 423 insertions(+), 2 deletions(-)
+ 5 files changed, 423 insertions(+), 4 deletions(-)
Index: multipath-tools-130222/libmultipath/config.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.c
+++ multipath-tools-130222/libmultipath/config.c
-@@ -589,6 +589,7 @@ load_config (char * file)
+@@ -587,8 +587,7 @@ load_config (char * file)
+ } 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));
-+ condlog(0, "You can run /sbin/mpathconf to create or modify /etc/multipath.conf");
+- 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));
++ condlog(0, "run \"/sbin/mpathconf --enable\" to create a default /etc/multipath.conf");
if (conf->blist_devnode == NULL) {
conf->blist_devnode = vector_alloc();
if (!conf->blist_devnode) {
diff --git a/0102-RHBZ-1160478-mpathconf-template.patch b/0102-RHBZ-1160478-mpathconf-template.patch
index 3c0e443..7e58736 100644
--- a/0102-RHBZ-1160478-mpathconf-template.patch
+++ b/0102-RHBZ-1160478-mpathconf-template.patch
@@ -1,6 +1,7 @@
---
- multipath/mpathconf | 26 ++++++++++++++++++++------
- 1 file changed, 20 insertions(+), 6 deletions(-)
+ multipath/mpathconf | 26 ++++++++++++++++++++------
+ multipath/mpathconf.8 | 16 +++++++---------
+ 2 files changed, 27 insertions(+), 15 deletions(-)
Index: multipath-tools-130222/multipath/mpathconf
===================================================================
@@ -50,3 +51,32 @@ Index: multipath-tools-130222/multipath/mpathconf
fi
if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
+Index: multipath-tools-130222/multipath/mpathconf.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf.8
++++ multipath-tools-130222/multipath/mpathconf.8
+@@ -34,17 +34,15 @@ that users can manually edit their confi
+ If
+ .B /etc/multipath.conf
+ already exists, mpathconf will edit it. If it does not exist, mpathconf will
+-use
+-.B /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf
+-as the starting file. This file has
++create a default file with
+ .B user_friendly_names
+-set. If this file does not exist, mpathconf will create
+-.B /etc/multipath.conf
+-from scratch. For most users, this means that
+-.B user_friendly_names
+-will be set by default, unless they use the
++and
++.B find_multipaths
++set. To disable these, use the
+ .B --user_friendly_names n
+-command.
++and
++.B --find_multipaths n
++options
+ .SH COMMANDS
+ .TP
+ .B --enable
diff --git a/0104-RHBZ-631009-deferred-remove.patch b/0104-RHBZ-631009-deferred-remove.patch
index 342b45d..07f734c 100644
--- a/0104-RHBZ-631009-deferred-remove.patch
+++ b/0104-RHBZ-631009-deferred-remove.patch
@@ -1,19 +1,19 @@
---
- libmultipath/Makefile | 6 ++
- libmultipath/config.c | 3 +
- libmultipath/config.h | 3 +
+ libmultipath/Makefile | 6 +
+ libmultipath/config.c | 3
+ libmultipath/config.h | 3
libmultipath/configure.c | 1
libmultipath/defaults.h | 1
- libmultipath/devmapper.c | 130 +++++++++++++++++++++++++++++++++++++++------
- libmultipath/devmapper.h | 12 ++--
- libmultipath/dict.c | 116 +++++++++++++++++++++++++++++++++++++++-
- libmultipath/propsel.c | 28 +++++++++
+ libmultipath/devmapper.c | 142 ++++++++++++++++++++++++++++++++++++++++-----
+ libmultipath/devmapper.h | 11 ++-
+ libmultipath/dict.c | 116 ++++++++++++++++++++++++++++++++++++
+ libmultipath/propsel.c | 28 ++++++++
libmultipath/propsel.h | 1
libmultipath/structs.h | 8 ++
- libmultipath/structs_vec.c | 3 -
- multipath/multipath.conf.5 | 36 ++++++++++++
+ libmultipath/structs_vec.c | 3
+ multipath/multipath.conf.5 | 36 +++++++++++
multipathd/main.c | 23 +++++--
- 14 files changed, 344 insertions(+), 27 deletions(-)
+ 14 files changed, 355 insertions(+), 27 deletions(-)
Index: multipath-tools-130222/libmultipath/config.c
===================================================================
@@ -99,7 +99,16 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/devmapper.c
+++ multipath-tools-130222/libmultipath/devmapper.c
-@@ -103,7 +103,9 @@ dm_lib_prereq (void)
+@@ -32,6 +32,8 @@
+ #define UUID_PREFIX "mpath-"
+ #define UUID_PREFIX_LEN 6
+
++static int dm_cancel_remove_partmaps(const char * mapname);
++
+ #ifndef LIBDM_API_COOKIE
+ static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
+ {
+@@ -103,7 +105,9 @@ dm_lib_prereq (void)
{
char version[64];
int v[3];
@@ -110,28 +119,31 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
int minv[3] = {1, 2, 82};
#elif defined(LIBDM_API_COOKIE)
int minv[3] = {1, 2, 38};
-@@ -202,7 +204,7 @@ dm_prereq (void)
+@@ -201,8 +205,10 @@ dm_prereq (void)
+ return dm_drv_prereq();
}
++#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS)
++
static int
-dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) {
+dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) {
int r = 0;
int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
task == DM_DEVICE_REMOVE));
-@@ -220,7 +222,10 @@ dm_simplecmd (int task, const char *name
+@@ -220,7 +226,10 @@ dm_simplecmd (int task, const char *name
if (no_flush)
dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
#endif
-
+#ifdef LIBDM_API_DEFERRED
-+ if (deferred_remove)
++ if (do_deferred(deferred_remove))
+ dm_task_deferred_remove(dmt);
+#endif
if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
goto out;
r = dm_task_run (dmt);
-@@ -232,12 +237,18 @@ dm_simplecmd (int task, const char *name
+@@ -232,12 +241,18 @@ dm_simplecmd (int task, const char *name
extern int
dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) {
@@ -145,14 +157,14 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
+ return dm_simplecmd(task, name, 1, 1, udev_flags, 0);
+}
+
-+extern int
++static int
+dm_device_remove (const char *name, int needsync, int deferred_remove) {
+ return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0,
+ deferred_remove);
}
extern int
-@@ -653,7 +664,7 @@ out:
+@@ -653,7 +668,7 @@ out:
}
extern int
@@ -161,7 +173,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
{
int r;
-@@ -663,23 +674,46 @@ _dm_flush_map (const char * mapname, int
+@@ -663,23 +678,46 @@ _dm_flush_map (const char * mapname, int
if (dm_type(mapname, TGT_MPATH) <= 0)
return 0; /* nothing to do */
@@ -170,7 +182,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
return 1;
- if (dm_get_opencount(mapname)) {
-+ if (!deferred_remove && dm_get_opencount(mapname)) {
++ if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) {
condlog(2, "%s: map in use", mapname);
return 1;
}
@@ -179,7 +191,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
+ r = dm_device_remove(mapname, need_sync, deferred_remove);
if (r) {
-+ if (deferred_remove && dm_map_present(mapname)) {
++ if (do_deferred(deferred_remove) && dm_map_present(mapname)) {
+ condlog(4, "multipath map %s remove deferred",
+ mapname);
+ return 2;
@@ -211,7 +223,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
extern int
dm_suspend_and_flush_map (const char * mapname)
{
-@@ -1076,6 +1110,7 @@ out:
+@@ -1076,6 +1114,7 @@ out:
struct remove_data {
int need_sync;
@@ -219,14 +231,15 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
};
static int
-@@ -1084,25 +1119,90 @@ remove_partmap(char *name, void *data)
+@@ -1084,25 +1123,98 @@ remove_partmap(char *name, void *data)
struct remove_data *rd = (struct remove_data *)data;
if (dm_get_opencount(name)) {
- dm_remove_partmaps(name, rd->need_sync);
- if (dm_get_opencount(name)) {
+ dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove);
-+ if (!rd->deferred_remove && dm_get_opencount(name)) {
++ if (!do_deferred(rd->deferred_remove) &&
++ dm_get_opencount(name)) {
condlog(2, "%s: map in use", name);
return 1;
}
@@ -252,6 +265,8 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
+static int
+cancel_remove_partmap (char *name, void *unused)
+{
++ if (dm_get_opencount(name))
++ dm_cancel_remove_partmaps(name);
+ if (dm_message(name, "@cancel_deferred_remove") != 0)
+ condlog(0, "%s: can't cancel deferred remove: %s", name,
+ strerror(errno));
@@ -283,6 +298,11 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
+ return r;
+}
+
++static int
++dm_cancel_remove_partmaps(const char * mapname) {
++ return do_foreach_partmaps(mapname, cancel_remove_partmap, NULL);
++}
++
+int
+dm_cancel_deferred_remove (struct multipath *mpp)
+{
@@ -293,7 +313,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c
+ if (mpp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS)
+ mpp->deferred_remove = DEFERRED_REMOVE_ON;
+
-+ do_foreach_partmaps(mpp->alias, cancel_remove_partmap, NULL);
++ dm_cancel_remove_partmaps(mpp->alias);
+ r = dm_message(mpp->alias, "@cancel_deferred_remove");
+ if (r)
+ condlog(0, "%s: can't cancel deferred remove: %s", mpp->alias,
@@ -320,14 +340,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/devmapper.h
+++ multipath-tools-130222/libmultipath/devmapper.h
-@@ -17,15 +17,18 @@ int dm_prereq (void);
- int dm_drv_version (unsigned int * version, char * str);
- int dm_simplecmd_flush (int, const char *, int, uint16_t);
- int dm_simplecmd_noflush (int, const char *, uint16_t);
-+int dm_device_remove (const char *, int, int);
- int dm_addmap_create (struct multipath *mpp, char *params);
- int dm_addmap_reload (struct multipath *mpp, char *params);
- int dm_map_present (const char *);
+@@ -23,9 +23,11 @@ int dm_map_present (const char *);
int dm_get_map(const char *, unsigned long long *, char *);
int dm_get_status(char *, char *);
int dm_type(const char *, char *);
@@ -342,7 +355,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.h
int dm_suspend_and_flush_map(const char * mapname);
int dm_flush_maps (void);
int dm_fail_path(char * mapname, char * path);
-@@ -40,7 +43,8 @@ int dm_geteventnr (char *name);
+@@ -40,7 +42,8 @@ int dm_geteventnr (char *name);
int dm_get_major (char *name);
int dm_get_minor (char *name);
char * dm_mapname(int major, int minor);
diff --git a/0107-RHBZ-1169935-no-new-devs.patch b/0107-RHBZ-1169935-no-new-devs.patch
index 99ae35a..c9ab012 100644
--- a/0107-RHBZ-1169935-no-new-devs.patch
+++ b/0107-RHBZ-1169935-no-new-devs.patch
@@ -104,7 +104,7 @@ Index: multipath-tools-130222/libmultipath/config.c
/*
* preload default hwtable
-@@ -732,6 +733,9 @@ load_config (char * file, struct udev *u
+@@ -730,6 +731,9 @@ load_config (char * file, struct udev *u
!conf->wwids_file)
goto out;
diff --git a/0112-RHBZ-1194917-add-config_dir-option.patch b/0112-RHBZ-1194917-add-config_dir-option.patch
index 6cc07e7..b256ff0 100644
--- a/0112-RHBZ-1194917-add-config_dir-option.patch
+++ b/0112-RHBZ-1194917-add-config_dir-option.patch
@@ -517,9 +517,9 @@ Index: multipath-tools-130222/libmultipath/config.c
} 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
+ condlog(0, "run \"/sbin/mpathconf --enable\" to create a default /etc/multipath.conf");
+ if (conf->blist_devnode == NULL) {
+@@ -675,6 +721,12 @@ load_config (char * file, struct udev *u
}
}
diff --git a/0126-RHBZ-1211383-alias-collision.patch b/0126-RHBZ-1211383-alias-collision.patch
index 965bf53..128a8a7 100644
--- a/0126-RHBZ-1211383-alias-collision.patch
+++ b/0126-RHBZ-1211383-alias-collision.patch
@@ -31,7 +31,7 @@ Index: multipath-tools-130222/libmultipath/config.c
/*
* preload default hwtable
-@@ -794,6 +795,9 @@ load_config (char * file, struct udev *u
+@@ -792,6 +793,9 @@ load_config (char * file, struct udev *u
if (conf->ignore_new_boot_devs)
in_initrd();
diff --git a/0133-RHBZ-1296979-fix-define.patch b/0133-RHBZ-1296979-fix-define.patch
new file mode 100644
index 0000000..cc50722
--- /dev/null
+++ b/0133-RHBZ-1296979-fix-define.patch
@@ -0,0 +1,17 @@
+---
+ libmultipath/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-bz1296979/libmultipath/Makefile
+===================================================================
+--- multipath-bz1296979.orig/libmultipath/Makefile
++++ multipath-bz1296979/libmultipath/Makefile
+@@ -30,7 +30,7 @@ ifneq ($(strip $(LIBDM_API_COOKIE)),0)
+ CFLAGS += -DLIBDM_API_COOKIE
+ endif
+
+-LIBUDEV_API_RECVBUF = $(shell grep -Ecs '^[a-z]*[[:space:]]+udev_monitor_set_resolve_buffer_size' /usr/include/libudev.h)
++LIBUDEV_API_RECVBUF = $(shell grep -Ecs '^[a-z]*[[:space:]]+udev_monitor_set_receive_buffer_size' /usr/include/libudev.h)
+
+ ifneq ($(strip $(LIBUDEV_API_RECVBUF)),0)
+ CFLAGS += -DLIBUDEV_API_RECVBUF
diff --git a/0134-RHBZ-1241528-check-mpath-prefix.patch b/0134-RHBZ-1241528-check-mpath-prefix.patch
new file mode 100644
index 0000000..9701a36
--- /dev/null
+++ b/0134-RHBZ-1241528-check-mpath-prefix.patch
@@ -0,0 +1,168 @@
+---
+ libmpathpersist/mpath_persist.c | 4 +-
+ libmultipath/devmapper.c | 67 +++++++++++++++++++++++++++++-----------
+ libmultipath/devmapper.h | 1
+ multipathd/main.c | 2 -
+ 4 files changed, 53 insertions(+), 21 deletions(-)
+
+Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
++++ multipath-tools-130222/libmpathpersist/mpath_persist.c
+@@ -160,7 +160,7 @@ int mpath_persistent_reserve_in (int fd,
+
+ condlog(3, "alias = %s", alias);
+ map_present = dm_map_present(alias);
+- if (map_present && dm_type(alias, TGT_MPATH) <= 0){
++ if (map_present && !dm_is_mpath(alias)){
+ condlog( 0, "%s: not a multipath device.", alias);
+ ret = MPATH_PR_DMMP_ERROR;
+ goto out;
+@@ -250,7 +250,7 @@ int mpath_persistent_reserve_out ( int f
+ condlog(3, "alias = %s", alias);
+ map_present = dm_map_present(alias);
+
+- if (map_present && dm_type(alias, TGT_MPATH) <= 0){
++ if (map_present && !dm_is_mpath(alias)){
+ condlog(3, "%s: not a multipath device.", alias);
+ ret = MPATH_PR_DMMP_ERROR;
+ goto out;
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -564,6 +564,48 @@ out:
+ return r;
+ }
+
++extern int
++dm_is_mpath(const char * name)
++{
++ int r = 0;
++ struct dm_task *dmt;
++ struct dm_info info;
++ uint64_t start, length;
++ char *target_type = NULL;
++ char *params;
++ const char *uuid;
++
++ if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
++ return 0;
++
++ if (!dm_task_set_name(dmt, name))
++ goto out;
++
++ dm_task_no_open_count(dmt);
++
++ if (!dm_task_run(dmt))
++ goto out;
++
++ if (!dm_task_get_info(dmt, &info) || !info.exists)
++ goto out;
++
++ uuid = dm_task_get_uuid(dmt);
++
++ if (!uuid || strncmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN) != 0)
++ goto out;
++
++ /* Fetch 1st target */
++ dm_get_next_target(dmt, NULL, &start, &length, &target_type, &params);
++
++ if (!target_type || strcmp(target_type, TGT_MPATH) != 0)
++ goto out;
++
++ r = 1;
++out:
++ dm_task_destroy(dmt);
++ return r;
++}
++
+ static int
+ dm_dev_t (const char * mapname, char * dev_t, int len)
+ {
+@@ -672,10 +714,7 @@ _dm_flush_map (const char * mapname, int
+ {
+ int r;
+
+- if (!dm_map_present(mapname))
+- return 0;
+-
+- if (dm_type(mapname, TGT_MPATH) <= 0)
++ if (!dm_is_mpath(mapname))
+ return 0; /* nothing to do */
+
+ if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
+@@ -725,10 +764,7 @@ dm_suspend_and_flush_map (const char * m
+ unsigned long long mapsize;
+ char params[PARAMS_SIZE] = {0};
+
+- if (!dm_map_present(mapname))
+- return 0;
+-
+- if (dm_type(mapname, TGT_MPATH) <= 0)
++ if (!dm_is_mpath(mapname))
+ return 0; /* nothing to do */
+
+ if (!dm_get_map(mapname, &mapsize, params)) {
+@@ -899,7 +935,6 @@ dm_get_maps (vector mp)
+ {
+ struct multipath * mpp;
+ int r = 1;
+- int info;
+ struct dm_task *dmt;
+ struct dm_names *names;
+ unsigned next = 0;
+@@ -924,9 +959,7 @@ dm_get_maps (vector mp)
+ }
+
+ do {
+- info = dm_type(names->name, TGT_MPATH);
+-
+- if (info <= 0)
++ if (!dm_is_mpath(names->name))
+ goto next;
+
+ mpp = alloc_multipath();
+@@ -939,13 +972,11 @@ dm_get_maps (vector mp)
+ if (!mpp->alias)
+ goto out1;
+
+- if (info > 0) {
+- if (dm_get_map(names->name, &mpp->size, NULL))
+- goto out1;
++ if (dm_get_map(names->name, &mpp->size, NULL))
++ goto out1;
+
+- dm_get_uuid(names->name, mpp->wwid);
+- dm_get_info(names->name, &mpp->dmi);
+- }
++ dm_get_uuid(names->name, mpp->wwid);
++ dm_get_info(names->name, &mpp->dmi);
+
+ if (!vector_alloc_slot(mp))
+ goto out1;
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -23,6 +23,7 @@ int dm_map_present (const char *);
+ int dm_get_map(const char *, unsigned long long *, char *);
+ int dm_get_status(char *, char *);
+ int dm_type(const char *, char *);
++int dm_is_mpath(const char *);
+ int _dm_flush_map (const char *, int, int);
+ int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
+ #define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0)
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -285,7 +285,7 @@ ev_add_map (char * dev, char * alias, st
+
+ map_present = dm_map_present(alias);
+
+- if (map_present && dm_type(alias, TGT_MPATH) <= 0) {
++ if (map_present && !dm_is_mpath(alias)) {
+ condlog(4, "%s: not a multipath map", alias);
+ return 0;
+ }
diff --git a/0135-RHBZ-1299600-path-dev-uevents.patch b/0135-RHBZ-1299600-path-dev-uevents.patch
new file mode 100644
index 0000000..fddbe19
--- /dev/null
+++ b/0135-RHBZ-1299600-path-dev-uevents.patch
@@ -0,0 +1,96 @@
+---
+ libmultipath/configure.c | 30 ++++++++++++++++++++++++++++--
+ libmultipath/wwids.c | 4 ++--
+ multipath/main.c | 2 +-
+ 3 files changed, 31 insertions(+), 5 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -38,6 +38,7 @@
+ #include "util.h"
+ #include "uxsock.h"
+ #include "wwids.h"
++#include "sysfs.h"
+
+ /* group paths in pg by host adapter
+ */
+@@ -569,6 +570,29 @@ fail:
+ return 1;
+ }
+
++static void
++trigger_uevents (struct multipath *mpp)
++{
++ struct pathgroup * pgp;
++ struct path * pp;
++ int i, j;
++
++ if (!mpp || !mpp->pg)
++ return;
++
++ vector_foreach_slot (mpp->pg, pgp, i) {
++ if (!pgp->paths)
++ continue;
++ vector_foreach_slot(pgp->paths, pp, j) {
++ if (!pp->udev)
++ continue;
++ sysfs_attr_set_value(pp->udev, "uevent", "change",
++ strlen("change"));
++ }
++ }
++}
++
++
+ /*
+ * Return value:
+ */
+@@ -658,8 +682,10 @@ domap (struct multipath * mpp, char * pa
+ * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
+ * succeeded
+ */
+- if (mpp->action == ACT_CREATE)
+- remember_wwid(mpp->wwid);
++ if (mpp->action == ACT_CREATE) {
++ if (remember_wwid(mpp->wwid) == 1)
++ trigger_uevents(mpp);
++ }
+ if (!conf->daemon) {
+ /* multipath client mode */
+ dm_switchgroup(mpp->alias, mpp->bestpg);
+Index: multipath-tools-130222/libmultipath/wwids.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/wwids.c
++++ multipath-tools-130222/libmultipath/wwids.c
+@@ -310,7 +310,7 @@ remember_wwid(char *wwid)
+ }
+ else
+ condlog(4, "wwid %s already in wwids file", wwid);
+- return 0;
++ return ret;
+ }
+
+ int remember_cmdline_wwid(void)
+@@ -344,7 +344,7 @@ int remember_cmdline_wwid(void)
+ next++;
+ }
+ if (strlen(ptr)) {
+- if (remember_wwid(ptr) != 0)
++ if (remember_wwid(ptr) < 0)
+ ret = -1;
+ }
+ else {
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -303,7 +303,7 @@ configure (void)
+ }
+ if (conf->cmd == CMD_ADD_WWID) {
+ r = remember_wwid(refwwid);
+- if (r == 0)
++ if (r >= 0)
+ printf("wwid '%s' added\n", refwwid);
+ else
+ printf("failed adding '%s' to wwids file\n",
diff --git a/0136-RHBZ-1304687-wait-for-map-add.patch b/0136-RHBZ-1304687-wait-for-map-add.patch
new file mode 100644
index 0000000..03deb1a
--- /dev/null
+++ b/0136-RHBZ-1304687-wait-for-map-add.patch
@@ -0,0 +1,495 @@
+---
+ libmultipath/config.c | 1
+ libmultipath/config.h | 2
+ libmultipath/configure.c | 4 +
+ libmultipath/defaults.h | 1
+ libmultipath/dict.c | 25 +++++++++
+ libmultipath/structs.h | 2
+ multipath.conf.defaults | 1
+ multipath/multipath.conf.5 | 8 +++
+ multipathd/cli_handlers.c | 65 ++++++++++++++++++++----
+ multipathd/main.c | 119 +++++++++++++++++++++++++++++++++++++++++++--
+ multipathd/main.h | 1
+ 11 files changed, 216 insertions(+), 13 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -701,6 +701,10 @@ domap (struct multipath * mpp, char * pa
+ */
+ if (mpp->action != ACT_CREATE)
+ mpp->action = ACT_NOTHING;
++ else {
++ mpp->wait_for_udev = 1;
++ mpp->uev_msg_tick = conf->uev_msg_delay;
++ }
+ }
+ dm_setgeometry(mpp);
+ return DOMAP_OK;
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -217,6 +217,8 @@ struct multipath {
+ int bestpg;
+ int queuedio;
+ int action;
++ int wait_for_udev;
++ int uev_msg_tick;
+ int pgfailback;
+ int failback_tick;
+ int rr_weight;
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -548,6 +548,11 @@ cli_reload(void *v, char **reply, int *l
+ condlog(0, "%s: invalid map name. cannot reload", mapname);
+ return 1;
+ }
++ if (mpp->wait_for_udev) {
++ condlog(2, "%s: device not fully created, failing reload",
++ mpp->alias);
++ return 1;
++ }
+
+ return reload_map(vecs, mpp, 0);
+ }
+@@ -592,6 +597,12 @@ cli_resize(void *v, char **reply, int *l
+ return 1;
+ }
+
++ if (mpp->wait_for_udev) {
++ condlog(2, "%s: device not fully created, failing resize",
++ mpp->alias);
++ return 1;
++ }
++
+ pgp = VECTOR_SLOT(mpp->pg, 0);
+
+ if (!pgp){
+@@ -756,6 +767,12 @@ cli_reconfigure(void * v, char ** reply,
+ {
+ struct vectors * vecs = (struct vectors *)data;
+
++ if (need_to_delay_reconfig(vecs)) {
++ conf->delayed_reconfig = 1;
++ condlog(2, "delaying reconfigure (operator)");
++ return 0;
++ }
++
+ condlog(2, "reconfigure (operator)");
+
+ return reconfigure(vecs);
+@@ -766,17 +783,25 @@ cli_suspend(void * v, char ** reply, int
+ {
+ struct vectors * vecs = (struct vectors *)data;
+ char * param = get_keyparam(v, MAP);
+- int r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
++ int r;
++ struct multipath * mpp;
+
+ param = convert_dev(param, 0);
+- condlog(2, "%s: suspend (operator)", param);
++ mpp = find_mp_by_alias(vecs->mpvec, param);
++ if (!mpp)
++ return 1;
+
+- if (!r) /* error */
++ if (mpp->wait_for_udev) {
++ condlog(2, "%s: device not fully created, failing suspend",
++ mpp->alias);
+ return 1;
++ }
+
+- struct multipath * mpp = find_mp_by_alias(vecs->mpvec, param);
++ r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
+
+- if (!mpp)
++ condlog(2, "%s: suspend (operator)", param);
++
++ if (!r) /* error */
+ return 1;
+
+ dm_get_info(param, &mpp->dmi);
+@@ -788,17 +813,25 @@ cli_resume(void * v, char ** reply, int
+ {
+ struct vectors * vecs = (struct vectors *)data;
+ char * param = get_keyparam(v, MAP);
+- int r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
++ int r;
++ struct multipath * mpp;
+
+ param = convert_dev(param, 0);
+- condlog(2, "%s: resume (operator)", param);
++ mpp = find_mp_by_alias(vecs->mpvec, param);
++ if (!mpp)
++ return 1;
+
+- if (!r) /* error */
++ if (mpp->wait_for_udev) {
++ condlog(2, "%s: device not fully created, failing resume",
++ mpp->alias);
+ return 1;
++ }
+
+- struct multipath * mpp = find_mp_by_alias(vecs->mpvec, param);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
+
+- if (!mpp)
++ condlog(2, "%s: resume (operator)", param);
++
++ if (!r) /* error */
+ return 1;
+
+ dm_get_info(param, &mpp->dmi);
+@@ -831,9 +864,21 @@ cli_reinstate(void * v, char ** reply, i
+ int
+ cli_reassign (void * v, char ** reply, int * len, void * data)
+ {
++ struct vectors * vecs = (struct vectors *)data;
+ char * param = get_keyparam(v, MAP);
++ struct multipath *mpp;
+
+ param = convert_dev(param, 0);
++ mpp = find_mp_by_alias(vecs->mpvec, param);
++ if (!mpp)
++ return 1;
++
++ if (mpp->wait_for_udev) {
++ condlog(2, "%s: device not fully created, failing reassign",
++ mpp->alias);
++ return 1;
++ }
++
+ condlog(3, "%s: reset devices (operator)", param);
+
+ dm_reassign(param);
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -142,6 +142,8 @@ struct config {
+ int retrigger_tries;
+ int retrigger_delay;
+ int new_bindings_in_boot;
++ int delayed_reconfig;
++ int uev_msg_delay;
+ unsigned int version[3];
+
+ char * dev;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -251,6 +251,47 @@ flush_map(struct multipath * mpp, struct
+ return 0;
+ }
+
++int
++update_map (struct multipath *mpp, struct vectors *vecs)
++{
++ int retries = 3;
++ char params[PARAMS_SIZE] = {0};
++
++retry:
++ condlog(4, "%s: updating new map", mpp->alias);
++ if (adopt_paths(vecs->pathvec, mpp, 1)) {
++ condlog(0, "%s: failed to adopt paths for new map update",
++ mpp->alias);
++ retries = -1;
++ goto fail;
++ }
++ verify_paths(mpp, vecs, NULL);
++ mpp->flush_on_last_del = FLUSH_UNDEF;
++ mpp->action = ACT_RELOAD;
++
++ if (setup_map(mpp, params, PARAMS_SIZE)) {
++ condlog(0, "%s: failed to setup new map in update", mpp->alias);
++ retries = -1;
++ goto fail;
++ }
++ if (domap(mpp, params) <= 0 && retries-- > 0) {
++ condlog(0, "%s: map_udate sleep", mpp->alias);
++ sleep(1);
++ goto retry;
++ }
++ dm_lib_release();
++
++fail:
++ if (setup_multipath(vecs, mpp))
++ return 1;
++
++ sync_map_state(mpp);
++
++ if (retries < 0)
++ condlog(0, "%s: failed reload in new map update", mpp->alias);
++ return 0;
++}
++
+ static int
+ uev_add_map (struct uevent * uev, struct vectors * vecs)
+ {
+@@ -293,6 +334,20 @@ ev_add_map (char * dev, char * alias, st
+ mpp = find_mp_by_alias(vecs->mpvec, alias);
+
+ if (mpp) {
++ if (mpp->wait_for_udev > 1) {
++ if (update_map(mpp, vecs))
++ /* setup multipathd removed the map */
++ return 1;
++ }
++ if (mpp->wait_for_udev) {
++ mpp->wait_for_udev = 0;
++ if (conf->delayed_reconfig &&
++ !need_to_delay_reconfig(vecs)) {
++ condlog(2, "reconfigure (delayed)");
++ reconfigure(vecs);
++ return 0;
++ }
++ }
+ /*
+ * Not really an error -- we generate our own uevent
+ * if we create a multipath mapped device as a result
+@@ -471,7 +526,14 @@ ev_add_path (struct path * pp, struct ve
+ condlog(0, "%s: failed to get path uid", pp->dev);
+ goto fail; /* leave path added to pathvec */
+ }
+- mpp = pp->mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
++ mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
++ if (mpp && mpp->wait_for_udev) {
++ mpp->wait_for_udev = 2;
++ orphan_path(pp);
++ return 0;
++ }
++
++ pp->mpp = mpp;
+ rescan:
+ if (mpp) {
+ if ((!pp->size) || (mpp->size != pp->size)) {
+@@ -670,6 +732,12 @@ ev_remove_path (struct path *pp, struct
+ " removal of path %s", mpp->alias, pp->dev);
+ goto fail;
+ }
++
++ if (mpp->wait_for_udev) {
++ mpp->wait_for_udev = 2;
++ goto out;
++ }
++
+ /*
+ * reload the map
+ */
+@@ -731,6 +799,11 @@ uev_update_path (struct uevent *uev, str
+ condlog(2, "%s: update path write_protect to '%d' (uevent)",
+ uev->kernel, ro);
+ if (pp->mpp) {
++ if (pp->mpp->wait_for_udev) {
++ pp->mpp->wait_for_udev = 2;
++ return 0;
++ }
++
+ retval = reload_map(vecs, pp->mpp, 0);
+
+ condlog(2, "%s: map %s reloaded (retval %d)",
+@@ -1063,6 +1136,20 @@ followover_should_failback(struct path *
+ }
+
+ static void
++missing_uev_message_tick(vector mpvec)
++{
++ struct multipath * mpp;
++ unsigned int i;
++
++ vector_foreach_slot (mpvec, mpp, i) {
++ if (mpp->wait_for_udev && --mpp->uev_msg_tick <= 0) {
++ condlog(0, "%s: startup incomplete. Still waiting on udev", mpp->alias);
++ mpp->uev_msg_tick = conf->uev_msg_delay;
++ }
++ }
++}
++
++static void
+ defered_failback_tick (vector mpvec)
+ {
+ struct multipath * mpp;
+@@ -1316,6 +1403,9 @@ check_path (struct vectors * vecs, struc
+
+ pp->state = newstate;
+
++
++ if (pp->mpp->wait_for_udev)
++ return;
+ /*
+ * path prio refreshing
+ */
+@@ -1369,6 +1459,7 @@ checkerloop (void *ap)
+ if (vecs->mpvec) {
+ defered_failback_tick(vecs->mpvec);
+ retry_count_tick(vecs->mpvec);
++ missing_uev_message_tick(vecs->mpvec);
+ }
+ if (count)
+ count--;
+@@ -1464,6 +1555,22 @@ configure (struct vectors * vecs, int st
+ }
+
+ int
++need_to_delay_reconfig(struct vectors * vecs)
++{
++ struct multipath *mpp;
++ int i;
++
++ if (!VECTOR_SIZE(vecs->mpvec))
++ return 0;
++
++ vector_foreach_slot(vecs->mpvec, mpp, i) {
++ if (mpp->wait_for_udev)
++ return 1;
++ }
++ return 0;
++}
++
++int
+ reconfigure (struct vectors * vecs)
+ {
+ struct config * old = conf;
+@@ -1543,12 +1650,18 @@ void
+ handle_signals(void)
+ {
+ if (reconfig_sig && running_state == DAEMON_RUNNING) {
+- condlog(2, "reconfigure (signal)");
+ pthread_cleanup_push(cleanup_lock,
+ &gvecs->lock);
+ lock(gvecs->lock);
+ pthread_testcancel();
+- reconfigure(gvecs);
++ if (need_to_delay_reconfig(gvecs)) {
++ conf->delayed_reconfig = 1;
++ condlog(2, "delaying reconfigure (signal)");
++ }
++ else {
++ condlog(2, "reconfigure (signal)");
++ reconfigure(gvecs);
++ }
+ lock_cleanup_pop(gvecs->lock);
+ }
+ if (log_reset_sig) {
+Index: multipath-tools-130222/multipathd/main.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.h
++++ multipath-tools-130222/multipathd/main.h
+@@ -18,6 +18,7 @@ extern pid_t daemon_pid;
+
+ void exit_daemon(void);
+ const char * daemon_status(void);
++int need_to_delay_reconfig (struct vectors *);
+ int reconfigure (struct vectors *);
+ int ev_add_path (struct path *, struct vectors *);
+ int ev_remove_path (struct path *, struct vectors *);
+Index: multipath-tools-130222/libmultipath/config.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.c
++++ multipath-tools-130222/libmultipath/config.c
+@@ -676,6 +676,7 @@ load_config (char * file, struct udev *u
+ conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
+ conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
+ conf->new_bindings_in_boot = 0;
++ conf->uev_msg_delay = DEFAULT_UEV_MSG_DELAY;
+
+ /*
+ * preload default hwtable
+Index: multipath-tools-130222/libmultipath/defaults.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/defaults.h
++++ multipath-tools-130222/libmultipath/defaults.h
+@@ -23,6 +23,7 @@
+ #define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF
+ #define DEFAULT_RETRIGGER_DELAY 10
+ #define DEFAULT_RETRIGGER_TRIES 3
++#define DEFAULT_UEV_MSG_DELAY 30
+
+ #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
+@@ -872,6 +872,24 @@ def_retrigger_delay_handler(vector strve
+ }
+
+ static int
++def_uev_msg_delay_handler(vector strvec)
++{
++ char *buff;
++
++ buff = set_value(strvec);
++
++ if (!buff)
++ return 1;
++
++ conf->uev_msg_delay = atoi(buff);
++ if (conf->uev_msg_delay <= 0)
++ conf->uev_msg_delay = DEFAULT_UEV_MSG_DELAY;
++ FREE(buff);
++
++ return 0;
++}
++
++static int
+ def_new_bindings_in_boot_handler(vector strvec)
+ {
+ char * buff;
+@@ -3261,6 +3279,12 @@ snprint_def_retrigger_delay (char * buff
+ }
+
+ static int
++snprint_def_uev_msg_delay (char * buff, int len, void * data)
++{
++ return snprintf(buff, len, "%i", conf->uev_msg_delay);
++}
++
++static int
+ snprint_def_new_bindings_in_boot(char * buff, int len, void * data)
+ {
+ if (conf->new_bindings_in_boot == 1)
+@@ -3345,6 +3369,7 @@ init_keywords(void)
+ install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
+ install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries);
+ install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay);
++ install_keyword("missing_uev_msg_delay", &def_uev_msg_delay_handler, &snprint_def_uev_msg_delay);
+ install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot);
+ __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+ __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -29,6 +29,7 @@
+ # config_dir "/etc/multipath/conf.d"
+ # delay_watch_checks no
+ # delay_wait_checks no
++# missing_uev_msg_delay 30
+ #}
+ #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
+@@ -478,6 +478,14 @@ used until it has passed
+ .I delay_wait_checks
+ checks. Default is
+ .I no
++.TP
++.B missing_uev_msg_delay
++Controls how long multipathd will wait, after a new multipath device is created,
++to receive a change event from udev for the device, before printing a warning
++message. This warning message will print every
++.I missing_uev_msg_delay
++seconds until the uevent is received. the default is
++.I 30
+ .
+ .SH "blacklist section"
+ The
diff --git a/0137-RHBZ-1280524-clear-chkr-msg.patch b/0137-RHBZ-1280524-clear-chkr-msg.patch
new file mode 100644
index 0000000..b7cd118
--- /dev/null
+++ b/0137-RHBZ-1280524-clear-chkr-msg.patch
@@ -0,0 +1,17 @@
+---
+ multipathd/main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1257,6 +1257,8 @@ check_path (struct vectors * vecs, struc
+ newstate = path_offline(pp);
+ if (newstate == PATH_UP)
+ newstate = get_state(pp, 1);
++ else
++ checker_clear_message(&pp->checker);
+
+ if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
+ condlog(2, "%s: unusable path", pp->dev);
diff --git a/0138-RHBZ-1288660-fix-mpathconf-allow.patch b/0138-RHBZ-1288660-fix-mpathconf-allow.patch
new file mode 100644
index 0000000..421f877
--- /dev/null
+++ b/0138-RHBZ-1288660-fix-mpathconf-allow.patch
@@ -0,0 +1,86 @@
+---
+ multipath/mpathconf | 37 ++++++++++++++++++++++++++-----------
+ 1 file changed, 26 insertions(+), 11 deletions(-)
+
+Index: multipath-tools-130222/multipath/mpathconf
+===================================================================
+--- multipath-tools-130222.orig/multipath/mpathconf
++++ multipath-tools-130222/multipath/mpathconf
+@@ -59,6 +59,19 @@ function usage
+ echo ""
+ }
+
++function add_wwid
++{
++ INDEX=0
++ while [ "$INDEX" -lt "$WWIDS" ] ; do
++ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then
++ return
++ fi
++ ((INDEX++))
++ done
++ WWID_LIST[$WWIDS]="$1"
++ ((WWIDS++))
++}
++
+ function get_dm_deps
+ {
+ shift 3
+@@ -76,11 +89,9 @@ function get_dm_deps
+ function set_dm_wwid
+ {
+ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then
+- WWID_LIST[$WWIDS]="${1##part*-mpath-}"
+- ((WWIDS++))
++ add_wwid "${1##part*-mpath-}"
+ elif [[ "$1" =~ ^mpath- ]] ; then
+- WWID_LIST[$WWIDS]="${1##mpath-}"
+- ((WWIDS++))
++ add_wwid "${1##mpath-}"
+ else
+ get_dm_deps `dmsetup deps -u $1`
+ fi
+@@ -99,8 +110,7 @@ function set_wwid
+ if [ -n "$UUID" ] ; then
+ set_dm_wwid $UUID
+ else
+- WWID_LIST[$WWIDS]="$1"
+- ((WWIDS++))
++ add_wwid "$1"
+ fi
+ }
+
+@@ -215,13 +225,13 @@ function validate_args
+
+ function add_blacklist_exceptions
+ {
+- echo "blacklist_exceptions {" >> $TMPFILE
+ INDEX=0
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
+- echo " wwid \"${WWID_LIST[$INDEX]}\"" >> $TMPFILE
++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
++ wwid '"\"${WWID_LIST[$INDEX]}\""'
++' $TMPFILE
+ ((INDEX++))
+ done
+- echo "}" >> $TMPFILE
+ }
+
+ umask 0077
+@@ -364,9 +374,14 @@ if [ "$ENABLE" = 2 ]; then
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
+ fi
+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then
+- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/d' $TMPFILE
++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
++ else
++ cat >> $TMPFILE <<- _EOF_
++
++blacklist_exceptions {
++}
++_EOF_
+ fi
+- echo $HAVE_WWID_DISABLE
+ add_blacklist_exceptions
+ elif [ "$ENABLE" = 1 ]; then
+ if [ "$HAVE_DISABLE" = 1 ]; then
diff --git a/0139-RHBZ-1273173-queue-no-daemon-doc.patch b/0139-RHBZ-1273173-queue-no-daemon-doc.patch
new file mode 100644
index 0000000..4531c1d
--- /dev/null
+++ b/0139-RHBZ-1273173-queue-no-daemon-doc.patch
@@ -0,0 +1,162 @@
+---
+ multipath.conf.defaults | 57 +++++++++++++++++++++++++++++++++++++--------
+ multipath/multipath.conf.5 | 2 -
+ 2 files changed, 48 insertions(+), 11 deletions(-)
+
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -377,7 +377,7 @@ multipathd running, access to the paths
+ cannot be told to stop queueing IO. Setting queue_without_daemon to
+ .I no
+ , avoids this problem. Default is
+-.I yes
++.I no
+ .TP
+ .B bindings_file
+ The full pathname of the binding file to be used when the user_friendly_names option is set. Defaults to
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -1,9 +1,12 @@
+ # These are the compiled in default settings. They will be used unless you
+ # overwrite these values in your config file.
+-
++
+ #defaults {
+ # verbosity 2
+ # polling_interval 5
++# max_polling_interval 20
++# reassign_maps "yes"
++# multipath_dir "/lib64/multipath"
+ # path_selector "service-time 0"
+ # path_grouping_policy "failover"
+ # uid_attribute "ID_SERIAL"
+@@ -12,28 +15,35 @@
+ # features "0"
+ # path_checker "directio"
+ # alias_prefix "mpath"
++# failback "manual"
+ # rr_min_io 1000
+ # rr_min_io_rq 1
+ # max_fds 1048576
+ # rr_weight "uniform"
+-# queue_without_daemon "yes"
+-# pg_timeout "none"
++# queue_without_daemon "no"
+ # flush_on_last_del "no"
+ # user_friendly_names "no"
+ # fast_io_fail_tmo 5
+ # bindings_file "/etc/multipath/bindings"
+ # wwids_file /etc/multipath/wwids
+ # log_checker_err always
++# find_multipaths no
+ # retain_attached_hw_handler no
+ # detect_prio no
++# hw_str_match no
++# force_sync no
++# deferred_remove no
++# ignore_new_boot_devs no
+ # config_dir "/etc/multipath/conf.d"
+ # delay_watch_checks no
+ # delay_wait_checks no
+-# missing_uev_msg_delay 30
++# retrigger_tries 3
++# retrigger_delay 10
++# new_bindings_in_boot no
+ #}
+ #blacklist {
+ # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
+-# devnode "^hd[a-z]"
++# devnode "^(td|hd|vd)[a-z]"
+ # devnode "^dcssblk[0-9]*"
+ # device {
+ # vendor "DGC"
+@@ -68,7 +78,7 @@
+ # product "Universal Xport"
+ # }
+ # device {
+-# vendor "(LSI|ENGENIO)"
++# vendor "(NETAPP|LSI|ENGENIO)"
+ # product "Universal Xport"
+ # }
+ #}
+@@ -666,7 +676,7 @@
+ # features "2 pg_init_retries 50"
+ # hardware_handler "1 rdac"
+ # prio "rdac"
+-# failback "immediate"
++# failback immediate
+ # rr_weight "uniform"
+ # no_path_retry 15
+ # }
+@@ -679,7 +689,7 @@
+ # features "2 pg_init_retries 50"
+ # hardware_handler "1 rdac"
+ # prio "rdac"
+-# failback "immediate"
++# failback immediate
+ # rr_weight "uniform"
+ # no_path_retry 15
+ # }
+@@ -696,6 +706,7 @@
+ # rr_min_io 128
+ # flush_on_last_del "yes"
+ # dev_loss_tmo "infinity"
++# user_friendly_names no
+ # retain_attached_hw_handler yes
+ # detect_prio yes
+ # }
+@@ -876,7 +887,7 @@
+ # rr_min_io_rq 1
+ # }
+ # device {
+-# vendor "(LSI|ENGENIO)"
++# vendor "(NETAPP|LSI|ENGENIO)"
+ # product "INF-01-00"
+ # product_blacklist "Universal Xport"
+ # path_grouping_policy "group_by_prio"
+@@ -886,7 +897,9 @@
+ # prio "rdac"
+ # failback immediate
+ # rr_weight "uniform"
+-# no_path_retry 15
++# no_path_retry 30
++# retain_attached_hw_handler yes
++# detect_prio yes
+ # }
+ # device {
+ # vendor "STK"
+@@ -925,6 +938,30 @@
+ # rr_weight "uniform"
+ # no_path_retry "queue"
+ # }
++# device {
++# vendor "DataCore"
++# product "Virtual Disk"
++# path_grouping_policy "group_by_prio"
++# path_checker "tur"
++# features "0"
++# hardware_handler "0"
++# prio "alua"
++# failback immediate
++# rr_weight "uniform"
++# no_path_retry "queue"
++# }
++# device {
++# vendor "XtremIO"
++# product "XtremApp"
++# path_grouping_policy "multibus"
++# path_selector "queue-length 0"
++# path_checker "directio"
++# features "0"
++# hardware_handler "0"
++# prio "const"
++# failback immediate
++# fast_io_fail_tmo 15
++# }
+ #}
+ #multipaths {
+ #}
diff --git a/0140-RHBZ-1299647-fix-help.patch b/0140-RHBZ-1299647-fix-help.patch
new file mode 100644
index 0000000..c504974
--- /dev/null
+++ b/0140-RHBZ-1299647-fix-help.patch
@@ -0,0 +1,16 @@
+---
+ multipath/main.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -111,7 +111,6 @@ usage (char * progname)
+ " -r force devmap reload\n" \
+ " -i ignore wwids file\n" \
+ " -B treat the bindings file as read only\n" \
+- " -p policy failover|multibus|group_by_serial|group_by_prio\n" \
+ " -b fil bindings file location\n" \
+ " -w remove a device from the wwids file\n" \
+ " -W reset the wwids file include only the current devices\n" \
diff --git a/0141-RHBZ-1303953-mpathpersist-typo.patch b/0141-RHBZ-1303953-mpathpersist-typo.patch
new file mode 100644
index 0000000..7525902
--- /dev/null
+++ b/0141-RHBZ-1303953-mpathpersist-typo.patch
@@ -0,0 +1,17 @@
+---
+ libmpathpersist/mpath_persist.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
++++ multipath-tools-130222/libmpathpersist/mpath_persist.c
+@@ -822,7 +822,7 @@ int update_map_pr(struct multipath *mpp)
+ if (!mpp->reservation_key)
+ {
+ /* Nothing to do. Assuming pr mgmt feature is disabled*/
+- condlog(3, "%s: reservation_key not set in multiapth.conf", mpp->alias);
++ condlog(3, "%s: reservation_key not set in multipath.conf", mpp->alias);
+ return MPATH_PR_SUCCESS;
+ }
+
diff --git a/0142-RHBZ-1283750-kpartx-fix.patch b/0142-RHBZ-1283750-kpartx-fix.patch
new file mode 100644
index 0000000..0bc21b8
--- /dev/null
+++ b/0142-RHBZ-1283750-kpartx-fix.patch
@@ -0,0 +1,189 @@
+---
+ kpartx/devmapper.c | 17 +++++++++++++--
+ kpartx/devmapper.h | 2 -
+ kpartx/kpartx.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 69 insertions(+), 7 deletions(-)
+
+Index: multipath-tools-130222/kpartx/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.c
++++ multipath-tools-130222/kpartx/devmapper.c
+@@ -140,12 +140,16 @@ addout:
+ }
+
+ extern int
+-dm_map_present (char * str)
++dm_map_present (char * str, char **uuid)
+ {
+ int r = 0;
+ struct dm_task *dmt;
++ const char *uuidtmp;
+ struct dm_info info;
+
++ if (uuid)
++ *uuid = NULL;
++
+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
+ return 0;
+
+@@ -160,8 +164,15 @@ dm_map_present (char * str)
+ if (!dm_task_get_info(dmt, &info))
+ goto out;
+
+- if (info.exists)
+- r = 1;
++ if (!info.exists)
++ goto out;
++
++ r = 1;
++ if (uuid) {
++ uuidtmp = dm_task_get_uuid(dmt);
++ if (uuidtmp && strlen(uuidtmp))
++ *uuid = strdup(uuidtmp);
++ }
+ out:
+ dm_task_destroy(dmt);
+ return r;
+Index: multipath-tools-130222/kpartx/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.h
++++ multipath-tools-130222/kpartx/devmapper.h
+@@ -14,7 +14,7 @@ int dm_prereq (char *, int, int, int);
+ int dm_simplecmd (int, const char *, int, uint32_t *, uint16_t);
+ int dm_addmap (int, const char *, const char *, const char *, uint64_t,
+ int, const char *, int, mode_t, uid_t, gid_t, uint32_t *);
+-int dm_map_present (char *);
++int dm_map_present (char *, char **);
+ char * dm_mapname(int major, int minor);
+ dev_t dm_get_first_dep(char *devname);
+ char * dm_mapuuid(int major, int minor);
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -191,6 +191,21 @@ get_hotplug_device(void)
+ return device;
+ }
+
++static int
++check_uuid(char *uuid, char *part_uuid, char **err_msg) {
++ char *map_uuid = strchr(part_uuid, '-');
++ if (!map_uuid || strncmp(part_uuid, "part", 4) != 0) {
++ *err_msg = "not a kpartx partition";
++ return -1;
++ }
++ map_uuid++;
++ if (strcmp(uuid, map_uuid) != 0) {
++ *err_msg = "a partition of a different device";
++ return -1;
++ }
++ return 0;
++}
++
+ int
+ main(int argc, char **argv){
+ int i, j, m, n, op, off, arg, ro=0;
+@@ -410,6 +425,8 @@ main(int argc, char **argv){
+
+ case DELETE:
+ for (j = MAXSLICES-1; j >= 0; j--) {
++ char *part_uuid, *reason;
++
+ if (safe_sprintf(partname, "%s%s%d",
+ mapname, delim, j+1)) {
+ fprintf(stderr, "partname too small\n");
+@@ -417,9 +434,18 @@ main(int argc, char **argv){
+ }
+ strip_slash(partname);
+
+- if (!dm_map_present(partname))
++ if (!dm_map_present(partname, &part_uuid))
+ continue;
+
++ if (part_uuid && uuid) {
++ if (check_uuid(uuid, part_uuid, &reason) != 0) {
++ fprintf(stderr, "%s is %s. Not removing\n", partname, reason);
++ free(part_uuid);
++ continue;
++ }
++ free(part_uuid);
++ }
++
+ if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
+ 0, &cookie, 0)) {
+ r++;
+@@ -444,6 +470,8 @@ main(int argc, char **argv){
+ case UPDATE:
+ /* ADD and UPDATE share the same code that adds new partitions. */
+ for (j = 0; j < n; j++) {
++ char *part_uuid, *reason;
++
+ if (slices[j].size == 0)
+ continue;
+
+@@ -460,9 +488,19 @@ main(int argc, char **argv){
+ exit(1);
+ }
+
+- op = (dm_map_present(partname) ?
++ op = (dm_map_present(partname, &part_uuid) ?
+ DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
+
++ if (part_uuid && uuid) {
++ if (check_uuid(uuid, part_uuid, &reason) != 0) {
++ fprintf(stderr, "%s is already in use, and %s\n", partname, reason);
++ r++;
++ free(part_uuid);
++ continue;
++ }
++ free(part_uuid);
++ }
++
+ if (!dm_addmap(op, partname, DM_TARGET, params,
+ slices[j].size, ro, uuid, j+1,
+ buf.st_mode & 0777, buf.st_uid,
+@@ -470,6 +508,7 @@ main(int argc, char **argv){
+ fprintf(stderr, "create/reload failed on %s\n",
+ partname);
+ r++;
++ continue;
+ }
+ if (op == DM_DEVICE_RELOAD &&
+ !dm_simplecmd(DM_DEVICE_RESUME, partname,
+@@ -477,6 +516,7 @@ main(int argc, char **argv){
+ fprintf(stderr, "resume failed on %s\n",
+ partname);
+ r++;
++ continue;
+ }
+ dm_devn(partname, &slices[j].major,
+ &slices[j].minor);
+@@ -494,6 +534,7 @@ main(int argc, char **argv){
+ }
+
+ for (j = MAXSLICES-1; j >= 0; j--) {
++ char *part_uuid, *reason;
+ if (safe_sprintf(partname, "%s%s%d",
+ mapname, delim, j+1)) {
+ fprintf(stderr, "partname too small\n");
+@@ -501,9 +542,19 @@ main(int argc, char **argv){
+ }
+ strip_slash(partname);
+
+- if (slices[j].size || !dm_map_present(partname))
++ if (slices[j].size ||
++ !dm_map_present(partname, &part_uuid))
+ continue;
+
++ if (part_uuid && uuid) {
++ if (check_uuid(uuid, part_uuid, &reason) != 0) {
++ fprintf(stderr, "%s is %s. Not removing\n", partname, reason);
++ free(part_uuid);
++ continue;
++ }
++ free(part_uuid);
++ }
++
+ if (!dm_simplecmd(DM_DEVICE_REMOVE,
+ partname, 1, &cookie, 0)) {
+ r++;
diff --git a/0143-RHBZ-1299648-kpartx-sync.patch b/0143-RHBZ-1299648-kpartx-sync.patch
new file mode 100644
index 0000000..5e9928d
--- /dev/null
+++ b/0143-RHBZ-1299648-kpartx-sync.patch
@@ -0,0 +1,59 @@
+---
+ kpartx/kpartx.c | 10 +++++++---
+ multipath/multipath.rules | 2 +-
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -57,7 +57,7 @@ struct pt {
+ } pts[MAXTYPES];
+
+ int ptct = 0;
+-int udev_sync = 0;
++int udev_sync = 1;
+
+ static void
+ addpts(char *t, ptreader f)
+@@ -85,7 +85,7 @@ initpts(void)
+ addpts("ps3", read_ps3_pt);
+ }
+
+-static char short_opts[] = "rladfgvp:t:su";
++static char short_opts[] = "rladfgvp:t:snu";
+
+ /* Used in gpt.c */
+ int force_gpt=0;
+@@ -104,7 +104,8 @@ usage(void) {
+ printf("\t-g force GUID partition table (GPT)\n");
+ printf("\t-f force devmap create\n");
+ printf("\t-v verbose\n");
+- printf("\t-s sync mode. Don't return until the partitions are created\n");
++ printf("\t-n nosync mode. Return before the partitions are created\n");
++ printf("\t-s sync mode. Don't return until the partitions are created. Default.\n");
+ return 1;
+ }
+
+@@ -285,6 +286,9 @@ main(int argc, char **argv){
+ case 's':
+ udev_sync = 1;
+ break;
++ case 'n':
++ udev_sync = 0;
++ break;
+ case 'u':
+ what = UPDATE;
+ break;
+Index: multipath-tools-130222/multipath/multipath.rules
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.rules
++++ multipath-tools-130222/multipath/multipath.rules
+@@ -48,6 +48,6 @@ ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPAT
+ ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
+ ENV{DM_ACTIVATION}!="1", ENV{DM_MULTIPATH_NEED_KPARTX}!="1", GOTO="end_mpath"
+-RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode", \
++RUN+="$env{MPATH_SBIN_PATH}/kpartx -an $tempnode", \
+ ENV{DM_MULTIPATH_NEED_KPARTX}=""
+ LABEL="end_mpath"
diff --git a/0144-RHBZ-1299652-alua-pref-arg.patch b/0144-RHBZ-1299652-alua-pref-arg.patch
new file mode 100644
index 0000000..9ae0b40
--- /dev/null
+++ b/0144-RHBZ-1299652-alua-pref-arg.patch
@@ -0,0 +1,136 @@
+---
+ libmultipath/prioritizers/alua.c | 20 +++++++++++++++++++-
+ libmultipath/propsel.c | 18 ++++++++++--------
+ multipath/multipath.conf.5 | 19 ++++++++++++++++---
+ 3 files changed, 45 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/prioritizers/alua.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c
++++ multipath-tools-130222/libmultipath/prioritizers/alua.c
+@@ -86,15 +86,33 @@ get_alua_info(int fd, struct alua_contex
+ return rc;
+ }
+
++int get_exclusive_perf_arg(char *args)
++{
++ char *ptr;
++
++ if (args == NULL)
++ return 0;
++ ptr = strstr(args, "exclusive_pref_bit");
++ if (!ptr)
++ return 0;
++ if (ptr[18] != '\0' && ptr[18] != ' ' && ptr[18] != '\t')
++ return 0;
++ if (ptr != args && ptr[-1] != ' ' && ptr[-1] != '\t')
++ return 0;
++ return 1;
++}
++
+ int getprio (struct path * pp, char * args)
+ {
+ int rc;
+ int aas;
+ int priopath;
++ int exclusive_perf;
+
+ if (pp->fd < 0)
+ return -ALUA_PRIO_NO_INFORMATION;
+
++ exclusive_perf = get_exclusive_perf_arg(args);
+ rc = get_alua_info(pp->fd, pp->prio.context);
+ if (rc >= 0) {
+ aas = (rc & 0x0f);
+@@ -115,7 +133,7 @@ int getprio (struct path * pp, char * ar
+ default:
+ rc = 0;
+ }
+- if (priopath && aas != AAS_OPTIMIZED)
++ if (priopath && (aas != AAS_OPTIMIZED || exclusive_perf))
+ rc += 80;
+ } else {
+ switch(-rc) {
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -420,17 +420,19 @@ select_prio (struct path * pp)
+ if (prio_selected(p)) {
+ condlog(3, "%s: prio = %s (detected setting)",
+ pp->dev, prio_name(p));
++ condlog(3, "%s: prio args = %s (detected setting)",
++ pp->dev, prio_args(p));
+ return 0;
+ }
+ }
+
+- if ((mpe = find_mpe(pp->wwid))) {
+- if (mpe->prio_name) {
+- prio_get(p, mpe->prio_name, mpe->prio_args);
+- condlog(3, "%s: prio = %s (LUN setting)",
+- pp->dev, prio_name(p));
+- return 0;
+- }
++ if ((mpe = find_mpe(pp->wwid)) && mpe->prio_name) {
++ prio_get(p, mpe->prio_name, mpe->prio_args);
++ condlog(3, "%s: prio = %s (LUN setting)",
++ pp->dev, prio_name(p));
++ condlog(3, "%s: prio args = %s (LUN setting)",
++ pp->dev, prio_args(p));
++ return 0;
+ }
+
+ if (pp->hwe && pp->hwe->prio_name) {
+@@ -452,7 +454,7 @@ select_prio (struct path * pp)
+ prio_get(p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
+ condlog(3, "%s: prio = %s (internal default)",
+ pp->dev, DEFAULT_PRIO);
+- condlog(3, "%s: prio = %s (internal default)",
++ condlog(3, "%s: prio args = %s (internal default)",
+ pp->dev, DEFAULT_PRIO_ARGS);
+ return 0;
+ }
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -182,7 +182,9 @@ Return a constant priority of \fI1\fR.
+ Generate the path priority for EMC arrays.
+ .TP
+ .B alua
+-Generate the path priority based on the SCSI-3 ALUA settings.
++Generate the path priority based on the SCSI-3 ALUA settings. This prioritizer
++accepts the optional prio_arg
++.I exclusive_pref_bit
+ .TP
+ .B ontap
+ Generate the path priority for NetApp arrays.
+@@ -208,14 +210,25 @@ Default value is \fBconst\fR.
+ .RE
+ .TP
+ .B prio_args
+-Arguments to pass to to the prio function. Currently only used with
+-.I weighted, which needs a value of the form
++Arguments to pass to to the prio function. This only applies to certain
++prioritizers
++.RS
++.TP 12
++.B weighted
++Needs a value of the form
+ .I "<hbtl|devname> <regex1> <prio1> <regex2> <prio2> ..."
+ .I hbtl
+ regex can be of SCSI H:B:T:L format Ex: 1:0:.:. , *:0:0:.
+ .I devname
+ regex can be of device name format Ex: sda , sd.e
+ .TP
++.B alua
++If
++.I exclusive_pref_bit
++is set, paths with the TPGS pref bit set will always be in their own path
++group.
++.RE
++.TP
+ .B features
+ Specify any device-mapper features to be used. Syntax is
+ .I num list
diff --git a/0145-UP-resize-help-msg.patch b/0145-UP-resize-help-msg.patch
new file mode 100644
index 0000000..33ca0f6
--- /dev/null
+++ b/0145-UP-resize-help-msg.patch
@@ -0,0 +1,172 @@
+diff --git a/multipathd/cli.c b/multipathd/cli.c
+index acc4249..8d26956 100644
+--- a/multipathd/cli.c
++++ b/multipathd/cli.c
+@@ -320,52 +320,90 @@ alloc_handlers (void)
+ }
+
+ static int
+-genhelp_sprint_aliases (char * reply, vector keys, struct key * refkw)
++genhelp_sprint_aliases (char * reply, int maxlen, vector keys,
++ struct key * refkw)
+ {
+- int i, fwd = 0;
++ int i, len = 0;
+ struct key * kw;
+
+- vector_foreach_slot (keys, kw, i)
+- if (kw->code == refkw->code && kw != refkw)
+- fwd += sprintf(reply, "|%s", kw->str);
++ vector_foreach_slot (keys, kw, i) {
++ if (kw->code == refkw->code && kw != refkw) {
++ len += snprintf(reply + len, maxlen - len,
++ "|%s", kw->str);
++ if (len >= maxlen)
++ return len;
++ }
++ }
+
+- return fwd;
++ return len;
+ }
+
+-static char *
+-genhelp_handler (void)
+-{
++static int
++do_genhelp(char *reply, int maxlen) {
++ int len = 0;
+ int i, j;
+ unsigned long fp;
+ struct handler * h;
+ struct key * kw;
+- char * reply;
+- char * p;
+-
+- reply = MALLOC(INITIAL_REPLY_LEN);
+
+- if (!reply)
+- return NULL;
+-
+- p = reply;
+- p += sprintf(p, VERSION_STRING);
+- p += sprintf(p, "CLI commands reference:\n");
++ len += snprintf(reply + len, maxlen - len, VERSION_STRING);
++ if (len >= maxlen)
++ goto out;
++ len += snprintf(reply + len, maxlen - len, "CLI commands reference:\n");
++ if (len >= maxlen)
++ goto out;
+
+ vector_foreach_slot (handlers, h, i) {
+ fp = h->fingerprint;
+ vector_foreach_slot (keys, kw, j) {
+ if ((kw->code & fp)) {
+ fp -= kw->code;
+- p += sprintf(p, " %s", kw->str);
+- p += genhelp_sprint_aliases(p, keys, kw);
+-
+- if (kw->has_param)
+- p += sprintf(p, " $%s", kw->str);
++ len += snprintf(reply + len , maxlen - len,
++ " %s", kw->str);
++ if (len >= maxlen)
++ goto out;
++ len += genhelp_sprint_aliases(reply + len,
++ maxlen - len,
++ keys, kw);
++ if (len >= maxlen)
++ goto out;
++
++ if (kw->has_param) {
++ len += snprintf(reply + len,
++ maxlen - len,
++ " $%s", kw->str);
++ if (len >= maxlen)
++ goto out;
++ }
+ }
+ }
+- p += sprintf(p, "\n");
++ len += snprintf(reply + len, maxlen - len, "\n");
++ if (len >= maxlen)
++ goto out;
+ }
++out:
++ return len;
++}
++
+
++static char *
++genhelp_handler (void)
++{
++ char * reply;
++ char * p = NULL;
++ int maxlen = INITIAL_REPLY_LEN;
++ int again = 1;
++
++ reply = MALLOC(maxlen);
++
++ while (again) {
++ if (!reply)
++ return NULL;
++ p = reply;
++ p += do_genhelp(reply, maxlen);
++ again = ((p - reply) >= maxlen);
++ REALLOC_REPLY(reply, again, maxlen);
++ }
+ return reply;
+ }
+
+diff --git a/multipathd/cli.h b/multipathd/cli.h
+index 09fdc68..2e0e1da 100644
+--- a/multipathd/cli.h
++++ b/multipathd/cli.h
+@@ -71,7 +71,21 @@ enum {
+ #define SETPRSTATUS (1UL << __SETPRSTATUS)
+ #define UNSETPRSTATUS (1UL << __UNSETPRSTATUS)
+
+-#define INITIAL_REPLY_LEN 1100
++#define INITIAL_REPLY_LEN 1200
++
++#define REALLOC_REPLY(r, a, m) \
++ do { \
++ if ((a)) { \
++ char *tmp = (r); \
++ (r) = REALLOC((r), (m) * 2); \
++ if ((r)) { \
++ memset((r) + (m), 0, (m)); \
++ (m) *= 2; \
++ } \
++ else \
++ free(tmp); \
++ } \
++ } while (0)
+
+ struct key {
+ char * str;
+diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
+index e47899a..23683f2 100644
+--- a/multipathd/cli_handlers.c
++++ b/multipathd/cli_handlers.c
+@@ -23,20 +23,6 @@
+ #include "cli.h"
+ #include "uevent.h"
+
+-#define REALLOC_REPLY(r, a, m) \
+- do { \
+- if ((a)) { \
+- char *tmp = (r); \
+- (r) = REALLOC((r), (m) * 2); \
+- if ((r)) { \
+- memset((r) + (m), 0, (m)); \
+- (m) *= 2; \
+- } \
+- else \
+- free(tmp); \
+- } \
+- } while (0)
+-
+ int
+ show_paths (char ** r, int * len, struct vectors * vecs, char * style)
+ {
diff --git a/0146-UPBZ-1299651-raw-output.patch b/0146-UPBZ-1299651-raw-output.patch
new file mode 100644
index 0000000..93a171e
--- /dev/null
+++ b/0146-UPBZ-1299651-raw-output.patch
@@ -0,0 +1,393 @@
+---
+ libmultipath/print.c | 42 ++++++++++++++++++++++++----------------
+ libmultipath/print.h | 4 +--
+ multipathd/cli.c | 5 +++-
+ multipathd/cli.h | 6 +++--
+ multipathd/cli_handlers.c | 48 ++++++++++++++++++++++++++++++++++------------
+ multipathd/cli_handlers.h | 2 +
+ multipathd/main.c | 2 +
+ 7 files changed, 76 insertions(+), 33 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -32,14 +32,21 @@
+ #define MAX(x,y) (x > y) ? x : y
+ #define TAIL (line + len - 1 - c)
+ #define NOPAD s = c
+-#define PAD(x) while ((int)(c - s) < (x) && (c < (line + len - 1))) \
+- *c++ = ' '; s = c
++#define PAD(x) \
++do { \
++ while ((int)(c - s) < (x) && (c < (line + len - 1))) \
++ *c++ = ' '; \
++ s = c; \
++} while (0)
++
+ #define ENDLINE \
+ if (c > line) \
+ line[c - line - 1] = '\n'
+-#define PRINT(var, size, format, args...) \
+- fwd = snprintf(var, size, format, ##args); \
+- c += (fwd >= size) ? size : fwd;
++#define PRINT(var, size, format, args...) \
++do { \
++ fwd = snprintf(var, size, format, ##args); \
++ c += (fwd >= size) ? size : fwd; \
++} while (0)
+
+ /*
+ * information printing helpers
+@@ -720,7 +727,7 @@ snprint_multipath_header (char * line, i
+
+ int
+ snprint_multipath (char * line, int len, char * format,
+- struct multipath * mpp)
++ struct multipath * mpp, int pad)
+ {
+ char * c = line; /* line cursor */
+ char * s = line; /* for padding */
+@@ -747,7 +754,8 @@ snprint_multipath (char * line, int len,
+
+ data->snprint(buff, MAX_FIELD_LEN, mpp);
+ PRINT(c, TAIL, "%s", buff);
+- PAD(data->width);
++ if (pad)
++ PAD(data->width);
+ buff[0] = '\0';
+ } while (*f++);
+
+@@ -790,7 +798,7 @@ snprint_path_header (char * line, int le
+
+ int
+ snprint_path (char * line, int len, char * format,
+- struct path * pp)
++ struct path * pp, int pad)
+ {
+ char * c = line; /* line cursor */
+ char * s = line; /* for padding */
+@@ -817,7 +825,8 @@ snprint_path (char * line, int len, char
+
+ data->snprint(buff, MAX_FIELD_LEN, pp);
+ PRINT(c, TAIL, "%s", buff);
+- PAD(data->width);
++ if (pad)
++ PAD(data->width);
+ } while (*f++);
+
+ ENDLINE;
+@@ -909,7 +918,7 @@ snprint_multipath_topology (char * buff,
+ reset_multipath_layout();
+
+ if (verbosity == 1)
+- return snprint_multipath(buff, len, "%n", mpp);
++ return snprint_multipath(buff, len, "%n", mpp, 1);
+
+ if(isatty(1))
+ c += sprintf(c, "%c[%dm", 0x1B, 1); /* bold on */
+@@ -928,10 +937,11 @@ snprint_multipath_topology (char * buff,
+ if(isatty(1))
+ c += sprintf(c, "%c[%dm", 0x1B, 0); /* bold off */
+
+- fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp);
++ fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp, 1);
+ if (fwd > len)
+ return len;
+- fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp);
++ fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp,
++ 1);
+ if (fwd > len)
+ return len;
+
+@@ -958,7 +968,7 @@ snprint_multipath_topology (char * buff,
+ strcpy(f, " |- " PRINT_PATH_INDENT);
+ else
+ strcpy(f, " `- " PRINT_PATH_INDENT);
+- fwd += snprint_path(buff + fwd, len - fwd, fmt, pp);
++ fwd += snprint_path(buff + fwd, len - fwd, fmt, pp, 1);
+ if (fwd > len)
+ return len;
+ }
+@@ -1425,7 +1435,7 @@ snprint_devices (char * buff, int len, s
+ if (r > 0)
+ fwd += snprintf(buff + fwd, len - fwd,
+ " devnode blacklisted, unmonitored");
+- else if (r < 0)
++ else if (r <= 0)
+ fwd += snprintf(buff + fwd, len - fwd,
+ " devnode whitelisted, unmonitored");
+ } else
+@@ -1455,7 +1465,7 @@ print_path (struct path * pp, char * sty
+ char line[MAX_LINE_LEN];
+
+ memset(&line[0], 0, MAX_LINE_LEN);
+- snprint_path(&line[0], MAX_LINE_LEN, style, pp);
++ snprint_path(&line[0], MAX_LINE_LEN, style, pp, 1);
+ printf("%s", line);
+ }
+
+@@ -1465,7 +1475,7 @@ print_multipath (struct multipath * mpp,
+ char line[MAX_LINE_LEN];
+
+ memset(&line[0], 0, MAX_LINE_LEN);
+- snprint_multipath(&line[0], MAX_LINE_LEN, style, mpp);
++ snprint_multipath(&line[0], MAX_LINE_LEN, style, mpp, 1);
+ printf("%s", line);
+ }
+
+Index: multipath-tools-130222/libmultipath/print.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.h
++++ multipath-tools-130222/libmultipath/print.h
+@@ -37,8 +37,8 @@ void get_path_layout (vector pathvec, in
+ void get_multipath_layout (vector mpvec, int header);
+ int snprint_path_header (char *, int, char *);
+ int snprint_multipath_header (char *, int, char *);
+-int snprint_path (char *, int, char *, struct path *);
+-int snprint_multipath (char *, int, char *, struct multipath *);
++int snprint_path (char *, int, char *, struct path *, int);
++int snprint_multipath (char *, int, char *, struct multipath *, int);
+ int snprint_multipath_topology (char *, int, struct multipath * mpp,
+ int verbosity);
+ int snprint_defaults (char *, int);
+Index: multipath-tools-130222/multipathd/cli.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.c
++++ multipath-tools-130222/multipathd/cli.c
+@@ -180,7 +180,7 @@ load_keys (void)
+ r += add_key(keys, "config", CONFIG, 0);
+ r += add_key(keys, "blacklist", BLACKLIST, 0);
+ r += add_key(keys, "devices", DEVICES, 0);
+- r += add_key(keys, "format", FMT, 1);
++ r += add_key(keys, "raw", RAW, 0);
+ r += add_key(keys, "wildcards", WILDCARDS, 0);
+ r += add_key(keys, "quit", QUIT, 0);
+ r += add_key(keys, "exit", QUIT, 0);
+@@ -188,6 +188,7 @@ load_keys (void)
+ r += add_key(keys, "getprstatus", GETPRSTATUS, 0);
+ r += add_key(keys, "setprstatus", SETPRSTATUS, 0);
+ r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0);
++ r += add_key(keys, "format", FMT, 1);
+
+ if (r) {
+ free_keys(keys);
+@@ -463,12 +464,14 @@ cli_init (void) {
+
+ add_handler(LIST+PATHS, NULL);
+ add_handler(LIST+PATHS+FMT, NULL);
++ add_handler(LIST+PATHS+RAW+FMT, NULL);
+ add_handler(LIST+STATUS, NULL);
+ add_handler(LIST+DAEMON, NULL);
+ add_handler(LIST+MAPS, NULL);
+ add_handler(LIST+MAPS+STATUS, NULL);
+ add_handler(LIST+MAPS+STATS, NULL);
+ add_handler(LIST+MAPS+FMT, NULL);
++ add_handler(LIST+MAPS+RAW+FMT, NULL);
+ add_handler(LIST+MAPS+TOPOLOGY, NULL);
+ add_handler(LIST+TOPOLOGY, NULL);
+ add_handler(LIST+MAP+TOPOLOGY, NULL);
+Index: multipath-tools-130222/multipathd/cli.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.h
++++ multipath-tools-130222/multipathd/cli.h
+@@ -26,13 +26,14 @@ enum {
+ __CONFIG,
+ __BLACKLIST,
+ __DEVICES,
+- __FMT,
++ __RAW,
+ __WILDCARDS,
+ __QUIT,
+ __SHUTDOWN,
+ __GETPRSTATUS,
+ __SETPRSTATUS,
+ __UNSETPRSTATUS,
++ __FMT,
+ };
+
+ #define LIST (1 << __LIST)
+@@ -62,7 +63,7 @@ enum {
+ #define CONFIG (1 << __CONFIG)
+ #define BLACKLIST (1 << __BLACKLIST)
+ #define DEVICES (1 << __DEVICES)
+-#define FMT (1 << __FMT)
++#define RAW (1 << __RAW)
+ #define COUNT (1 << __COUNT)
+ #define WILDCARDS (1 << __WILDCARDS)
+ #define QUIT (1 << __QUIT)
+@@ -70,6 +71,7 @@ enum {
+ #define GETPRSTATUS (1UL << __GETPRSTATUS)
+ #define SETPRSTATUS (1UL << __SETPRSTATUS)
+ #define UNSETPRSTATUS (1UL << __UNSETPRSTATUS)
++#define FMT (1UL << __FMT)
+
+ #define INITIAL_REPLY_LEN 1200
+
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -24,7 +24,8 @@
+ #include "uevent.h"
+
+ int
+-show_paths (char ** r, int * len, struct vectors * vecs, char * style)
++show_paths (char ** r, int * len, struct vectors * vecs, char * style,
++ int pretty)
+ {
+ int i;
+ struct path * pp;
+@@ -42,13 +43,13 @@ show_paths (char ** r, int * len, struct
+
+ c = reply;
+
+- if (VECTOR_SIZE(vecs->pathvec) > 0)
++ if (pretty && VECTOR_SIZE(vecs->pathvec) > 0)
+ c += snprint_path_header(c, reply + maxlen - c,
+ style);
+
+ vector_foreach_slot(vecs->pathvec, pp, i)
+ c += snprint_path(c, reply + maxlen - c,
+- style, pp);
++ style, pp, pretty);
+
+ again = ((c - reply) == (maxlen - 1));
+
+@@ -183,7 +184,7 @@ cli_list_paths (void * v, char ** reply,
+
+ condlog(3, "list paths (operator)");
+
+- return show_paths(reply, len, vecs, PRINT_PATH_CHECKER);
++ return show_paths(reply, len, vecs, PRINT_PATH_CHECKER, 1);
+ }
+
+ int
+@@ -194,7 +195,18 @@ cli_list_paths_fmt (void * v, char ** re
+
+ condlog(3, "list paths (operator)");
+
+- return show_paths(reply, len, vecs, fmt);
++ return show_paths(reply, len, vecs, fmt, 1);
++}
++
++int
++cli_list_paths_raw (void * v, char ** reply, int * len, void * data)
++{
++ struct vectors * vecs = (struct vectors *)data;
++ char * fmt = get_keyparam(v, FMT);
++
++ condlog(3, "list paths (operator)");
++
++ return show_paths(reply, len, vecs, fmt, 0);
+ }
+
+ int
+@@ -285,7 +297,8 @@ show_daemon (char ** r, int *len)
+ }
+
+ int
+-show_maps (char ** r, int *len, struct vectors * vecs, char * style)
++show_maps (char ** r, int *len, struct vectors * vecs, char * style,
++ int pretty)
+ {
+ int i;
+ struct multipath * mpp;
+@@ -302,13 +315,13 @@ show_maps (char ** r, int *len, struct v
+ return 1;
+
+ c = reply;
+- if (VECTOR_SIZE(vecs->mpvec) > 0)
++ if (pretty && VECTOR_SIZE(vecs->mpvec) > 0)
+ c += snprint_multipath_header(c, reply + maxlen - c,
+ style);
+
+ vector_foreach_slot(vecs->mpvec, mpp, i)
+ c += snprint_multipath(c, reply + maxlen - c,
+- style, mpp);
++ style, mpp, pretty);
+
+ again = ((c - reply) == (maxlen - 1));
+
+@@ -327,7 +340,18 @@ cli_list_maps_fmt (void * v, char ** rep
+
+ condlog(3, "list maps (operator)");
+
+- return show_maps(reply, len, vecs, fmt);
++ return show_maps(reply, len, vecs, fmt, 1);
++}
++
++int
++cli_list_maps_raw (void * v, char ** reply, int * len, void * data)
++{
++ struct vectors * vecs = (struct vectors *)data;
++ char * fmt = get_keyparam(v, FMT);
++
++ condlog(3, "list maps (operator)");
++
++ return show_maps(reply, len, vecs, fmt, 0);
+ }
+
+ int
+@@ -337,7 +361,7 @@ cli_list_maps (void * v, char ** reply,
+
+ condlog(3, "list maps (operator)");
+
+- return show_maps(reply, len, vecs, PRINT_MAP_NAMES);
++ return show_maps(reply, len, vecs, PRINT_MAP_NAMES, 1);
+ }
+
+ int
+@@ -357,7 +381,7 @@ cli_list_maps_status (void * v, char **
+
+ condlog(3, "list maps status (operator)");
+
+- return show_maps(reply, len, vecs, PRINT_MAP_STATUS);
++ return show_maps(reply, len, vecs, PRINT_MAP_STATUS, 1);
+ }
+
+ int
+@@ -367,7 +391,7 @@ cli_list_maps_stats (void * v, char ** r
+
+ condlog(3, "list maps stats (operator)");
+
+- return show_maps(reply, len, vecs, PRINT_MAP_STATS);
++ return show_maps(reply, len, vecs, PRINT_MAP_STATS, 1);
+ }
+
+ int
+Index: multipath-tools-130222/multipathd/cli_handlers.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.h
++++ multipath-tools-130222/multipathd/cli_handlers.h
+@@ -1,9 +1,11 @@
+ int cli_list_paths (void * v, char ** reply, int * len, void * data);
+ int cli_list_paths_fmt (void * v, char ** reply, int * len, void * data);
++int cli_list_paths_raw (void * v, char ** reply, int * len, void * data);
+ int cli_list_status (void * v, char ** reply, int * len, void * data);
+ int cli_list_daemon (void * v, char ** reply, int * len, void * data);
+ int cli_list_maps (void * v, char ** reply, int * len, void * data);
+ int cli_list_maps_fmt (void * v, char ** reply, int * len, void * data);
++int cli_list_maps_raw (void * v, char ** reply, int * len, void * data);
+ int cli_list_maps_status (void * v, char ** reply, int * len, void * data);
+ int cli_list_maps_stats (void * v, char ** reply, int * len, void * data);
+ int cli_list_map_topology (void * v, char ** reply, int * len, void * data);
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -967,12 +967,14 @@ uxlsnrloop (void * ap)
+
+ set_handler_callback(LIST+PATHS, cli_list_paths);
+ set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt);
++ set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw);
+ set_handler_callback(LIST+MAPS, cli_list_maps);
+ set_handler_callback(LIST+STATUS, cli_list_status);
+ set_handler_callback(LIST+DAEMON, cli_list_daemon);
+ set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status);
+ set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats);
+ set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt);
++ set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
+ set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
+ set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
+ set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
diff --git a/0147-RHBZ-1272620-fail-rm-msg.patch b/0147-RHBZ-1272620-fail-rm-msg.patch
new file mode 100644
index 0000000..b48ed6b
--- /dev/null
+++ b/0147-RHBZ-1272620-fail-rm-msg.patch
@@ -0,0 +1,60 @@
+---
+ multipathd/cli_handlers.c | 8 ++++----
+ multipathd/main.c | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -459,7 +459,7 @@ cli_del_path (void * v, char ** reply, i
+ pp = find_path_by_dev(vecs->pathvec, param);
+ if (!pp) {
+ condlog(0, "%s: path already removed", param);
+- return 0;
++ return 1;
+ }
+ return ev_remove_path(pp, vecs);
+ }
+@@ -520,19 +520,19 @@ cli_del_map (void * v, char ** reply, in
+ minor = dm_get_minor(param);
+ if (minor < 0) {
+ condlog(2, "%s: not a device mapper table", param);
+- return 0;
++ return 1;
+ }
+ major = dm_get_major(param);
+ if (major < 0) {
+ condlog(2, "%s: not a device mapper table", param);
+- return 0;
++ return 1;
+ }
+ sprintf(dev_path,"dm-%d", minor);
+ alias = dm_mapname(major, minor);
+ if (!alias) {
+ condlog(2, "%s: mapname not found for %d:%d",
+ param, major, minor);
+- return 0;
++ return 1;
+ }
+ rc = ev_remove_map(param, alias, minor, vecs);
+ FREE(alias);
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -437,12 +437,12 @@ ev_remove_map (char * devname, char * al
+ if (!mpp) {
+ condlog(2, "%s: devmap not registered, can't remove",
+ devname);
+- return 0;
++ return 1;
+ }
+ if (strcmp(mpp->alias, alias)) {
+ condlog(2, "%s: minor number mismatch (map %d, event %d)",
+ mpp->alias, mpp->dmi->minor, minor);
+- return 0;
++ return 1;
+ }
+ return flush_map(mpp, vecs, 0);
+ }
diff --git a/0148-RHBZ-1292599-verify-before-remove.patch b/0148-RHBZ-1292599-verify-before-remove.patch
new file mode 100644
index 0000000..3e33b89
--- /dev/null
+++ b/0148-RHBZ-1292599-verify-before-remove.patch
@@ -0,0 +1,142 @@
+---
+ libmultipath/devmapper.c | 45 +++++++++++++++++++++++++++++++++++++--------
+ libmultipath/devmapper.h | 2 +-
+ 2 files changed, 38 insertions(+), 9 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -33,6 +33,9 @@
+ #define UUID_PREFIX_LEN 6
+
+ static int dm_cancel_remove_partmaps(const char * mapname);
++static int do_foreach_partmaps (const char * mapname,
++ int (*partmap_func)(const char *, void *),
++ void *data);
+
+ #ifndef LIBDM_API_COOKIE
+ static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
+@@ -709,6 +712,26 @@ out:
+ return r;
+ }
+
++static int
++partmap_in_use(const char *name, void *data)
++{
++ int part_count, *ret_count = (int *)data;
++ int open_count = dm_get_opencount(name);
++
++ if (ret_count)
++ (*ret_count)++;
++ part_count = 0;
++ if (open_count) {
++ if (do_foreach_partmaps(name, partmap_in_use, &part_count))
++ return 1;
++ if (open_count != part_count) {
++ condlog(2, "%s: map in use", name);
++ return 1;
++ }
++ }
++ return 0;
++}
++
+ extern int
+ _dm_flush_map (const char * mapname, int need_sync, int deferred_remove)
+ {
+@@ -717,6 +740,11 @@ _dm_flush_map (const char * mapname, int
+ if (!dm_is_mpath(mapname))
+ return 0; /* nothing to do */
+
++ /* If you aren't doing a deferred remove, make sure that no
++ * devices are in use */
++ if (!do_deferred(deferred_remove) && partmap_in_use(mapname, NULL))
++ return 1;
++
+ if (dm_remove_partmaps(mapname, need_sync, deferred_remove))
+ return 1;
+
+@@ -825,7 +853,7 @@ dm_flush_maps (void)
+ }
+
+ int
+-dm_message(char * mapname, char * message)
++dm_message(const char * mapname, char * message)
+ {
+ int r = 1;
+ struct dm_task *dmt;
+@@ -1076,7 +1104,8 @@ bad:
+ }
+
+ static int
+-do_foreach_partmaps (const char * mapname, int (*partmap_func)(char *, void *),
++do_foreach_partmaps (const char * mapname,
++ int (*partmap_func)(const char *, void *),
+ void *data)
+ {
+ struct dm_task *dmt;
+@@ -1149,7 +1178,7 @@ struct remove_data {
+ };
+
+ static int
+-remove_partmap(char *name, void *data)
++remove_partmap(const char *name, void *data)
+ {
+ struct remove_data *rd = (struct remove_data *)data;
+
+@@ -1176,7 +1205,7 @@ dm_remove_partmaps (const char * mapname
+ #ifdef LIBDM_API_DEFERRED
+
+ static int
+-cancel_remove_partmap (char *name, void *unused)
++cancel_remove_partmap (const char *name, void *unused)
+ {
+ if (dm_get_opencount(name))
+ dm_cancel_remove_partmaps(name);
+@@ -1296,13 +1325,13 @@ out:
+ }
+
+ struct rename_data {
+- char *old;
++ const char *old;
+ char *new;
+ char *delim;
+ };
+
+ static int
+-rename_partmap (char *name, void *data)
++rename_partmap (const char *name, void *data)
+ {
+ char buff[PARAMS_SIZE];
+ int offset;
+@@ -1319,7 +1348,7 @@ rename_partmap (char *name, void *data)
+ }
+
+ int
+-dm_rename_partmaps (char * old, char * new)
++dm_rename_partmaps (const char * old, char * new)
+ {
+ struct rename_data rd;
+
+@@ -1333,7 +1362,7 @@ dm_rename_partmaps (char * old, char * n
+ }
+
+ int
+-dm_rename (char * old, char * new)
++dm_rename (const char * old, char * new)
+ {
+ int r = 0;
+ struct dm_task *dmt;
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -47,7 +47,7 @@ int dm_remove_partmaps (const char * map
+ int deferred_remove);
+ int dm_get_uuid(char *name, char *uuid);
+ int dm_get_info (char * mapname, struct dm_info ** dmi);
+-int dm_rename (char * old, char * new);
++int dm_rename (const char * old, char * new);
+ int dm_reassign(const char * mapname);
+ int dm_reassign_table(const char *name, char *old, char *new);
+ int dm_setgeometry(struct multipath *mpp);
diff --git a/0149-RHBZ-1292599-restore-removed-parts.patch b/0149-RHBZ-1292599-restore-removed-parts.patch
new file mode 100644
index 0000000..62757c4
--- /dev/null
+++ b/0149-RHBZ-1292599-restore-removed-parts.patch
@@ -0,0 +1,82 @@
+---
+ libmultipath/configure.c | 8 ++++++--
+ libmultipath/structs.h | 1 +
+ multipathd/main.c | 1 +
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -398,6 +398,7 @@ select_action (struct multipath * mpp, v
+ cmpp->alias, mpp->alias);
+ strncpy(mpp->alias_old, cmpp->alias, WWID_SIZE);
+ mpp->action = ACT_RENAME;
++ mpp->force_udev_reload = force_reload;
+ if (force_reload)
+ mpp->action = ACT_RENAME2;
+ return;
+@@ -437,11 +438,13 @@ select_action (struct multipath * mpp, v
+ return;
+ }
+ if (force_reload) {
++ mpp->force_udev_reload = 1;
+ mpp->action = ACT_RELOAD;
+ condlog(3, "%s: set ACT_RELOAD (forced by user)",
+ mpp->alias);
+ return;
+ }
++ mpp->force_udev_reload = !pathcount(mpp, PATH_WILD);
+ if (cmpp->size != mpp->size) {
+ mpp->action = ACT_RESIZE;
+ condlog(3, "%s: set ACT_RESIZE (size change)",
+@@ -651,7 +654,7 @@ domap (struct multipath * mpp, char * pa
+ case ACT_RELOAD:
+ r = dm_addmap_reload(mpp, params);
+ if (r)
+- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
+ break;
+
+ case ACT_RESIZE:
+@@ -669,7 +672,7 @@ domap (struct multipath * mpp, char * pa
+ if (r) {
+ r = dm_addmap_reload(mpp, params);
+ if (r)
+- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, MPATH_UDEV_RELOAD_FLAG);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
+ }
+ break;
+
+@@ -682,6 +685,7 @@ domap (struct multipath * mpp, char * pa
+ * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
+ * succeeded
+ */
++ mpp->force_udev_reload = 0;
+ if (mpp->action == ACT_CREATE) {
+ if (remember_wwid(mpp->wwid) == 1)
+ trigger_uevents(mpp);
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -234,6 +234,7 @@ struct multipath {
+ int deferred_remove;
+ int delay_watch_checks;
+ int delay_wait_checks;
++ int force_udev_reload;
+ unsigned int dev_loss;
+ uid_t uid;
+ gid_t gid;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -554,6 +554,7 @@ rescan:
+
+ condlog(4,"%s: adopting all paths for path %s",
+ mpp->alias, pp->dev);
++ mpp->force_udev_reload = !pathcount(mpp, PATH_WILD);
+ if (adopt_paths(vecs->pathvec, mpp, 1))
+ goto fail; /* leave path added to pathvec */
+
diff --git a/0150-RHBZ-1253913-fix-startup-msg.patch b/0150-RHBZ-1253913-fix-startup-msg.patch
new file mode 100644
index 0000000..ca661e8
--- /dev/null
+++ b/0150-RHBZ-1253913-fix-startup-msg.patch
@@ -0,0 +1,128 @@
+---
+ multipathd/main.c | 38 +++++++++++++++++++++++++++++---------
+ 1 file changed, 29 insertions(+), 9 deletions(-)
+
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -87,6 +87,7 @@ unsigned int mpath_mx_alloc_len;
+ int logsink;
+ enum daemon_status running_state;
+ pid_t daemon_pid;
++pid_t parent_pid = -1;
+
+ static sem_t exit_sem;
+ /*
+@@ -1704,6 +1705,12 @@ sigusr2 (int sig)
+ }
+
+ static void
++sigalrm (int sig)
++{
++ exit(0);
++}
++
++static void
+ signal_init(void)
+ {
+ sigset_t set;
+@@ -1806,6 +1813,9 @@ child (void * param)
+ }
+
+ running_state = DAEMON_START;
++ pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
++ if (parent_pid > 0)
++ kill(parent_pid, SIGALRM);
+
+ condlog(2, "--------start up--------");
+ condlog(2, "read " DEFAULT_CONFIGFILE);
+@@ -1897,8 +1907,6 @@ child (void * param)
+ }
+ pthread_attr_destroy(&misc_attr);
+
+- /* Startup complete, create logfile */
+- pid_rc = pidfile_create(DEFAULT_PIDFILE, daemon_pid);
+ update_timestamp(1);
+ /* Ignore errors, we can live without */
+
+@@ -1978,7 +1986,10 @@ daemonize(void)
+ {
+ int pid;
+ int dev_null_fd;
++ struct sigaction oldsig;
+
++ oldsig.sa_handler = signal_set(SIGALRM, sigalrm);
++ parent_pid = getpid();
+ if( (pid = fork()) < 0){
+ fprintf(stderr, "Failed first fork : %s\n", strerror(errno));
+ return -1;
+@@ -1986,10 +1997,13 @@ daemonize(void)
+ else if (pid != 0)
+ return pid;
+
++ signal_set(SIGALRM, oldsig.sa_handler);
+ setsid();
+
+- if ( (pid = fork()) < 0)
++ if ( (pid = fork()) < 0) {
+ fprintf(stderr, "Failed second fork : %s\n", strerror(errno));
++ goto fail;
++ }
+ else if (pid != 0)
+ _exit(0);
+
+@@ -2000,30 +2014,34 @@ daemonize(void)
+ if (dev_null_fd < 0){
+ fprintf(stderr, "cannot open /dev/null for input & output : %s\n",
+ strerror(errno));
+- _exit(0);
++ goto fail;
+ }
+
+ close(STDIN_FILENO);
+ if (dup(dev_null_fd) < 0) {
+ fprintf(stderr, "cannot dup /dev/null to stdin : %s\n",
+ strerror(errno));
+- _exit(0);
++ goto fail;
+ }
+ close(STDOUT_FILENO);
+ if (dup(dev_null_fd) < 0) {
+ fprintf(stderr, "cannot dup /dev/null to stdout : %s\n",
+ strerror(errno));
+- _exit(0);
++ goto fail;
+ }
+ close(STDERR_FILENO);
+ if (dup(dev_null_fd) < 0) {
+ fprintf(stderr, "cannot dup /dev/null to stderr : %s\n",
+ strerror(errno));
+- _exit(0);
++ goto fail;
+ }
+ close(dev_null_fd);
+ daemon_pid = getpid();
+ return 0;
++
++fail:
++ kill(parent_pid, SIGALRM);
++ _exit(0);
+ }
+
+ int
+@@ -2102,10 +2120,12 @@ main (int argc, char *argv[])
+ if (err < 0)
+ /* error */
+ exit(1);
+- else if (err > 0)
++ else if (err > 0) {
++ /* wait up to 3 seconds for the child to start */
++ sleep(3);
+ /* parent dies */
+ exit(0);
+- else
++ } else
+ /* child lives */
+ return (child(NULL));
+ }
diff --git a/0151-RHBZ-1297456-weighted-fix.patch b/0151-RHBZ-1297456-weighted-fix.patch
new file mode 100644
index 0000000..57b2fed
--- /dev/null
+++ b/0151-RHBZ-1297456-weighted-fix.patch
@@ -0,0 +1,156 @@
+---
+ libmultipath/print.c | 8 +++---
+ libmultipath/print.h | 4 +++
+ libmultipath/prioritizers/weightedpath.c | 37 +++++++++++++++++++++++++++++++
+ libmultipath/prioritizers/weightedpath.h | 1
+ multipath/multipath.conf.5 | 8 +++++-
+ 5 files changed, 53 insertions(+), 5 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/print.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.c
++++ multipath-tools-130222/libmultipath/print.c
+@@ -468,19 +468,19 @@ out:
+ return ret;
+ }
+
+-static int
++int
+ snprint_host_wwnn (char * buff, size_t len, struct path * pp)
+ {
+ return snprint_host_attr(buff, len, pp, "node_name");
+ }
+
+-static int
++int
+ snprint_host_wwpn (char * buff, size_t len, struct path * pp)
+ {
+ return snprint_host_attr(buff, len, pp, "port_name");
+ }
+
+-static int
++int
+ snprint_tgt_wwpn (char * buff, size_t len, struct path * pp)
+ {
+ struct udev_device *rport_dev = NULL;
+@@ -510,7 +510,7 @@ out:
+ }
+
+
+-static int
++int
+ snprint_tgt_wwnn (char * buff, size_t len, struct path * pp)
+ {
+ if (pp->tgt_node_name[0] == '\0')
+Index: multipath-tools-130222/libmultipath/print.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/print.h
++++ multipath-tools-130222/libmultipath/print.h
+@@ -50,6 +50,10 @@ int snprint_status (char *, int, struct
+ int snprint_devices (char *, int, struct vectors *);
+ int snprint_hwtable (char *, int, vector);
+ int snprint_mptable (char *, int, vector);
++int snprint_host_wwnn (char *, size_t, struct path *);
++int snprint_host_wwpn (char *, size_t, struct path *);
++int snprint_tgt_wwnn (char *, size_t, struct path *);
++int snprint_tgt_wwpn (char *, size_t, struct path *);
+
+ void print_multipath_topology (struct multipath * mpp, int verbosity);
+ void print_path (struct path * pp, char * style);
+Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c
++++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c
+@@ -32,6 +32,8 @@
+ #include <memory.h>
+ #include <debug.h>
+ #include <regex.h>
++#include <structs_vec.h>
++#include <print.h>
+ #include "def_func.h"
+
+ char *get_next_string(char **temp, char *split_char)
+@@ -43,6 +45,36 @@ char *get_next_string(char **temp, char
+ return token;
+ }
+
++#define CHECK_LEN \
++do { \
++ if ((p - str) >= (len - 1)) { \
++ condlog(0, "%s: %s - buffer size too small", pp->dev, pp->prio.name); \
++ return -1; \
++ } \
++} while(0)
++
++static int
++build_wwn_path(struct path *pp, char *str, int len)
++{
++ char *p = str;
++
++ p += snprint_host_wwnn(p, str + len - p, pp);
++ CHECK_LEN;
++ p += snprintf(p, str + len - p, ":");
++ CHECK_LEN;
++ p += snprint_host_wwpn(p, str + len - p, pp);
++ CHECK_LEN;
++ p += snprintf(p, str + len - p, ":");
++ CHECK_LEN;
++ p += snprint_tgt_wwnn(p, str + len - p, pp);
++ CHECK_LEN;
++ p += snprintf(p, str + len - p, ":");
++ CHECK_LEN;
++ p += snprint_tgt_wwpn(p, str + len - p, pp);
++ CHECK_LEN;
++ return 0;
++}
++
+ /* main priority routine */
+ int prio_path_weight(struct path *pp, char *prio_args)
+ {
+@@ -72,6 +104,11 @@ int prio_path_weight(struct path *pp, ch
+ pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
+ } else if (!strcmp(regex, DEV_NAME)) {
+ strcpy(path, pp->dev);
++ } else if (!strcmp(regex, WWN)) {
++ if (build_wwn_path(pp, path, FILE_NAME_SIZE) != 0) {
++ FREE(arg);
++ return priority;
++ }
+ } else {
+ condlog(0, "%s: %s - Invalid arguments", pp->dev,
+ pp->prio.name);
+Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.h
++++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.h
+@@ -4,6 +4,7 @@
+ #define PRIO_WEIGHTED_PATH "weightedpath"
+ #define HBTL "hbtl"
+ #define DEV_NAME "devname"
++#define WWN "wwn"
+ #define DEFAULT_PRIORITY 0
+
+ int prio_path_weight(struct path *pp, char *prio_args);
+Index: multipath-tools-130222/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.conf.5
++++ multipath-tools-130222/multipath/multipath.conf.5
+@@ -216,11 +216,17 @@ prioritizers
+ .TP 12
+ .B weighted
+ Needs a value of the form
+-.I "<hbtl|devname> <regex1> <prio1> <regex2> <prio2> ..."
++.I "<hbtl|devname|wwn> <regex1> <prio1> <regex2> <prio2> ..."
+ .I hbtl
+ regex can be of SCSI H:B:T:L format Ex: 1:0:.:. , *:0:0:.
+ .I devname
+ regex can be of device name format Ex: sda , sd.e
++.I wwn
++regex can be of the form
++.I "host_wwnn:host_wwpn:target_wwnn:target_wwpn"
++these values can be looked up through sysfs or by running
++.I mulitpathd show paths format "%N:%R:%n:%r"
++Ex: 0x200100e08ba0aea0:0x210100e08ba0aea0:.*:.* , .*:.*:iqn.2009-10.com.redhat.msp.lab.ask-06:.*
+ .TP
+ .B alua
+ If
diff --git a/0152-RHBZ-1269293-fix-blk-unit-file.patch b/0152-RHBZ-1269293-fix-blk-unit-file.patch
new file mode 100644
index 0000000..cadc3f3
--- /dev/null
+++ b/0152-RHBZ-1269293-fix-blk-unit-file.patch
@@ -0,0 +1,16 @@
+---
+ multipathd/multipathd.service | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-130222/multipathd/multipathd.service
+===================================================================
+--- multipath-tools-130222.orig/multipathd/multipathd.service
++++ multipath-tools-130222/multipathd/multipathd.service
+@@ -1,6 +1,6 @@
+ [Unit]
+ Description=Device-Mapper Multipath Device Controller
+-Requires=blk-availability.service
++Wants=blk-availability.service
+ Before=iscsi.service iscsid.service lvm2-activation-early.service
+ After=syslog.target
+ ConditionPathExists=/etc/multipath.conf
diff --git a/0153-RH-fix-i686-size-bug.patch b/0153-RH-fix-i686-size-bug.patch
new file mode 100644
index 0000000..325ec9d
--- /dev/null
+++ b/0153-RH-fix-i686-size-bug.patch
@@ -0,0 +1,156 @@
+---
+ multipathd/cli.c | 22 +++++++++++-----------
+ multipathd/cli.h | 20 +++++++++++---------
+ 2 files changed, 22 insertions(+), 20 deletions(-)
+
+Index: multipath-tools-130222/multipathd/cli.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.c
++++ multipath-tools-130222/multipathd/cli.c
+@@ -26,7 +26,7 @@ alloc_handler (void)
+ }
+
+ static int
+-add_key (vector vec, char * str, unsigned long code, int has_param)
++add_key (vector vec, char * str, uint64_t code, int has_param)
+ {
+ struct key * kw;
+
+@@ -57,7 +57,7 @@ out:
+ }
+
+ int
+-add_handler (unsigned long fp, int (*fn)(void *, char **, int *, void *))
++add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *))
+ {
+ struct handler * h;
+
+@@ -79,7 +79,7 @@ add_handler (unsigned long fp, int (*fn)
+ }
+
+ static struct handler *
+-find_handler (unsigned long fp)
++find_handler (uint64_t fp)
+ {
+ int i;
+ struct handler *h;
+@@ -92,7 +92,7 @@ find_handler (unsigned long fp)
+ }
+
+ int
+-set_handler_callback (unsigned long fp, int (*fn)(void *, char **, int *, void *))
++set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *))
+ {
+ struct handler * h = find_handler(fp);
+
+@@ -293,11 +293,11 @@ out:
+ return r;
+ }
+
+-static unsigned long
++static uint64_t
+ fingerprint(vector vec)
+ {
+ int i;
+- unsigned long fp = 0;
++ uint64_t fp = 0;
+ struct key * kw;
+
+ if (!vec)
+@@ -343,7 +343,7 @@ static int
+ do_genhelp(char *reply, int maxlen) {
+ int len = 0;
+ int i, j;
+- unsigned long fp;
++ uint64_t fp;
+ struct handler * h;
+ struct key * kw;
+
+@@ -442,7 +442,7 @@ parse_cmd (char * cmd, char ** reply, in
+ }
+
+ char *
+-get_keyparam (vector v, unsigned long code)
++get_keyparam (vector v, uint64_t code)
+ {
+ struct key * kw;
+ int i;
+@@ -515,7 +515,7 @@ void cli_exit(void)
+ }
+
+ static int
+-key_match_fingerprint (struct key * kw, unsigned long fp)
++key_match_fingerprint (struct key * kw, uint64_t fp)
+ {
+ if (!fp)
+ return 0;
+@@ -530,7 +530,7 @@ char *
+ key_generator (const char * str, int state)
+ {
+ static int index, len, has_param;
+- static unsigned long rlfp;
++ static uint64_t rlfp;
+ struct key * kw;
+ int i;
+ struct handler *h;
+@@ -600,7 +600,7 @@ key_generator (const char * str, int sta
+ * nfp is the candidate fingerprint we try to
+ * validate against all known command fingerprints.
+ */
+- unsigned long nfp = rlfp | kw->code;
++ uint64_t nfp = rlfp | kw->code;
+ vector_foreach_slot(handlers, h, i) {
+ if (!rlfp || ((h->fingerprint & nfp) == nfp)) {
+ /*
+Index: multipath-tools-130222/multipathd/cli.h
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli.h
++++ multipath-tools-130222/multipathd/cli.h
+@@ -1,3 +1,5 @@
++#include <stdint.h>
++
+ enum {
+ __LIST,
+ __ADD,
+@@ -68,10 +70,10 @@ enum {
+ #define WILDCARDS (1 << __WILDCARDS)
+ #define QUIT (1 << __QUIT)
+ #define SHUTDOWN (1 << __SHUTDOWN)
+-#define GETPRSTATUS (1UL << __GETPRSTATUS)
+-#define SETPRSTATUS (1UL << __SETPRSTATUS)
+-#define UNSETPRSTATUS (1UL << __UNSETPRSTATUS)
+-#define FMT (1UL << __FMT)
++#define GETPRSTATUS (1ULL << __GETPRSTATUS)
++#define SETPRSTATUS (1ULL << __SETPRSTATUS)
++#define UNSETPRSTATUS (1ULL << __UNSETPRSTATUS)
++#define FMT (1ULL << __FMT)
+
+ #define INITIAL_REPLY_LEN 1200
+
+@@ -92,21 +94,21 @@ enum {
+ struct key {
+ char * str;
+ char * param;
+- unsigned long code;
++ uint64_t code;
+ int has_param;
+ };
+
+ struct handler {
+- unsigned long fingerprint;
++ uint64_t fingerprint;
+ int (*fn)(void *, char **, int *, void *);
+ };
+
+ int alloc_handlers (void);
+-int add_handler (unsigned long fp, int (*fn)(void *, char **, int *, void *));
+-int set_handler_callback (unsigned long fp, int (*fn)(void *, char **, int *, void *));
++int add_handler (uint64_t fp, int (*fn)(void *, char **, int *, void *));
++int set_handler_callback (uint64_t fp, int (*fn)(void *, char **, int *, void *));
+ int parse_cmd (char * cmd, char ** reply, int * len, void *);
+ int load_keys (void);
+-char * get_keyparam (vector v, unsigned long code);
++char * get_keyparam (vector v, uint64_t code);
+ void free_keys (vector vec);
+ void free_handlers (void);
+ int cli_init (void);
diff --git a/0154-UPBZ-1291406-disable-reinstate.patch b/0154-UPBZ-1291406-disable-reinstate.patch
new file mode 100644
index 0000000..a652e5c
--- /dev/null
+++ b/0154-UPBZ-1291406-disable-reinstate.patch
@@ -0,0 +1,154 @@
+---
+ libmultipath/propsel.c | 20 ++++++++++++++++----
+ libmultipath/structs.h | 1 +
+ multipathd/main.c | 37 ++++++++++++++++++++++++++-----------
+ 3 files changed, 43 insertions(+), 15 deletions(-)
+
+Index: multipath-tools-130222/libmultipath/propsel.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/propsel.c
++++ multipath-tools-130222/libmultipath/propsel.c
+@@ -398,9 +398,11 @@ detect_prio(struct path * pp)
+ {
+ int ret;
+ struct prio *p = &pp->prio;
++ int tpgs = 0;
+
+- if (get_target_port_group_support(pp->fd) <= 0)
++ if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
+ return;
++ pp->tpgs = tpgs;
+ ret = get_target_port_group(pp->fd, NULL);
+ if (ret < 0)
+ return;
+@@ -432,7 +434,7 @@ select_prio (struct path * pp)
+ pp->dev, prio_name(p));
+ condlog(3, "%s: prio args = %s (LUN setting)",
+ pp->dev, prio_args(p));
+- return 0;
++ goto out;
+ }
+
+ if (pp->hwe && pp->hwe->prio_name) {
+@@ -441,7 +443,7 @@ select_prio (struct path * pp)
+ pp->dev, pp->hwe->prio_name);
+ condlog(3, "%s: prio args = %s (controller setting)",
+ pp->dev, pp->hwe->prio_args);
+- return 0;
++ goto out;
+ }
+ if (conf->prio_name) {
+ prio_get(p, conf->prio_name, conf->prio_args);
+@@ -449,13 +451,23 @@ select_prio (struct path * pp)
+ pp->dev, conf->prio_name);
+ condlog(3, "%s: prio args = %s (config file default)",
+ pp->dev, conf->prio_args);
+- return 0;
++ goto out;
+ }
+ prio_get(p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
+ condlog(3, "%s: prio = %s (internal default)",
+ pp->dev, DEFAULT_PRIO);
+ condlog(3, "%s: prio args = %s (internal default)",
+ pp->dev, DEFAULT_PRIO_ARGS);
++out:
++ /*
++ * fetch tpgs mode for alua
++ */
++ if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
++ int tpgs = 0;
++ if (!pp->tpgs &&
++ (tpgs = get_target_port_group_support(pp->fd)) >= 0)
++ pp->tpgs = tpgs;
++ }
+ return 0;
+ }
+
+Index: multipath-tools-130222/libmultipath/structs.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/structs.h
++++ multipath-tools-130222/libmultipath/structs.h
+@@ -193,6 +193,7 @@ struct path {
+ int detect_prio;
+ int watch_checks;
+ int wait_checks;
++ int tpgs;
+ char * uid_attribute;
+ struct prio prio;
+ char * prio_args;
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -19,6 +19,7 @@
+ #include <libudev.h>
+ #include <semaphore.h>
+ #include <mpath_persist.h>
++#include "prioritizers/alua_rtpg.h"
+
+ /*
+ * libcheckers
+@@ -1235,6 +1236,7 @@ check_path (struct vectors * vecs, struc
+ int newstate;
+ int new_path_up = 0;
+ int chkr_new_path_up = 0;
++ int disable_reinstate = 0;
+ int oldchkrstate = pp->chkrstate;
+
+ if (!pp->mpp && (pp->missing_udev_info != INFO_MISSING ||
+@@ -1299,6 +1301,16 @@ check_path (struct vectors * vecs, struc
+ pp->wait_checks = 0;
+ }
+
++ /*
++ * don't reinstate failed path, if its in stand-by
++ * and if target supports only implicit tpgs mode.
++ * this will prevent unnecessary i/o by dm on stand-by
++ * paths if there are no other active paths in map.
++ */
++ disable_reinstate = (newstate == PATH_GHOST &&
++ pp->mpp->nr_active == 0 &&
++ pp->tpgs == TPGS_IMPLICIT) ? 1 : 0;
++
+ pp->chkrstate = newstate;
+ if (newstate != pp->state) {
+ int oldstate = pp->state;
+@@ -1354,15 +1366,17 @@ check_path (struct vectors * vecs, struc
+ /*
+ * reinstate this path
+ */
+- if (oldstate != PATH_UP &&
+- oldstate != PATH_GHOST) {
+- if (pp->mpp->delay_watch_checks > 0)
+- pp->watch_checks = pp->mpp->delay_watch_checks;
+- reinstate_path(pp, 1);
+- } else {
+- if (pp->watch_checks > 0)
+- pp->watch_checks--;
+- reinstate_path(pp, 0);
++ if (!disable_reinstate) {
++ if (oldstate != PATH_UP &&
++ oldstate != PATH_GHOST) {
++ if (pp->mpp->delay_watch_checks > 0)
++ pp->watch_checks = pp->mpp->delay_watch_checks;
++ reinstate_path(pp, 1);
++ } else {
++ if (pp->watch_checks > 0)
++ pp->watch_checks--;
++ reinstate_path(pp, 0);
++ }
+ }
+ new_path_up = 1;
+
+@@ -1377,8 +1391,9 @@ check_path (struct vectors * vecs, struc
+ enable_group(pp);
+ }
+ else if (newstate == PATH_UP || newstate == PATH_GHOST) {
+- if (pp->dmstate == PSTATE_FAILED ||
+- pp->dmstate == PSTATE_UNDEF) {
++ if ((pp->dmstate == PSTATE_FAILED ||
++ pp->dmstate == PSTATE_UNDEF) &&
++ !disable_reinstate) {
+ /* Clear IO errors */
+ reinstate_path(pp, 0);
+ } else {
diff --git a/0155-UPBZ-1300415-PURE-config.patch b/0155-UPBZ-1300415-PURE-config.patch
new file mode 100644
index 0000000..e2bb0e1
--- /dev/null
+++ b/0155-UPBZ-1300415-PURE-config.patch
@@ -0,0 +1,54 @@
+---
+ libmultipath/hwtable.c | 16 ++++++++++++++++
+ multipath.conf.defaults | 11 +++++++++++
+ 2 files changed, 27 insertions(+)
+
+Index: multipath-tools-130222/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/hwtable.c
++++ multipath-tools-130222/libmultipath/hwtable.c
+@@ -1166,6 +1166,22 @@ static struct hwentry default_hw[] = {
+ .prio_name = DEFAULT_PRIO,
+ .prio_args = NULL,
+ },
++ {
++ .vendor = "PURE",
++ .product = "FlashArray",
++ .features = DEFAULT_FEATURES,
++ .hwhandler = DEFAULT_HWHANDLER,
++ .selector = "queue-length 0",
++ .pgpolicy = MULTIBUS,
++ .pgfailback = -FAILBACK_IMMEDIATE,
++ .checker_name = TUR,
++ .fast_io_fail = 10,
++ .user_friendly_names = USER_FRIENDLY_NAMES_OFF,
++ .prio_name = DEFAULT_PRIO,
++ .no_path_retry = 0,
++ .dev_loss = 60,
++ .prio_args = NULL,
++ },
+ /*
+ * EOL
+ */
+Index: multipath-tools-130222/multipath.conf.defaults
+===================================================================
+--- multipath-tools-130222.orig/multipath.conf.defaults
++++ multipath-tools-130222/multipath.conf.defaults
+@@ -962,6 +962,17 @@
+ # failback immediate
+ # fast_io_fail_tmo 15
+ # }
++# device {
++# vendor "PURE"
++# path_selector "queue-length 0"
++# path_grouping_policy "multibus"
++# path_checker "tur"
++# fast_io_fail_tmo 10
++# user_friendly_names "no"
++# no_path_retry 0
++# features 0
++# dev_loss_tmo 60
++# }
+ #}
+ #multipaths {
+ #}
diff --git a/0156-UPBZ-1313324-dont-fail-discovery.patch b/0156-UPBZ-1313324-dont-fail-discovery.patch
new file mode 100644
index 0000000..36262f7
--- /dev/null
+++ b/0156-UPBZ-1313324-dont-fail-discovery.patch
@@ -0,0 +1,236 @@
+---
+ libmpathpersist/mpath_persist.c | 14 ++++++------
+ libmultipath/discovery.c | 46 ++++++++++++++++++++--------------------
+ libmultipath/discovery.h | 4 +++
+ multipath/main.c | 2 -
+ multipathd/main.c | 6 +++--
+ 5 files changed, 39 insertions(+), 33 deletions(-)
+
+Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
+===================================================================
+--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
++++ multipath-tools-130222/libmpathpersist/mpath_persist.c
+@@ -178,7 +178,7 @@ int mpath_persistent_reserve_in (int fd,
+ goto out;
+ }
+
+- if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER)) {
++ if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER) < 0) {
+ ret = MPATH_PR_DMMP_ERROR;
+ goto out1;
+ }
+@@ -262,13 +262,13 @@ int mpath_persistent_reserve_out ( int f
+ curmp = vector_alloc ();
+ pathvec = vector_alloc ();
+
+- if (!curmp || !pathvec){
+- condlog (0, "%s: vector allocation failed.", alias);
+- ret = MPATH_PR_DMMP_ERROR;
+- goto out;
+- }
++ if (!curmp || !pathvec){
++ condlog (0, "%s: vector allocation failed.", alias);
++ ret = MPATH_PR_DMMP_ERROR;
++ goto out;
++ }
+
+- if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER)) {
++ if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER) < 0) {
+ ret = MPATH_PR_DMMP_ERROR;
+ goto out1;
+ }
+Index: multipath-tools-130222/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.c
++++ multipath-tools-130222/libmultipath/discovery.c
+@@ -32,7 +32,7 @@ int
+ store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
+ int flag, struct path **pp_ptr)
+ {
+- int err = 1;
++ int err = PATHINFO_FAILED;
+ struct path * pp;
+ const char * devname;
+
+@@ -41,12 +41,12 @@ store_pathinfo (vector pathvec, vector h
+
+ devname = udev_device_get_sysname(udevice);
+ if (!devname)
+- return 1;
++ return PATHINFO_FAILED;
+
+ pp = alloc_path();
+
+ if (!pp)
+- return 1;
++ return PATHINFO_FAILED;
+
+ if(safe_sprintf(pp->dev, "%s", devname)) {
+ condlog(0, "pp->dev too small");
+@@ -80,19 +80,16 @@ path_discover (vector pathvec, struct co
+
+ devname = udev_device_get_sysname(udevice);
+ if (!devname)
+- return 0;
++ return PATHINFO_FAILED;
+
+ if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
+ (char *)devname) > 0)
+- return 0;
++ return PATHINFO_SKIPPED;
+
+ pp = find_path_by_dev(pathvec, (char *)devname);
+ if (!pp) {
+- if (store_pathinfo(pathvec, conf->hwtable,
+- udevice, flag, NULL) != 1)
+- return 0;
+- else
+- return 1;
++ return store_pathinfo(pathvec, conf->hwtable,
++ udevice, flag, NULL);
+ }
+ return pathinfo(pp, conf->hwtable, flag);
+ }
+@@ -104,11 +101,11 @@ path_discovery (vector pathvec, struct c
+ struct udev_list_entry *entry;
+ struct udev_device *udevice;
+ const char *devpath;
+- int r = 0;
++ int num_paths = 0, total_paths = 0;
+
+ udev_iter = udev_enumerate_new(conf->udev);
+ if (!udev_iter)
+- return 1;
++ return -ENOMEM;
+
+ udev_enumerate_add_match_subsystem(udev_iter, "block");
+ udev_enumerate_scan_devices(udev_iter);
+@@ -121,17 +118,20 @@ path_discovery (vector pathvec, struct c
+ udevice = udev_device_new_from_syspath(conf->udev, devpath);
+ if (!udevice) {
+ condlog(4, "%s: no udev information", devpath);
+- r++;
+ continue;
+ }
+ devtype = udev_device_get_devtype(udevice);
+- if(devtype && !strncmp(devtype, "disk", 4))
+- r += path_discover(pathvec, conf, udevice, flag);
++ if(devtype && !strncmp(devtype, "disk", 4)) {
++ total_paths++;
++ if (path_discover(pathvec, conf,
++ udevice, flag) == PATHINFO_OK)
++ num_paths++;
++ }
+ udev_device_unref(udevice);
+ }
+ udev_enumerate_unref(udev_iter);
+- condlog(4, "Discovery status %d", r);
+- return r;
++ condlog(4, "Discovered %d/%d paths", num_paths, total_paths);
++ return (total_paths - num_paths);
+ }
+
+ #define declare_sysfs_get_str(fname) \
+@@ -1021,7 +1021,7 @@ get_state (struct path * pp, int daemon)
+
+ if (!checker_selected(c)) {
+ if (daemon) {
+- if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
++ if (pathinfo(pp, conf->hwtable, DI_SYSFS) != PATHINFO_OK) {
+ condlog(3, "%s: couldn't get sysfs pathinfo",
+ pp->dev);
+ return PATH_UNCHECKED;
+@@ -1140,7 +1140,7 @@ pathinfo (struct path *pp, vector hwtabl
+ int path_state;
+
+ if (!pp)
+- return 1;
++ return PATHINFO_FAILED;
+
+ condlog(3, "%s: mask = 0x%x", pp->dev, mask);
+
+@@ -1148,12 +1148,12 @@ pathinfo (struct path *pp, vector hwtabl
+ * fetch info available in sysfs
+ */
+ if (mask & DI_SYSFS && sysfs_pathinfo(pp))
+- return 1;
++ return PATHINFO_FAILED;
+
+ if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
+ if (filter_device(conf->blist_device, conf->elist_device,
+ pp->vendor_id, pp->product_id) > 0) {
+- return 2;
++ return PATHINFO_SKIPPED;
+ }
+ }
+
+@@ -1199,7 +1199,7 @@ pathinfo (struct path *pp, vector hwtabl
+ if (mask & DI_BLACKLIST && mask & DI_WWID) {
+ if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
+ pp->wwid) > 0) {
+- return 2;
++ return PATHINFO_SKIPPED;
+ }
+ }
+
+@@ -1213,7 +1213,7 @@ pathinfo (struct path *pp, vector hwtabl
+ }
+ }
+
+- return 0;
++ return PATHINFO_OK;
+
+ blank:
+ /*
+Index: multipath-tools-130222/libmultipath/discovery.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/discovery.h
++++ multipath-tools-130222/libmultipath/discovery.h
+@@ -24,6 +24,10 @@
+ #define SCSI_COMMAND_TERMINATED 0x22
+ #define SG_ERR_DRIVER_SENSE 0x08
+
++#define PATHINFO_OK 0
++#define PATHINFO_FAILED 1
++#define PATHINFO_SKIPPED 2
++
+ struct config;
+
+ int sysfs_get_dev (struct udev_device *udev, char * buff, size_t len);
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -343,7 +343,7 @@ configure (void)
+ /* maximum info */
+ di_flag = DI_ALL;
+
+- if (path_discovery(pathvec, conf, di_flag))
++ if (path_discovery(pathvec, conf, di_flag) < 0)
+ goto out;
+
+ if (conf->verbosity > 2)
+Index: multipath-tools-130222/multipathd/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/main.c
++++ multipath-tools-130222/multipathd/main.c
+@@ -1502,7 +1502,7 @@ configure (struct vectors * vecs, int st
+ struct multipath * mpp;
+ struct path * pp;
+ vector mpvec;
+- int i;
++ int i, ret;
+
+ if (!vecs->pathvec && !(vecs->pathvec = vector_alloc()))
+ return 1;
+@@ -1516,7 +1516,9 @@ configure (struct vectors * vecs, int st
+ /*
+ * probe for current path (from sysfs) and map (from dm) sets
+ */
+- path_discovery(vecs->pathvec, conf, DI_ALL);
++ ret = path_discovery(vecs->pathvec, conf, DI_ALL);
++ if (ret < 0)
++ return 1;
+
+ vector_foreach_slot (vecs->pathvec, pp, i){
+ if (filter_path(conf, pp) > 0){
diff --git a/0157-RHBZ-1319853-multipath-c-error-msg.patch b/0157-RHBZ-1319853-multipath-c-error-msg.patch
new file mode 100644
index 0000000..dbf47c7
--- /dev/null
+++ b/0157-RHBZ-1319853-multipath-c-error-msg.patch
@@ -0,0 +1,63 @@
+---
+ libmultipath/alias.c | 8 ++++++++
+ libmultipath/alias.h | 1 +
+ multipath/main.c | 7 ++++++-
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-130222/libmultipath/alias.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.c
++++ multipath-tools-130222/libmultipath/alias.c
+@@ -36,6 +36,14 @@
+ * See the file COPYING included with this distribution for more details.
+ */
+
++int
++valid_alias(char *alias)
++{
++ if (strchr(alias, '/') != NULL)
++ return 0;
++ return 1;
++}
++
+
+ static int
+ format_devname(char *name, int id, int len, char *prefix)
+Index: multipath-tools-130222/libmultipath/alias.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/alias.h
++++ multipath-tools-130222/libmultipath/alias.h
+@@ -7,6 +7,7 @@
+ "# alias wwid\n" \
+ "#\n"
+
++int valid_alias(char *alias);
+ char *get_user_friendly_alias(char *wwid, char *file, char *prefix,
+ int bindings_readonly);
+ int get_user_friendly_wwid(char *alias, char *buff, char *file);
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -454,8 +454,9 @@ get_dev_type(char *dev) {
+ }
+ else if (sscanf(dev, "%d:%d", &i, &i) == 2)
+ return DEV_DEVT;
+- else
++ else if (valid_alias(dev))
+ return DEV_DEVMAP;
++ return DEV_NONE;
+ }
+
+ int
+@@ -607,6 +608,10 @@ main (int argc, char *argv[])
+
+ strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
+ conf->dev_type = get_dev_type(conf->dev);
++ if (conf->dev_type == DEV_NONE) {
++ condlog(0, "'%s' is not a valid argument\n", conf->dev);
++ goto out;
++ }
+ }
+ conf->daemon = 0;
+
diff --git a/0158-RHBZ-1318581-timestamp-doc-fix.patch b/0158-RHBZ-1318581-timestamp-doc-fix.patch
new file mode 100644
index 0000000..d9af360
--- /dev/null
+++ b/0158-RHBZ-1318581-timestamp-doc-fix.patch
@@ -0,0 +1,26 @@
+---
+ multipath/multipath.8 | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+Index: multipath-tools-130222/multipath/multipath.8
+===================================================================
+--- multipath-tools-130222.orig/multipath/multipath.8
++++ multipath-tools-130222/multipath/multipath.8
+@@ -83,6 +83,17 @@ remove the wwid for the specified device
+ .B \-W
+ reset the wwids file to only include the current multipath devices
+ .TP
++.B \-T "tm:valid"
++check if
++.I tm
++matches the multipathd configuration timestamp value from
++.I "/run/multipathd/timestamp"
++If so, return success if
++.I valid
++is 1. Otherwise, return failure. If the timestamp doesn't match continue
++with multipath execution. This option is designed to be used with -c by
++the udev rules.
++.TP
+ .BI \-p " policy"
+ force new maps to use the specified policy:
+ .RS 1.2i
diff --git a/0159-UPBZ-1255885-udev-waits.patch b/0159-UPBZ-1255885-udev-waits.patch
new file mode 100644
index 0000000..9af0981
--- /dev/null
+++ b/0159-UPBZ-1255885-udev-waits.patch
@@ -0,0 +1,425 @@
+---
+ kpartx/devmapper.c | 53 ++++++++++++++++++++++++++++++++++------------
+ kpartx/devmapper.h | 4 +--
+ kpartx/kpartx.c | 16 ++++++-------
+ libmultipath/config.h | 1
+ libmultipath/configure.c | 5 ++--
+ libmultipath/devmapper.c | 48 +++++++++++++++++++++++++++++++----------
+ libmultipath/devmapper.h | 2 -
+ multipath/main.c | 2 -
+ multipathd/cli_handlers.c | 4 +--
+ 9 files changed, 92 insertions(+), 43 deletions(-)
+
+Index: multipath-tools-130222/kpartx/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.c
++++ multipath-tools-130222/kpartx/devmapper.c
+@@ -14,13 +14,6 @@
+ #define MAX_PREFIX_LEN 8
+ #define PARAMS_SIZE 1024
+
+-#ifndef LIBDM_API_COOKIE
+-static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
+-{
+- return 1;
+-}
+-#endif
+-
+ extern int
+ dm_prereq (char * str, int x, int y, int z)
+ {
+@@ -60,10 +53,13 @@ dm_prereq (char * str, int x, int y, int
+ }
+
+ extern int
+-dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie, uint16_t udev_flags) {
++dm_simplecmd (int task, const char *name, int no_flush, uint16_t udev_flags) {
+ int r = 0;
+ int udev_wait_flag = (task == DM_DEVICE_RESUME ||
+ task == DM_DEVICE_REMOVE);
++#ifdef LIBDM_API_COOKIE
++ uint32_t cookie = 0;
++#endif
+ struct dm_task *dmt;
+
+ if (!(dmt = dm_task_create(task)))
+@@ -78,10 +74,23 @@ dm_simplecmd (int task, const char *name
+ if (no_flush)
+ dm_task_no_flush(dmt);
+
+- if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, ((udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK) | udev_flags))
++#ifdef LIBDM_API_COOKIE
++ if (!udev_sync)
++ udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
++ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, udev_flags)) {
++ dm_udev_complete(cookie);
+ goto out;
++ }
++#endif
+ r = dm_task_run(dmt);
+-
++#ifdef LIBDM_API_COOKIE
++ if (udev_wait_flag) {
++ if (!r)
++ dm_udev_complete(cookie);
++ else
++ dm_udev_wait(cookie);
++ }
++#endif
+ out:
+ dm_task_destroy(dmt);
+ return r;
+@@ -90,10 +99,14 @@ dm_simplecmd (int task, const char *name
+ extern int
+ dm_addmap (int task, const char *name, const char *target,
+ const char *params, uint64_t size, int ro, const char *uuid, int part,
+- mode_t mode, uid_t uid, gid_t gid, uint32_t *cookie) {
++ mode_t mode, uid_t uid, gid_t gid) {
+ int r = 0;
+ struct dm_task *dmt;
+ char *prefixed_uuid = NULL;
++#ifdef LIBDM_API_COOKIE
++ uint32_t cookie = 0;
++ uint16_t udev_flags = 0;
++#endif
+
+ if (!(dmt = dm_task_create (task)))
+ return 0;
+@@ -128,10 +141,24 @@ dm_addmap (int task, const char *name, c
+
+ dm_task_no_open_count(dmt);
+
+- if (task == DM_DEVICE_CREATE && !dm_task_set_cookie(dmt, cookie, (udev_sync)? 0 : DM_UDEV_DISABLE_LIBRARY_FALLBACK))
++#ifdef LIBDM_API_COOKIE
++ if (!udev_sync)
++ udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
++ if (task == DM_DEVICE_CREATE &&
++ !dm_task_set_cookie(dmt, &cookie, udev_flags)) {
++ dm_udev_complete(cookie);
+ goto addout;
++ }
++#endif
+ r = dm_task_run (dmt);
+-
++#ifdef LIBDM_API_COOKIE
++ if (task == DM_DEVICE_CREATE) {
++ if (!r)
++ dm_udev_complete(cookie);
++ else
++ dm_udev_wait(cookie);
++ }
++#endif
+ addout:
+ dm_task_destroy (dmt);
+ free(prefixed_uuid);
+Index: multipath-tools-130222/kpartx/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/kpartx/devmapper.h
++++ multipath-tools-130222/kpartx/devmapper.h
+@@ -11,9 +11,9 @@
+ extern int udev_sync;
+
+ int dm_prereq (char *, int, int, int);
+-int dm_simplecmd (int, const char *, int, uint32_t *, uint16_t);
++int dm_simplecmd (int, const char *, int, uint16_t);
+ int dm_addmap (int, const char *, const char *, const char *, uint64_t,
+- int, const char *, int, mode_t, uid_t, gid_t, uint32_t *);
++ int, const char *, int, mode_t, uid_t, gid_t);
+ int dm_map_present (char *, char **);
+ char * dm_mapname(int major, int minor);
+ dev_t dm_get_first_dep(char *devname);
+Index: multipath-tools-130222/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-130222.orig/kpartx/kpartx.c
++++ multipath-tools-130222/kpartx/kpartx.c
+@@ -224,7 +224,6 @@ main(int argc, char **argv){
+ int hotplug = 0;
+ int loopcreated = 0;
+ struct stat buf;
+- uint32_t cookie = 0;
+
+ initpts();
+ init_crc32();
+@@ -300,6 +299,8 @@ main(int argc, char **argv){
+ #ifdef LIBDM_API_COOKIE
+ if (!udev_sync)
+ dm_udev_set_sync_support(0);
++ else
++ dm_udev_set_sync_support(1);
+ #endif
+
+ if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE || what == UPDATE)) {
+@@ -451,7 +452,7 @@ main(int argc, char **argv){
+ }
+
+ if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
+- 0, &cookie, 0)) {
++ 0, 0)) {
+ r++;
+ continue;
+ }
+@@ -508,7 +509,7 @@ main(int argc, char **argv){
+ if (!dm_addmap(op, partname, DM_TARGET, params,
+ slices[j].size, ro, uuid, j+1,
+ buf.st_mode & 0777, buf.st_uid,
+- buf.st_gid, &cookie)) {
++ buf.st_gid)) {
+ fprintf(stderr, "create/reload failed on %s\n",
+ partname);
+ r++;
+@@ -516,12 +517,13 @@ main(int argc, char **argv){
+ }
+ if (op == DM_DEVICE_RELOAD &&
+ !dm_simplecmd(DM_DEVICE_RESUME, partname,
+- 1, &cookie, MPATH_UDEV_RELOAD_FLAG)) {
++ 1, MPATH_UDEV_RELOAD_FLAG)) {
+ fprintf(stderr, "resume failed on %s\n",
+ partname);
+ r++;
+ continue;
+ }
++
+ dm_devn(partname, &slices[j].major,
+ &slices[j].minor);
+
+@@ -560,7 +562,7 @@ main(int argc, char **argv){
+ }
+
+ if (!dm_simplecmd(DM_DEVICE_REMOVE,
+- partname, 1, &cookie, 0)) {
++ partname, 1, 0)) {
+ r++;
+ continue;
+ }
+@@ -586,9 +588,7 @@ main(int argc, char **argv){
+ }
+ printf("loop deleted : %s\n", device);
+ }
+-#ifdef LIBDM_API_COOKIE
+- dm_udev_wait(cookie);
+-#endif
++
+ dm_lib_release();
+ dm_lib_exit();
+
+Index: multipath-tools-130222/libmultipath/config.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/config.h
++++ multipath-tools-130222/libmultipath/config.h
+@@ -129,7 +129,6 @@ struct config {
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+- uint32_t cookie;
+ int reassign_maps;
+ int retain_hwhandler;
+ int detect_prio;
+Index: multipath-tools-130222/libmultipath/configure.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/configure.c
++++ multipath-tools-130222/libmultipath/configure.c
+@@ -654,7 +654,8 @@ domap (struct multipath * mpp, char * pa
+ case ACT_RELOAD:
+ r = dm_addmap_reload(mpp, params);
+ if (r)
+- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias,
++ 0, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
+ break;
+
+ case ACT_RESIZE:
+@@ -672,7 +673,7 @@ domap (struct multipath * mpp, char * pa
+ if (r) {
+ r = dm_addmap_reload(mpp, params);
+ if (r)
+- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, 0, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
+ }
+ break;
+
+Index: multipath-tools-130222/libmultipath/devmapper.c
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.c
++++ multipath-tools-130222/libmultipath/devmapper.c
+@@ -215,6 +215,7 @@ dm_simplecmd (int task, const char *name
+ int r = 0;
+ int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
+ task == DM_DEVICE_REMOVE));
++ uint32_t cookie = 0;
+ struct dm_task *dmt;
+
+ if (!(dmt = dm_task_create (task)))
+@@ -233,10 +234,18 @@ dm_simplecmd (int task, const char *name
+ if (do_deferred(deferred_remove))
+ dm_task_deferred_remove(dmt);
+ #endif
+- if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags))
++ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags)) {
++ dm_udev_complete(cookie);
+ goto out;
++ }
+ r = dm_task_run (dmt);
+
++ if (udev_wait_flag) {
++ if (!r)
++ dm_udev_complete(cookie);
++ else
++ udev_wait(cookie);
++ }
+ out:
+ dm_task_destroy (dmt);
+ return r;
+@@ -248,8 +257,8 @@ dm_simplecmd_flush (int task, const char
+ }
+
+ extern int
+-dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) {
+- return dm_simplecmd(task, name, 1, 1, udev_flags, 0);
++dm_simplecmd_noflush (int task, const char *name, int needsync, uint16_t udev_flags) {
++ return dm_simplecmd(task, name, 1, needsync, udev_flags, 0);
+ }
+
+ static int
+@@ -264,6 +273,7 @@ dm_addmap (int task, const char *target,
+ int r = 0;
+ struct dm_task *dmt;
+ char *prefixed_uuid = NULL;
++ uint32_t cookie = 0;
+
+ if (!(dmt = dm_task_create (task)))
+ return 0;
+@@ -304,10 +314,18 @@ dm_addmap (int task, const char *target,
+ dm_task_no_open_count(dmt);
+
+ if (task == DM_DEVICE_CREATE &&
+- !dm_task_set_cookie(dmt, &conf->cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
++ !dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) {
++ dm_udev_complete(cookie);
+ goto freeout;
++ }
+ r = dm_task_run (dmt);
+
++ if (task == DM_DEVICE_CREATE) {
++ if (!r)
++ dm_udev_complete(cookie);
++ else
++ udev_wait(cookie);
++ }
+ freeout:
+ if (prefixed_uuid)
+ FREE(prefixed_uuid);
+@@ -325,7 +343,8 @@ dm_addmap_create (struct multipath *mpp,
+ for (ro = 0; ro <= 1; ro++) {
+ int err;
+
+- if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro))
++ if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH,
++ mpp, params, 1, ro))
+ return 1;
+ /*
+ * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
+@@ -806,14 +825,14 @@ dm_suspend_and_flush_map (const char * m
+ if (s)
+ queue_if_no_path = 0;
+ else
+- s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0);
++ s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 1, 0);
+
+ if (!dm_flush_map(mapname)) {
+ condlog(4, "multipath map %s removed", mapname);
+ return 0;
+ }
+ condlog(2, "failed to remove multipath map %s", mapname);
+- dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0);
++ dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 1, 0);
+ if (queue_if_no_path)
+ s = dm_queue_if_no_path((char *)mapname, 1);
+ return 1;
+@@ -1366,6 +1385,7 @@ dm_rename (const char * old, char * new)
+ {
+ int r = 0;
+ struct dm_task *dmt;
++ uint32_t cookie;
+
+ if (dm_rename_partmaps(old, new))
+ return r;
+@@ -1381,14 +1401,18 @@ dm_rename (const char * old, char * new)
+
+ dm_task_no_open_count(dmt);
+
+- if (!dm_task_set_cookie(dmt, &conf->cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
+- goto out;
+- if (!dm_task_run(dmt))
++ if (!dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
+ goto out;
++ r = dm_task_run(dmt);
++
++ if (!r)
++ dm_udev_complete(cookie);
++ else
++ udev_wait(cookie);
+
+- r = 1;
+ out:
+ dm_task_destroy(dmt);
++
+ return r;
+ }
+
+@@ -1453,7 +1477,7 @@ int dm_reassign_table(const char *name,
+ condlog(3, "%s: failed to reassign targets", name);
+ goto out_reload;
+ }
+- dm_simplecmd_noflush(DM_DEVICE_RESUME, name, MPATH_UDEV_RELOAD_FLAG);
++ dm_simplecmd_noflush(DM_DEVICE_RESUME, name, 1, MPATH_UDEV_RELOAD_FLAG);
+ }
+ r = 1;
+
+Index: multipath-tools-130222/libmultipath/devmapper.h
+===================================================================
+--- multipath-tools-130222.orig/libmultipath/devmapper.h
++++ multipath-tools-130222/libmultipath/devmapper.h
+@@ -16,7 +16,7 @@ void dm_init(void);
+ int dm_prereq (void);
+ int dm_drv_version (unsigned int * version, char * str);
+ int dm_simplecmd_flush (int, const char *, int, uint16_t);
+-int dm_simplecmd_noflush (int, const char *, uint16_t);
++int dm_simplecmd_noflush (int, const char *, int, uint16_t);
+ int dm_addmap_create (struct multipath *mpp, char *params);
+ int dm_addmap_reload (struct multipath *mpp, char *params);
+ int dm_map_present (const char *);
+Index: multipath-tools-130222/multipath/main.c
+===================================================================
+--- multipath-tools-130222.orig/multipath/main.c
++++ multipath-tools-130222/multipath/main.c
+@@ -681,8 +681,6 @@ main (int argc, char *argv[])
+ condlog(3, "restart multipath configuration process");
+
+ out:
+- udev_wait(conf->cookie);
+-
+ dm_lib_release();
+ dm_lib_exit();
+
+Index: multipath-tools-130222/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-130222.orig/multipathd/cli_handlers.c
++++ multipath-tools-130222/multipathd/cli_handlers.c
+@@ -807,7 +807,7 @@ cli_suspend(void * v, char ** reply, int
+ return 1;
+ }
+
+- r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0);
++ r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0, 0);
+
+ condlog(2, "%s: suspend (operator)", param);
+
+@@ -837,7 +837,7 @@ cli_resume(void * v, char ** reply, int
+ return 1;
+ }
+
+- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0, 0);
+
+ condlog(2, "%s: resume (operator)", param);
+
diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec
index 5f18f7f..b1a066c 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: 81%{?dist}
+Release: 82%{?dist}
License: GPL+
Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/
@@ -140,6 +140,33 @@ Patch0129: 0129-RHBZ-1241774-sun-partition-numbering.patch
Patch0130: 0130-UPBZ-1254292-iscsi-targetname.patch
Patch0131: 0131-RHBZ-1259523-host_name_len.patch
Patch0132: 0132-UPBZ-1259831-lock-retry.patch
+Patch0133: 0133-RHBZ-1296979-fix-define.patch
+Patch0134: 0134-RHBZ-1241528-check-mpath-prefix.patch
+Patch0135: 0135-RHBZ-1299600-path-dev-uevents.patch
+Patch0136: 0136-RHBZ-1304687-wait-for-map-add.patch
+Patch0137: 0137-RHBZ-1280524-clear-chkr-msg.patch
+Patch0138: 0138-RHBZ-1288660-fix-mpathconf-allow.patch
+Patch0139: 0139-RHBZ-1273173-queue-no-daemon-doc.patch
+Patch0140: 0140-RHBZ-1299647-fix-help.patch
+Patch0141: 0141-RHBZ-1303953-mpathpersist-typo.patch
+Patch0142: 0142-RHBZ-1283750-kpartx-fix.patch
+Patch0143: 0143-RHBZ-1299648-kpartx-sync.patch
+Patch0144: 0144-RHBZ-1299652-alua-pref-arg.patch
+Patch0145: 0145-UP-resize-help-msg.patch
+Patch0146: 0146-UPBZ-1299651-raw-output.patch
+Patch0147: 0147-RHBZ-1272620-fail-rm-msg.patch
+Patch0148: 0148-RHBZ-1292599-verify-before-remove.patch
+Patch0149: 0149-RHBZ-1292599-restore-removed-parts.patch
+Patch0150: 0150-RHBZ-1253913-fix-startup-msg.patch
+Patch0151: 0151-RHBZ-1297456-weighted-fix.patch
+Patch0152: 0152-RHBZ-1269293-fix-blk-unit-file.patch
+Patch0153: 0153-RH-fix-i686-size-bug.patch
+Patch0154: 0154-UPBZ-1291406-disable-reinstate.patch
+Patch0155: 0155-UPBZ-1300415-PURE-config.patch
+Patch0156: 0156-UPBZ-1313324-dont-fail-discovery.patch
+Patch0157: 0157-RHBZ-1319853-multipath-c-error-msg.patch
+Patch0158: 0158-RHBZ-1318581-timestamp-doc-fix.patch
+Patch0159: 0159-UPBZ-1255885-udev-waits.patch
# runtime
Requires: %{name}-libs = %{version}-%{release}
@@ -325,6 +352,33 @@ kpartx manages partition creation and removal for device-mapper devices.
%patch0130 -p1
%patch0131 -p1
%patch0132 -p1
+%patch0133 -p1
+%patch0134 -p1
+%patch0135 -p1
+%patch0136 -p1
+%patch0137 -p1
+%patch0138 -p1
+%patch0139 -p1
+%patch0140 -p1
+%patch0141 -p1
+%patch0142 -p1
+%patch0143 -p1
+%patch0144 -p1
+%patch0145 -p1
+%patch0146 -p1
+%patch0147 -p1
+%patch0148 -p1
+%patch0149 -p1
+%patch0150 -p1
+%patch0151 -p1
+%patch0152 -p1
+%patch0153 -p1
+%patch0154 -p1
+%patch0155 -p1
+%patch0156 -p1
+%patch0157 -p1
+%patch0158 -p1
+%patch0159 -p1
cp %{SOURCE1} .
%build
@@ -426,6 +480,66 @@ fi
%{_mandir}/man8/kpartx.8.gz
%changelog
+* Thu Apr 21 2016 Benjamin Marzinski <bmarzins@redhat.com> 0.4.9-82
+- Modify 0005-RH-add-mpathconf.patch
+ * changed warning message
+- Modify 0102-RHBZ-1160478-mpathconf-template.patch
+ * updated man page
+- Modify 0104-RHBZ-631009-deferred-remove.patch
+ * refactor code and minor fix
+- Refresh 0107-RHBZ-1169935-no-new-devs.patch
+- Refresh 0112-RHBZ-1194917-add-config_dir-option.patch
+- Refresh 0126-RHBZ-1211383-alias-collision.patch
+- Add 0133-RHBZ-1296979-fix-define.patch
+ * look for the correct libudev function to set define
+- Add 0134-RHBZ-1241528-check-mpath-prefix.patch
+ * only touch devices with a "mpath-" dm uuid prefix
+- Add 0135-RHBZ-1299600-path-dev-uevents.patch
+ * trigger path uevent the first time a path is claimed by multipath
+- Add 0136-RHBZ-1304687-wait-for-map-add.patch
+ * wait for the device to finish being added before reloading it.
+- Add 0137-RHBZ-1280524-clear-chkr-msg.patch
+- Add 0138-RHBZ-1288660-fix-mpathconf-allow.patch
+ * don't remove existing lines from blacklist_exceptions section
+- Add 0139-RHBZ-1273173-queue-no-daemon-doc.patch
+- Add 0140-RHBZ-1299647-fix-help.patch
+- Add 0141-RHBZ-1303953-mpathpersist-typo.patch
+- Add 0142-RHBZ-1283750-kpartx-fix.patch
+ * only remove devices if their uuid says that they are the correct
+ partition device
+- Add 0143-RHBZ-1299648-kpartx-sync.patch
+ * default to using udev sync mode
+- Add 0144-RHBZ-1299652-alua-pref-arg.patch
+ * allow "exclusive_pref_bit" argument to alua prioritizer
+- Add 0145-UP-resize-help-msg.patch
+- Add 0146-UPBZ-1299651-raw-output.patch
+ * allow raw format mutipathd show commands, that remove headers and padding
+- Add 0147-RHBZ-1272620-fail-rm-msg.patch
+- Add 0148-RHBZ-1292599-verify-before-remove.patch
+ * verify that all partitions are unused before attempting to remove a device
+- Add 0149-RHBZ-1292599-restore-removed-parts.patch
+ * don't disable kpartx when restoring the first path of a device.
+- Add 0150-RHBZ-1253913-fix-startup-msg.patch
+ * wait for multipathd daemon to write pidfile before returning
+- Add 0151-RHBZ-1297456-weighted-fix.patch
+ * add wwn keyword to weighted prioritizer for persistent naming
+- Add 0152-RHBZ-1269293-fix-blk-unit-file.patch
+ * use "Wants" instead of "Requires"
+- Add 0153-RH-fix-i686-size-bug.patch
+ * use 64-bit keycodes for multipathd client commands
+- Add 0154-UPBZ-1291406-disable-reinstate.patch
+ * don't automatically reinstate ghost paths for implicit alua devices
+- Add 0155-UPBZ-1300415-PURE-config.patch
+ * Add default config for PURE FlashArray
+- Add 0156-UPBZ-1313324-dont-fail-discovery.patch
+ * don't fail discovery because individual paths failed.
+- Add 0157-RHBZ-1319853-multipath-c-error-msg.patch
+ * better error reporting for multipath -c
+- Add 0158-RHBZ-1318581-timestamp-doc-fix.patch
+ * add documentation for -T
+- Add 0159-UPBZ-1255885-udev-waits.patch
+ * make multipath and kpartx wait after for udev after each command
+
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.4.9-81
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild