From 814d7d2747caab70c0ac0a23ebcdede356d02836 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Sat, 23 Jan 2010 01:39:39 +0000 Subject: [PATCH] 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. --- 0001-RH-queue-without-daemon.patch | 59 +- 0002-RH-path-checker.patch | 59 +- 0003-for-upstream-default-configs.patch | 56 + 0010-RH-multipath-rules-udev-changes.patch | 39 +- 0014-RH-add-hp_tur-checker.patch | 28 +- 0016-RHBZ-554561-fix-init-error-msg.patch | 23 + 0017-RHBZ-554592-man-page-note.patch | 17 + 0018-RHBZ-554596-SUN-6540-config.patch | 57 + 0019-RHBZ-554598-fix-multipath-locking.patch | 43 + 0020-RHBZ-554605-fix-manual-failover.patch | 52 + 0021-RHBZ-548874-add-find-multipaths.patch | 1137 +++++++++++++++++ 0022-RHBZ-557845-RHEL5-style-partitions.patch | 325 +++++ device-mapper-multipath.spec | 44 +- 13 files changed, 1862 insertions(+), 77 deletions(-) create mode 100644 0003-for-upstream-default-configs.patch create mode 100644 0016-RHBZ-554561-fix-init-error-msg.patch create mode 100644 0017-RHBZ-554592-man-page-note.patch create mode 100644 0018-RHBZ-554596-SUN-6540-config.patch create mode 100644 0019-RHBZ-554598-fix-multipath-locking.patch create mode 100644 0020-RHBZ-554605-fix-manual-failover.patch create mode 100644 0021-RHBZ-548874-add-find-multipaths.patch create mode 100644 0022-RHBZ-557845-RHEL5-style-partitions.patch 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 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 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 --- :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 +-#include +-#include +-#include + #include + #include + #include + #include + #include +-#include + + #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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 + #include + #include ++#include + + #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 " ++ echo "" ++ echo "Commands:" ++ echo "Enable: --enable [--user_friendly_names ] [--find_multipaths " ++ echo "Disable: --disable" ++ echo "Set user_friendly_names: --user_friendly_names " ++ echo "Set find_multipaths: --find_multipaths " ++ 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 -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 -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