From ebef98f4eb0558a8ff166d02e235d48252a9684c Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 07 2021 19:18:10 +0000 Subject: import device-mapper-multipath-0.8.7-3.el9 --- diff --git a/.device-mapper-multipath.metadata b/.device-mapper-multipath.metadata index 4fb0280..dc57af5 100644 --- a/.device-mapper-multipath.metadata +++ b/.device-mapper-multipath.metadata @@ -1 +1 @@ -a8afc76e75aeaba7e21c066ca95e236be3bfc5b4 SOURCES/multipath-tools-0.8.6.tgz +067d668de8e3a70b7c176bbf0c0616d5835bbe44 SOURCES/multipath-tools-0.8.7.tgz diff --git a/.gitignore b/.gitignore index 4d2c931..c2b966c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/multipath-tools-0.8.6.tgz +SOURCES/multipath-tools-0.8.7.tgz diff --git a/SOURCES/0001-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0001-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index e84f9e0..0000000 --- a/SOURCES/0001-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,63 +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. 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 f1e23131..c593fd3b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -55,7 +55,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 d7527d7d..0e0d70d5 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -36,6 +36,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 0828a8f7..b9bbb3cf 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/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch b/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch new file mode 100644 index 0000000..559d5a5 --- /dev/null +++ b/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 8 Sep 2021 22:33:54 +0200 +Subject: [PATCH] multipath-tools: add info about IO affinity path selector to + manpage + +Added in 5.11: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e4d2e82b2300b03f66b3ca8417590c86e661fab1 + +Cc: Mike Christie +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index d6b8c7f6..42a15ffd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -6,7 +6,7 @@ + .\" + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2018-05-21 Linux ++.TH MULTIPATH.CONF 5 2021-09-08 Linux + . + . + .\" ---------------------------------------------------------------------------- +@@ -210,6 +210,10 @@ of outstanding I/O to the path and its relative throughput. + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP ++.I "io-affinity 0" ++(Since 5.11 kernel) Choose the path for the next bunch of I/O based on a CPU to ++path mapping the user passes in and what CPU we are executing on. ++.TP + The default is: \fBservice-time 0\fR + .RE + . diff --git a/SOURCES/0002-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0002-RH-Remove-the-property-blacklist-exception-builtin.patch deleted file mode 100644 index dcb1491..0000000 --- a/SOURCES/0002-RH-Remove-the-property-blacklist-exception-builtin.patch +++ /dev/null @@ -1,101 +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 | 6 ++---- - multipath/multipath.conf.5 | 11 ++++++----- - tests/blacklist.c | 7 ++----- - 3 files changed, 10 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 6c6a5979..785f5ee9 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -201,9 +201,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) - return 1; - -- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) -- return 1; -- - vector_foreach_slot (conf->hwtable, hwe, i) { - if (hwe->bl_product) { - if (find_blacklist_device(conf->blist_device, -@@ -407,7 +404,8 @@ filter_property(const struct config *conf, struct udev_device *udev, - *uid_attribute != '\0'; - bool uid_attr_seen = false; - -- r = MATCH_PROPERTY_BLIST_MISSING; -+ if (VECTOR_SIZE(conf->elist_property)) -+ r = MATCH_PROPERTY_BLIST_MISSING; - udev_list_entry_foreach(list_entry, - udev_device_get_properties_list_entry(udev)) { - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 064e4826..0d2bce09 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1347,9 +1347,14 @@ keywords. Both are regular expressions. For a full description of these keywords - Regular expression for an udev property. All - devices that have matching udev properties will be excluded/included. - The handling of the \fIproperty\fR keyword is special, --because devices \fBmust\fR have at least one whitelisted udev property; -+because if a property blacklist_exception is set, devices \fBmust\fR have at -+least one whitelisted udev property; - otherwise they're treated as blacklisted, and the message - "\fIblacklisted, udev property missing\fR" is displayed in the logs. -+For example, setting the property blacklist_exception to -+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices -+that provide a WWN (World Wide Number) to be included, and all others to be -+excluded. This works to exclude most non-multipathable devices. - . - .RS - .PP -@@ -1360,10 +1365,6 @@ Blacklisting by missing properties is only applied to devices which do have the - property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) - set. Previously, it was applied to every device, possibly causing devices to be - blacklisted because of temporary I/O error conditions. --.PP --The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing --well-behaved SCSI devices and devices that provide a WWN (World Wide Number) --to be included, and all others to be excluded. - .RE - .TP - .B protocol -diff --git a/tests/blacklist.c b/tests/blacklist.c -index 882aa3a1..6a22b660 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -375,9 +375,8 @@ static void test_property_missing(void **state) - { - static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; - conf.blist_property = blist_property_wwn; -- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); - assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), -- MATCH_PROPERTY_BLIST_MISSING); -+ MATCH_NOTHING); - assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), - MATCH_NOTHING); - assert_int_equal(filter_property(&conf, &udev, 3, ""), -@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) - conf.blist_device = blist_device_foo_bar; - conf.blist_protocol = blist_protocol_fcp; - conf.blist_wwid = blist_wwid_xyzzy; -- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); -- assert_int_equal(filter_path(&conf, &miss1_pp), -- MATCH_PROPERTY_BLIST_MISSING); -+ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING); - } - - /* This one matches the property whitelist, to test the other missing diff --git a/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch b/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch new file mode 100644 index 0000000..5312160 --- /dev/null +++ b/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Mon, 13 Sep 2021 10:43:14 +0800 +Subject: [PATCH] multipathd: fix missing persistent reseravtion for active + path + +There are two paths(sucu as sda and adb) for one LUN. The two +paths log in, but before the two uevents have been processed +(for example there are many uevent), users use multipathd add +path /dev/sda to cause mpatha and use mpathpersist -o -I to +register prkey for mpatha. The add map uevent is after add path +uevent, the the uevent(add sdb) will delay and missing persistent +reseravtion check. + +Here, we add persistent reseravtion check in update_map() which +is called ev_add_map(). + +Signed-off-by: Lixiaokeng +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3aff241d..1defeaf1 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -490,6 +490,8 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; ++ struct path *pp; ++ int i; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -502,6 +504,15 @@ retry: + verify_paths(mpp); + mpp->action = ACT_RELOAD; + ++ if (mpp->prflag) { ++ vector_foreach_slot(mpp->paths, pp, i) { ++ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { ++ /* persistent reseravtion check*/ ++ mpath_pr_event_handle(pp); ++ } ++ } ++ } ++ + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; diff --git a/SOURCES/0003-RH-don-t-start-without-a-config-file.patch b/SOURCES/0003-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index 1d5c693..0000000 --- a/SOURCES/0003-RH-don-t-start-without-a-config-file.patch +++ /dev/null @@ -1,94 +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 | 13 +++++++++++++ - libmultipath/config.h | 1 + - multipath/multipath.rules | 1 + - multipathd/multipathd.8 | 2 ++ - multipathd/multipathd.service | 1 + - 5 files changed, 18 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 30046a17..5f35c3d3 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf) - goto out; - } - factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); -+ } else { -+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); -+ 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, ".*", 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 933fe0d1..5f01c1fc 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 - - enum devtypes { - DEV_NONE, -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 9df11a95..0486bf70 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -9,6 +9,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 048a838d..8bd47a80 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 7d547fa7..af592057 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-activation-early.service - Before=local-fs-pre.target blk-availability.service shutdown.target - After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service -+ConditionPathExists=/etc/multipath.conf - DefaultDependencies=no - Conflicts=shutdown.target - ConditionKernelCommandLine=!nompath diff --git a/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch b/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch new file mode 100644 index 0000000..ddad7b0 --- /dev/null +++ b/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 16 Sep 2021 00:44:49 +0200 +Subject: [PATCH] multipath-tools: minor fixes to multipath.conf.5 man page + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 42a15ffd..c74129bd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1,9 +1,9 @@ + .\" ---------------------------------------------------------------------------- +-.\" Update the date below if you make any significant change. + .\" Make sure there are no errors with: + .\" groff -z -wall -b -e -t multipath/multipath.conf.5 + .\" man --warnings -E UTF-8 -l -Tutf8 -Z multipath/multipath.conf.5 >/dev/null + .\" ++.\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . + .TH MULTIPATH.CONF 5 2021-09-08 Linux +@@ -189,7 +189,7 @@ The default is: \fB\fR + .TP + .B path_selector + The default path selector algorithm to use; they are offered by the +-kernel multipath target. There are three selector algorithms: ++kernel multipath target: + .RS + .TP 12 + .I "round-robin 0" +@@ -206,7 +206,7 @@ of outstanding I/O to the path. + of outstanding I/O to the path and its relative throughput. + .TP + .I "historical-service-time 0" +-(Since 5.8 kernel) Choose the path for the next bunch of IOs based on the ++(Since 5.8 kernel) Choose the path for the next bunch of I/O based on the + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP diff --git a/SOURCES/0004-RH-Fix-nvme-function-missing-argument.patch b/SOURCES/0004-RH-Fix-nvme-function-missing-argument.patch deleted file mode 100644 index ced7159..0000000 --- a/SOURCES/0004-RH-Fix-nvme-function-missing-argument.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 25 Jan 2019 14:54:56 -0600 -Subject: [PATCH] RH: Fix nvme function missing argument - -A future patch will change the compilation options to error when -function declarations have unspecified arguments. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/nvme/argconfig.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index adb192b6..bfd10ef8 100644 ---- a/libmultipath/nvme/argconfig.h -+++ b/libmultipath/nvme/argconfig.h -@@ -76,7 +76,7 @@ struct argconfig_commandline_options { - extern "C" { - #endif - --typedef void argconfig_help_func(); -+typedef void argconfig_help_func(void); - void argconfig_append_usage(const char *str); - void argconfig_print_help(const char *program_desc, - const struct argconfig_commandline_options *options); diff --git a/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch b/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch new file mode 100644 index 0000000..da06d58 --- /dev/null +++ b/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 25 Sep 2021 00:27:36 +0200 +Subject: [PATCH] multipath-tools: make IBM/XIV config work with alua and + multibus + +And add recommended pgfailback value. + +ALUA is supported since XIV_Gen2 and microcode 10.2.1 +(All ports across all controllers in single Target Port Group) + +https://www.ibm.com/support/pages/ibm-flashsystem%C2%AE-a9000-and-a9000r-hyperswap-solution-deployment-linux%C2%AE-ibm-z-systems%C2%AE +https://www.google.com/search?q=%222810XIV%22+%22path_grouping_policy%22+site%3Aibm.com + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +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 0caac0da..72f81c60 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -712,7 +712,8 @@ static struct hwentry default_hw[] = { + .vendor = "(XIV|IBM)", + .product = "(NEXTRA|2810XIV)", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = 15, + }, + { + /* TMS RamSan / FlashSystem 710/720/810/820/840/900 */ diff --git a/SOURCES/0005-RH-use-rpm-optflags-if-present.patch b/SOURCES/0005-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index debec54..0000000 --- a/SOURCES/0005-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,57 +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 | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index c593fd3b..87fb39f2 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -92,15 +92,27 @@ TEST_CC_OPTION = $(shell \ - echo "$(2)"; \ - fi) - --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - --OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -+ifndef RPM_OPT_FLAGS -+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -+ endif -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -+ endif -+else -+ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 -+endif -+WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -+ -Wstrict-prototypes - CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP -@@ -138,4 +150,4 @@ check_file = $(shell \ - - %.o: %.c - @echo building $@ because of $? -- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -+ $(CC) $(CFLAGS) -c -o $@ $< diff --git a/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch b/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch new file mode 100644 index 0000000..e6b34a2 --- /dev/null +++ b/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Luca BRUNO +Date: Fri, 24 Sep 2021 09:34:01 +0000 +Subject: [PATCH] multipathd.socket: add missing conditions from service unit + +This aligns 'multipathd' socket and service units, by adding the +start conditions that are set on the service but not on the socket. +It should help avoiding situations where the socket unit ends up +marked as failed after hitting its retry-limit. + +Fixes: https://github.com/opensvc/multipath-tools/issues/15 +Signed-off-by: Luca BRUNO +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/multipathd.socket | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index 0ed4a1f7..c777e5e3 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,9 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionKernelCommandLine=!nompath ++ConditionKernelCommandLine=!multipath=off ++ConditionVirtualization=!container + Before=sockets.target + + [Socket] diff --git a/SOURCES/0006-RH-add-mpathconf.patch b/SOURCES/0006-RH-add-mpathconf.patch deleted file mode 100644 index d262f55..0000000 --- a/SOURCES/0006-RH-add-mpathconf.patch +++ /dev/null @@ -1,771 +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 | 2 + - multipath/Makefile | 5 + - multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 697 insertions(+) - create mode 100644 multipath/mpathconf - create mode 100644 multipath/mpathconf.8 - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 5f35c3d3..cee3bbb7 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf) - factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); - } else { - condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); -+ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); -+ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details"); - if (conf->blist_devnode == NULL) { - conf->blist_devnode = vector_alloc(); - if (!conf->blist_devnode) { -diff --git a/multipath/Makefile b/multipath/Makefile -index b9bbb3cf..e720c7f6 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - $(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: dep_clean - $(RM) core *.o $(EXEC) *.gz -diff --git a/multipath/mpathconf b/multipath/mpathconf -new file mode 100644 -index 00000000..2f4f3eaf ---- /dev/null -+++ b/multipath/mpathconf -@@ -0,0 +1,555 @@ -+#!/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 PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN 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 -+ enable_foreign \"^$\" -+} -+ -+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 "Set default property blacklist (Default y): --property_blacklist " -+ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " -+ 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 -+ ;; -+ --property_blacklist) -+ if [ -n "$2" ]; then -+ PROPERTY=$2 -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; -+ --enable_foreign) -+ if [ -n "$2" ]; then -+ FOREIGN=$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 "$PROPERTY" -o -n "$MODULE" ]; then -+ echo "ignoring extra parameters on disable" -+ FRIENDLY="" -+ FIND="" -+ PROPERTY="" -+ 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 [ "$FIND" = "y" ]; then -+ FIND="yes" -+ elif [ "$FIND" = "n" ]; then -+ FIND="no" -+ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then -+ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" -+ exit 1 -+ fi -+ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then -+ echo "--property_blacklist must be either 'y' or 'n'" -+ exit 1 -+ fi -+ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then -+ echo "--enable_foreign must be either 'y' or 'n'" -+ exit 1 -+ fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; 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 -+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` -+ if [ "$HAVE_FIND" = "1" ]; then -+ HAVE_FIND="yes" -+ elif [ "$HAVE_FIND" = "0" ]; then -+ HAVE_FIND="no" -+ 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 -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then -+ HAVE_FOREIGN=0 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then -+ HAVE_FOREIGN=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then -+ HAVE_FOREIGN=2 -+ fi -+fi -+ -+if [ "$HAVE_EXCEPTIONS" = "1" ]; then -+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then -+ HAVE_PROPERTY=1 -+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then -+ HAVE_PROPERTY=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" ]; then -+ echo "find_multipaths is no" -+ else -+ echo "find_multipaths is $HAVE_FIND" -+ 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 [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then -+ echo "default property blacklist is disabled" -+ else -+ echo "default property blacklist is enabled" -+ fi -+ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then -+ echo "enable_foreign is not set (all foreign multipath devices will be shown)" -+ elif [ "$HAVE_FOREIGN" = 1 ]; then -+ echo "enable_foreign is set (no foreign multipath devices will be shown)" -+ else -+ echo "enable_foreign is set (foreign multipath devices may not be shown)" -+ 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 [ -n "$FIND" ]; then -+ if [ -z "$HAVE_FIND" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ find_multipaths '"$FIND"' -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$FIND" != "$HAVE_FIND" ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $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 [ "$PROPERTY" = "n" ]; then -+ if [ "$HAVE_PROPERTY" = 1 ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$PROPERTY" = "y" ]; then -+ if [ -z "$HAVE_PROPERTY" ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ -+ property "(SCSI_IDENT_|ID_WWN)" -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_PROPERTY" = 0 ]; then -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+fi -+ -+if [ "$FOREIGN" = "y" ]; then -+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FOREIGN" = "n" ]; then -+ if [ -z "$HAVE_FOREIGN" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ enable_foreign "^$" -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $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 00000000..83515eb4 ---- /dev/null -+++ b/multipath/mpathconf.8 -@@ -0,0 +1,135 @@ -+.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, but -+will not create of modify -+.B /etc/multipath.conf -+ -+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 -+set and -+.B find_multipaths -+set to \fByes\fP. 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. Also, creates -+.B /etc/multipath.conf -+if it doesn't exist. -+.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 --allow \fB\fP -+Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all -+wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\fP -+can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper -+device, either a multipath device, or any device on stacked on top of one or -+more multipath devices. This command can be used multiple times to allow -+multiple devices. \fBNOTE:\fP This action will create a configuration file that -+mpathconf will not be able to revert back to its previous state. Because -+of this, \fB--outfile\fP is required when using \fB--allow\fP. -+.TP -+.B --user_friendly_names \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 { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } -+If set to \fB\fP, this adds the line -+.B find_multipaths -+to the -+.B /etc/multipath.conf -+defaults section. This command can be used along with any other command. -+\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. -+.TP -+.B --property_blacklist \fP { \fBy\fP | \fBn\fP } -+If set to \fBy\fP, this adds the line -+.B property "(SCSI_IDENT_|ID_WWN)" -+to the -+.B /etc/multipath.conf -+blacklist_exceptions section. If set to \fBn\fP, this removes the line, if -+present. This command can be used along with any other command. -+.TP -+.B --enable_foreign\fP { \fBy\fP | \fBn\fP } -+If set to \fBn\fP, this adds the line -+.B enable_foreign "^$" -+to the -+.B /etc/multipath.conf -+defaults section. if set to \fBy\fP, this removes the line, if present. This -+command can be used along with any other command. -+.TP -+.B --outfile \fB\fP -+Write the resulting multipath configuration to \fB\fP instead of -+\fB/etc/multipath.conf\fP. -+.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 diff --git a/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch b/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch new file mode 100644 index 0000000..97cc8ef --- /dev/null +++ b/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 18:52:10 +0200 +Subject: [PATCH] multipath-tools: make IBM/2107900 (DS8000) config work with + alua and multibus + +ALUA is supported since the beginning: +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/device_handler/scsi_dh_alua.c?id=057ea7c9683c3d684128cced796f03c179ecf1c2#n683 + +... the DS8000 is an Asymmetric Logical Unit Access (ALUA) capable storage array, +pag#160(144): https://www.redbooks.ibm.com/redbooks/pdfs/sg248887.pdf + +kernel log: +https://marc.info/?l=linux-scsi&m=156407413807511&q=mbox + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +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 72f81c60..f115c4f9 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -656,7 +656,8 @@ static struct hwentry default_hw[] = { + .vendor = "IBM", + .product = "^2107900", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / diff --git a/SOURCES/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/SOURCES/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch deleted file mode 100644 index 557669b..0000000 --- a/SOURCES/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ /dev/null @@ -1,151 +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 ---- - multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- - multipath/multipath.8 | 7 ++++- - multipathd/multipathd.service | 1 + - 3 files changed, 59 insertions(+), 3 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index ef89c7cf..f618550d 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -122,7 +122,7 @@ usage (char * progname) - fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); - fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); - fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); -- fprintf (stderr, " %s [-v level] -W\n", progname); -+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); - fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); - fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); - fprintf (stderr, " %s [-h|-t|-T]\n", progname); -@@ -136,6 +136,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" -@@ -450,6 +452,50 @@ static void cleanup_vecs(void) - free_pathvec(vecs.pathvec, FREE_PATHS); - } - -+static 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; -+} -+ - static int - configure (struct config *conf, enum mpath_cmds cmd, - enum devtypes dev_type, char *devpath) -@@ -823,7 +869,7 @@ main (int argc, char *argv[]) - conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -900,6 +946,10 @@ main (int argc, char *argv[]) - case 'T': - cmd = CMD_DUMP_CONFIG; - break; -+ case 'A': -+ if (remember_cmdline_wwid() != 0) -+ exit(RTVL_FAIL); -+ exit(RTVL_OK); - case 'h': - usage(argv[0]); - exit(RTVL_OK); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 5b29a5d9..0478f4e7 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. - .B multipath - .RB [\| \-v\ \c - .IR level \|] --.B -W -+.RB [\| \-A | \-W \|] - . - .LP - .B multipath -@@ -145,6 +145,11 @@ device mapper, path checkers ...). - Add the WWID for the specified device to the WWIDs file. - . - .TP -+.B \-A -+Add the WWIDs from any kernel command line \fImpath.wwid\fR 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 af592057..bc8fa07a 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 - TasksMax=infinity diff --git a/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch b/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch new file mode 100644 index 0000000..201232a --- /dev/null +++ b/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:20:59 +0200 +Subject: [PATCH] multipath-tools: make EMC/SYMMETRIX config work with alua and + multibus + +ALUA is supported since VMAX3 and HYPERMAX OS 5977.811.784, pag#113: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +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 f115c4f9..7095aaf1 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,8 +329,9 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 6, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/SOURCES/0008-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0008-RH-reset-default-find_mutipaths-value-to-off.patch deleted file mode 100644 index d5b5601..0000000 --- a/SOURCES/0008-RH-reset-default-find_mutipaths-value-to-off.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 7 Jun 2018 17:43:52 -0500 -Subject: [PATCH] RH: reset default find_mutipaths value to off - -Upstream has changed to default find_multipaths to "strict". For now -Redhat will retain the previous default of "off". - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index c27946c7..e0dd32ad 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -23,7 +23,7 @@ - #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF - #define DEFAULT_VERBOSITY 2 - #define DEFAULT_REASSIGN_MAPS 0 --#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT -+#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF - #define DEFAULT_FAST_IO_FAIL 5 - #define DEFAULT_DEV_LOSS_TMO 600 - #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch b/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch new file mode 100644 index 0000000..723f023 --- /dev/null +++ b/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:31:21 +0200 +Subject: [PATCH] multipath-tools: make EMC/Invista config work with alua and + multibus + +Optimal Path Management (OPM) was introduced with VPLEX 5.5 to improve VPLEX +performance. OPM uses the ALUA mechanism to spread the I/O load across VPLEX directors +while gaining cache locality, pag #187: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +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 7095aaf1..4e8b52ff 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,8 +350,9 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 5, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/SOURCES/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch deleted file mode 100644 index 06233ff..0000000 --- a/SOURCES/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Apr 2019 13:25:42 -0500 -Subject: [PATCH] RH: attempt to get ANA info via sysfs first - -When the ANA prioritizer is run, first see if the "ana_state" sysfs file -exists, and if it does, try to read the state from there. If that fails, -fallback to using an ioctl. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index b5c7873d..e139360c 100644 ---- a/libmultipath/prioritizers/ana.c -+++ b/libmultipath/prioritizers/ana.c -@@ -24,6 +24,7 @@ - #include "prio.h" - #include "util.h" - #include "structs.h" -+#include "sysfs.h" - - enum { - ANA_ERR_GETCTRL_FAILED = 1, -@@ -36,6 +37,7 @@ enum { - ANA_ERR_GETNS_FAILED, - ANA_ERR_NO_MEMORY, - ANA_ERR_NO_INFORMATION, -+ ANA_ERR_INVALID_STATE, - }; - - static const char *ana_errmsg[] = { -@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { - [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", - [ANA_ERR_NO_MEMORY] = "out of memory", - [ANA_ERR_NO_INFORMATION] = "invalid fd", -+ [ANA_ERR_INVALID_STATE] = "invalid state", - }; - - static const char *anas_string[] = { -@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, - return -ANA_ERR_GETANAS_NOTFOUND; - } - -+static int get_ana_info_sysfs(struct path *pp) -+{ -+ char state[32]; -+ -+ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state, -+ sizeof(state)) <= 0) -+ return -ANA_ERR_NO_INFORMATION; -+ -+ if (strcmp(state, "optimized") == 0) -+ return NVME_ANA_OPTIMIZED; -+ if (strcmp(state, "non-optimized") == 0) -+ return NVME_ANA_NONOPTIMIZED; -+ if (strcmp(state, "inaccessible") == 0) -+ return NVME_ANA_INACCESSIBLE; -+ if (strcmp(state, "persistent-loss") == 0) -+ return NVME_ANA_PERSISTENT_LOSS; -+ if (strcmp(state, "change") == 0) -+ return NVME_ANA_CHANGE; -+ return -ANA_ERR_INVALID_STATE; -+} -+ - static int get_ana_info(struct path * pp) - { - int rc; -@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, - - if (pp->fd < 0) - rc = -ANA_ERR_NO_INFORMATION; -- else -- rc = get_ana_info(pp); -+ else { -+ rc = get_ana_info_sysfs(pp); -+ if (rc < 0) -+ rc = get_ana_info(pp); -+ } - - switch (rc) { - case NVME_ANA_OPTIMIZED: diff --git a/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch b/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch new file mode 100644 index 0000000..e2a93ee --- /dev/null +++ b/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:15:56 +0200 +Subject: [PATCH] multipath-tools: make "COMPELNT/Compellent Vol" config work + with alua and multibus + +ALUA is needed by SAS arrays, pag#124: +https://downloads.dell.com/manuals/all-products/esuprt_solutions_int/esuprt_solutions_int_solutions_resources/general-solution-resources_white-papers2_en-us.pdf + +Cc: Sean McGinnis +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +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 4e8b52ff..7fc5bc04 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -368,7 +368,8 @@ static struct hwentry default_hw[] = { + */ + .vendor = "COMPELNT", + .product = "Compellent Vol", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + .no_path_retry = NO_PATH_RETRY_QUEUE, + }, + { diff --git a/SOURCES/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/SOURCES/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch deleted file mode 100644 index 0ab20c5..0000000 --- a/SOURCES/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Mar 2021 13:05:10 -0500 -Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output - -Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using -the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match -that. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 18 ++---------------- - 1 file changed, 2 insertions(+), 16 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ec99a7aa..2704270e 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1135,12 +1135,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - naa_prio = 7; - break; - case 2: -- /* IEEE Extended: Prio 6 */ -- naa_prio = 6; -- break; - case 3: -- /* IEEE Locally assigned: Prio 1 */ -- naa_prio = 1; -+ /* IEEE Extended or Locally assigned: Prio 6 */ -+ naa_prio = 6; - break; - default: - /* Default: no priority */ -@@ -1159,17 +1156,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - vpd = d; - } - break; -- case 0x8: -- /* SCSI Name: Prio 3 */ -- if (memcmp(d + 4, "eui.", 4) && -- memcmp(d + 4, "naa.", 4) && -- memcmp(d + 4, "iqn.", 4)) -- break; -- if (prio < 3) { -- prio = 3; -- vpd = d; -- } -- break; - case 0x1: - /* T-10 Vendor ID: Prio 2 */ - if (prio < 2) { diff --git a/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch b/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch new file mode 100644 index 0000000..f8e9cc0 --- /dev/null +++ b/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:39:17 +0200 +Subject: [PATCH] multipath-tools: remove Compellent maintainer + +e-mail was bounced: 550 5.1.1 User Unknown + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7fc5bc04..763982cd 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -361,11 +361,7 @@ static struct hwentry default_hw[] = { + .pgpolicy = MULTIBUS, + }, + { +- /* +- * SC Series, formerly Compellent +- * +- * Maintainer: Sean McGinnis +- */ ++ /* SC Series, formerly Compellent */ + .vendor = "COMPELNT", + .product = "Compellent Vol", + .pgpolicy = GROUP_BY_PRIO, diff --git a/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch b/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch new file mode 100644 index 0000000..1912f80 --- /dev/null +++ b/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:44:54 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/Invista config work with + alua and multibus" + +This reverts commit 309ff281aaa07e862540d3d645a8263f3e9baaed. + +Mail from , 20210930: + +"OPM is no longer supported in the Dell VPLEX product. If we at Dell had +wished to change the default device stanzas for any of our products they +would have been done when the product and/or feature is released. +Please remove this patch as well. It is not needed." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 763982cd..211087ad 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,9 +350,8 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 5, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/SOURCES/0011-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch b/SOURCES/0011-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch deleted file mode 100644 index 24c9043..0000000 --- a/SOURCES/0011-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 May 2021 11:15:47 -0500 -Subject: [PATCH] multipathd: don't fail to remove path once the map is removed - -In ev_remove_path(), if update_mpp_paths() fails, we delete the entire -map. However, since update_mpp_paths() happens before we call -set_path_removed(), pp->initialized isn't set to INIT_REMOVED, so -remove_map_and_stop_waiter() doesn't remove the path when in removes the -map. But with the map removed, there's nothing to keep us from removing -the path. - -Call set_path_removed() before update_mpp_paths() to avoid the odd case -of ev_remove_path() removing the map but not the path. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 4 ++-- - multipathd/main.c | 13 ++++++++----- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index d242c06b..75390198 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -45,8 +45,8 @@ int update_mpp_paths(struct multipath *mpp, vector pathvec) - - /* - * Avoid adding removed paths to the map again -- * when we reload it. Such paths may exist if -- * domap fails in ev_remove_path(). -+ * when we reload it. Such paths may exist in -+ * ev_remove_paths() or if it returns failure. - */ - pp1 = find_path_by_devt(pathvec, pp->dev_t); - if (pp1 && pp->initialized != INIT_REMOVED && -diff --git a/multipathd/main.c b/multipathd/main.c -index 102946bf..449ce384 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1199,6 +1199,13 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - * avoid referring to the map of an orphaned path - */ - if ((mpp = pp->mpp)) { -+ /* -+ * Mark the path as removed. In case of success, we -+ * will delete it for good. Otherwise, it will be deleted -+ * later, unless all attempts to reload this map fail. -+ */ -+ set_path_removed(pp); -+ - /* - * transform the mp->pg vector of vectors of paths - * into a mp->params string to feed the device-mapper -@@ -1210,13 +1217,9 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - } - - /* -- * Mark the path as removed. In case of success, we -- * will delete it for good. Otherwise, it will be deleted -- * later, unless all attempts to reload this map fail. -- * Note: we have to explicitly remove pp from mpp->paths, -+ * we have to explicitly remove pp from mpp->paths, - * update_mpp_paths() doesn't do that. - */ -- set_path_removed(pp); - i = find_slot(mpp->paths, pp); - if (i != -1) - vector_del_slot(mpp->paths, i); diff --git a/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch b/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch new file mode 100644 index 0000000..b889ea8 --- /dev/null +++ b/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:46:09 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/SYMMETRIX config work with + alua and multibus" + +This reverts commit 831af0dbfa171cd39d968ba6174669f11a278be9. + +Mail from "berthiaume, wayne" , 210930: + +"As a representative of Dell I request this patch be withdrawn. If we had +wanted the default stanza changed we would have already implemented it. +Also for your information we only advertise the entire enterprise storage +product line (DMX, VMAX, VMAX AFA, PowerMax) as SYMMETRIX in the VPD page. +The ALUA capability is only used for mobility devices in an SRDF/Metro +configuration and the current device stanza still works well in all of our +testing." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 211087ad..a8ba28e3 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,9 +329,8 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 6, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/SOURCES/0012-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch b/SOURCES/0012-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch deleted file mode 100644 index 38b1d2b..0000000 --- a/SOURCES/0012-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 May 2021 11:55:14 -0500 -Subject: [PATCH] multipathd: remove duplicate orphan_paths in flush_map - -remove_map_and_stop_waiter() already calls orphan_paths() so flush_map() -doesn't need to call orphan_paths() before calling -remove_map_and_stop_waiter(). - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 449ce384..6090434c 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -660,7 +660,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - else - condlog(2, "%s: map flushed", mpp->alias); - -- orphan_paths(vecs->pathvec, mpp, "map flushed"); - remove_map_and_stop_waiter(mpp, vecs); - - return 0; diff --git a/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..df4455e --- /dev/null +++ b/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,63 @@ +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 d0ec9b44..2a75dc9c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -55,7 +55,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 d7527d7d..0e0d70d5 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -36,6 +36,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 0828a8f7..b9bbb3cf 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/SOURCES/0013-multipathd-fix-ev_remove_path-return-code-handling.patch b/SOURCES/0013-multipathd-fix-ev_remove_path-return-code-handling.patch deleted file mode 100644 index c9e5333..0000000 --- a/SOURCES/0013-multipathd-fix-ev_remove_path-return-code-handling.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 May 2021 13:58:57 -0500 -Subject: [PATCH] multipathd: fix ev_remove_path return code handling - -When ev_remove_path() returned success, callers assumed that the path -(and possibly the map) had been removed. When ev_remove_path() returned -failure, callers assumed that the path had not been removed. However, -the path could be removed on both success or failure. This could cause -callers to dereference the path after it was removed. - -To deal with this, make ev_remove_path() return a different symbolic -value for each outcome, and make the callers react appropriately for -the different values. Found by coverity. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 24 +++++++++++++++++++++-- - multipathd/main.c | 41 ++++++++++++++++++++------------------- - multipathd/main.h | 14 +++++++++++++ - 3 files changed, 57 insertions(+), 22 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 1de6ad8e..6765fcf0 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -752,7 +752,8 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - /* Have the checker reinstate this path asap */ - pp->tick = 1; - return 0; -- } else if (!ev_remove_path(pp, vecs, true)) -+ } else if (ev_remove_path(pp, vecs, true) & -+ REMOVE_PATH_SUCCESS) - /* Path removed in ev_remove_path() */ - pp = NULL; - else { -@@ -813,6 +814,7 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, PATH); - struct path *pp; -+ int ret; - - param = convert_dev(param, 1); - condlog(2, "%s: remove path (operator)", param); -@@ -821,7 +823,25 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - condlog(0, "%s: path already removed", param); - return 1; - } -- return ev_remove_path(pp, vecs, 1); -+ ret = ev_remove_path(pp, vecs, 1); -+ if (ret == REMOVE_PATH_DELAY) { -+ *reply = strdup("delayed\n"); -+ if (*reply) -+ *len = strlen(*reply) + 1; -+ else { -+ *len = 0; -+ ret = REMOVE_PATH_FAILURE; -+ } -+ } else if (ret == REMOVE_PATH_MAP_ERROR) { -+ *reply = strdup("map reload error. removed\n"); -+ if (*reply) -+ *len = strlen(*reply) + 1; -+ else { -+ *len = 0; -+ ret = REMOVE_PATH_FAILURE; -+ } -+ } -+ return (ret == REMOVE_PATH_FAILURE); - } - - int -diff --git a/multipathd/main.c b/multipathd/main.c -index 6090434c..8e2beddd 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -838,7 +838,7 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - return; - - udd = udev_device_ref(pp->udev); -- if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { -+ if (!(ev_remove_path(pp, vecs, 1) & REMOVE_PATH_SUCCESS) && pp->mpp) { - pp->dmstate = PSTATE_FAILED; - dm_fail_path(pp->mpp->alias, pp->dev_t); - } -@@ -948,8 +948,8 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - * Make another attempt to remove the path - */ - pp->mpp = prev_mpp; -- ret = ev_remove_path(pp, vecs, true); -- if (ret != 0) { -+ if (!(ev_remove_path(pp, vecs, true) & -+ REMOVE_PATH_SUCCESS)) { - /* - * Failure in ev_remove_path will keep - * path in pathvec in INIT_REMOVED state -@@ -960,6 +960,7 @@ uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - dm_fail_path(pp->mpp->alias, pp->dev_t); - condlog(1, "%s: failed to re-add path still mapped in %s", - pp->dev, pp->mpp->alias); -+ ret = 1; - } else if (r == PATHINFO_OK) - /* - * Path successfully freed, move on to -@@ -1167,7 +1168,6 @@ static int - uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - { - struct path *pp; -- int ret; - - condlog(3, "%s: remove path (uevent)", uev->kernel); - delete_foreign(uev->udev); -@@ -1177,21 +1177,18 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - pthread_testcancel(); - pp = find_path_by_dev(vecs->pathvec, uev->kernel); - if (pp) -- ret = ev_remove_path(pp, vecs, need_do_map); -+ ev_remove_path(pp, vecs, need_do_map); - lock_cleanup_pop(vecs->lock); -- if (!pp) { -- /* Not an error; path might have been purged earlier */ -+ if (!pp) /* Not an error; path might have been purged earlier */ - condlog(0, "%s: path already removed", uev->kernel); -- return 0; -- } -- return ret; -+ return 0; - } - - int - ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - { - struct multipath * mpp; -- int i, retval = 0; -+ int i, retval = REMOVE_PATH_SUCCESS; - char params[PARAMS_SIZE] = {0}; - - /* -@@ -1245,7 +1242,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - condlog(2, "%s: removed map after" - " removing all paths", - alias); -- retval = 0; - /* flush_map() has freed the path */ - goto out; - } -@@ -1262,11 +1258,14 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - - if (mpp->wait_for_udev) { - mpp->wait_for_udev = 2; -+ retval = REMOVE_PATH_DELAY; - goto out; - } - -- if (!need_do_map) -+ if (!need_do_map) { -+ retval = REMOVE_PATH_DELAY; - goto out; -+ } - /* - * reload the map - */ -@@ -1275,7 +1274,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - condlog(0, "%s: failed in domap for " - "removal of path %s", - mpp->alias, pp->dev); -- retval = 1; -+ retval = REMOVE_PATH_FAILURE; - } else { - /* - * update our state from kernel -@@ -1283,12 +1282,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - char devt[BLK_DEV_SIZE]; - - strlcpy(devt, pp->dev_t, sizeof(devt)); -+ -+ /* setup_multipath will free the path -+ * regardless of whether it succeeds or -+ * fails */ - if (setup_multipath(vecs, mpp)) -- return 1; -- /* -- * Successful map reload without this path: -- * sync_map_state() will free it. -- */ -+ return REMOVE_PATH_MAP_ERROR; - sync_map_state(mpp); - - condlog(2, "%s: path removed from map %s", -@@ -1304,8 +1303,10 @@ out: - return retval; - - fail: -+ condlog(0, "%s: error removing path. removing map %s", pp->dev, -+ mpp->alias); - remove_map_and_stop_waiter(mpp, vecs); -- return 1; -+ return REMOVE_PATH_MAP_ERROR; - } - - static int -diff --git a/multipathd/main.h b/multipathd/main.h -index ddd953f9..bc1f938f 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -13,6 +13,20 @@ enum daemon_status { - DAEMON_STATUS_SIZE, - }; - -+enum remove_path_result { -+ REMOVE_PATH_FAILURE = 0x0, /* path could not be removed. It is still -+ * part of the kernel map, but its state -+ * is set to INIT_REMOVED, and it will be -+ * removed at the next possible occassion */ -+ REMOVE_PATH_SUCCESS = 0x1, /* path was removed */ -+ REMOVE_PATH_DELAY = 0x2, /* path is set to be removed later. it -+ * currently still exists and is part of the -+ * kernel map */ -+ REMOVE_PATH_MAP_ERROR = 0x5, /* map was removed because of error. value -+ * includes REMOVE_PATH_SUCCESS bit -+ * because the path was also removed */ -+}; -+ - struct prout_param_descriptor; - struct prin_resp; - diff --git a/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch new file mode 100644 index 0000000..c1cdc10 --- /dev/null +++ b/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -0,0 +1,101 @@ +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 | 6 ++---- + multipath/multipath.conf.5 | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index 4e315c97..1e463ef6 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -202,9 +202,6 @@ setup_default_blist (struct config * conf) + if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) + return 1; + +- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) +- return 1; +- + vector_foreach_slot (conf->hwtable, hwe, i) { + if (hwe->bl_product) { + if (find_blacklist_device(conf->blist_device, +@@ -410,7 +407,8 @@ filter_property(const struct config *conf, struct udev_device *udev, + *uid_attribute != '\0'; + bool uid_attr_seen = false; + +- r = MATCH_PROPERTY_BLIST_MISSING; ++ if (VECTOR_SIZE(conf->elist_property)) ++ r = MATCH_PROPERTY_BLIST_MISSING; + udev_list_entry_foreach(list_entry, + udev_device_get_properties_list_entry(udev)) { + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index c74129bd..dd9f4dc7 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1351,9 +1351,14 @@ keywords. Both are regular expressions. For a full description of these keywords + Regular expression for an udev property. All + devices that have matching udev properties will be excluded/included. + The handling of the \fIproperty\fR keyword is special, +-because devices \fBmust\fR have at least one whitelisted udev property; ++because if a property blacklist_exception is set, devices \fBmust\fR have at ++least one whitelisted udev property; + otherwise they're treated as blacklisted, and the message + "\fIblacklisted, udev property missing\fR" is displayed in the logs. ++For example, setting the property blacklist_exception to ++\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices ++that provide a WWN (World Wide Number) to be included, and all others to be ++excluded. This works to exclude most non-multipathable devices. + . + .RS + .PP +@@ -1364,10 +1369,6 @@ Blacklisting by missing properties is only applied to devices which do have the + property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) + set. Previously, it was applied to every device, possibly causing devices to be + blacklisted because of temporary I/O error conditions. +-.PP +-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing +-well-behaved SCSI devices and devices that provide a WWN (World Wide Number) +-to be included, and all others to be excluded. + .RE + .TP + .B protocol +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 882aa3a1..6a22b660 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -375,9 +375,8 @@ static void test_property_missing(void **state) + { + static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; + conf.blist_property = blist_property_wwn; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), +- MATCH_PROPERTY_BLIST_MISSING); ++ MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), + MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, ""), +@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) + conf.blist_device = blist_device_foo_bar; + conf.blist_protocol = blist_protocol_fcp; + conf.blist_wwid = blist_wwid_xyzzy; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); +- assert_int_equal(filter_path(&conf, &miss1_pp), +- MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING); + } + + /* This one matches the property whitelist, to test the other missing diff --git a/SOURCES/0014-multipath-free-vectors-in-configure.patch b/SOURCES/0014-multipath-free-vectors-in-configure.patch deleted file mode 100644 index eeb09d7..0000000 --- a/SOURCES/0014-multipath-free-vectors-in-configure.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 May 2021 15:25:21 -0500 -Subject: [PATCH] multipath: free vectors in configure - -configure() can retry multiple times, each time reallocing a maps and -paths vector, and leaking the previous ones. Fix this by always freeing -the vectors before configure() exits. Found by coverity. - -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index f618550d..9fe53dcd 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -512,7 +512,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - */ - curmp = vector_alloc(); - pathvec = vector_alloc(); -- atexit(cleanup_vecs); - - if (!curmp || !pathvec) { - condlog(0, "can not allocate memory"); -@@ -624,6 +623,11 @@ out: - if (refwwid) - FREE(refwwid); - -+ free_multipathvec(curmp, KEEP_PATHS); -+ vecs.mpvec = NULL; -+ free_pathvec(pathvec, FREE_PATHS); -+ vecs.pathvec = NULL; -+ - return r; - } - -@@ -869,6 +873,7 @@ main (int argc, char *argv[]) - conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; -+ atexit(cleanup_vecs); - while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); diff --git a/SOURCES/0015-RH-don-t-start-without-a-config-file.patch b/SOURCES/0015-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..8061a99 --- /dev/null +++ b/SOURCES/0015-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,107 @@ +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 | 13 +++++++++++++ + libmultipath/config.h | 1 + + multipath/multipath.rules | 1 + + multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.service | 1 + + multipathd/multipathd.socket | 1 + + 6 files changed, 19 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 30046a17..5f35c3d3 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf) + goto out; + } + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); ++ } else { ++ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ 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, ".*", 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 933fe0d1..5f01c1fc 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 + + enum devtypes { + DEV_NONE, +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index 9df11a95..0486bf70 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -9,6 +9,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 048a838d..8bd47a80 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 0b2ac814..6d57c7e8 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-activation-early.service + Before=local-fs-pre.target blk-availability.service shutdown.target + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + ConditionKernelCommandLine=!nompath +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index c777e5e3..3c20a2ff 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,7 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionPathExists=/etc/multipath.conf + ConditionKernelCommandLine=!nompath + ConditionKernelCommandLine=!multipath=off + ConditionVirtualization=!container diff --git a/SOURCES/0015-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch b/SOURCES/0015-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch deleted file mode 100644 index 75004cc..0000000 --- a/SOURCES/0015-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 11 May 2021 16:03:13 -0500 -Subject: [PATCH] kpartx: Don't leak memory when getblock returns NULL - -If a new block was allocated, but couldn't be filled, getblock will -discard it. When it does so, it needs to free the block to avoid leaking -memory. Found by coverity. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 8ff116b8..7bc64543 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -766,6 +766,8 @@ getblock (int fd, unsigned int blknr) { - if (read(fd, bp->block, secsz) != secsz) { - fprintf(stderr, "read error, sector %d\n", secnr); - blockhead = bp->next; -+ free(bp->block); -+ free(bp); - return NULL; - } - diff --git a/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch b/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch new file mode 100644 index 0000000..ced7159 --- /dev/null +++ b/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Jan 2019 14:54:56 -0600 +Subject: [PATCH] RH: Fix nvme function missing argument + +A future patch will change the compilation options to error when +function declarations have unspecified arguments. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/nvme/argconfig.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h +index adb192b6..bfd10ef8 100644 +--- a/libmultipath/nvme/argconfig.h ++++ b/libmultipath/nvme/argconfig.h +@@ -76,7 +76,7 @@ struct argconfig_commandline_options { + extern "C" { + #endif + +-typedef void argconfig_help_func(); ++typedef void argconfig_help_func(void); + void argconfig_append_usage(const char *str); + void argconfig_print_help(const char *program_desc, + const struct argconfig_commandline_options *options); diff --git a/SOURCES/0016-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch b/SOURCES/0016-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch deleted file mode 100644 index 6c68ea3..0000000 --- a/SOURCES/0016-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 14 May 2021 13:45:28 -0500 -Subject: [PATCH] multipathd: don't rescan_path on wwid change in - uev_update_path - -If get_uid() is returning a different wwid in uev_update_path(), then -the uid_attribute must have already gotten updated, which was the -purpose behind calling rescan_path() in the first place. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 8e2beddd..2750f5e9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1359,7 +1359,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - condlog(0, "%s: path wwid changed from '%s' to '%s'", - uev->kernel, wwid, pp->wwid); - ev_remove_path(pp, vecs, 1); -- rescan_path(uev->udev); - needs_reinit = 1; - goto out; - } else { diff --git a/SOURCES/0017-RH-mpathconf-correctly-handle-spaces-after-option-na.patch b/SOURCES/0017-RH-mpathconf-correctly-handle-spaces-after-option-na.patch deleted file mode 100644 index ca81cc5..0000000 --- a/SOURCES/0017-RH-mpathconf-correctly-handle-spaces-after-option-na.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 9 Jul 2021 14:30:10 -0500 -Subject: [PATCH] RH: mpathconf: correctly handle spaces after option names - -mpathconf was either accepting any number of spaces, including zero, -after option names, or it was only accepting one space. It should -accept one or more spaces. Also, fix enable_foreign handling. It was -still working like it did in RHEL8, where the default was to enable -all foreign devices. - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 62 +++++++++++++++++++++++++-------------------- - 1 file changed, 34 insertions(+), 28 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index 2f4f3eaf..039b3e47 100644 ---- a/multipath/mpathconf -+++ b/multipath/mpathconf -@@ -240,7 +240,7 @@ function validate_args - echo "--enable_foreign must be either 'y' or 'n'" - exit 1 - fi -- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then - SHOW_STATUS=1 - fi - if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then -@@ -315,46 +315,50 @@ if [ "$MULTIPATHD" = "y" ]; then - fi - - if [ "$HAVE_BLACKLIST" = "1" ]; then -- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then -+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then - HAVE_DISABLE=1 -- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then -+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then - HAVE_DISABLE=0 - fi - fi - - if [ "$HAVE_BLACKLIST" = "1" ]; then -- if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then -+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then - HAVE_WWID_DISABLE=1 -- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then -+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then - HAVE_WWID_DISABLE=0 - fi - fi - - if [ "$HAVE_DEFAULTS" = "1" ]; then -- HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` -+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` - if [ "$HAVE_FIND" = "1" ]; then - HAVE_FIND="yes" - elif [ "$HAVE_FIND" = "0" ]; then - HAVE_FIND="no" - fi -- if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then - HAVE_FRIENDLY=1 -- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then - HAVE_FRIENDLY=0 - fi - if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then - HAVE_FOREIGN=0 -- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then - HAVE_FOREIGN=1 -- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then -+ HAVE_FOREIGN=2 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then - HAVE_FOREIGN=2 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then -+ HAVE_FOREIGN=3 - fi - fi - - if [ "$HAVE_EXCEPTIONS" = "1" ]; then -- if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then -+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then - HAVE_PROPERTY=1 -- elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then -+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then - HAVE_PROPERTY=0 - fi - fi -@@ -381,8 +385,10 @@ if [ -n "$SHOW_STATUS" ]; then - echo "default property blacklist is enabled" - fi - if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then -- echo "enable_foreign is not set (all foreign multipath devices will be shown)" -+ echo "enable_foreign is not set (no foreign multipath devices will be shown)" - elif [ "$HAVE_FOREIGN" = 1 ]; then -+ echo "enable_foreign is set (all foreign multipath devices will be shown)" -+ elif [ "$HAVE_FOREIGN" = 2 ]; then - echo "enable_foreign is set (no foreign multipath devices will be shown)" - else - echo "enable_foreign is set (foreign multipath devices may not be shown)" -@@ -427,14 +433,14 @@ fi - - if [ "$ENABLE" = 2 ]; then - if [ "$HAVE_DISABLE" = 1 ]; then -- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# 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 -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE - fi - if [ "$HAVE_EXCEPTIONS" = 1 ]; then - sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE -@@ -448,7 +454,7 @@ _EOF_ - add_blacklist_exceptions - elif [ "$ENABLE" = 1 ]; then - if [ "$HAVE_DISABLE" = 1 ]; then -- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE - fi - elif [ "$ENABLE" = 0 ]; then - if [ -z "$HAVE_DISABLE" ]; then -@@ -456,7 +462,7 @@ elif [ "$ENABLE" = 0 ]; then - devnode ".*" - ' $TMPFILE - elif [ "$HAVE_DISABLE" = 0 ]; then -- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE -+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE - fi - fi - -@@ -467,14 +473,14 @@ if [ -n "$FIND" ]; then - ' $TMPFILE - CHANGED_CONFIG=1 - elif [ "$FIND" != "$HAVE_FIND" ]; then -- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $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 -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE - CHANGED_CONFIG=1 - fi - elif [ "$FRIENDLY" = "y" ]; then -@@ -484,14 +490,14 @@ elif [ "$FRIENDLY" = "y" ]; then - ' $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 -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE - CHANGED_CONFIG=1 - fi - fi - - if [ "$PROPERTY" = "n" ]; then - if [ "$HAVE_PROPERTY" = 1 ]; then -- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE - CHANGED_CONFIG=1 - fi - elif [ "$PROPERTY" = "y" ]; then -@@ -501,24 +507,24 @@ elif [ "$PROPERTY" = "y" ]; then - ' $TMPFILE - CHANGED_CONFIG=1 - elif [ "$HAVE_PROPERTY" = 0 ]; then -- sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE -+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE - CHANGED_CONFIG=1 - fi - fi - --if [ "$FOREIGN" = "y" ]; then -- if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then -+if [ "$FOREIGN" = "n" ]; then -+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then - sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE - CHANGED_CONFIG=1 - fi --elif [ "$FOREIGN" = "n" ]; then -+elif [ "$FOREIGN" = "y" ]; then - if [ -z "$HAVE_FOREIGN" ]; then - sed -i '/^defaults[[:space:]]*{/ a\ -- enable_foreign "^$" -+ enable_foreign ".*" - ' $TMPFILE - CHANGED_CONFIG=1 -- elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then -- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE - CHANGED_CONFIG=1 - fi - fi diff --git a/SOURCES/0017-RH-use-rpm-optflags-if-present.patch b/SOURCES/0017-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..a1c081c --- /dev/null +++ b/SOURCES/0017-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,66 @@ +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 | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 2a75dc9c..5ac660de 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -92,23 +92,35 @@ TEST_CC_OPTION = $(shell \ + echo "$(2)"; \ + fi) + +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) + +-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ ++ifndef RPM_OPT_FLAGS ++ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ++ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ $(STACKPROT) -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ++ endif ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ++ endif ++else ++ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 ++endif ++WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ ++ -Wstrict-prototypes + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs ++LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. +@@ -139,4 +151,4 @@ check_file = $(shell \ + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) -c -o $@ $< diff --git a/SOURCES/0018-RH-add-mpathconf.patch b/SOURCES/0018-RH-add-mpathconf.patch new file mode 100644 index 0000000..f7bbecb --- /dev/null +++ b/SOURCES/0018-RH-add-mpathconf.patch @@ -0,0 +1,772 @@ +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 | 2 + + multipath/Makefile | 5 + + multipath/mpathconf | 556 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 135 ++++++++++ + 4 files changed, 698 insertions(+) + create mode 100644 multipath/mpathconf + create mode 100644 multipath/mpathconf.8 + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 5f35c3d3..cee3bbb7 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf) + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + } else { + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); ++ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details"); + if (conf->blist_devnode == NULL) { + conf->blist_devnode = vector_alloc(); + if (!conf->blist_devnode) { +diff --git a/multipath/Makefile b/multipath/Makefile +index b9bbb3cf..e720c7f6 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + $(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: dep_clean + $(RM) core *.o $(EXEC) *.gz +diff --git a/multipath/mpathconf b/multipath/mpathconf +new file mode 100644 +index 00000000..c00d2555 +--- /dev/null ++++ b/multipath/mpathconf +@@ -0,0 +1,556 @@ ++#!/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 PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN 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 ++}" ++ ++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 "Set default property blacklist (Default n): --property_blacklist " ++ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ 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 ++ ;; ++ --property_blacklist) ++ if [ -n "$2" ]; then ++ PROPERTY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --enable_foreign) ++ if [ -n "$2" ]; then ++ FOREIGN=$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 "$PROPERTY" -o -n "$MODULE" ]; then ++ echo "ignoring extra parameters on disable" ++ FRIENDLY="" ++ FIND="" ++ PROPERTY="" ++ 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 [ "$FIND" = "y" ]; then ++ FIND="yes" ++ elif [ "$FIND" = "n" ]; then ++ FIND="no" ++ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" ++ exit 1 ++ fi ++ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then ++ echo "--property_blacklist must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then ++ echo "--enable_foreign must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; 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[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_DISABLE=0 ++ fi ++fi ++ ++if [ "$HAVE_BLACKLIST" = "1" ]; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=0 ++ fi ++fi ++ ++if [ "$HAVE_DEFAULTS" = "1" ]; then ++ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` ++ if [ "$HAVE_FIND" = "1" ]; then ++ HAVE_FIND="yes" ++ elif [ "$HAVE_FIND" = "0" ]; then ++ HAVE_FIND="no" ++ fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then ++ HAVE_FRIENDLY=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then ++ HAVE_FRIENDLY=0 ++ fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=0 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=3 ++ fi ++fi ++ ++if [ "$HAVE_EXCEPTIONS" = "1" ]; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=1 ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=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" ]; then ++ echo "find_multipaths is no" ++ else ++ echo "find_multipaths is $HAVE_FIND" ++ 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 [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then ++ echo "default property blacklist is disabled" ++ else ++ echo "default property blacklist is enabled" ++ fi ++ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then ++ echo "enable_foreign is not set (no foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ else ++ echo "enable_foreign is set (foreign multipath devices may not be shown)" ++ 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[[:space:]][[:space:]]*\"\.\?\*\"/# 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[[:space:]][[:space:]]*\"\.\?\*\"/ 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[[:space:]][[:space:]]*\"\.\?\*\"/# 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[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE ++ fi ++fi ++ ++if [ -n "$FIND" ]; then ++ if [ -z "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ find_multipaths '"$FIND"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$FIND" != "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $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:]][[: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:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$PROPERTY" = "n" ]; then ++ if [ "$HAVE_PROPERTY" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$PROPERTY" = "y" ]; then ++ if [ -z "$HAVE_PROPERTY" ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ property "(SCSI_IDENT_|ID_WWN)" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_PROPERTY" = 0 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FOREIGN" = "n" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "y" ]; then ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign ".*" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $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 00000000..a14d831e +--- /dev/null ++++ b/multipath/mpathconf.8 +@@ -0,0 +1,135 @@ ++.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, but ++will not create of modify ++.B /etc/multipath.conf ++ ++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 ++set and ++.B find_multipaths ++set to \fByes\fP. 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. Also, creates ++.B /etc/multipath.conf ++if it doesn't exist. ++.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 --allow \fB\fP ++Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all ++wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\fP ++can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper ++device, either a multipath device, or any device on stacked on top of one or ++more multipath devices. This command can be used multiple times to allow ++multiple devices. \fBNOTE:\fP This action will create a configuration file that ++mpathconf will not be able to revert back to its previous state. Because ++of this, \fB--outfile\fP is required when using \fB--allow\fP. ++.TP ++.B --user_friendly_names \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 { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++If set to \fB\fP, this adds the line ++.B find_multipaths ++to the ++.B /etc/multipath.conf ++defaults section. This command can be used along with any other command. ++\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. ++.TP ++.B --property_blacklist \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B property "(SCSI_IDENT_|ID_WWN)" ++to the ++.B /etc/multipath.conf ++blacklist_exceptions section. If set to \fBn\fP, this removes the line, if ++present. This command can be used along with any other command. ++.TP ++.B --enable_foreign\fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B enable_foreign ".*" ++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 --outfile \fB\fP ++Write the resulting multipath configuration to \fB\fP instead of ++\fB/etc/multipath.conf\fP. ++.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 diff --git a/SOURCES/0018-multipath.conf-fix-typo-in-ghost_delay-description.patch b/SOURCES/0018-multipath.conf-fix-typo-in-ghost_delay-description.patch deleted file mode 100644 index 4ee62d9..0000000 --- a/SOURCES/0018-multipath.conf-fix-typo-in-ghost_delay-description.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 15 Jul 2021 14:46:49 -0500 -Subject: [PATCH] multipath.conf: fix typo in ghost_delay description - -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 0d2bce09..689d09aa 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1251,7 +1251,7 @@ The default is: in \fB/sys/block//queue/max_sectors_kb\fR - 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 -+to switch the ghost paths to active ones. Setting this to \fI0\fR or \fIno\fR - makes multipath immediately mark a device with only ghost paths as ready. - .RS - .TP diff --git a/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch new file mode 100644 index 0000000..055eeb6 --- /dev/null +++ b/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -0,0 +1,151 @@ +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 +--- + multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- + multipath/multipath.8 | 7 ++++- + multipathd/multipathd.service | 1 + + 3 files changed, 59 insertions(+), 3 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 65ece830..748e7902 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -122,7 +122,7 @@ usage (char * progname) + fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); + fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); + fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); +- fprintf (stderr, " %s [-v level] -W\n", progname); ++ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); + fprintf (stderr, " %s [-h|-t|-T]\n", progname); +@@ -136,6 +136,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" +@@ -450,6 +452,50 @@ static void cleanup_vecs(void) + free_pathvec(vecs.pathvec, FREE_PATHS); + } + ++static 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; ++} ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) +@@ -838,7 +884,7 @@ main (int argc, char *argv[]) + conf->retrigger_tries = 0; + conf->force_sync = 1; + atexit(cleanup_vecs); +- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -915,6 +961,10 @@ main (int argc, char *argv[]) + case 'T': + cmd = CMD_DUMP_CONFIG; + break; ++ case 'A': ++ if (remember_cmdline_wwid() != 0) ++ exit(RTVL_FAIL); ++ exit(RTVL_OK); + case 'h': + usage(argv[0]); + exit(RTVL_OK); +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 17df59f5..5ca75359 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. + .B multipath + .RB [\| \-v\ \c + .IR level \|] +-.B -W ++.RB [\| \-A | \-W \|] + . + .LP + .B multipath +@@ -145,6 +145,11 @@ device mapper, path checkers ...). + Add the WWID for the specified device to the WWIDs file. + . + .TP ++.B \-A ++Add the WWIDs from any kernel command line \fImpath.wwid\fR 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 6d57c7e8..dfc1e962 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -16,6 +16,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 + TasksMax=infinity diff --git a/SOURCES/0019-mpathpersist-fail-commands-when-no-usable-paths-exis.patch b/SOURCES/0019-mpathpersist-fail-commands-when-no-usable-paths-exis.patch deleted file mode 100644 index 32f4f60..0000000 --- a/SOURCES/0019-mpathpersist-fail-commands-when-no-usable-paths-exis.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 15 Jul 2021 17:09:05 -0500 -Subject: [PATCH] mpathpersist: fail commands when no usable paths exist - -"mpathpersist -oCK " will return success if it -is run on devices with no usable paths, but nothing is actually done. -The -L command will fail, but it should give up sooner, and with a more -helpful error message. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 190e9707..26710e79 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -604,7 +604,8 @@ int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, - return ret ; - } - } -- return MPATH_PR_SUCCESS; -+ condlog (0, "%s: no path available", mpp->wwid); -+ return MPATH_PR_DMMP_ERROR; - } - - int send_prout_activepath(char * dev, int rq_servact, int rq_scope, -@@ -663,6 +664,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - - active_pathcount = count_active_paths(mpp); - -+ if (active_pathcount == 0) { -+ condlog (0, "%s: no path available", mpp->wwid); -+ return MPATH_PR_DMMP_ERROR; -+ } -+ - struct threadinfo thread[active_pathcount]; - memset(thread, 0, sizeof(thread)); - for (i = 0; i < active_pathcount; i++){ diff --git a/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch new file mode 100644 index 0000000..d5b5601 --- /dev/null +++ b/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 7 Jun 2018 17:43:52 -0500 +Subject: [PATCH] RH: reset default find_mutipaths value to off + +Upstream has changed to default find_multipaths to "strict". For now +Redhat will retain the previous default of "off". + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index c27946c7..e0dd32ad 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -23,7 +23,7 @@ + #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF + #define DEFAULT_VERBOSITY 2 + #define DEFAULT_REASSIGN_MAPS 0 +-#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT ++#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF + #define DEFAULT_FAST_IO_FAIL 5 + #define DEFAULT_DEV_LOSS_TMO 600 + #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/SOURCES/0020-multipath-print-warning-if-multipathd-is-not-running.patch b/SOURCES/0020-multipath-print-warning-if-multipathd-is-not-running.patch deleted file mode 100644 index 9321b28..0000000 --- a/SOURCES/0020-multipath-print-warning-if-multipathd-is-not-running.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 16 Jul 2021 12:39:17 -0500 -Subject: [PATCH] multipath: print warning if multipathd is not running. - -If multipath notices that multipath devices exist or were created, and -multipathd is not running, it now prints a warning message, so users are -notified of the issue. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 13 +++++++++++-- - libmultipath/configure.h | 1 + - libmultipath/libmultipath.version | 5 +++++ - multipath/main.c | 5 +++++ - 4 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6ca1f4bb..9da85ce6 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1083,7 +1083,8 @@ deadmap (struct multipath * mpp) - return 1; /* dead */ - } - --int check_daemon(void) -+extern int -+check_daemon(void) - { - int fd; - char *reply; -@@ -1138,6 +1139,8 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - struct config *conf; - int allow_queueing; - struct bitfield *size_mismatch_seen; -+ bool map_processed = false; -+ bool no_daemon = false; - - /* ignore refwwid if it's empty */ - if (refwwid && !strlen(refwwid)) -@@ -1288,7 +1291,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - conf = get_multipath_config(); - allow_queueing = conf->allow_queueing; - put_multipath_config(conf); -- if (!is_daemon && !allow_queueing && !check_daemon()) { -+ if (!is_daemon && !allow_queueing && -+ (no_daemon || !check_daemon())) { -+ no_daemon = true; - if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && - mpp->no_path_retry != NO_PATH_RETRY_FAIL) - condlog(3, "%s: multipathd not running, unset " -@@ -1311,6 +1316,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - else - remove_map(mpp, vecs->pathvec, vecs->mpvec, - KEEP_VEC); -+ map_processed = true; - } - /* - * Flush maps with only dead paths (ie not in sysfs) -@@ -1336,6 +1342,9 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid, - condlog(2, "%s: remove (dead)", alias); - } - } -+ if (map_processed && !is_daemon && (no_daemon || !check_daemon())) -+ condlog(2, "multipath devices exist, but multipathd service is not running"); -+ - ret = CP_OK; - out: - free(size_mismatch_seen); -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 70cf77a3..741066b3 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -60,3 +60,4 @@ struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); - void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); - void trigger_partitions_udev_change(struct udev_device *dev, const char *action, - int len); -+int check_daemon(void); -diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version -index 0cff3111..d8be5fd2 100644 ---- a/libmultipath/libmultipath.version -+++ b/libmultipath/libmultipath.version -@@ -274,3 +274,8 @@ global: - local: - *; - }; -+ -+LIBMULTIPATH_5.1.0 { -+global: -+ check_daemon; -+} LIBMULTIPATH_5.0.0; -diff --git a/multipath/main.c b/multipath/main.c -index 9fe53dcd..85e4481d 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -182,6 +182,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - int i; - struct multipath * mpp; - int flags = (cmd == CMD_LIST_SHORT ? DI_NOIO : DI_ALL); -+ bool maps_present = false; - - if (dm_get_maps(curmp)) - return 1; -@@ -214,11 +215,15 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - - if (cmd == CMD_CREATE) - reinstate_paths(mpp); -+ -+ maps_present = true; - } - - if (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) - print_foreign_topology(libmp_verbosity); - -+ if (maps_present && !check_daemon()) -+ condlog(2, "multipath devices exist, but multipathd service is not running"); - return 0; - } - diff --git a/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch new file mode 100644 index 0000000..06233ff --- /dev/null +++ b/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Apr 2019 13:25:42 -0500 +Subject: [PATCH] RH: attempt to get ANA info via sysfs first + +When the ANA prioritizer is run, first see if the "ana_state" sysfs file +exists, and if it does, try to read the state from there. If that fails, +fallback to using an ioctl. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c +index b5c7873d..e139360c 100644 +--- a/libmultipath/prioritizers/ana.c ++++ b/libmultipath/prioritizers/ana.c +@@ -24,6 +24,7 @@ + #include "prio.h" + #include "util.h" + #include "structs.h" ++#include "sysfs.h" + + enum { + ANA_ERR_GETCTRL_FAILED = 1, +@@ -36,6 +37,7 @@ enum { + ANA_ERR_GETNS_FAILED, + ANA_ERR_NO_MEMORY, + ANA_ERR_NO_INFORMATION, ++ ANA_ERR_INVALID_STATE, + }; + + static const char *ana_errmsg[] = { +@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { + [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", + [ANA_ERR_NO_MEMORY] = "out of memory", + [ANA_ERR_NO_INFORMATION] = "invalid fd", ++ [ANA_ERR_INVALID_STATE] = "invalid state", + }; + + static const char *anas_string[] = { +@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, + return -ANA_ERR_GETANAS_NOTFOUND; + } + ++static int get_ana_info_sysfs(struct path *pp) ++{ ++ char state[32]; ++ ++ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state, ++ sizeof(state)) <= 0) ++ return -ANA_ERR_NO_INFORMATION; ++ ++ if (strcmp(state, "optimized") == 0) ++ return NVME_ANA_OPTIMIZED; ++ if (strcmp(state, "non-optimized") == 0) ++ return NVME_ANA_NONOPTIMIZED; ++ if (strcmp(state, "inaccessible") == 0) ++ return NVME_ANA_INACCESSIBLE; ++ if (strcmp(state, "persistent-loss") == 0) ++ return NVME_ANA_PERSISTENT_LOSS; ++ if (strcmp(state, "change") == 0) ++ return NVME_ANA_CHANGE; ++ return -ANA_ERR_INVALID_STATE; ++} ++ + static int get_ana_info(struct path * pp) + { + int rc; +@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, + + if (pp->fd < 0) + rc = -ANA_ERR_NO_INFORMATION; +- else +- rc = get_ana_info(pp); ++ else { ++ rc = get_ana_info_sysfs(pp); ++ if (rc < 0) ++ rc = get_ana_info(pp); ++ } + + switch (rc) { + case NVME_ANA_OPTIMIZED: diff --git a/SOURCES/0021-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch b/SOURCES/0021-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch deleted file mode 100644 index 11d8b4e..0000000 --- a/SOURCES/0021-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 29 Jul 2021 13:16:57 -0500 -Subject: [PATCH] libmultipath: deal with dynamic PTHREAD_STACK_MIN - -Starting in glibc-2.34 (commit 5d98a7da), PTHREAD_STACK_MIN is defined -as sysconf(_SC_THREAD_STACK_MIN) if _GNU_SOURCE is defined. sysconf() -returns a long and can, at least in theory, return -1. This change -causes compilation to fail in setup_thread_attr() due to a comparision -with different signedness, since stacksize is a size_t. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/util.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 0e37f3ff..17f8fcc6 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -223,8 +223,8 @@ setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached) - - ret = pthread_attr_init(attr); - assert(ret == 0); -- if (stacksize < PTHREAD_STACK_MIN) -- stacksize = PTHREAD_STACK_MIN; -+ if (PTHREAD_STACK_MIN > 0 && stacksize < (size_t)PTHREAD_STACK_MIN) -+ stacksize = (size_t)PTHREAD_STACK_MIN; - ret = pthread_attr_setstacksize(attr, stacksize); - assert(ret == 0); - if (detached) { diff --git a/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch new file mode 100644 index 0000000..1d10c09 --- /dev/null +++ b/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Mar 2021 13:05:10 -0500 +Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output + +Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using +the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match +that. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 18 ++---------------- + tests/vpd.c | 6 ++++++ + 2 files changed, 8 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f25fe9e3..6fb81c28 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1136,12 +1136,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + naa_prio = 7; + break; + case 2: +- /* IEEE Extended: Prio 6 */ +- naa_prio = 6; +- break; + case 3: +- /* IEEE Locally assigned: Prio 1 */ +- naa_prio = 1; ++ /* IEEE Extended or Locally assigned: Prio 6 */ ++ naa_prio = 6; + break; + default: + /* Default: no priority */ +@@ -1160,17 +1157,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + vpd = d; + } + break; +- case 0x8: +- /* SCSI Name: Prio 3 */ +- if (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4)) +- break; +- if (prio < 3) { +- prio = 3; +- vpd = d; +- } +- break; + case 0x1: + /* T-10 Vendor ID: Prio 2 */ + if (prio < 2) { +diff --git a/tests/vpd.c b/tests/vpd.c +index 8e730d37..7bf7990f 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -230,11 +230,13 @@ static const char * const str_prefix[] = { + [STR_IQN] = "iqn.", + }; + ++#if 0 + static const char byte0[] = { + [STR_EUI] = '2', + [STR_NAA] = '3', + [STR_IQN] = '8', + }; ++#endif + + /** + * create_scsi_string_desc() - create a SCSI name string descriptor. +@@ -659,6 +661,7 @@ make_test_vpd_naa(2, 18); + make_test_vpd_naa(2, 17); + make_test_vpd_naa(2, 16); + ++#if 0 + /* SCSI Name string: EUI64, WWID size: 17 */ + make_test_vpd_str(0, 20, 18) + make_test_vpd_str(0, 20, 17) +@@ -694,6 +697,7 @@ make_test_vpd_str(18, 20, 18) + make_test_vpd_str(18, 20, 17) + make_test_vpd_str(18, 20, 16) + make_test_vpd_str(18, 20, 15) ++#endif + + static int test_vpd(void) + { +@@ -767,6 +771,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_naa_2_18), + cmocka_unit_test(test_vpd_naa_2_17), + cmocka_unit_test(test_vpd_naa_2_16), ++/* + cmocka_unit_test(test_vpd_str_0_20_18), + cmocka_unit_test(test_vpd_str_0_20_17), + cmocka_unit_test(test_vpd_str_0_20_16), +@@ -791,6 +796,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_str_18_20_17), + cmocka_unit_test(test_vpd_str_18_20_16), + cmocka_unit_test(test_vpd_str_18_20_15), ++*/ + }; + return cmocka_run_group_tests(tests, setup, teardown); + } diff --git a/SOURCES/0022-multipathd-cli_handlers-cleanup-setting-reply-length.patch b/SOURCES/0022-multipathd-cli_handlers-cleanup-setting-reply-length.patch deleted file mode 100644 index 3099df6..0000000 --- a/SOURCES/0022-multipathd-cli_handlers-cleanup-setting-reply-length.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 17 May 2021 22:37:34 +0200 -Subject: [PATCH] multipathd: cli_handlers: cleanup setting reply length - -Create a macro for setting the reply length for string literals -correctly, and use it where necessary. - -In cli_del_path(), don't change the function's return code -if just the buffer allocation for the reply failed. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 33 ++++++++++++--------------------- - 1 file changed, 12 insertions(+), 21 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 6765fcf0..96064944 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -32,6 +32,12 @@ - #include "foreign.h" - #include "cli_handlers.h" - -+#define SET_REPLY_AND_LEN(__rep, __len, string_literal) \ -+ do { \ -+ *(__rep) = strdup(string_literal); \ -+ *(__len) = *(__rep) ? sizeof(string_literal) : 0; \ -+ } while (0) -+ - int - show_paths (char ** r, int * len, struct vectors * vecs, char * style, - int pretty) -@@ -802,8 +808,7 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - } - return ev_add_path(pp, vecs, 1); - blacklisted: -- *reply = strdup("blacklisted\n"); -- *len = strlen(*reply) + 1; -+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); - condlog(2, "%s: path blacklisted", param); - return 0; - } -@@ -824,23 +829,10 @@ cli_del_path (void * v, char ** reply, int * len, void * data) - return 1; - } - ret = ev_remove_path(pp, vecs, 1); -- if (ret == REMOVE_PATH_DELAY) { -- *reply = strdup("delayed\n"); -- if (*reply) -- *len = strlen(*reply) + 1; -- else { -- *len = 0; -- ret = REMOVE_PATH_FAILURE; -- } -- } else if (ret == REMOVE_PATH_MAP_ERROR) { -- *reply = strdup("map reload error. removed\n"); -- if (*reply) -- *len = strlen(*reply) + 1; -- else { -- *len = 0; -- ret = REMOVE_PATH_FAILURE; -- } -- } -+ if (ret == REMOVE_PATH_DELAY) -+ SET_REPLY_AND_LEN(reply, len, "delayed\n"); -+ else if (ret == REMOVE_PATH_MAP_ERROR) -+ SET_REPLY_AND_LEN(reply, len, "map reload error. removed\n"); - return (ret == REMOVE_PATH_FAILURE); - } - -@@ -865,8 +857,7 @@ cli_add_map (void * v, char ** reply, int * len, void * data) - invalid = 1; - pthread_cleanup_pop(1); - if (invalid) { -- *reply = strdup("blacklisted\n"); -- *len = strlen(*reply) + 1; -+ SET_REPLY_AND_LEN(reply, len, "blacklisted\n"); - condlog(2, "%s: map blacklisted", param); - return 1; - } diff --git a/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch b/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch new file mode 100644 index 0000000..f79a876 --- /dev/null +++ b/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 23 Sep 2021 14:16:51 -0500 +Subject: [PATCH] libmultipath: add section name to invalid keyword output + +If users forget the closing brace for a section in multipath.conf, +multipath has no way to detect that. When it sees the keyword at the +start of the next section, it will complain that there is an invalid +keyword, because that keyword doesn't belong in previous section (which +was never ended with a closing brace). This can confuse users. To make +this easier to understand, when multipath prints an invalid keyword +message, it now also prints the current section name, which can give +users a hint that they didn't end the previous section. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 8ca91bf2..611054f7 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -504,7 +504,7 @@ validate_config_strvec(vector strvec, const char *file) + + static int + process_stream(struct config *conf, FILE *stream, vector keywords, +- const char *file) ++ const char *section, const char *file) + { + int i; + int r = 0, t; +@@ -568,16 +568,22 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + if (keyword->sub) { + kw_level++; + r += process_stream(conf, stream, +- keyword->sub, file); ++ keyword->sub, ++ keyword->string, ++ file); + kw_level--; + } + break; + } + } +- if (i >= VECTOR_SIZE(keywords)) +- condlog(1, "%s line %d, invalid keyword: %s", +- file, line_nr, str); +- ++ if (i >= VECTOR_SIZE(keywords)) { ++ if (section) ++ condlog(1, "%s line %d, invalid keyword in the %s section: %s", ++ file, line_nr, section, str); ++ else ++ condlog(1, "%s line %d, invalid keyword: %s", ++ file, line_nr, str); ++ } + free_strvec(strvec); + } + if (kw_level == 1) +@@ -608,7 +614,7 @@ process_file(struct config *conf, const char *file) + + /* Stream handling */ + line_nr = 0; +- r = process_stream(conf, stream, conf->keywords, file); ++ r = process_stream(conf, stream, conf->keywords, NULL, file); + fclose(stream); + //free_keywords(keywords); + diff --git a/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch b/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch new file mode 100644 index 0000000..c96a932 --- /dev/null +++ b/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 23 Sep 2021 21:39:36 -0500 +Subject: [PATCH] libmultipath: use typedef for keyword handler function + +Don't keep writing out the function type. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 6 +++--- + libmultipath/parser.h | 15 ++++++--------- + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 611054f7..ebe1cbd9 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -33,7 +33,7 @@ static int line_nr; + + int + keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -72,7 +72,7 @@ install_sublevel_end(void) + + int + _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -558,7 +558,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = (*keyword->handler) (conf, strvec); ++ t = keyword->handler(conf, strvec); + r += t; + if (t) + condlog(1, "multipath.conf +%d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index b43d46f8..3452bde1 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,10 +43,11 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); ++typedef int handler_fn(struct config *, vector); + + struct keyword { + char *string; +- int (*handler) (struct config *, vector); ++ handler_fn *handler; + print_fn *print; + vector sub; + int unique; +@@ -62,18 +63,14 @@ struct keyword { + for (i = 0; i < (k)->sub->allocated && ((p) = (k)->sub->slot[i]); i++) + + /* Prototypes */ +-extern int keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int keyword_alloc(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword_root(str, h) keyword_alloc(keywords, str, h, NULL, 1) + extern void install_sublevel(void); + extern void install_sublevel_end(void); + +-extern int _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int _install_keyword(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword(str, vec, pri) _install_keyword(keywords, str, vec, pri, 1) + #define install_keyword_multi(str, vec, pri) _install_keyword(keywords, str, vec, pri, 0) + extern void dump_keywords(vector keydump, int level); diff --git a/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch b/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch new file mode 100644 index 0000000..6374e20 --- /dev/null +++ b/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 24 Sep 2021 13:13:31 -0500 +Subject: [PATCH] libmultipath: print the correct file when parsing fails + +Don't assume that parsing failed on multipath.conf + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index ebe1cbd9..d5595fb0 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -561,8 +561,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + t = keyword->handler(conf, strvec); + r += t; + if (t) +- condlog(1, "multipath.conf +%d, parsing failed: %s", +- line_nr, buf); ++ condlog(1, "%s line %d, parsing failed: %s", ++ file, line_nr, buf); + } + + if (keyword->sub) { diff --git a/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch b/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch new file mode 100644 index 0000000..a3e51f2 --- /dev/null +++ b/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch @@ -0,0 +1,527 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 24 Sep 2021 17:59:12 -0500 +Subject: [PATCH] libmultipath: pass file and line number to keyword handlers + +This will make it possible for the keyword handlers to print more useful +warning messages. It will be used by future patches. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 143 +++++++++++++++++++++++++----------------- + libmultipath/parser.c | 3 +- + libmultipath/parser.h | 2 +- + 3 files changed, 90 insertions(+), 58 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 7a727389..eb2c44c0 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,7 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr) ++set_int(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -58,7 +58,7 @@ set_int(vector strvec, void *ptr) + } + + static int +-set_uint(vector strvec, void *ptr) ++set_uint(vector strvec, void *ptr, const char *file, int line_nr) + { + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; +@@ -90,7 +90,7 @@ set_uint(vector strvec, void *ptr) + } + + static int +-set_str(vector strvec, void *ptr) ++set_str(vector strvec, void *ptr, const char *file, int line_nr) + { + char **str_ptr = (char **)ptr; + +@@ -105,7 +105,7 @@ set_str(vector strvec, void *ptr) + } + + static int +-set_yes_no(vector strvec, void *ptr) ++set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -124,7 +124,7 @@ set_yes_no(vector strvec, void *ptr) + } + + static int +-set_yes_no_undef(vector strvec, void *ptr) ++set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -187,9 +187,10 @@ static int print_yes_no_undef(struct strbuf *buff, long v) + + #define declare_def_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option); \ ++ return function (strvec, &conf->option, file, line_nr); \ + } + + #define declare_def_snprint(option, function) \ +@@ -224,12 +225,13 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_hw_handler(option, function) \ + static int \ +-hw_ ## option ## _handler (struct config *conf, vector strvec) \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ + if (!hwe) \ + return 1; \ +- return function (strvec, &hwe->option); \ ++ return function (strvec, &hwe->option, file, line_nr); \ + } + + #define declare_hw_snprint(option, function) \ +@@ -243,11 +245,12 @@ snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_ovr_handler(option, function) \ + static int \ +-ovr_ ## option ## _handler (struct config *conf, vector strvec) \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + if (!conf->overrides) \ + return 1; \ +- return function (strvec, &conf->overrides->option); \ ++ return function (strvec, &conf->overrides->option, file, line_nr); \ + } + + #define declare_ovr_snprint(option, function) \ +@@ -260,12 +263,13 @@ snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option); \ ++ return function (strvec, &mpe->option, file, line_nr); \ + } + + #define declare_mp_snprint(option, function) \ +@@ -277,9 +281,10 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + return function(buff, mpe->option); \ + } + +-static int checkint_handler(struct config *conf, vector strvec) ++static int checkint_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_uint(strvec, &conf->checkint); ++ int rc = set_uint(strvec, &conf->checkint, file, line_nr); + + if (rc) + return rc; +@@ -302,9 +307,10 @@ declare_def_snprint(reassign_maps, print_yes_no) + declare_def_handler(multipath_dir, set_str) + declare_def_snprint(multipath_dir, print_str) + +-static int def_partition_delim_handler(struct config *conf, vector strvec) ++static int def_partition_delim_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim); ++ int rc = set_str(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -334,13 +340,13 @@ static const char * const find_multipaths_optvals[] = { + }; + + static int +-def_find_multipaths_handler(struct config *conf, vector strvec) ++def_find_multipaths_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths) == 0 && +- conf->find_multipaths != FIND_MULTIPATHS_UNDEF) ++ if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) + return 0; + + buff = set_value(strvec); +@@ -396,7 +402,8 @@ static int snprint_uid_attrs(struct config *conf, struct strbuf *buff, + return total; + } + +-static int uid_attrs_handler(struct config *conf, vector strvec) ++static int uid_attrs_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *val; + +@@ -597,7 +604,8 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef) + declare_hw_snprint(skip_kpartx, print_yes_no_undef) + declare_mp_handler(skip_kpartx, set_yes_no_undef) + declare_mp_snprint(skip_kpartx, print_yes_no_undef) +-static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) ++static int def_disable_changed_wwids_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return 0; + } +@@ -629,20 +637,23 @@ declare_def_snprint_defstr(enable_foreign, print_str, + DEFAULT_ENABLE_FOREIGN) + + static int +-def_config_dir_handler(struct config *conf, vector strvec) ++def_config_dir_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir); ++ return set_str(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + + #define declare_def_attr_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option, &conf->attribute_flags);\ ++ return function (strvec, &conf->option, &conf->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_def_attr_snprint(option, function) \ +@@ -655,12 +666,14 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_attr_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option, &mpe->attribute_flags); \ ++ return function (strvec, &mpe->option, &mpe->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_mp_attr_snprint(option, function) \ +@@ -673,7 +686,7 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + } + + static int +-set_mode(vector strvec, void *ptr, int *flags) ++set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + mode_t mode; + mode_t *mode_ptr = (mode_t *)ptr; +@@ -694,7 +707,7 @@ set_mode(vector strvec, void *ptr, int *flags) + } + + static int +-set_uid(vector strvec, void *ptr, int *flags) ++set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + uid_t uid; + uid_t *uid_ptr = (uid_t *)ptr; +@@ -719,7 +732,7 @@ set_uid(vector strvec, void *ptr, int *flags) + } + + static int +-set_gid(vector strvec, void *ptr, int *flags) ++set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + gid_t gid; + gid_t *gid_ptr = (gid_t *)ptr; +@@ -786,7 +799,7 @@ declare_mp_attr_handler(gid, set_gid) + declare_mp_attr_snprint(gid, print_gid) + + static int +-set_undef_off_zero(vector strvec, void *ptr) ++set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -827,7 +840,7 @@ declare_hw_handler(fast_io_fail, set_undef_off_zero) + declare_hw_snprint(fast_io_fail, print_undef_off_zero) + + static int +-set_dev_loss(vector strvec, void *ptr) ++set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + unsigned int *uint_ptr = (unsigned int *)ptr; +@@ -870,7 +883,7 @@ declare_hw_handler(eh_deadline, set_undef_off_zero) + declare_hw_snprint(eh_deadline, print_undef_off_zero) + + static int +-set_pgpolicy(vector strvec, void *ptr) ++set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -936,7 +949,8 @@ get_sys_max_fds(int *max_fds) + + + static int +-max_fds_handler(struct config *conf, vector strvec) ++max_fds_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + int r = 0, max_fds; +@@ -981,7 +995,7 @@ snprint_max_fds (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-set_rr_weight(vector strvec, void *ptr) ++set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1025,7 +1039,7 @@ declare_mp_handler(rr_weight, set_rr_weight) + declare_mp_snprint(rr_weight, print_rr_weight) + + static int +-set_pgfailback(vector strvec, void *ptr) ++set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1075,7 +1089,7 @@ declare_mp_handler(pgfailback, set_pgfailback) + declare_mp_snprint(pgfailback, print_pgfailback) + + static int +-no_path_retry_helper(vector strvec, void *ptr) ++no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1120,7 +1134,8 @@ declare_mp_handler(no_path_retry, no_path_retry_helper) + declare_mp_snprint(no_path_retry, print_no_path_retry) + + static int +-def_log_checker_err_handler(struct config *conf, vector strvec) ++def_log_checker_err_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char * buff; + +@@ -1193,7 +1208,8 @@ print_reservation_key(struct strbuf *buff, + } + + static int +-def_reservation_key_handler(struct config *conf, vector strvec) ++def_reservation_key_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return set_reservation_key(strvec, &conf->reservation_key, + &conf->sa_flags, +@@ -1209,7 +1225,8 @@ snprint_def_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-mp_reservation_key_handler(struct config *conf, vector strvec) ++mp_reservation_key_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); + if (!mpe) +@@ -1229,7 +1246,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-set_off_int_undef(vector strvec, void *ptr) ++set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1370,7 +1387,8 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef) + + + static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec) ++def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + unsigned int uxsock_timeout; + char *buff; +@@ -1390,7 +1408,8 @@ def_uxsock_timeout_handler(struct config *conf, vector strvec) + } + + static int +-hw_vpd_vendor_handler(struct config *conf, vector strvec) ++hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + int i; + char *buff; +@@ -1430,7 +1449,8 @@ snprint_hw_vpd_vendor(struct config *conf, struct strbuf *buff, + * blacklist block handlers + */ + static int +-blacklist_handler(struct config *conf, vector strvec) ++blacklist_handler(struct config *conf, vector strvec, const char*file, ++ int line_nr) + { + if (!conf->blist_devnode) + conf->blist_devnode = vector_alloc(); +@@ -1452,7 +1472,8 @@ blacklist_handler(struct config *conf, vector strvec) + } + + static int +-blacklist_exceptions_handler(struct config *conf, vector strvec) ++blacklist_exceptions_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + if (!conf->elist_devnode) + conf->elist_devnode = vector_alloc(); +@@ -1475,7 +1496,8 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) + + #define declare_ble_handler(option) \ + static int \ +-ble_ ## option ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char *buff; \ + int rc; \ +@@ -1494,7 +1516,8 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ + + #define declare_ble_device_handler(name, option, vend, prod) \ + static int \ +-ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char * buff; \ + int rc; \ +@@ -1536,13 +1559,15 @@ snprint_ble_simple (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-ble_device_handler(struct config *conf, vector strvec) ++ble_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->blist_device); + } + + static int +-ble_except_device_handler(struct config *conf, vector strvec) ++ble_except_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->elist_device); + } +@@ -1574,7 +1599,8 @@ static int snprint_bled_product(struct config *conf, struct strbuf *buff, + * devices block handlers + */ + static int +-devices_handler(struct config *conf, vector strvec) ++devices_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->hwtable) + conf->hwtable = vector_alloc(); +@@ -1586,7 +1612,8 @@ devices_handler(struct config *conf, vector strvec) + } + + static int +-device_handler(struct config *conf, vector strvec) ++device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct hwentry * hwe; + +@@ -1623,7 +1650,8 @@ declare_hw_snprint(hwhandler, print_str) + * overrides handlers + */ + static int +-overrides_handler(struct config *conf, vector strvec) ++overrides_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->overrides) + conf->overrides = alloc_hwe(); +@@ -1640,7 +1668,8 @@ overrides_handler(struct config *conf, vector strvec) + * multipaths block handlers + */ + static int +-multipaths_handler(struct config *conf, vector strvec) ++multipaths_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->mptable) + conf->mptable = vector_alloc(); +@@ -1652,7 +1681,8 @@ multipaths_handler(struct config *conf, vector strvec) + } + + static int +-multipath_handler(struct config *conf, vector strvec) ++multipath_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe; + +@@ -1681,7 +1711,8 @@ declare_mp_snprint(alias, print_str) + */ + + static int +-deprecated_handler(struct config *conf, vector strvec) ++deprecated_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index d5595fb0..68262d0e 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -558,7 +558,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = keyword->handler(conf, strvec); ++ t = keyword->handler(conf, strvec, file, ++ line_nr); + r += t; + if (t) + condlog(1, "%s line %d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index 3452bde1..11ea2278 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,7 +43,7 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); +-typedef int handler_fn(struct config *, vector); ++typedef int handler_fn(struct config *, vector, const char *file, int line_nr); + + struct keyword { + char *string; diff --git a/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch b/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch new file mode 100644 index 0000000..eda393f --- /dev/null +++ b/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch @@ -0,0 +1,250 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 28 Sep 2021 15:59:19 -0500 +Subject: [PATCH] libmultipath: make set_int take a range for valid values + +If a value outside of the valid range is passed to set_int, it caps the +value at appropriate limit, and issues a warning. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 121 +++++++++++++++++++++++++++----------------- + 1 file changed, 75 insertions(+), 46 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index eb2c44c0..57b6a7b6 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,8 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, const char *file, int line_nr) ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -44,11 +45,17 @@ set_int(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || res > INT_MAX || res < INT_MIN) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ if (*buff == '\0' || *eptr != '\0') { ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), ++ (res == max)? "large" : "small", res); ++ } + rc = 0; + *int_ptr = res; + } +@@ -77,8 +84,8 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + while (isspace(*eptr)) + eptr++; + if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { + rc = 0; +@@ -193,6 +200,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_range_handler(option, minval, maxval) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_def_snprint(option, function) \ + static int \ + snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -234,6 +249,18 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &hwe->option, file, line_nr); \ + } + ++#define declare_hw_range_handler(option, minval, maxval) \ ++static int \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ ++ if (!hwe) \ ++ return 1; \ ++ return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ ++} ++ ++ + #define declare_hw_snprint(option, function) \ + static int \ + snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -253,6 +280,17 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->overrides->option, file, line_nr); \ + } + ++#define declare_ovr_range_handler(option, minval, maxval) \ ++static int \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ if (!conf->overrides) \ ++ return 1; \ ++ return set_int(strvec, &conf->overrides->option, minval, maxval, \ ++ file, line_nr); \ ++} ++ + #define declare_ovr_snprint(option, function) \ + static int \ + snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -272,6 +310,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &mpe->option, file, line_nr); \ + } + ++#define declare_mp_range_handler(option, minval, maxval) \ ++static int \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ ++ if (!mpe) \ ++ return 1; \ ++ return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_mp_snprint(option, function) \ + static int \ + snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -298,7 +347,7 @@ declare_def_snprint(checkint, print_int) + declare_def_handler(max_checkint, set_uint) + declare_def_snprint(max_checkint, print_int) + +-declare_def_handler(verbosity, set_int) ++declare_def_range_handler(verbosity, 0, MAX_VERBOSITY) + declare_def_snprint(verbosity, print_int) + + declare_def_handler(reassign_maps, set_yes_no) +@@ -473,22 +522,22 @@ declare_ovr_snprint(checker_name, print_str) + declare_hw_handler(checker_name, set_str) + declare_hw_snprint(checker_name, print_str) + +-declare_def_handler(minio, set_int) ++declare_def_range_handler(minio, 0, INT_MAX) + declare_def_snprint_defint(minio, print_int, DEFAULT_MINIO) +-declare_ovr_handler(minio, set_int) ++declare_ovr_range_handler(minio, 0, INT_MAX) + declare_ovr_snprint(minio, print_nonzero) +-declare_hw_handler(minio, set_int) ++declare_hw_range_handler(minio, 0, INT_MAX) + declare_hw_snprint(minio, print_nonzero) +-declare_mp_handler(minio, set_int) ++declare_mp_range_handler(minio, 0, INT_MAX) + declare_mp_snprint(minio, print_nonzero) + +-declare_def_handler(minio_rq, set_int) ++declare_def_range_handler(minio_rq, 0, INT_MAX) + declare_def_snprint_defint(minio_rq, print_int, DEFAULT_MINIO_RQ) +-declare_ovr_handler(minio_rq, set_int) ++declare_ovr_range_handler(minio_rq, 0, INT_MAX) + declare_ovr_snprint(minio_rq, print_nonzero) +-declare_hw_handler(minio_rq, set_int) ++declare_hw_range_handler(minio_rq, 0, INT_MAX) + declare_hw_snprint(minio_rq, print_nonzero) +-declare_mp_handler(minio_rq, set_int) ++declare_mp_range_handler(minio_rq, 0, INT_MAX) + declare_mp_snprint(minio_rq, print_nonzero) + + declare_def_handler(queue_without_daemon, set_yes_no) +@@ -512,7 +561,7 @@ snprint_def_queue_without_daemon(struct config *conf, struct strbuf *buff, + return append_strbuf_quoted(buff, qwd); + } + +-declare_def_handler(checker_timeout, set_int) ++declare_def_range_handler(checker_timeout, 0, INT_MAX) + declare_def_snprint(checker_timeout, print_nonzero) + + declare_def_handler(allow_usb_devices, set_yes_no) +@@ -583,13 +632,13 @@ declare_hw_snprint(deferred_remove, print_yes_no_undef) + declare_mp_handler(deferred_remove, set_yes_no_undef) + declare_mp_snprint(deferred_remove, print_yes_no_undef) + +-declare_def_handler(retrigger_tries, set_int) ++declare_def_range_handler(retrigger_tries, 0, INT_MAX) + declare_def_snprint(retrigger_tries, print_int) + +-declare_def_handler(retrigger_delay, set_int) ++declare_def_range_handler(retrigger_delay, 0, INT_MAX) + declare_def_snprint(retrigger_delay, print_int) + +-declare_def_handler(uev_wait_timeout, set_int) ++declare_def_range_handler(uev_wait_timeout, 0, INT_MAX) + declare_def_snprint(uev_wait_timeout, print_int) + + declare_def_handler(strict_timing, set_yes_no) +@@ -616,19 +665,19 @@ static int snprint_def_disable_changed_wwids(struct config *conf, + return print_ignored(buff); + } + +-declare_def_handler(remove_retries, set_int) ++declare_def_range_handler(remove_retries, 0, INT_MAX) + declare_def_snprint(remove_retries, print_int) + +-declare_def_handler(max_sectors_kb, set_int) ++declare_def_range_handler(max_sectors_kb, 0, INT_MAX) + declare_def_snprint(max_sectors_kb, print_nonzero) +-declare_ovr_handler(max_sectors_kb, set_int) ++declare_ovr_range_handler(max_sectors_kb, 0, INT_MAX) + declare_ovr_snprint(max_sectors_kb, print_nonzero) +-declare_hw_handler(max_sectors_kb, set_int) ++declare_hw_range_handler(max_sectors_kb, 0, INT_MAX) + declare_hw_snprint(max_sectors_kb, print_nonzero) +-declare_mp_handler(max_sectors_kb, set_int) ++declare_mp_range_handler(max_sectors_kb, 0, INT_MAX) + declare_mp_snprint(max_sectors_kb, print_nonzero) + +-declare_def_handler(find_multipaths_timeout, set_int) ++declare_def_range_handler(find_multipaths_timeout, INT_MIN, INT_MAX) + declare_def_snprint_defint(find_multipaths_timeout, print_int, + DEFAULT_FIND_MULTIPATHS_TIMEOUT) + +@@ -1385,27 +1434,7 @@ declare_ovr_snprint(recheck_wwid, print_yes_no_undef) + declare_hw_handler(recheck_wwid, set_yes_no_undef) + declare_hw_snprint(recheck_wwid, print_yes_no_undef) + +- +-static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, +- int line_nr) +-{ +- unsigned int uxsock_timeout; +- char *buff; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; +- +- if (sscanf(buff, "%u", &uxsock_timeout) == 1 && +- uxsock_timeout > DEFAULT_REPLY_TIMEOUT) +- conf->uxsock_timeout = uxsock_timeout; +- else +- conf->uxsock_timeout = DEFAULT_REPLY_TIMEOUT; +- +- free(buff); +- return 0; +-} ++declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX) + + static int + hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, diff --git a/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch b/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch new file mode 100644 index 0000000..eb8c5a6 --- /dev/null +++ b/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch @@ -0,0 +1,170 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 29 Sep 2021 12:56:04 -0500 +Subject: [PATCH] libmultipath: improve checks for set_str + +multipath always requires absolute pathnames, so make sure all file and +directory names start with a slash. Also check that the directories +exist. Finally, some strings, like the alias, will be used in paths. +These must not contain the slash character '/', since it is a forbidden +character in file/directory names. This patch adds seperate handlers for +these three cases. If a config line is invalid, these handlers retain +the existing config string, if any. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 88 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 78 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 57b6a7b6..149d3348 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -5,6 +5,8 @@ + * Copyright (c) 2005 Kiyoshi Ueda, NEC + */ + #include ++#include ++#include + #include + #include + #include "checkers.h" +@@ -111,6 +113,72 @@ set_str(vector strvec, void *ptr, const char *file, int line_nr) + return 0; + } + ++static int ++set_dir(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ struct stat sb; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute directory path. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else { ++ if (stat(*str_ptr, &sb) == 0 && S_ISDIR(sb.st_mode)) ++ free(old_str); ++ else { ++ condlog(1, "%s line %d, %s is not an existing directory. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } ++ } ++ return 0; ++} ++ ++static int ++set_path(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute path. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ ++static int ++set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if (strchr(*str_ptr, '/')) { ++ condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ + static int + set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -353,13 +421,13 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_str) ++declare_def_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, + const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim, file, line_nr); ++ int rc = set_str_noslash(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -490,11 +558,11 @@ declare_hw_snprint(prio_name, print_str) + declare_mp_handler(prio_name, set_str) + declare_mp_snprint(prio_name, print_str) + +-declare_def_handler(alias_prefix, set_str) ++declare_def_handler(alias_prefix, set_str_noslash) + declare_def_snprint_defstr(alias_prefix, print_str, DEFAULT_ALIAS_PREFIX) +-declare_ovr_handler(alias_prefix, set_str) ++declare_ovr_handler(alias_prefix, set_str_noslash) + declare_ovr_snprint(alias_prefix, print_str) +-declare_hw_handler(alias_prefix, set_str) ++declare_hw_handler(alias_prefix, set_str_noslash) + declare_hw_snprint(alias_prefix, print_str) + + declare_def_handler(prio_args, set_str) +@@ -586,13 +654,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_str) ++declare_def_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_str) ++declare_def_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_str) ++declare_def_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -692,7 +760,7 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir, file, line_nr); ++ return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + +@@ -1732,7 +1800,7 @@ multipath_handler(struct config *conf, vector strvec, const char *file, + declare_mp_handler(wwid, set_str) + declare_mp_snprint(wwid, print_str) + +-declare_mp_handler(alias, set_str) ++declare_mp_handler(alias, set_str_noslash) + declare_mp_snprint(alias, print_str) + + /* diff --git a/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch b/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch new file mode 100644 index 0000000..103dcac --- /dev/null +++ b/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch @@ -0,0 +1,114 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 10 Nov 2021 18:34:08 -0600 +Subject: [PATCH] libmultipath: deprecate file and directory config options + +Having multipath able to select pathnames for the files and directories +it needs causes unnecessary maintainer headaches. Mark these as +deprecated, but still support them for now. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 19 +++++++++++++++---- + multipath/multipath.conf.5 | 5 +++++ + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 149d3348..d14be340 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -268,6 +268,15 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_warn_handler(option, function) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ condlog(2, "%s line %d, \"" #option "\" is deprecated and will be disabled in a future release", file, line_nr); \ ++ return function (strvec, &conf->option, file, line_nr); \ ++} ++ + #define declare_def_range_handler(option, minval, maxval) \ + static int \ + def_ ## option ## _handler (struct config *conf, vector strvec, \ +@@ -421,7 +430,7 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_dir) ++declare_def_warn_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, +@@ -654,13 +663,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_path) ++declare_def_warn_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_path) ++declare_def_warn_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_path) ++declare_def_warn_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -760,6 +769,8 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; ++ condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", ++ file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index dd9f4dc7..7f85f766 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -178,6 +178,7 @@ The default is: \fBno\fR + . + .TP + .B multipath_dir ++This option is deprecated, and will be removed in a future release. + Directory where the dynamic shared objects are stored. Defined at compile time, + commonly \fI/lib64/multipath/\fR or \fI/lib/multipath/\fR. + .RS +@@ -742,6 +743,7 @@ The default is: \fB\fR + . + .TP + .B bindings_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the binding file to be used when the user_friendly_names + option is set. + .RS +@@ -752,6 +754,7 @@ The default is: \fB/etc/multipath/bindings\fR + . + .TP + .B wwids_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the WWIDs file, which is used by multipath to keep track + of the WWIDs for LUNs it has created multipath devices on in the past. + .RS +@@ -762,6 +765,7 @@ The default is: \fB/etc/multipath/wwids\fR + . + .TP + .B prkeys_file ++This option is deprecated, and will be removed in a future release. + 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. +@@ -933,6 +937,7 @@ The default is: \fB\fR + . + .TP + .B config_dir ++This option is deprecated, and will be removed in a future release. + If set to anything other than "", multipath will search this directory + alphabetically for file ending in ".conf" and it will read configuration + information from them, just as if it was in \fI/etc/multipath.conf\fR. diff --git a/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch b/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch new file mode 100644 index 0000000..9f33473 --- /dev/null +++ b/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch @@ -0,0 +1,191 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Oct 2021 15:27:36 -0500 +Subject: [PATCH] libmultipath: split set_int to enable reuse + +Split the code that does the actual value parsing out of set_int(), into +a helper function, do_set_int(), so that it can be used by other +handlers. These functions no longer set the config value at all, when +they have invalid input. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 82 +++++++++++++++++++++++++-------------------- + 1 file changed, 46 insertions(+), 36 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index d14be340..68647061 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -31,17 +31,12 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, int min, int max, const char *file, +- int line_nr) ++do_set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr, char *buff) + { + int *int_ptr = (int *)ptr; +- char *buff, *eptr; ++ char *eptr; + long res; +- int rc; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; + + res = strtol(buff, &eptr, 10); + if (eptr > buff) +@@ -50,17 +45,30 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- if (res > max || res < min) { +- res = (res > max) ? max : min; +- condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ return 1; ++ } ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), +- (res == max)? "large" : "small", res); +- } +- rc = 0; +- *int_ptr = res; ++ (res == max)? "large" : "small", res); + } ++ *int_ptr = res; ++ return 0; ++} ++ ++static int ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) ++{ ++ char *buff; ++ int rc; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); + return rc; +@@ -929,6 +937,7 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -938,10 +947,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else if (sscanf(buff, "%d", int_ptr) != 1 || +- *int_ptr < UOZ_ZERO) +- *int_ptr = UOZ_UNDEF; +- else if (*int_ptr == 0) ++ else ++ rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, ++ buff); ++ if (rc == 0 && *int_ptr == 0) + *int_ptr = UOZ_ZERO; + + FREE(buff); +@@ -1093,14 +1102,12 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + /* Assume safe limit */ + max_fds = 4096; + } +- if (strlen(buff) == 3 && +- !strcmp(buff, "max")) +- conf->max_fds = max_fds; +- else +- conf->max_fds = atoi(buff); +- +- if (conf->max_fds > max_fds) ++ if (!strcmp(buff, "max")) { + conf->max_fds = max_fds; ++ r = 0; ++ } else ++ r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, ++ line_nr, buff); + + FREE(buff); + +@@ -1169,6 +1176,7 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1183,11 +1191,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- *int_ptr = atoi(buff); ++ rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return 0; ++ return rc; + } + + int +@@ -1219,6 +1227,7 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1230,11 +1239,11 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + *int_ptr = NO_PATH_RETRY_FAIL; + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NO_PATH_RETRY_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int +@@ -1376,6 +1385,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1385,11 +1395,11 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NU_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int diff --git a/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch b/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch new file mode 100644 index 0000000..c8978f2 --- /dev/null +++ b/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Oct 2021 16:52:55 -0500 +Subject: [PATCH] libmultipath: cleanup invalid config handling + +Add error reporting to the remaining config handlers. If the value is +invalid, do not change the existing config option's value. Also print +an error whenever 0 is returned for an invalid value. When the handler +returns 1, config processing already fails with an error message. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 73 +++++++++++++++++++++++++++++++-------------- + 1 file changed, 51 insertions(+), 22 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 68647061..c534d703 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -199,8 +199,11 @@ set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YN_YES; +- else ++ else if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) + *int_ptr = YN_NO; ++ else ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -221,7 +224,8 @@ set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YNU_YES; + else +- *int_ptr = YNU_UNDEF; ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -480,9 +484,6 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) +- return 0; +- + buff = set_value(strvec); + if (!buff) + return 1; +@@ -495,9 +496,14 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + } + } + +- if (conf->find_multipaths == YNU_UNDEF) { +- condlog(0, "illegal value for find_multipaths: %s", buff); +- conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; ++ if (i >= __FIND_MULTIPATHS_LAST) { ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_OFF; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_ON; ++ else ++ condlog(1, "%s line %d, invalid value for find_multipaths: \"%s\"", ++ file, line_nr, buff); + } + + FREE(buff); +@@ -546,8 +552,10 @@ static int uid_attrs_handler(struct config *conf, vector strvec, + if (!val) + return 1; + if (parse_uid_attrs(val, conf)) +- condlog(1, "error parsing uid_attrs: \"%s\"", val); +- condlog(3, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); ++ condlog(1, "%s line %d,error parsing uid_attrs: \"%s\"", file, ++ line_nr, val); ++ else ++ condlog(4, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); + FREE(val); + return 0; + } +@@ -775,8 +783,11 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + /* this is only valid in the main config file */ +- if (conf->processed_main_config) ++ if (conf->processed_main_config) { ++ condlog(1, "%s line %d, config_dir option only valid in /etc/multipath.conf", ++ file, line_nr); + return 0; ++ } + condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", + file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); +@@ -836,7 +847,9 @@ set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) { + *flags |= (1 << ATTR_MODE); + *mode_ptr = mode; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for mode: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -861,7 +874,9 @@ set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &uid) == 1){ + *flags |= (1 << ATTR_UID); + *uid_ptr = uid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for uid: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -887,7 +902,9 @@ set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &gid) == 1){ + *flags |= (1 << ATTR_GID); + *gid_ptr = gid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for gid: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + return 0; + } +@@ -989,7 +1006,8 @@ set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "infinity")) + *uint_ptr = MAX_DEV_LOSS_TMO; + else if (sscanf(buff, "%u", uint_ptr) != 1) +- *uint_ptr = DEV_LOSS_TMO_UNSET; ++ condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1023,13 +1041,19 @@ static int + set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; ++ int policy; + int *int_ptr = (int *)ptr; + + buff = set_value(strvec); + if (!buff) + return 1; + +- *int_ptr = get_pgpolicy_id(buff); ++ policy = get_pgpolicy_id(buff); ++ if (policy != IOPOLICY_UNDEF) ++ *int_ptr = policy; ++ else ++ condlog(1, "%s line %d, invalid value for path_grouping_policy: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1142,10 +1166,11 @@ set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "priorities")) + *int_ptr = RR_WEIGHT_PRIO; +- +- if (!strcmp(buff, "uniform")) ++ else if (!strcmp(buff, "uniform")) + *int_ptr = RR_WEIGHT_NONE; +- ++ else ++ condlog(1, "%s line %d, invalid value for rr_weight: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1281,10 +1306,13 @@ def_log_checker_err_handler(struct config *conf, vector strvec, + if (!buff) + return 1; + +- if (strlen(buff) == 4 && !strcmp(buff, "once")) ++ if (!strcmp(buff, "once")) + conf->log_checker_err = LOG_CHKR_ERR_ONCE; +- else if (strlen(buff) == 6 && !strcmp(buff, "always")) ++ else if (!strcmp(buff, "always")) + conf->log_checker_err = LOG_CHKR_ERR_ALWAYS; ++ else ++ condlog(1, "%s line %d, invalid value for log_checker_err: \"%s\"", ++ file, line_nr, buff); + + free(buff); + return 0; +@@ -1545,7 +1573,8 @@ hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, + goto out; + } + } +- hwe->vpd_vendor_id = 0; ++ condlog(1, "%s line %d, invalid value for vpd_vendor: \"%s\"", ++ file, line_nr, buff); + out: + FREE(buff); + return 0; diff --git a/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch b/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch new file mode 100644 index 0000000..5ce85d4 --- /dev/null +++ b/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch @@ -0,0 +1,218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 17:37:05 -0600 +Subject: [PATCH] libmultipath: don't return error on invalid values + +do_set_int and set_uint return 1 for invalid values. This can cause +multipath to fail completely, while reading the config. The config +handlers should only return a non-zero value if there is an internal +error, not if there is just an invalid value. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 64 ++++++++++++++++++--------------------------- + 1 file changed, 25 insertions(+), 39 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index c534d703..1b75be47 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -30,7 +30,7 @@ + #include "dict.h" + #include "strbuf.h" + +-static int ++static void + do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr, char *buff) + { +@@ -45,7 +45,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- return 1; ++ return; + } + if (res > max || res < min) { + res = (res > max) ? max : min; +@@ -54,7 +54,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + (res == max)? "large" : "small", res); + } + *int_ptr = res; +- return 0; ++ return; + } + + static int +@@ -62,16 +62,15 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr) + { + char *buff; +- int rc; + + buff = set_value(strvec); + if (!buff) + return 1; + +- rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); ++ do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -80,7 +79,6 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; + unsigned long res; +- int rc; + + buff = set_value(strvec); + if (!buff) +@@ -93,17 +91,14 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { ++ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- rc = 0; ++ else + *uint_ptr = res; +- } + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -954,7 +949,6 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -964,11 +958,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else +- rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, +- buff); +- if (rc == 0 && *int_ptr == 0) ++ else if (strcmp(buff, "0") == 0) + *int_ptr = UOZ_ZERO; ++ else ++ do_set_int(strvec, int_ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1114,28 +1107,24 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + char * buff; +- int r = 0, max_fds; ++ int max_fds; + + buff = set_value(strvec); + + if (!buff) + return 1; + +- r = get_sys_max_fds(&max_fds); +- if (r) { +- /* Assume safe limit */ +- max_fds = 4096; +- } +- if (!strcmp(buff, "max")) { ++ if (get_sys_max_fds(&max_fds) != 0) ++ max_fds = 4096; /* Assume safe limit */ ++ if (!strcmp(buff, "max")) + conf->max_fds = max_fds; +- r = 0; +- } else +- r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, +- line_nr, buff); ++ else ++ do_set_int(strvec, &conf->max_fds, 0, max_fds, file, line_nr, ++ buff); + + FREE(buff); + +- return r; ++ return 0; + } + + static int +@@ -1201,7 +1190,6 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1216,11 +1204,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return rc; ++ return 0; + } + + int +@@ -1252,7 +1240,6 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1265,10 +1252,10 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int +@@ -1413,7 +1400,6 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1424,10 +1410,10 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int diff --git a/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch b/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch new file mode 100644 index 0000000..7bbe406 --- /dev/null +++ b/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 15 Nov 2021 10:54:35 -0600 +Subject: [PATCH] multipathd: avoid unnecessary path read-only reloads + +A mulitpath device can only be reloaded read/write when all paths are +read/write. Also, whenever a read-only device is rescanned, the scsi +subsystem will first unconditionally issue a uevent with DISK_RO=0 +before checking the read-only status, and if it the device is still +read-only, issuing another uevent with DISK_RO=1. These uevents cause +pointless reloads when read-only paths are rescanned. To avoid this, +check to see if all paths are read/write before changing a multipath +device from read-only to read/write. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 5 +++++ + libmultipath/sysfs.c | 22 ++++++++++++++++++++++ + libmultipath/sysfs.h | 1 + + multipathd/main.c | 31 ++++++++++++++++++++++++++++++- + 4 files changed, 58 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index eb5b5b55..dd1b4122 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -287,3 +287,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_9.1.0 { ++global: ++ sysfs_get_ro; ++} LIBMULTIPATH_9.0.0; +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 9ff145f2..24c12b6a 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -236,6 +236,28 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + return 0; + } + ++int ++sysfs_get_ro (struct path *pp) ++{ ++ int ro; ++ char buff[3]; /* Either "0\n\0" or "1\n\0" */ ++ ++ if (!pp->udev) ++ return -1; ++ ++ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); ++ return -1; ++ } ++ ++ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { ++ condlog(3, "%s: Cannot parse ro attribute", pp->dev); ++ return -1; ++ } ++ ++ return ro; ++} ++ + int sysfs_check_holders(char * check_devt, char * new_devt) + { + unsigned int major, new_minor, table_minor; +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 72b39ab2..c948c467 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -13,6 +13,7 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); + int sysfs_get_size (struct path *pp, unsigned long long * size); ++int sysfs_get_ro(struct path *pp); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); + #endif +diff --git a/multipathd/main.c b/multipathd/main.c +index 1defeaf1..6145e512 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1324,6 +1324,35 @@ fail: + return REMOVE_PATH_MAP_ERROR; + } + ++static bool ++needs_ro_update(struct multipath *mpp, int ro) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ unsigned int i, j; ++ struct dm_info *dmi = NULL; ++ ++ if (!mpp || ro < 0) ++ return false; ++ dm_get_info(mpp->alias, &dmi); ++ if (!dmi) /* assume we do need to reload the device */ ++ return true; ++ if (dmi->read_only == ro) { ++ free(dmi); ++ return false; ++ } ++ free(dmi); ++ if (ro == 1) ++ return true; ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ if (sysfs_get_ro(pp) == 1) ++ return false; ++ } ++ } ++ return true; ++} ++ + static int + uev_update_path (struct uevent *uev, struct vectors * vecs) + { +@@ -1388,7 +1417,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + } + + ro = uevent_get_disk_ro(uev); +- if (mpp && ro >= 0) { ++ if (needs_ro_update(mpp, ro)) { + condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); + + if (mpp->wait_for_udev) diff --git a/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch b/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch new file mode 100644 index 0000000..66a18f5 --- /dev/null +++ b/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 22 Oct 2021 12:58:11 +0200 +Subject: [PATCH] multipath: fix exit status of multipath -T + +We must set the return value in configure(). + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipath/main.c b/multipath/main.c +index 748e7902..80fa68e5 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -606,6 +606,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + + dump_config(conf, hwes, curmp); + vector_free(hwes); ++ r = RTVL_OK; + goto out; + } + diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index c736549..f48572c 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,37 +1,50 @@ Name: device-mapper-multipath -Version: 0.8.6 -Release: 7%{?dist} +Version: 0.8.7 +Release: 3%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 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 -L https://github.com/opensvc/multipath-tools/archive/0.8.6.tar.gz -o multipath-tools-0.8.6.tgz -Source0: multipath-tools-0.8.6.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.7.tar.gz -o multipath-tools-0.8.7.tgz +Source0: multipath-tools-0.8.7.tgz Source1: multipath.conf -Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch -Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0003: 0003-RH-don-t-start-without-a-config-file.patch -Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch -Patch0005: 0005-RH-use-rpm-optflags-if-present.patch -Patch0006: 0006-RH-add-mpathconf.patch -Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch0011: 0011-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch -Patch0012: 0012-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch -Patch0013: 0013-multipathd-fix-ev_remove_path-return-code-handling.patch -Patch0014: 0014-multipath-free-vectors-in-configure.patch -Patch0015: 0015-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch -Patch0016: 0016-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch -Patch0017: 0017-RH-mpathconf-correctly-handle-spaces-after-option-na.patch -Patch0018: 0018-multipath.conf-fix-typo-in-ghost_delay-description.patch -Patch0019: 0019-mpathpersist-fail-commands-when-no-usable-paths-exis.patch -Patch0020: 0020-multipath-print-warning-if-multipathd-is-not-running.patch -Patch0021: 0021-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch -Patch0022: 0022-multipathd-cli_handlers-cleanup-setting-reply-length.patch +Patch0001: 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch +Patch0002: 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch +Patch0003: 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch +Patch0004: 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch +Patch0005: 0005-multipathd.socket-add-missing-conditions-from-servic.patch +Patch0006: 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch +Patch0007: 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch +Patch0008: 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch +Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch +Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch +Patch0011: 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch +Patch0012: 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch +Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch +Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0015: 0015-RH-don-t-start-without-a-config-file.patch +Patch0016: 0016-RH-Fix-nvme-function-missing-argument.patch +Patch0017: 0017-RH-use-rpm-optflags-if-present.patch +Patch0018: 0018-RH-add-mpathconf.patch +Patch0019: 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0021: 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0022: 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0023: 0023-libmultipath-add-section-name-to-invalid-keyword-out.patch +Patch0024: 0024-libmultipath-use-typedef-for-keyword-handler-functio.patch +Patch0025: 0025-libmultipath-print-the-correct-file-when-parsing-fai.patch +Patch0026: 0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +Patch0027: 0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch +Patch0028: 0028-libmultipath-improve-checks-for-set_str.patch +Patch0029: 0029-libmultipath-deprecate-file-and-directory-config-opt.patch +Patch0030: 0030-libmultipath-split-set_int-to-enable-reuse.patch +Patch0031: 0031-libmultipath-cleanup-invalid-config-handling.patch +Patch0032: 0032-libmultipath-don-t-return-error-on-invalid-values.patch +Patch0033: 0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch +Patch0034: 0034-multipath-fix-exit-status-of-multipath-T.patch + # runtime Requires: %{name}-libs = %{version}-%{release} @@ -115,7 +128,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.6 -p1 +%autosetup -n multipath-tools-0.8.7 -p1 cp %{SOURCE1} . %build @@ -230,6 +243,46 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Nov 19 2021 Benjamin Marzinski - 0.8.7-3 +- Add 0024-libmultipath-use-typedef-for-keyword-handler-functio.patch +- Add 0025-libmultipath-print-the-correct-file-when-parsing-fai.patch +- Add 0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +- Add 0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch +- Add 0028-libmultipath-improve-checks-for-set_str.patch +- Add 0029-libmultipath-deprecate-file-and-directory-config-opt.patch +- Add 0030-libmultipath-split-set_int-to-enable-reuse.patch +- Add 0031-libmultipath-cleanup-invalid-config-handling.patch +- Add 0032-libmultipath-don-t-return-error-on-invalid-values.patch + * The above 9 patches fix bz #2017969 +- Add 0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch + * Fixes bz #2017979 +- Add 0034-multipath-fix-exit-status-of-multipath-T.patch +- Resolves: bz #2017969, #2017979 + +* Mon Nov 08 2021 Benjamin Marzinski - 0.8.7-2 +- Modify 0017-RH-use-rpm-optflags-if-present.patch + * use RPM_LF_FLAGS +- Modify 0018-RH-add-mpathconf.patch + * update default config to match multipath changes +- Modify 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch + * fix cmocka vpd tests +- Rename 0023-libmulitpath-add-section-name-to-invalid-keyword-out.patch to + 0023-libmultipath-add-section-name-to-invalid-keyword-out.patch +- Resolves: bz#2017592 + +* Fri Oct 29 2021 Benjamin Marzinski - 0.8.7-1 +- Update Source to upstream version 0.8.7 plus upstream staged commits + * Previous patches 0011-0016 & 0018-0022 are included in the source tarball + * Fixes bz#2017592 +- Rename files + * Previous patches 0001-0010 are now patches 0013-0022 +- Modify 0018-RH-add-mpathconf.patch + * merged with previous patch 0017 +- Add 0023-libmulitpath-add-section-name-to-invalid-keyword-out.patch + * Fixes bz#1984303 +- Fix multipath_conf_syntax test to work with bz #1984303 +- Resolves: bz #1984303, #2017592 + * Mon Aug 09 2021 Mohan Boddu - 0.8.6-7 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags Related: rhbz#1991688