summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@fedoraproject.org>2010-01-23 01:39:39 +0000
committerBenjamin Marzinski <bmarzins@fedoraproject.org>2010-01-23 01:39:39 +0000
commit814d7d2747caab70c0ac0a23ebcdede356d02836 (patch)
tree528f69050573b7efe155126dd54df99b4d662602
parentdfebc4dab31e9fe97d3005c08b75634362c60612 (diff)
downloaddevice-mapper-multipath-814d7d2747caab70c0ac0a23ebcdede356d02836.tar.gz
device-mapper-multipath-814d7d2747caab70c0ac0a23ebcdede356d02836.tar.xz
device-mapper-multipath-814d7d2747caab70c0ac0a23ebcdede356d02836.zip
Refresh 0001-RH-queue-without-daemon.patch Refreshdevice-mapper-multipath-0_4_9-12_fc13
0002-RH-path-checker.patch Modify 0010-RH-multipath-rules-udev-changes.patch Fix udev rules to use DM_SBIN_PATH when calling kpartx install udev rules to /lib/udev/rules.d instead of /etc/udev/rules.d Modify 0014-RH-add-hp_tur-checker.patch Add 0003-for-upstream-default-configs.patch Add 0016-RHBZ-554561-fix-init-error-msg.patch Add 0017-RHBZ-554592-man-page-note.patch Add 0018-RHBZ-554596-SUN-6540-config.patch Add 0019-RHBZ-554598-fix-multipath-locking.patch Add 0020-RHBZ-554605-fix-manual-failover.patch Add 0021-RHBZ-548874-add-find-multipaths.patch Added find_multipaths multipath.conf option Added /sbin/mpathconf for simple editting of multipath.conf Add 0022-RHBZ-557845-RHEL5-style-partitions.patch Make kpartx deal with logical partitions like it did in RHEL5. Don't create a dm-device for the extended partition itself. Create the logical partitions on top of the dm-device for the whole disk.
-rw-r--r--0001-RH-queue-without-daemon.patch59
-rw-r--r--0002-RH-path-checker.patch59
-rw-r--r--0003-for-upstream-default-configs.patch56
-rw-r--r--0010-RH-multipath-rules-udev-changes.patch39
-rw-r--r--0014-RH-add-hp_tur-checker.patch28
-rw-r--r--0016-RHBZ-554561-fix-init-error-msg.patch23
-rw-r--r--0017-RHBZ-554592-man-page-note.patch17
-rw-r--r--0018-RHBZ-554596-SUN-6540-config.patch57
-rw-r--r--0019-RHBZ-554598-fix-multipath-locking.patch43
-rw-r--r--0020-RHBZ-554605-fix-manual-failover.patch52
-rw-r--r--0021-RHBZ-548874-add-find-multipaths.patch1137
-rw-r--r--0022-RHBZ-557845-RHEL5-style-partitions.patch325
-rw-r--r--device-mapper-multipath.spec44
13 files changed, 1862 insertions, 77 deletions
diff --git a/0001-RH-queue-without-daemon.patch b/0001-RH-queue-without-daemon.patch
index 1dfe5e0..3834bfc 100644
--- a/0001-RH-queue-without-daemon.patch
+++ b/0001-RH-queue-without-daemon.patch
@@ -19,11 +19,11 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
multipathd/main.c | 5 +++++
6 files changed, 57 insertions(+), 0 deletions(-)
-diff --git a/libmultipath/config.h b/libmultipath/config.h
-index 50a728c..86b1320 100644
---- a/libmultipath/config.h
-+++ b/libmultipath/config.h
-@@ -72,6 +72,7 @@ struct config {
+Index: multipath-tools/libmultipath/config.h
+===================================================================
+--- multipath-tools.orig/libmultipath/config.h
++++ multipath-tools/libmultipath/config.h
+@@ -74,6 +74,7 @@ struct config {
int pg_timeout;
int max_fds;
int force_reload;
@@ -31,11 +31,11 @@ index 50a728c..86b1320 100644
int daemon;
int flush_on_last_del;
int attribute_flags;
-diff --git a/libmultipath/dict.c b/libmultipath/dict.c
-index ee4de68..7888e8e 100644
---- a/libmultipath/dict.c
-+++ b/libmultipath/dict.c
-@@ -333,6 +333,28 @@ def_no_path_retry_handler(vector strvec)
+Index: multipath-tools/libmultipath/dict.c
+===================================================================
+--- multipath-tools.orig/libmultipath/dict.c
++++ multipath-tools/libmultipath/dict.c
+@@ -362,6 +362,28 @@ def_no_path_retry_handler(vector strvec)
}
static int
@@ -64,7 +64,7 @@ index ee4de68..7888e8e 100644
def_pg_timeout_handler(vector strvec)
{
int pg_timeout;
-@@ -1846,6 +1868,18 @@ snprint_def_no_path_retry (char * buff, int len, void * data)
+@@ -1944,6 +1966,18 @@ snprint_def_no_path_retry (char * buff,
}
static int
@@ -83,7 +83,7 @@ index ee4de68..7888e8e 100644
snprint_def_pg_timeout (char * buff, int len, void * data)
{
if (conf->pg_timeout == DEFAULT_PGTIMEOUT)
-@@ -1931,6 +1965,7 @@ init_keywords(void)
+@@ -2029,6 +2063,7 @@ init_keywords(void)
install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
@@ -91,10 +91,10 @@ index ee4de68..7888e8e 100644
install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
-diff --git a/libmultipath/structs.h b/libmultipath/structs.h
-index afd1246..2e7a0d1 100644
---- a/libmultipath/structs.h
-+++ b/libmultipath/structs.h
+Index: multipath-tools/libmultipath/structs.h
+===================================================================
+--- multipath-tools.orig/libmultipath/structs.h
++++ multipath-tools/libmultipath/structs.h
@@ -63,6 +63,12 @@ enum pgstates {
PGSTATE_ACTIVE
};
@@ -108,10 +108,10 @@ index afd1246..2e7a0d1 100644
enum pgtimeouts {
PGTIMEOUT_UNDEF,
PGTIMEOUT_NONE
-diff --git a/multipath.conf.annotated b/multipath.conf.annotated
-index c222da4..9afa615 100644
---- a/multipath.conf.annotated
-+++ b/multipath.conf.annotated
+Index: multipath-tools/multipath.conf.annotated
+===================================================================
+--- multipath-tools.orig/multipath.conf.annotated
++++ multipath-tools/multipath.conf.annotated
@@ -153,6 +153,15 @@
# no_path_retry queue
#
@@ -128,10 +128,10 @@ index c222da4..9afa615 100644
# # name : user_friendly_names
# # scope : multipath
# # desc : If set to "yes", using the bindings file
-diff --git a/multipath.conf.synthetic b/multipath.conf.synthetic
-index 3e0fd6e..44d1329 100644
---- a/multipath.conf.synthetic
-+++ b/multipath.conf.synthetic
+Index: multipath-tools/multipath.conf.synthetic
+===================================================================
+--- multipath-tools.orig/multipath.conf.synthetic
++++ multipath-tools/multipath.conf.synthetic
@@ -16,6 +16,7 @@
# rr_weight priorities
# failback immediate
@@ -140,10 +140,10 @@ index 3e0fd6e..44d1329 100644
# user_friendly_names no
# mode 644
# uid 0
-diff --git a/multipathd/main.c b/multipathd/main.c
-index 41a9bd0..90de6df 100644
---- a/multipathd/main.c
-+++ b/multipathd/main.c
+Index: multipath-tools/multipathd/main.c
+===================================================================
+--- multipath-tools.orig/multipathd/main.c
++++ multipath-tools/multipathd/main.c
@@ -1334,6 +1334,8 @@ child (void * param)
pthread_t check_thr, uevent_thr, uxlsnr_thr;
pthread_attr_t log_attr, misc_attr;
@@ -163,6 +163,3 @@ index 41a9bd0..90de6df 100644
remove_maps_and_stop_waiters(vecs);
free_pathvec(vecs->pathvec, FREE_PATHS);
---
-1.6.5.1
-
diff --git a/0002-RH-path-checker.patch b/0002-RH-path-checker.patch
index a851e2f..37864ed 100644
--- a/0002-RH-path-checker.patch
+++ b/0002-RH-path-checker.patch
@@ -15,10 +15,10 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
multipathd/main.c | 21 +-------------
4 files changed, 52 insertions(+), 34 deletions(-)
-diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
-index e06dc52..47107a2 100644
---- a/libmultipath/checkers/tur.c
-+++ b/libmultipath/checkers/tur.c
+Index: multipath-tools/libmultipath/checkers/tur.c
+===================================================================
+--- multipath-tools.orig/libmultipath/checkers/tur.c
++++ multipath-tools/libmultipath/checkers/tur.c
@@ -69,7 +69,6 @@ libcheck_check (struct checker * c)
case DID_NO_CONNECT:
case DID_BAD_TARGET:
@@ -27,11 +27,11 @@ index e06dc52..47107a2 100644
case DID_TRANSPORT_FAILFAST:
break;
default:
-diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
-index 98d1618..00aa5ea 100644
---- a/libmultipath/discovery.c
-+++ b/libmultipath/discovery.c
-@@ -579,10 +579,9 @@ struct sysfs_device *sysfs_device_from_path(struct path *pp)
+Index: multipath-tools/libmultipath/discovery.c
+===================================================================
+--- multipath-tools.orig/libmultipath/discovery.c
++++ multipath-tools/libmultipath/discovery.c
+@@ -616,10 +616,9 @@ struct sysfs_device *sysfs_device_from_p
}
int
@@ -43,7 +43,7 @@ index 98d1618..00aa5ea 100644
pp->sysdev = sysfs_device_from_path(pp);
if (!pp->sysdev) {
-@@ -604,6 +603,16 @@ path_offline (struct path * pp)
+@@ -641,6 +640,16 @@ path_offline (struct path * pp)
return 1;
condlog(3, "%s: state = %s", pp->dev, buff);
@@ -60,7 +60,7 @@ index 98d1618..00aa5ea 100644
if (!strncmp(buff, "offline", 7)) {
pp->offline = 1;
-@@ -613,6 +622,21 @@ path_offline (struct path * pp)
+@@ -650,6 +659,21 @@ path_offline (struct path * pp)
return 0;
}
@@ -82,7 +82,7 @@ index 98d1618..00aa5ea 100644
extern int
sysfs_pathinfo(struct path * pp)
{
-@@ -699,36 +723,43 @@ cciss_ioctl_pathinfo (struct path * pp, int mask)
+@@ -736,36 +760,43 @@ cciss_ioctl_pathinfo (struct path * pp,
return 0;
}
@@ -117,15 +117,15 @@ index 98d1618..00aa5ea 100644
- pp->state = PATH_DOWN;
- return 0;
+ return PATH_DOWN;
-+ }
-+ if (daemon) {
-+ if (path_blocked(pp))
-+ return PATH_PENDING;
-+ checker_set_async(c);
}
- pp->state = checker_check(c);
- condlog(3, "%s: state = %i", pp->dev, pp->state);
- if (pp->state == PATH_DOWN && strlen(checker_message(c)))
++ if (daemon) {
++ if (path_blocked(pp))
++ return PATH_PENDING;
++ checker_set_async(c);
++ }
+ state = checker_check(c);
+ condlog(3, "%s: state = %i", pp->dev, state);
+ if (state == PATH_DOWN && strlen(checker_message(c)))
@@ -136,7 +136,7 @@ index 98d1618..00aa5ea 100644
}
static int
-@@ -813,8 +844,11 @@ pathinfo (struct path *pp, vector hwtable, int mask)
+@@ -850,8 +881,11 @@ pathinfo (struct path *pp, vector hwtabl
cciss_ioctl_pathinfo(pp, mask))
goto blank;
@@ -150,11 +150,11 @@ index 98d1618..00aa5ea 100644
/*
* Retrieve path priority, even for PATH_DOWN paths if it has never
-diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
-index 7283f36..17cd4af 100644
---- a/libmultipath/discovery.h
-+++ b/libmultipath/discovery.h
-@@ -30,6 +30,8 @@ int path_discovery (vector pathvec, struct config * conf, int flag);
+Index: multipath-tools/libmultipath/discovery.h
+===================================================================
+--- multipath-tools.orig/libmultipath/discovery.h
++++ multipath-tools/libmultipath/discovery.h
+@@ -30,6 +30,8 @@ int path_discovery (vector pathvec, stru
int do_tur (char *);
int devt2devname (char *, char *);
int path_offline (struct path *);
@@ -163,11 +163,11 @@ index 7283f36..17cd4af 100644
int pathinfo (struct path *, vector hwtable, int mask);
struct path * store_pathinfo (vector pathvec, vector hwtable,
char * devname, int flag);
-diff --git a/multipathd/main.c b/multipathd/main.c
-index 90de6df..5d3625a 100644
---- a/multipathd/main.c
-+++ b/multipathd/main.c
-@@ -908,26 +908,9 @@ check_path (struct vectors * vecs, struct path * pp)
+Index: multipath-tools/multipathd/main.c
+===================================================================
+--- multipath-tools.orig/multipathd/main.c
++++ multipath-tools/multipathd/main.c
+@@ -908,26 +908,9 @@ check_path (struct vectors * vecs, struc
*/
pp->tick = conf->checkint;
@@ -196,6 +196,3 @@ index 90de6df..5d3625a 100644
condlog(2, "%s: unusable path", pp->dev);
pathinfo(pp, conf->hwtable, 0);
return;
---
-1.6.5.1
-
diff --git a/0003-for-upstream-default-configs.patch b/0003-for-upstream-default-configs.patch
new file mode 100644
index 0000000..fdd6347
--- /dev/null
+++ b/0003-for-upstream-default-configs.patch
@@ -0,0 +1,56 @@
+Index: multipath-tools/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools.orig/libmultipath/hwtable.c
++++ multipath-tools/libmultipath/hwtable.c
+@@ -425,6 +425,21 @@ static struct hwentry default_hw[] = {
+ .prio_name = PRIO_RDAC,
+ },
+ {
++ .vendor = "IBM",
++ .product = "1745|1746",
++ .getuid = DEFAULT_GETUID,
++ .features = "2 pg_init_retries 50",
++ .hwhandler = "1 rdac",
++ .selector = DEFAULT_SELECTOR,
++ .pgpolicy = GROUP_BY_PRIO,
++ .pgfailback = -FAILBACK_IMMEDIATE,
++ .rr_weight = RR_WEIGHT_NONE,
++ .no_path_retry = 15,
++ .minio = DEFAULT_MINIO,
++ .checker_name = RDAC,
++ .prio_name = PRIO_RDAC,
++ },
++ {
+ /* IBM DS4700 */
+ .vendor = "IBM",
+ .product = "1814",
+@@ -661,12 +676,13 @@ static struct hwentry default_hw[] = {
+ .vendor = "DELL",
+ .product = "MD3000",
+ .getuid = DEFAULT_GETUID,
+- .features = "1 queue_if_no_path",
++ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
++ .no_path_retry = 15,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+@@ -676,12 +692,13 @@ static struct hwentry default_hw[] = {
+ .vendor = "DELL",
+ .product = "MD3000i",
+ .getuid = DEFAULT_GETUID,
+- .features = "1 queue_if_no_path",
++ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
++ .no_path_retry = 15,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
diff --git a/0010-RH-multipath-rules-udev-changes.patch b/0010-RH-multipath-rules-udev-changes.patch
index 325e26e..4250ec7 100644
--- a/0010-RH-multipath-rules-udev-changes.patch
+++ b/0010-RH-multipath-rules-udev-changes.patch
@@ -6,13 +6,14 @@ Subject: [PATCH 10/12] RH: multipath rules + udev changes
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 ac97749... 064196d... M multipath/multipath.rules
+ multipath/Makefile | 6 +++---
multipath/multipath.rules | 18 +++++++++++-------
- 1 files changed, 11 insertions(+), 7 deletions(-)
+ 2 files changed, 14 insertions(+), 10 deletions(-)
-diff --git a/multipath/multipath.rules b/multipath/multipath.rules
-index ac97749..064196d 100644
---- a/multipath/multipath.rules
-+++ b/multipath/multipath.rules
+Index: multipath-tools/multipath/multipath.rules
+===================================================================
+--- multipath-tools.orig/multipath/multipath.rules
++++ multipath-tools/multipath/multipath.rules
@@ -1,7 +1,11 @@
-#
-# udev rules for multipathing.
@@ -30,8 +31,28 @@ index ac97749..064196d 100644
+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
+ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
-+RUN+="/sbin/kpartx -a -p p $tempnode"
++RUN+="$env{DM_SBIN_PATH}/kpartx -a -p p $tempnode"
+LABEL="end_mpath"
---
-1.6.5.1
-
+Index: multipath-tools/multipath/Makefile
+===================================================================
+--- multipath-tools.orig/multipath/Makefile
++++ multipath-tools/multipath/Makefile
+@@ -21,15 +21,15 @@ $(EXEC): $(OBJS)
+ install:
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
+ $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
+- $(INSTALL_PROGRAM) -d $(DESTDIR)/etc/udev/rules.d
+- $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/etc/udev/rules.d/
++ $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
++ $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
+
+ uninstall:
+- rm $(DESTDIR)/etc/udev/rules.d/multipath.rules
++ rm $(DESTDIR)/lib/udev/rules.d/multipath.rules
+ rm $(DESTDIR)$(bindir)/$(EXEC)
+ rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
+ rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
diff --git a/0014-RH-add-hp_tur-checker.patch b/0014-RH-add-hp_tur-checker.patch
index 36bf136..33dd43a 100644
--- a/0014-RH-add-hp_tur-checker.patch
+++ b/0014-RH-add-hp_tur-checker.patch
@@ -1,8 +1,9 @@
---
libmultipath/checkers.h | 3 +
libmultipath/checkers/Makefile | 4 +
- libmultipath/checkers/tur.c | 110 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 117 insertions(+)
+ libmultipath/checkers/tur.c | 111 +++++++++++++++++++++++++++++++++++++++++
+ multipath.conf.annotated | 5 +
+ 4 files changed, 121 insertions(+), 2 deletions(-)
Index: multipath-tools/libmultipath/checkers.h
===================================================================
@@ -205,3 +206,26 @@ Index: multipath-tools/libmultipath/checkers/tur.c
MSG(c, MSG_TUR_UP);
return PATH_UP;
}
+Index: multipath-tools/multipath.conf.annotated
+===================================================================
+--- multipath-tools.orig/multipath.conf.annotated
++++ multipath-tools/multipath.conf.annotated
+@@ -86,7 +86,8 @@
+ # # name : path_checker, checker
+ # # scope : multipath & multipathd
+ # # desc : the default method used to determine the paths' state
+-# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|cciss_tur
++# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|
++# cciss_tur|hp_tur
+ # # default : directio
+ # #
+ # path_checker directio
+@@ -456,7 +457,7 @@
+ # # scope : multipathd
+ # # desc : path checking alorithm to use to check path state
+ # # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|
+-# # cciss_tur
++# # cciss_tur|hp_tur
+ # #
+ # path_checker directio
+ #
diff --git a/0016-RHBZ-554561-fix-init-error-msg.patch b/0016-RHBZ-554561-fix-init-error-msg.patch
new file mode 100644
index 0000000..ae0ae70
--- /dev/null
+++ b/0016-RHBZ-554561-fix-init-error-msg.patch
@@ -0,0 +1,23 @@
+---
+ multipathd/multipathd.init.redhat | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+Index: multipath-tools/multipathd/multipathd.init.redhat
+===================================================================
+--- multipath-tools.orig/multipathd/multipathd.init.redhat
++++ multipath-tools/multipathd/multipathd.init.redhat
+@@ -75,9 +75,11 @@ start() {
+
+ stop() {
+ root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
+- dm_num=`dmsetup info -c --noheadings -o minor $root_dev`
+- root_dm_device="dm-$dm_num"
+- [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
++ dm_num=`dmsetup info -c --noheadings -o minor $root_dev 2> /dev/null`
++ if [ $? -eq 0 ]; then
++ root_dm_device="dm-$dm_num"
++ [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
++ fi
+
+ echo -n $"Stopping $prog daemon: "
+ killproc $DAEMON
diff --git a/0017-RHBZ-554592-man-page-note.patch b/0017-RHBZ-554592-man-page-note.patch
new file mode 100644
index 0000000..9ebaf92
--- /dev/null
+++ b/0017-RHBZ-554592-man-page-note.patch
@@ -0,0 +1,17 @@
+---
+ multipath/multipath.8 | 2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: multipath-tools/multipath/multipath.8
+===================================================================
+--- multipath-tools.orig/multipath/multipath.8
++++ multipath-tools/multipath/multipath.8
+@@ -75,6 +75,8 @@ is in.
+ is in the /dev/sdb (as shown by udev in the $DEVNAME variable) or major:minor format.
+ .I device
+ may alternatively be a multipath mapname
++.SH NOTES
++a map may be unused if, eg, the file system on it is not mounted or there are no open file descriptors against the device file, as in a raw device.
+ .SH "SEE ALSO"
+ .BR udev (8),
+ .BR dmsetup (8)
diff --git a/0018-RHBZ-554596-SUN-6540-config.patch b/0018-RHBZ-554596-SUN-6540-config.patch
new file mode 100644
index 0000000..e3296d3
--- /dev/null
+++ b/0018-RHBZ-554596-SUN-6540-config.patch
@@ -0,0 +1,57 @@
+---
+ libmultipath/hwtable.c | 16 ++++++++++++++++
+ multipath.conf.defaults | 16 ++++++++++++++++
+ 2 files changed, 32 insertions(+)
+
+Index: multipath-tools/libmultipath/hwtable.c
+===================================================================
+--- multipath-tools.orig/libmultipath/hwtable.c
++++ multipath-tools/libmultipath/hwtable.c
+@@ -959,6 +959,22 @@ static struct hwentry default_hw[] = {
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ },
++ {
++ .vendor = "STK",
++ .product = "FLEXLINE 380",
++ .bl_product = "Universal Xport",
++ .getuid = DEFAULT_GETUID,
++ .features = DEFAULT_FEATURES,
++ .hwhandler = "1 rdac",
++ .selector = DEFAULT_SELECTOR,
++ .pgpolicy = GROUP_BY_PRIO,
++ .pgfailback = -FAILBACK_IMMEDIATE,
++ .rr_weight = RR_WEIGHT_NONE,
++ .no_path_retry = NO_PATH_RETRY_QUEUE,
++ .minio = DEFAULT_MINIO,
++ .checker_name = RDAC,
++ .prio_name = PRIO_RDAC,
++ },
+ /*
+ * EOL
+ */
+Index: multipath-tools/multipath.conf.defaults
+===================================================================
+--- multipath-tools.orig/multipath.conf.defaults
++++ multipath-tools/multipath.conf.defaults
+@@ -571,4 +571,20 @@
+ # path_checker rdac
+ # prio rdac
+ # }
++# device {
++# vendor "STK"
++# product "FLEXLINE 380"
++# product_blacklist "Universal Xport"
++# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
++# features "0"
++# hardware_handler "1 rdac"
++# path_selector "round-robin 0"
++# path_grouping_policy group_by_prio
++# failback immediate
++# rr_weight uniform
++# no_path_retry queue
++# rr_min_io 1000
++# path_checker rdac
++# prio rdac
++# }
+ #}
diff --git a/0019-RHBZ-554598-fix-multipath-locking.patch b/0019-RHBZ-554598-fix-multipath-locking.patch
new file mode 100644
index 0000000..cf101e2
--- /dev/null
+++ b/0019-RHBZ-554598-fix-multipath-locking.patch
@@ -0,0 +1,43 @@
+---
+ libmultipath/configure.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+Index: multipath-tools/libmultipath/configure.c
+===================================================================
+--- multipath-tools.orig/libmultipath/configure.c
++++ multipath-tools/libmultipath/configure.c
+@@ -284,6 +284,7 @@ lock_multipath (struct multipath * mpp,
+ struct pathgroup * pgp;
+ struct path * pp;
+ int i, j;
++ int x, y;
+
+ if (!mpp || !mpp->pg)
+ return 0;
+@@ -294,12 +295,25 @@ lock_multipath (struct multipath * mpp,
+ vector_foreach_slot(pgp->paths, pp, j) {
+ if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) &&
+ errno == EWOULDBLOCK)
+- return 1;
++ goto fail;
+ else if (!lock)
+ flock(pp->fd, LOCK_UN);
+ }
+ }
+ return 0;
++fail:
++ vector_foreach_slot (mpp->pg, pgp, x) {
++ if (x > i)
++ return 1;
++ if (!pgp->paths)
++ continue;
++ vector_foreach_slot(pgp->paths, pp, y) {
++ if (x == i && y > j)
++ return 1;
++ flock(pp->fd, LOCK_UN);
++ }
++ }
++ return 1;
+ }
+
+ /*
diff --git a/0020-RHBZ-554605-fix-manual-failover.patch b/0020-RHBZ-554605-fix-manual-failover.patch
new file mode 100644
index 0000000..51b66bd
--- /dev/null
+++ b/0020-RHBZ-554605-fix-manual-failover.patch
@@ -0,0 +1,52 @@
+---
+ libmultipath/pgpolicies.c | 23 +++++++++++++++++++----
+ 1 file changed, 19 insertions(+), 4 deletions(-)
+
+Index: multipath-tools/libmultipath/pgpolicies.c
+===================================================================
+--- multipath-tools.orig/libmultipath/pgpolicies.c
++++ multipath-tools/libmultipath/pgpolicies.c
+@@ -205,7 +205,8 @@ out:
+ extern int
+ one_path_per_group (struct multipath * mp)
+ {
+- int i;
++ int i, j;
++ unsigned int prio;
+ struct path * pp;
+ struct pathgroup * pgp;
+
+@@ -217,16 +218,30 @@ one_path_per_group (struct multipath * m
+
+ for (i = 0; i < VECTOR_SIZE(mp->paths); i++) {
+ pp = VECTOR_SLOT(mp->paths, i);
++ prio = pp->priority;
++
++ vector_foreach_slot(mp->pg, pgp, j) {
++ pp = VECTOR_SLOT(pgp->paths, 0);
++
++ if (prio > pp->priority)
++ break;
++ }
++
+ pgp = alloc_pathgroup();
+
+ if (!pgp)
+ goto out;
+
+- if (store_pathgroup(mp->pg, pgp))
++ if (store_path(pgp->paths, VECTOR_SLOT(mp->paths, i)))
+ goto out;
+
+- if (store_path(pgp->paths, pp))
+- goto out;
++ if (j < VECTOR_SIZE(mp->pg)) {
++ if (!vector_insert_slot(mp->pg, j, pgp))
++ goto out;
++ } else {
++ if (store_pathgroup(mp->pg, pgp))
++ goto out;
++ }
+ }
+ free_pathvec(mp->paths, KEEP_PATHS);
+ mp->paths = NULL;
diff --git a/0021-RHBZ-548874-add-find-multipaths.patch b/0021-RHBZ-548874-add-find-multipaths.patch
new file mode 100644
index 0000000..3490793
--- /dev/null
+++ b/0021-RHBZ-548874-add-find-multipaths.patch
@@ -0,0 +1,1137 @@
+---
+ libmultipath/Makefile | 2
+ libmultipath/alias.c | 152 ------------------------------
+ libmultipath/alias.h | 1
+ libmultipath/config.c | 1
+ libmultipath/config.h | 1
+ libmultipath/configure.c | 23 ++++
+ libmultipath/defaults.h | 2
+ libmultipath/dict.c | 34 ++++++
+ libmultipath/file.c | 178 ++++++++++++++++++++++++++++++++++++
+ libmultipath/file.h | 11 ++
+ libmultipath/finder.c | 150 ++++++++++++++++++++++++++++++
+ libmultipath/finder.h | 18 +++
+ multipath/Makefile | 2
+ multipath/main.c | 2
+ multipath/mpathconf | 232 +++++++++++++++++++++++++++++++++++++++++++++++
+ multipathd/main.c | 27 +++--
+ 16 files changed, 674 insertions(+), 162 deletions(-)
+
+Index: multipath-tools/libmultipath/alias.c
+===================================================================
+--- multipath-tools.orig/libmultipath/alias.c
++++ multipath-tools/libmultipath/alias.c
+@@ -3,19 +3,16 @@
+ * Copyright (c) 2005 Benjamin Marzinski, Redhat
+ */
+ #include <stdlib.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+ #include <errno.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <limits.h>
+ #include <stdio.h>
+-#include <signal.h>
+
+ #include "debug.h"
+ #include "uxsock.h"
+ #include "alias.h"
++#include "file.h"
+
+
+ /*
+@@ -37,149 +34,6 @@
+ */
+
+ static int
+-ensure_directories_exist(char *str, mode_t dir_mode)
+-{
+- char *pathname;
+- char *end;
+- int err;
+-
+- pathname = strdup(str);
+- if (!pathname){
+- condlog(0, "Cannot copy bindings file pathname : %s",
+- strerror(errno));
+- return -1;
+- }
+- end = pathname;
+- /* skip leading slashes */
+- while (end && *end && (*end == '/'))
+- end++;
+-
+- while ((end = strchr(end, '/'))) {
+- /* if there is another slash, make the dir. */
+- *end = '\0';
+- err = mkdir(pathname, dir_mode);
+- if (err && errno != EEXIST) {
+- condlog(0, "Cannot make directory [%s] : %s",
+- pathname, strerror(errno));
+- free(pathname);
+- return -1;
+- }
+- if (!err)
+- condlog(3, "Created dir [%s]", pathname);
+- *end = '/';
+- end++;
+- }
+- free(pathname);
+- return 0;
+-}
+-
+-static void
+-sigalrm(int sig)
+-{
+- /* do nothing */
+-}
+-
+-static int
+-lock_bindings_file(int fd)
+-{
+- struct sigaction act, oldact;
+- sigset_t set, oldset;
+- struct flock lock;
+- int err;
+-
+- memset(&lock, 0, sizeof(lock));
+- lock.l_type = F_WRLCK;
+- lock.l_whence = SEEK_SET;
+-
+- act.sa_handler = sigalrm;
+- sigemptyset(&act.sa_mask);
+- act.sa_flags = 0;
+- sigemptyset(&set);
+- sigaddset(&set, SIGALRM);
+-
+- sigaction(SIGALRM, &act, &oldact);
+- sigprocmask(SIG_UNBLOCK, &set, &oldset);
+-
+- alarm(BINDINGS_FILE_TIMEOUT);
+- err = fcntl(fd, F_SETLKW, &lock);
+- alarm(0);
+-
+- if (err) {
+- if (errno != EINTR)
+- condlog(0, "Cannot lock bindings file : %s",
+- strerror(errno));
+- else
+- condlog(0, "Bindings file is locked. Giving up.");
+- }
+-
+- sigprocmask(SIG_SETMASK, &oldset, NULL);
+- sigaction(SIGALRM, &oldact, NULL);
+- return err;
+-
+-}
+-
+-
+-static int
+-open_bindings_file(char *file, int *can_write)
+-{
+- int fd;
+- struct stat s;
+-
+- if (ensure_directories_exist(file, 0700))
+- return -1;
+- *can_write = 1;
+- fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+- if (fd < 0) {
+- if (errno == EROFS) {
+- *can_write = 0;
+- condlog(3, "Cannot open bindings file [%s] read/write. "
+- " trying readonly", file);
+- fd = open(file, O_RDONLY);
+- if (fd < 0) {
+- condlog(0, "Cannot open bindings file [%s] "
+- "readonly : %s", file, strerror(errno));
+- return -1;
+- }
+- }
+- else {
+- condlog(0, "Cannot open bindings file [%s] : %s", file,
+- strerror(errno));
+- return -1;
+- }
+- }
+- if (*can_write && lock_bindings_file(fd) < 0)
+- goto fail;
+-
+- memset(&s, 0, sizeof(s));
+- if (fstat(fd, &s) < 0){
+- condlog(0, "Cannot stat bindings file : %s", strerror(errno));
+- goto fail;
+- }
+- if (s.st_size == 0) {
+- if (*can_write == 0)
+- goto fail;
+- /* If bindings file is empty, write the header */
+- size_t len = strlen(BINDINGS_FILE_HEADER);
+- if (write_all(fd, BINDINGS_FILE_HEADER, len) != len) {
+- condlog(0,
+- "Cannot write header to bindings file : %s",
+- strerror(errno));
+- /* cleanup partially written header */
+- ftruncate(fd, 0);
+- goto fail;
+- }
+- fsync(fd);
+- condlog(3, "Initialized new bindings file [%s]", file);
+- }
+-
+- return fd;
+-
+-fail:
+- close(fd);
+- return -1;
+-}
+-
+-static int
+ format_devname(char *name, int id, int len)
+ {
+ int pos;
+@@ -364,7 +218,7 @@ get_user_friendly_alias(char *wwid, char
+ return NULL;
+ }
+
+- fd = open_bindings_file(file, &can_write);
++ fd = open_file(file, &can_write, BINDINGS_FILE_HEADER);
+ if (fd < 0)
+ return NULL;
+
+@@ -414,7 +268,7 @@ get_user_friendly_wwid(char *alias, char
+ return NULL;
+ }
+
+- fd = open_bindings_file(file, &unused);
++ fd = open_file(file, &unused, BINDINGS_FILE_HEADER);
+ if (fd < 0)
+ return NULL;
+
+Index: multipath-tools/libmultipath/alias.h
+===================================================================
+--- multipath-tools.orig/libmultipath/alias.h
++++ multipath-tools/libmultipath/alias.h
+@@ -1,4 +1,3 @@
+-#define BINDINGS_FILE_TIMEOUT 30
+ #define BINDINGS_FILE_HEADER \
+ "# Multipath bindings, Version : 1.0\n" \
+ "# NOTE: this file is automatically maintained by the multipath program.\n" \
+Index: multipath-tools/libmultipath/config.c
+===================================================================
+--- multipath-tools.orig/libmultipath/config.c
++++ multipath-tools/libmultipath/config.c
+@@ -452,6 +452,7 @@ load_config (char * file)
+ conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
+ conf->flush_on_last_del = 0;
+ conf->attribute_flags = 0;
++ conf->find_multipaths = DEFAULT_FIND_MULTIPATHS;
+
+ /*
+ * preload default hwtable
+Index: multipath-tools/libmultipath/config.h
+===================================================================
+--- multipath-tools.orig/libmultipath/config.h
++++ multipath-tools/libmultipath/config.h
+@@ -84,6 +84,7 @@ struct config {
+ int attribute_flags;
+ int fast_io_fail;
+ unsigned int dev_loss;
++ int find_multipaths;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+Index: multipath-tools/libmultipath/configure.c
+===================================================================
+--- multipath-tools.orig/libmultipath/configure.c
++++ multipath-tools/libmultipath/configure.c
+@@ -35,6 +35,7 @@
+ #include "alias.h"
+ #include "prio.h"
+ #include "util.h"
++#include "finder.h"
+
+ extern int
+ setup_map (struct multipath * mpp)
+@@ -462,6 +463,10 @@ coalesce_paths (struct vectors * vecs, v
+
+ memset(empty_buff, 0, WWID_SIZE);
+
++ /* ignore refwwid if it's empty */
++ if (refwwid && !strlen(refwwid))
++ refwwid = NULL;
++
+ if (force_reload) {
+ vector_foreach_slot (pathvec, pp1, k) {
+ pp1->mpp = NULL;
+@@ -472,21 +477,35 @@ coalesce_paths (struct vectors * vecs, v
+
+ /* 1. if path has no unique id or wwid blacklisted */
+ if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
+- filter_path(conf, pp1) > 0)
++ filter_path(conf, pp1) > 0) {
++ orphan_path(pp1);
+ continue;
++ }
+
+ /* 2. if path already coalesced */
+ if (pp1->mpp)
+ continue;
+
+ /* 3. if path has disappeared */
+- if (!pp1->size)
++ if (!pp1->size) {
++ orphan_path(pp1);
+ continue;
++ }
+
+ /* 4. path is out of scope */
+ if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
+ continue;
+
++ /* If find_multipaths was selected check if the path is valid */
++ if (conf->find_multipaths){
++ if (refwwid || should_multipath(pp1, pathvec))
++ remember_wwid(pp1->wwid);
++ else {
++ orphan_path(pp1);
++ continue;
++ }
++ }
++
+ /*
+ * at this point, we know we really got a new mp
+ */
+Index: multipath-tools/libmultipath/defaults.h
+===================================================================
+--- multipath-tools.orig/libmultipath/defaults.h
++++ multipath-tools/libmultipath/defaults.h
+@@ -12,6 +12,7 @@
+ #define DEFAULT_PGTIMEOUT -PGTIMEOUT_NONE
+ #define DEFAULT_USER_FRIENDLY_NAMES 0
+ #define DEFAULT_VERBOSITY 2
++#define DEFAULT_FIND_MULTIPATHS 0
+
+ #define DEFAULT_CHECKINT 5
+ #define MAX_CHECKINT(a) (a << 2)
+@@ -20,5 +21,6 @@
+ #define DEFAULT_SOCKET "/var/run/multipathd.sock"
+ #define DEFAULT_CONFIGFILE "/etc/multipath.conf"
+ #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
++#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
+
+ char * set_default (char * str);
+Index: multipath-tools/libmultipath/dict.c
+===================================================================
+--- multipath-tools.orig/libmultipath/dict.c
++++ multipath-tools/libmultipath/dict.c
+@@ -444,6 +444,27 @@ def_flush_on_last_del_handler(vector str
+ }
+
+ static int
++def_find_multipaths_handler(vector strvec)
++{
++ char * buff;
++
++ buff = set_value(strvec);
++
++ if (!buff)
++ return 1;
++
++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
++ (strlen(buff) == 1 && !strcmp(buff, "0")))
++ conf->find_multipaths = 0;
++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
++ (strlen(buff) == 1 && !strcmp(buff, "1")))
++ conf->find_multipaths = 1;
++
++ FREE(buff);
++ return 0;
++}
++
++static int
+ names_handler(vector strvec)
+ {
+ char * buff;
+@@ -2076,6 +2097,18 @@ snprint_def_flush_on_last_del (char * bu
+ }
+
+ static int
++snprint_def_find_multipaths (char * buff, int len, void * data)
++{
++ if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS)
++ return 0;
++ if (!conf->find_multipaths)
++ return snprintf(buff, len, "no");
++
++ return snprintf(buff, len, "yes");
++}
++
++
++static int
+ snprint_def_user_friendly_names (char * buff, int len, void * data)
+ {
+ if (conf->user_friendly_names == DEFAULT_USER_FRIENDLY_NAMES)
+@@ -2141,6 +2174,7 @@ init_keywords(void)
+ install_keyword("gid", &def_gid_handler, &snprint_def_gid);
+ install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
+ install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
++ install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
+ __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
+ __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
+ __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
+Index: multipath-tools/libmultipath/file.c
+===================================================================
+--- /dev/null
++++ multipath-tools/libmultipath/file.c
+@@ -0,0 +1,178 @@
++/*
++ * Copyright (c) 2005 Christophe Varoqui
++ * Copyright (c) 2005 Benjamin Marzinski, Redhat
++ */
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <unistd.h>
++#include <string.h>
++#include <limits.h>
++#include <stdio.h>
++#include <signal.h>
++
++#include "file.h"
++#include "debug.h"
++#include "uxsock.h"
++
++
++/*
++ * significant parts of this file were taken from iscsi-bindings.c of the
++ * linux-iscsi project.
++ * Copyright (C) 2002 Cisco Systems, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published
++ * by the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * See the file COPYING included with this distribution for more details.
++ */
++
++static int
++ensure_directories_exist(char *str, mode_t dir_mode)
++{
++ char *pathname;
++ char *end;
++ int err;
++
++ pathname = strdup(str);
++ if (!pathname){
++ condlog(0, "Cannot copy file pathname %s : %s",
++ str, strerror(errno));
++ return -1;
++ }
++ end = pathname;
++ /* skip leading slashes */
++ while (end && *end && (*end == '/'))
++ end++;
++
++ while ((end = strchr(end, '/'))) {
++ /* if there is another slash, make the dir. */
++ *end = '\0';
++ err = mkdir(pathname, dir_mode);
++ if (err && errno != EEXIST) {
++ condlog(0, "Cannot make directory [%s] : %s",
++ pathname, strerror(errno));
++ free(pathname);
++ return -1;
++ }
++ if (!err)
++ condlog(3, "Created dir [%s]", pathname);
++ *end = '/';
++ end++;
++ }
++ free(pathname);
++ return 0;
++}
++
++static void
++sigalrm(int sig)
++{
++ /* do nothing */
++}
++
++static int
++lock_file(int fd, char *file_name)
++{
++ struct sigaction act, oldact;
++ sigset_t set, oldset;
++ struct flock lock;
++ int err;
++
++ memset(&lock, 0, sizeof(lock));
++ lock.l_type = F_WRLCK;
++ lock.l_whence = SEEK_SET;
++
++ act.sa_handler = sigalrm;
++ sigemptyset(&act.sa_mask);
++ act.sa_flags = 0;
++ sigemptyset(&set);
++ sigaddset(&set, SIGALRM);
++
++ sigaction(SIGALRM, &act, &oldact);
++ sigprocmask(SIG_UNBLOCK, &set, &oldset);
++
++ alarm(FILE_TIMEOUT);
++ err = fcntl(fd, F_SETLKW, &lock);
++ alarm(0);
++
++ if (err) {
++ if (errno != EINTR)
++ condlog(0, "Cannot lock %s : %s", file_name,
++ strerror(errno));
++ else
++ condlog(0, "%s is locked. Giving up.", file_name);
++ }
++
++ sigprocmask(SIG_SETMASK, &oldset, NULL);
++ sigaction(SIGALRM, &oldact, NULL);
++ return err;
++}
++
++int
++open_file(char *file, int *can_write, char *header)
++{
++ int fd;
++ struct stat s;
++
++ if (ensure_directories_exist(file, 0700))
++ return -1;
++ *can_write = 1;
++ fd = open(file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
++ if (fd < 0) {
++ if (errno == EROFS) {
++ *can_write = 0;
++ condlog(3, "Cannot open file [%s] read/write. "
++ " trying readonly", file);
++ fd = open(file, O_RDONLY);
++ if (fd < 0) {
++ condlog(0, "Cannot open file [%s] "
++ "readonly : %s", file, strerror(errno));
++ return -1;
++ }
++ }
++ else {
++ condlog(0, "Cannot open file [%s] : %s", file,
++ strerror(errno));
++ return -1;
++ }
++ }
++ if (*can_write && lock_file(fd, file) < 0)
++ goto fail;
++
++ memset(&s, 0, sizeof(s));
++ if (fstat(fd, &s) < 0){
++ condlog(0, "Cannot stat file %s : %s", file, strerror(errno));
++ goto fail;
++ }
++ if (s.st_size == 0) {
++ if (*can_write == 0)
++ goto fail;
++ /* If file is empty, write the header */
++ size_t len = strlen(header);
++ if (write_all(fd, header, len) != len) {
++ condlog(0,
++ "Cannot write header to file %s : %s", file,
++ strerror(errno));
++ /* cleanup partially written header */
++ ftruncate(fd, 0);
++ goto fail;
++ }
++ fsync(fd);
++ condlog(3, "Initialized new file [%s]", file);
++ }
++
++ return fd;
++
++fail:
++ close(fd);
++ return -1;
++}
+Index: multipath-tools/libmultipath/file.h
+===================================================================
+--- /dev/null
++++ multipath-tools/libmultipath/file.h
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (c) 2010 Benjamin Marzinski, Redhat
++ */
++
++#ifndef _FILE_H
++#define _FILE_H
++
++#define FILE_TIMEOUT 30
++int open_file(char *file, int *can_write, char *header);
++
++#endif /* _FILE_H */
+Index: multipath-tools/libmultipath/finder.c
+===================================================================
+--- /dev/null
++++ multipath-tools/libmultipath/finder.c
+@@ -0,0 +1,150 @@
++#include <stdlib.h>
++#include <errno.h>
++#include <unistd.h>
++#include <string.h>
++#include <limits.h>
++#include <stdio.h>
++
++#include "checkers.h"
++#include "vector.h"
++#include "structs.h"
++#include "debug.h"
++#include "uxsock.h"
++#include "file.h"
++#include "finder.h"
++#include "defaults.h"
++
++/*
++ * Copyright (c) 2010 Benjamin Marzinski, Redhat
++ */
++
++static int
++lookup_wwid(FILE *f, char *wwid) {
++ char buf[LINE_MAX];
++
++ while (fgets(buf, LINE_MAX, f)) {
++ char *c;
++
++ c = strpbrk(buf, "#\n\r");
++ if (c)
++ *c = '\0';
++ if (*buf == '\0')
++ continue;
++ if (strncmp(wwid, buf, WWID_SIZE) == 0)
++ return 1;
++ }
++ return 0;
++}
++
++static int
++write_out_wwid(int fd, char *wwid) {
++ int ret;
++ off_t offset;
++ char buf[WWID_SIZE + 1];
++
++ ret = snprintf(buf, WWID_SIZE + 1, "%s\n", wwid);
++ if (ret > WWID_SIZE || ret < 0){
++ condlog(0, "can't format wwid for writing (%d) : %s",
++ ret, strerror(errno));
++ return -1;
++ }
++ offset = lseek(fd, 0, SEEK_END);
++ if (offset < 0) {
++ condlog(0, "can't seek to the end of wwids file : %s",
++ strerror(errno));
++ return -1;
++ }
++ if (write_all(fd, buf, strlen(buf)) != strlen(buf)) {
++ condlog(0, "cannot write wwid to wwids file : %s",
++ strerror(errno));
++ ftruncate(fd, offset);
++ return -1;
++ }
++ return 1;
++}
++
++static int
++check_wwids_file(char *wwid, int write_wwid)
++{
++ int scan_fd, fd, can_write, found, ret;
++ FILE *f;
++ fd = open_file(DEFAULT_WWIDS_FILE, &can_write, WWIDS_FILE_HEADER);
++ if (fd < 0)
++ return -1;
++
++ scan_fd = dup(fd);
++ if (scan_fd < 0) {
++ condlog(0, "can't dup wwids file descriptor : %s",
++ strerror(errno));
++ close(fd);
++ return -1;
++ }
++ f = fdopen(scan_fd, "r");
++ if (!f) {
++ condlog(0,"can't fdopen wwids file : %s", strerror(errno));
++ close(fd);
++ close(scan_fd);
++ return -1;
++ }
++ found = lookup_wwid(f, wwid);
++ if (found) {
++ ret = 0;
++ goto out;
++ }
++ if (!write_wwid) {
++ ret = -1;
++ goto out;
++ }
++ if (!can_write) {
++ condlog(0, "wwids file is read-only. Can't write wwid");
++ ret = -1;
++ goto out;
++ }
++ ret = write_out_wwid(fd, wwid);
++out:
++ fclose(f);
++ close(scan_fd);
++ close(fd);
++ return ret;
++}
++
++int
++should_multipath(struct path *pp1, vector pathvec)
++{
++ int i;
++ struct path *pp2;
++
++ condlog(4, "checking if %s should be multipathed", pp1->dev);
++ vector_foreach_slot(pathvec, pp2, i) {
++ if (pp1->dev == pp2->dev)
++ continue;
++ if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) {
++ condlog(3, "found multiple paths with wwid %s, "
++ "multipathing %s", pp1->wwid, pp1->dev);
++ return 1;
++ }
++ }
++ if (check_wwids_file(pp1->wwid, 0) < 0) {
++ condlog(3, "wwid %s not in wwids file, skipping %s",
++ pp1->wwid, pp1->dev);
++ return 0;
++ }
++ condlog(3, "found wwid %s in wwids file, multipathing %s", pp1->wwid,
++ pp1->dev);
++ return 1;
++}
++
++int
++remember_wwid(char *wwid)
++{
++ int ret = check_wwids_file(wwid, 1);
++ if (ret < 0){
++ condlog(3, "failed writing wwid %s to wwids file", wwid);
++ return -1;
++ }
++ if (ret == 1)
++ condlog(3, "wrote wwid %s to wwids file", wwid);
++ else
++ condlog(4, "wwid %s already in wwids file", wwid);
++ return 0;
++}
+Index: multipath-tools/libmultipath/finder.h
+===================================================================
+--- /dev/null
++++ multipath-tools/libmultipath/finder.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright (c) 2010 Benjamin Marzinski, Redhat
++ */
++
++#ifndef _FINDER_H
++#define _FINDER_H
++
++#define WWIDS_FILE_HEADER \
++"# Multipath wwids, Version : 1.0\n" \
++"# NOTE: This file is automatically maintained by multipath and multipathd.\n" \
++"# You should not need to edit this file in normal circumstances.\n" \
++"#\n" \
++"# Valid WWIDs:\n"
++
++int should_multipath(struct path *pp, vector pathvec);
++int remember_wwid(char *wwid);
++
++#endif /* _FINDER_H */
+Index: multipath-tools/multipath/main.c
+===================================================================
+--- multipath-tools.orig/multipath/main.c
++++ multipath-tools/multipath/main.c
+@@ -307,7 +307,7 @@ configure (void)
+ /*
+ * core logic entry point
+ */
+- r = coalesce_paths(&vecs, NULL, NULL, conf->force_reload);
++ r = coalesce_paths(&vecs, NULL, refwwid, conf->force_reload);
+
+ out:
+ if (refwwid)
+Index: multipath-tools/multipathd/main.c
+===================================================================
+--- multipath-tools.orig/multipathd/main.c
++++ multipath-tools/multipathd/main.c
+@@ -47,6 +47,7 @@
+ #include <print.h>
+ #include <configure.h>
+ #include <prio.h>
++#include <finder.h>
+
+ #include "main.h"
+ #include "pidfile.h"
+@@ -397,7 +398,7 @@ ev_add_path (char * devname, struct vect
+ */
+ if (memcmp(empty_buff, pp->wwid, WWID_SIZE) == 0) {
+ condlog(0, "%s: failed to get path uid", devname);
+- return 1; /* leave path added to pathvec */
++ goto fail; /* leave path added to pathvec */
+ }
+ if (filter_path(conf, pp) > 0){
+ int i = find_slot(vecs->pathvec, (void *)pp);
+@@ -412,18 +413,26 @@ rescan:
+ condlog(4,"%s: adopting all paths for path %s",
+ mpp->alias, pp->dev);
+ if (adopt_paths(vecs->pathvec, mpp))
+- return 1; /* leave path added to pathvec */
++ goto fail; /* leave path added to pathvec */
+
+ verify_paths(mpp, vecs, NULL);
+ mpp->flush_on_last_del = FLUSH_UNDEF;
+ mpp->action = ACT_RELOAD;
+ }
+ else {
++ if (conf->find_multipaths) {
++ if (should_multipath(pp, vecs->pathvec))
++ remember_wwid(pp->wwid);
++ else {
++ orphan_path(pp);
++ return 0;
++ }
++ }
+ condlog(4,"%s: creating new map", pp->dev);
+ if ((mpp = add_map_with_path(vecs, pp, 1)))
+ mpp->action = ACT_CREATE;
+ else
+- return 1; /* leave path added to pathvec */
++ goto fail; /* leave path added to pathvec */
+ }
+
+ /*
+@@ -432,7 +441,7 @@ rescan:
+ if (setup_map(mpp)) {
+ condlog(0, "%s: failed to setup map for addition of new "
+ "path %s", mpp->alias, devname);
+- goto out;
++ goto fail_map;
+ }
+ /*
+ * reload the map for the multipath mapped device
+@@ -450,7 +459,7 @@ rescan:
+ goto rescan;
+ }
+ else
+- goto out;
++ goto fail_map;
+ }
+ dm_lib_release();
+
+@@ -458,19 +467,21 @@ rescan:
+ * update our state from kernel regardless of create or reload
+ */
+ if (setup_multipath(vecs, mpp))
+- goto out;
++ goto fail_map;
+
+ sync_map_state(mpp);
+
+ if (mpp->action == ACT_CREATE &&
+ start_waiter_thread(mpp, vecs))
+- goto out;
++ goto fail_map;
+
+ condlog(2, "%s path added to devmap %s", devname, mpp->alias);
+ return 0;
+
+-out:
++fail_map:
+ remove_map(mpp, vecs, 1);
++fail:
++ orphan_path(pp);
+ return 1;
+ }
+
+Index: multipath-tools/libmultipath/Makefile
+===================================================================
+--- multipath-tools.orig/libmultipath/Makefile
++++ multipath-tools/libmultipath/Makefile
+@@ -12,7 +12,7 @@ OBJS = memory.o parser.o vector.o devmap
+ pgpolicies.o debug.o regex.o defaults.o uevent.o \
+ switchgroup.o uxsock.o print.o alias.o log_pthread.o \
+ log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
+- lock.o waiter.o
++ lock.o waiter.o file.o finder.o
+
+ LIBDM_API_FLUSH = $(shell if test -d /lib64 ; then objdump -T /lib64/libdevmapper.so* ; else objdump -T /lib/libdevmapper.so.* ; fi | grep -c dm_task_no_flush)
+
+Index: multipath-tools/multipath/mpathconf
+===================================================================
+--- /dev/null
++++ multipath-tools/multipath/mpathconf
+@@ -0,0 +1,232 @@
++#!/bin/sh
++#
++# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
++#
++# This file is part of the device-mapper-multipath package.
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions
++# of the GNU General Public License v.2.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++#
++# Simple editting of /etc/multipath.conf
++# This program was largely ripped off from lvmconf
++#
++
++DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
++CONFIGFILE="/etc/multipath.conf"
++MULTIPATHDIR="/etc/multipath"
++TMPFILE=/etc/multipath/.multipath.conf.tmp
++
++function usage
++{
++ echo "usage: $0 <command>"
++ echo ""
++ echo "Commands:"
++ echo "Enable: --enable [--user_friendly_names <y|n>] [--find_multipaths <y|n>"
++ echo "Disable: --disable"
++ echo "Set user_friendly_names: --user_friendly_names <y|n>"
++ echo "Set find_multipaths: --find_multipaths <y|n>"
++ echo ""
++}
++
++function parse_args
++{
++ while [ -n "$1" ]; do
++ case $1 in
++ --enable)
++ ENABLE=1
++ shift
++ ;;
++ --disable)
++ ENABLE=0
++ shift
++ ;;
++ --user_friendly_names)
++ if [ -n "$2" ]; then
++ FRIENDLY=$2
++ shift 2
++ else
++ usage
++ exit 1
++ fi
++ ;;
++ --find_multipaths)
++ if [ -n "$2" ]; then
++ FIND=$2
++ shift 2
++ else
++ usage
++ exit 1
++ fi
++ ;;
++ *)
++ usage
++ exit
++ esac
++ done
++}
++
++function validate_args
++{
++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" ]; then
++ echo "ignoring extra parameters on disable"
++ FRIENDLY=""
++ FIND=""
++ fi
++ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
++ echo "--user_friendly_names must be either 'y' or 'n'"
++ exit 1
++ fi
++ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
++ echo "--find_multipaths must be either 'y' or 'n'"
++ exit 1
++ fi
++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
++ DISPLAY=1
++ fi
++}
++
++umask 0077
++
++parse_args "$@"
++
++validate_args
++
++if [ ! -d "$MULTIPATHDIR" ]; then
++ echo "/etc/multipath/ does not exist. failing"
++ exit 1
++fi
++
++rm $TMPFILE 2> /dev/null
++if [ -f "$CONFIGFILE" ]; then
++ cp $CONFIGFILE $TMPFILE
++elif [ -f "$DEFAULT_CONFIGFILE" ]; then
++ cp $DEFAULT_CONFIGFILE $TMPFILE
++else
++ touch $TMPFILE
++fi
++
++if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
++ HAVE_BLACKLIST=1
++fi
++
++if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
++ HAVE_DEFAULTS=1
++fi
++
++if [ "$HAVE_BLACKLIST" = "1" ]; then
++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
++ HAVE_DISABLE=1
++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"" ; then
++ HAVE_DISABLE=0
++ fi
++fi
++
++if [ "$HAVE_DEFAULTS" = "1" ]; then
++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
++ HAVE_FIND=1
++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
++ HAVE_FIND=0
++ fi
++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
++ HAVE_FRIENDLY=1
++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
++ HAVE_FRIENDLY=0
++ fi
++fi
++
++if [ -n "$DISPLAY" ]; then
++ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
++ echo "multipath is enabled"
++ else
++ echo "multipath is disabled"
++ fi
++ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
++ echo "find_multipaths is disabled"
++ else
++ echo "find_multipaths is enabled"
++ fi
++ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
++ echo "user_friendly_names is disabled"
++ else
++ echo "user_friendly_names is enabled"
++ fi
++ exit 0
++fi
++
++if [ -z "$HAVE_BLACKLIST" ]; then
++ cat >> $TMPFILE <<- _EOF_
++
++blacklist {
++}
++_EOF_
++fi
++
++if [ -z "$HAVE_DEFAULTS" ]; then
++ cat >> $TMPFILE <<- _EOF_
++
++defaults {
++}
++_EOF_
++fi
++
++if [ "$ENABLE" = 1 ]; then
++ if [ "$HAVE_DISABLE" = 1 ]; then
++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
++ fi
++elif [ "$ENABLE" = 0 ]; then
++ if [ -z "$HAVE_DISABLE" ]; then
++ sed -i '/^blacklist[[:space:]]*{/ a\
++ devnode "*"
++' $TMPFILE
++ elif [ "$HAVE_DISABLE" = 0 ]; then
++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
++ fi
++fi
++
++if [ "$FIND" = "n" ]; then
++ if [ "$HAVE_FIND" = 1 ]; then
++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
++ fi
++elif [ "$FIND" = "y" ]; then
++ if [ -z "$HAVE_FIND" ]; then
++ sed -i '/^defaults[[:space:]]*{/ a\
++ find_multipaths yes
++' $TMPFILE
++ elif [ "$HAVE_FIND" = 0 ]; then
++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
++ fi
++fi
++
++if [ "$FRIENDLY" = "n" ]; then
++ if [ "$HAVE_FRIENDLY" = 1 ]; then
++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
++ fi
++elif [ "$FRIENDLY" = "y" ]; then
++ if [ -z "$HAVE_FRIENDLY" ]; then
++ sed -i '/^defaults[[:space:]]*{/ a\
++ user_friendly_names yes
++' $TMPFILE
++ elif [ "$HAVE_FRIENDLY" = 0 ]; then
++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
++ fi
++fi
++
++cp $CONFIGFILE $CONFIGFILE.old
++if [ $? != 0 ]; then
++ echo "failed to backup old config file, $CONFIGFILE not updated"
++ exit 1
++fi
++
++cp $TMPFILE $CONFIGFILE
++if [ $? != 0 ]; then
++ echo "failed to copy new config file into place, check $CONFIGFILE is still OK"
++ exit 1
++fi
++
++rm -f $TMPFILE
+Index: multipath-tools/multipath/Makefile
+===================================================================
+--- multipath-tools.orig/multipath/Makefile
++++ multipath-tools/multipath/Makefile
+@@ -21,6 +21,7 @@ $(EXEC): $(OBJS)
+ install:
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
+ $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
++ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
+ $(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
+ $(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
+@@ -31,6 +32,7 @@ install:
+ uninstall:
+ rm $(DESTDIR)/lib/udev/rules.d/multipath.rules
+ rm $(DESTDIR)$(bindir)/$(EXEC)
++ rm $(DESTDIR)$(bindir)/mpathconf
+ rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
+ rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
+
diff --git a/0022-RHBZ-557845-RHEL5-style-partitions.patch b/0022-RHBZ-557845-RHEL5-style-partitions.patch
new file mode 100644
index 0000000..72a0910
--- /dev/null
+++ b/0022-RHBZ-557845-RHEL5-style-partitions.patch
@@ -0,0 +1,325 @@
+---
+ kpartx/bsd.c | 35 ----------------
+ kpartx/dos.c | 7 +--
+ kpartx/kpartx.c | 121 +++++++-------------------------------------------------
+ kpartx/kpartx.h | 1
+ kpartx/sun.c | 35 ----------------
+ 5 files changed, 24 insertions(+), 175 deletions(-)
+
+Index: multipath-tools/kpartx/bsd.c
+===================================================================
+--- multipath-tools.orig/kpartx/bsd.c
++++ multipath-tools/kpartx/bsd.c
+@@ -50,10 +50,10 @@ int
+ read_bsd_pt(int fd, struct slice all, struct slice *sp, int ns) {
+ struct bsd_disklabel *l;
+ struct bsd_partition *p;
+- unsigned int offset = all.start, end;
++ unsigned int offset = all.start;
+ int max_partitions;
+ char *bp;
+- int n = 0, i, j;
++ int n = 0;
+
+ bp = getblock(fd, offset+1); /* 1 sector suffices */
+ if (bp == NULL)
+@@ -79,36 +79,5 @@ read_bsd_pt(int fd, struct slice all, st
+ break;
+ }
+ }
+- /*
+- * Convention has it that the bsd disklabel will always have
+- * the 'c' partition spanning the entire disk.
+- * So we have to check for contained slices.
+- */
+- for(i = 0; i < n; i++) {
+- if (sp[i].size == 0)
+- continue;
+-
+- end = sp[i].start + sp[i].size;
+- for(j = 0; j < n; j ++) {
+- if ( i == j )
+- continue;
+- if (sp[j].size == 0)
+- continue;
+-
+- if (sp[i].start < sp[j].start) {
+- if (end > sp[j].start &&
+- end < sp[j].start + sp[j].size) {
+- /* Invalid slice */
+- fprintf(stderr,
+- "bsd_disklabel: slice %d overlaps with %d\n", i , j);
+- sp[i].size = 0;
+- }
+- } else {
+- if (end <= sp[j].start + sp[j].size) {
+- sp[i].container = j + 1;
+- }
+- }
+- }
+- }
+ return n;
+ }
+Index: multipath-tools/kpartx/dos.c
+===================================================================
+--- multipath-tools.orig/kpartx/dos.c
++++ multipath-tools/kpartx/dos.c
+@@ -16,7 +16,7 @@ is_extended(int type) {
+ }
+
+ static int
+-read_extended_partition(int fd, struct partition *ep, int en,
++read_extended_partition(int fd, struct partition *ep,
+ struct slice *sp, int ns)
+ {
+ struct partition p;
+@@ -53,7 +53,6 @@ read_extended_partition(int fd, struct p
+ if (n < ns) {
+ sp[n].start = here + le32_to_cpu(p.start_sect);
+ sp[n].size = le32_to_cpu(p.nr_sects);
+- sp[n].container = en + 1;
+ n++;
+ } else {
+ fprintf(stderr,
+@@ -98,7 +97,9 @@ read_dos_pt(int fd, struct slice all, st
+ break;
+ }
+ if (is_extended(p.sys_type)) {
+- n += read_extended_partition(fd, &p, i, sp+n, ns-n);
++ n += read_extended_partition(fd, &p, sp+n, ns-n);
++ /* hide the extended partition itself */
++ sp[i].size = 0;
+ }
+ }
+ return n;
+Index: multipath-tools/kpartx/kpartx.c
+===================================================================
+--- multipath-tools.orig/kpartx/kpartx.c
++++ multipath-tools/kpartx/kpartx.c
+@@ -184,7 +184,7 @@ get_hotplug_device(void)
+
+ int
+ main(int argc, char **argv){
+- int fd, i, j, m, n, op, off, arg, c, d;
++ int fd, i, j, k, n, op, off, arg;
+ struct slice all;
+ struct pt *ptp;
+ enum action what = LIST;
+@@ -350,49 +350,30 @@ main(int argc, char **argv){
+ else
+ continue;
+
++ /*
++ * test for overlap, as in the case of an extended partition
++ * zero their size to avoid mapping
++ */
++ for (j = 0; j < n; j++) {
++ for (k = j + 1; k < n; k++) {
++ if (slices[k].start > slices[j].start &&
++ slices[k].start < slices[j].start +
++ slices[j].size)
++ slices[j].size = 0;
++ }
++ }
++
+ switch(what) {
+ case LIST:
+- for (j = 0, c = 0, m = 0; j < n; j++) {
++ for (j = 0; j < n; j++) {
+ if (slices[j].size == 0)
+ continue;
+- if (slices[j].container > 0) {
+- c++;
+- continue;
+- }
+-
+- slices[j].minor = m++;
+
+ printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
+ mapname, delim, j+1,
+ slices[j].size, device,
+ slices[j].start);
+ }
+- /* Loop to resolve contained slices */
+- d = c;
+- while (c) {
+- for (j = 0; j < n; j++) {
+- uint64_t start;
+- int k = slices[j].container - 1;
+-
+- if (slices[j].size == 0)
+- continue;
+- if (slices[j].minor > 0)
+- continue;
+- if (slices[j].container == 0)
+- continue;
+- slices[j].minor = m++;
+-
+- start = slices[j].start - slices[k].start;
+- printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
+- mapname, delim, j+1,
+- slices[j].size,
+- slices[k].minor, start);
+- c--;
+- }
+- /* Terminate loop if nothing more to resolve */
+- if (d == c)
+- break;
+- }
+
+ if (loopcreated && S_ISREG (buf.st_mode)) {
+ if (del_loop(device)) {
+@@ -438,16 +419,10 @@ main(int argc, char **argv){
+ break;
+
+ case ADD:
+- for (j = 0, c = 0; j < n; j++) {
++ for (j = 0; j < n; j++) {
+ if (slices[j].size == 0)
+ continue;
+
+- /* Skip all contained slices */
+- if (slices[j].container > 0) {
+- c++;
+- continue;
+- }
+-
+ if (safe_sprintf(partname, "%s%s%d",
+ mapname, delim, j+1)) {
+ fprintf(stderr, "partname too small\n");
+@@ -488,70 +463,6 @@ main(int argc, char **argv){
+ slices[j].minor, slices[j].size,
+ DM_TARGET, params);
+ }
+- /* Loop to resolve contained slices */
+- d = c;
+- while (c) {
+- for (j = 0; j < n; j++) {
+- uint64_t start;
+- int k = slices[j].container - 1;
+-
+- if (slices[j].size == 0)
+- continue;
+-
+- /* Skip all existing slices */
+- if (slices[j].minor > 0)
+- continue;
+-
+- /* Skip all simple slices */
+- if (slices[j].container == 0)
+- continue;
+-
+- /* Check container slice */
+- if (slices[k].size == 0)
+- fprintf(stderr, "Invalid slice %d\n",
+- k);
+-
+- if (safe_sprintf(partname, "%s%s%d",
+- mapname, delim, j+1)) {
+- fprintf(stderr, "partname too small\n");
+- exit(1);
+- }
+- strip_slash(partname);
+-
+- start = slices[j].start - slices[k].start;
+- if (safe_sprintf(params, "%d:%d %" PRIu64,
+- slices[k].major,
+- slices[k].minor,
+- start)) {
+- fprintf(stderr, "params too small\n");
+- exit(1);
+- }
+-
+- op = (dm_map_present(partname) ?
+- DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
+-
+- dm_addmap(op, partname, DM_TARGET, params,
+- slices[j].size, uuid, j+1,
+- buf.st_mode & 0777,
+- buf.st_uid, buf.st_gid);
+-
+- if (op == DM_DEVICE_RELOAD)
+- dm_simplecmd(DM_DEVICE_RESUME,
+- partname, 1);
+-
+- dm_devn(partname, &slices[j].major,
+- &slices[j].minor);
+-
+- if (verbose)
+- printf("add map %s : 0 %" PRIu64 " %s %s\n",
+- partname, slices[j].size,
+- DM_TARGET, params);
+- c--;
+- }
+- /* Terminate loop */
+- if (d == c)
+- break;
+- }
+ break;
+
+ default:
+Index: multipath-tools/kpartx/kpartx.h
+===================================================================
+--- multipath-tools.orig/kpartx/kpartx.h
++++ multipath-tools/kpartx/kpartx.h
+@@ -24,7 +24,6 @@
+ struct slice {
+ uint64_t start;
+ uint64_t size;
+- int container;
+ int major;
+ int minor;
+ };
+Index: multipath-tools/kpartx/sun.c
+===================================================================
+--- multipath-tools.orig/kpartx/sun.c
++++ multipath-tools/kpartx/sun.c
+@@ -62,8 +62,8 @@ int
+ read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
+ struct sun_disk_label *l;
+ struct sun_raw_part *s;
+- unsigned int offset = all.start, end;
+- int i, j, n;
++ unsigned int offset = all.start;
++ int i, n;
+ char *bp;
+
+ bp = getblock(fd, offset);
+@@ -95,37 +95,6 @@ read_sun_pt(int fd, struct slice all, st
+ break;
+ }
+ }
+- /*
+- * Convention has it that the SUN disklabel will always have
+- * the 'c' partition spanning the entire disk.
+- * So we have to check for contained slices.
+- */
+- for(i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
+- if (sp[i].size == 0)
+- continue;
+-
+- end = sp[i].start + sp[i].size;
+- for(j = 0; j < SUN_DISK_MAXPARTITIONS; j ++) {
+- if ( i == j )
+- continue;
+- if (sp[j].size == 0)
+- continue;
+-
+- if (sp[i].start < sp[j].start) {
+- if (end > sp[j].start &&
+- end < sp[j].start + sp[j].size) {
+- /* Invalid slice */
+- fprintf(stderr,
+- "sun_disklabel: slice %d overlaps with %d\n", i , j);
+- sp[i].size = 0;
+- }
+- } else {
+- if (end <= sp[j].start + sp[j].size) {
+- sp[i].container = j + 1;
+- }
+- }
+- }
+- }
+ return n;
+ }
+
diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec
index f97e3af..7d50a9e 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: 11%{?dist}
+Release: 12%{?dist}
License: GPL+
Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/
@@ -11,6 +11,7 @@ Source1: multipath.conf
# patch that should go upstream
Patch1: 0001-for-upstream-add-tpg_pref-prioritizer.patch
Patch2: 0002-for-upstream-add-tmo-config-options.patch
+Patch3: 0003-for-upstream-default-configs.patch
# local patches
Patch1001: 0001-RH-queue-without-daemon.patch
Patch1002: 0002-RH-path-checker.patch
@@ -27,6 +28,13 @@ Patch1012: 0012-RH-explicitly-disable-dm-udev-sync-support-in-kpartx.patch
Patch1013: 0013-RH-add-weighted_prio-prioritizer.patch
Patch1014: 0014-RH-add-hp_tur-checker.patch
Patch1015: 0015-RH-add-multipathd-count-paths-cmd.patch
+Patch1016: 0016-RHBZ-554561-fix-init-error-msg.patch
+Patch1017: 0017-RHBZ-554592-man-page-note.patch
+Patch1018: 0018-RHBZ-554596-SUN-6540-config.patch
+Patch1019: 0019-RHBZ-554598-fix-multipath-locking.patch
+Patch1020: 0020-RHBZ-554605-fix-manual-failover.patch
+Patch1021: 0021-RHBZ-548874-add-find-multipaths.patch
+Patch1022: 0022-RHBZ-557845-RHEL5-style-partitions.patch
# runtime
Requires: %{name}-libs = %{version}-%{release}
@@ -72,6 +80,7 @@ kpartx manages partition creation and removal for device-mapper devices.
%setup -q -n multipath-tools
%patch1 -p1
%patch2 -p1
+%patch3 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
@@ -87,6 +96,13 @@ kpartx manages partition creation and removal for device-mapper devices.
%patch1013 -p1
%patch1014 -p1
%patch1015 -p1
+%patch1016 -p1
+%patch1017 -p1
+%patch1018 -p1
+%patch1019 -p1
+%patch1020 -p1
+%patch1021 -p1
+%patch1022 -p1
cp %{SOURCE1} .
%build
@@ -108,8 +124,6 @@ make install \
# tree fix up
# install -m 0644 %{SOURCE1} %{buildroot}/etc/multipath.conf
install -d %{buildroot}/etc/multipath
-mv %{buildroot}/etc/udev/rules.d/multipath.rules \
- %{buildroot}/etc/udev/rules.d/40-multipath.rules
%clean
rm -rf %{buildroot}
@@ -138,11 +152,12 @@ fi
%{_sbindir}/multipath
%{_sbindir}/multipathd
%{_sbindir}/cciss_id
+%{_sbindir}/mpathconf
%{_initrddir}/multipathd
%{_mandir}/man5/multipath.conf.5.gz
%{_mandir}/man8/multipath.8.gz
%{_mandir}/man8/multipathd.8.gz
-%config /etc/udev/rules.d/40-multipath.rules
+%config /lib/udev/rules.d/40-multipath.rules
%doc AUTHOR COPYING FAQ
%doc multipath.conf multipath.conf.annotated
%doc multipath.conf.defaults multipath.conf.synthetic
@@ -165,6 +180,27 @@ fi
%{_mandir}/man8/kpartx.8.gz
%changelog
+* Fri Jan 22 2010 Benjamin Marzinski <bmarzins@redhat.com> -0.4.9-12
+- Refresh 0001-RH-queue-without-daemon.patch
+- Refresh 0002-RH-path-checker.patch
+- Modify 0010-RH-multipath-rules-udev-changes.patch
+ * Fix udev rules to use DM_SBIN_PATH when calling kpartx
+ * install udev rules to /lib/udev/rules.d instead of /etc/udev/rules.d
+- Modify 0014-RH-add-hp_tur-checker.patch
+- Add 0003-for-upstream-default-configs.patch
+- Add 0016-RHBZ-554561-fix-init-error-msg.patch
+- Add 0017-RHBZ-554592-man-page-note.patch
+- Add 0018-RHBZ-554596-SUN-6540-config.patch
+- Add 0019-RHBZ-554598-fix-multipath-locking.patch
+- Add 0020-RHBZ-554605-fix-manual-failover.patch
+- Add 0021-RHBZ-548874-add-find-multipaths.patch
+ * Added find_multipaths multipath.conf option
+ * Added /sbin/mpathconf for simple editting of multipath.conf
+- Add 0022-RHBZ-557845-RHEL5-style-partitions.patch
+ * Make kpartx deal with logical partitions like it did in RHEL5.
+ Don't create a dm-device for the extended partition itself.
+ Create the logical partitions on top of the dm-device for the whole disk.
+
* Mon Nov 16 2009 Benjamin Marzinski <bmarzins@redhat.com> -0.4.9-11
- Add 0002-for-upstream-add-tmo-config-options.patch
* Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options