From 542c8d8bff557bb8b620443635f22f940001443c Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 7 Nov 2017 17:51:09 -0600 Subject: device-mapper-multipath-0.7.3-1 Update Source to upstream 0.7.3 release * Previous patch 0001 is included in this commit, and 0002 was solved in a different manner causing some change to previous patch 0003 * Previous patches 0003-0010 are now patches 0007-0014 Add 0001-mpathpersist-Fix-invalid-condition-check.patch * Fix incorrect check. posted upstream Add 0002-multipath-add-man-page-info-for-my-prkey-changes.patch * Add missing man page info. posted upstream Add 0003-multipath-there-is-no-none-path-state.patch * remove incorrect path state. posted upstream Add 0004-mutipath-updated-Huawei-storage-config.patch * update builtin device configuration. posted upstream Add 0005-multipath-fix-doc-typo.patch * fix man page typo. posted upstream Add 0006-multipath-add-ghost_delay-parameter.patch * add new multipath.conf parameter "ghost_delay". posted upstream --- .gitignore | 1 + ...bmultipath-update-3PARdata-builtin-config.patch | 28 - ...-mpathpersist-Fix-invalid-condition-check.patch | 35 ++ ...th-add-man-page-info-for-my-prkey-changes.patch | 79 +++ ...ltipath-attempt-at-common-multipath.rules.patch | 107 ---- 0003-RH-fixup-udev-rules-for-redhat.patch | 110 ---- 0003-multipath-there-is-no-none-path-state.patch | 27 + ...-the-property-blacklist-exception-builtin.patch | 70 --- 0004-mutipath-updated-Huawei-storage-config.patch | 30 + 0005-RH-don-t-start-without-a-config-file.patch | 108 ---- 0005-multipath-fix-doc-typo.patch | 29 + 0006-RH-use-rpm-optflags-if-present.patch | 50 -- 0006-multipath-add-ghost_delay-parameter.patch | 397 +++++++++++++ 0007-RH-add-mpathconf.patch | 648 --------------------- 0007-RH-fixup-udev-rules-for-redhat.patch | 66 +++ ...-the-property-blacklist-exception-builtin.patch | 70 +++ ...ds-from-kernel-cmdline-mpath.wwids-with-A.patch | 166 ------ 0009-RH-don-t-start-without-a-config-file.patch | 108 ++++ ...gger-change-uevent-on-new-device-creation.patch | 138 ----- 0010-RH-use-rpm-optflags-if-present.patch | 50 ++ ...-warn-on-invalid-regex-instead-of-failing.patch | 121 ---- 0011-RH-add-mpathconf.patch | 648 +++++++++++++++++++++ ...ds-from-kernel-cmdline-mpath.wwids-with-A.patch | 166 ++++++ ...gger-change-uevent-on-new-device-creation.patch | 138 +++++ ...-warn-on-invalid-regex-instead-of-failing.patch | 121 ++++ device-mapper-multipath.spec | 61 +- sources | 2 +- 27 files changed, 2012 insertions(+), 1562 deletions(-) delete mode 100644 0001-libmultipath-update-3PARdata-builtin-config.patch create mode 100644 0001-mpathpersist-Fix-invalid-condition-check.patch create mode 100644 0002-multipath-add-man-page-info-for-my-prkey-changes.patch delete mode 100644 0002-multipath-attempt-at-common-multipath.rules.patch delete mode 100644 0003-RH-fixup-udev-rules-for-redhat.patch create mode 100644 0003-multipath-there-is-no-none-path-state.patch delete mode 100644 0004-RH-Remove-the-property-blacklist-exception-builtin.patch create mode 100644 0004-mutipath-updated-Huawei-storage-config.patch delete mode 100644 0005-RH-don-t-start-without-a-config-file.patch create mode 100644 0005-multipath-fix-doc-typo.patch delete mode 100644 0006-RH-use-rpm-optflags-if-present.patch create mode 100644 0006-multipath-add-ghost_delay-parameter.patch delete mode 100644 0007-RH-add-mpathconf.patch create mode 100644 0007-RH-fixup-udev-rules-for-redhat.patch create mode 100644 0008-RH-Remove-the-property-blacklist-exception-builtin.patch delete mode 100644 0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch create mode 100644 0009-RH-don-t-start-without-a-config-file.patch delete mode 100644 0009-RH-trigger-change-uevent-on-new-device-creation.patch create mode 100644 0010-RH-use-rpm-optflags-if-present.patch delete mode 100644 0010-RH-warn-on-invalid-regex-instead-of-failing.patch create mode 100644 0011-RH-add-mpathconf.patch create mode 100644 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch create mode 100644 0013-RH-trigger-change-uevent-on-new-device-creation.patch create mode 100644 0014-RH-warn-on-invalid-regex-instead-of-failing.patch diff --git a/.gitignore b/.gitignore index 13608b9..7ff8a6c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ multipath-tools-091027.tar.gz /multipath-tools-f21166a.tgz /multipath.conf /multipath-tools-git847cc43.tgz +/multipath-tools-0.7.3.tgz diff --git a/0001-libmultipath-update-3PARdata-builtin-config.patch b/0001-libmultipath-update-3PARdata-builtin-config.patch deleted file mode 100644 index 578716a..0000000 --- a/0001-libmultipath-update-3PARdata-builtin-config.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 26 Jun 2017 14:03:19 -0500 -Subject: [PATCH] libmultipath: update 3PARdata builtin config - -This updated config comes from hp. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 390d143..54bdcfc 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -49,6 +49,8 @@ static struct hwentry default_hw[] = { - .hwhandler = "1 alua", - .prio_name = PRIO_ALUA, - .no_path_retry = 18, -+ .fast_io_fail = 10, -+ .dev_loss = MAX_DEV_LOSS_TMO, - }, - { - /* RA8000 / ESA12000 */ --- -2.7.4 - diff --git a/0001-mpathpersist-Fix-invalid-condition-check.patch b/0001-mpathpersist-Fix-invalid-condition-check.patch new file mode 100644 index 0000000..4f7b6bb --- /dev/null +++ b/0001-mpathpersist-Fix-invalid-condition-check.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 6 Sep 2017 16:27:36 -0500 +Subject: [PATCH] mpathpersist: Fix invalid condition check + +In commit 1990257c (mpathpersist: add support for prkeys file), the +check to see if mpathpersist needed to tell multipathd to update a +device's prkey was wrong. It had a typo that made it evaluate to true +for any service action, instead of just for registrations. This is the +correct check. + +Signed-off-by: Benjamin Marzinski +--- + libmpathpersist/mpath_persist.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c +index b5ed556..84ab293 100644 +--- a/libmpathpersist/mpath_persist.c ++++ b/libmpathpersist/mpath_persist.c +@@ -339,8 +339,9 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, + + memcpy(&prkey, paramp->sa_key, 8); + if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && +- ((!get_be64(mpp->reservation_key) && MPATH_PROUT_REG_SA) || +- MPATH_PROUT_REG_IGN_SA)) { ++ ((!get_be64(mpp->reservation_key) && ++ rq_servact == MPATH_PROUT_REG_SA) || ++ rq_servact == MPATH_PROUT_REG_IGN_SA)) { + memcpy(&mpp->reservation_key, paramp->sa_key, 8); + if (update_prkey(alias, get_be64(mpp->reservation_key))) { + condlog(0, "%s: failed to set prkey for multipathd.", +-- +2.7.4 + diff --git a/0002-multipath-add-man-page-info-for-my-prkey-changes.patch b/0002-multipath-add-man-page-info-for-my-prkey-changes.patch new file mode 100644 index 0000000..0ce4f81 --- /dev/null +++ b/0002-multipath-add-man-page-info-for-my-prkey-changes.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 19 Sep 2017 16:29:18 -0500 +Subject: [PATCH] multipath: add man page info for my prkey changes + +Update the man pages to list the new configuration options and +multipathd commands. + +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 17 +++++++++++++++++ + multipathd/multipathd.8 | 16 ++++++++++++++++ + 2 files changed, 33 insertions(+) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 5b6dde7..92ad8b1 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -682,6 +682,17 @@ The default is: \fB/etc/multipath/wwids\fR + . + . + .TP ++.B prkeys_file ++The full pathname of the prkeys file, which is used by multipathd to keep ++track of the persistent reservation key used for a specific WWID, when ++\fIreservation_key\fR is set to \fBfile\fR. ++.RS ++.TP ++The default is \fB/etc/multipath/prkeys\fR ++.RE ++. ++. ++.TP + .B log_checker_err + If set to + .I once +@@ -703,6 +714,12 @@ the same as the RESERVATION KEY field of the PERSISTENT RESERVE OUT parameter + list which contains an 8-byte value provided by the application client to the + device server to identify the I_T nexus. + .RS ++.PP ++Alternatively, this can be set to \fBfile\fR, which will store the RESERVATION ++KEY registered by mpathpersist in the \fIprkeys_file\fR. multipathd will then ++use this key to register additional paths as they appear. When the ++registration is removed, the RESERVATION KEY is removed from the ++\fIprkeys_file\fR. + .TP + The default is: \fB\fR + .RE +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index 2615728..5c96680 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -247,6 +247,22 @@ Disable persistent reservation management on $map. + Get the current persistent reservation management status of $map. + . + .TP ++.B map|multipath $map getprkey ++Get the current persistent reservation key associated with $map. ++. ++.TP ++.B map|multipath $map setprkey key $key ++Set the persistent reservation key associated with $map to $key in the ++\fIprkeys_file\fR. This key will only be used by multipathd if ++\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++. ++.TP ++.B map|multipath $map unsetprkey ++Remove the persistent reservation key associated with $map from the ++\fIprkeys_file\fR. This will only unset the key used by multipathd if ++\fIreservation_key\fR is set to \fBfile\fR in \fI/etc/multipath.conf\fR. ++. ++.TP + .B quit|exit + End interactive session. + . +-- +2.7.4 + diff --git a/0002-multipath-attempt-at-common-multipath.rules.patch b/0002-multipath-attempt-at-common-multipath.rules.patch deleted file mode 100644 index 076c1e0..0000000 --- a/0002-multipath-attempt-at-common-multipath.rules.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 12 Apr 2017 09:07:51 -0500 -Subject: [PATCH] multipath: attempt at common multipath.rules - -This is a proposal to try and bring the Redhat and SuSE multipath.rules -closer. There are a couple of changes that I'd like some input on. - -The big change is moving the kpartx call into the multipath rules. Half -of the current kpartx.rules file is about creating symlinks for multiple -types of dm devices. The other half auto-creates kpartx devices on top -of multipath devices. Since it is only creating kpartx devices on top of -multipath devices, I've moved the these rules into multipath.rules, or -rather, I've replaced them with the redhat rules in multipath.rules. The -biggest difference is the kpartx isn't run on every reload. It works -with the 11-dm-mpath.rules code to not run kpartx on multipathd -generated reloads or when there aren't any working paths. It does -remember if it didn't get to run kpartx when it was supposed to (because -there were no valid paths or the device was suspended) and will make -sure to run it on the next possible uevent. - -The other change is the redhat multipath rules remove the partition -device nodes for devices claimed by multipath. The udev rule will only -do this one time (both to keep from running partx on every event, and so -that if users manually reread the partition table, we don't keep -removing them when clearly they are wanted). Redhat does this because we -had multiple customer issues where they were using the scsi partitions -instead of the kpartx devices. Obviously, with setting the partition -devices to not ready and clearing their fs_type, this isn't essential, -but it has helped make customers do the right thing. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 8 -------- - multipath/multipath.rules | 27 ++++++++++++++++++++++++--- - 2 files changed, 24 insertions(+), 11 deletions(-) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index a958791..906e320 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -34,12 +34,4 @@ ENV{ID_FS_LABEL_ENC}=="?*", IMPORT{db}="ID_FS_LABEL_ENC" - ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", \ - SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" - --# Create dm tables for partitions --ENV{DM_ACTION}=="PATH_FAILED|PATH_REINSTATED", GOTO="kpartx_end" --ENV{DM_NR_VALID_PATHS}=="0", GOTO="kpartx_end" --ENV{ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" --ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="kpartx_end" --ENV{DM_STATE}!="SUSPENDED", ENV{DM_UUID}=="mpath-*", \ -- RUN+="/sbin/kpartx -un -p -part /dev/$name" -- - LABEL="kpartx_end" -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 86defc0..616a04c 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -1,13 +1,13 @@ - # Set DM_MULTIPATH_DEVICE_PATH if the device should be handled by multipath - SUBSYSTEM!="block", GOTO="end_mpath" - ACTION!="add|change", GOTO="end_mpath" --KERNEL!="sd*|dasd*", GOTO="end_mpath" -- -+KERNEL!="sd*|dasd*|rbd*|dm-*", GOTO="end_mpath" - IMPORT{cmdline}="nompath" - ENV{nompath}=="?*", GOTO="end_mpath" - IMPORT{cmdline}="multipath" - ENV{multipath}=="off", GOTO="end_mpath" - -+KERNEL=="dm-*", GOTO="check_kpartx" - ENV{DEVTYPE}!="partition", GOTO="test_dev" - IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" - ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{ID_FS_TYPE}="none", \ -@@ -21,7 +21,28 @@ TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin" - - ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \ - PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -u %k", \ -- ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="none", \ -+ ENV{DM_MULTIPATH_DEVICE_PATH}="1", ENV{ID_FS_TYPE}="mpath_member", \ - ENV{SYSTEMD_READY}="0" - -+ENV{DM_MULTIPATH_DEVICE_PATH}!="1", GOTO="end_mpath" -+ -+IMPORT{db}="DM_MULTIPATH_WIPE_PARTS" -+ENV{DM_MULTIPATH_WIPE_PARTS}!="1", ENV{DM_MULTIPATH_WIPE_PARTS}="1", \ -+ RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}" -+GOTO="end_mpath" -+ -+LABEL="check_kpartx" -+ -+IMPORT{db}="DM_MULTIPATH_NEED_KPARTX" -+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" -+ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="end_mpath" -+ACTION!="change", GOTO="end_mpath" -+ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath" -+ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPATH_NEED_KPARTX}="1" -+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath" -+ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath" -+ENV{DM_ACTIVATION}!="1", ENV{DM_MULTIPATH_NEED_KPARTX}!="1", GOTO="end_mpath" -+RUN+="/sbin/kpartx -un -p -part /dev/$name" -+ENV{DM_MULTIPATH_NEED_KPARTX}="" -+ - LABEL="end_mpath" --- -2.7.4 - diff --git a/0003-RH-fixup-udev-rules-for-redhat.patch b/0003-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index fc94375..0000000 --- a/0003-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 13 Apr 2017 07:22:23 -0500 -Subject: [PATCH] RH: fixup udev rules for redhat - -The multipath rules need to run after scsi_id is run. This means moving -them after 60-persistent-storage.rules for redhat. Also, we don't -currently set up all the symlinks that SuSE does. If we want them, they -should be done in the device-mapper package, since they are for all -device-mapper devices. Redhat also uses a different naming scheme for -partitions than SuSE. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - kpartx/Makefile | 14 +++++++------- - multipath/Makefile | 4 ++-- - multipath/multipath.rules | 3 ++- - 4 files changed, 12 insertions(+), 11 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 29c290a..cea015b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -48,7 +48,7 @@ endif - prefix = - exec_prefix = $(prefix) - usr_prefix = $(prefix) --bindir = $(exec_prefix)/sbin -+bindir = $(exec_prefix)/usr/sbin - libudevdir = $(prefix)/$(SYSTEMDPATH)/udev - udevrulesdir = $(libudevdir)/rules.d - multipathdir = $(TOPDIR)/libmultipath -diff --git a/kpartx/Makefile b/kpartx/Makefile -index 7b75032..bfa6fe8 100644 ---- a/kpartx/Makefile -+++ b/kpartx/Makefile -@@ -26,19 +26,19 @@ $(EXEC): $(OBJS) - install: $(EXEC) $(EXEC).8 - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -- $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -- $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+# $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir) -+# $(INSTALL_PROGRAM) -m 755 kpartx_id $(DESTDIR)$(libudevdir) -+# $(INSTALL_PROGRAM) -d $(DESTDIR)$(libudevdir)/rules.d -+# $(INSTALL_PROGRAM) -m 644 kpartx.rules $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz -- $(RM) $(DESTDIR)$(libudevdir)/kpartx_id -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules -+# $(RM) $(DESTDIR)$(libudevdir)/kpartx_id -+# $(RM) $(DESTDIR)$(libudevdir)/rules.d/66-kpartx.rules -+# $(RM) $(DESTDIR)$(libudevdir)/rules.d/67-kpartx-compat.rules - - clean: - $(RM) core *.o $(EXEC) *.gz -diff --git a/multipath/Makefile b/multipath/Makefile -index c85314e..1e9ee4b 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -24,7 +24,7 @@ install: - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -@@ -33,7 +33,7 @@ install: - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz - -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 616a04c..4d78b98 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -33,6 +33,7 @@ GOTO="end_mpath" - - LABEL="check_kpartx" - -+ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10" - IMPORT{db}="DM_MULTIPATH_NEED_KPARTX" - ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" - ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="end_mpath" -@@ -42,7 +43,7 @@ ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPATH_NEED_KPARTX}="1" - ENV{DM_SUSPENDED}=="1", GOTO="end_mpath" - ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath" - ENV{DM_ACTIVATION}!="1", ENV{DM_MULTIPATH_NEED_KPARTX}!="1", GOTO="end_mpath" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - ENV{DM_MULTIPATH_NEED_KPARTX}="" - - LABEL="end_mpath" --- -2.7.4 - diff --git a/0003-multipath-there-is-no-none-path-state.patch b/0003-multipath-there-is-no-none-path-state.patch new file mode 100644 index 0000000..e7bbcd4 --- /dev/null +++ b/0003-multipath-there-is-no-none-path-state.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 26 Oct 2017 17:00:20 -0500 +Subject: [PATCH] multipath: there is no "none" path state + +There is a "none" path checker, but not a "none" path state. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c +index cd6d6a3..94d8486 100644 +--- a/libmultipath/checkers.c ++++ b/libmultipath/checkers.c +@@ -19,7 +19,6 @@ char *checker_state_names[] = { + "timeout", + "removed", + "delayed", +- "none", + }; + + static LIST_HEAD(checkers); +-- +2.7.4 + diff --git a/0004-RH-Remove-the-property-blacklist-exception-builtin.patch b/0004-RH-Remove-the-property-blacklist-exception-builtin.patch deleted file mode 100644 index 93bf0ba..0000000 --- a/0004-RH-Remove-the-property-blacklist-exception-builtin.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 2 Jul 2014 12:49:53 -0500 -Subject: [PATCH] RH: Remove the property blacklist exception builtin - -Multipath set the default property blacklist exceptions to -(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal -devices. These devices may never have multiple paths, but it is nice -to be able to set multipath up on them all the same. This patch simply -removes the default, and makes it so that if no property -blacklist_exception is given, then devices aren't failed for not matching -it. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 15 ++++++--------- - multipath/multipath.conf.5 | 4 ---- - 2 files changed, 6 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index ee396e2..19d4697 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -181,12 +181,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) - return 1; - -- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); -- if (!str) -- return 1; -- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) -- return 1; -- - vector_foreach_slot (conf->hwtable, hwe, i) { - if (hwe->bl_product) { - if (_blacklist_device(conf->blist_device, hwe->vendor, -@@ -390,9 +384,12 @@ filter_property(struct config * conf, struct udev_device * udev) - * This is the inverse of the 'normal' matching; - * the environment variable _has_ to match. - */ -- log_filter(devname, NULL, NULL, NULL, NULL, -- MATCH_PROPERTY_BLIST_MISSING); -- return MATCH_PROPERTY_BLIST_MISSING; -+ if (VECTOR_SIZE(conf->elist_property)) { -+ log_filter(devname, NULL, NULL, NULL, NULL, -+ MATCH_PROPERTY_BLIST_MISSING); -+ return MATCH_PROPERTY_BLIST_MISSING; -+ } -+ return 0; - } - - void -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 0049cba..35fc0b1 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1034,10 +1034,6 @@ The \fIWorld Wide Identification\fR of a device. - .TP - .B property - Regular expression of the udev property to be whitelisted. --.RS --.TP --The default is: \fB(SCSI_IDENT_|ID_WWN)\fR --.RE - .TP - .B device - Subsection for the device description. This subsection recognizes the --- -2.7.4 - diff --git a/0004-mutipath-updated-Huawei-storage-config.patch b/0004-mutipath-updated-Huawei-storage-config.patch new file mode 100644 index 0000000..dd5e74c --- /dev/null +++ b/0004-mutipath-updated-Huawei-storage-config.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 1 Nov 2017 19:53:11 -0500 +Subject: [PATCH] mutipath: updated Huawei storage config + +I was given this updated built-in config by Zhou Weigang from +Huawei. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index b018ddf..78de1fa 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -940,7 +940,8 @@ static struct hwentry default_hw[] = { + /* OceanStor V3 */ + .vendor = "HUAWEI", + .product = "XSG1", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .prio_name = PRIO_ALUA, + }, + /* + * Red Hat +-- +2.7.4 + diff --git a/0005-RH-don-t-start-without-a-config-file.patch b/0005-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index 4e5fb6a..0000000 --- a/0005-RH-don-t-start-without-a-config-file.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 15 Oct 2014 10:39:30 -0500 -Subject: [PATCH] RH: don't start without a config file - -If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist -all devices when running multipath. A completely blank configuration file -is almost never what users want. Also, people may have the multipath -packages installed but don't want to use them. This patch provides a -simple way to disable multipath. Simply removing or renaming -/etc/multipath.conf will keep multipath from doing anything. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 17 +++++++++++++++++ - libmultipath/config.h | 1 + - multipath/multipath.rules | 1 + - multipathd/multipathd.8 | 2 ++ - multipathd/multipathd.service | 1 + - 5 files changed, 22 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 6b23601..9368962 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -25,6 +25,7 @@ - #include "prio.h" - #include "devmapper.h" - #include "mpath_cmd.h" -+#include "version.h" - - static int - hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2) -@@ -674,6 +675,22 @@ load_config (char * file) - factorize_hwtable(conf->hwtable, builtin_hwtable_size); - } - -+ } else { -+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); -+ condlog(0, "A default multipath.conf file is located at"); -+ condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); -+ if (conf->blist_devnode == NULL) { -+ conf->blist_devnode = vector_alloc(); -+ if (!conf->blist_devnode) { -+ condlog(0, "cannot allocate blacklist\n"); -+ goto out; -+ } -+ } -+ if (store_ble(conf->blist_devnode, strdup(".*"), -+ ORIGIN_NO_CONFIG)) { -+ condlog(0, "cannot store default no-config blacklist\n"); -+ goto out; -+ } - } - - conf->processed_main_config = 1; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index ffc69b5..614331c 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -7,6 +7,7 @@ - - #define ORIGIN_DEFAULT 0 - #define ORIGIN_CONFIG 1 -+#define ORIGIN_NO_CONFIG 2 - - /* - * In kernel, fast_io_fail == 0 means immediate failure on rport delete. -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 4d78b98..5753766 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -6,6 +6,7 @@ IMPORT{cmdline}="nompath" - ENV{nompath}=="?*", GOTO="end_mpath" - IMPORT{cmdline}="multipath" - ENV{multipath}=="off", GOTO="end_mpath" -+TEST!="/etc/multipath.conf", GOTO="end_mpath" - - KERNEL=="dm-*", GOTO="check_kpartx" - ENV{DEVTYPE}!="partition", GOTO="test_dev" -diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index 2615728..d64040f 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8 -@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. - This daemon executes the external \fBmultipath\fR tool when events occur. - In turn, the multipath tool signals the multipathd daemon when it is done with - devmap reconfiguration, so that it can refresh its failed path list. -+ -+In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. - . - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index fd66cf6..fafd088 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service - Before=iscsi.service iscsid.service lvm2-lvmetad.service lvm2-activation-early.service - Before=local-fs-pre.target blk-availability.service - After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service -+ConditionPathExists=/etc/multipath.conf - DefaultDependencies=no - Conflicts=shutdown.target - ConditionKernelCommandLine=!nompath --- -2.7.4 - diff --git a/0005-multipath-fix-doc-typo.patch b/0005-multipath-fix-doc-typo.patch new file mode 100644 index 0000000..30cf241 --- /dev/null +++ b/0005-multipath-fix-doc-typo.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 1 Nov 2017 19:58:10 -0500 +Subject: [PATCH] multipath: fix doc typo + +The dev_loss_tmo cap if fast_io_fail_tmo isn't set is 600 seconds, +not 300 seconds. + +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 92ad8b1..4bd1a8d 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -653,7 +653,7 @@ seconds, or 68 years. It will be automatically adjusted to the overall + retry interval \fIno_path_retry\fR * \fIpolling_interval\fR + if a number of retries is given with \fIno_path_retry\fR and the + overall retry interval is longer than the specified \fIdev_loss_tmo\fR value. +-The Linux kernel will cap this value to \fI300\fR if \fIfast_io_fail_tmo\fR ++The Linux kernel will cap this value to \fI600\fR if \fIfast_io_fail_tmo\fR + is not set. See KNOWN ISSUES. + .RS + .TP +-- +2.7.4 + diff --git a/0006-RH-use-rpm-optflags-if-present.patch b/0006-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index 6ec413c..0000000 --- a/0006-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 19 Apr 2017 06:10:01 -0500 -Subject: [PATCH] RH: use rpm optflags if present - -Use the passed in optflags when compiling as an RPM, and keep the -default flags as close as possible to the current fedora flags, while -still being generic. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index cea015b..d6b4ef7 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -82,13 +82,21 @@ TEST_CC_OPTION = $(shell \ - echo "$(2)"; \ - fi) - --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -- --OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -- -Werror=implicit-function-declaration -Werror=format-security \ -- -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \ -- -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \ -- --param=ssp-buffer-size=4 -+ifndef RPM_OPT_FLAGS -+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \ -+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) --param=ssp-buffer-size=4 \ -+ -grecord-gcc-switches -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -+ endif -+else -+ OPTFLAGS = $(RPM_OPT_FLAGS) -+endif -+OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \ -+ -Werror=implicit-function-declaration -Wno-sign-compare \ -+ -Wno-unused-parameter - - CFLAGS = $(OPTFLAGS) -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" - BIN_CFLAGS = -fPIE -DPIE --- -2.7.4 - diff --git a/0006-multipath-add-ghost_delay-parameter.patch b/0006-multipath-add-ghost_delay-parameter.patch new file mode 100644 index 0000000..5bb211a --- /dev/null +++ b/0006-multipath-add-ghost_delay-parameter.patch @@ -0,0 +1,397 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 2 Nov 2017 18:02:56 -0500 +Subject: [PATCH] multipath: add "ghost_delay" parameter + +If the lower-priority passive paths for a multipath device appear first, +IO can go to them and cause the hardware handler to activate them, +before the higher priority paths appear, causing the devices to +failback. Setting the "ghost_delay" parameter to a value greater than +0 can avoid this ping-ponging by causing udev to not mark the device as +Ready after its initial creation until either an active path appears, +or ghost_delay seconds have passed. Multipathd does this by setting +the MPATH_UDEV_NO_PATHS_FLAG. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 3 +++ + libmultipath/config.h | 3 +++ + libmultipath/configure.c | 11 +++++++++++ + libmultipath/defaults.h | 1 + + libmultipath/devmapper.c | 2 +- + libmultipath/dict.c | 14 ++++++++++++++ + libmultipath/hwtable.c | 1 + + libmultipath/propsel.c | 15 +++++++++++++++ + libmultipath/propsel.h | 1 + + libmultipath/structs.h | 7 +++++++ + multipath/multipath.conf.5 | 19 +++++++++++++++++++ + multipathd/main.c | 28 +++++++++++++++++++++++++++- + 12 files changed, 103 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index ea2359a..9486116 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -351,6 +351,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) + merge_num(delay_wait_checks); + merge_num(skip_kpartx); + merge_num(max_sectors_kb); ++ merge_num(ghost_delay); + merge_num(san_path_err_threshold); + merge_num(san_path_err_forget_rate); + merge_num(san_path_err_recovery_time); +@@ -422,6 +423,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe) + hwe->retain_hwhandler = dhwe->retain_hwhandler; + hwe->detect_prio = dhwe->detect_prio; + hwe->detect_checker = dhwe->detect_checker; ++ hwe->ghost_delay = dhwe->ghost_delay; + + if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product))) + goto out; +@@ -622,6 +624,7 @@ load_config (char * file) + conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; + conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS; + conf->remove_retries = 0; ++ conf->ghost_delay = DEFAULT_GHOST_DELAY; + + /* + * preload default hwtable +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 240730b..67ff983 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -80,6 +80,7 @@ struct hwentry { + int san_path_err_recovery_time; + int skip_kpartx; + int max_sectors_kb; ++ int ghost_delay; + char * bl_product; + }; + +@@ -112,6 +113,7 @@ struct mpentry { + int san_path_err_recovery_time; + int skip_kpartx; + int max_sectors_kb; ++ int ghost_delay; + uid_t uid; + gid_t gid; + mode_t mode; +@@ -170,6 +172,7 @@ struct config { + int disable_changed_wwids; + int remove_retries; + int max_sectors_kb; ++ int ghost_delay; + unsigned int version[3]; + + char * multipath_dir; +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 7a3db31..e2f393f 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -300,6 +300,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size) + select_san_path_err_recovery_time(conf, mpp); + select_skip_kpartx(conf, mpp); + select_max_sectors_kb(conf, mpp); ++ select_ghost_delay(conf, mpp); + + sysfs_set_scsi_tmo(mpp, conf->checkint); + put_multipath_config(conf); +@@ -760,6 +761,9 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + } + + sysfs_set_max_sectors_kb(mpp, 0); ++ if (is_daemon && mpp->ghost_delay > 0 && mpp->nr_active && ++ pathcount(mpp, PATH_GHOST) == mpp->nr_active) ++ mpp->ghost_delay_tick = mpp->ghost_delay; + r = dm_addmap_create(mpp, params); + + lock_multipath(mpp, 0); +@@ -767,11 +771,15 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + + case ACT_RELOAD: + sysfs_set_max_sectors_kb(mpp, 1); ++ if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) ++ mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 0); + break; + + case ACT_RESIZE: + sysfs_set_max_sectors_kb(mpp, 1); ++ if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) ++ mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 1); + break; + +@@ -789,6 +797,9 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + put_multipath_config(conf); + if (r) { + sysfs_set_max_sectors_kb(mpp, 1); ++ if (mpp->ghost_delay_tick > 0 && ++ pathcount(mpp, PATH_UP)) ++ mpp->ghost_delay_tick = 0; + r = dm_addmap_reload(mpp, params, 0); + } + break; +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index 740ccf4..c9e3411 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -40,6 +40,7 @@ + #define DEFAULT_SKIP_KPARTX SKIP_KPARTX_OFF + #define DEFAULT_DISABLE_CHANGED_WWIDS 0 + #define DEFAULT_MAX_SECTORS_KB MAX_SECTORS_KB_UNDEF ++#define DEFAULT_GHOST_DELAY GHOST_DELAY_OFF + + #define DEFAULT_CHECKINT 5 + #define MAX_CHECKINT(a) (a << 2) +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index fcac6bc..573fc75 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -378,7 +378,7 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) + /* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */ + return (mpp->skip_kpartx == SKIP_KPARTX_ON ? + MPATH_UDEV_NO_KPARTX_FLAG : 0) | +- (mpp->nr_active == 0 ? ++ ((mpp->nr_active == 0 || mpp->ghost_delay_tick > 0)? + MPATH_UDEV_NO_PATHS_FLAG : 0) | + (reload && !mpp->force_udev_reload ? + MPATH_UDEV_RELOAD_FLAG : 0); +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 36cccc9..54652d4 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -1110,6 +1110,16 @@ declare_hw_handler(san_path_err_recovery_time, set_off_int_undef) + declare_hw_snprint(san_path_err_recovery_time, print_off_int_undef) + declare_mp_handler(san_path_err_recovery_time, set_off_int_undef) + declare_mp_snprint(san_path_err_recovery_time, print_off_int_undef) ++ ++declare_def_handler(ghost_delay, set_off_int_undef) ++declare_def_snprint(ghost_delay, print_off_int_undef) ++declare_ovr_handler(ghost_delay, set_off_int_undef) ++declare_ovr_snprint(ghost_delay, print_off_int_undef) ++declare_hw_handler(ghost_delay, set_off_int_undef) ++declare_hw_snprint(ghost_delay, print_off_int_undef) ++declare_mp_handler(ghost_delay, set_off_int_undef) ++declare_mp_snprint(ghost_delay, print_off_int_undef) ++ + static int + def_uxsock_timeout_handler(struct config *conf, vector strvec) + { +@@ -1456,6 +1466,7 @@ init_keywords(vector keywords) + install_keyword("disable_changed_wwids", &def_disable_changed_wwids_handler, &snprint_def_disable_changed_wwids); + install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries); + install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb); ++ install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +@@ -1535,6 +1546,7 @@ init_keywords(vector keywords) + install_keyword("san_path_err_recovery_time", &hw_san_path_err_recovery_time_handler, &snprint_hw_san_path_err_recovery_time); + install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx); + install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb); ++ install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay); + install_sublevel_end(); + + install_keyword_root("overrides", &overrides_handler); +@@ -1569,6 +1581,7 @@ init_keywords(vector keywords) + + install_keyword("skip_kpartx", &ovr_skip_kpartx_handler, &snprint_ovr_skip_kpartx); + install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb); ++ install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay); + + install_keyword_root("multipaths", &multipaths_handler); + install_keyword_multi("multipath", &multipath_handler, NULL); +@@ -1600,5 +1613,6 @@ init_keywords(vector keywords) + install_keyword("san_path_err_recovery_time", &mp_san_path_err_recovery_time_handler, &snprint_mp_san_path_err_recovery_time); + install_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx); + install_keyword("max_sectors_kb", &mp_max_sectors_kb_handler, &snprint_mp_max_sectors_kb); ++ install_keyword("ghost_delay", &mp_ghost_delay_handler, &snprint_mp_ghost_delay); + install_sublevel_end(); + } +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 78de1fa..7226fb1 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -72,6 +72,7 @@ + .delay_wait_checks = DELAY_CHECKS_OFF, + .skip_kpartx = SKIP_KPARTX_OFF, + .max_sectors_kb = MAX_SECTORS_KB_UNDEF, ++ .ghost_delay = GHOST_DELAY_OFF + }, + #endif + +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index 00adc0d..6721cc6 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -835,3 +835,18 @@ out: + origin); + return 0; + } ++ ++int select_ghost_delay (struct config *conf, struct multipath * mp) ++{ ++ char *origin, buff[12]; ++ ++ mp_set_mpe(ghost_delay); ++ mp_set_ovr(ghost_delay); ++ mp_set_hwe(ghost_delay); ++ mp_set_conf(ghost_delay); ++ mp_set_default(ghost_delay, DEFAULT_GHOST_DELAY); ++out: ++ print_off_int_undef(buff, 12, &mp->ghost_delay); ++ condlog(3, "%s: ghost_delay = %s %s", mp->alias, buff, origin); ++ return 0; ++} +diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h +index f8e96d8..494fb10 100644 +--- a/libmultipath/propsel.h ++++ b/libmultipath/propsel.h +@@ -25,6 +25,7 @@ int select_delay_watch_checks (struct config *conf, struct multipath * mp); + int select_delay_wait_checks (struct config *conf, struct multipath * mp); + int select_skip_kpartx (struct config *conf, struct multipath * mp); + int select_max_sectors_kb (struct config *conf, struct multipath * mp); ++int select_ghost_delay(struct config *conf, struct multipath * mp); + int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp); + int select_san_path_err_threshold(struct config *conf, struct multipath *mp); + int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index f06824a..d2d7701 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -167,6 +167,11 @@ enum no_undef_states { + NU_UNDEF = 0, + }; + ++enum ghost_delay_states { ++ GHOST_DELAY_OFF = NU_NO, ++ GHOST_DELAY_UNDEF = NU_UNDEF, ++}; ++ + enum initialized_states { + INIT_FAILED, + INIT_MISSING_UDEV, +@@ -282,6 +287,8 @@ struct multipath { + int max_sectors_kb; + int force_readonly; + int force_udev_reload; ++ int ghost_delay; ++ int ghost_delay_tick; + unsigned int dev_loss; + uid_t uid; + gid_t gid; +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 4bd1a8d..8783124 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1017,6 +1017,19 @@ The default is: \fB\fR + .RE + . + . ++.TP ++.B ghost_delay ++Sets the number of seconds that multipath will wait after creating a device ++with only ghost paths before marking it ready for use in systemd. This gives ++the active paths time to appear before the multipath runs the hardware handler ++to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIon\fR ++makes multipath immediately mark a device with only ghost paths as ready. ++.RS ++.TP ++The default is \fBno\fR ++.RE ++. ++. + .\" ---------------------------------------------------------------------------- + .SH "blacklist section" + .\" ---------------------------------------------------------------------------- +@@ -1157,6 +1170,8 @@ are taken from the \fIdefaults\fR or \fIdevices\fR section: + .B skip_kpartx + .TP + .B max_sectors_kb ++.TP ++.B ghost_delay + .RE + .PD + .LP +@@ -1284,6 +1299,8 @@ section: + .B skip_kpartx + .TP + .B max_sectors_kb ++.TP ++.B ghost_delay + .RE + .PD + .LP +@@ -1354,6 +1371,8 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections: + .B delay_wait_checks + .TP + .B skip_kpartx ++.TP ++.B ghost_delay + .RE + .PD + .LP +diff --git a/multipathd/main.c b/multipathd/main.c +index 8049da2..c475fcd 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -351,6 +351,8 @@ sync_map_state(struct multipath *mpp) + pp->state == PATH_WILD || + pp->state == PATH_DELAYED) + continue; ++ if (mpp->ghost_delay_tick > 0) ++ continue; + if ((pp->dmstate == PSTATE_FAILED || + pp->dmstate == PSTATE_UNDEF) && + (pp->state == PATH_UP || pp->state == PATH_GHOST)) +@@ -735,7 +737,8 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid); + if (mpp && mpp->wait_for_udev && + (pathcount(mpp, PATH_UP) > 0 || +- (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT))) { ++ (pathcount(mpp, PATH_GHOST) > 0 && pp->tpgs != TPGS_IMPLICIT && ++ mpp->ghost_delay_tick <= 0))) { + /* if wait_for_udev is set and valid paths exist */ + condlog(2, "%s: delaying path addition until %s is fully initialized", pp->dev, mpp->alias); + mpp->wait_for_udev = 2; +@@ -1416,6 +1419,28 @@ missing_uev_wait_tick(struct vectors *vecs) + } + + static void ++ghost_delay_tick(struct vectors *vecs) ++{ ++ struct multipath * mpp; ++ unsigned int i; ++ ++ vector_foreach_slot (vecs->mpvec, mpp, i) { ++ if (mpp->ghost_delay_tick <= 0) ++ continue; ++ if (--mpp->ghost_delay_tick <= 0) { ++ condlog(0, "%s: timed out waiting for active path", ++ mpp->alias); ++ mpp->force_udev_reload = 1; ++ if (update_map(mpp, vecs) != 0) { ++ /* update_map removed map */ ++ i--; ++ continue; ++ } ++ } ++ } ++} ++ ++static void + defered_failback_tick (vector mpvec) + { + struct multipath * mpp; +@@ -1961,6 +1986,7 @@ checkerloop (void *ap) + defered_failback_tick(vecs->mpvec); + retry_count_tick(vecs->mpvec); + missing_uev_wait_tick(vecs); ++ ghost_delay_tick(vecs); + lock_cleanup_pop(vecs->lock); + + if (count) +-- +2.7.4 + diff --git a/0007-RH-add-mpathconf.patch b/0007-RH-add-mpathconf.patch deleted file mode 100644 index 885014a..0000000 --- a/0007-RH-add-mpathconf.patch +++ /dev/null @@ -1,648 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 16 Oct 2014 15:49:01 -0500 -Subject: [PATCH] RH: add mpathconf - -mpathconf is a program (largely based on lvmcomf) to help users -configure /etc/multipath.conf and enable or disable multipathing. It -has a couple of built-in options that can be set directly from the -command line. But, mostly it is used to get a multipath.conf file -with the OS defaults, and to enable and disable multipathing via -a single command. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 1 + - multipath/Makefile | 5 + - multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 101 +++++++++++ - 4 files changed, 571 insertions(+) - create mode 100644 multipath/mpathconf - create mode 100644 multipath/mpathconf.8 - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 9368962..bdde113 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -679,6 +679,7 @@ load_config (char * file) - condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); - condlog(0, "A default multipath.conf file is located at"); - condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); -+ condlog(0, "You can run /sbin/mpathconf to create or modify /etc/multipath.conf"); - if (conf->blist_devnode == NULL) { - conf->blist_devnode = vector_alloc(); - if (!conf->blist_devnode) { -diff --git a/multipath/Makefile b/multipath/Makefile -index 1e9ee4b..3d4d459 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) - $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz -+ $(GZIP) mpathconf.8 > mpathconf.8.gz - - install: - $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ -+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules -@@ -29,13 +31,16 @@ install: - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) -+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir) - - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules - $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules -+ $(RM) $(DESTDIR)$(bindir)/mpathconf - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz -+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz - - clean: - $(RM) core *.o $(EXEC) *.gz -diff --git a/multipath/mpathconf b/multipath/mpathconf -new file mode 100644 -index 0000000..e839134 ---- /dev/null -+++ b/multipath/mpathconf -@@ -0,0 +1,464 @@ -+#!/bin/bash -+# -+# 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 -+# -+ -+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST -+ -+DEFAULT_CONFIG="# device-mapper-multipath configuration file -+ -+# For a complete list of the default configuration values, run either: -+# # multipath -t -+# or -+# # multipathd show config -+ -+# For a list of configuration options with descriptions, see the -+# multipath.conf man page. -+ -+defaults { -+ user_friendly_names yes -+ find_multipaths yes -+} -+ -+blacklist_exceptions { -+ property \"(SCSI_IDENT_|ID_WWN)\" -+}" -+ -+CONFIGFILE="/etc/multipath.conf" -+OUTPUTFILE="/etc/multipath.conf" -+MULTIPATHDIR="/etc/multipath" -+TMPFILE="/etc/multipath/.multipath.conf.tmp" -+WWIDS=0 -+ -+function usage -+{ -+ echo "usage: $0 " -+ echo "" -+ echo "Commands:" -+ echo "Enable: --enable " -+ echo "Disable: --disable" -+ echo "Only allow certain wwids (instead of enable): --allow " -+ echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " -+ echo "Load the dm-multipath modules on enable (Default y): --with_module " -+ echo "start/stop/reload multipathd (Default n): --with_multipathd " -+ echo "select output file (Default /etc/multipath.conf): --outfile " -+ echo "" -+} -+ -+function add_wwid -+{ -+ INDEX=0 -+ while [ "$INDEX" -lt "$WWIDS" ] ; do -+ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then -+ return -+ fi -+ ((INDEX++)) -+ done -+ WWID_LIST[$WWIDS]="$1" -+ ((WWIDS++)) -+} -+ -+function get_dm_deps -+{ -+ shift 3 -+ while [ -n "$1" -a -n "$2" ]; do -+ MAJOR=$(echo $1 | tr -d '(,') -+ MINOR=$(echo $2 | tr -d ')') -+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` -+ if [ -n "$UUID" ] ; then -+ set_dm_wwid $UUID -+ fi -+ shift 2 -+ done -+} -+ -+function set_dm_wwid -+{ -+ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then -+ add_wwid "${1##part*-mpath-}" -+ elif [[ "$1" =~ ^mpath- ]] ; then -+ add_wwid "${1##mpath-}" -+ else -+ get_dm_deps `dmsetup deps -u $1` -+ fi -+} -+ -+function set_wwid -+{ -+ UUID="" -+ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then -+ MAJOR=${1%%:*} -+ MINOR=${1##*:} -+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` -+ else -+ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null` -+ fi -+ if [ -n "$UUID" ] ; then -+ set_dm_wwid $UUID -+ else -+ add_wwid "$1" -+ fi -+} -+ -+function parse_args -+{ -+ while [ -n "$1" ]; do -+ case $1 in -+ --enable) -+ ENABLE=1 -+ shift -+ ;; -+ --disable) -+ ENABLE=0 -+ shift -+ ;; -+ --allow) -+ ENABLE=2 -+ if [ -n "$2" ]; then -+ set_wwid $2 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; -+ --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 -+ ;; -+ --with_module) -+ if [ -n "$2" ]; then -+ MODULE=$2 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; -+ --with_multipathd) -+ if [ -n "$2" ]; then -+ MULTIPATHD=$2 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; -+ --outfile) -+ if [ -n "$2" ]; then -+ OUTPUTFILE=$2 -+ HAVE_OUTFILE=1 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; -+ *) -+ usage -+ exit -+ esac -+ done -+} -+ -+function validate_args -+{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then -+ echo "ignoring extra parameters on disable" -+ FRIENDLY="" -+ FIND="" -+ MODULE="" -+ 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 -+ SHOW_STATUS=1 -+ fi -+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then -+ echo "--with_module must be either 'y' or 'n'" -+ exit 1 -+ fi -+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then -+ echo "--with_multipathd must be either 'y' or 'n'" -+ exit 1 -+ fi -+ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then -+ echo "Because --allow makes changes that cannot be automatically reversed," -+ echo "you must set --outfile when you set --allow" -+ exit 1 -+ fi -+} -+ -+function add_blacklist_exceptions -+{ -+ INDEX=0 -+ while [ "$INDEX" -lt "$WWIDS" ] ; do -+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ -+ wwid '"\"${WWID_LIST[$INDEX]}\""' -+' $TMPFILE -+ ((INDEX++)) -+ done -+} -+ -+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 -+echo "$DEFAULT_CONFIG" > $TMPFILE -+if [ -f "$CONFIGFILE" ]; then -+ cp $CONFIGFILE $TMPFILE -+fi -+ -+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then -+ HAVE_BLACKLIST=1 -+fi -+ -+if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then -+ HAVE_EXCEPTIONS=1 -+fi -+ -+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then -+ HAVE_DEFAULTS=1 -+fi -+ -+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then -+ if lsmod | grep -q "dm_multipath" ; then -+ HAVE_MODULE=1 -+ else -+ HAVE_MODULE=0 -+ fi -+fi -+ -+if [ "$MULTIPATHD" = "y" ]; then -+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then -+ HAVE_MULTIPATHD=1 -+ else -+ HAVE_MULTIPATHD=0 -+ fi -+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_BLACKLIST" = "1" ]; then -+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then -+ HAVE_WWID_DISABLE=1 -+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then -+ HAVE_WWID_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 "$SHOW_STATUS" ]; 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 -+ if [ -n "$HAVE_MODULE" ]; then -+ if [ "$HAVE_MODULE" = 1 ]; then -+ echo "dm_multipath module is loaded" -+ else -+ echo "dm_multipath module is not loaded" -+ fi -+ fi -+ if [ -z "$HAVE_MULTIPATHD" ]; then -+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then -+ HAVE_MULTIPATHD=1 -+ else -+ HAVE_MULTIPATHD=0 -+ fi -+ fi -+ if [ "$HAVE_MULTIPATHD" = 1 ]; then -+ echo "multipathd is running" -+ else -+ echo "multipathd is not running" -+ 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" = 2 ]; then -+ if [ "$HAVE_DISABLE" = 1 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE -+ fi -+ if [ -z "$HAVE_WWID_DISABLE" ]; then -+ sed -i '/^blacklist[[:space:]]*{/ a\ -+ wwid ".*" -+' $TMPFILE -+ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE -+ fi -+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE -+ else -+ cat >> $TMPFILE <<- _EOF_ -+ -+blacklist_exceptions { -+} -+_EOF_ -+ fi -+ add_blacklist_exceptions -+elif [ "$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 -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FIND" = "y" ]; then -+ if [ -z "$HAVE_FIND" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ find_multipaths yes -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_FIND" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE -+ CHANGED_CONFIG=1 -+ 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 -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FRIENDLY" = "y" ]; then -+ if [ -z "$HAVE_FRIENDLY" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ user_friendly_names yes -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_FRIENDLY" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+fi -+ -+if [ -f "$OUTPUTFILE" ]; then -+ cp $OUTPUTFILE $OUTPUTFILE.old -+ if [ $? != 0 ]; then -+ echo "failed to backup old config file, $OUTPUTFILE not updated" -+ exit 1 -+ fi -+fi -+ -+cp $TMPFILE $OUTPUTFILE -+if [ $? != 0 ]; then -+ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK" -+ exit 1 -+fi -+ -+rm -f $TMPFILE -+ -+if [ "$ENABLE" = 1 ]; then -+ if [ "$HAVE_MODULE" = 0 ]; then -+ modprobe dm_multipath -+ fi -+ if [ "$HAVE_MULTIPATHD" = 0 ]; then -+ systemctl start multipathd.service -+ fi -+elif [ "$ENABLE" = 0 ]; then -+ if [ "$HAVE_MULTIPATHD" = 1 ]; then -+ systemctl stop multipathd.service -+ fi -+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then -+ systemctl reload multipathd.service -+fi -diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 -new file mode 100644 -index 0000000..4cd3267 ---- /dev/null -+++ b/multipath/mpathconf.8 -@@ -0,0 +1,101 @@ -+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" -+.SH NAME -+mpathconf - A tool for configuring device-mapper-multipath -+.SH SYNOPSIS -+.B mpathconf -+.RB [\| commands \|] -+.RB [\| options \|] -+.SH DESCRIPTION -+.B mpathconf -+is a utility that creates or modifies -+.B /etc/multipath.conf. -+It can enable or disable multipathing and configure some common options. -+.B mpathconf -+can also load the -+.B dm_multipath -+module, start and stop the -+.B multipathd -+daemon, and configure the -+.B multipathd -+service to start automatically or not. If -+.B mpathconf -+is called with no commands, it will display the current configuration. -+ -+The default options for mpathconf are -+.B --with_module -+The -+.B --with_multipathd -+option is not set by default. Enabling multipathing will load the -+.B dm_multipath -+module but it will not immediately start it. This is so -+that users can manually edit their config file if necessary, before starting -+.B multipathd. -+ -+If -+.B /etc/multipath.conf -+already exists, mpathconf will edit it. If it does not exist, mpathconf will -+create a default file with -+.B user_friendly_names -+and -+.B find_multipaths -+set. To disable these, use the -+.B --user_friendly_names n -+and -+.B --find_multipaths n -+options -+.SH COMMANDS -+.TP -+.B --enable -+Removes any line that blacklists all device nodes from the -+.B /etc/multipath.conf -+blacklist section. -+.TP -+.B --disable -+Adds a line that blacklists all device nodes to the -+.B /etc/multipath.conf -+blacklist section. If no blacklist section exists, it will create one. -+.TP -+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B user_friendly_names yes -+to the -+.B /etc/multipath.conf -+defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used along with any other command. -+.TP -+.B --find_multipaths\fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B find_multipaths yes -+to the -+.B /etc/multipath.conf -+defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used aldong with any other command. -+.SH OPTIONS -+.TP -+.B --with_module\fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this runs -+.B modprobe dm_multipath -+to install the multipath modules. This option only works with the -+.B --enable -+command. This option is set to \fBy\fP by default. -+.TP -+.B --with_multipathd { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this runs -+.B service multipathd start -+to start the multipathd daemon on \fB--enable\fP, -+.B service multipathd stop -+to stop the multipathd daemon on \fB--disable\fP, and -+.B service multipathd reload -+to reconfigure multipathd on \fB--user_frindly_names\fP and -+\fB--find_multipaths\fP. -+This option is set to \fBn\fP by default. -+.SH FILES -+.BR /etc/multipath.conf -+.SH "SEE ALSO" -+.BR multipath.conf (5), -+.BR modprobe (8), -+.BR multipath (8), -+.BR multipathd (8), -+.BR service (8), -+.SH AUTHOR -+Benjamin Marzinski --- -2.7.4 - diff --git a/0007-RH-fixup-udev-rules-for-redhat.patch b/0007-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..005ccb1 --- /dev/null +++ b/0007-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 13 Apr 2017 07:22:23 -0500 +Subject: [PATCH] RH: fixup udev rules for redhat + +The multipath rules need to run after scsi_id is run. This means moving +them after 60-persistent-storage.rules for redhat. Redhat also uses a +different naming scheme for partitions than SuSE. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + kpartx/kpartx.rules | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 29c290a..cea015b 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -48,7 +48,7 @@ endif + prefix = + exec_prefix = $(prefix) + usr_prefix = $(prefix) +-bindir = $(exec_prefix)/sbin ++bindir = $(exec_prefix)/usr/sbin + libudevdir = $(prefix)/$(SYSTEMDPATH)/udev + udevrulesdir = $(libudevdir)/rules.d + multipathdir = $(TOPDIR)/libmultipath +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 8f99049..8a3a171 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="/sbin/kpartx -un -p -part /dev/$name" ++RUN+="/sbin/kpartx -un /dev/$name" + + LABEL="kpartx_end" +diff --git a/multipath/Makefile b/multipath/Makefile +index 468c056..dda5565 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -24,7 +24,7 @@ install: + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) +@@ -33,7 +33,7 @@ install: + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz + +-- +2.7.4 + diff --git a/0008-RH-Remove-the-property-blacklist-exception-builtin.patch b/0008-RH-Remove-the-property-blacklist-exception-builtin.patch new file mode 100644 index 0000000..a4b5770 --- /dev/null +++ b/0008-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -0,0 +1,70 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Jul 2014 12:49:53 -0500 +Subject: [PATCH] RH: Remove the property blacklist exception builtin + +Multipath set the default property blacklist exceptions to +(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal +devices. These devices may never have multiple paths, but it is nice +to be able to set multipath up on them all the same. This patch simply +removes the default, and makes it so that if no property +blacklist_exception is given, then devices aren't failed for not matching +it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 15 ++++++--------- + multipath/multipath.conf.5 | 4 ---- + 2 files changed, 6 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index ee396e2..19d4697 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -181,12 +181,6 @@ setup_default_blist (struct config * conf) + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) + return 1; + +- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); +- if (!str) +- return 1; +- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) +- return 1; +- + vector_foreach_slot (conf->hwtable, hwe, i) { + if (hwe->bl_product) { + if (_blacklist_device(conf->blist_device, hwe->vendor, +@@ -390,9 +384,12 @@ filter_property(struct config * conf, struct udev_device * udev) + * This is the inverse of the 'normal' matching; + * the environment variable _has_ to match. + */ +- log_filter(devname, NULL, NULL, NULL, NULL, +- MATCH_PROPERTY_BLIST_MISSING); +- return MATCH_PROPERTY_BLIST_MISSING; ++ if (VECTOR_SIZE(conf->elist_property)) { ++ log_filter(devname, NULL, NULL, NULL, NULL, ++ MATCH_PROPERTY_BLIST_MISSING); ++ return MATCH_PROPERTY_BLIST_MISSING; ++ } ++ return 0; + } + + void +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 8783124..fa4333d 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1085,10 +1085,6 @@ The \fIWorld Wide Identification\fR of a device. + .TP + .B property + Regular expression of the udev property to be whitelisted. +-.RS +-.TP +-The default is: \fB(SCSI_IDENT_|ID_WWN)\fR +-.RE + .TP + .B device + Subsection for the device description. This subsection recognizes the +-- +2.7.4 + diff --git a/0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch deleted file mode 100644 index ad6f505..0000000 --- a/0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 17 Oct 2014 11:20:34 -0500 -Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A - -This patch adds another option to multipath, "-A", which reads -/proc/cmdline for mpath.wwid= options, and adds any wwids it finds -to /etc/multipath/wwids. While this isn't usually important during -normal operation, since these wwids should already be added, it can be -helpful during installation, to make sure that multipath can claim -devices as its own, before LVM or something else makes use of them. The -patch also execs "/sbin/multipath -A" before running multipathd in -multipathd.service - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/wwids.h | 1 + - multipath/main.c | 10 ++++++++-- - multipath/multipath.8 | 5 ++++- - multipathd/multipathd.service | 1 + - 5 files changed, 58 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index bc70a27..88bb72b 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -321,3 +321,47 @@ remember_wwid(char *wwid) - condlog(4, "wwid %s already in wwids file", wwid); - return 0; - } -+ -+int remember_cmdline_wwid(void) -+{ -+ FILE *f = NULL; -+ char buf[LINE_MAX], *next, *ptr; -+ int ret = 0; -+ -+ f = fopen("/proc/cmdline", "re"); -+ if (!f) { -+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno)); -+ return -1; -+ } -+ -+ if (!fgets(buf, sizeof(buf), f)) { -+ if (ferror(f)) -+ condlog(0, "read of /proc/cmdline failed : %s", -+ strerror(errno)); -+ else -+ condlog(0, "couldn't read /proc/cmdline"); -+ fclose(f); -+ return -1; -+ } -+ fclose(f); -+ next = buf; -+ while((ptr = strstr(next, "mpath.wwid="))) { -+ ptr += 11; -+ next = strpbrk(ptr, " \t\n"); -+ if (next) { -+ *next = '\0'; -+ next++; -+ } -+ if (strlen(ptr)) { -+ if (remember_wwid(ptr) != 0) -+ ret = -1; -+ } -+ else { -+ condlog(0, "empty mpath.wwid kernel command line option"); -+ ret = -1; -+ } -+ if (!next) -+ break; -+ } -+ return ret; -+} -diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h -index 9527012..b665232 100644 ---- a/libmultipath/wwids.h -+++ b/libmultipath/wwids.h -@@ -17,5 +17,6 @@ int remember_wwid(char *wwid); - int check_wwids_file(char *wwid, int write_wwid); - int remove_wwid(char *wwid); - int replace_wwids(vector mp); -+int remember_cmdline_wwid(void); - - #endif /* _WWIDS_H */ -diff --git a/multipath/main.c b/multipath/main.c -index dede017..9dda21d 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -102,7 +102,7 @@ usage (char * progname) - { - fprintf (stderr, VERSION_STRING); - fprintf (stderr, "Usage:\n"); -- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); -+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); - fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); - fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); - fprintf (stderr, " %s -t\n", progname); -@@ -116,6 +116,8 @@ usage (char * progname) - " -f flush a multipath device map\n" - " -F flush all multipath device maps\n" - " -a add a device wwid to the wwids file\n" -+ " -A add devices from kernel command line mpath.wwids\n" -+ " parameters to wwids file\n" - " -c check if a device should be a path in a multipath device\n" - " -q allow queue_if_no_path when multipathd is not running\n" - " -d dry run, do not create or update devmaps\n" -@@ -522,7 +524,7 @@ main (int argc, char *argv[]) - exit(1); - multipath_conf = conf; - conf->retrigger_tries = 0; -- while ((arg = getopt(argc, argv, ":adchl::FfM:v:p:b:BrR:itquwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdchl::FfM:v:p:b:BrR:itquwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -586,6 +588,10 @@ main (int argc, char *argv[]) - case 't': - r = dump_config(conf); - goto out_free_config; -+ case 'A': -+ if (remember_cmdline_wwid() != 0) -+ exit(1); -+ exit(0); - case 'h': - usage(argv[0]); - exit(0); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index b9436e5..b9ad6b1 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -25,7 +25,7 @@ multipath \- Device mapper target autoconfig. - .RB [\| \-b\ \c - .IR bindings_file \|] - .RB [\| \-d \|] --.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \|-i | \-a | \|-u | \-w | \-W \|] -+.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-q | \|-r | \|-i | \-a | \-A | \-u | \-w | \-W \|] - .RB [\| \-p\ \c - .IR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|] - .RB [\| \-R\ \c -@@ -122,6 +122,9 @@ Add the WWID for the specified device to the WWIDs file. - Check if the device specified in the program environment should be - a path in a multipath device. - . -+.B \-A -+add wwids from any kernel command line mpath.wwid parameters to the wwids file -+. - .TP - .B \-w - Remove the WWID for the specified device from the WWIDs file. -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index fafd088..a623a3f 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -15,6 +15,7 @@ Type=notify - NotifyAccess=main - LimitCORE=infinity - ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath -+ExecStartPre=-/sbin/multipath -A - ExecStart=/sbin/multipathd -d -s - ExecReload=/sbin/multipathd reconfigure - --- -2.7.4 - diff --git a/0009-RH-don-t-start-without-a-config-file.patch b/0009-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..38cbbf0 --- /dev/null +++ b/0009-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,108 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 15 Oct 2014 10:39:30 -0500 +Subject: [PATCH] RH: don't start without a config file + +If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist +all devices when running multipath. A completely blank configuration file +is almost never what users want. Also, people may have the multipath +packages installed but don't want to use them. This patch provides a +simple way to disable multipath. Simply removing or renaming +/etc/multipath.conf will keep multipath from doing anything. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 17 +++++++++++++++++ + libmultipath/config.h | 1 + + multipath/multipath.rules | 1 + + multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.service | 1 + + 5 files changed, 22 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 9486116..85e32ee 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -26,6 +26,7 @@ + #include "devmapper.h" + #include "mpath_cmd.h" + #include "propsel.h" ++#include "version.h" + + static int + hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2) +@@ -659,6 +660,22 @@ load_config (char * file) + factorize_hwtable(conf->hwtable, builtin_hwtable_size); + } + ++ } else { ++ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ condlog(0, "A default multipath.conf file is located at"); ++ condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); ++ if (conf->blist_devnode == NULL) { ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_devnode) { ++ condlog(0, "cannot allocate blacklist\n"); ++ goto out; ++ } ++ } ++ if (store_ble(conf->blist_devnode, strdup(".*"), ++ ORIGIN_NO_CONFIG)) { ++ condlog(0, "cannot store default no-config blacklist\n"); ++ goto out; ++ } + } + + conf->processed_main_config = 1; +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 67ff983..1dbb9a7 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -9,6 +9,7 @@ + + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 ++#define ORIGIN_NO_CONFIG 2 + + /* + * In kernel, fast_io_fail == 0 means immediate failure on rport delete. +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index bc1a852..2bc0348 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -7,6 +7,7 @@ IMPORT{cmdline}="nompath" + ENV{nompath}=="?*", GOTO="end_mpath" + IMPORT{cmdline}="multipath" + ENV{multipath}=="off", GOTO="end_mpath" ++TEST!="/etc/multipath.conf", GOTO="end_mpath" + + ENV{DEVTYPE}!="partition", GOTO="test_dev" + IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index 5c96680..0515211 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. + This daemon executes the external \fBmultipath\fR tool when events occur. + In turn, the multipath tool signals the multipathd daemon when it is done with + devmap reconfiguration, so that it can refresh its failed path list. ++ ++In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index fd66cf6..fafd088 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service + Before=iscsi.service iscsid.service lvm2-lvmetad.service lvm2-activation-early.service + Before=local-fs-pre.target blk-availability.service + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + ConditionKernelCommandLine=!nompath +-- +2.7.4 + diff --git a/0009-RH-trigger-change-uevent-on-new-device-creation.patch b/0009-RH-trigger-change-uevent-on-new-device-creation.patch deleted file mode 100644 index 8e20b18..0000000 --- a/0009-RH-trigger-change-uevent-on-new-device-creation.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 24 Apr 2017 09:39:57 -0500 -Subject: [PATCH] RH: trigger change uevent on new device creation - -When multipath first sees a path device with user_friendly names -enabled, it can't know if the device should be multipathed. This means -that it will not claim the device in udev. If the device is eventually -multipathed, multipath should trigger a change uevent to update the udev -database to claim the device. - -This also reverts commit 64e27ec066a001012f44550f095c93443e91d845. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 26 ++++++++++++++++++++++++-- - libmultipath/configure.h | 1 + - libmultipath/wwids.c | 4 ++-- - multipath/main.c | 2 +- - multipathd/main.c | 7 ++----- - 5 files changed, 30 insertions(+), 10 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index bd090d9..843dd09 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -422,6 +422,28 @@ trigger_udev_change(const struct multipath *mpp) - udev_device_unref(udd); - } - -+void -+trigger_paths_udev_change(const struct multipath *mpp) -+{ -+ struct pathgroup * pgp; -+ struct path * pp; -+ int i, j; -+ -+ if (!mpp || !mpp->pg) -+ return; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ if (!pgp->paths) -+ continue; -+ vector_foreach_slot(pgp->paths, pp, j) { -+ if (!pp->udev) -+ continue; -+ sysfs_attr_set_value(pp->udev, "uevent", "change", -+ strlen("change")); -+ } -+ } -+} -+ - static int - is_mpp_known_to_udev(const struct multipath *mpp) - { -@@ -802,8 +824,8 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - * succeeded - */ - mpp->force_udev_reload = 0; -- if (mpp->action == ACT_CREATE) -- remember_wwid(mpp->wwid); -+ if (mpp->action == ACT_CREATE && remember_wwid(mpp->wwid) == 1) -+ trigger_paths_udev_change(mpp); - if (!is_daemon) { - /* multipath client mode */ - dm_switchgroup(mpp->alias, mpp->bestpg); -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index fd7f581..253e29b 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -36,3 +36,4 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type, - vector pathvec, char **wwid); - int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon); - int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name); -+void trigger_paths_udev_change(const struct multipath *mpp); -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 88bb72b..249c6c1 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -319,7 +319,7 @@ remember_wwid(char *wwid) - condlog(3, "wrote wwid %s to wwids file", wwid); - else - condlog(4, "wwid %s already in wwids file", wwid); -- return 0; -+ return ret; - } - - int remember_cmdline_wwid(void) -@@ -353,7 +353,7 @@ int remember_cmdline_wwid(void) - next++; - } - if (strlen(ptr)) { -- if (remember_wwid(ptr) != 0) -+ if (remember_wwid(ptr) < 0) - ret = -1; - } - else { -diff --git a/multipath/main.c b/multipath/main.c -index 9dda21d..baae256 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -336,7 +336,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - } - if (cmd == CMD_ADD_WWID) { - r = remember_wwid(refwwid); -- if (r == 0) -+ if (r >= 0) - printf("wwid '%s' added\n", refwwid); - else - printf("failed adding '%s' to wwids file\n", -diff --git a/multipathd/main.c b/multipathd/main.c -index 4be2c57..fc5b18a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2093,7 +2093,8 @@ configure (struct vectors * vecs, int start_waiters) - - sync_maps_state(mpvec); - vector_foreach_slot(mpvec, mpp, i){ -- remember_wwid(mpp->wwid); -+ if (remember_wwid(mpp->wwid) == 1) -+ trigger_paths_udev_change(mpp); - update_map_pr(mpp); - } - -@@ -2175,10 +2176,6 @@ reconfigure (struct vectors * vecs) - conf->verbosity = verbosity; - if (bindings_read_only) - conf->bindings_read_only = bindings_read_only; -- if (conf->find_multipaths) { -- condlog(2, "find_multipaths is set: -n is implied"); -- ignore_new_devs = 1; -- } - if (ignore_new_devs) - conf->ignore_new_devs = ignore_new_devs; - uxsock_timeout = conf->uxsock_timeout; --- -2.7.4 - diff --git a/0010-RH-use-rpm-optflags-if-present.patch b/0010-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..6ec413c --- /dev/null +++ b/0010-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 19 Apr 2017 06:10:01 -0500 +Subject: [PATCH] RH: use rpm optflags if present + +Use the passed in optflags when compiling as an RPM, and keep the +default flags as close as possible to the current fedora flags, while +still being generic. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index cea015b..d6b4ef7 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -82,13 +82,21 @@ TEST_CC_OPTION = $(shell \ + echo "$(2)"; \ + fi) + +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) +- +-OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \ +- -Werror=implicit-function-declaration -Werror=format-security \ +- -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \ +- -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \ +- --param=ssp-buffer-size=4 ++ifndef RPM_OPT_FLAGS ++ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ++ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \ ++ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ $(STACKPROT) --param=ssp-buffer-size=4 \ ++ -grecord-gcc-switches ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ++ endif ++else ++ OPTFLAGS = $(RPM_OPT_FLAGS) ++endif ++OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \ ++ -Werror=implicit-function-declaration -Wno-sign-compare \ ++ -Wno-unused-parameter + + CFLAGS = $(OPTFLAGS) -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" + BIN_CFLAGS = -fPIE -DPIE +-- +2.7.4 + diff --git a/0010-RH-warn-on-invalid-regex-instead-of-failing.patch b/0010-RH-warn-on-invalid-regex-instead-of-failing.patch deleted file mode 100644 index 298b7ac..0000000 --- a/0010-RH-warn-on-invalid-regex-instead-of-failing.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Nov 2017 21:39:28 -0600 -Subject: [PATCH] RH: warn on invalid regex instead of failing - -multipath.conf used to allow "*" as a match everything regular expression, -instead of requiring ".*". Instead of erroring when the old style -regular expressions are used, it should print a warning and convert -them. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 27 +++++++++++++++++++++------ - libmultipath/parser.c | 13 +++++++++++++ - libmultipath/parser.h | 1 + - 3 files changed, 35 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 82066f6..c68d6f1 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -51,6 +51,21 @@ set_str(vector strvec, void *ptr) - } - - static int -+set_regex(vector strvec, void *ptr) -+{ -+ char **str_ptr = (char **)ptr; -+ -+ if (*str_ptr) -+ FREE(*str_ptr); -+ *str_ptr = set_regex_value(strvec); -+ -+ if (!*str_ptr) -+ return 1; -+ -+ return 0; -+} -+ -+static int - set_yes_no(vector strvec, void *ptr) - { - char * buff; -@@ -1175,7 +1190,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1191,7 +1206,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1286,16 +1301,16 @@ device_handler(struct config *conf, vector strvec) - return 0; - } - --declare_hw_handler(vendor, set_str) -+declare_hw_handler(vendor, set_regex) - declare_hw_snprint(vendor, print_str) - --declare_hw_handler(product, set_str) -+declare_hw_handler(product, set_regex) - declare_hw_snprint(product, print_str) - --declare_hw_handler(revision, set_str) -+declare_hw_handler(revision, set_regex) - declare_hw_snprint(revision, print_str) - --declare_hw_handler(bl_product, set_str) -+declare_hw_handler(bl_product, set_regex) - declare_hw_snprint(bl_product, print_str) - - declare_hw_handler(hwhandler, set_str) -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index c47d891..74b4efe 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -346,6 +346,19 @@ set_value(vector strvec) - return alloc; - } - -+void * -+set_regex_value(vector strvec) -+{ -+ char *buff = set_value(strvec); -+ -+ if (buff && strcmp("*", buff) == 0) { -+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\""); -+ FREE(buff); -+ return strdup(".*"); -+ } -+ return buff; -+} -+ - /* non-recursive configuration stream handler */ - static int kw_level = 0; - -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 519b805..96f40bd 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -73,6 +73,7 @@ extern void dump_keywords(vector keydump, int level); - extern void free_keywords(vector keywords); - extern vector alloc_strvec(char *string); - extern void *set_value(vector strvec); -+extern void *set_regex_value(vector strvec); - extern int process_file(struct config *conf, char *conf_file); - extern struct keyword * find_keyword(vector keywords, vector v, char * name); - int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, --- -2.7.4 - diff --git a/0011-RH-add-mpathconf.patch b/0011-RH-add-mpathconf.patch new file mode 100644 index 0000000..cd3fca0 --- /dev/null +++ b/0011-RH-add-mpathconf.patch @@ -0,0 +1,648 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 16 Oct 2014 15:49:01 -0500 +Subject: [PATCH] RH: add mpathconf + +mpathconf is a program (largely based on lvmcomf) to help users +configure /etc/multipath.conf and enable or disable multipathing. It +has a couple of built-in options that can be set directly from the +command line. But, mostly it is used to get a multipath.conf file +with the OS defaults, and to enable and disable multipathing via +a single command. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 1 + + multipath/Makefile | 5 + + multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 101 +++++++++++ + 4 files changed, 571 insertions(+) + create mode 100644 multipath/mpathconf + create mode 100644 multipath/mpathconf.8 + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 85e32ee..f1a6ca8 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -664,6 +664,7 @@ load_config (char * file) + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "A default multipath.conf file is located at"); + condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); ++ condlog(0, "You can run /sbin/mpathconf to create or modify /etc/multipath.conf"); + if (conf->blist_devnode == NULL) { + conf->blist_devnode = vector_alloc(); + if (!conf->blist_devnode) { +diff --git a/multipath/Makefile b/multipath/Makefile +index dda5565..d35127a 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + $(GZIP) $(EXEC).8 > $(EXEC).8.gz + $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz ++ $(GZIP) mpathconf.8 > mpathconf.8.gz + + install: + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules +@@ -29,13 +31,16 @@ install: + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) ++ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir) + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules ++ $(RM) $(DESTDIR)$(bindir)/mpathconf + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz ++ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz + + clean: + $(RM) core *.o $(EXEC) *.gz +diff --git a/multipath/mpathconf b/multipath/mpathconf +new file mode 100644 +index 0000000..e839134 +--- /dev/null ++++ b/multipath/mpathconf +@@ -0,0 +1,464 @@ ++#!/bin/bash ++# ++# 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 ++# ++ ++unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++ ++DEFAULT_CONFIG="# device-mapper-multipath configuration file ++ ++# For a complete list of the default configuration values, run either: ++# # multipath -t ++# or ++# # multipathd show config ++ ++# For a list of configuration options with descriptions, see the ++# multipath.conf man page. ++ ++defaults { ++ user_friendly_names yes ++ find_multipaths yes ++} ++ ++blacklist_exceptions { ++ property \"(SCSI_IDENT_|ID_WWN)\" ++}" ++ ++CONFIGFILE="/etc/multipath.conf" ++OUTPUTFILE="/etc/multipath.conf" ++MULTIPATHDIR="/etc/multipath" ++TMPFILE="/etc/multipath/.multipath.conf.tmp" ++WWIDS=0 ++ ++function usage ++{ ++ echo "usage: $0 " ++ echo "" ++ echo "Commands:" ++ echo "Enable: --enable " ++ echo "Disable: --disable" ++ echo "Only allow certain wwids (instead of enable): --allow " ++ echo "Set user_friendly_names (Default y): --user_friendly_names " ++ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Load the dm-multipath modules on enable (Default y): --with_module " ++ echo "start/stop/reload multipathd (Default n): --with_multipathd " ++ echo "select output file (Default /etc/multipath.conf): --outfile " ++ echo "" ++} ++ ++function add_wwid ++{ ++ INDEX=0 ++ while [ "$INDEX" -lt "$WWIDS" ] ; do ++ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then ++ return ++ fi ++ ((INDEX++)) ++ done ++ WWID_LIST[$WWIDS]="$1" ++ ((WWIDS++)) ++} ++ ++function get_dm_deps ++{ ++ shift 3 ++ while [ -n "$1" -a -n "$2" ]; do ++ MAJOR=$(echo $1 | tr -d '(,') ++ MINOR=$(echo $2 | tr -d ')') ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ fi ++ shift 2 ++ done ++} ++ ++function set_dm_wwid ++{ ++ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then ++ add_wwid "${1##part*-mpath-}" ++ elif [[ "$1" =~ ^mpath- ]] ; then ++ add_wwid "${1##mpath-}" ++ else ++ get_dm_deps `dmsetup deps -u $1` ++ fi ++} ++ ++function set_wwid ++{ ++ UUID="" ++ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then ++ MAJOR=${1%%:*} ++ MINOR=${1##*:} ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ else ++ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null` ++ fi ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ else ++ add_wwid "$1" ++ fi ++} ++ ++function parse_args ++{ ++ while [ -n "$1" ]; do ++ case $1 in ++ --enable) ++ ENABLE=1 ++ shift ++ ;; ++ --disable) ++ ENABLE=0 ++ shift ++ ;; ++ --allow) ++ ENABLE=2 ++ if [ -n "$2" ]; then ++ set_wwid $2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --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 ++ ;; ++ --with_module) ++ if [ -n "$2" ]; then ++ MODULE=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --with_multipathd) ++ if [ -n "$2" ]; then ++ MULTIPATHD=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --outfile) ++ if [ -n "$2" ]; then ++ OUTPUTFILE=$2 ++ HAVE_OUTFILE=1 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ *) ++ usage ++ exit ++ esac ++ done ++} ++ ++function validate_args ++{ ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then ++ echo "ignoring extra parameters on disable" ++ FRIENDLY="" ++ FIND="" ++ MODULE="" ++ 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 ++ SHOW_STATUS=1 ++ fi ++ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then ++ echo "--with_module must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then ++ echo "--with_multipathd must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then ++ echo "Because --allow makes changes that cannot be automatically reversed," ++ echo "you must set --outfile when you set --allow" ++ exit 1 ++ fi ++} ++ ++function add_blacklist_exceptions ++{ ++ INDEX=0 ++ while [ "$INDEX" -lt "$WWIDS" ] ; do ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ wwid '"\"${WWID_LIST[$INDEX]}\""' ++' $TMPFILE ++ ((INDEX++)) ++ done ++} ++ ++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 ++echo "$DEFAULT_CONFIG" > $TMPFILE ++if [ -f "$CONFIGFILE" ]; then ++ cp $CONFIGFILE $TMPFILE ++fi ++ ++if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then ++ HAVE_BLACKLIST=1 ++fi ++ ++if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then ++ HAVE_EXCEPTIONS=1 ++fi ++ ++if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then ++ HAVE_DEFAULTS=1 ++fi ++ ++if [ -z "$MODULE" -o "$MODULE" = "y" ]; then ++ if lsmod | grep -q "dm_multipath" ; then ++ HAVE_MODULE=1 ++ else ++ HAVE_MODULE=0 ++ fi ++fi ++ ++if [ "$MULTIPATHD" = "y" ]; then ++ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then ++ HAVE_MULTIPATHD=1 ++ else ++ HAVE_MULTIPATHD=0 ++ fi ++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_BLACKLIST" = "1" ]; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then ++ HAVE_WWID_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 "$SHOW_STATUS" ]; 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 ++ if [ -n "$HAVE_MODULE" ]; then ++ if [ "$HAVE_MODULE" = 1 ]; then ++ echo "dm_multipath module is loaded" ++ else ++ echo "dm_multipath module is not loaded" ++ fi ++ fi ++ if [ -z "$HAVE_MULTIPATHD" ]; then ++ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then ++ HAVE_MULTIPATHD=1 ++ else ++ HAVE_MULTIPATHD=0 ++ fi ++ fi ++ if [ "$HAVE_MULTIPATHD" = 1 ]; then ++ echo "multipathd is running" ++ else ++ echo "multipathd is not running" ++ 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" = 2 ]; then ++ if [ "$HAVE_DISABLE" = 1 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ fi ++ if [ -z "$HAVE_WWID_DISABLE" ]; then ++ sed -i '/^blacklist[[:space:]]*{/ a\ ++ wwid ".*" ++' $TMPFILE ++ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE ++ fi ++ if [ "$HAVE_EXCEPTIONS" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE ++ else ++ cat >> $TMPFILE <<- _EOF_ ++ ++blacklist_exceptions { ++} ++_EOF_ ++ fi ++ add_blacklist_exceptions ++elif [ "$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 ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FIND" = "y" ]; then ++ if [ -z "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ find_multipaths yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FIND" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ 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 ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FRIENDLY" = "y" ]; then ++ if [ -z "$HAVE_FRIENDLY" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ user_friendly_names yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FRIENDLY" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ -f "$OUTPUTFILE" ]; then ++ cp $OUTPUTFILE $OUTPUTFILE.old ++ if [ $? != 0 ]; then ++ echo "failed to backup old config file, $OUTPUTFILE not updated" ++ exit 1 ++ fi ++fi ++ ++cp $TMPFILE $OUTPUTFILE ++if [ $? != 0 ]; then ++ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK" ++ exit 1 ++fi ++ ++rm -f $TMPFILE ++ ++if [ "$ENABLE" = 1 ]; then ++ if [ "$HAVE_MODULE" = 0 ]; then ++ modprobe dm_multipath ++ fi ++ if [ "$HAVE_MULTIPATHD" = 0 ]; then ++ systemctl start multipathd.service ++ fi ++elif [ "$ENABLE" = 0 ]; then ++ if [ "$HAVE_MULTIPATHD" = 1 ]; then ++ systemctl stop multipathd.service ++ fi ++elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then ++ systemctl reload multipathd.service ++fi +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +new file mode 100644 +index 0000000..4cd3267 +--- /dev/null ++++ b/multipath/mpathconf.8 +@@ -0,0 +1,101 @@ ++.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" ++.SH NAME ++mpathconf - A tool for configuring device-mapper-multipath ++.SH SYNOPSIS ++.B mpathconf ++.RB [\| commands \|] ++.RB [\| options \|] ++.SH DESCRIPTION ++.B mpathconf ++is a utility that creates or modifies ++.B /etc/multipath.conf. ++It can enable or disable multipathing and configure some common options. ++.B mpathconf ++can also load the ++.B dm_multipath ++module, start and stop the ++.B multipathd ++daemon, and configure the ++.B multipathd ++service to start automatically or not. If ++.B mpathconf ++is called with no commands, it will display the current configuration. ++ ++The default options for mpathconf are ++.B --with_module ++The ++.B --with_multipathd ++option is not set by default. Enabling multipathing will load the ++.B dm_multipath ++module but it will not immediately start it. This is so ++that users can manually edit their config file if necessary, before starting ++.B multipathd. ++ ++If ++.B /etc/multipath.conf ++already exists, mpathconf will edit it. If it does not exist, mpathconf will ++create a default file with ++.B user_friendly_names ++and ++.B find_multipaths ++set. To disable these, use the ++.B --user_friendly_names n ++and ++.B --find_multipaths n ++options ++.SH COMMANDS ++.TP ++.B --enable ++Removes any line that blacklists all device nodes from the ++.B /etc/multipath.conf ++blacklist section. ++.TP ++.B --disable ++Adds a line that blacklists all device nodes to the ++.B /etc/multipath.conf ++blacklist section. If no blacklist section exists, it will create one. ++.TP ++.B --user_friendly_name \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B user_friendly_names yes ++to the ++.B /etc/multipath.conf ++defaults section. If set to \fBn\fP, this removes the line, if present. This ++command can be used along with any other command. ++.TP ++.B --find_multipaths\fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B find_multipaths yes ++to the ++.B /etc/multipath.conf ++defaults section. If set to \fBn\fP, this removes the line, if present. This ++command can be used aldong with any other command. ++.SH OPTIONS ++.TP ++.B --with_module\fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this runs ++.B modprobe dm_multipath ++to install the multipath modules. This option only works with the ++.B --enable ++command. This option is set to \fBy\fP by default. ++.TP ++.B --with_multipathd { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this runs ++.B service multipathd start ++to start the multipathd daemon on \fB--enable\fP, ++.B service multipathd stop ++to stop the multipathd daemon on \fB--disable\fP, and ++.B service multipathd reload ++to reconfigure multipathd on \fB--user_frindly_names\fP and ++\fB--find_multipaths\fP. ++This option is set to \fBn\fP by default. ++.SH FILES ++.BR /etc/multipath.conf ++.SH "SEE ALSO" ++.BR multipath.conf (5), ++.BR modprobe (8), ++.BR multipath (8), ++.BR multipathd (8), ++.BR service (8), ++.SH AUTHOR ++Benjamin Marzinski +-- +2.7.4 + diff --git a/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch new file mode 100644 index 0000000..a5ef7bd --- /dev/null +++ b/0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -0,0 +1,166 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 17 Oct 2014 11:20:34 -0500 +Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A + +This patch adds another option to multipath, "-A", which reads +/proc/cmdline for mpath.wwid= options, and adds any wwids it finds +to /etc/multipath/wwids. While this isn't usually important during +normal operation, since these wwids should already be added, it can be +helpful during installation, to make sure that multipath can claim +devices as its own, before LVM or something else makes use of them. The +patch also execs "/sbin/multipath -A" before running multipathd in +multipathd.service + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++++++++++ + libmultipath/wwids.h | 1 + + multipath/main.c | 10 ++++++++-- + multipath/multipath.8 | 5 ++++- + multipathd/multipathd.service | 1 + + 5 files changed, 58 insertions(+), 3 deletions(-) + +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index bc70a27..88bb72b 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -321,3 +321,47 @@ remember_wwid(char *wwid) + condlog(4, "wwid %s already in wwids file", wwid); + return 0; + } ++ ++int remember_cmdline_wwid(void) ++{ ++ FILE *f = NULL; ++ char buf[LINE_MAX], *next, *ptr; ++ int ret = 0; ++ ++ f = fopen("/proc/cmdline", "re"); ++ if (!f) { ++ condlog(0, "can't open /proc/cmdline : %s", strerror(errno)); ++ return -1; ++ } ++ ++ if (!fgets(buf, sizeof(buf), f)) { ++ if (ferror(f)) ++ condlog(0, "read of /proc/cmdline failed : %s", ++ strerror(errno)); ++ else ++ condlog(0, "couldn't read /proc/cmdline"); ++ fclose(f); ++ return -1; ++ } ++ fclose(f); ++ next = buf; ++ while((ptr = strstr(next, "mpath.wwid="))) { ++ ptr += 11; ++ next = strpbrk(ptr, " \t\n"); ++ if (next) { ++ *next = '\0'; ++ next++; ++ } ++ if (strlen(ptr)) { ++ if (remember_wwid(ptr) != 0) ++ ret = -1; ++ } ++ else { ++ condlog(0, "empty mpath.wwid kernel command line option"); ++ ret = -1; ++ } ++ if (!next) ++ break; ++ } ++ return ret; ++} +diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h +index 9527012..b665232 100644 +--- a/libmultipath/wwids.h ++++ b/libmultipath/wwids.h +@@ -17,5 +17,6 @@ int remember_wwid(char *wwid); + int check_wwids_file(char *wwid, int write_wwid); + int remove_wwid(char *wwid); + int replace_wwids(vector mp); ++int remember_cmdline_wwid(void); + + #endif /* _WWIDS_H */ +diff --git a/multipath/main.c b/multipath/main.c +index bffe065..2e69300 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -102,7 +102,7 @@ usage (char * progname) + { + fprintf (stderr, VERSION_STRING); + fprintf (stderr, "Usage:\n"); +- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); ++ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); + fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); + fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); + fprintf (stderr, " %s -t\n", progname); +@@ -116,6 +116,8 @@ usage (char * progname) + " -f flush a multipath device map\n" + " -F flush all multipath device maps\n" + " -a add a device wwid to the wwids file\n" ++ " -A add devices from kernel command line mpath.wwids\n" ++ " parameters to wwids file\n" + " -c check if a device should be a path in a multipath device\n" + " -C check if a multipath device has usable paths\n" + " -q allow queue_if_no_path when multipathd is not running\n" +@@ -598,7 +600,7 @@ main (int argc, char *argv[]) + exit(1); + multipath_conf = conf; + conf->retrigger_tries = 0; +- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -665,6 +667,10 @@ main (int argc, char *argv[]) + case 't': + r = dump_config(conf); + goto out_free_config; ++ case 'A': ++ if (remember_cmdline_wwid() != 0) ++ exit(1); ++ exit(0); + case 'h': + usage(argv[0]); + exit(0); +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 56f8703..9fc2317 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -25,7 +25,7 @@ multipath \- Device mapper target autoconfig. + .RB [\| \-b\ \c + .IR bindings_file \|] + .RB [\| \-d \|] +-.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-u | \-U | \-w | \-W \|] ++.RB [\| \-h | \-l | \-ll | \-f | \-t | \-F | \-B | \-c | \-C | \-q | \-r | \-i | \-a | \-A | \-u | \-U | \-w | \-W \|] + .RB [\| \-p\ \c + .IR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|] + .RB [\| \-R\ \c +@@ -128,6 +128,9 @@ Add the WWID for the specified device to the WWIDs file. + Check if the device specified in the program environment should be + a path in a multipath device. + . ++.B \-A ++add wwids from any kernel command line mpath.wwid parameters to the wwids file ++. + .TP + .B \-U + Check if the device specified in the program environment is a multipath device +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index fafd088..a623a3f 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -15,6 +15,7 @@ Type=notify + NotifyAccess=main + LimitCORE=infinity + ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath ++ExecStartPre=-/sbin/multipath -A + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + +-- +2.7.4 + diff --git a/0013-RH-trigger-change-uevent-on-new-device-creation.patch b/0013-RH-trigger-change-uevent-on-new-device-creation.patch new file mode 100644 index 0000000..391485e --- /dev/null +++ b/0013-RH-trigger-change-uevent-on-new-device-creation.patch @@ -0,0 +1,138 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 24 Apr 2017 09:39:57 -0500 +Subject: [PATCH] RH: trigger change uevent on new device creation + +When multipath first sees a path device with user_friendly names +enabled, it can't know if the device should be multipathed. This means +that it will not claim the device in udev. If the device is eventually +multipathed, multipath should trigger a change uevent to update the udev +database to claim the device. + +This also reverts commit 64e27ec066a001012f44550f095c93443e91d845. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 26 ++++++++++++++++++++++++-- + libmultipath/configure.h | 1 + + libmultipath/wwids.c | 4 ++-- + multipath/main.c | 2 +- + multipathd/main.c | 7 ++----- + 5 files changed, 30 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index e2f393f..64d7751 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -423,6 +423,28 @@ trigger_udev_change(const struct multipath *mpp) + udev_device_unref(udd); + } + ++void ++trigger_paths_udev_change(const struct multipath *mpp) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ int i, j; ++ ++ if (!mpp || !mpp->pg) ++ return; ++ ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ if (!pgp->paths) ++ continue; ++ vector_foreach_slot(pgp->paths, pp, j) { ++ if (!pp->udev) ++ continue; ++ sysfs_attr_set_value(pp->udev, "uevent", "change", ++ strlen("change")); ++ } ++ } ++} ++ + static int + is_mpp_known_to_udev(const struct multipath *mpp) + { +@@ -814,8 +836,8 @@ int domap(struct multipath *mpp, char *params, int is_daemon) + * succeeded + */ + mpp->force_udev_reload = 0; +- if (mpp->action == ACT_CREATE) +- remember_wwid(mpp->wwid); ++ if (mpp->action == ACT_CREATE && remember_wwid(mpp->wwid) == 1) ++ trigger_paths_udev_change(mpp); + if (!is_daemon) { + /* multipath client mode */ + dm_switchgroup(mpp->alias, mpp->bestpg); +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index 0ffc28e..09603ba 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -37,3 +37,4 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type, + int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon); + int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name); + struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); ++void trigger_paths_udev_change(const struct multipath *mpp); +diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c +index 88bb72b..249c6c1 100644 +--- a/libmultipath/wwids.c ++++ b/libmultipath/wwids.c +@@ -319,7 +319,7 @@ remember_wwid(char *wwid) + condlog(3, "wrote wwid %s to wwids file", wwid); + else + condlog(4, "wwid %s already in wwids file", wwid); +- return 0; ++ return ret; + } + + int remember_cmdline_wwid(void) +@@ -353,7 +353,7 @@ int remember_cmdline_wwid(void) + next++; + } + if (strlen(ptr)) { +- if (remember_wwid(ptr) != 0) ++ if (remember_wwid(ptr) < 0) + ret = -1; + } + else { +diff --git a/multipath/main.c b/multipath/main.c +index 2e69300..4dde5af 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -412,7 +412,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + } + if (cmd == CMD_ADD_WWID) { + r = remember_wwid(refwwid); +- if (r == 0) ++ if (r >= 0) + printf("wwid '%s' added\n", refwwid); + else + printf("failed adding '%s' to wwids file\n", +diff --git a/multipathd/main.c b/multipathd/main.c +index c475fcd..50749a8 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2138,7 +2138,8 @@ configure (struct vectors * vecs, int start_waiters) + + sync_maps_state(mpvec); + vector_foreach_slot(mpvec, mpp, i){ +- remember_wwid(mpp->wwid); ++ if (remember_wwid(mpp->wwid) == 1) ++ trigger_paths_udev_change(mpp); + update_map_pr(mpp); + } + +@@ -2220,10 +2221,6 @@ reconfigure (struct vectors * vecs) + conf->verbosity = verbosity; + if (bindings_read_only) + conf->bindings_read_only = bindings_read_only; +- if (conf->find_multipaths) { +- condlog(2, "find_multipaths is set: -n is implied"); +- ignore_new_devs = 1; +- } + if (ignore_new_devs) + conf->ignore_new_devs = ignore_new_devs; + uxsock_timeout = conf->uxsock_timeout; +-- +2.7.4 + diff --git a/0014-RH-warn-on-invalid-regex-instead-of-failing.patch b/0014-RH-warn-on-invalid-regex-instead-of-failing.patch new file mode 100644 index 0000000..22a66a2 --- /dev/null +++ b/0014-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 6 Nov 2017 21:39:28 -0600 +Subject: [PATCH] RH: warn on invalid regex instead of failing + +multipath.conf used to allow "*" as a match everything regular expression, +instead of requiring ".*". Instead of erroring when the old style +regular expressions are used, it should print a warning and convert +them. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 27 +++++++++++++++++++++------ + libmultipath/parser.c | 13 +++++++++++++ + libmultipath/parser.h | 1 + + 3 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 54652d4..8d97602 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -52,6 +52,21 @@ set_str(vector strvec, void *ptr) + } + + static int ++set_regex(vector strvec, void *ptr) ++{ ++ char **str_ptr = (char **)ptr; ++ ++ if (*str_ptr) ++ FREE(*str_ptr); ++ *str_ptr = set_regex_value(strvec); ++ ++ if (!*str_ptr) ++ return 1; ++ ++ return 0; ++} ++ ++static int + set_yes_no(vector strvec, void *ptr) + { + char * buff; +@@ -1190,7 +1205,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ + if (!conf->option) \ + return 1; \ + \ +- buff = set_value(strvec); \ ++ buff = set_regex_value(strvec); \ + if (!buff) \ + return 1; \ + \ +@@ -1206,7 +1221,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ + if (!conf->option) \ + return 1; \ + \ +- buff = set_value(strvec); \ ++ buff = set_regex_value(strvec); \ + if (!buff) \ + return 1; \ + \ +@@ -1301,16 +1316,16 @@ device_handler(struct config *conf, vector strvec) + return 0; + } + +-declare_hw_handler(vendor, set_str) ++declare_hw_handler(vendor, set_regex) + declare_hw_snprint(vendor, print_str) + +-declare_hw_handler(product, set_str) ++declare_hw_handler(product, set_regex) + declare_hw_snprint(product, print_str) + +-declare_hw_handler(revision, set_str) ++declare_hw_handler(revision, set_regex) + declare_hw_snprint(revision, print_str) + +-declare_hw_handler(bl_product, set_str) ++declare_hw_handler(bl_product, set_regex) + declare_hw_snprint(bl_product, print_str) + + declare_hw_handler(hwhandler, set_str) +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index c47d891..74b4efe 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -346,6 +346,19 @@ set_value(vector strvec) + return alloc; + } + ++void * ++set_regex_value(vector strvec) ++{ ++ char *buff = set_value(strvec); ++ ++ if (buff && strcmp("*", buff) == 0) { ++ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\""); ++ FREE(buff); ++ return strdup(".*"); ++ } ++ return buff; ++} ++ + /* non-recursive configuration stream handler */ + static int kw_level = 0; + +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index 519b805..96f40bd 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -73,6 +73,7 @@ extern void dump_keywords(vector keydump, int level); + extern void free_keywords(vector keywords); + extern vector alloc_strvec(char *string); + extern void *set_value(vector strvec); ++extern void *set_regex_value(vector strvec); + extern int process_file(struct config *conf, char *conf_file); + extern struct keyword * find_keyword(vector keywords, vector v, char * name); + int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, +-- +2.7.4 + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 6c8aca1..332e5ed 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,26 +1,30 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath -Version: 0.7.1 -Release: 8.git847cc43%{?dist} +Version: 0.7.3 +Release: 1%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -# curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=847cc43;sf=tgz" -o multipath-tools-git847cc43.tgz -Source0: multipath-tools-git847cc43.tgz +# curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.7.3;sf=tgz" -o multipath-tools-0.7.3.tgz +Source0: multipath-tools-0.7.3.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-update-3PARdata-builtin-config.patch -Patch0002: 0002-multipath-attempt-at-common-multipath.rules.patch -Patch0003: 0003-RH-fixup-udev-rules-for-redhat.patch -Patch0004: 0004-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0005: 0005-RH-don-t-start-without-a-config-file.patch -Patch0006: 0006-RH-use-rpm-optflags-if-present.patch -Patch0007: 0007-RH-add-mpathconf.patch -Patch0008: 0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0009: 0009-RH-trigger-change-uevent-on-new-device-creation.patch -Patch0010: 0010-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0001: 0001-mpathpersist-Fix-invalid-condition-check.patch +Patch0002: 0002-multipath-add-man-page-info-for-my-prkey-changes.patch +Patch0003: 0003-multipath-there-is-no-none-path-state.patch +Patch0004: 0004-mutipath-updated-Huawei-storage-config.patch +Patch0005: 0005-multipath-fix-doc-typo.patch +Patch0006: 0006-multipath-add-ghost_delay-parameter.patch +Patch0007: 0007-RH-fixup-udev-rules-for-redhat.patch +Patch0008: 0008-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0009: 0009-RH-don-t-start-without-a-config-file.patch +Patch0010: 0010-RH-use-rpm-optflags-if-present.patch +Patch0011: 0011-RH-add-mpathconf.patch +Patch0012: 0012-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0013: 0013-RH-trigger-change-uevent-on-new-device-creation.patch +Patch0014: 0014-RH-warn-on-invalid-regex-instead-of-failing.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -98,7 +102,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%setup -q -n multipath-tools-847cc43 +%setup -q -n multipath-tools-0.7.3 %patch0001 -p1 %patch0002 -p1 %patch0003 -p1 @@ -109,6 +113,10 @@ device-mapper-multipath's libdmmp C API library %patch0008 -p1 %patch0009 -p1 %patch0010 -p1 +%patch0011 -p1 +%patch0012 -p1 +%patch0013 -p1 +%patch0014 -p1 cp %{SOURCE1} . %build @@ -208,7 +216,11 @@ fi %{!?_licensedir:%global license %%doc} %license COPYING %{_sbindir}/kpartx +/usr/lib/udev/kpartx_id %{_mandir}/man8/kpartx.8.gz +%config /usr/lib/udev/rules.d/11-dm-parts.rules +%config /usr/lib/udev/rules.d/66-kpartx.rules +%config /usr/lib/udev/rules.d/68-del-part-nodes.rules %files -n libdmmp %defattr(-,root,root,-) @@ -230,6 +242,25 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Nov 7 2017 Benjamin Marzinski 0.7.3-1 +- Update Source to upstream 0.7.3 release + * Previous patch 0001 is included in this commit, and 0002 was solved in a + different manner causing some change to previous patch 0003 + * Previous patches 0003-0010 are now patches 0007-0014 +- Add 0001-mpathpersist-Fix-invalid-condition-check.patch + * Fix incorrect check. posted upstream +- Add 0002-multipath-add-man-page-info-for-my-prkey-changes.patch + * Add missing man page info. posted upstream +- Add 0003-multipath-there-is-no-none-path-state.patch + * remove incorrect path state. posted upstream +- Add 0004-mutipath-updated-Huawei-storage-config.patch + * update builtin device configuration. posted upstream +- Add 0005-multipath-fix-doc-typo.patch + * fix man page typo. posted upstream +- Add 0006-multipath-add-ghost_delay-parameter.patch + * add new multipath.conf parameter "ghost_delay". posted upstream + + * Tue Nov 7 2017 Benjamin Marzinski 0.7.1-8.git847cc43 - Refresh 0001-libmultipath-update-3PARdata-builtin-config.patch - Add 0010-RH-warn-on-invalid-regex-instead-of-failing.patch diff --git a/sources b/sources index 6cea34d..cc13e36 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 -SHA512 (multipath-tools-git847cc43.tgz) = b7d9fd34a6e171d1382de2eef75c6a0fe522ff4e76b34f682c53b1662559c134bebf84dbae78d64462d1af746b7bbcbfa72ac5282d1225bfd695598dd59d7e37 +SHA512 (multipath-tools-0.7.3.tgz) = d1e1f4e57ead7a79accf55173263138a78b86c3b846bac8ad2526f36f01fe32a8b7e6bb5bb785b083f3bdbf39c34c06032b7a0d6db6c4cc99e5bc98f67a7e7f3 -- cgit