diff --git a/.device-mapper-multipath.metadata b/.device-mapper-multipath.metadata deleted file mode 100644 index 6f07c28..0000000 --- a/.device-mapper-multipath.metadata +++ /dev/null @@ -1 +0,0 @@ -b52c2be340449664f0a122070838f6d8edd42e4a SOURCES/multipath-tools-0.8.4.tgz diff --git a/.gitignore b/.gitignore index 044d015..8670591 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/multipath-tools-0.8.4.tgz +multipath-tools-0.9.9.tgz diff --git a/0001-multipathd-fix-flush-check-in-flush_map.patch b/0001-multipathd-fix-flush-check-in-flush_map.patch new file mode 100644 index 0000000..3ff957d --- /dev/null +++ b/0001-multipathd-fix-flush-check-in-flush_map.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 5 Jun 2024 19:22:48 -0400 +Subject: [PATCH] multipathd: fix flush check in flush_map() + +Forgot the comparison in the "if" statement. + +Fixes 8a3898339 ("multipathd: sync features on flush_map failure corner case") + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + multipathd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 09286dd0..58afe14a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -813,7 +813,7 @@ flush_map(struct multipath * mpp, struct vectors * vecs) + { + int r = dm_suspend_and_flush_map(mpp->alias, 0); + if (r != DM_FLUSH_OK) { +- if (DM_FLUSH_FAIL_CANT_RESTORE) ++ if (r == DM_FLUSH_FAIL_CANT_RESTORE) + remove_feature(&mpp->features, "queue_if_no_path"); + condlog(0, "%s: can't flush", mpp->alias); + return r; diff --git a/0002-RH-fixup-udev-rules-for-redhat.patch b/0002-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..d78919e --- /dev/null +++ b/0002-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 81b86cd8..33dbb99c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -34,7 +34,7 @@ endif + # Paths. All these can be overridden on the "make" command line. + prefix := + # Prefix for binaries +-exec_prefix := $(prefix) ++exec_prefix := $(prefix)/usr + # Prefix for non-essential libraries (libdmmp) + usr_prefix := $(if $(prefix),$(prefix),/usr) + # Prefix for configuration files (multipath.conf) +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index 8dd3369c..7c3c7524 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -39,6 +39,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 67fb5e62..2ea9e528 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -27,7 +27,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +- $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/56-multipath.rules ++ $(Q)$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)$(udevrulesdir)/62-multipath.rules + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 +@@ -50,7 +50,7 @@ uninstall: + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf +- $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf diff --git a/SOURCES/0012-RH-Remove-the-property-blacklist-exception-builtin.patch b/0003-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 74% rename from SOURCES/0012-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0003-RH-Remove-the-property-blacklist-exception-builtin.patch index 10cc1b3..b039539 100644 --- a/SOURCES/0012-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0003-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,29 +13,25 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 9 ++------- - multipath/multipath.conf.5 | 11 ++++++----- - tests/blacklist.c | 6 ++---- - 3 files changed, 10 insertions(+), 16 deletions(-) + libmultipath/blacklist.c | 5 ++--- + multipath/multipath.conf.5.in | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 00e8dbdb..d9691b17 100644 +index 75100b20..0b212078 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf) - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) - return 1; +@@ -230,8 +230,6 @@ setup_default_blist (struct config * conf) + ORIGIN_DEFAULT)) + return 1; + } +- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) +- return 1; -- str = STRDUP("(SCSI_IDENT_|ID_WWN)"); -- if (!str) -- return 1; -- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT)) -- return 1; -- vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { - if (find_blacklist_device(conf->blist_device, -@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, +@@ -438,7 +436,8 @@ filter_property(const struct config *conf, struct udev_device *udev, *uid_attribute != '\0'; bool uid_attr_seen = false; @@ -45,11 +41,11 @@ index 00e8dbdb..d9691b17 100644 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 05a5e8ff..3455b1cc 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1286,9 +1286,14 @@ keywords. Both are regular expressions. For a full description of these keywords +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index dacb9b0e..645e8f88 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1468,9 +1468,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, @@ -65,7 +61,7 @@ index 05a5e8ff..3455b1cc 100644 . .RS .PP -@@ -1299,10 +1304,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1481,10 +1486,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. @@ -77,19 +73,21 @@ index 05a5e8ff..3455b1cc 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index 6e7c1864..cc8a9a4a 100644 +index ba8dfd07..693db3fa 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -271,7 +271,7 @@ static void test_property_missing(void **state) +@@ -384,9 +384,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"); +- 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, ""), -@@ -363,9 +363,7 @@ static void test_filter_path_missing1(void **state) +@@ -478,9 +477,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; @@ -100,6 +98,3 @@ index 6e7c1864..cc8a9a4a 100644 } /* This one matches the property whitelist, to test the other missing --- -2.17.2 - diff --git a/0004-RH-don-t-start-without-a-config-file.patch b/0004-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..267ffa7 --- /dev/null +++ b/0004-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,137 @@ +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/main.c | 6 ++++++ + multipath/multipath.rules.in | 1 + + multipathd/multipathd.8.in | 2 ++ + multipathd/multipathd.service.in | 1 + + multipathd/multipathd.socket | 1 + + 7 files changed, 25 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 83fa7369..002027a7 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -959,6 +959,19 @@ int _init_config (const char *file, struct config *conf) + } + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + validate_pctable(conf->overrides, 0, 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 384193ab..158cebf0 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -10,6 +10,7 @@ + + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 ++#define ORIGIN_NO_CONFIG 2 + + enum devtypes { + DEV_NONE, +diff --git a/multipath/main.c b/multipath/main.c +index ce702e7f..c21e3e0b 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -842,11 +842,14 @@ main (int argc, char *argv[]) + char *dev = NULL; + struct config *conf; + bool enable_foreign = false; ++ bool have_config; ++ struct stat buf; + + libmultipath_init(); + if (atexit(dm_lib_exit) || atexit(libmultipath_exit)) + condlog(1, "failed to register cleanup handler for libmultipath: %m"); + logsink = LOGSINK_STDERR_WITH_TIME; ++ have_config = (stat(DEFAULT_CONFIGFILE, &buf) == 0); + if (init_config(DEFAULT_CONFIGFILE)) + exit(RTVL_FAIL); + if (atexit(uninit_config)) +@@ -1097,6 +1100,9 @@ main (int argc, char *argv[]) + while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) + condlog(3, "restart multipath configuration process"); + ++ if (!have_config && r == RTVL_OK && ++ (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG)) ++ r = RTVL_FAIL; + out: + put_multipath_config(conf); + if (dev) +diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in +index 780bf852..2c518378 100644 +--- a/multipath/multipath.rules.in ++++ b/multipath/multipath.rules.in +@@ -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.in b/multipathd/multipathd.8.in +index 7bc8806e..315884eb 100644 +--- a/multipathd/multipathd.8.in ++++ b/multipathd/multipathd.8.in +@@ -49,6 +49,8 @@ map regains its maximum performance and redundancy. + With the \fB-k\fR option, \fBmultipathd\fR acts as a client utility that + sends commands to a running instance of the multipathd daemon (see + \fBCOMMANDS\fR below). ++ ++In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index a63ddd9a..01ceff7d 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket @MODPROBE_UNIT@ + After=systemd-udevd-kernel.socket @MODPROBE_UNIT@ + After=multipathd.socket systemd-remount-fs.service + Before=initrd-cleanup.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + Conflicts=initrd-cleanup.service +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index 6a62f5fd..263b6b0c 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/0019-RH-Fix-nvme-compilation-warning.patch b/0005-RH-Fix-nvme-function-missing-argument.patch similarity index 82% rename from SOURCES/0019-RH-Fix-nvme-compilation-warning.patch rename to 0005-RH-Fix-nvme-function-missing-argument.patch index fc6ccd7..ced7159 100644 --- a/SOURCES/0019-RH-Fix-nvme-compilation-warning.patch +++ b/0005-RH-Fix-nvme-function-missing-argument.patch @@ -1,7 +1,10 @@ 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 compilation warning +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 --- @@ -21,6 +24,3 @@ index adb192b6..bfd10ef8 100644 void argconfig_append_usage(const char *str); void argconfig_print_help(const char *program_desc, const struct argconfig_commandline_options *options); --- -2.17.2 - diff --git a/0006-RH-use-rpm-optflags-if-present.patch b/0006-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..0f354e7 --- /dev/null +++ b/0006-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 19 Apr 2017 06:10:01 -0500 +Subject: [PATCH] RH: use rpm optflags if present + +Use the passed in optflags when compiling as an RPM, and keep the +default flags as close as possible to the current fedora flags, while +still being generic. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 33dbb99c..94e0ec85 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -95,11 +95,23 @@ SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo + MODPROBE_UNIT := $(shell test "0$(SYSTEMD)" -lt 245 2>/dev/null || \ + echo "modprobe@dm_multipath.service") + +-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ ++ifndef RPM_OPT_FLAGS ++ OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 \ ++ -Wall $(FORTIFY_OPT) -fexceptions -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables ++ 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) $(W_URCU_TYPE_LIMITS) +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes ++CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ + -D_FILE_OFFSET_BITS=64 \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ +@@ -109,7 +121,7 @@ CFLAGS := -std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe + 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 + + # Source code directories. Don't modify. diff --git a/SOURCES/0015-RH-add-mpathconf.patch b/0007-RH-add-mpathconf.patch similarity index 64% rename from SOURCES/0015-RH-add-mpathconf.patch rename to 0007-RH-add-mpathconf.patch index 009a033..fd65e34 100644 --- a/SOURCES/0015-RH-add-mpathconf.patch +++ b/0007-RH-add-mpathconf.patch @@ -10,22 +10,23 @@ 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. +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + - multipath/Makefile | 5 + - multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 697 insertions(+) + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 ++++++++++ + 4 files changed, 815 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index b36778b0..26f8e050 100644 +index 002027a7..3d5943d3 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -781,6 +781,8 @@ load_config (char * file) - factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); +@@ -961,6 +961,8 @@ int _init_config (const char *file, struct config *conf) + validate_pctable(conf->overrides, 0, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); @@ -34,45 +35,46 @@ index b36778b0..26f8e050 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b9bbb3cf..e720c7f6 100644 +index 2ea9e528..3dc241cc 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 - +@@ -24,6 +24,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so 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) + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -32,6 +33,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).8 $(DESTDIR)$(mandir)/man8 ++ $(Q)$(INSTALL_PROGRAM) -m 644 mpathconf.8 $(DESTDIR)$(mandir)/man8 + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)/man5 + $(Q)$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5 $(DESTDIR)$(mandir)/man5 + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(modulesloaddir) +@@ -46,12 +48,14 @@ endif 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 + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/scsi_dh.conf + $(Q)$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(Q)$(RM) $(DESTDIR)$(mandir)/man8/$(EXEC).8 ++ $(Q)$(RM) $(DESTDIR)$(mandir)/man8/mpathconf.8 + $(Q)$(RM) $(DESTDIR)$(mandir)/man5/$(EXEC).conf.5 + $(Q)$(RM) $(DESTDIR)$(tmpfilesdir)/multipath.conf - clean: dep_clean - $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 00000000..f34003c9 +index 00000000..ce430075 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,555 @@ +@@ -0,0 +1,658 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -92,7 +94,7 @@ index 00000000..f34003c9 +# 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 ++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 HAVE_OPTION OPTION_NAME OPTION_VALUE HAVE_RECHECK_WWID RECHECK_WWID + +DEFAULT_CONFIG="# device-mapper-multipath configuration file + @@ -106,12 +108,7 @@ index 00000000..f34003c9 + +defaults { + user_friendly_names yes -+ find_multipaths yes -+ enable_foreign \"^$\" -+} -+ -+blacklist_exceptions { -+ property \"(SCSI_IDENT_|ID_WWN)\" ++ find_multipaths on +}" + +CONFIGFILE="/etc/multipath.conf" @@ -129,9 +126,11 @@ index 00000000..f34003c9 + 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 find_multipaths (Default on): --find_multipaths " ++ echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Set recheck_wwid (Defaut n): --recheck_wwid " ++ echo "Add/Change/Remove option in defaults section: --option :" + 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 " @@ -224,6 +223,15 @@ index 00000000..f34003c9 + exit 1 + fi + ;; ++ --recheck_wwid) ++ if [ -n "$2" ]; then ++ RECHECK_WWID=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --find_multipaths) + if [ -n "$2" ]; then + FIND=$2 @@ -242,6 +250,20 @@ index 00000000..f34003c9 + exit 1 + fi + ;; ++ --option) ++ if [ -n "$2" ]; then ++ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) ++ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) ++ if [ -z "$OPTION_NAME" ]; then ++ usage ++ exit 1 ++ fi ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --enable_foreign) + if [ -n "$2" ]; then + FOREIGN=$2 @@ -288,19 +310,31 @@ index 00000000..f34003c9 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" -o -n "$RECHECK_WWID" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" ++ FOREIGN="" ++ OPTION_NAME="" ++ OPTION_VALUE="" ++ RECHECK_WWID="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" + exit 1 + fi -+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then -+ echo "--find_multipaths must be either 'y' or 'n'" ++ if [ -n "$RECHECK_WWID" ] && [ "$RECHECK_WWID" != "y" -a "$RECHECK_WWID" != "n" ]; then ++ echo "--recheck_wwid must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ "$FIND" = "y" ]; then ++ FIND="on" ++ elif [ "$FIND" = "n" ]; then ++ FIND="off" ++ elif [ -n "$FIND" ] && [ "$FIND" != "on" -a "$FIND" != "yes" -a "$FIND" != "off" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'on' 'yes' 'y' 'off' 'no' 'n' 'strict' 'greedy' or 'smart'" + exit 1 + fi + if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then @@ -311,7 +345,19 @@ index 00000000..f34003c9 + 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 [ -n "$OPTION_NAME" ]; then ++ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then ++ echo "--option name \"$OPTION_NAME\" is invalid" ++ exit 1 ++ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then ++ echo "--option value \"$OPTION_VALUE\" is invalid" ++ exit 1 ++ fi ++ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then ++ OPTION_VALUE=\"$OPTION_VALUE\" ++ fi ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" -a -z "$RECHECK_WWID" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -386,45 +432,62 @@ index 00000000..f34003c9 +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 -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then -+ HAVE_FIND=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then -+ HAVE_FIND=0 ++ 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:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)" ; then ++ HAVE_RECHECK_WWID=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)" ; then ++ HAVE_RECHECK_WWID=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 ++ if [ -n "$OPTION_NAME" ]; then ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then ++ HAVE_OPTION=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then ++ HAVE_OPTION=0 ++ fi + 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 @@ -435,24 +498,31 @@ index 00000000..f34003c9 + else + echo "multipath is disabled" + fi -+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then -+ echo "find_multipaths is disabled" ++ if [ -z "$HAVE_FIND" ]; then ++ echo "find_multipaths is off" + else -+ echo "find_multipaths is enabled" ++ 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_RECHECK_WWID" -o "$HAVE_RECHECK_WWID" = 0 ]; then ++ echo "recheck_wwid is disabled" ++ else ++ echo "recheck_wwid 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)" ++ 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)" @@ -497,14 +567,14 @@ index 00000000..f34003c9 + +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 @@ -518,7 +588,7 @@ index 00000000..f34003c9 + 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 @@ -526,30 +596,25 @@ index 00000000..f34003c9 + 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 + -+if [ "$FIND" = "n" ]; then -+ if [ "$HAVE_FIND" = 1 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ "$FIND" = "y" ]; then ++if [ -n "$FIND" ]; then + if [ -z "$HAVE_FIND" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ -+ find_multipaths yes ++ find_multipaths '"$FIND"' +' $TMPFILE + CHANGED_CONFIG=1 -+ elif [ "$HAVE_FIND" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE ++ 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:]]*\(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 @@ -559,45 +624,85 @@ index 00000000..f34003c9 +' $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 [ "$RECHECK_WWID" = "n" ]; then ++ if [ "$HAVE_RECHECK_WWID" = 1 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(yes\|1\)/ recheck_wwid no/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$RECHECK_WWID" = "y" ]; then ++ if [ -z "$HAVE_RECHECK_WWID" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ recheck_wwid yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_RECHECK_WWID" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*recheck_wwid[[:space:]][[:space:]]*\(no\|0\)/ recheck_wwid 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 -+ if [ -z "$HAVE_PROPERTY" ]; then ++ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then ++ cat >> $TMPFILE << _EOF_ ++ ++blacklist_exceptions { ++ property "(SCSI_IDENT_|ID_WWN)" ++} ++_EOF_ ++ CHANGED_CONFIG=1 ++ elif [ -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 ++ 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 + ++if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then ++ if [ -z "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ '"$OPTION_NAME"' '"$OPTION_VALUE"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_OPTION" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE ++ CHANGED_CONFIG=1 ++fi ++ +if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then @@ -630,10 +735,10 @@ index 00000000..f34003c9 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..b82961d6 +index 00000000..ea025f31 --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,135 @@ +@@ -0,0 +1,151 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -674,12 +779,12 @@ index 00000000..b82961d6 +already exists, mpathconf will edit it. If it does not exist, mpathconf will +create a default file with +.B user_friendly_names -+and ++set and +.B find_multipaths -+set. To disable these, use the ++set to \fBon\fP. To disable these, use the +.B --user_friendly_names n +and -+.B --find_multipaths n ++.B --find_multipaths off +options +.SH COMMANDS +.TP @@ -713,13 +818,22 @@ index 00000000..b82961d6 +defaults section. If set to \fBn\fP, this removes the line, if present. This +command can be used along with any other command. +.TP -+.B --find_multipaths\fP { \fBy\fP | \fBn\fP } ++.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } +If set to \fBy\fP, this adds the line -+.B find_multipaths yes ++.B recheck_wwid 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. ++defaults section, or sets an existing line to \fByes\fP. If set to \fBn\fP, this ++sets an existing \fBrecheck_wwid\fP line to \fBno\fP. This command can be used ++along with any other command. ++.TP ++.B --find_multipaths\fP { \fBon\fP | \fByes\fP | \fBy\fP | \fBoff\fP | \fBno\fP | \fBn\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 @@ -730,11 +844,18 @@ index 00000000..b82961d6 +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 "^$" ++If set to \fBy\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 ++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 --option \fB:[]\fP ++Sets the defaults section option \fB\fP to \fB\fP. If the ++option was not previously set in the defaults section, it is added. If it was ++set, its value is changed to \fB\fP. If \fB\fP is left blank, ++then the option is removed from the defaults section, if was set there. This +command can be used along with any other command. +.TP +.B --outfile \fB\fP @@ -769,6 +890,3 @@ index 00000000..b82961d6 +.BR service (8), +.SH AUTHOR +Benjamin Marzinski --- -2.17.2 - diff --git a/SOURCES/0016-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 61% rename from SOURCES/0016-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index fb0d281..9884258 100644 --- a/SOURCES/0016-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -14,23 +14,38 @@ multipathd.service Signed-off-by: Benjamin Marzinski --- - libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++ - libmultipath/wwids.h | 1 + - multipath/main.c | 10 ++++++-- - multipath/multipath.8 | 7 +++++- - multipathd/multipathd.service | 1 + - 5 files changed, 60 insertions(+), 3 deletions(-) + multipath/main.c | 54 ++++++++++++++++++++++++++++++-- + multipath/multipath.8.in | 7 ++++- + multipathd/multipathd.service.in | 1 + + 3 files changed, 59 insertions(+), 3 deletions(-) -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 28a2150d..fab6fc8f 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -454,3 +454,47 @@ int op ## _wwid(const char *wwid) \ - declare_failed_wwid_op(is_failed, false) - declare_failed_wwid_op(mark_failed, true) - declare_failed_wwid_op(unmark_failed, true) -+ -+int remember_cmdline_wwid(void) +diff --git a/multipath/main.c b/multipath/main.c +index c21e3e0b..3f3ac9fb 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -120,7 +120,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); +@@ -134,6 +134,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" +@@ -448,6 +450,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; @@ -73,50 +88,20 @@ index 28a2150d..fab6fc8f 100644 + } + return ret; +} -diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h -index 0c6ee54d..e32a0b0e 100644 ---- a/libmultipath/wwids.h -+++ b/libmultipath/wwids.h -@@ -17,6 +17,7 @@ int remember_wwid(char *wwid); - int check_wwids_file(char *wwid, int write_wwid); - int remove_wwid(char *wwid); - int replace_wwids(vector mp); -+int remember_cmdline_wwid(void); - - enum { - WWID_IS_NOT_FAILED = 0, -diff --git a/multipath/main.c b/multipath/main.c -index cf9d2a28..78822ee1 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -138,7 +138,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); -@@ -151,6 +151,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" -@@ -907,7 +909,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) +@@ -861,7 +907,7 @@ main (int argc, char *argv[]) + condlog(1, "failed to register cleanup handler for vecs: %m"); + if (atexit(cleanup_bindings)) + condlog(1, "failed to register cleanup handler for bindings: %m"); +- 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; -@@ -977,6 +979,10 @@ main (int argc, char *argv[]) + case 'v': + if (!isdigit(optarg[0])) { +@@ -932,6 +978,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -127,11 +112,11 @@ index cf9d2a28..78822ee1 100644 case 'h': usage(argv[0]); exit(RTVL_OK); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 9cdd05a3..8befc45a 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. +diff --git a/multipath/multipath.8.in b/multipath/multipath.8.in +index b88e9a4c..edd742aa 100644 +--- a/multipath/multipath.8.in ++++ b/multipath/multipath.8.in +@@ -64,7 +64,7 @@ multipath \- Device mapper target autoconfig. .B multipath .RB [\| \-v\ \c .IR level \|] @@ -140,7 +125,7 @@ index 9cdd05a3..8befc45a 100644 . .LP .B multipath -@@ -145,6 +145,11 @@ device mapper, path checkers ...). +@@ -146,6 +146,11 @@ device mapper, path checkers ...). Add the WWID for the specified device to the WWIDs file. . .TP @@ -152,18 +137,15 @@ index 9cdd05a3..8befc45a 100644 .B \-w Remove the WWID for the specified device from the WWIDs file. . -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 17434cef..0fbcc46b 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -15,6 +15,7 @@ Type=notify +diff --git a/multipathd/multipathd.service.in b/multipathd/multipathd.service.in +index 01ceff7d..e0c2011b 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -17,6 +17,7 @@ ConditionVirtualization=!container + [Service] + 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 --- -2.17.2 - diff --git a/SOURCES/0018-RH-reset-default-find_mutipaths-value-to-off.patch b/0009-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 56% rename from SOURCES/0018-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0009-RH-reset-default-find_mutipaths-value-to-off.patch index 2e53cd9..04ad52c 100644 --- a/SOURCES/0018-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0009-RH-reset-default-find_mutipaths-value-to-off.patch @@ -6,16 +6,18 @@ 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". +Co-authored-by: Paul Donohue Signed-off-by: Benjamin Marzinski --- - libmultipath/defaults.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + libmultipath/defaults.h | 2 +- + multipath/multipath.conf.5.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index e5ee6afe..52fe05b9 100644 +index ed08c251..4b033ff9 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -22,7 +22,7 @@ +@@ -23,7 +23,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -24,6 +26,16 @@ index e5ee6afe..52fe05b9 100644 #define DEFAULT_FAST_IO_FAIL 5 #define DEFAULT_DEV_LOSS_TMO 600 #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON --- -2.17.2 - +diff --git a/multipath/multipath.conf.5.in b/multipath/multipath.conf.5.in +index 645e8f88..a7543939 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1225,7 +1225,7 @@ as non-multipath and passed on to upper layers. + \fBNote:\fR this may cause delays during device detection if + there are single-path devices which aren\'t blacklisted. + .TP +-The default is: \fBstrict\fR ++The default is: \fBoff\fR + .RE + . + . diff --git a/SOURCES/0020-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0010-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 94% rename from SOURCES/0020-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0010-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 14b3367..1f94eb3 100644 --- a/SOURCES/0020-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0010-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index b5c7873d..e139360c 100644 +index e9827dca..80a32aa3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c @@ -24,6 +24,7 @@ @@ -68,7 +68,7 @@ index b5c7873d..e139360c 100644 static int get_ana_info(struct path * pp) { int rc; -@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, +@@ -209,8 +233,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args) if (pp->fd < 0) rc = -ANA_ERR_NO_INFORMATION; @@ -82,6 +82,3 @@ index b5c7873d..e139360c 100644 switch (rc) { case NVME_ANA_OPTIMIZED: --- -2.17.2 - diff --git a/0011-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0011-RH-make-parse_vpd_pg83-match-scsi_id-output.patch new file mode 100644 index 0000000..c090da0 --- /dev/null +++ b/0011-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -0,0 +1,96 @@ +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 | 12 ++---------- + tests/vpd.c | 6 ++++++ + 2 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index e2052422..3bcd94ce 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1221,13 +1221,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + good_len = 8; + break; + case 2: +- /* IEEE Extended: Prio 6 */ +- new_prio = 6; +- good_len = 8; +- break; + case 3: +- /* IEEE Locally assigned: Prio 1 */ +- new_prio = 1; ++ /* IEEE Extended or Locally assigned: Prio 6 */ ++ new_prio = 6; + good_len = 8; + break; + default: +@@ -1245,10 +1241,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + break; + case 0x8: + /* SCSI Name: Prio 3 */ +- invalid = (d[3] < 4 || (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4))); +- new_prio = 3; + break; + case 0x1: + /* T-10 Vendor ID: Prio 2 */ +diff --git a/tests/vpd.c b/tests/vpd.c +index e3212e61..cdb111bb 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -232,11 +232,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. +@@ -767,6 +769,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) +@@ -802,6 +805,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) + { +@@ -910,6 +914,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), +@@ -934,6 +939,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/0012-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0012-RH-add-scsi-device-handlers-to-modules-load.d.patch new file mode 100644 index 0000000..7624c5b --- /dev/null +++ b/0012-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Mar 2022 18:12:06 -0500 +Subject: [PATCH] RH: add scsi device handlers to modules-load.d + +Make scsi_dh_alua scsi_dh_emc and scsi_dh_rdac get loaded in early boot. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 94e0ec85..49514b06 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -16,7 +16,7 @@ READLINE := + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac +-SCSI_DH_MODULES_PRELOAD := ++SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_emc scsi_dh_rdac + + EXTRAVERSION := $(shell rev=$$(git rev-parse --short=7 HEAD 2>/dev/null); echo $${rev:+-g$$rev}) + diff --git a/0013-RH-compile-with-libreadline-support.patch b/0013-RH-compile-with-libreadline-support.patch new file mode 100644 index 0000000..eb0ab13 --- /dev/null +++ b/0013-RH-compile-with-libreadline-support.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 15 Nov 2022 18:03:33 -0600 +Subject: [PATCH] RH: compile with libreadline support + +Since the license issue has been resolved, and there are problems with +the command completion with libedit, use libreadline. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 49514b06..a3ed9f28 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -12,7 +12,7 @@ + # Readline library to use, libedit, libreadline, or empty + # Caution: Using libreadline may make the multipathd binary undistributable, + # see https://github.com/opensvc/multipath-tools/issues/36 +-READLINE := ++READLINE := libreadline + + # List of scsi device handler modules to load on boot, e.g. + # SCSI_DH_MODULES_PRELOAD := scsi_dh_alua scsi_dh_rdac diff --git a/0014-RH-Add-mpathcleanup.patch b/0014-RH-Add-mpathcleanup.patch new file mode 100644 index 0000000..bd2dcd6 --- /dev/null +++ b/0014-RH-Add-mpathcleanup.patch @@ -0,0 +1,186 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 7 Jul 2023 15:25:59 -0500 +Subject: [PATCH] RH: Add mpathcleanup + +mpathcleanup is a program that will remove a multipath device as well as +all of the scsi path devices that make it up. + +Signed-off-by: Benjamin Marzinski +--- + multipath/Makefile | 2 + + multipath/mpathcleanup | 145 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 147 insertions(+) + create mode 100755 multipath/mpathcleanup + +diff --git a/multipath/Makefile b/multipath/Makefile +index 3dc241cc..47e82234 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -25,6 +25,7 @@ install: + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(Q)$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ ++ $(Q)$(INSTALL_PROGRAM) -m 755 mpathcleanup $(DESTDIR)$(bindir)/ + $(Q)$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(Q)$(INSTALL_PROGRAM) -m 644 99-z-dm-mpath-late.rules $(DESTDIR)$(udevrulesdir) +@@ -49,6 +50,7 @@ endif + uninstall: + $(Q)$(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(Q)$(RM) $(DESTDIR)$(bindir)/mpathconf ++ $(Q)$(RM) $(DESTDIR)$(bindir)/mpathcleanup + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(Q)$(RM) $(DESTDIR)$(udevrulesdir)/99-z-dm-mpath-late.rules + $(Q)$(RM) $(DESTDIR)$(modulesloaddir)/multipath.conf +diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup +new file mode 100755 +index 00000000..6fd921e4 +--- /dev/null ++++ b/multipath/mpathcleanup +@@ -0,0 +1,145 @@ ++#!/bin/bash ++# ++# Copyright (C) 2023 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 ++ ++unset PROGRAM FLUSH DEVICE DEVNAME MAJOR MINOR PATHDEVS PATHDEV HAVE_MULTIPATHD QUEUEING ++ ++function usage ++{ ++ echo "usage: $PROGRAM [-h] [--flush] " ++ echo "" ++ echo "remove a multipath device and its scsi path devices" ++ echo "" ++ echo "options:" ++ echo " -h, --help show this help message and exit" ++ echo " --flush disable queuing on the multipath device and" ++ echo " flush the path devices before removing" ++} ++ ++function parse_args ++{ ++ while [ -n "$1" ]; do ++ case $1 in ++ --flush) ++ FLUSH=1 ++ shift ++ ;; ++ --help | -h) ++ usage ++ exit 1 ++ ;; ++ *) ++ if [ -n "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ DEVICE=$1 ++ shift ++ ;; ++ esac ++ done ++} ++ ++function validate_device ++{ ++ if [ -z "$DEVICE" ]; then ++ usage ++ exit 1 ++ fi ++ if [[ "$DEVICE" =~ ^[[:digit:]]+:[[:digit:]]+$ ]]; then ++ MAJOR=${DEVICE%%:*} ++ MINOR=${DEVICE##*:} ++ DEVNAME=`dmsetup ls --target multipath | grep "($MAJOR, $MINOR)$" | awk '{print $1}'` ++ else ++ DEVNAME=`dmsetup ls --target multipath | awk '{print $1}' | grep "^$DEVICE$"` ++ fi ++ if [ -z "$DEVNAME" ]; then ++ DEVNAME=`multipath -v 1 -l $DEVICE 2>/dev/null` ++ if [ -z "$DEVNAME" ]; then ++ echo "$DEVICE is not a multipath device" ++ exit 1 ++ fi ++ # verify that this is not a native nvme multipath device ++ dmsetup ls --target multipath | awk '{print $1}' | grep -q "^$DEVNAME$" ++ if test $? -eq 1; then ++ echo "$DEVICE is not a device-mapper multipath device" ++ exit 1 ++ fi ++ fi ++ if [ -z "$MINOR" ]; then ++ MINOR=`dmsetup info -c --noheadings -o minor $DEVNAME` ++ fi ++} ++ ++function get_paths ++{ ++ PATHDEVS=`ls /sys/block/dm-$MINOR/slaves` ++ for PATHDEV in $PATHDEVS; do ++ if [[ ! "$PATHDEV" =~ ^sd[a-z]+$ ]]; then ++ echo "$PATHDEV is not a scsi device. $PROGRAM only works with scsi devices" ++ exit 1 ++ fi ++ done ++} ++ ++function remove_devs ++{ ++ pidof multipathd > /dev/null ++ HAVE_MULTIPATHD=$? ++ multipath -v2 -l "$DEVNAME" | grep features | grep -q queue_if_no_path ++ QUEUEING=$? ++ if [ -n "$FLUSH" ] && [ "$QUEUEING" -eq 0 ]; then ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipathd disablequeueing map "$DEVNAME" > /dev/null ++ else ++ dmsetup message "$DEVNAME" 0 fail_if_no_path ++ fi ++ sleep 1 ++ fi ++ if test $HAVE_MULTIPATHD -eq 0; then ++ multipath -f "$DEVNAME" ++ else ++ multipathd -Df "$DEVNAME" ++ fi ++ if test $? -eq 1; then ++ echo "$DEVICE cannot be removed" ++ exit 1 ++ fi ++ for PATHDEV in $PATHDEVS; do ++ if [ -n "$FLUSH" ]; then ++ blockdev --flushbufs /dev/"$PATHDEV" ++ fi ++ echo 1 > /sys/block/"$PATHDEV"/device/delete ++ done ++} ++ ++function verify_removal ++{ ++ multipath -v 1 -d $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removed but path devices still exist" ++ exit 1 ++ fi ++ multipath -v 1 -l $DEVNAME | grep -q "^$DEVNAME$" ++ if test $? -eq 0; then ++ echo "$DEVICE removal succeeded, but device still exists" ++ exit 1 ++ fi ++} ++ ++PROGRAM="$0" ++parse_args "$@" ++validate_device ++get_paths ++remove_devs ++verify_removal diff --git a/0015-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch b/0015-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch new file mode 100644 index 0000000..b112cad --- /dev/null +++ b/0015-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 7 Aug 2024 18:59:10 -0400 +Subject: [PATCH] libmultipath: fix ontap prioritizer snprintf limits + +The ontap prioritizer functions dump_cdb() and process_sg_error() both +incorrectly set the snprintf() limits larger than the available space. +Instead of multiplying the number of elements to print by the size of an +element to calculate the limit, they multiplied the number of elements +to print by the maximum number of elements that the buffer could hold. + +Fix this by making these functions use strbufs instead. + +mwilck: removed log message in print_strbuf() failure case. + +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Signed-off-by: Martin Wilck +--- + libmultipath/prioritizers/ontap.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/libmultipath/prioritizers/ontap.c b/libmultipath/prioritizers/ontap.c +index 117886ea..90eaf274 100644 +--- a/libmultipath/prioritizers/ontap.c ++++ b/libmultipath/prioritizers/ontap.c +@@ -23,6 +23,7 @@ + #include "prio.h" + #include "structs.h" + #include "unaligned.h" ++#include "strbuf.h" + + #define INQUIRY_CMD 0x12 + #define INQUIRY_CMDLEN 6 +@@ -35,32 +36,29 @@ + static void dump_cdb(unsigned char *cdb, int size) + { + int i; +- char buf[10*5+1]; +- char * p = &buf[0]; ++ STRBUF_ON_STACK(buf); + +- condlog(0, "- SCSI CDB: "); +- for (i=0; imasked_status, + io_hdr->host_status, io_hdr->driver_status); + if (io_hdr->sb_len_wr > 0) { +- condlog(0, "- SCSI sense data: "); +- for (i=0; isb_len_wr; i++) { +- p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ", +- io_hdr->sbp[i]); ++ for (i = 0; i < io_hdr->sb_len_wr; i++) { ++ if (print_strbuf(&buf, "0x%02x ", io_hdr->sbp[i]) < 0) ++ return; + } +- condlog(0, "%s", buf); ++ condlog(0, "- SCSI sense data: %s", get_strbuf_str(&buf)); + } + } + diff --git a/0016-multipathd-checker-port_state-before-setting-it.patch b/0016-multipathd-checker-port_state-before-setting-it.patch new file mode 100644 index 0000000..32b7397 --- /dev/null +++ b/0016-multipathd-checker-port_state-before-setting-it.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 16 Sep 2024 19:29:13 -0400 +Subject: [PATCH] multipathd: checker port_state before setting it. + +If the rport port_state is already Marginal, trying to set it to +Marginal causes an error like the following: + +multipathd[365376]: /sys/devices/pci0000:c0/0000:c0:01.1/0000:c4:00.0/host0/rport-0:0-5/fc_remote_ports/rport-0:0-5: failed to set port_state to marginal: Invalid argument + +To avoid causing this confusing error message, check if the port_state +is already marginal before trying to set it. + +Cc: Muneendra Kumar +Signed-off-by: Benjamin Marzinski +--- + multipathd/fpin_handlers.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +index be087ca0..6b56f9b7 100644 +--- a/multipathd/fpin_handlers.c ++++ b/multipathd/fpin_handlers.c +@@ -169,9 +169,14 @@ fpin_els_add_li_frame(struct fc_nl_event *fc_event) + /*Sets the rport port_state to marginal*/ + static void fpin_set_rport_marginal(struct udev_device *rport_dev) + { ++ char old_value[20]; /* match kernel show_fc_rport_port_state() size */ + static const char marginal[] = "Marginal"; + ssize_t ret; + ++ ret = sysfs_attr_get_value(rport_dev, "port_state", ++ old_value, sizeof(old_value)); ++ if (ret == sizeof(marginal) - 1 && strcmp(old_value, marginal) == 0) ++ return; + ret = sysfs_attr_set_value(rport_dev, "port_state", + marginal, sizeof(marginal) - 1); + if (ret != sizeof(marginal) - 1) diff --git a/SOURCES/0138-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch b/0017-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch similarity index 87% rename from SOURCES/0138-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch rename to 0017-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch index 7d2c1d3..ec9ed2b 100644 --- a/SOURCES/0138-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +++ b/0017-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 5feb1e95..1d48b08d 100644 +index 6f2d8800..235306ff 100644 --- a/libmultipath/foreign/nvme.c +++ b/libmultipath/foreign/nvme.c -@@ -697,6 +697,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) +@@ -708,6 +708,7 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) path = _find_path_by_syspath(map, udev_device_get_syspath(udev)); if (path != NULL) { @@ -23,7 +23,7 @@ index 5feb1e95..1d48b08d 100644 path->seen = true; condlog(4, "%s: %s already known", __func__, fn); -@@ -704,8 +705,10 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) +@@ -715,8 +716,10 @@ static void _find_controllers(struct context *ctx, struct nvme_map *map) } path = calloc(1, sizeof(*path)); diff --git a/SOURCES/0001-libmultipath-assign-variable-to-make-gcc-happy.patch b/SOURCES/0001-libmultipath-assign-variable-to-make-gcc-happy.patch deleted file mode 100644 index 06de678..0000000 --- a/SOURCES/0001-libmultipath-assign-variable-to-make-gcc-happy.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 17 Mar 2020 17:28:24 -0500 -Subject: [PATCH] libmultipath: assign variable to make gcc happy -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There is nothing wrong with is_queueing not being set at the start -of __set_no_path_retry(), it will always get set before it is accessed, -but gcc 8.2.1 is failing with - -structs_vec.c: In function ‘__set_no_path_retry’: -structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in -this function [-Werror=maybe-uninitialized] - bool is_queueing; - ^~~~~~~~~~~ - -so, assign a value to make it happy. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 3dbbaa0f..077f2e42 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp) - - void __set_no_path_retry(struct multipath *mpp, bool check_features) - { -- bool is_queueing; -+ bool is_queueing = false; /* assign a value to make gcc happy */ - - check_features = check_features && mpp->features != NULL; - if (check_features) --- -2.17.2 - diff --git a/SOURCES/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/SOURCES/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch deleted file mode 100644 index 9a1ce41..0000000 --- a/SOURCES/0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Sat, 21 Mar 2020 23:49:59 -0500 -Subject: [PATCH] libmutipath: don't close fd on dm_lib_release - -If dm_hold_control_open() isn't set, when dm_lib_release() is called, it -will close the control fd. The control fd will get re-opened on the next -dm_task_run() call, but if there is a dm_task_run() call already -in progress in another thread, it can fail. Since many of the -device-mapper callouts happen with the vecs lock held, this wasn't too -noticeable, but there is code that calls dm_task_run() without the -vecs lock held, notably the dmevent waiter code. - -Since, as Martin pointed out, dm_hold_control_open() hasn't always -existed in libdevmapper, check if it's supported on compilation, -and update the version requirements if so. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 4 ++++ - libmultipath/devmapper.c | 7 ++++++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index e5651e49..ad690a49 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0) - CFLAGS += -DLIBDM_API_DEFERRED - endif - -+ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) -+ CFLAGS += -DLIBDM_API_HOLD_CONTROL -+endif -+ - OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - hwtable.o blacklist.o util.o dmparser.o config.o \ - structs.o discovery.o propsel.o dict.o \ -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index bed8ddc6..13a1cf53 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -108,7 +108,9 @@ dm_lib_prereq (void) - { - char version[64]; - int v[3]; --#if defined(LIBDM_API_DEFERRED) -+#if defined(LIBDM_API_HOLD_CONTROL) -+ int minv[3] = {1, 2, 111}; -+#elif defined(LIBDM_API_DEFERRED) - int minv[3] = {1, 2, 89}; - #elif defined(DM_SUBSYSTEM_UDEV_FLAG0) - int minv[3] = {1, 2, 82}; -@@ -254,6 +256,9 @@ void libmp_dm_init(void) - memcpy(conf->version, version, sizeof(version)); - put_multipath_config(conf); - dm_init(verbosity); -+#ifdef LIBDM_API_HOLD_CONTROL -+ dm_hold_control_dev(1); -+#endif - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - --- -2.17.2 - diff --git a/SOURCES/0003-libmultipath-allow-force-reload-with-no-active-paths.patch b/SOURCES/0003-libmultipath-allow-force-reload-with-no-active-paths.patch deleted file mode 100644 index a6efaaa..0000000 --- a/SOURCES/0003-libmultipath-allow-force-reload-with-no-active-paths.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 19 Mar 2020 22:17:51 -0500 -Subject: [PATCH] libmultipath: allow force reload with no active paths - -If the partition information has changed on multipath devices (say, -because it was updated on another node that has access to the same -storage), users expect that running "multipathd reconfigure" will update -that. However, if the checkers for the multipath device are pending for -too long when the the device is reconfigured, multipathd will give up -waiting for them, and refuse to reload the device, since there are no -active paths. This means that no kpartx update will be triggered. - -Multipath is fully capable of reloading a multipath device that has no -active paths. This has been possible for years. If multipath is supposed -to reload the device, it should do so, even if there are no active paths. - -Generally, when multipath is force reloaded, kpartx will be updated. -However when a device is reloaded with no paths, the udev rules won't -run kpartx. But they also weren't running kpartx when the first valid -path appeared, even though the dm activation rules get run in this case. -This changes 11-dm-mpath.rules to run kpartx when a device goes from no -usable paths to having usable paths. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 6 ------ - multipath/11-dm-mpath.rules | 2 +- - 2 files changed, 1 insertion(+), 7 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index c95848a0..96c79610 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - return; - } - -- if (pathcount(mpp, PATH_UP) == 0) { -- mpp->action = ACT_IMPOSSIBLE; -- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)", -- mpp->alias); -- return; -- } - if (force_reload) { - mpp->force_udev_reload = 1; - mpp->action = ACT_RELOAD; -diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules -index 07320a14..cd522e8c 100644 ---- a/multipath/11-dm-mpath.rules -+++ b/multipath/11-dm-mpath.rules -@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" - ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\ - ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\ - ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\ -- ENV{DM_ACTIVATION}="1" -+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0" - - # The code to check multipath state ends here. We need to set - # properties and symlinks regardless whether the map is usable or --- -2.17.2 - diff --git a/SOURCES/0004-libmpathpersist-depend-on-libmultipath.patch b/SOURCES/0004-libmpathpersist-depend-on-libmultipath.patch deleted file mode 100644 index 47aad9b..0000000 --- a/SOURCES/0004-libmpathpersist-depend-on-libmultipath.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Christian Hesse -Date: Wed, 6 May 2020 09:35:47 +0200 -Subject: [PATCH] libmpathpersist: depend on libmultipath - -Without this the build fails with: - -/usr/bin/ld: cannot find -lmultipath - -Signed-off-by: Christian Hesse -Signed-off-by: Benjamin Marzinski ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index 1dee3680..ba1d73ba 100644 ---- a/Makefile -+++ b/Makefile -@@ -28,7 +28,7 @@ all: $(BUILDDIRS) - $(BUILDDIRS): - $(MAKE) -C $@ - --multipath multipathd mpathpersist: libmultipath -+libmpathpersist multipath multipathd mpathpersist: libmultipath - mpathpersist: libmpathpersist - - $(BUILDDIRS.clean): --- -2.17.2 - diff --git a/SOURCES/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/SOURCES/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch deleted file mode 100644 index c75ba30..0000000 --- a/SOURCES/0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:39:21 +0200 -Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel - build - -Extend the late fixes from Christian. - -Cc: Christian Hesse -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index ba1d73ba..fec3b73b 100644 ---- a/Makefile -+++ b/Makefile -@@ -28,8 +28,9 @@ all: $(BUILDDIRS) - $(BUILDDIRS): - $(MAKE) -C $@ - --libmpathpersist multipath multipathd mpathpersist: libmultipath --mpathpersist: libmpathpersist -+libmultipath libdmmp: libmpathcmd -+libmpathpersist multipath multipathd: libmultipath -+mpathpersist multipathd: libmpathpersist - - $(BUILDDIRS.clean): - $(MAKE) -C ${@:.clean=} clean --- -2.17.2 - diff --git a/SOURCES/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/SOURCES/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch deleted file mode 100644 index 1ad917f..0000000 --- a/SOURCES/0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:39:24 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered - -We need to ignore -Wclobbered because gcc has trouble dealing with glibc's -implementation of pthread_cleanup_push(). - -For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also -set. Compilation with -Wno-error=clobbered works, though. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index d4d1e0dd..9060ac9b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \ - - 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,) -+WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - - OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ --- -2.17.2 - diff --git a/SOURCES/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/SOURCES/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch deleted file mode 100644 index b24cca6..0000000 --- a/SOURCES/0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:39:25 +0200 -Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t - -Otherwise compilation for 32bit targets spits out warnings. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ee3290cd..ffec5162 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len) - } - - if (len >= out_len) { -- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required", -+ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required", - len + 1, out_len); - len = out_len - 1; - } -@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - - len = sprintf(out, "%d", vpd_type); - if (2 * vpd_len >= out_len - len) { -- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required", - __func__, vpd_type, - 2 * vpd_len + len + 1, out_len); - vpd_len = (out_len - len - 1) / 2; -@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - len += sprintf(out + len, - "%02x", vpd[i]); - } else if (vpd_type == 0x8 && vpd_len < 4) { -- condlog(1, "%s: VPD length %lu too small for designator type 8", -+ condlog(1, "%s: VPD length %zu too small for designator type 8", - __func__, vpd_len); - return -EINVAL; - } else if (vpd_type == 0x8) { -@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - while (len > 2 && vpd[len - 2] == '\0') - --len; - if (len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required", - __func__, out[0], len + 1, out_len); - len = out_len - 1; - } -@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - while ((p = memchr(vpd, ' ', vpd_len))) { - p_len = p - vpd; - if (len + p_len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", - __func__, len + p_len, out_len); - p_len = out_len - len - 1; - } -@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - p_len = vpd_len; - if (p_len > 0 && len < out_len - 1) { - if (len + p_len > out_len - 1) { -- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required", -+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required", - __func__, len + p_len + 1, out_len); - p_len = out_len - len - 1; - } -@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len, - - memset(out, 0x0, out_len); - if (in_len <= 4 || (in[4] > 3 && in_len < 44)) { -- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len); -+ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len); - return -EINVAL; - } - if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */ - return -ENODATA; - len = get_unaligned_be32(&in[40]); - if (len > out_len || len + 44 > in_len) { -- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu", -+ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu", - len); - return -EINVAL; - } --- -2.17.2 - diff --git a/SOURCES/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/SOURCES/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch deleted file mode 100644 index ac5b284..0000000 --- a/SOURCES/0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:39:26 +0200 -Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons - -Fix some more compiler warnings about signed/unsigned comparison. -I've observed these only on 32bit builds, therefore they went unnoticed -before. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 12 ++++++------ - libmultipath/prioritizers/alua_spc3.h | 2 +- - multipathd/cli_handlers.c | 20 ++++++++++---------- - multipathd/main.c | 2 +- - 4 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index b944ef32..298b3764 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len, - } - - c = reply + snprint_defaults(conf, reply, maxlen); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_blacklist(conf, c, reply + maxlen - c); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_blacklist_except(conf, c, reply + maxlen - c); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_hwtable(conf, c, reply + maxlen - c, - hwtable ? hwtable : conf->hwtable); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - c += snprint_overrides(conf, c, reply + maxlen - c, - conf->overrides); -- if ((c - reply) == maxlen) -+ if (c == reply + maxlen) - continue; - - if (VECTOR_SIZE(conf->mptable) > 0 || -@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len, - c += snprint_mptable(conf, c, reply + maxlen - c, - mpvec); - -- if ((c - reply) < maxlen) { -+ if (c < reply + maxlen) { - if (len) - *len = c - reply; - return reply; -diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h -index 18b495ef..7ba2cf4c 100644 ---- a/libmultipath/prioritizers/alua_spc3.h -+++ b/libmultipath/prioritizers/alua_spc3.h -@@ -284,7 +284,7 @@ struct rtpg_data { - #define RTPG_FOR_EACH_PORT_GROUP(p, g) \ - for( \ - g = &(p->data[0]); \ -- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \ -+ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \ - g = (struct rtpg_tpg_dscr *) ( \ - ((char *) g) + \ - sizeof(struct rtpg_tpg_dscr) + \ -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 7d878c88..31c3d9fd 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style, - c += snprint_foreign_paths(c, reply + maxlen - c, - style, pretty); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp, - - c += snprint_path(c, reply + maxlen - c, style, pp, 0); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp, - c = reply; - - c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2); -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs) - } - c += snprint_foreign_topology(c, reply + maxlen - c, 2); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs) - c = reply; - - c += snprint_multipath_topology_json(c, maxlen, vecs); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp, - c = reply; - - c += snprint_multipath_map_json(c, maxlen, mpp); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style, - c += snprint_multipath(c, reply + maxlen - c, style, - mpp, pretty); - -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style, - } - c += snprint_foreign_multipaths(c, reply + maxlen - c, - style, pretty); -- again = ((c - reply) == (maxlen - 1)); -+ again = (c == reply + maxlen - 1); - - REALLOC_REPLY(reply, again, maxlen); - } -@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len) - - c = reply; - c += snprint_blacklist_report(conf, c, maxlen); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - REALLOC_REPLY(reply, again, maxlen); - } - pthread_cleanup_pop(1); -@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs) - - c = reply; - c += snprint_devices(conf, c, maxlen, vecs); -- again = ((c - reply) == maxlen); -+ again = (c == reply + maxlen); - REALLOC_REPLY(reply, again, maxlen); - } - pthread_cleanup_pop(1); -diff --git a/multipathd/main.c b/multipathd/main.c -index 8baf9abe..6b7db2c0 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2374,7 +2374,7 @@ checkerloop (void *ap) - conf = get_multipath_config(); - max_checkint = conf->max_checkint; - put_multipath_config(conf); -- if (diff_time.tv_sec > max_checkint) -+ if (diff_time.tv_sec > (time_t)max_checkint) - condlog(1, "path checkers took longer " - "than %lu seconds, consider " - "increasing max_polling_interval", --- -2.17.2 - diff --git a/SOURCES/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch b/SOURCES/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch deleted file mode 100644 index 25f83c3..0000000 --- a/SOURCES/0009-libmultipath-set_uint-fix-parsing-for-32bit.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:39:27 +0200 -Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit - -On architectures where sizeof(long) == sizeof(int), the code wouldn't -work as intended. Use strtoul instead. As strtoul happily parses -negative numbers as input, require the number to begin with a digit. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 3e25e74f..0e9ea387 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -60,19 +60,22 @@ static int - set_uint(vector strvec, void *ptr) - { - unsigned int *uint_ptr = (unsigned int *)ptr; -- char *buff, *eptr; -- long res; -+ char *buff, *eptr, *p; -+ unsigned long res; - int rc; - - buff = set_value(strvec); - if (!buff) - return 1; - -- res = strtol(buff, &eptr, 10); -+ p = buff; -+ while (isspace(*p)) -+ p++; -+ res = strtoul(p, &eptr, 10); - if (eptr > buff) - while (isspace(*eptr)) - eptr++; -- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) { -+ 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); - rc = 1; --- -2.17.2 - diff --git a/SOURCES/0010-multipath-tools-Makefile-add-install-dependency.patch b/SOURCES/0010-multipath-tools-Makefile-add-install-dependency.patch deleted file mode 100644 index ee1da02..0000000 --- a/SOURCES/0010-multipath-tools-Makefile-add-install-dependency.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 22:38:22 +0200 -Subject: [PATCH] multipath-tools Makefile: add install dependency - -$(libdir) must exist before running "make install" on prioritizer, checker, -and foreign libraries. - -Cc: Christian Hesse -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/Makefile b/Makefile -index fec3b73b..8bcaba66 100644 ---- a/Makefile -+++ b/Makefile -@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd - libmpathpersist multipath multipathd: libmultipath - mpathpersist multipathd: libmpathpersist - -+libmultipath/checkers.install \ -+ libmultipath/prioritizers.install \ -+ libmultipath/foreign.install: libmultipath.install -+ - $(BUILDDIRS.clean): - $(MAKE) -C ${@:.clean=} clean - --- -2.17.2 - diff --git a/SOURCES/0011-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0011-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index 1a8e108..0000000 --- a/SOURCES/0011-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,66 +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 9060ac9b..034752d9 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -53,7 +53,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 8f990494..8a3a1718 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end" - GOTO="kpartx_end" - - LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - - LABEL="kpartx_end" -diff --git a/multipath/Makefile b/multipath/Makefile -index 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 - --- -2.17.2 - diff --git a/SOURCES/0013-RH-don-t-start-without-a-config-file.patch b/SOURCES/0013-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index 86cdf68..0000000 --- a/SOURCES/0013-RH-don-t-start-without-a-config-file.patch +++ /dev/null @@ -1,106 +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 | 15 +++++++++++++++ - libmultipath/config.h | 1 + - multipath/multipath.rules | 1 + - multipathd/multipathd.8 | 2 ++ - multipathd/multipathd.service | 1 + - 5 files changed, 20 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index b4d87689..b36778b0 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -26,6 +26,7 @@ - #include "devmapper.h" - #include "mpath_cmd.h" - #include "propsel.h" -+#include "version.h" - - static int - hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) -@@ -778,6 +779,20 @@ load_config (char * file) - 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, strdup(".*"), -+ ORIGIN_NO_CONFIG)) { -+ condlog(0, "cannot store default no-config blacklist\n"); -+ goto out; -+ } - } - - conf->processed_main_config = 1; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index ceecff2d..3368d8c9 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -9,6 +9,7 @@ - - #define ORIGIN_DEFAULT 0 - #define ORIGIN_CONFIG 1 -+#define ORIGIN_NO_CONFIG 2 - - /* - * In kernel, fast_io_fail == 0 means immediate failure on rport delete. -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 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 ba24983e..17434cef 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 - After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service -+ConditionPathExists=/etc/multipath.conf - DefaultDependencies=no - Conflicts=shutdown.target - ConditionKernelCommandLine=!nompath --- -2.17.2 - diff --git a/SOURCES/0014-RH-use-rpm-optflags-if-present.patch b/SOURCES/0014-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index be1af2e..0000000 --- a/SOURCES/0014-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,64 +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 | 29 +++++++++++++++++++++-------- - 1 file changed, 21 insertions(+), 8 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 034752d9..c2abd301 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -89,16 +89,29 @@ 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,) -+ifndef RPM_OPT_FLAGS -+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \ -+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables -+ 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) -+endif -+OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ -+ -Werror=implicit-int -Werror=implicit-function-declaration \ -+ $(WNOCLOBBERED) \ -+ -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -+ --param=ssp-buffer-size=4 - --OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -- -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) \ -- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- $(STACKPROT) --param=ssp-buffer-size=4 --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 - CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP $(CFLAGS) - BIN_CFLAGS = -fPIE -DPIE -@@ -135,4 +148,4 @@ check_file = $(shell \ - - %.o: %.c - @echo building $@ because of $? -- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< -+ $(CC) $(CFLAGS) -c -o $@ $< --- -2.17.2 - diff --git a/SOURCES/0017-RH-warn-on-invalid-regex-instead-of-failing.patch b/SOURCES/0017-RH-warn-on-invalid-regex-instead-of-failing.patch deleted file mode 100644 index 18dd530..0000000 --- a/SOURCES/0017-RH-warn-on-invalid-regex-instead-of-failing.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Nov 2017 21:39:28 -0600 -Subject: [PATCH] RH: warn on invalid regex instead of failing - -multipath.conf used to allow "*" as a match everything regular expression, -instead of requiring ".*". Instead of erroring when the old style -regular expressions are used, it should print a warning and convert -them. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dict.c | 27 +++++++++++++++++++++------ - libmultipath/parser.c | 13 +++++++++++++ - libmultipath/parser.h | 1 + - 3 files changed, 35 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 0e9ea387..184d4b22 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -103,6 +103,21 @@ set_str(vector strvec, void *ptr) - return 0; - } - -+static int -+set_regex(vector strvec, void *ptr) -+{ -+ char **str_ptr = (char **)ptr; -+ -+ if (*str_ptr) -+ FREE(*str_ptr); -+ *str_ptr = set_regex_value(strvec); -+ -+ if (!*str_ptr) -+ return 1; -+ -+ return 0; -+} -+ - static int - set_yes_no(vector strvec, void *ptr) - { -@@ -1504,7 +1519,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1520,7 +1535,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ - if (!conf->option) \ - return 1; \ - \ -- buff = set_value(strvec); \ -+ buff = set_regex_value(strvec); \ - if (!buff) \ - return 1; \ - \ -@@ -1623,16 +1638,16 @@ device_handler(struct config *conf, vector strvec) - return 0; - } - --declare_hw_handler(vendor, set_str) -+declare_hw_handler(vendor, set_regex) - declare_hw_snprint(vendor, print_str) - --declare_hw_handler(product, set_str) -+declare_hw_handler(product, set_regex) - declare_hw_snprint(product, print_str) - --declare_hw_handler(revision, set_str) -+declare_hw_handler(revision, set_regex) - declare_hw_snprint(revision, print_str) - --declare_hw_handler(bl_product, set_str) -+declare_hw_handler(bl_product, set_regex) - declare_hw_snprint(bl_product, print_str) - - declare_hw_handler(hwhandler, set_str) -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index d478b177..a184511b 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -382,6 +382,19 @@ oom: - return NULL; - } - -+void * -+set_regex_value(vector strvec) -+{ -+ char *buff = set_value(strvec); -+ -+ if (buff && strcmp("*", buff) == 0) { -+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\""); -+ FREE(buff); -+ return strdup(".*"); -+ } -+ return buff; -+} -+ - /* non-recursive configuration stream handler */ - static int kw_level = 0; - -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 62906e98..b7917052 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level); - extern void free_keywords(vector keywords); - extern vector alloc_strvec(char *string); - extern void *set_value(vector strvec); -+extern void *set_regex_value(vector strvec); - extern int process_file(struct config *conf, char *conf_file); - extern struct keyword * find_keyword(vector keywords, vector v, char * name); - int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, --- -2.17.2 - diff --git a/SOURCES/0021-libmultipath-remove-_blacklist_exceptions-functions.patch b/SOURCES/0021-libmultipath-remove-_blacklist_exceptions-functions.patch deleted file mode 100644 index 1177dd5..0000000 --- a/SOURCES/0021-libmultipath-remove-_blacklist_exceptions-functions.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 8 Jun 2020 14:27:51 -0500 -Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions - -_blacklist_exceptions() and _blacklist_exceptions_device() are exactly -the same as _blacklist() and _blacklist_device(), so remove them, and -give the remaining functions to a more general name. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 62 ++++++++++------------------------------ - 1 file changed, 15 insertions(+), 47 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index d9691b17..04d3adb9 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - return 0; - } - --int --_blacklist_exceptions (vector elist, const char * str) --{ -- int i; -- struct blentry * ele; -- -- vector_foreach_slot (elist, ele, i) { -- if (!regexec(&ele->regex, str, 0, NULL, 0)) -- return 1; -- } -- return 0; --} -- --int --_blacklist (vector blist, const char * str) -+static int -+match_reglist (vector blist, const char * str) - { - int i; - struct blentry * ble; -@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str) - return 0; - } - --int --_blacklist_exceptions_device(const struct _vector *elist, const char * vendor, -- const char * product) --{ -- int i; -- struct blentry_device * ble; -- -- vector_foreach_slot (elist, ble, i) { -- if (!ble->vendor && !ble->product) -- continue; -- if ((!ble->vendor || -- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && -- (!ble->product || -- !regexec(&ble->product_reg, product, 0, NULL, 0))) -- return 1; -- } -- return 0; --} -- --int --_blacklist_device (const struct _vector *blist, const char * vendor, -- const char * product) -+static int -+match_reglist_device (const struct _vector *blist, const char * vendor, -+ const char * product) - { - int i; - struct blentry_device * ble; -@@ -294,9 +262,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product, - int r = MATCH_NOTHING; - - if (vendor && product) { -- if (_blacklist_exceptions_device(elist, vendor, product)) -+ if (match_reglist_device(elist, vendor, product)) - r = MATCH_DEVICE_BLIST_EXCEPT; -- else if (_blacklist_device(blist, vendor, product)) -+ else if (match_reglist_device(blist, vendor, product)) - r = MATCH_DEVICE_BLIST; - } - -@@ -310,9 +278,9 @@ filter_devnode (vector blist, vector elist, char * dev) - int r = MATCH_NOTHING; - - if (dev) { -- if (_blacklist_exceptions(elist, dev)) -+ if (match_reglist(elist, dev)) - r = MATCH_DEVNODE_BLIST_EXCEPT; -- else if (_blacklist(blist, dev)) -+ else if (match_reglist(blist, dev)) - r = MATCH_DEVNODE_BLIST; - } - -@@ -326,9 +294,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev) - int r = MATCH_NOTHING; - - if (wwid) { -- if (_blacklist_exceptions(elist, wwid)) -+ if (match_reglist(elist, wwid)) - r = MATCH_WWID_BLIST_EXCEPT; -- else if (_blacklist(blist, wwid)) -+ else if (match_reglist(blist, wwid)) - r = MATCH_WWID_BLIST; - } - -@@ -345,9 +313,9 @@ filter_protocol(vector blist, vector elist, struct path * pp) - if (pp) { - snprint_path_protocol(buf, sizeof(buf), pp); - -- if (_blacklist_exceptions(elist, buf)) -+ if (match_reglist(elist, buf)) - r = MATCH_PROTOCOL_BLIST_EXCEPT; -- else if (_blacklist(blist, buf)) -+ else if (match_reglist(blist, buf)) - r = MATCH_PROTOCOL_BLIST; - } - -@@ -417,11 +385,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, - if (check_missing_prop && !strcmp(env, uid_attribute)) - uid_attr_seen = true; - -- if (_blacklist_exceptions(conf->elist_property, env)) { -+ if (match_reglist(conf->elist_property, env)) { - r = MATCH_PROPERTY_BLIST_EXCEPT; - break; - } -- if (_blacklist(conf->blist_property, env)) { -+ if (match_reglist(conf->blist_property, env)) { - r = MATCH_PROPERTY_BLIST; - break; - } --- -2.17.2 - diff --git a/SOURCES/0022-libmultipath-fix-parser-issue-with-comments-in-strin.patch b/SOURCES/0022-libmultipath-fix-parser-issue-with-comments-in-strin.patch deleted file mode 100644 index 898826c..0000000 --- a/SOURCES/0022-libmultipath-fix-parser-issue-with-comments-in-strin.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 8 Jun 2020 20:23:56 -0500 -Subject: [PATCH] libmultipath: fix parser issue with comments in strings - -If a quoted string starts with '#' or '!', the parser will stop -parsing the line, thinking that it's a comment. It should only -be checking for comments outside of quoted strings. Fixed this and -added unit tests to verify it. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/parser.c | 4 +++- - tests/parser.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 45 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index a184511b..a7285a35 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -300,8 +300,10 @@ alloc_strvec(char *string) - (isspace((int) *cp) || !isascii((int) *cp))) - && *cp != '\0') - cp++; -- if (*cp == '\0' || *cp == '!' || *cp == '#') -+ if (*cp == '\0' || -+ (!in_string && (*cp == '!' || *cp == '#'))) { - return strvec; -+ } - } - out: - vector_free(strvec); -diff --git a/tests/parser.c b/tests/parser.c -index 29859dac..5772391e 100644 ---- a/tests/parser.c -+++ b/tests/parser.c -@@ -440,6 +440,46 @@ static void test18(void **state) - free_strvec(v); - } - -+static void test19(void **state) -+{ -+#define QUOTED19 "!value" -+ vector v = alloc_strvec("key \"" QUOTED19 "\""); -+ char *val; -+ -+ assert_int_equal(VECTOR_SIZE(v), 4); -+ assert_string_equal(VECTOR_SLOT(v, 0), "key"); -+ assert_true(is_quote(VECTOR_SLOT(v, 1))); -+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19); -+ assert_true(is_quote(VECTOR_SLOT(v, 3))); -+ assert_int_equal(validate_config_strvec(v, test_file), 0); -+ -+ val = set_value(v); -+ assert_string_equal(val, QUOTED19); -+ -+ free(val); -+ free_strvec(v); -+} -+ -+static void test20(void **state) -+{ -+#define QUOTED20 "#value" -+ vector v = alloc_strvec("key \"" QUOTED20 "\""); -+ char *val; -+ -+ assert_int_equal(VECTOR_SIZE(v), 4); -+ assert_string_equal(VECTOR_SLOT(v, 0), "key"); -+ assert_true(is_quote(VECTOR_SLOT(v, 1))); -+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20); -+ assert_true(is_quote(VECTOR_SLOT(v, 3))); -+ assert_int_equal(validate_config_strvec(v, test_file), 0); -+ -+ val = set_value(v); -+ assert_string_equal(val, QUOTED20); -+ -+ free(val); -+ free_strvec(v); -+} -+ - int test_config_parser(void) - { - const struct CMUnitTest tests[] = { -@@ -461,6 +501,8 @@ int test_config_parser(void) - cmocka_unit_test(test16), - cmocka_unit_test(test17), - cmocka_unit_test(test18), -+ cmocka_unit_test(test19), -+ cmocka_unit_test(test20), - }; - return cmocka_run_group_tests(tests, setup, teardown); - } --- -2.17.2 - diff --git a/SOURCES/0023-libmultipath-invert-regexes-that-start-with-exclamat.patch b/SOURCES/0023-libmultipath-invert-regexes-that-start-with-exclamat.patch deleted file mode 100644 index 575e771..0000000 --- a/SOURCES/0023-libmultipath-invert-regexes-that-start-with-exclamat.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 8 Jun 2020 13:40:16 -0500 -Subject: [PATCH] libmultipath: invert regexes that start with exclamation - point - -The number of devices that multipath needs to blacklist keeps growing, -and the udev rules already have - -KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" - -so they only work correctly with these device types. Instead of -individually blacklisting every type of device that can't be -multipathed, multipath's default blacklist should work like the udev -rule, and blacklist all devices that aren't scsi, dasd, or nvme. -Unfortunately, the c regex library doesn't support negative lookahead. -Instead, multipath should treat "!" at the beginning of -blacklist/exceptions regexes as inverse matching the rest of the regex. -If users need to match a literal '!' as the first character of their -regex, they can use "\!" instead. This allows multipath to change the -default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])". - -Extra tests have been added to the blacklist unit tests to verify the -inverse matching code and the new default blacklist. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 41 +++++++++----- - libmultipath/blacklist.h | 3 + - multipath/multipath.conf.5 | 17 ++++-- - tests/blacklist.c | 110 +++++++++++++++++++++++++++++++++++++ - tests/test-lib.c | 2 +- - 5 files changed, 155 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 04d3adb9..0c58aa32 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -15,9 +15,24 @@ - #include "structs_vec.h" - #include "print.h" - -+char *check_invert(char *str, bool *invert) -+{ -+ if (str[0] == '!') { -+ *invert = true; -+ return str + 1; -+ } -+ if (str[0] == '\\' && str[1] == '!') { -+ *invert = false; -+ return str + 1; -+ } -+ *invert = false; -+ return str; -+} -+ - int store_ble(vector blist, char * str, int origin) - { - struct blentry * ble; -+ char *regex_str; - - if (!str) - return 0; -@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin) - if (!ble) - goto out; - -- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB)) -+ regex_str = check_invert(str, &ble->invert); -+ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB)) - goto out1; - - if (!vector_alloc_slot(blist)) -@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist) - int set_ble_device(vector blist, char * vendor, char * product, int origin) - { - struct blentry_device * ble; -+ char *regex_str; - - if (!blist) - return 1; -@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - return 1; - - if (vendor) { -- if (regcomp(&ble->vendor_reg, vendor, -+ regex_str = check_invert(vendor, &ble->vendor_invert); -+ if (regcomp(&ble->vendor_reg, regex_str, - REG_EXTENDED|REG_NOSUB)) { - FREE(vendor); - if (product) -@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin) - ble->vendor = vendor; - } - if (product) { -- if (regcomp(&ble->product_reg, product, -+ regex_str = check_invert(product, &ble->product_invert); -+ if (regcomp(&ble->product_reg, regex_str, - REG_EXTENDED|REG_NOSUB)) { - FREE(product); - if (vendor) { -@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str) - struct blentry * ble; - - vector_foreach_slot (blist, ble, i) { -- if (!regexec(&ble->regex, str, 0, NULL, 0)) -+ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert) - return 1; - } - return 0; -@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor, - if (!ble->vendor && !ble->product) - continue; - if ((!ble->vendor || -- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) && -+ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) == -+ ble->vendor_invert) && - (!ble->product || -- !regexec(&ble->product_reg, product, 0, NULL, 0))) -+ !!regexec(&ble->product_reg, product, 0, NULL, 0) == -+ ble->product_invert)) - return 1; - } - return 0; -@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf) - char * str; - int i; - -- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]"); -- if (!str) -- return 1; -- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) -- return 1; -- -- str = STRDUP("^(td|hd|vd)[a-z]"); -+ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])"); - if (!str) - return 1; - if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index 2d721f60..4305857d 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -20,6 +20,7 @@ - struct blentry { - char * str; - regex_t regex; -+ bool invert; - int origin; - }; - -@@ -28,6 +29,8 @@ struct blentry_device { - char * product; - regex_t vendor_reg; - regex_t product_reg; -+ bool vendor_invert; -+ bool product_invert; - int origin; - }; - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 3455b1cc..6dc26f10 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1248,6 +1248,16 @@ being handled by multipath-tools. - .LP - . - . -+In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a -+quoted value with an exclamation mark \fB"!"\fR will invert the matching -+of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will -+match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark -+can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a -+regular expression. \fBNote:\fR The exclamation mark must be inside quotes, -+otherwise it will be treated as starting a comment. -+.LP -+. -+. - The \fIblacklist_exceptions\fR section is used to revert the actions of the - \fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which - would normally be excluded via the \fIblacklist\fR section. A common usage is -@@ -1264,10 +1274,9 @@ unless explicitly stated. - Regular expression matching the device nodes to be excluded/included. - .RS - .PP --The default \fIblacklist\fR consists of the regular expressions --"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and --"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other --device types to be excluded from multipath handling by default. -+The default \fIblacklist\fR consists of the regular expression -+\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other -+than scsi, dasd, and nvme to be excluded from multipath handling by default. - .RE - .TP - .B wwid -diff --git a/tests/blacklist.c b/tests/blacklist.c -index cc8a9a4a..d20e97af 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) - return *(const char **)list_entry; - } - -+vector elist_property_default; -+vector blist_devnode_default; - vector blist_devnode_sdb; -+vector blist_devnode_sdb_inv; - vector blist_all; - vector blist_device_foo_bar; -+vector blist_device_foo_inv_bar; -+vector blist_device_foo_bar_inv; - vector blist_device_all; - vector blist_wwid_xyzzy; -+vector blist_wwid_xyzzy_inv; - vector blist_protocol_fcp; -+vector blist_protocol_fcp_inv; - vector blist_property_wwn; -+vector blist_property_wwn_inv; - - static int setup(void **state) - { -+ struct config conf; -+ -+ memset(&conf, 0, sizeof(conf)); -+ conf.blist_devnode = vector_alloc(); -+ if (!conf.blist_devnode) -+ return -1; -+ conf.elist_property = vector_alloc(); -+ if (!conf.elist_property) -+ return -1; -+ if (setup_default_blist(&conf) != 0) -+ return -1; -+ elist_property_default = conf.elist_property; -+ blist_devnode_default = conf.blist_devnode; -+ - blist_devnode_sdb = vector_alloc(); - if (!blist_devnode_sdb || - store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) - return -1; -+ blist_devnode_sdb_inv = vector_alloc(); -+ if (!blist_devnode_sdb_inv || -+ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG)) -+ return -1; - - blist_all = vector_alloc(); - if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) -@@ -84,6 +110,18 @@ static int setup(void **state) - set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), - ORIGIN_CONFIG)) - return -1; -+ blist_device_foo_inv_bar = vector_alloc(); -+ if (!blist_device_foo_inv_bar || -+ alloc_ble_device(blist_device_foo_inv_bar) || -+ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"), -+ strdup("bar"), ORIGIN_CONFIG)) -+ return -1; -+ blist_device_foo_bar_inv = vector_alloc(); -+ if (!blist_device_foo_bar_inv || -+ alloc_ble_device(blist_device_foo_bar_inv) || -+ set_ble_device(blist_device_foo_bar_inv, strdup("foo"), -+ strdup("!bar"), ORIGIN_CONFIG)) -+ return -1; - - blist_device_all = vector_alloc(); - if (!blist_device_all || alloc_ble_device(blist_device_all) || -@@ -95,29 +133,50 @@ static int setup(void **state) - if (!blist_wwid_xyzzy || - store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) - return -1; -+ blist_wwid_xyzzy_inv = vector_alloc(); -+ if (!blist_wwid_xyzzy_inv || -+ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG)) -+ return -1; - - blist_protocol_fcp = vector_alloc(); - if (!blist_protocol_fcp || - store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) - return -1; -+ blist_protocol_fcp_inv = vector_alloc(); -+ if (!blist_protocol_fcp_inv || -+ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"), -+ ORIGIN_CONFIG)) -+ return -1; - - blist_property_wwn = vector_alloc(); - if (!blist_property_wwn || - store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) - return -1; -+ blist_property_wwn_inv = vector_alloc(); -+ if (!blist_property_wwn_inv || -+ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG)) -+ return -1; - - return 0; - } - - static int teardown(void **state) - { -+ free_blacklist(elist_property_default); -+ free_blacklist(blist_devnode_default); - free_blacklist(blist_devnode_sdb); -+ free_blacklist(blist_devnode_sdb_inv); - free_blacklist(blist_all); - free_blacklist_device(blist_device_foo_bar); -+ free_blacklist_device(blist_device_foo_inv_bar); -+ free_blacklist_device(blist_device_foo_bar_inv); - free_blacklist_device(blist_device_all); - free_blacklist(blist_wwid_xyzzy); -+ free_blacklist(blist_wwid_xyzzy_inv); - free_blacklist(blist_protocol_fcp); -+ free_blacklist(blist_protocol_fcp_inv); - free_blacklist(blist_property_wwn); -+ free_blacklist(blist_property_wwn_inv); - return 0; - } - -@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state) - expect_condlog(3, "sdb: device node name blacklisted\n"); - assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), - MATCH_DEVNODE_BLIST); -+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"), -+ MATCH_NOTHING); -+ expect_condlog(3, "sdc: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"), -+ MATCH_DEVNODE_BLIST); - } - - static void test_devnode_whitelist(void **state) -@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state) - MATCH_NOTHING); - } - -+static void test_devnode_default(void **state) -+{ -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"), -+ MATCH_NOTHING); -+ expect_condlog(3, "hda: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"), -+ MATCH_DEVNODE_BLIST); -+} -+ - static void test_device_blacklist(void **state) - { - expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); - assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", - "bar", "sdb"), - MATCH_DEVICE_BLIST); -+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_NOTHING); -+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_NOTHING); -+ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz", -+ "bar", "sdb"), -+ MATCH_DEVICE_BLIST); -+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo", -+ "baz", "sdb"), -+ MATCH_DEVICE_BLIST); - } - - static void test_device_whitelist(void **state) -@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state) - expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); - assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), - MATCH_WWID_BLIST); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy", -+ "sdb"), MATCH_NOTHING); -+ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh", -+ "sdb"), MATCH_WWID_BLIST); - } - - static void test_wwid_whitelist(void **state) -@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state) - expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); - assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), - MATCH_PROTOCOL_BLIST); -+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), -+ MATCH_NOTHING); -+ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA; -+ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp), -+ MATCH_PROTOCOL_BLIST); - } - - static void test_protocol_whitelist(void **state) -@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state) - static void test_property_blacklist(void **state) - { - static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } }; - conf.blist_property = blist_property_wwn; - expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); - assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), - MATCH_PROPERTY_BLIST); -+ conf.blist_property = blist_property_wwn_inv; -+ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n"); -+ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), -+ MATCH_PROPERTY_BLIST); -+ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"), -+ MATCH_NOTHING); - } - - /* the property check works different in that you check all the property -@@ -482,6 +591,7 @@ int test_blacklist(void) - cmocka_unit_test(test_devnode_blacklist), - cmocka_unit_test(test_devnode_whitelist), - cmocka_unit_test(test_devnode_missing), -+ cmocka_unit_test(test_devnode_default), - cmocka_unit_test(test_device_blacklist), - cmocka_unit_test(test_device_whitelist), - cmocka_unit_test(test_device_missing), -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 59275163..08ff2d8d 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -15,7 +15,7 @@ - #include "test-lib.h" - - const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO); --const char default_devnode[] = "sdTEST"; -+const char default_devnode[] = "sdxTEST"; - const char default_wwid[] = "TEST-WWID"; - /* default_wwid should be a substring of default_wwid_1! */ - const char default_wwid_1[] = "TEST-WWID-1"; --- -2.17.2 - diff --git a/SOURCES/0024-libmultipath-make-dm_get_map-status-return-codes-sym.patch b/SOURCES/0024-libmultipath-make-dm_get_map-status-return-codes-sym.patch deleted file mode 100644 index e5159bb..0000000 --- a/SOURCES/0024-libmultipath-make-dm_get_map-status-return-codes-sym.patch +++ /dev/null @@ -1,322 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 23 Jun 2020 22:17:31 -0500 -Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic - -dm_get_map() and dm_get_status() now use symbolic return codes. They -also differentiate between failing to get information from device-mapper -and not finding the requested device. These symboilc return codes are -also used by update_multipath_* functions. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 51 +++++++++++++++++++++++++------------- - libmultipath/devmapper.h | 6 +++++ - libmultipath/structs_vec.c | 45 +++++++++++++++++++-------------- - multipathd/main.c | 12 ++++----- - 4 files changed, 72 insertions(+), 42 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 13a1cf53..f6204e5f 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -525,36 +525,43 @@ int dm_map_present(const char * str) - - int dm_get_map(const char *name, unsigned long long *size, char *outparams) - { -- int r = 1; -+ int r = DMP_ERR; - struct dm_task *dmt; - uint64_t start, length; - char *target_type = NULL; - char *params = NULL; - - if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE))) -- return 1; -+ return r; - - if (!dm_task_set_name(dmt, name)) - goto out; - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) -+ errno = 0; -+ if (!dm_task_run(dmt)) { -+ if (dm_task_get_errno(dmt) == ENXIO) -+ r = DMP_NOT_FOUND; - goto out; -+ } - -+ r = DMP_NOT_FOUND; - /* Fetch 1st target */ -- dm_get_next_target(dmt, NULL, &start, &length, -- &target_type, ¶ms); -+ if (dm_get_next_target(dmt, NULL, &start, &length, -+ &target_type, ¶ms) != NULL) -+ /* more than one target */ -+ goto out; - - if (size) - *size = length; - - if (!outparams) { -- r = 0; -+ r = DMP_OK; - goto out; - } - if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE) -- r = 0; -+ r = DMP_OK; - out: - dm_task_destroy(dmt); - return r; -@@ -628,35 +635,45 @@ is_mpath_part(const char *part_name, const char *map_name) - - int dm_get_status(const char *name, char *outstatus) - { -- int r = 1; -+ int r = DMP_ERR; - struct dm_task *dmt; - uint64_t start, length; - char *target_type = NULL; - char *status = NULL; - - if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS))) -- return 1; -+ return r; - - if (!dm_task_set_name(dmt, name)) - goto out; - - dm_task_no_open_count(dmt); - -- if (!dm_task_run(dmt)) -+ errno = 0; -+ if (!dm_task_run(dmt)) { -+ if (dm_task_get_errno(dmt) == ENXIO) -+ r = DMP_NOT_FOUND; - goto out; -+ } - -+ r = DMP_NOT_FOUND; - /* Fetch 1st target */ -- dm_get_next_target(dmt, NULL, &start, &length, -- &target_type, &status); -+ if (dm_get_next_target(dmt, NULL, &start, &length, -+ &target_type, &status) != NULL) -+ goto out; -+ -+ if (!target_type || strcmp(target_type, TGT_MPATH) != 0) -+ goto out; -+ - if (!status) { - condlog(2, "get null status."); - goto out; - } - - if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) -- r = 0; -+ r = DMP_OK; - out: -- if (r) -+ if (r != DMP_OK) - condlog(0, "%s: error getting map status string", name); - - dm_task_destroy(dmt); -@@ -866,7 +883,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - return 1; - - if (need_suspend && -- !dm_get_map(mapname, &mapsize, params) && -+ dm_get_map(mapname, &mapsize, params) == DMP_OK && - strstr(params, "queue_if_no_path")) { - if (!dm_queue_if_no_path(mapname, 0)) - queue_if_no_path = 1; -@@ -1075,7 +1092,7 @@ struct multipath *dm_get_multipath(const char *name) - if (!mpp->alias) - goto out; - -- if (dm_get_map(name, &mpp->size, NULL)) -+ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK) - goto out; - - dm_get_uuid(name, mpp->wwid, WWID_SIZE); -@@ -1259,7 +1276,7 @@ do_foreach_partmaps (const char * mapname, - /* - * and we can fetch the map table from the kernel - */ -- !dm_get_map(names->name, &size, ¶ms[0]) && -+ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK && - - /* - * and the table maps over the multipath map -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 7557a86b..adb55000 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -27,6 +27,12 @@ - #define UUID_PREFIX "mpath-" - #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) - -+enum { -+ DMP_ERR, -+ DMP_OK, -+ DMP_NOT_FOUND, -+}; -+ - void dm_init(int verbosity); - void libmp_dm_init(void); - void libmp_udev_set_sync_support(int on); -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 077f2e42..8137ea21 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp) - int - update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon) - { -+ int r = DMP_ERR; - char params[PARAMS_SIZE] = {0}; - - if (!mpp) -- return 1; -+ return r; - -- if (dm_get_map(mpp->alias, &mpp->size, params)) { -- condlog(3, "%s: cannot get map", mpp->alias); -- return 1; -+ r = dm_get_map(mpp->alias, &mpp->size, params); -+ if (r != DMP_OK) { -+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present"); -+ return r; - } - - if (disassemble_map(pathvec, params, mpp, is_daemon)) { - condlog(3, "%s: cannot disassemble map", mpp->alias); -- return 1; -+ return DMP_ERR; - } - -- return 0; -+ return DMP_OK; - } - - int - update_multipath_status (struct multipath *mpp) - { -+ int r = DMP_ERR; - char status[PARAMS_SIZE] = {0}; - - if (!mpp) -- return 1; -+ return r; - -- if (dm_get_status(mpp->alias, status)) { -- condlog(3, "%s: cannot get status", mpp->alias); -- return 1; -+ r = dm_get_status(mpp->alias, status); -+ if (r != DMP_OK) { -+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present"); -+ return r; - } - - if (disassemble_status(status, mpp)) { - condlog(3, "%s: cannot disassemble status", mpp->alias); -- return 1; -+ return DMP_ERR; - } - -- return 0; -+ return DMP_OK; - } - - void sync_paths(struct multipath *mpp, vector pathvec) -@@ -264,10 +268,10 @@ int - update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) - { - struct pathgroup *pgp; -- int i; -+ int i, r = DMP_ERR; - - if (!mpp) -- return 1; -+ return r; - - update_mpp_paths(mpp, pathvec); - condlog(4, "%s: %s", mpp->alias, __FUNCTION__); -@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon) - free_pgvec(mpp->pg, KEEP_PATHS); - mpp->pg = NULL; - -- if (update_multipath_table(mpp, pathvec, is_daemon)) -- return 1; -+ r = update_multipath_table(mpp, pathvec, is_daemon); -+ if (r != DMP_OK) -+ return r; -+ - sync_paths(mpp, pathvec); - -- if (update_multipath_status(mpp)) -- return 1; -+ r = update_multipath_status(mpp); -+ if (r != DMP_OK) -+ return r; - - vector_foreach_slot(mpp->pg, pgp, i) - if (pgp->paths) - path_group_prio_update(pgp); - -- return 0; -+ return DMP_OK; - } - - static void enter_recovery_mode(struct multipath *mpp) -diff --git a/multipathd/main.c b/multipathd/main.c -index 6b7db2c0..e3427d3d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -414,7 +414,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp, - goto out; - } - -- if (update_multipath_strings(mpp, vecs->pathvec, 1)) { -+ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) { - condlog(0, "%s: failed to setup multipath", mpp->alias); - goto out; - } -@@ -553,9 +553,9 @@ add_map_without_path (struct vectors *vecs, const char *alias) - mpp->mpe = find_mpe(conf->mptable, mpp->wwid); - put_multipath_config(conf); - -- if (update_multipath_table(mpp, vecs->pathvec, 1)) -+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK) - goto out; -- if (update_multipath_status(mpp)) -+ if (update_multipath_status(mpp) != DMP_OK) - goto out; - - if (!vector_alloc_slot(vecs->mpvec)) -@@ -1346,8 +1346,8 @@ map_discovery (struct vectors * vecs) - return 1; - - vector_foreach_slot (vecs->mpvec, mpp, i) -- if (update_multipath_table(mpp, vecs->pathvec, 1) || -- update_multipath_status(mpp)) { -+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK || -+ update_multipath_status(mpp) != DMP_OK) { - remove_map(mpp, vecs, 1); - i--; - } -@@ -2087,7 +2087,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * Synchronize with kernel state - */ -- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) { -+ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { - condlog(1, "%s: Could not synchronize with kernel state", - pp->dev); - pp->dmstate = PSTATE_UNDEF; --- -2.17.2 - diff --git a/SOURCES/0025-multipathd-fix-check_path-errors-with-removed-map.patch b/SOURCES/0025-multipathd-fix-check_path-errors-with-removed-map.patch deleted file mode 100644 index 1ea59c7..0000000 --- a/SOURCES/0025-multipathd-fix-check_path-errors-with-removed-map.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 11 Jun 2020 15:41:18 -0500 -Subject: [PATCH] multipathd: fix check_path errors with removed map - -If a multipath device is removed during, or immediately before the call -to check_path(), multipathd can behave incorrectly. A missing multpath -device will cause update_multipath_strings() to fail, setting -pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause -reinstate_path() to be called, which will also fail. This will trigger -a reload, restoring the recently removed device. - -If update_multipath_strings() fails because there is no multipath -device, check_path should just quit, since the remove dmevent and uevent -are likely already queued up. Also, I don't see any reason to reload the -multipath device if reinstate fails. This code was added by -fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate -could fail if the path was disabled. Looking through the current kernel -code, I can't see any reason why a reinstate would fail, where a reload -would help. If the path was missing from the multipath device, -update_multipath_strings() would already catch that, and quit -check_path() early, which make more sense to me than reloading does. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 44 +++++++++++++++++++------------------------- - 1 file changed, 19 insertions(+), 25 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e3427d3d..1d9ce7f7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1611,22 +1611,18 @@ fail_path (struct path * pp, int del_active) - /* - * caller must have locked the path list before calling that function - */ --static int -+static void - reinstate_path (struct path * pp) - { -- int ret = 0; -- - if (!pp->mpp) -- return 0; -+ return; - -- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) { -+ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) - condlog(0, "%s: reinstate failed", pp->dev_t); -- ret = 1; -- } else { -+ else { - condlog(2, "%s: reinstated", pp->dev_t); - update_queue_mode_add_path(pp->mpp); - } -- return ret; - } - - static void -@@ -2087,9 +2083,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * Synchronize with kernel state - */ -- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) { -- condlog(1, "%s: Could not synchronize with kernel state", -- pp->dev); -+ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1); -+ if (ret != DMP_OK) { -+ if (ret == DMP_NOT_FOUND) { -+ /* multipath device missing. Likely removed */ -+ condlog(1, "%s: multipath device '%s' not found", -+ pp->dev, pp->mpp->alias); -+ return 0; -+ } else -+ condlog(1, "%s: Couldn't synchronize with kernel state", -+ pp->dev); - pp->dmstate = PSTATE_UNDEF; - } - /* if update_multipath_strings orphaned the path, quit early */ -@@ -2179,12 +2182,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - /* - * reinstate this path - */ -- if (!disable_reinstate && reinstate_path(pp)) { -- condlog(3, "%s: reload map", pp->dev); -- ev_add_path(pp, vecs, 1); -- pp->tick = 1; -- return 0; -- } -+ if (!disable_reinstate) -+ reinstate_path(pp); - new_path_up = 1; - - if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) -@@ -2200,15 +2199,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - else if (newstate == PATH_UP || newstate == PATH_GHOST) { - if ((pp->dmstate == PSTATE_FAILED || - pp->dmstate == PSTATE_UNDEF) && -- !disable_reinstate) { -+ !disable_reinstate) - /* Clear IO errors */ -- if (reinstate_path(pp)) { -- condlog(3, "%s: reload map", pp->dev); -- ev_add_path(pp, vecs, 1); -- pp->tick = 1; -- return 0; -- } -- } else { -+ reinstate_path(pp); -+ else { - LOG_MSG(4, verbosity, pp); - if (pp->checkint != max_checkint) { - /* --- -2.17.2 - diff --git a/SOURCES/0026-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch b/SOURCES/0026-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch deleted file mode 100644 index 55381a3..0000000 --- a/SOURCES/0026-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 17 Jun 2020 13:31:37 -0500 -Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success - -dm_flush_maps() returned both 0 and 1 on error, depending on which part -of the function it was in, but the caller was always treating 0 as a -success. Make dm_flush_maps() always return 1 on error and 0 on success. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f6204e5f..cda83ce4 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -953,13 +953,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) - - int dm_flush_maps (int retries) - { -- int r = 0; -+ int r = 1; - struct dm_task *dmt; - struct dm_names *names; - unsigned next = 0; - - if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST))) -- return 0; -+ return r; - - dm_task_no_open_count(dmt); - -@@ -972,6 +972,7 @@ int dm_flush_maps (int retries) - if (!names->dev) - goto out; - -+ r = 0; - do { - r |= dm_suspend_and_flush_map(names->name, retries); - next = names->next; --- -2.17.2 - diff --git a/SOURCES/0027-multipathd-add-del-maps-multipathd-command.patch b/SOURCES/0027-multipathd-add-del-maps-multipathd-command.patch deleted file mode 100644 index 2f535e2..0000000 --- a/SOURCES/0027-multipathd-add-del-maps-multipathd-command.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 15 Jun 2020 17:00:54 -0500 -Subject: [PATCH] multipathd: add "del maps" multipathd command - -This will flush all multipath devices. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 7 +++++-- - libmultipath/devmapper.h | 2 +- - multipath/main.c | 2 +- - multipathd/cli.c | 1 + - multipathd/cli_handlers.c | 19 +++++++++++++++++++ - multipathd/cli_handlers.h | 1 + - multipathd/main.c | 3 ++- - multipathd/main.h | 1 + - 8 files changed, 31 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index cda83ce4..7f98bf9d 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -951,7 +951,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove) - - #endif - --int dm_flush_maps (int retries) -+int dm_flush_maps (int need_suspend, int retries) - { - int r = 1; - struct dm_task *dmt; -@@ -974,7 +974,10 @@ int dm_flush_maps (int retries) - - r = 0; - do { -- r |= dm_suspend_and_flush_map(names->name, retries); -+ if (need_suspend) -+ r |= dm_suspend_and_flush_map(names->name, retries); -+ else -+ r |= dm_flush_map(names->name); - next = names->next; - names = (void *) names + next; - } while (next); -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index adb55000..7e8812ad 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -55,7 +55,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove); - #define dm_suspend_and_flush_map(mapname, retries) \ - _dm_flush_map(mapname, 1, 0, 1, retries) - int dm_cancel_deferred_remove(struct multipath *mpp); --int dm_flush_maps (int retries); -+int dm_flush_maps (int need_suspend, int retries); - int dm_fail_path(const char * mapname, char * path); - int dm_reinstate_path(const char * mapname, char * path); - int dm_queue_if_no_path(const char *mapname, int enable); -diff --git a/multipath/main.c b/multipath/main.c -index 78822ee1..7ab3102f 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1127,7 +1127,7 @@ main (int argc, char *argv[]) - goto out; - } - else if (conf->remove == FLUSH_ALL) { -- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK; -+ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; - goto out; - } - while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY) -diff --git a/multipathd/cli.c b/multipathd/cli.c -index 800c0fbe..bdc9fb10 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -568,6 +568,7 @@ cli_init (void) { - add_handler(DEL+PATH, NULL); - add_handler(ADD+MAP, NULL); - add_handler(DEL+MAP, NULL); -+ add_handler(DEL+MAPS, NULL); - add_handler(SWITCH+MAP+GROUP, NULL); - add_handler(RECONFIGURE, NULL); - add_handler(SUSPEND+MAP, NULL); -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 31c3d9fd..782bb003 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data) - return rc; - } - -+int -+cli_del_maps (void *v, char **reply, int *len, void *data) -+{ -+ struct vectors * vecs = (struct vectors *)data; -+ struct multipath *mpp; -+ int i, ret = 0; -+ -+ condlog(2, "remove maps (operator)"); -+ vector_foreach_slot(vecs->mpvec, mpp, i) { -+ if (flush_map(mpp, vecs, 0)) -+ ret++; -+ else -+ i--; -+ } -+ /* flush any multipath maps that aren't currently known by multipathd */ -+ ret |= dm_flush_maps(0, 0); -+ return ret; -+} -+ - int - cli_reload(void *v, char **reply, int *len, void *data) - { -diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h -index 0f451064..6f57b429 100644 ---- a/multipathd/cli_handlers.h -+++ b/multipathd/cli_handlers.h -@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data); - int cli_del_path (void * v, char ** reply, int * len, void * data); - int cli_add_map (void * v, char ** reply, int * len, void * data); - int cli_del_map (void * v, char ** reply, int * len, void * data); -+int cli_del_maps (void * v, char ** reply, int * len, void * data); - int cli_switch_group(void * v, char ** reply, int * len, void * data); - int cli_reconfigure(void * v, char ** reply, int * len, void * data); - int cli_resize(void * v, char ** reply, int * len, void * data); -diff --git a/multipathd/main.c b/multipathd/main.c -index 1d9ce7f7..1d0579e9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -631,7 +631,7 @@ sync_maps_state(vector mpvec) - sync_map_state(mpp); - } - --static int -+int - flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - { - int r; -@@ -1551,6 +1551,7 @@ uxlsnrloop (void * ap) - set_handler_callback(DEL+PATH, cli_del_path); - set_handler_callback(ADD+MAP, cli_add_map); - set_handler_callback(DEL+MAP, cli_del_map); -+ set_handler_callback(DEL+MAPS, cli_del_maps); - set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); - set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); - set_handler_callback(SUSPEND+MAP, cli_suspend); -diff --git a/multipathd/main.h b/multipathd/main.h -index 7bb8463f..5dff17e5 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int); - int ev_remove_path (struct path *, struct vectors *, int); - int ev_add_map (char *, const char *, struct vectors *); - int ev_remove_map (char *, char *, int, struct vectors *); -+int flush_map(struct multipath *, struct vectors *, int); - int set_config_state(enum daemon_status); - void * mpath_alloc_prin_response(int prin_sa); - int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp, --- -2.17.2 - diff --git a/SOURCES/0028-multipath-make-flushing-maps-work-like-other-command.patch b/SOURCES/0028-multipath-make-flushing-maps-work-like-other-command.patch deleted file mode 100644 index 1674230..0000000 --- a/SOURCES/0028-multipath-make-flushing-maps-work-like-other-command.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 15 Jun 2020 23:54:29 -0500 -Subject: [PATCH] multipath: make flushing maps work like other commands - -The config structure doesn't need a special variable just for removes. -Multipath can just use the cmd variable, like it does for the other -commands. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 3 ++- - libmultipath/configure.h | 3 --- - multipath/main.c | 20 ++++++++++---------- - 3 files changed, 12 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 3368d8c9..4042eba6 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -39,6 +39,8 @@ enum mpath_cmds { - CMD_ADD_WWID, - CMD_USABLE_PATHS, - CMD_DUMP_CONFIG, -+ CMD_FLUSH_ONE, -+ CMD_FLUSH_ALL, - }; - - enum force_reload_types { -@@ -143,7 +145,6 @@ struct config { - unsigned int max_checkint; - bool use_watchdog; - int pgfailback; -- int remove; - int rr_weight; - int no_path_retry; - int user_friendly_names; -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index d7509000..0e33bf40 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -45,9 +45,6 @@ enum { - CP_RETRY, - }; - --#define FLUSH_ONE 1 --#define FLUSH_ALL 2 -- - struct vectors; - - int setup_map (struct multipath * mpp, char * params, int params_size, -diff --git a/multipath/main.c b/multipath/main.c -index 7ab3102f..a2080029 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -942,10 +942,10 @@ main (int argc, char *argv[]) - cmd = CMD_DRY_RUN; - break; - case 'f': -- conf->remove = FLUSH_ONE; -+ cmd = CMD_FLUSH_ONE; - break; - case 'F': -- conf->remove = FLUSH_ALL; -+ cmd = CMD_FLUSH_ALL; - break; - case 'l': - if (optarg && !strncmp(optarg, "l", 1)) -@@ -1084,6 +1084,10 @@ main (int argc, char *argv[]) - condlog(0, "the -w option requires a device"); - goto out; - } -+ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) { -+ condlog(0, "the -f option requires a map name to remove"); -+ goto out; -+ } - - switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) { - case DELEGATE_OK: -@@ -1117,16 +1121,12 @@ main (int argc, char *argv[]) - } - if (retries < 0) - retries = conf->remove_retries; -- if (conf->remove == FLUSH_ONE) { -- if (dev_type == DEV_DEVMAP) { -- r = dm_suspend_and_flush_map(dev, retries) ? -- RTVL_FAIL : RTVL_OK; -- } else -- condlog(0, "must provide a map name to remove"); -- -+ if (cmd == CMD_FLUSH_ONE) { -+ r = dm_suspend_and_flush_map(dev, retries) ? -+ RTVL_FAIL : RTVL_OK; - goto out; - } -- else if (conf->remove == FLUSH_ALL) { -+ else if (cmd == CMD_FLUSH_ALL) { - r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK; - goto out; - } --- -2.17.2 - diff --git a/SOURCES/0029-multipath-delegate-flushing-maps-to-multipathd.patch b/SOURCES/0029-multipath-delegate-flushing-maps-to-multipathd.patch deleted file mode 100644 index f610b93..0000000 --- a/SOURCES/0029-multipath-delegate-flushing-maps-to-multipathd.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jun 2020 16:25:34 -0500 -Subject: [PATCH] multipath: delegate flushing maps to multipathd - -Since there can be problems with removing maps outside of multipathd, -multipath should attempt to delegate this command to multipathd. -However, multipathd doesn't attempt to suspend the device, in order -to avoid potential hangs. If delegating to multipathd fails, multipath -should try the remove itself. - -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 14 ++++++++++++++ - multipath/multipath.8 | 4 ++-- - 2 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index a2080029..612c6815 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -828,6 +828,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { - p += snprintf(p, n, "reconfigure"); - } -+ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) { -+ p += snprintf(p, n, "del map %s", dev); -+ /* multipathd doesn't try as hard, to avoid potentially -+ * hanging. If it fails, retry with the regular multipath -+ * command */ -+ r = NOT_DELEGATED; -+ } -+ else if (cmd == CMD_FLUSH_ALL) { -+ p += snprintf(p, n, "del maps"); -+ /* multipathd doesn't try as hard, to avoid potentially -+ * hanging. If it fails, retry with the regular multipath -+ * command */ -+ r = NOT_DELEGATED; -+ } - /* Add other translations here */ - - if (strlen(command) == 0) -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 8befc45a..47a33f9b 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -125,11 +125,11 @@ the system. - Other operation modes are chosen by using one of the following command line switches: - .TP - .B \-f --Flush (remove) a multipath device map specified as parameter, if unused. -+Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running. - . - .TP - .B \-F --Flush (remove) all unused multipath device maps. -+Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running. - . - .TP - .B \-l --- -2.17.2 - diff --git a/SOURCES/0030-multipath-add-option-to-skip-multipathd-delegation.patch b/SOURCES/0030-multipath-add-option-to-skip-multipathd-delegation.patch deleted file mode 100644 index 141a565..0000000 --- a/SOURCES/0030-multipath-add-option-to-skip-multipathd-delegation.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 16 Jun 2020 17:36:33 -0500 -Subject: [PATCH] multipath: add option to skip multipathd delegation - -Add the -D option to allow users to skip delegating commands to -multipathd. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - multipath/main.c | 8 +++++++- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 4042eba6..160867cd 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -191,6 +191,7 @@ struct config { - int ghost_delay; - int find_multipaths_timeout; - int marginal_pathgroups; -+ int skip_delegate; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/multipath/main.c b/multipath/main.c -index 612c6815..3c3d2398 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -825,6 +825,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - *p = '\0'; - n = sizeof(command); - -+ if (conf->skip_delegate) -+ return NOT_DELEGATED; -+ - if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) { - p += snprintf(p, n, "reconfigure"); - } -@@ -923,7 +926,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":aAdDcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -955,6 +958,9 @@ main (int argc, char *argv[]) - if (cmd == CMD_CREATE) - cmd = CMD_DRY_RUN; - break; -+ case 'D': -+ conf->skip_delegate = 1; -+ break; - case 'f': - cmd = CMD_FLUSH_ONE; - break; --- -2.17.2 - diff --git a/SOURCES/0031-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch b/SOURCES/0031-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch deleted file mode 100644 index 6954d3c..0000000 --- a/SOURCES/0031-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Jun 2020 20:46:08 -0500 -Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing - -dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as -a signed integer. This means that if dev_loss_tmo is above INT_MAX, the -sysfs value will be a negative number. Parsing this was causing -sysfs_set_rport_tmo() to fail. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index ffec5162..83a41a4a 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -583,7 +583,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - struct udev_device *rport_dev = NULL; - char value[16], *eptr; - char rport_id[32]; -- unsigned long long tmo = 0; -+ unsigned int tmo; - int ret; - - sprintf(rport_id, "rport-%d:%d-%d", -@@ -607,8 +607,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - "error %d", rport_id, -ret); - goto out; - } -- tmo = strtoull(value, &eptr, 0); -- if (value == eptr || tmo == ULLONG_MAX) { -+ tmo = strtoul(value, &eptr, 0); -+ if (value == eptr) { - condlog(0, "%s: Cannot parse dev_loss_tmo " - "attribute '%s'", rport_id, value); - goto out; --- -2.17.2 - diff --git a/SOURCES/0032-kpartx-read-devices-with-direct-IO.patch b/SOURCES/0032-kpartx-read-devices-with-direct-IO.patch deleted file mode 100644 index 16d8937..0000000 --- a/SOURCES/0032-kpartx-read-devices-with-direct-IO.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 26 Jun 2020 20:06:24 -0500 -Subject: [PATCH] kpartx: read devices with direct IO - -If kpartx is used on top of shared storage, and a device has its -partition table changed on one machine, and then kpartx is run on -another, it may not see the new data, because the cache still contains -the old data, and there is nothing to tell the machine running kpartx to -invalidate it. To solve this, kpartx should read the devices using -direct io. - -One issue with how this code has been updated is that the original code -for getblock() always read 1024 bytes. The new code reads a logical -sector size chunk of the device, and returns a pointer to the 512 byte -sector that the caller asked for, within that (possibly larger) chunk. -This means that if the logical sector size is 512, then the code is now -only reading 512 bytes. Looking through the code for the various -partition types, I can't see a case where more than 512 bytes is needed -and getblock() is used. If anyone has a reason why this code should be -reading 1024 bytes at minmum, I can certainly change this. But when I -looked, I couldn't find a case where reading 512 bytes would cause a -problem. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/dasd.c | 7 ++++--- - kpartx/gpt.c | 22 +++++++++---------- - kpartx/kpartx.c | 56 +++++++++++++++++++++++++++++++++++++++---------- - kpartx/kpartx.h | 2 ++ - 4 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/kpartx/dasd.c b/kpartx/dasd.c -index 14b9d3aa..f0398645 100644 ---- a/kpartx/dasd.c -+++ b/kpartx/dasd.c -@@ -22,6 +22,7 @@ - * along with this program. If not, see . - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -117,13 +118,13 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, - - sprintf(pathname, "/dev/.kpartx-node-%u-%u", - (unsigned int)major(dev), (unsigned int)minor(dev)); -- if ((fd_dasd = open(pathname, O_RDONLY)) == -1) { -+ if ((fd_dasd = open(pathname, O_RDONLY | O_DIRECT)) == -1) { - /* Devicenode does not exist. Try to create one */ - if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) { - /* Couldn't create a device node */ - return -1; - } -- fd_dasd = open(pathname, O_RDONLY); -+ fd_dasd = open(pathname, O_RDONLY | O_DIRECT); - /* - * The file will vanish when the last process (we) - * has ceased to access it. -@@ -175,7 +176,7 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all, - * Get volume label, extract name and type. - */ - -- if (!(data = (unsigned char *)malloc(blocksize))) -+ if (aligned_malloc((void **)&data, blocksize, NULL)) - goto out; - - -diff --git a/kpartx/gpt.c b/kpartx/gpt.c -index 785b34ea..f7fefb70 100644 ---- a/kpartx/gpt.c -+++ b/kpartx/gpt.c -@@ -243,8 +243,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt) - - if (!count) return NULL; - -- pte = (gpt_entry *)malloc(count); -- if (!pte) -+ if (aligned_malloc((void **)&pte, get_sector_size(fd), &count)) - return NULL; - memset(pte, 0, count); - -@@ -269,12 +268,11 @@ static gpt_header * - alloc_read_gpt_header(int fd, uint64_t lba) - { - gpt_header *gpt; -- gpt = (gpt_header *) -- malloc(sizeof (gpt_header)); -- if (!gpt) -+ size_t size = sizeof (gpt_header); -+ if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size)) - return NULL; -- memset(gpt, 0, sizeof (*gpt)); -- if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) { -+ memset(gpt, 0, size); -+ if (!read_lba(fd, lba, gpt, size)) { - free(gpt); - return NULL; - } -@@ -498,6 +496,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) - gpt_header *pgpt = NULL, *agpt = NULL; - gpt_entry *pptes = NULL, *aptes = NULL; - legacy_mbr *legacymbr = NULL; -+ size_t size = sizeof(legacy_mbr); - uint64_t lastlba; - if (!gpt || !ptes) - return 0; -@@ -526,11 +525,10 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes) - } - - /* This will be added to the EFI Spec. per Intel after v1.02. */ -- legacymbr = malloc(sizeof (*legacymbr)); -- if (legacymbr) { -- memset(legacymbr, 0, sizeof (*legacymbr)); -- read_lba(fd, 0, (uint8_t *) legacymbr, -- sizeof (*legacymbr)); -+ if (aligned_malloc((void **)&legacymbr, get_sector_size(fd), -+ &size) == 0) { -+ memset(legacymbr, 0, size); -+ read_lba(fd, 0, (uint8_t *) legacymbr, size); - good_pmbr = is_pmbr_valid(legacymbr); - free(legacymbr); - legacymbr=NULL; -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index d3620c5c..c24ad6d9 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -19,6 +19,7 @@ - * cva, 2002-10-26 - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -41,7 +42,6 @@ - - #define SIZE(a) (sizeof(a)/sizeof((a)[0])) - --#define READ_SIZE 1024 - #define MAXTYPES 64 - #define MAXSLICES 256 - #define DM_TARGET "linear" -@@ -388,7 +388,7 @@ main(int argc, char **argv){ - set_delimiter(mapname, delim); - } - -- fd = open(device, O_RDONLY); -+ fd = open(device, O_RDONLY | O_DIRECT); - - if (fd == -1) { - perror(device); -@@ -690,9 +690,9 @@ xmalloc (size_t size) { - */ - - static int --sseek(int fd, unsigned int secnr) { -+sseek(int fd, unsigned int secnr, int secsz) { - off64_t in, out; -- in = ((off64_t) secnr << 9); -+ in = ((off64_t) secnr * secsz); - out = 1; - - if ((out = lseek64(fd, in, SEEK_SET)) != in) -@@ -703,6 +703,31 @@ sseek(int fd, unsigned int secnr) { - return 0; - } - -+int -+aligned_malloc(void **mem_p, size_t align, size_t *size_p) -+{ -+ static size_t pgsize = 0; -+ size_t size; -+ int err; -+ -+ if (!mem_p || !align || (size_p && !*size_p)) -+ return EINVAL; -+ -+ if (!pgsize) -+ pgsize = getpagesize(); -+ -+ if (size_p) -+ size = ((*size_p + align - 1) / align) * align; -+ else -+ size = pgsize; -+ -+ err = posix_memalign(mem_p, pgsize, size); -+ if (!err && size_p) -+ *size_p = size; -+ return err; -+} -+ -+/* always in sector size blocks */ - static - struct block { - unsigned int secnr; -@@ -710,30 +735,39 @@ struct block { - struct block *next; - } *blockhead; - -+/* blknr is always in 512 byte blocks */ - char * --getblock (int fd, unsigned int secnr) { -+getblock (int fd, unsigned int blknr) { -+ unsigned int secsz = get_sector_size(fd); -+ unsigned int blks_per_sec = secsz / 512; -+ unsigned int secnr = blknr / blks_per_sec; -+ unsigned int blk_off = (blknr % blks_per_sec) * 512; - struct block *bp; - - for (bp = blockhead; bp; bp = bp->next) - - if (bp->secnr == secnr) -- return bp->block; -+ return bp->block + blk_off; - -- if (sseek(fd, secnr)) -+ if (sseek(fd, secnr, secsz)) - return NULL; - - bp = xmalloc(sizeof(struct block)); - bp->secnr = secnr; - bp->next = blockhead; - blockhead = bp; -- bp->block = (char *) xmalloc(READ_SIZE); -+ if (aligned_malloc((void **)&bp->block, secsz, NULL)) { -+ fprintf(stderr, "aligned_malloc failed\n"); -+ exit(1); -+ } - -- if (read(fd, bp->block, READ_SIZE) != READ_SIZE) { -+ if (read(fd, bp->block, secsz) != secsz) { - fprintf(stderr, "read error, sector %d\n", secnr); -- bp->block = NULL; -+ blockhead = bp->next; -+ return NULL; - } - -- return bp->block; -+ return bp->block + blk_off; - } - - int -diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h -index 67edeb82..727632c1 100644 ---- a/kpartx/kpartx.h -+++ b/kpartx/kpartx.h -@@ -1,6 +1,7 @@ - #ifndef _KPARTX_H - #define _KPARTX_H - -+#include - #include - #include - -@@ -61,6 +62,7 @@ extern ptreader read_mac_pt; - extern ptreader read_sun_pt; - extern ptreader read_ps3_pt; - -+int aligned_malloc(void **mem_p, size_t align, size_t *size_p); - char *getblock(int fd, unsigned int secnr); - - static inline unsigned int --- -2.17.2 - diff --git a/SOURCES/0033-kpartx-handle-alternate-bsd-disklabel-location.patch b/SOURCES/0033-kpartx-handle-alternate-bsd-disklabel-location.patch deleted file mode 100644 index 556ea24..0000000 --- a/SOURCES/0033-kpartx-handle-alternate-bsd-disklabel-location.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 30 Jun 2020 10:49:59 -0500 -Subject: [PATCH] kpartx: handle alternate bsd disklabel location - -bsd disk labels can either be at the start of the second sector, or 64 -bytes into the first sector, but kpartx only handled the first case. -However the second case is what parted creates, and what the linux -kernel partition code expects. kpartx should handle both cases. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/bsd.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/kpartx/bsd.c b/kpartx/bsd.c -index 0e661fbc..950b0f92 100644 ---- a/kpartx/bsd.c -+++ b/kpartx/bsd.c -@@ -1,6 +1,7 @@ - #include "kpartx.h" - #include - -+#define BSD_LABEL_OFFSET 64 - #define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ - #define XBSD_MAXPARTITIONS 16 - #define BSD_FS_UNUSED 0 -@@ -60,8 +61,19 @@ read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) { - return -1; - - l = (struct bsd_disklabel *) bp; -- if (l->d_magic != BSD_DISKMAGIC) -- return -1; -+ if (l->d_magic != BSD_DISKMAGIC) { -+ /* -+ * BSD disklabels can also start 64 bytes offset from the -+ * start of the first sector -+ */ -+ bp = getblock(fd, offset); -+ if (bp == NULL) -+ return -1; -+ -+ l = (struct bsd_disklabel *)(bp + 64); -+ if (l->d_magic != BSD_DISKMAGIC) -+ return -1; -+ } - - max_partitions = 16; - if (l->d_npartitions < max_partitions) --- -2.17.2 - diff --git a/SOURCES/0034-libmultipath-fix-checker-detection-for-nvme-devices.patch b/SOURCES/0034-libmultipath-fix-checker-detection-for-nvme-devices.patch deleted file mode 100644 index ac5a32c..0000000 --- a/SOURCES/0034-libmultipath-fix-checker-detection-for-nvme-devices.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 30 Jun 2020 13:59:13 -0500 -Subject: [PATCH] libmultipath: fix checker detection for nvme devices - -In order to fix hwhandler autodetection, commit 8794a776 made -detect_alua() differentiate between failures to detect whether alua was -supported, and successfully detecting that it was not supported. -However, this causes nvme devices to get the TUR checker assigned to -them. This is because there is nothing in detect_alua() to make it only -work on scsi devices, and select_checker wasn't updated to handle -detect_alua() failing without setting pp->tpgs to TPGS_NONE. - -detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on -non-scsi devices. Also, select_checker() should not assume that a -devices is ALUA, simply because if failed to detect if alua was -supported. - -Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are - down" -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 6 ++++++ - libmultipath/propsel.c | 4 +++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 83a41a4a..aa5942c3 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -887,6 +887,12 @@ detect_alua(struct path * pp) - int tpgs; - unsigned int timeout; - -+ -+ if (pp->bus != SYSFS_BUS_SCSI) { -+ pp->tpgs = TPGS_NONE; -+ return; -+ } -+ - if (sysfs_get_timeout(pp, &timeout) <= 0) - timeout = DEF_TIMEOUT; - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 897e48ca..d362beb4 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -521,7 +521,9 @@ int select_checker(struct config *conf, struct path *pp) - if (check_rdac(pp)) { - ckr_name = RDAC; - goto out; -- } else if (path_get_tpgs(pp) != TPGS_NONE) { -+ } -+ path_get_tpgs(pp); -+ if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) { - ckr_name = TUR; - goto out; - } --- -2.17.2 - diff --git a/SOURCES/0035-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/SOURCES/0035-Makefile.inc-trim-extra-information-from-systemd-ver.patch deleted file mode 100644 index 27ce5fe..0000000 --- a/SOURCES/0035-Makefile.inc-trim-extra-information-from-systemd-ver.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Jul 2020 13:21:12 -0500 -Subject: [PATCH] Makefile.inc: trim extra information from systemd version - -Some systemd versions print extra information in the -"pkg-config --modversion" output, which confuses make. Trim this -off. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index c2abd301..220009e0 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,7 +37,7 @@ endif - - ifndef SYSTEMD - ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell pkg-config --modversion libsystemd) -+ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}') - else - ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1) - SYSTEMD = $(shell systemctl --version 2> /dev/null | \ --- -2.17.2 - diff --git a/SOURCES/0036-kpartx-fix-Wsign-compare-error.patch b/SOURCES/0036-kpartx-fix-Wsign-compare-error.patch deleted file mode 100644 index ffaa477..0000000 --- a/SOURCES/0036-kpartx-fix-Wsign-compare-error.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 6 Jul 2020 17:28:46 -0500 -Subject: [PATCH] kpartx: fix -Wsign-compare error - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index c24ad6d9..653ce0c8 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -738,7 +738,7 @@ struct block { - /* blknr is always in 512 byte blocks */ - char * - getblock (int fd, unsigned int blknr) { -- unsigned int secsz = get_sector_size(fd); -+ int secsz = get_sector_size(fd); - unsigned int blks_per_sec = secsz / 512; - unsigned int secnr = blknr / blks_per_sec; - unsigned int blk_off = (blknr % blks_per_sec) * 512; --- -2.17.2 - diff --git a/SOURCES/0037-libmultipath-count-pending-paths-as-active-on-loads.patch b/SOURCES/0037-libmultipath-count-pending-paths-as-active-on-loads.patch deleted file mode 100644 index d4ff3c2..0000000 --- a/SOURCES/0037-libmultipath-count-pending-paths-as-active-on-loads.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 7159242be31dbb3f25aa67920462107bc2bc5fe0 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 9 Jul 2020 18:20:18 -0500 -Subject: [PATCH] libmultipath: count pending paths as active on loads - -When multipath loads a table, it signals to udev if there are no active -paths. Multipath wasn't counting pending paths as active. This meant -that if all the paths were pending, udev would treat the device as not -ready, and not run kpartx on it. Even if the pending paths later -because active and were reinstated, the kernel would not send a new -uevent, because from its point of view, they were always up. - -The alternative would be to continue to treat them as failed in the udev -rules, but then also tell the kernel that they were down, so that it -would trigger a uevent when they were reinstated. However, this could -lead to newly created multipath devices failing IO, simply because the -path checkers hadn't returned yet. Having udev assume that the the -device is up, like the kernel does, seems like the safer option. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 3 ++- - libmultipath/structs.c | 20 ++++++++++++++++++++ - libmultipath/structs.h | 1 + - 3 files changed, 23 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 7f98bf9d..91ff0b3d 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -408,7 +408,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload) - /* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */ - return (mpp->skip_kpartx == SKIP_KPARTX_ON ? - MPATH_UDEV_NO_KPARTX_FLAG : 0) | -- ((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ? -+ ((count_active_pending_paths(mpp) == 0 || -+ mpp->ghost_delay_tick > 0) ? - MPATH_UDEV_NO_PATHS_FLAG : 0) | - (reload && !mpp->force_udev_reload ? - MPATH_UDEV_RELOAD_FLAG : 0); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 2dd378c4..dda9884c 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -500,6 +500,26 @@ int count_active_paths(const struct multipath *mpp) - return count; - } - -+int count_active_pending_paths(const struct multipath *mpp) -+{ -+ struct pathgroup *pgp; -+ struct path *pp; -+ int count = 0; -+ int i, j; -+ -+ if (!mpp->pg) -+ return 0; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if (pp->state == PATH_UP || pp->state == PATH_GHOST || -+ pp->state == PATH_PENDING) -+ count++; -+ } -+ } -+ return count; -+} -+ - int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) - { - int i, j; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9bd39eb1..8e78b8c0 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -465,6 +465,7 @@ struct path * first_path (const struct multipath *mpp); - int pathcountgr (const struct pathgroup *, int); - int pathcount (const struct multipath *, int); - int count_active_paths(const struct multipath *); -+int count_active_pending_paths(const struct multipath *); - int pathcmp (const struct pathgroup *, const struct pathgroup *); - int add_feature (char **, const char *); - int remove_feature (char **, const char *); --- -2.17.2 - diff --git a/SOURCES/0038-multipath-deal-with-failures-flushing-maps.patch b/SOURCES/0038-multipath-deal-with-failures-flushing-maps.patch deleted file mode 100644 index a73e25f..0000000 --- a/SOURCES/0038-multipath-deal-with-failures-flushing-maps.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 13 Jul 2020 15:41:15 -0500 -Subject: [PATCH] multipath: deal with failures flushing maps - -dm_flush_maps() was failing if there were no device-mapper devices at -all, instead of returning success, since there is nothing to do. - -delegate_to_multipathd() was returning success, even if the multipathd -command failed. Also, if the command was set to fail with NOT_DELEGATED, -it shouldn't print any errors, since multipath will try to issue to -command itself. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - multipath/main.c | 9 ++++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 91ff0b3d..3f70e576 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -970,10 +970,10 @@ int dm_flush_maps (int need_suspend, int retries) - if (!(names = dm_task_get_names (dmt))) - goto out; - -+ r = 0; - if (!names->dev) - goto out; - -- r = 0; - do { - if (need_suspend) - r |= dm_suspend_and_flush_map(names->name, retries); -diff --git a/multipath/main.c b/multipath/main.c -index 3c3d2398..607cada2 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -869,9 +869,12 @@ int delegate_to_multipathd(enum mpath_cmds cmd, - goto out; - } - -- if (reply != NULL && *reply != '\0' && strcmp(reply, "ok\n")) -- printf("%s", reply); -- r = DELEGATE_OK; -+ if (reply != NULL && *reply != '\0') { -+ if (strcmp(reply, "fail\n")) -+ r = DELEGATE_OK; -+ if (r != NOT_DELEGATED && strcmp(reply, "ok\n")) -+ printf("%s", reply); -+ } - - out: - FREE(reply); --- -2.17.2 - diff --git a/SOURCES/0039-libmultipath-factor-out-code-to-get-vpd-page-data.patch b/SOURCES/0039-libmultipath-factor-out-code-to-get-vpd-page-data.patch deleted file mode 100644 index 9862e22..0000000 --- a/SOURCES/0039-libmultipath-factor-out-code-to-get-vpd-page-data.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 3 Nov 2020 14:27:58 -0600 -Subject: [PATCH] libmultipath: factor out code to get vpd page data - -A future patch will reuse the code to get the vpd page data, so factor -it out from get_vpd_sgio(). - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index aa5942c3..eb1e735d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1239,11 +1239,10 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen) - return len; - } - --int --get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) -+static int -+fetch_vpd_page(int fd, int pg, unsigned char *buff) - { -- int len, buff_len; -- unsigned char buff[4096]; -+ int buff_len; - - memset(buff, 0x0, 4096); - if (sgio_get_vpd(buff, 4096, fd, pg) < 0) { -@@ -1264,6 +1263,18 @@ get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) - condlog(3, "vpd pg%02x page truncated", pg); - buff_len = 4096; - } -+ return buff_len; -+} -+ -+int -+get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) -+{ -+ int len, buff_len; -+ unsigned char buff[4096]; -+ -+ buff_len = fetch_vpd_page(fd, pg, buff); -+ if (buff_len < 0) -+ return buff_len; - if (pg == 0x80) - len = parse_vpd_pg80(buff, str, maxlen); - else if (pg == 0x83) --- -2.17.2 - diff --git a/SOURCES/0040-libmultipath-limit-reading-0xc9-vpd-page.patch b/SOURCES/0040-libmultipath-limit-reading-0xc9-vpd-page.patch deleted file mode 100644 index d23bdaf..0000000 --- a/SOURCES/0040-libmultipath-limit-reading-0xc9-vpd-page.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 7 Oct 2020 21:43:02 -0500 -Subject: [PATCH] libmultipath: limit reading 0xc9 vpd page - -Only rdac arrays support 0xC9 vpd page inquiries. All other arrays will -return a failure. Only do the rdac inquiry when detecting array -capabilities if the array's path checker is explicitly set to rdac, or -the path checker is not set, and the array reports that it supports vpd -page 0xC9 in the Supported VPD Pages (0x00) vpd page. - -Multipath was doing the check if either the path checker was set to -rdac, or no path checker was set. This means that for almost all -non-rdac arrays, multipath was issuing a bad inquiry. This was annoying -users. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 25 +++++++++++++++++++++++++ - libmultipath/discovery.h | 1 + - libmultipath/propsel.c | 10 ++++++---- - 3 files changed, 32 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index eb1e735d..01aadba9 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1266,6 +1266,31 @@ fetch_vpd_page(int fd, int pg, unsigned char *buff) - return buff_len; - } - -+/* heavily based on sg_inq.c from sg3_utils */ -+bool -+is_vpd_page_supported(int fd, int pg) -+{ -+ int i, len, buff_len; -+ unsigned char buff[4096]; -+ -+ buff_len = fetch_vpd_page(fd, 0x00, buff); -+ if (buff_len < 0) -+ return false; -+ if (buff_len < 4) { -+ condlog(3, "VPD page 00h too short"); -+ return false; -+ } -+ -+ len = buff[3] + 4; -+ if (len > buff_len) -+ condlog(3, "vpd page 00h trucated, expected %d, have %d", -+ len, buff_len); -+ for (i = 4; i < len; ++i) -+ if (buff[i] == pg) -+ return true; -+ return false; -+} -+ - int - get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen) - { -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 6444887d..d3193daf 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -56,6 +56,7 @@ int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); - int get_uid(struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback); -+bool is_vpd_page_supported(int fd, int pg); - - /* - * discovery bitmask -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d362beb4..d7febec6 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -496,13 +496,15 @@ check_rdac(struct path * pp) - { - int len; - char buff[44]; -- const char *checker_name; -+ const char *checker_name = NULL; - - if (pp->bus != SYSFS_BUS_SCSI) - return 0; -- /* Avoid ioctl if this is likely not an RDAC array */ -- if (__do_set_from_hwe(checker_name, pp, checker_name) && -- strcmp(checker_name, RDAC)) -+ /* Avoid checking 0xc9 if this is likely not an RDAC array */ -+ if (!__do_set_from_hwe(checker_name, pp, checker_name) && -+ !is_vpd_page_supported(pp->fd, 0xC9)) -+ return 0; -+ if (checker_name && strcmp(checker_name, RDAC)) - return 0; - len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44); - if (len <= 0) --- -2.17.2 - diff --git a/SOURCES/0041-libmultipath-add-device-to-hwtable.c.patch b/SOURCES/0041-libmultipath-add-device-to-hwtable.c.patch deleted file mode 100644 index 9d5e780..0000000 --- a/SOURCES/0041-libmultipath-add-device-to-hwtable.c.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Steve Schremmer -Date: Mon, 6 Jul 2020 20:22:35 +0000 -Subject: [PATCH] libmultipath: add device to hwtable.c - -Add FUJITSU ETERNUS_AHB defaults. - -Signed-off-by: Steve Schremmer -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d1fcfdb3..d680bdfc 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -428,6 +428,22 @@ static struct hwentry default_hw[] = { - .pgpolicy = MULTIBUS, - .no_path_retry = 10, - }, -+ { -+ /* -+ * ETERNUS AB/HB -+ * Maintainer: NetApp RDAC team -+ */ -+ .vendor = "FUJITSU", -+ .product = "ETERNUS_AHB", -+ .bl_product = "Universal Xport", -+ .pgpolicy = GROUP_BY_PRIO, -+ .checker_name = RDAC, -+ .features = "2 pg_init_retries 50", -+ .hwhandler = "1 rdac", -+ .prio_name = PRIO_RDAC, -+ .pgfailback = -FAILBACK_IMMEDIATE, -+ .no_path_retry = 30, -+ }, - /* - * Hitachi Vantara - * --- -2.17.2 - diff --git a/SOURCES/0042-libmultipath-move-fast_io_fail-defines-to-structs.h.patch b/SOURCES/0042-libmultipath-move-fast_io_fail-defines-to-structs.h.patch deleted file mode 100644 index 0cd6997..0000000 --- a/SOURCES/0042-libmultipath-move-fast_io_fail-defines-to-structs.h.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 12 Oct 2020 16:06:11 -0500 -Subject: [PATCH] libmultipath: move fast_io_fail defines to structs.h - -Since fast_io_fail is part of the multipath struct, its symbolic values -belong in structs.h. Also, make it an instance of a general enum, which -will be used again in future patches, and change the set/print functions -which use it to use the general enum instead. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 8 -------- - libmultipath/dict.c | 30 +++++++++++++++--------------- - libmultipath/dict.h | 2 +- - libmultipath/propsel.c | 2 +- - libmultipath/structs.h | 17 +++++++++++++++++ - 5 files changed, 34 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 160867cd..f38c7639 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -11,14 +11,6 @@ - #define ORIGIN_CONFIG 1 - #define ORIGIN_NO_CONFIG 2 - --/* -- * In kernel, fast_io_fail == 0 means immediate failure on rport delete. -- * OTOH '0' means not-configured in various places in multipath-tools. -- */ --#define MP_FAST_IO_FAIL_UNSET (0) --#define MP_FAST_IO_FAIL_OFF (-1) --#define MP_FAST_IO_FAIL_ZERO (-2) -- - enum devtypes { - DEV_NONE, - DEV_DEVT, -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 184d4b22..ce8e1cda 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -834,7 +834,7 @@ declare_mp_attr_handler(gid, set_gid) - declare_mp_attr_snprint(gid, print_gid) - - static int --set_fast_io_fail(vector strvec, void *ptr) -+set_undef_off_zero(vector strvec, void *ptr) - { - char * buff; - int *int_ptr = (int *)ptr; -@@ -844,36 +844,36 @@ set_fast_io_fail(vector strvec, void *ptr) - return 1; - - if (strcmp(buff, "off") == 0) -- *int_ptr = MP_FAST_IO_FAIL_OFF; -+ *int_ptr = UOZ_OFF; - else if (sscanf(buff, "%d", int_ptr) != 1 || -- *int_ptr < MP_FAST_IO_FAIL_ZERO) -- *int_ptr = MP_FAST_IO_FAIL_UNSET; -+ *int_ptr < UOZ_ZERO) -+ *int_ptr = UOZ_UNDEF; - else if (*int_ptr == 0) -- *int_ptr = MP_FAST_IO_FAIL_ZERO; -+ *int_ptr = UOZ_ZERO; - - FREE(buff); - return 0; - } - - int --print_fast_io_fail(char * buff, int len, long v) -+print_undef_off_zero(char * buff, int len, long v) - { -- if (v == MP_FAST_IO_FAIL_UNSET) -+ if (v == UOZ_UNDEF) - return 0; -- if (v == MP_FAST_IO_FAIL_OFF) -+ if (v == UOZ_OFF) - return snprintf(buff, len, "\"off\""); -- if (v == MP_FAST_IO_FAIL_ZERO) -+ if (v == UOZ_ZERO) - return snprintf(buff, len, "0"); - return snprintf(buff, len, "%ld", v); - } - --declare_def_handler(fast_io_fail, set_fast_io_fail) --declare_def_snprint_defint(fast_io_fail, print_fast_io_fail, -+declare_def_handler(fast_io_fail, set_undef_off_zero) -+declare_def_snprint_defint(fast_io_fail, print_undef_off_zero, - DEFAULT_FAST_IO_FAIL) --declare_ovr_handler(fast_io_fail, set_fast_io_fail) --declare_ovr_snprint(fast_io_fail, print_fast_io_fail) --declare_hw_handler(fast_io_fail, set_fast_io_fail) --declare_hw_snprint(fast_io_fail, print_fast_io_fail) -+declare_ovr_handler(fast_io_fail, set_undef_off_zero) -+declare_ovr_snprint(fast_io_fail, print_undef_off_zero) -+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) -diff --git a/libmultipath/dict.h b/libmultipath/dict.h -index a40ac66f..a917e1ca 100644 ---- a/libmultipath/dict.h -+++ b/libmultipath/dict.h -@@ -13,7 +13,7 @@ int print_rr_weight(char *buff, int len, long v); - int print_pgfailback(char *buff, int len, long v); - int print_pgpolicy(char *buff, int len, long v); - int print_no_path_retry(char *buff, int len, long v); --int print_fast_io_fail(char *buff, int len, long v); -+int print_undef_off_zero(char *buff, int len, long v); - int print_dev_loss(char *buff, int len, unsigned long v); - int print_reservation_key(char * buff, int len, struct be64 key, uint8_t - flags, int source); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d7febec6..725db2b1 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -755,7 +755,7 @@ int select_fast_io_fail(struct config *conf, struct multipath *mp) - mp_set_conf(fast_io_fail); - mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); - out: -- print_fast_io_fail(buff, 12, mp->fast_io_fail); -+ print_undef_off_zero(buff, 12, mp->fast_io_fail); - condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin); - return 0; - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 8e78b8c0..29209984 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -229,6 +229,23 @@ enum vpd_vendor_ids { - VPD_VP_ARRAY_SIZE, /* This must remain the last entry */ - }; - -+/* -+ * Multipath treats 0 as undefined for optional config parameters. -+ * Use this for cases where 0 is a valid option for systems multipath -+ * is communicating with -+ */ -+enum undefined_off_zero { -+ UOZ_UNDEF = 0, -+ UOZ_OFF = -1, -+ UOZ_ZERO = -2, -+}; -+ -+enum fast_io_fail_states { -+ MP_FAST_IO_FAIL_UNSET = UOZ_UNDEF, -+ MP_FAST_IO_FAIL_OFF = UOZ_OFF, -+ MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; --- -2.17.2 - diff --git a/SOURCES/0043-libmultipath-add-eh_deadline-multipath.conf-paramete.patch b/SOURCES/0043-libmultipath-add-eh_deadline-multipath.conf-paramete.patch deleted file mode 100644 index a8ebb2c..0000000 --- a/SOURCES/0043-libmultipath-add-eh_deadline-multipath.conf-paramete.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 14 Oct 2020 18:38:20 -0500 -Subject: [PATCH] libmultipath: add eh_deadline multipath.conf parameter - -There are times a fc rport is never lost, meaning that fast_io_fail_tmo -and dev_loss_tmo never trigger, but scsi commands still hang. This can -cause problems in cases where users have string timing requirements, and -the easiest way to solve these issues is to set eh_deadline. Since it's -already possible to set fast_io_fail_tmo and dev_loss_tmo from -multipath.conf, and have multipath take care of setting it correctly for -the scsi devices in sysfs, it makes sense to allow users to set -eh_deadline here as well. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 2 ++ - libmultipath/config.h | 2 ++ - libmultipath/configure.c | 1 + - libmultipath/dict.c | 10 +++++++ - libmultipath/discovery.c | 58 +++++++++++++++++++++++++++++++++----- - libmultipath/propsel.c | 17 +++++++++++ - libmultipath/propsel.h | 1 + - libmultipath/structs.h | 7 +++++ - multipath/multipath.conf.5 | 16 +++++++++++ - 9 files changed, 107 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 26f8e050..a71db2d0 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -359,6 +359,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - merge_num(flush_on_last_del); - merge_num(fast_io_fail); - merge_num(dev_loss); -+ merge_num(eh_deadline); - merge_num(user_friendly_names); - merge_num(retain_hwhandler); - merge_num(detect_prio); -@@ -514,6 +515,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe) - hwe->flush_on_last_del = dhwe->flush_on_last_del; - hwe->fast_io_fail = dhwe->fast_io_fail; - hwe->dev_loss = dhwe->dev_loss; -+ hwe->eh_deadline = dhwe->eh_deadline; - hwe->user_friendly_names = dhwe->user_friendly_names; - hwe->retain_hwhandler = dhwe->retain_hwhandler; - hwe->detect_prio = dhwe->detect_prio; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index f38c7639..a22c1b4e 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -64,6 +64,7 @@ struct hwentry { - int flush_on_last_del; - int fast_io_fail; - unsigned int dev_loss; -+ int eh_deadline; - int user_friendly_names; - int retain_hwhandler; - int detect_prio; -@@ -149,6 +150,7 @@ struct config { - int attribute_flags; - int fast_io_fail; - unsigned int dev_loss; -+ int eh_deadline; - int log_checker_err; - int allow_queueing; - int find_multipaths; -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 96c79610..b7113291 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -340,6 +340,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_gid(conf, mpp); - select_fast_io_fail(conf, mpp); - select_dev_loss(conf, mpp); -+ select_eh_deadline(conf, mpp); - select_reservation_key(conf, mpp); - select_deferred_remove(conf, mpp); - select_marginal_path_err_sample_time(conf, mpp); -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index ce8e1cda..8fd91d8c 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -911,6 +911,13 @@ declare_ovr_snprint(dev_loss, print_dev_loss) - declare_hw_handler(dev_loss, set_dev_loss) - declare_hw_snprint(dev_loss, print_dev_loss) - -+declare_def_handler(eh_deadline, set_undef_off_zero) -+declare_def_snprint(eh_deadline, print_undef_off_zero) -+declare_ovr_handler(eh_deadline, set_undef_off_zero) -+declare_ovr_snprint(eh_deadline, print_undef_off_zero) -+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) - { -@@ -1776,6 +1783,7 @@ init_keywords(vector keywords) - install_keyword("gid", &def_gid_handler, &snprint_def_gid); - install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail); - install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); -+ install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline); - install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file); - install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file); - install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file); -@@ -1885,6 +1893,7 @@ init_keywords(vector keywords) - install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del); - install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail); - install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss); -+ install_keyword("eh_deadline", &hw_eh_deadline_handler, &snprint_hw_eh_deadline); - install_keyword("user_friendly_names", &hw_user_friendly_names_handler, &snprint_hw_user_friendly_names); - install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler); - install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_hw_detect_prio); -@@ -1925,6 +1934,7 @@ init_keywords(vector keywords) - install_keyword("flush_on_last_del", &ovr_flush_on_last_del_handler, &snprint_ovr_flush_on_last_del); - install_keyword("fast_io_fail_tmo", &ovr_fast_io_fail_handler, &snprint_ovr_fast_io_fail); - install_keyword("dev_loss_tmo", &ovr_dev_loss_handler, &snprint_ovr_dev_loss); -+ install_keyword("eh_deadline", &ovr_eh_deadline_handler, &snprint_ovr_eh_deadline); - install_keyword("user_friendly_names", &ovr_user_friendly_names_handler, &snprint_ovr_user_friendly_names); - install_keyword("retain_attached_hw_handler", &ovr_retain_hwhandler_handler, &snprint_ovr_retain_hwhandler); - install_keyword("detect_prio", &ovr_detect_prio_handler, &snprint_ovr_detect_prio); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 01aadba9..a328aafa 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -577,6 +577,42 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - return !!preferred; - } - -+static int -+sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp) -+{ -+ struct udev_device *hostdev; -+ char host_name[HOST_NAME_LEN], value[16]; -+ int ret; -+ -+ if (mpp->eh_deadline == EH_DEADLINE_UNSET) -+ return 0; -+ -+ sprintf(host_name, "host%d", pp->sg_id.host_no); -+ hostdev = udev_device_new_from_subsystem_sysname(udev, -+ "scsi_host", host_name); -+ if (!hostdev) -+ return 1; -+ -+ if (mpp->eh_deadline == EH_DEADLINE_OFF) -+ sprintf(value, "off"); -+ else if (mpp->eh_deadline == EH_DEADLINE_ZERO) -+ sprintf(value, "0"); -+ else -+ snprintf(value, 16, "%u", mpp->eh_deadline); -+ -+ ret = sysfs_attr_set_value(hostdev, "eh_deadline", -+ value, strlen(value)); -+ /* -+ * not all scsi drivers support setting eh_deadline, so failing -+ * is totally reasonable -+ */ -+ if (ret <= 0) -+ condlog(4, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret); -+ -+ udev_device_unref(hostdev); -+ return (ret <= 0); -+} -+ - static void - sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - { -@@ -787,16 +823,24 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) - mpp->alias, mpp->fast_io_fail); - mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF; - } -- if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET && -+ mpp->eh_deadline == EH_DEADLINE_UNSET) - return 0; - - vector_foreach_slot(mpp->paths, pp, i) { -- if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) -- sysfs_set_rport_tmo(mpp, pp); -- if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI) -- sysfs_set_session_tmo(mpp, pp); -- if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS) -- sysfs_set_nexus_loss_tmo(mpp, pp); -+ if (pp->bus != SYSFS_BUS_SCSI) -+ continue; -+ -+ if (mpp->dev_loss || -+ mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -+ if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) -+ sysfs_set_rport_tmo(mpp, pp); -+ else if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI) -+ sysfs_set_session_tmo(mpp, pp); -+ else if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS) -+ sysfs_set_nexus_loss_tmo(mpp, pp); -+ } -+ sysfs_set_eh_deadline(mpp, pp); - } - return 0; - } -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 725db2b1..1150cfe8 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -776,6 +776,23 @@ out: - return 0; - } - -+int select_eh_deadline(struct config *conf, struct multipath *mp) -+{ -+ const char *origin; -+ char buff[12]; -+ -+ mp_set_ovr(eh_deadline); -+ mp_set_hwe(eh_deadline); -+ mp_set_conf(eh_deadline); -+ mp->eh_deadline = EH_DEADLINE_UNSET; -+ /* not changing sysfs in default cause, so don't print anything */ -+ return 0; -+out: -+ print_undef_off_zero(buff, 12, mp->eh_deadline); -+ condlog(3, "%s: eh_deadline = %s %s", mp->alias, buff, origin); -+ return 0; -+} -+ - int select_flush_on_last_del(struct config *conf, struct multipath *mp) - { - const char *origin; -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index 3d6edd8a..a68bacf0 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -17,6 +17,7 @@ int select_uid(struct config *conf, struct multipath *mp); - int select_gid(struct config *conf, struct multipath *mp); - int select_fast_io_fail(struct config *conf, struct multipath *mp); - int select_dev_loss(struct config *conf, struct multipath *mp); -+int select_eh_deadline(struct config *conf, struct multipath *mp); - int select_reservation_key(struct config *conf, struct multipath *mp); - int select_retain_hwhandler (struct config *conf, struct multipath * mp); - int select_detect_prio(struct config *conf, struct path * pp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 29209984..65542dea 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -246,6 +246,12 @@ enum fast_io_fail_states { - MP_FAST_IO_FAIL_ZERO = UOZ_ZERO, - }; - -+enum eh_deadline_states { -+ EH_DEADLINE_UNSET = UOZ_UNDEF, -+ EH_DEADLINE_OFF = UOZ_OFF, -+ EH_DEADLINE_ZERO = UOZ_ZERO, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; -@@ -366,6 +372,7 @@ struct multipath { - int ghost_delay; - int ghost_delay_tick; - unsigned int dev_loss; -+ int eh_deadline; - uid_t uid; - gid_t gid; - mode_t mode; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 6dc26f10..60954574 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -700,6 +700,22 @@ The default is: \fB600\fR - . - . - .TP -+.B eh_deadline -+Specify the maximum number of seconds the SCSI layer will spend doing error -+handling when scsi devices fail. After this timeout the scsi layer will perform -+a full HBA reset. Setting this may be necessary in cases where the rport is -+never lost, so \fIfast_io_fail_tmo\fR and \fIdev_loss_tmo\fR will never -+trigger, but (frequently do to load) scsi commands still hang. \fBNote:\fR when -+the scsi error handler performs the HBA reset, all target paths on that HBA -+will be affected. eh_deadline should only be set in cases where all targets on -+the affected HBAs are multipathed. -+.RS -+.TP -+The default is: \fB\fR -+.RE -+. -+. -+.TP - .B bindings_file - The full pathname of the binding file to be used when the user_friendly_names - option is set. --- -2.17.2 - diff --git a/SOURCES/0044-libmultipath-don-t-dlclose-tur-checker-DSO.patch b/SOURCES/0044-libmultipath-don-t-dlclose-tur-checker-DSO.patch deleted file mode 100644 index 18ed578..0000000 --- a/SOURCES/0044-libmultipath-don-t-dlclose-tur-checker-DSO.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 23 Oct 2020 11:38:24 -0500 -Subject: [PATCH] libmultipath: don't dlclose tur checker DSO - -The multipathd tur checker thread is designed to be able to finish at -any time, even after the tur checker itself has been freed. The -multipathd shutdown code makes sure all the checkers have been freed -before freeing the checker_class and calling dlclose() to unload the -DSO, but this doesn't guarantee that the checker threads have finished. -If one hasn't, the DSO will get unloaded while the thread still running -code from it, causing a segfault. Unfortunately, it's not possible to be -sure that all tur checker threads have ended during shutdown, without -making them joinable. - -However, since libmultipath will never be reinitialized after it has -been uninitialzed, not dlclosing the tur checker DSO once a thread is -started has minimal cost (keeping the DSO code around until the program -exits, which usually happens right after freeing the checkers). - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers.c | 10 +++++++++- - libmultipath/checkers.h | 1 + - libmultipath/checkers/tur.c | 1 + - 3 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c -index 8d2be8a9..6359e5d8 100644 ---- a/libmultipath/checkers.c -+++ b/libmultipath/checkers.c -@@ -21,6 +21,7 @@ struct checker_class { - void (*reset)(void); /* to reset the global variables */ - const char **msgtable; - short msgtable_size; -+ int keep_dso; - }; - - char *checker_state_names[] = { -@@ -69,7 +70,7 @@ void free_checker_class(struct checker_class *c) - list_del(&c->node); - if (c->reset) - c->reset(); -- if (c->handle) { -+ if (c->handle && !c->keep_dso) { - if (dlclose(c->handle) != 0) { - condlog(0, "Cannot unload checker %s: %s", - c->name, dlerror()); -@@ -192,6 +193,13 @@ out: - return NULL; - } - -+void checker_keep_dso(struct checker * c) -+{ -+ if (!c || !c->cls) -+ return; -+ c->cls->keep_dso = 1; -+} -+ - void checker_set_fd (struct checker * c, int fd) - { - if (!c) -diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h -index b458118d..f183cff9 100644 ---- a/libmultipath/checkers.h -+++ b/libmultipath/checkers.h -@@ -145,6 +145,7 @@ void checker_reset (struct checker *); - void checker_set_sync (struct checker *); - void checker_set_async (struct checker *); - void checker_set_fd (struct checker *, int); -+void checker_keep_dso(struct checker *c); - void checker_enable (struct checker *); - void checker_disable (struct checker *); - int checker_check (struct checker *, int); -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index e886fcf8..fd58d62a 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -394,6 +394,7 @@ int libcheck_check(struct checker * c) - uatomic_set(&ct->running, 1); - tur_set_async_timeout(c); - setup_thread_attr(&attr, 32 * 1024, 1); -+ checker_keep_dso(c); - r = pthread_create(&ct->thread, &attr, tur_thread, ct); - pthread_attr_destroy(&attr); - if (r) { --- -2.17.2 - diff --git a/SOURCES/0045-libmultipath-warn-about-missing-braces-at-end-of-mul.patch b/SOURCES/0045-libmultipath-warn-about-missing-braces-at-end-of-mul.patch deleted file mode 100644 index f8f45f8..0000000 --- a/SOURCES/0045-libmultipath-warn-about-missing-braces-at-end-of-mul.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 16 Nov 2020 13:52:09 -0600 -Subject: [PATCH] libmultipath: warn about missing braces at end of - multipath.conf - -Multipath doesn't warn when multipath.conf is missing closing braces at -the end of the file. This has confused people about the correct config -file syntax, so add a warning. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/parser.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index a7285a35..48b54e87 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -544,7 +544,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, char *file) - if (!strcmp(str, EOB)) { - if (kw_level > 0) { - free_strvec(strvec); -- break; -+ goto out; - } - condlog(0, "unmatched '%s' at line %d of %s", - EOB, line_nr, file); -@@ -583,7 +583,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, char *file) - - free_strvec(strvec); - } -- -+ if (kw_level == 1) -+ condlog(1, "missing '%s' at end of %s", EOB, file); - out: - FREE(buf); - free_uniques(uniques); --- -2.17.2 - diff --git a/SOURCES/0046-libmultipath-ignore-multipaths-sections-without-wwid.patch b/SOURCES/0046-libmultipath-ignore-multipaths-sections-without-wwid.patch deleted file mode 100644 index 3ccf175..0000000 --- a/SOURCES/0046-libmultipath-ignore-multipaths-sections-without-wwid.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 16 Nov 2020 16:38:21 -0600 -Subject: [PATCH] libmultipath: ignore multipaths sections without wwid option - -"multipathd show config local" was crashing in find_mp_by_wwid() if -the multipath configuration included a multipaths section that did -not set a wwid option. There is no reason to keep a mpentry that -didn't set its wwid. Remove it in merge_mptable(). - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index a71db2d0..dc81c994 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -444,6 +444,13 @@ void merge_mptable(vector mptable) - int i, j; - - vector_foreach_slot(mptable, mp1, i) { -+ /* drop invalid multipath configs */ -+ if (!mp1->wwid) { -+ condlog(0, "multipaths config section missing wwid"); -+ vector_del_slot(mptable, i--); -+ free_mpe(mp1); -+ continue; -+ } - j = i + 1; - vector_foreach_slot_after(mptable, mp2, j) { - if (strcmp(mp1->wwid, mp2->wwid)) --- -2.17.2 - diff --git a/SOURCES/0047-tests-fix-missing-priority-blacklist-test.patch b/SOURCES/0047-tests-fix-missing-priority-blacklist-test.patch deleted file mode 100644 index a73ffe6..0000000 --- a/SOURCES/0047-tests-fix-missing-priority-blacklist-test.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 16 Nov 2020 23:21:41 -0600 -Subject: [PATCH] tests: fix missing priority blacklist test - -Signed-off-by: Benjamin Marzinski ---- - tests/blacklist.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/tests/blacklist.c b/tests/blacklist.c -index d20e97af..401600d9 100644 ---- a/tests/blacklist.c -+++ b/tests/blacklist.c -@@ -378,7 +378,6 @@ 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_NOTHING); - assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), --- -2.17.2 - diff --git a/SOURCES/0048-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch b/SOURCES/0048-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch deleted file mode 100644 index fa9d703..0000000 --- a/SOURCES/0048-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 5 Nov 2020 09:15:43 -0600 -Subject: [PATCH] mpathpersist: Fix Register and Ignore with 0x00 SARK - -When the Register and Ignore command is run with sg_persist, if a 0x00 -Service Action Reservation Key is given or the --param-sark option is -not used at all, sg_persist will clear the registration. mpathpersist -will fail with an error. This patch fixes mpathpersist to work like -sg_persist in this case. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 3da7a6cf..aa196008 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -321,7 +321,8 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - } - - if (memcmp(paramp->key, &mpp->reservation_key, 8) && -- memcmp(paramp->sa_key, &mpp->reservation_key, 8)) { -+ memcmp(paramp->sa_key, &mpp->reservation_key, 8) && -+ (prkey || rq_servact != MPATH_PROUT_REG_IGN_SA)) { - condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); - ret = MPATH_PR_SYNTAX_ERROR; - goto out1; --- -2.17.2 - diff --git a/SOURCES/0049-mpathpersist-update-prkeys-file-on-changing-registra.patch b/SOURCES/0049-mpathpersist-update-prkeys-file-on-changing-registra.patch deleted file mode 100644 index 0cd0ab2..0000000 --- a/SOURCES/0049-mpathpersist-update-prkeys-file-on-changing-registra.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 23 Nov 2020 20:45:50 -0600 -Subject: [PATCH] mpathpersist: update prkeys file on changing registrations - -When the "reservation_key" option is set to "file" and Register command -is run with both the current Reservation Key and a new Service Action -Reservation Key, mpathpersist will change the registration, but will not -update the prkeys file. This means that future paths that come online -will not be able to register, since multipathd is still using the old -reservation key. Fix this. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index aa196008..a01dfb0b 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -307,9 +307,10 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - - memcpy(&prkey, paramp->sa_key, 8); - if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && -- ((!get_be64(mpp->reservation_key) && -- rq_servact == MPATH_PROUT_REG_SA) || -- rq_servact == MPATH_PROUT_REG_IGN_SA)) { -+ (rq_servact == MPATH_PROUT_REG_IGN_SA || -+ (rq_servact == MPATH_PROUT_REG_SA && -+ (!get_be64(mpp->reservation_key) || -+ memcmp(paramp->key, &mpp->reservation_key, 8) == 0)))) { - memcpy(&mpp->reservation_key, paramp->sa_key, 8); - if (update_prkey_flags(alias, get_be64(mpp->reservation_key), - paramp->sa_flags)) { --- -2.17.2 - diff --git a/SOURCES/0050-multipathd-Fix-multipathd-stopping-on-shutdown.patch b/SOURCES/0050-multipathd-Fix-multipathd-stopping-on-shutdown.patch deleted file mode 100644 index a9f8969..0000000 --- a/SOURCES/0050-multipathd-Fix-multipathd-stopping-on-shutdown.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 14 Dec 2020 14:16:29 -0600 -Subject: [PATCH] multipathd: Fix multipathd stopping on shutdown - -According to man "systemd.special" - -"shutdown.target: ... Services that shall be terminated on system -shutdown shall add Conflicts= and Before= dependencies to this unit for -their service unit, which is implicitly done when -DefaultDependencies=yes is set (the default)." - -multipathd.service sets DefaultDependencies=no and includes the -Conflits= dependency, but not the Before= one. This can cause multipathd -to continue running past when it is supposed to during shutdown. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/multipathd.service | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 0fbcc46b..bc8fa07a 100644 ---- a/multipathd/multipathd.service -+++ b/multipathd/multipathd.service -@@ -2,7 +2,7 @@ - Description=Device-Mapper Multipath Device Controller - 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 -+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 --- -2.17.2 - diff --git a/SOURCES/0051-multipath.conf.5-Improve-checker_timeout-description.patch b/SOURCES/0051-multipath.conf.5-Improve-checker_timeout-description.patch deleted file mode 100644 index 1e1f249..0000000 --- a/SOURCES/0051-multipath.conf.5-Improve-checker_timeout-description.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 15 Dec 2020 12:47:14 -0600 -Subject: [PATCH] multipath.conf.5: Improve checker_timeout description - -I was asked to explain how checker_timeout works for checkers like -directio, that don't issue scsi commands with an explicit timeout - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 60954574..a5686090 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -634,8 +634,13 @@ The default is: \fBno\fR - . - .TP - .B checker_timeout --Specify the timeout to use for path checkers and prioritizers that issue SCSI --commands with an explicit timeout, in seconds. -+Specify the timeout to use for path checkers and prioritizers, in seconds. -+Only prioritizers that issue scsi commands use checker_timeout. Checkers -+that support an asynchronous mode (\fItur\fR and \fIdirectio\fR), will -+return shortly after being called by multipathd, regardless of whether the -+storage array responds. If the storage array hasn't responded, mulitpathd will -+check for a response every second, until \fIchecker_timeout\fR seconds have -+elapsed. - .RS - .TP - The default is: in \fB/sys/block/sd/device/timeout\fR --- -2.17.2 - diff --git a/SOURCES/0052-libmultipath-check-for-null-wwid-before-strcmp.patch b/SOURCES/0052-libmultipath-check-for-null-wwid-before-strcmp.patch deleted file mode 100644 index fe33783..0000000 --- a/SOURCES/0052-libmultipath-check-for-null-wwid-before-strcmp.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 4 Jan 2021 21:59:54 -0600 -Subject: [PATCH] libmultipath: check for null wwid before strcmp - -Commit 749aabd0 (libmultipath: ignore multipaths sections without wwid -option) removed all mpentries with a NULL wwid, but didn't stop strcmp() -from being run on them in merge_mptable(). The result of strcmp() with -a NULL parameter is undefined, so fix that. - -Signed-off-by: Benjamin Marzinski - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index dc81c994..dd645f17 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -453,7 +453,7 @@ void merge_mptable(vector mptable) - } - j = i + 1; - vector_foreach_slot_after(mptable, mp2, j) { -- if (strcmp(mp1->wwid, mp2->wwid)) -+ if (!mp2->wwid || strcmp(mp1->wwid, mp2->wwid)) - continue; - condlog(1, "%s: duplicate multipath config section for %s", - __func__, mp1->wwid); --- -2.17.2 - diff --git a/SOURCES/0053-libmultipath-make-find_err_path_by_dev-static.patch b/SOURCES/0053-libmultipath-make-find_err_path_by_dev-static.patch deleted file mode 100644 index 8375b10..0000000 --- a/SOURCES/0053-libmultipath-make-find_err_path_by_dev-static.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:22 -0600 -Subject: [PATCH] libmultipath: make find_err_path_by_dev() static - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 1b9cd6c0..449760a0 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -89,7 +89,7 @@ static void rcu_unregister(__attribute__((unused)) void *param) - rcu_unregister_thread(); - } - --struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) -+static struct io_err_stat_path *find_err_path_by_dev(vector pathvec, char *dev) - { - int i; - struct io_err_stat_path *pp; --- -2.17.2 - diff --git a/SOURCES/0054-multipathd-avoid-io_err_stat-crash-during-shutdown.patch b/SOURCES/0054-multipathd-avoid-io_err_stat-crash-during-shutdown.patch deleted file mode 100644 index 67aa4e2..0000000 --- a/SOURCES/0054-multipathd-avoid-io_err_stat-crash-during-shutdown.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:23 -0600 -Subject: [PATCH] multipathd: avoid io_err_stat crash during shutdown - -The checker thread is reponsible for enqueueing paths for the -io_err_stat thread to check. During shutdown, the io_err_stat thread is -shut down and cleaned up before the checker thread. There is no code -to make sure that the checker thread isn't accessing the io_err_stat -pathvec or its mutex while they are being freed, which can lead to -memory corruption crashes. - -To solve this, get rid of the io_err_stat_pathvec structure, and -statically define the mutex. This means that the mutex is always valid -to access, and the io_err_stat pathvec can only be accessed while -holding it. If the io_err_stat thread has already been cleaned up -when the checker tries to access the pathvec, it will be NULL, and the -checker will simply fail to enqueue the path. - -This change also fixes a bug in free_io_err_pathvec(), which previously -only attempted to free the pathvec if it was not set, instead of when it -was set. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 112 +++++++++++++++---------------------- - libmultipath/util.c | 5 ++ - libmultipath/util.h | 1 + - 3 files changed, 50 insertions(+), 68 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 449760a0..f6c564f0 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -34,6 +34,7 @@ - #include "lock.h" - #include "time-util.h" - #include "io_err_stat.h" -+#include "util.h" - - #define IOTIMEOUT_SEC 60 - #define TIMEOUT_NO_IO_NSEC 10000000 /*10ms = 10000000ns*/ -@@ -46,12 +47,6 @@ - #define io_err_stat_log(prio, fmt, args...) \ - condlog(prio, "io error statistic: " fmt, ##args) - -- --struct io_err_stat_pathvec { -- pthread_mutex_t mutex; -- vector pathvec; --}; -- - struct dio_ctx { - struct timespec io_starttime; - unsigned int blksize; -@@ -76,9 +71,10 @@ pthread_attr_t io_err_stat_attr; - - static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER; - static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER; -+static pthread_mutex_t io_err_pathvec_lock = PTHREAD_MUTEX_INITIALIZER; - static int io_err_thread_running = 0; - --static struct io_err_stat_pathvec *paths; -+static vector io_err_pathvec; - struct vectors *vecs; - io_context_t ioctx; - -@@ -208,46 +204,23 @@ static void free_io_err_stat_path(struct io_err_stat_path *p) - FREE(p); - } - --static struct io_err_stat_pathvec *alloc_pathvec(void) --{ -- struct io_err_stat_pathvec *p; -- int r; -- -- p = (struct io_err_stat_pathvec *)MALLOC(sizeof(*p)); -- if (!p) -- return NULL; -- p->pathvec = vector_alloc(); -- if (!p->pathvec) -- goto out_free_struct_pathvec; -- r = pthread_mutex_init(&p->mutex, NULL); -- if (r) -- goto out_free_member_pathvec; -- -- return p; -- --out_free_member_pathvec: -- vector_free(p->pathvec); --out_free_struct_pathvec: -- FREE(p); -- return NULL; --} -- --static void free_io_err_pathvec(struct io_err_stat_pathvec *p) -+static void free_io_err_pathvec(void) - { - struct io_err_stat_path *path; - int i; - -- if (!p) -- return; -- pthread_mutex_destroy(&p->mutex); -- if (!p->pathvec) { -- vector_foreach_slot(p->pathvec, path, i) { -- destroy_directio_ctx(path); -- free_io_err_stat_path(path); -- } -- vector_free(p->pathvec); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); -+ if (!io_err_pathvec) -+ goto out; -+ vector_foreach_slot(io_err_pathvec, path, i) { -+ destroy_directio_ctx(path); -+ free_io_err_stat_path(path); - } -- FREE(p); -+ vector_free(io_err_pathvec); -+ io_err_pathvec = NULL; -+out: -+ pthread_cleanup_pop(1); - } - - /* -@@ -259,13 +232,13 @@ static int enqueue_io_err_stat_by_path(struct path *path) - { - struct io_err_stat_path *p; - -- pthread_mutex_lock(&paths->mutex); -- p = find_err_path_by_dev(paths->pathvec, path->dev); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ p = find_err_path_by_dev(io_err_pathvec, path->dev); - if (p) { -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - return 0; - } -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - p = alloc_io_err_stat_path(); - if (!p) -@@ -277,18 +250,18 @@ static int enqueue_io_err_stat_by_path(struct path *path) - - if (setup_directio_ctx(p)) - goto free_ioerr_path; -- pthread_mutex_lock(&paths->mutex); -- if (!vector_alloc_slot(paths->pathvec)) -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ if (!vector_alloc_slot(io_err_pathvec)) - goto unlock_destroy; -- vector_set_slot(paths->pathvec, p); -- pthread_mutex_unlock(&paths->mutex); -+ vector_set_slot(io_err_pathvec, p); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - io_err_stat_log(2, "%s: enqueue path %s to check", - path->mpp->alias, path->dev); - return 0; - - unlock_destroy: -- pthread_mutex_unlock(&paths->mutex); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - destroy_directio_ctx(p); - free_ioerr_path: - free_io_err_stat_path(p); -@@ -421,9 +394,9 @@ static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) - { - int i; - -- i = find_slot(paths->pathvec, p); -+ i = find_slot(io_err_pathvec, p); - if (i != -1) -- vector_del_slot(paths->pathvec, i); -+ vector_del_slot(io_err_pathvec, i); - - destroy_directio_ctx(p); - free_io_err_stat_path(p); -@@ -594,7 +567,7 @@ static void poll_async_io_timeout(void) - - if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) - return; -- vector_foreach_slot(paths->pathvec, pp, i) { -+ vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, - &curr_time, pp->devname); -@@ -640,7 +613,7 @@ static void handle_async_io_done_event(struct io_event *io_evt) - int rc = PATH_UNCHECKED; - int i, j; - -- vector_foreach_slot(paths->pathvec, pp, i) { -+ vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - ct = pp->dio_ctx_array + j; - if (&ct->io == io_evt->obj) { -@@ -674,19 +647,14 @@ static void service_paths(void) - struct io_err_stat_path *pp; - int i; - -- pthread_mutex_lock(&paths->mutex); -- vector_foreach_slot(paths->pathvec, pp, i) { -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ vector_foreach_slot(io_err_pathvec, pp, i) { - send_batch_async_ios(pp); - process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); - poll_async_io_timeout(); - poll_io_err_stat(vecs, pp); - } -- pthread_mutex_unlock(&paths->mutex); --} -- --static void cleanup_unlock(void *arg) --{ -- pthread_mutex_unlock((pthread_mutex_t*) arg); -+ pthread_mutex_unlock(&io_err_pathvec_lock); - } - - static void cleanup_exited(__attribute__((unused)) void *arg) -@@ -744,12 +712,17 @@ int start_io_err_stat_thread(void *data) - io_err_stat_log(4, "io_setup failed"); - return 1; - } -- paths = alloc_pathvec(); -- if (!paths) -+ -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ io_err_pathvec = vector_alloc(); -+ if (!io_err_pathvec) { -+ pthread_mutex_unlock(&io_err_pathvec_lock); - goto destroy_ctx; -+ } -+ pthread_mutex_unlock(&io_err_pathvec_lock); - - pthread_mutex_lock(&io_err_thread_lock); -- pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_thread_lock); - - ret = pthread_create(&io_err_stat_thr, &io_err_stat_attr, - io_err_stat_loop, data); -@@ -769,7 +742,10 @@ int start_io_err_stat_thread(void *data) - return 0; - - out_free: -- free_io_err_pathvec(paths); -+ pthread_mutex_lock(&io_err_pathvec_lock); -+ vector_free(io_err_pathvec); -+ io_err_pathvec = NULL; -+ pthread_mutex_unlock(&io_err_pathvec_lock); - destroy_ctx: - io_destroy(ioctx); - io_err_stat_log(0, "failed to start io_error statistic thread"); -@@ -785,6 +761,6 @@ void stop_io_err_stat_thread(void) - pthread_cancel(io_err_stat_thr); - - pthread_join(io_err_stat_thr, NULL); -- free_io_err_pathvec(paths); -+ free_io_err_pathvec(); - io_destroy(ioctx); - } -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 51c38c87..dd30a46e 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -469,3 +469,8 @@ void close_fd(void *arg) - { - close((long)arg); - } -+ -+void cleanup_mutex(void *arg) -+{ -+ pthread_mutex_unlock(arg); -+} -diff --git a/libmultipath/util.h b/libmultipath/util.h -index 56bd78c7..ce277680 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -44,6 +44,7 @@ void set_max_fds(rlim_t max_fds); - pthread_cleanup_push(((void (*)(void *))&f), (arg)) - - void close_fd(void *arg); -+void cleanup_mutex(void *arg); - - struct scandir_result { - struct dirent **di; --- -2.17.2 - diff --git a/SOURCES/0055-multipathd-avoid-io_err_stat-ABBA-deadlock.patch b/SOURCES/0055-multipathd-avoid-io_err_stat-ABBA-deadlock.patch deleted file mode 100644 index 8fd1605..0000000 --- a/SOURCES/0055-multipathd-avoid-io_err_stat-ABBA-deadlock.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:24 -0600 -Subject: [PATCH] multipathd: avoid io_err_stat ABBA deadlock - -When the checker thread enqueues paths for the io_err_stat thread to -check, it calls enqueue_io_err_stat_by_path() with the vecs lock held. -start_io_err_stat_thread() is also called with the vecs lock held. -These two functions both lock io_err_pathvec_lock. When the io_err_stat -thread updates the paths in vecs->pathvec in poll_io_err_stat(), it has -the io_err_pathvec_lock held, and then locks the vecs lock. This can -cause an ABBA deadlock. - -To solve this, service_paths() no longer updates the paths in -vecs->pathvec with the io_err_pathvec_lock held. It does this by moving -the io_err_stat_path from io_err_pathvec to a local vector when it needs -to update the path. After releasing the io_err_pathvec_lock, it goes -through this temporary vector, updates the paths with the vecs lock -held, and then frees everything. - -This change fixes a bug in service_paths() where elements were being -deleted from io_err_pathvec, without the index being decremented, -causing the loop to skip elements. Also, service_paths() could be -cancelled while holding the io_err_pathvec_lock, so it should have a -cleanup handler. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 56 ++++++++++++++++++++++---------------- - 1 file changed, 32 insertions(+), 24 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index f6c564f0..63ee2e07 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -390,20 +390,6 @@ recover: - return 0; - } - --static int delete_io_err_stat_by_addr(struct io_err_stat_path *p) --{ -- int i; -- -- i = find_slot(io_err_pathvec, p); -- if (i != -1) -- vector_del_slot(io_err_pathvec, i); -- -- destroy_directio_ctx(p); -- free_io_err_stat_path(p); -- -- return 0; --} -- - static void account_async_io_state(struct io_err_stat_path *pp, int rc) - { - switch (rc) { -@@ -420,17 +406,26 @@ static void account_async_io_state(struct io_err_stat_path *pp, int rc) - } - } - --static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) -+static int io_err_stat_time_up(struct io_err_stat_path *pp) - { - struct timespec currtime, difftime; -- struct path *path; -- double err_rate; - - if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return 1; -+ return 0; - timespecsub(&currtime, &pp->start_time, &difftime); - if (difftime.tv_sec < pp->total_time) - return 0; -+ return 1; -+} -+ -+static void end_io_err_stat(struct io_err_stat_path *pp) -+{ -+ struct timespec currtime; -+ struct path *path; -+ double err_rate; -+ -+ if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -+ currtime = pp->start_time; - - io_err_stat_log(4, "%s: check end", pp->devname); - -@@ -469,10 +464,6 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) - pp->devname); - } - lock_cleanup_pop(vecs->lock); -- -- delete_io_err_stat_by_addr(pp); -- -- return 0; - } - - static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) -@@ -632,6 +623,7 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) - struct timespec timeout = { .tv_nsec = timeout_nsecs }; - - errno = 0; -+ pthread_testcancel(); - n = io_getevents(ioctx, 1L, CONCUR_NR_EVENT, events, &timeout); - if (n < 0) { - io_err_stat_log(3, "%s: async io events returned %d (errno=%s)", -@@ -644,17 +636,33 @@ static void process_async_ios_event(int timeout_nsecs, char *dev) - - static void service_paths(void) - { -+ struct _vector _pathvec = {0}; -+ /* avoid gcc warnings that &_pathvec will never be NULL in vector ops */ -+ struct _vector * const tmp_pathvec = &_pathvec; - struct io_err_stat_path *pp; - int i; - - pthread_mutex_lock(&io_err_pathvec_lock); -+ pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); - vector_foreach_slot(io_err_pathvec, pp, i) { - send_batch_async_ios(pp); - process_async_ios_event(TIMEOUT_NO_IO_NSEC, pp->devname); - poll_async_io_timeout(); -- poll_io_err_stat(vecs, pp); -+ if (io_err_stat_time_up(pp)) { -+ if (!vector_alloc_slot(tmp_pathvec)) -+ continue; -+ vector_del_slot(io_err_pathvec, i--); -+ vector_set_slot(tmp_pathvec, pp); -+ } - } -- pthread_mutex_unlock(&io_err_pathvec_lock); -+ pthread_cleanup_pop(1); -+ vector_foreach_slot_backwards(tmp_pathvec, pp, i) { -+ end_io_err_stat(pp); -+ vector_del_slot(tmp_pathvec, i); -+ destroy_directio_ctx(pp); -+ free_io_err_stat_path(pp); -+ } -+ vector_reset(tmp_pathvec); - } - - static void cleanup_exited(__attribute__((unused)) void *arg) --- -2.17.2 - diff --git a/SOURCES/0056-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch b/SOURCES/0056-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch deleted file mode 100644 index c6ebd39..0000000 --- a/SOURCES/0056-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:25 -0600 -Subject: [PATCH] multipathd: use get_monotonic_time() in io_err_stat code - -Instead of calling clock_gettime(), and dealing with failure -conditions, just call get_monotonic_time(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 34 +++++++++++----------------------- - 1 file changed, 11 insertions(+), 23 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 63ee2e07..3389d693 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -305,8 +305,7 @@ int io_err_stat_handle_pathfail(struct path *path) - * the repeated count threshold and time frame, we assume a path - * which fails at least twice within 60 seconds is flaky. - */ -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) -- return 1; -+ get_monotonic_time(&curr_time); - if (path->io_err_pathfail_cnt == 0) { - path->io_err_pathfail_cnt++; - path->io_err_pathfail_starttime = curr_time.tv_sec; -@@ -362,9 +361,9 @@ int need_io_err_check(struct path *pp) - } - if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) - return 1; -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 || -- (curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -- pp->mpp->marginal_path_err_recheck_gap_time) { -+ get_monotonic_time(&curr_time); -+ if ((curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -+ pp->mpp->marginal_path_err_recheck_gap_time) { - io_err_stat_log(4, "%s: reschedule checking after %d seconds", - pp->dev, - pp->mpp->marginal_path_err_recheck_gap_time); -@@ -410,8 +409,7 @@ static int io_err_stat_time_up(struct io_err_stat_path *pp) - { - struct timespec currtime, difftime; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return 0; -+ get_monotonic_time(&currtime); - timespecsub(&currtime, &pp->start_time, &difftime); - if (difftime.tv_sec < pp->total_time) - return 0; -@@ -424,8 +422,7 @@ static void end_io_err_stat(struct io_err_stat_path *pp) - struct path *path; - double err_rate; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- currtime = pp->start_time; -+ get_monotonic_time(&currtime); - - io_err_stat_log(4, "%s: check end", pp->devname); - -@@ -474,11 +471,7 @@ static int send_each_async_io(struct dio_ctx *ct, int fd, char *dev) - ct->io_starttime.tv_sec == 0) { - struct iocb *ios[1] = { &ct->io }; - -- if (clock_gettime(CLOCK_MONOTONIC, &ct->io_starttime) != 0) { -- ct->io_starttime.tv_sec = 0; -- ct->io_starttime.tv_nsec = 0; -- return rc; -- } -+ get_monotonic_time(&ct->io_starttime); - io_prep_pread(&ct->io, fd, ct->buf, ct->blksize, 0); - if (io_submit(ioctx, 1, ios) != 1) { - io_err_stat_log(5, "%s: io_submit error %i", -@@ -497,8 +490,7 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) - struct dio_ctx *ct; - struct timespec currtime, difftime; - -- if (clock_gettime(CLOCK_MONOTONIC, &currtime) != 0) -- return; -+ get_monotonic_time(&currtime); - /* - * Give a free time for all IO to complete or timeout - */ -@@ -513,11 +505,8 @@ static void send_batch_async_ios(struct io_err_stat_path *pp) - if (!send_each_async_io(ct, pp->fd, pp->devname)) - pp->io_nr++; - } -- if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0 && -- clock_gettime(CLOCK_MONOTONIC, &pp->start_time)) { -- pp->start_time.tv_sec = 0; -- pp->start_time.tv_nsec = 0; -- } -+ if (pp->start_time.tv_sec == 0 && pp->start_time.tv_nsec == 0) -+ get_monotonic_time(&pp->start_time); - } - - static int try_to_cancel_timeout_io(struct dio_ctx *ct, struct timespec *t, -@@ -556,8 +545,7 @@ static void poll_async_io_timeout(void) - int rc = PATH_UNCHECKED; - int i, j; - -- if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0) -- return; -+ get_monotonic_time(&curr_time); - vector_foreach_slot(io_err_pathvec, pp, i) { - for (j = 0; j < CONCUR_NR_EVENT; j++) { - rc = try_to_cancel_timeout_io(pp->dio_ctx_array + j, --- -2.17.2 - diff --git a/SOURCES/0057-multipathd-combine-free_io_err_stat_path-and-destroy.patch b/SOURCES/0057-multipathd-combine-free_io_err_stat_path-and-destroy.patch deleted file mode 100644 index c3573c7..0000000 --- a/SOURCES/0057-multipathd-combine-free_io_err_stat_path-and-destroy.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Jan 2021 20:20:26 -0600 -Subject: [PATCH] multipathd: combine free_io_err_stat_path and - destroy_directio_ctx - -destroy_directio_ctx() is only called from free_io_err_stat_path(), and -free_io_err_stat_path() is very short, so combine them. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 24 ++++++++++-------------- - 1 file changed, 10 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 3389d693..bf1d3910 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -163,12 +163,15 @@ fail_close: - return 1; - } - --static void destroy_directio_ctx(struct io_err_stat_path *p) -+static void free_io_err_stat_path(struct io_err_stat_path *p) - { - int i; - -- if (!p || !p->dio_ctx_array) -+ if (!p) - return; -+ if (!p->dio_ctx_array) -+ goto free_path; -+ - cancel_inflight_io(p); - - for (i = 0; i < CONCUR_NR_EVENT; i++) -@@ -177,6 +180,8 @@ static void destroy_directio_ctx(struct io_err_stat_path *p) - - if (p->fd > 0) - close(p->fd); -+free_path: -+ FREE(p); - } - - static struct io_err_stat_path *alloc_io_err_stat_path(void) -@@ -199,11 +204,6 @@ static struct io_err_stat_path *alloc_io_err_stat_path(void) - return p; - } - --static void free_io_err_stat_path(struct io_err_stat_path *p) --{ -- FREE(p); --} -- - static void free_io_err_pathvec(void) - { - struct io_err_stat_path *path; -@@ -213,10 +213,8 @@ static void free_io_err_pathvec(void) - pthread_cleanup_push(cleanup_mutex, &io_err_pathvec_lock); - if (!io_err_pathvec) - goto out; -- vector_foreach_slot(io_err_pathvec, path, i) { -- destroy_directio_ctx(path); -+ vector_foreach_slot(io_err_pathvec, path, i) - free_io_err_stat_path(path); -- } - vector_free(io_err_pathvec); - io_err_pathvec = NULL; - out: -@@ -252,7 +250,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) - goto free_ioerr_path; - pthread_mutex_lock(&io_err_pathvec_lock); - if (!vector_alloc_slot(io_err_pathvec)) -- goto unlock_destroy; -+ goto unlock_pathvec; - vector_set_slot(io_err_pathvec, p); - pthread_mutex_unlock(&io_err_pathvec_lock); - -@@ -260,9 +258,8 @@ static int enqueue_io_err_stat_by_path(struct path *path) - path->mpp->alias, path->dev); - return 0; - --unlock_destroy: -+unlock_pathvec: - pthread_mutex_unlock(&io_err_pathvec_lock); -- destroy_directio_ctx(p); - free_ioerr_path: - free_io_err_stat_path(p); - -@@ -647,7 +644,6 @@ static void service_paths(void) - vector_foreach_slot_backwards(tmp_pathvec, pp, i) { - end_io_err_stat(pp); - vector_del_slot(tmp_pathvec, i); -- destroy_directio_ctx(pp); - free_io_err_stat_path(pp); - } - vector_reset(tmp_pathvec); --- -2.17.2 - diff --git a/SOURCES/0058-multipathd-cleanup-logging-for-marginal-paths.patch b/SOURCES/0058-multipathd-cleanup-logging-for-marginal-paths.patch deleted file mode 100644 index 2983712..0000000 --- a/SOURCES/0058-multipathd-cleanup-logging-for-marginal-paths.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 18 Jan 2021 22:46:04 -0600 -Subject: [PATCH] multipathd: cleanup logging for marginal paths - -io_err_stat logged at level 2 whenever it enqueued a path to check, -which could happen multiple times while a path was marginal. On the -other hand if marginal_pathgroups wasn't set, multipathd didn't log when -paths were set to marginal. Now io_err_stat only logs at level 2 when -something unexpected happens, but multipathd will always log when a -path switches its marginal state. - -This patch also fixes an issue where paths in the delayed state could -get set to the pending state if they could not be checked in time. -Aside from going against the idea the paths should not be set to pending -if they already have a valid state, this caused multipathd to log a -message whenever the path state switched to from delayed to pending and -then back. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/io_err_stat.c | 7 +++---- - multipathd/main.c | 20 +++++++++++++------- - 2 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index bf1d3910..ee711f7f 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -254,7 +254,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) - vector_set_slot(io_err_pathvec, p); - pthread_mutex_unlock(&io_err_pathvec_lock); - -- io_err_stat_log(2, "%s: enqueue path %s to check", -+ io_err_stat_log(3, "%s: enqueue path %s to check", - path->mpp->alias, path->dev); - return 0; - -@@ -353,7 +353,7 @@ int need_io_err_check(struct path *pp) - if (uatomic_read(&io_err_thread_running) == 0) - return 0; - if (count_active_paths(pp->mpp) <= 0) { -- io_err_stat_log(2, "%s: recover path early", pp->dev); -+ io_err_stat_log(2, "%s: no paths. recovering early", pp->dev); - goto recover; - } - if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) -@@ -371,8 +371,7 @@ int need_io_err_check(struct path *pp) - * Or else, return 1 to set path state to PATH_SHAKY - */ - if (r == 1) { -- io_err_stat_log(3, "%s: enqueue fails, to recover", -- pp->dev); -+ io_err_stat_log(2, "%s: enqueue failed. recovering early", pp->dev); - goto recover; - } else - pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING; -diff --git a/multipathd/main.c b/multipathd/main.c -index 1d0579e9..cc1aeea2 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2041,8 +2041,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - pathinfo(pp, conf, 0); - pthread_cleanup_pop(1); - return 1; -- } else if ((newstate != PATH_UP && newstate != PATH_GHOST) && -- (pp->state == PATH_DELAYED)) { -+ } else if ((newstate != PATH_UP && newstate != PATH_GHOST && -+ newstate != PATH_PENDING) && (pp->state == PATH_DELAYED)) { - /* If path state become failed again cancel path delay state */ - pp->state = newstate; - return 1; -@@ -2104,8 +2104,9 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - if ((newstate == PATH_UP || newstate == PATH_GHOST) && - (san_path_check_enabled(pp->mpp) || - marginal_path_check_enabled(pp->mpp))) { -- int was_marginal = pp->marginal; - if (should_skip_path(pp)) { -+ if (!pp->marginal && pp->state != PATH_DELAYED) -+ condlog(2, "%s: path is now marginal", pp->dev); - if (!marginal_pathgroups) { - if (marginal_path_check_enabled(pp->mpp)) - /* to reschedule as soon as possible, -@@ -2115,13 +2116,18 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - pp->state = PATH_DELAYED; - return 1; - } -- if (!was_marginal) { -+ if (!pp->marginal) { - pp->marginal = 1; - marginal_changed = 1; - } -- } else if (marginal_pathgroups && was_marginal) { -- pp->marginal = 0; -- marginal_changed = 1; -+ } else { -+ if (pp->marginal || pp->state == PATH_DELAYED) -+ condlog(2, "%s: path is no longer marginal", -+ pp->dev); -+ if (marginal_pathgroups && pp->marginal) { -+ pp->marginal = 0; -+ marginal_changed = 1; -+ } - } - } - --- -2.17.2 - diff --git a/SOURCES/0059-libmpathpersist-fix-thread-safety-of-default-functio.patch b/SOURCES/0059-libmpathpersist-fix-thread-safety-of-default-functio.patch deleted file mode 100644 index 5bbd255..0000000 --- a/SOURCES/0059-libmpathpersist-fix-thread-safety-of-default-functio.patch +++ /dev/null @@ -1,277 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 25 Jan 2021 23:31:04 -0600 -Subject: [PATCH] libmpathpersist: fix thread safety of default functions - -commit a839e39e ("libmpathpersist: factor out initialization and -teardown") made mpath_presistent_reserve_{in,out} use share variables -for curmp and pathvec. There are users of this library that call these -functions in a multi-threaded process, and this change causes their -application to crash. config and udev are also shared variables, but -libmpathpersist doesn't write to the config in -mpath_presistent_reserve_{in,out}, and looking into the libudev code, I -don't see any place where libmpathpersist uses the udev object in a way -that isn't thread-safe. - -This patch makes mpath_presistent_reserve_{in,out} go back to using -local variables for curmp and pathvec, so that multiple threads won't -be operating on these variables at the same time. - -Fixes: a839e39e ("libmpathpersist: factor out initialization and teardown") -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 116 +++++++++++++++++++++----------- - libmpathpersist/mpath_persist.h | 24 +++++-- - 2 files changed, 94 insertions(+), 46 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index a01dfb0b..07a5f17f 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -147,72 +147,60 @@ mpath_prin_activepath (struct multipath *mpp, int rq_servact, - return ret; - } - --int mpath_persistent_reserve_in (int fd, int rq_servact, -- struct prin_resp *resp, int noisy, int verbose) --{ -- int ret = mpath_persistent_reserve_init_vecs(verbose); -- -- if (ret != MPATH_PR_SUCCESS) -- return ret; -- ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy); -- mpath_persistent_reserve_free_vecs(); -- return ret; --} -- --int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) --{ -- int ret = mpath_persistent_reserve_init_vecs(verbose); -- -- if (ret != MPATH_PR_SUCCESS) -- return ret; -- ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type, -- paramp, noisy); -- mpath_persistent_reserve_free_vecs(); -- return ret; --} -- - static vector curmp; - static vector pathvec; - --void mpath_persistent_reserve_free_vecs(void) -+static void __mpath_persistent_reserve_free_vecs(vector curmp, vector pathvec) - { - free_multipathvec(curmp, KEEP_PATHS); - free_pathvec(pathvec, FREE_PATHS); -+} -+ -+void mpath_persistent_reserve_free_vecs(void) -+{ -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); - curmp = pathvec = NULL; - } - --int mpath_persistent_reserve_init_vecs(int verbose) -+static int __mpath_persistent_reserve_init_vecs(vector *curmp_p, -+ vector *pathvec_p, int verbose) - { - struct config *conf = get_multipath_config(); - - conf->verbosity = verbose; - put_multipath_config(conf); - -- if (curmp) -+ if (*curmp_p) - return MPATH_PR_SUCCESS; - /* - * allocate core vectors to store paths and multipaths - */ -- curmp = vector_alloc (); -- pathvec = vector_alloc (); -+ *curmp_p = vector_alloc (); -+ *pathvec_p = vector_alloc (); - -- if (!curmp || !pathvec){ -+ if (!*curmp_p || !*pathvec_p){ - condlog (0, "vector allocation failed."); - goto err; - } - -- if (dm_get_maps(curmp)) -+ if (dm_get_maps(*curmp_p)) - goto err; - - return MPATH_PR_SUCCESS; - - err: -- mpath_persistent_reserve_free_vecs(); -+ __mpath_persistent_reserve_free_vecs(*curmp_p, *pathvec_p); -+ *curmp_p = *pathvec_p = NULL; - return MPATH_PR_DMMP_ERROR; - } - --static int mpath_get_map(int fd, char **palias, struct multipath **pmpp) -+int mpath_persistent_reserve_init_vecs(int verbose) -+{ -+ return __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, verbose); -+} -+ -+static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, -+ struct multipath **pmpp) - { - int ret = MPATH_PR_DMMP_ERROR; - struct stat info; -@@ -272,13 +260,13 @@ out: - return ret; - } - --int __mpath_persistent_reserve_in (int fd, int rq_servact, -- struct prin_resp *resp, int noisy) -+static int do_mpath_persistent_reserve_in (vector curmp, vector pathvec, -+ int fd, int rq_servact, struct prin_resp *resp, int noisy) - { - struct multipath *mpp; - int ret; - -- ret = mpath_get_map(fd, NULL, &mpp); -+ ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - -@@ -287,8 +275,17 @@ int __mpath_persistent_reserve_in (int fd, int rq_servact, - return ret; - } - --int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) -+ -+int __mpath_persistent_reserve_in (int fd, int rq_servact, -+ struct prin_resp *resp, int noisy) -+{ -+ return do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, -+ resp, noisy); -+} -+ -+static int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd, -+ int rq_servact, int rq_scope, unsigned int rq_type, -+ struct prout_param_descriptor *paramp, int noisy) - { - struct multipath *mpp; - char *alias; -@@ -296,7 +293,7 @@ int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - uint64_t prkey; - struct config *conf; - -- ret = mpath_get_map(fd, &alias, &mpp); -+ ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - -@@ -366,6 +363,45 @@ out1: - return ret; - } - -+ -+int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -+ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) -+{ -+ return do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, -+ rq_scope, rq_type, paramp, -+ noisy); -+} -+ -+int mpath_persistent_reserve_in (int fd, int rq_servact, -+ struct prin_resp *resp, int noisy, int verbose) -+{ -+ vector curmp = NULL, pathvec; -+ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, -+ verbose); -+ -+ if (ret != MPATH_PR_SUCCESS) -+ return ret; -+ ret = do_mpath_persistent_reserve_in(curmp, pathvec, fd, rq_servact, -+ resp, noisy); -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); -+ return ret; -+} -+ -+int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, -+ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose) -+{ -+ vector curmp = NULL, pathvec; -+ int ret = __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, -+ verbose); -+ -+ if (ret != MPATH_PR_SUCCESS) -+ return ret; -+ ret = do_mpath_persistent_reserve_out(curmp, pathvec, fd, rq_servact, -+ rq_scope, rq_type, paramp, noisy); -+ __mpath_persistent_reserve_free_vecs(curmp, pathvec); -+ return ret; -+} -+ - int - get_mpvec (vector curmp, vector pathvec, char * refwwid) - { -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 7cf4faf9..0e4e0e53 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -215,9 +215,13 @@ extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp - - /* - * DESCRIPTION : -- * This function is like mpath_persistent_reserve_in(), except that it doesn't call -- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() -- * before and after the actual PR call. -+ * This function is like mpath_persistent_reserve_in(), except that it -+ * requires mpath_persistent_reserve_init_vecs() to be called before the -+ * PR call to set up internal variables. These must later be cleanup up -+ * by calling mpath_persistent_reserve_free_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - extern int __mpath_persistent_reserve_in(int fd, int rq_servact, - struct prin_resp *resp, int noisy); -@@ -249,9 +253,13 @@ extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, - int verbose); - /* - * DESCRIPTION : -- * This function is like mpath_persistent_reserve_out(), except that it doesn't call -- * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs() -- * before and after the actual PR call. -+ * This function is like mpath_persistent_reserve_out(), except that it -+ * requires mpath_persistent_reserve_init_vecs() to be called before the -+ * PR call to set up internal variables. These must later be cleanup up -+ * by calling mpath_persistent_reserve_free_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor *paramp, -@@ -265,6 +273,7 @@ extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope, - * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose - * - * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - * - * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status specified - * above in RETURN_STATUS. -@@ -275,6 +284,9 @@ int mpath_persistent_reserve_init_vecs(int verbose); - * DESCRIPTION : - * This function frees data structures allocated by - * mpath_persistent_reserve_init_vecs(). -+ * -+ * RESTRICTIONS: -+ * This function uses static internal variables, and is not thread-safe. - */ - void mpath_persistent_reserve_free_vecs(void); - --- -2.17.2 - diff --git a/SOURCES/0060-kpartx-free-loop-device-after-listing-partitions.patch b/SOURCES/0060-kpartx-free-loop-device-after-listing-partitions.patch deleted file mode 100644 index c50bbc0..0000000 --- a/SOURCES/0060-kpartx-free-loop-device-after-listing-partitions.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Feb 2021 17:16:04 -0600 -Subject: [PATCH] kpartx: free loop device after listing partitions - -If "kpartx -l" is run on a file that doesn't already have a loop device -associated with it, it will create a loop device to run the command. -Starting with da59d15c6 ("Fix loopback file with kpartx -av"), it will -not free the loop device when exitting. This is because it checks if the -the file it stat()ed is a regular file, before freeing the loop device. -However, after da59d15c6, stat() is rerun on the loop device itself, so -the check fails. There is no need to check this, if loopcreated is -true, then the file will be a kpartx created loop device, and should be -freed. - -Also, keep kpartx from printing that the loop device has been removed -at normal verbosity. - -Fixes: da59d15c6 ("Fix loopback file with kpartx -av") -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index 653ce0c8..a337a07b 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -407,7 +407,7 @@ main(int argc, char **argv){ - fprintf(stderr, "can't del loop : %s\n", - loopdev); - r = 1; -- } else -+ } else if (verbose) - fprintf(stderr, "loop deleted : %s\n", loopdev); - } - goto end; -@@ -649,16 +649,17 @@ main(int argc, char **argv){ - if (n > 0) - break; - } -- if (what == LIST && loopcreated && S_ISREG (buf.st_mode)) { -+ if (what == LIST && loopcreated) { - if (fd != -1) - close(fd); - if (del_loop(device)) { - if (verbose) -- printf("can't del loop : %s\n", -+ fprintf(stderr, "can't del loop : %s\n", - device); - exit(1); - } -- printf("loop deleted : %s\n", device); -+ if (verbose) -+ fprintf(stderr, "loop deleted : %s\n", device); - } - - end: --- -2.17.2 - diff --git a/SOURCES/0061-RH-fix-find_multipaths-in-mpathconf.patch b/SOURCES/0061-RH-fix-find_multipaths-in-mpathconf.patch deleted file mode 100644 index ea9d530..0000000 --- a/SOURCES/0061-RH-fix-find_multipaths-in-mpathconf.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 10 Feb 2021 15:42:42 -0600 -Subject: [PATCH] RH: fix find_multipaths in mpathconf - -mpathconf wasn't correctly dealing with the new rhel-8 values for -find_multipaths - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 38 +++++++++++++++++++------------------- - multipath/mpathconf.8 | 14 +++++++------- - 2 files changed, 26 insertions(+), 26 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index f34003c9..2f4f3eaf 100644 ---- a/multipath/mpathconf -+++ b/multipath/mpathconf -@@ -54,7 +54,7 @@ function usage - 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 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 " -@@ -224,8 +224,12 @@ function validate_args - echo "--user_friendly_names must be either 'y' or 'n'" - exit 1 - fi -- if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then -- echo "--find_multipaths must be either 'y' or 'n'" -+ 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 -@@ -327,10 +331,11 @@ if [ "$HAVE_BLACKLIST" = "1" ]; then - fi - - if [ "$HAVE_DEFAULTS" = "1" ]; then -- if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then -- HAVE_FIND=1 -- elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then -- HAVE_FIND=0 -+ 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 -@@ -360,10 +365,10 @@ if [ -n "$SHOW_STATUS" ]; then - else - echo "multipath is disabled" - fi -- if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then -- echo "find_multipaths is disabled" -+ if [ -z "$HAVE_FIND" ]; then -+ echo "find_multipaths is no" - else -- echo "find_multipaths is enabled" -+ echo "find_multipaths is $HAVE_FIND" - fi - if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then - echo "user_friendly_names is disabled" -@@ -455,19 +460,14 @@ elif [ "$ENABLE" = 0 ]; then - fi - fi - --if [ "$FIND" = "n" ]; then -- if [ "$HAVE_FIND" = 1 ]; then -- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE -- CHANGED_CONFIG=1 -- fi --elif [ "$FIND" = "y" ]; then -+if [ -n "$FIND" ]; then - if [ -z "$HAVE_FIND" ]; then - sed -i '/^defaults[[:space:]]*{/ a\ -- find_multipaths yes -+ find_multipaths '"$FIND"' - ' $TMPFILE - CHANGED_CONFIG=1 -- elif [ "$HAVE_FIND" = 0 ]; then -- sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE -+ elif [ "$FIND" != "$HAVE_FIND" ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE - CHANGED_CONFIG=1 - fi - fi -diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 -index b82961d6..83515eb4 100644 ---- a/multipath/mpathconf.8 -+++ b/multipath/mpathconf.8 -@@ -38,9 +38,9 @@ If - already exists, mpathconf will edit it. If it does not exist, mpathconf will - create a default file with - .B user_friendly_names --and -+set and - .B find_multipaths --set. To disable these, use the -+set to \fByes\fP. To disable these, use the - .B --user_friendly_names n - and - .B --find_multipaths n -@@ -77,13 +77,13 @@ to the - defaults section. If set to \fBn\fP, this removes the line, if present. This - command can be used along with any other command. - .TP --.B --find_multipaths\fP { \fBy\fP | \fBn\fP } --If set to \fBy\fP, this adds the line --.B find_multipaths yes -+.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. If set to \fBn\fP, this removes the line, if present. This --command can be used along with any other command. -+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 --- -2.17.2 - diff --git a/SOURCES/0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch b/SOURCES/0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch deleted file mode 100644 index d34e9e3..0000000 --- a/SOURCES/0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 7a7b96246b84ccf533a6f4dc0424830792fdb96a Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 Jul 2020 15:17:09 +0200 -Subject: [PATCH] libmultipath: select_action(): don't drop map if alias - clashes - -If for a given map, if we find that the requested alias is already -used by a map with different WWID, while the map's own WWID is -not used yet, give up the alias and use the WWID instead. This -is safer than trying to destroy the existing map, which is likely -to fail. - -This allows us to make use const for the "curmp" parameter. - -Reviewed-by: Benjamin Marzinski ---- - libmultipath/configure.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index b7113291..2e8f34f9 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -690,12 +690,13 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - } - - if (!cmpp) { -- condlog(2, "%s: remove (wwid changed)", mpp->alias); -- dm_flush_map(mpp->alias); -- strlcpy(cmpp_by_name->wwid, mpp->wwid, WWID_SIZE); -- drop_multipath(curmp, cmpp_by_name->wwid, KEEP_PATHS); -+ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -+ mpp->wwid, mpp->alias, cmpp_by_name->wwid); -+ /* We can do this because wwid wasn't found */ -+ free(mpp->alias); -+ mpp->alias = strdup(mpp->wwid); - mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map wwid change)", -+ condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", - mpp->alias); - return; - } --- -2.17.2 - diff --git a/SOURCES/0063-libmultipath-check-if-user_friendly_name-is-in-use.patch b/SOURCES/0063-libmultipath-check-if-user_friendly_name-is-in-use.patch deleted file mode 100644 index 81947be..0000000 --- a/SOURCES/0063-libmultipath-check-if-user_friendly_name-is-in-use.patch +++ /dev/null @@ -1,231 +0,0 @@ -From e714eb26fddc8768a8de279d1de3ffedab35929e Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 5 Mar 2021 21:40:57 -0600 -Subject: [PATCH] libmultipath: check if user_friendly_name is in use - -If there are multipath devices that have user_friendly_names but do not -have their bindings in the bindings_file, get_user_friendly_alias() can -currently give out those names again. This can result in an incorrect -entry in the bindings file, and a device that gets created with a WWID -alias instead of a user_friendly_name. This situation can happen after -the pivot root, if a multipath device is created in the initramfs. If -this device doesn't have a binding in the regular filesystem -bindings_file and a new multipath device is created before it can add -its binding, the new device can steal that user_friendly_name during -multipathd's initial configure. - -To solve this, get_user_friendly_alias() now calls lookup_binding() with -a new paramter, telling it to check if the id it found is already in use -by a diffent device. If so, lookup_binding() will continue to check open -ids, until it finds one that it not currently in use by a dm device. ---- - libmultipath/alias.c | 48 +++++++++++++++++++++++++++++++++++++++++--- - tests/alias.c | 22 ++++++++++---------- - 2 files changed, 56 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/alias.c b/libmultipath/alias.c -index 14401cae..01f737f4 100644 ---- a/libmultipath/alias.c -+++ b/libmultipath/alias.c -@@ -17,6 +17,7 @@ - #include "vector.h" - #include "checkers.h" - #include "structs.h" -+#include "devmapper.h" - - - /* -@@ -104,6 +105,28 @@ scan_devname(const char *alias, const char *prefix) - return n; - } - -+static int -+id_already_taken(int id, const char *prefix, const char *map_wwid) -+{ -+ char alias[LINE_MAX]; -+ -+ if (format_devname(alias, id, LINE_MAX, prefix) < 0) -+ return 0; -+ -+ if (dm_map_present(alias)) { -+ char wwid[WWID_SIZE]; -+ -+ /* If both the name and the wwid match, then it's fine.*/ -+ if (dm_get_uuid(alias, wwid, sizeof(wwid)) == 0 && -+ strncmp(map_wwid, wwid, sizeof(wwid)) == 0) -+ return 0; -+ condlog(3, "%s: alias '%s' already taken, but not in bindings file. reselecting alias", map_wwid, alias); -+ return 1; -+ } -+ return 0; -+} -+ -+ - /* - * Returns: 0 if matching entry in WWIDs file found - * -1 if an error occurs -@@ -113,7 +136,7 @@ scan_devname(const char *alias, const char *prefix) - */ - static int - lookup_binding(FILE *f, const char *map_wwid, char **map_alias, -- const char *prefix) -+ const char *prefix, int check_if_taken) - { - char buf[LINE_MAX]; - unsigned int line_nr = 0; -@@ -168,12 +191,31 @@ lookup_binding(FILE *f, const char *map_wwid, char **map_alias, - return 0; - } - } -+ if (!prefix && check_if_taken) -+ id = -1; - if (id >= smallest_bigger_id) { - if (biggest_id < INT_MAX) - id = biggest_id + 1; - else - id = -1; - } -+ if (id > 0 && check_if_taken) { -+ while(id_already_taken(id, prefix, map_wwid)) { -+ if (id == INT_MAX) { -+ id = -1; -+ break; -+ } -+ id++; -+ if (id == smallest_bigger_id) { -+ if (biggest_id == INT_MAX) { -+ id = -1; -+ break; -+ } -+ if (biggest_id >= smallest_bigger_id) -+ id = biggest_id + 1; -+ } -+ } -+ } - if (id < 0) { - condlog(0, "no more available user_friendly_names"); - return -1; -@@ -316,7 +358,7 @@ use_existing_alias (const char *wwid, const char *file, const char *alias_old, - goto out; - } - -- id = lookup_binding(f, wwid, &alias, NULL); -+ id = lookup_binding(f, wwid, &alias, NULL, 0); - if (alias) { - condlog(3, "Use existing binding [%s] for WWID [%s]", - alias, wwid); -@@ -373,7 +415,7 @@ get_user_friendly_alias(const char *wwid, const char *file, const char *prefix, - return NULL; - } - -- id = lookup_binding(f, wwid, &alias, prefix); -+ id = lookup_binding(f, wwid, &alias, prefix, 1); - if (id < 0) { - fclose(f); - return NULL; -diff --git a/tests/alias.c b/tests/alias.c -index 30414db0..ab1a9325 100644 ---- a/tests/alias.c -+++ b/tests/alias.c -@@ -356,7 +356,7 @@ static void lb_empty(void **state) - - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID0", &alias, NULL); -+ rc = lookup_binding(NULL, "WWID0", &alias, NULL, 0); - assert_int_equal(rc, 1); - assert_ptr_equal(alias, NULL); - } -@@ -369,7 +369,7 @@ static void lb_match_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - expect_condlog(3, "Found matching wwid [WWID0] in bindings file." - " Setting alias to MPATHa\n"); -- rc = lookup_binding(NULL, "WWID0", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID0", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHa"); -@@ -384,7 +384,7 @@ static void lb_nomatch_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -398,7 +398,7 @@ static void lb_match_c(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - expect_condlog(3, "Found matching wwid [WWID1] in bindings file." - " Setting alias to MPATHc\n"); -- rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID1", &alias, "MPATH", 0); - assert_int_equal(rc, 0); - assert_ptr_not_equal(alias, NULL); - assert_string_equal(alias, "MPATHc"); -@@ -414,7 +414,7 @@ static void lb_nomatch_a_c(void **state) - will_return(__wrap_fgets, "MPATHc WWID1\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -428,7 +428,7 @@ static void lb_nomatch_c_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 2); - assert_ptr_equal(alias, NULL); - } -@@ -443,7 +443,7 @@ static void lb_nomatch_a_b(void **state) - will_return(__wrap_fgets, "MPATHb WWID1\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -459,7 +459,7 @@ static void lb_nomatch_a_b_bad(void **state) - will_return(__wrap_fgets, NULL); - expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 3); - assert_ptr_equal(alias, NULL); - } -@@ -474,7 +474,7 @@ static void lb_nomatch_b_a(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, 27); - assert_ptr_equal(alias, NULL); - } -@@ -490,7 +490,7 @@ static void lb_nomatch_int_max(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(0, "no more available user_friendly_names\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, -1); - assert_ptr_equal(alias, NULL); - } -@@ -505,7 +505,7 @@ static void lb_nomatch_int_max_m1(void **state) - will_return(__wrap_fgets, "MPATHa WWID0\n"); - will_return(__wrap_fgets, NULL); - expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); -- rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); -+ rc = lookup_binding(NULL, "WWID2", &alias, "MPATH", 0); - assert_int_equal(rc, INT_MAX); - assert_ptr_equal(alias, NULL); - } --- -2.17.2 - diff --git a/SOURCES/0064-libmultipath-check-udev_device_get_-return-value-to-.patch b/SOURCES/0064-libmultipath-check-udev_device_get_-return-value-to-.patch deleted file mode 100644 index 20afb10..0000000 --- a/SOURCES/0064-libmultipath-check-udev_device_get_-return-value-to-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Mon, 21 Sep 2020 12:00:39 +0800 -Subject: [PATCH] libmultipath: check udev_device_get_* return value to avoid - segfault - -The udev_device_get_* function may return NULL, and it will be -deregerenced in str* and sscanf func. We check the return value -to avoid segfault. Fix all. - -Reviewed-by: Martin Wilck -Signed-off-by:Lixiaokeng -Signed-off-by: Zhiqiang Liu -Signed-off-by: Linfeilong -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 4 +++- - libmultipath/discovery.c | 9 +++++++-- - libmultipath/foreign/nvme.c | 10 +++++++--- - 3 files changed, 17 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 2e8f34f9..a6893d8d 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -511,6 +511,7 @@ static void trigger_partitions_udev_change(struct udev_device *dev, - { - struct udev_enumerate *part_enum; - struct udev_list_entry *item; -+ const char *devtype; - - part_enum = udev_enumerate_new(udev); - if (!part_enum) -@@ -531,7 +532,8 @@ static void trigger_partitions_udev_change(struct udev_device *dev, - if (!part) - continue; - -- if (!strcmp("partition", udev_device_get_devtype(part))) { -+ devtype = udev_device_get_devtype(part); -+ if (devtype && !strcmp("partition", devtype)) { - condlog(4, "%s: triggering %s event for %s", __func__, - action, syspath); - sysfs_attr_set_value(part, "uevent", action, len); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index a328aafa..74abf34d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -353,7 +353,7 @@ sysfs_get_tgt_nodename(struct path *pp, char *node) - tgtdev = udev_device_get_parent(parent); - while (tgtdev) { - tgtname = udev_device_get_sysname(tgtdev); -- if (sscanf(tgtname, "end_device-%d:%d", -+ if (tgtname && sscanf(tgtname, "end_device-%d:%d", - &host, &tgtid) == 2) - break; - tgtdev = udev_device_get_parent(tgtdev); -@@ -386,7 +386,7 @@ sysfs_get_tgt_nodename(struct path *pp, char *node) - /* Check for FibreChannel */ - tgtdev = udev_device_get_parent(parent); - value = udev_device_get_sysname(tgtdev); -- if (sscanf(value, "rport-%d:%d-%d", -+ if (value && sscanf(value, "rport-%d:%d-%d", - &host, &channel, &tgtid) == 3) { - tgtdev = udev_device_new_from_subsystem_sysname(udev, - "fc_remote_ports", value); -@@ -516,6 +516,9 @@ int sysfs_get_host_pci_name(const struct path *pp, char *pci_name) - */ - value = udev_device_get_sysname(parent); - -+ if (!value) -+ return 1; -+ - strncpy(pci_name, value, SLOT_NAME_SIZE); - udev_device_unref(hostdev); - return 0; -@@ -1518,6 +1521,8 @@ ccw_sysfs_pathinfo (struct path * pp, vector hwtable) - * host / bus / target / lun - */ - attr_path = udev_device_get_sysname(parent); -+ if (!attr_path) -+ return PATHINFO_FAILED; - pp->sg_id.lun = 0; - if (sscanf(attr_path, "%i.%i.%x", - &pp->sg_id.host_no, -diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c -index 09cdddf0..5feb1e95 100644 ---- a/libmultipath/foreign/nvme.c -+++ b/libmultipath/foreign/nvme.c -@@ -482,6 +482,7 @@ _find_path_by_syspath(struct nvme_map *map, const char *syspath) - struct nvme_pathgroup *pg; - char real[PATH_MAX]; - const char *ppath; -+ const char *psyspath; - int i; - - ppath = realpath(syspath, real); -@@ -493,8 +494,8 @@ _find_path_by_syspath(struct nvme_map *map, const char *syspath) - vector_foreach_slot(&map->pgvec, pg, i) { - struct nvme_path *path = nvme_pg_to_path(pg); - -- if (!strcmp(ppath, -- udev_device_get_syspath(path->udev))) -+ psyspath = udev_device_get_syspath(path->udev); -+ if (psyspath && !strcmp(ppath, psyspath)) - return path; - } - condlog(4, "%s: %s: %s not found", __func__, THIS, ppath); -@@ -538,6 +539,7 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - struct udev_list_entry *item; - struct udev_device *blkdev = NULL; - struct udev_enumerate *enm = udev_enumerate_new(ctx->udev); -+ const char *devtype; - - if (enm == NULL) - return NULL; -@@ -562,7 +564,9 @@ struct udev_device *get_ctrl_blkdev(const struct context *ctx, - udev_list_entry_get_name(item)); - if (tmp == NULL) - continue; -- if (!strcmp(udev_device_get_devtype(tmp), "disk")) { -+ -+ devtype = udev_device_get_devtype(tmp); -+ if (devtype && !strcmp(devtype, "disk")) { - blkdev = tmp; - break; - } else --- -2.17.2 - diff --git a/SOURCES/0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch b/SOURCES/0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch deleted file mode 100644 index 41aed73..0000000 --- a/SOURCES/0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:33:20 -0600 -Subject: [PATCH] libmultipath: cleanup code to strip wwid trailing spaces - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 74abf34d..126a70b3 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2062,11 +2062,11 @@ int - get_uid (struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback) - { -- char *c; - const char *origin = "unknown"; - ssize_t len = 0; - struct config *conf; - int used_fallback = 0; -+ size_t i; - - if (!pp->uid_attribute && !pp->getuid) { - conf = get_multipath_config(); -@@ -2119,12 +2119,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - return 1; - } else { - /* Strip any trailing blanks */ -- c = strchr(pp->wwid, '\0'); -- c--; -- while (c && c >= pp->wwid && *c == ' ') { -- *c = '\0'; -- c--; -- } -+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); -+ /* no-op */ -+ pp->wwid[i] = '\0'; - } - condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev, - *pp->wwid == '\0' ? "" : pp->wwid, origin); --- -2.17.2 - diff --git a/SOURCES/0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch b/SOURCES/0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch deleted file mode 100644 index 500c1ce..0000000 --- a/SOURCES/0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch +++ /dev/null @@ -1,429 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 24 Feb 2021 00:33:22 -0600 -Subject: [PATCH] multipathd: add recheck_wwid option to verify the path wwid - -There are cases where the wwid of a path changes due to LUN remapping -without triggering uevent for the changed path. Multipathd has no method -for trying to catch these cases, and corruption has resulted because of -it. - -In order to have a better chance at catching these cases, multipath now -has a recheck_wwid option. If this is set to "yes", when a failed path -has become active again, multipathd will recheck its wwid. If multipathd -notices that a path's wwid has changed, it will remove and re-add the -path, just like the existing wwid checking code for change events does. -In cases where the no uevent occurs, both the udev database entry and -sysfs will have the old wwid, so the only way to get a current wwid is -to ask the device directly. Currently multipath only has code to -directly get the wwid for scsi devices, so this option only effects scsi -devices, and they must be configured to be able to use the uid_fallback -methods. To make sure both the sysfs and udev database values are -updated, multipathd triggers a both a rescan of the device and a udev -add event. - -Co-developed-by: Chongyun Wu -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 2 + - libmultipath/config.h | 2 + - libmultipath/configure.c | 4 +- - libmultipath/configure.h | 2 + - libmultipath/defaults.h | 1 + - libmultipath/dict.c | 11 ++++++ - libmultipath/discovery.c | 3 +- - libmultipath/discovery.h | 1 + - libmultipath/propsel.c | 21 ++++++++++ - libmultipath/propsel.h | 1 + - libmultipath/structs.h | 7 ++++ - multipath/multipath.conf.5 | 14 +++++++ - multipathd/cli_handlers.c | 9 +++++ - multipathd/main.c | 78 ++++++++++++++++++++++++++++++++++++++ - multipathd/main.h | 2 + - 15 files changed, 155 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index dd645f17..abbddaf1 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -371,6 +371,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - merge_num(max_sectors_kb); - merge_num(ghost_delay); - merge_num(all_tg_pt); -+ merge_num(recheck_wwid); - merge_num(vpd_vendor_id); - merge_num(san_path_err_threshold); - merge_num(san_path_err_forget_rate); -@@ -762,6 +763,7 @@ load_config (char * file) - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; - conf->all_tg_pt = DEFAULT_ALL_TG_PT; -+ conf->recheck_wwid = DEFAULT_RECHECK_WWID; - /* - * preload default hwtable - */ -diff --git a/libmultipath/config.h b/libmultipath/config.h -index a22c1b4e..e2e3f143 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -84,6 +84,7 @@ struct hwentry { - int ghost_delay; - int all_tg_pt; - int vpd_vendor_id; -+ int recheck_wwid; - char * bl_product; - }; - -@@ -188,6 +189,7 @@ struct config { - int skip_delegate; - unsigned int version[3]; - unsigned int sequence_nr; -+ int recheck_wwid; - - char * multipath_dir; - char * selector; -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index a6893d8d..f24d9283 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -506,8 +506,8 @@ trigger_udev_change(const struct multipath *mpp) - udev_device_unref(udd); - } - --static void trigger_partitions_udev_change(struct udev_device *dev, -- const char *action, int len) -+void trigger_partitions_udev_change(struct udev_device *dev, -+ const char *action, int len) - { - struct udev_enumerate *part_enum; - struct udev_list_entry *item; -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 0e33bf40..81090dd4 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -57,3 +57,5 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type, - int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon); - 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); -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 52fe05b9..f1cb000d 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -50,6 +50,7 @@ - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 - #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF -+#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF - /* Enable all foreign libraries by default */ - #define DEFAULT_ENABLE_FOREIGN "" - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 8fd91d8c..13698b76 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1413,6 +1413,14 @@ declare_hw_snprint(all_tg_pt, print_yes_no_undef) - declare_def_handler(marginal_pathgroups, set_yes_no) - declare_def_snprint(marginal_pathgroups, print_yes_no) - -+declare_def_handler(recheck_wwid, set_yes_no_undef) -+declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID) -+declare_ovr_handler(recheck_wwid, set_yes_no_undef) -+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) - { -@@ -1824,6 +1832,7 @@ init_keywords(vector keywords) - install_keyword("enable_foreign", &def_enable_foreign_handler, - &snprint_def_enable_foreign); - install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups); -+ install_keyword("recheck_wwid", &def_recheck_wwid_handler, &snprint_def_recheck_wwid); - __deprecated install_keyword("default_selector", &def_selector_handler, NULL); - __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); - __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); -@@ -1913,6 +1922,7 @@ init_keywords(vector keywords) - install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay); - install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt); - install_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor); -+ install_keyword("recheck_wwid", &hw_recheck_wwid_handler, &snprint_hw_recheck_wwid); - install_sublevel_end(); - - install_keyword_root("overrides", &overrides_handler); -@@ -1954,6 +1964,7 @@ init_keywords(vector keywords) - install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb); - install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay); - install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt); -+ install_keyword("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid); - - install_keyword_root("multipaths", &multipaths_handler); - install_keyword_multi("multipath", &multipath_handler, NULL); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 126a70b3..bc267609 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2040,7 +2040,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - return len; - } - --static bool has_uid_fallback(struct path *pp) -+bool has_uid_fallback(struct path *pp) - { - /* - * Falling back to direct WWID determination is dangerous -@@ -2072,6 +2072,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - conf = get_multipath_config(); - pthread_cleanup_push(put_multipath_config, conf); - select_getuid(conf, pp); -+ select_recheck_wwid(conf, pp); - pthread_cleanup_pop(1); - } - -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index d3193daf..a5446b4d 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,6 +54,7 @@ ssize_t sysfs_get_inquiry(struct udev_device *udev, - unsigned char *buff, size_t len); - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); -+bool has_uid_fallback(struct path *pp); - int get_uid(struct path * pp, int path_state, struct udev_device *udev, - int allow_fallback); - bool is_vpd_page_supported(int fd, int pg); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 1150cfe8..127b3370 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -581,6 +581,27 @@ out: - return 0; - } - -+/* must be called after select_getuid */ -+int select_recheck_wwid(struct config *conf, struct path * pp) -+{ -+ const char *origin; -+ -+ pp_set_ovr(recheck_wwid); -+ pp_set_hwe(recheck_wwid); -+ pp_set_conf(recheck_wwid); -+ pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID); -+out: -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL || -+ !has_uid_fallback(pp))) { -+ pp->recheck_wwid = RECHECK_WWID_OFF; -+ origin = "(setting: unsupported by device type/config)"; -+ } -+ condlog(3, "%s: recheck_wwid = %i %s", pp->dev, pp->recheck_wwid, -+ origin); -+ return 0; -+} -+ - void - detect_prio(struct config *conf, struct path * pp) - { -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index a68bacf0..72a7e33c 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -7,6 +7,7 @@ int select_features (struct config *conf, struct multipath * mp); - int select_hwhandler (struct config *conf, struct multipath * mp); - int select_checker(struct config *conf, struct path *pp); - int select_getuid (struct config *conf, struct path * pp); -+int select_recheck_wwid(struct config *conf, struct path * pp); - int select_prio (struct config *conf, struct path * pp); - int select_find_multipaths_timeout(struct config *conf, struct path *pp); - int select_no_path_retry(struct config *conf, struct multipath *mp); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 65542dea..a5dbad5b 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -252,6 +252,12 @@ enum eh_deadline_states { - EH_DEADLINE_ZERO = UOZ_ZERO, - }; - -+enum recheck_wwid_states { -+ RECHECK_WWID_UNDEF = YNU_UNDEF, -+ RECHECK_WWID_OFF = YNU_NO, -+ RECHECK_WWID_ON = YNU_YES, -+}; -+ - struct vpd_vendor_page { - int pg; - const char *name; -@@ -326,6 +332,7 @@ struct path { - int find_multipaths_timeout; - int marginal; - int vpd_vendor_id; -+ int recheck_wwid; - /* configlet pointers */ - vector hwe; - struct gen_path generic_path; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index a5686090..6da15aad 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1256,6 +1256,20 @@ The default is: \fB\(dq\(dq\fR (the empty regular expression) - .RE - . - . -+.TP -+.B recheck_wwid -+If set to \fIyes\fR, when a failed path is restored, its wwid is rechecked. If -+the wwid has changed, the path is removed from the current multipath device, -+and re-added as a new path. Multipathd will also recheck a path's wwid if it is -+manually re-added. This option only works for SCSI devices that are configured -+to use the default uid_attribute, \fIID_SERIAL\fR, or sysfs for getting their -+wwid. -+.RS -+.TP -+The default is \fBno\fR -+.RE -+. -+. - - . - .\" ---------------------------------------------------------------------------- -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 782bb003..8b4bd187 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -715,6 +715,15 @@ cli_add_path (void * v, char ** reply, int * len, void * data) - pp = find_path_by_dev(vecs->pathvec, param); - if (pp) { - condlog(2, "%s: path already in pathvec", param); -+ -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ check_path_wwid_change(pp)) { -+ condlog(0, "%s: wwid changed. Removing device", -+ pp->dev); -+ handle_path_wwid_change(pp, vecs); -+ return 1; -+ } -+ - if (pp->mpp) - return 0; - } else { -diff --git a/multipathd/main.c b/multipathd/main.c -index cc1aeea2..1fbc31eb 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -822,6 +822,73 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) - return flush_map(mpp, vecs, 0); - } - -+static void -+rescan_path(struct udev_device *parent) -+{ -+ while(parent) { -+ const char *subsys = udev_device_get_subsystem(parent); -+ if (subsys && !strncmp(subsys, "scsi", 4)) -+ break; -+ parent = udev_device_get_parent(parent); -+ } -+ if (parent) -+ sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); -+} -+ -+void -+handle_path_wwid_change(struct path *pp, struct vectors *vecs) -+{ -+ struct udev_device *udd; -+ -+ if (!pp || !pp->udev) -+ return; -+ -+ udd = udev_device_ref(pp->udev); -+ if (ev_remove_path(pp, vecs, 1) != 0 && pp->mpp) { -+ pp->dmstate = PSTATE_FAILED; -+ dm_fail_path(pp->mpp->alias, pp->dev_t); -+ } -+ rescan_path(udd); -+ sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -+ trigger_partitions_udev_change(udd, "add", strlen("add")); -+ udev_device_unref(udd); -+} -+ -+bool -+check_path_wwid_change(struct path *pp) -+{ -+ char wwid[WWID_SIZE]; -+ int len = 0; -+ size_t i; -+ -+ if (!strlen(pp->wwid)) -+ return false; -+ -+ /* Get the real fresh device wwid by sgio. sysfs still has old -+ * data, so only get_vpd_sgio will work to get the new wwid */ -+ len = get_vpd_sgio(pp->fd, 0x83, 0, wwid, WWID_SIZE); -+ -+ if (len <= 0) { -+ condlog(2, "%s: failed to check wwid by sgio: len = %d", -+ pp->dev, len); -+ return false; -+ } -+ -+ /*Strip any trailing blanks */ -+ for (i = strlen(pp->wwid); i > 0 && pp->wwid[i-1] == ' '; i--); -+ /* no-op */ -+ pp->wwid[i] = '\0'; -+ condlog(4, "%s: Got wwid %s by sgio", pp->dev, wwid); -+ -+ if (strncmp(wwid, pp->wwid, WWID_SIZE)) { -+ condlog(0, "%s: wwid '%s' doesn't match wwid '%s' from device", -+ pp->dev, pp->wwid, wwid); -+ return true; -+ } -+ -+ return false; -+} -+ - static int - uev_add_path (struct uevent *uev, struct vectors * vecs, int need_do_map) - { -@@ -1241,6 +1308,7 @@ 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 { -@@ -2101,6 +2169,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - return 0; - set_no_path_retry(pp->mpp); - -+ if (pp->recheck_wwid == RECHECK_WWID_ON && -+ (newstate == PATH_UP || newstate == PATH_GHOST) && -+ ((pp->state != PATH_UP && pp->state != PATH_GHOST) || -+ pp->dmstate == PSTATE_FAILED) && -+ check_path_wwid_change(pp)) { -+ condlog(0, "%s: path wwid change detected. Removing", pp->dev); -+ handle_path_wwid_change(pp, vecs); -+ return 0; -+ } -+ - if ((newstate == PATH_UP || newstate == PATH_GHOST) && - (san_path_check_enabled(pp->mpp) || - marginal_path_check_enabled(pp->mpp))) { -diff --git a/multipathd/main.h b/multipathd/main.h -index 5dff17e5..8f0028a9 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -49,4 +49,6 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset); - int update_path_groups(struct multipath *mpp, struct vectors *vecs, - int refresh); - -+void handle_path_wwid_change(struct path *pp, struct vectors *vecs); -+bool check_path_wwid_change(struct path *pp); - #endif /* MAIN_H */ --- -2.17.2 - diff --git a/SOURCES/0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch b/SOURCES/0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch deleted file mode 100644 index c261ee2..0000000 --- a/SOURCES/0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Mar 2021 19:52:43 -0500 -Subject: [PATCH] libmultipath: avoid infinite loop with bad vpd page 83 - identifier - -If a device with a scsi name identifier has an unknown prefix, -parse_vpd_pg83() needs to advance to the next identifier, instead of -simply trying the same one again in an infinite loop. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index bc267609..8c2ab073 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1101,7 +1101,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - if (memcmp(d + 4, "eui.", 4) && - memcmp(d + 4, "naa.", 4) && - memcmp(d + 4, "iqn.", 4)) -- continue; -+ break; - if (prio < 4) { - prio = 4; - vpd = d; --- -2.17.2 - diff --git a/SOURCES/0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch b/SOURCES/0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch deleted file mode 100644 index d4ab400..0000000 --- a/SOURCES/0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Mar 2021 19:52:44 -0500 -Subject: [PATCH] libmultipath: fix priorities in parse_vpd_pg83 - -The priorities for the EUI-64 (0x02) and NAME (0x08) scsi identifiers in -parse_vpd_pg83() don't match their priorities in 55-scsi-sg3_id.rules. -Switch them so that they match. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 8c2ab073..5e988631 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1096,19 +1096,19 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, - vpd = d; - } - break; -- case 0x8: -- /* SCSI Name: Prio 4 */ -- if (memcmp(d + 4, "eui.", 4) && -- memcmp(d + 4, "naa.", 4) && -- memcmp(d + 4, "iqn.", 4)) -- break; -+ case 0x2: -+ /* EUI-64: Prio 4 */ - if (prio < 4) { - prio = 4; - vpd = d; - } - break; -- case 0x2: -- /* EUI-64: Prio 3 */ -+ 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; --- -2.17.2 - diff --git a/SOURCES/0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/SOURCES/0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch deleted file mode 100644 index d8f7ac1..0000000 --- a/SOURCES/0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +++ /dev/null @@ -1,54 +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 5e988631..2404cb87 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1079,12 +1079,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 */ -@@ -1103,17 +1100,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) { --- -2.17.2 - diff --git a/SOURCES/0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch b/SOURCES/0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch deleted file mode 100644 index 6bb94fd..0000000 --- a/SOURCES/0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Mar 2021 19:52:45 -0500 -Subject: [PATCH] multipathd: improve getting parent udevice in rescan_path - -Instead of looping through parents and checking, just call -udev_device_get_parent_with_subsystem_devtype() to get the -right one. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 1fbc31eb..4598d354 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -823,16 +823,12 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs) - } - - static void --rescan_path(struct udev_device *parent) -+rescan_path(struct udev_device *ud) - { -- while(parent) { -- const char *subsys = udev_device_get_subsystem(parent); -- if (subsys && !strncmp(subsys, "scsi", 4)) -- break; -- parent = udev_device_get_parent(parent); -- } -- if (parent) -- sysfs_attr_set_value(parent, "rescan", "1", strlen("1")); -+ ud = udev_device_get_parent_with_subsystem_devtype(ud, "scsi", -+ "scsi_device"); -+ if (ud) -+ sysfs_attr_set_value(ud, "rescan", "1", strlen("1")); - } - - void --- -2.17.2 - diff --git a/SOURCES/0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch b/SOURCES/0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch deleted file mode 100644 index b96d496..0000000 --- a/SOURCES/0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 25 Mar 2021 19:52:46 -0500 -Subject: [PATCH] multipathd: don't trigger uevent for partitions on wwid - change - -If the wwid changed, the device is no longer the same, so sending add -events to the devices partitions doesn't make any sense. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 4598d354..e6c19ab2 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -846,7 +846,6 @@ handle_path_wwid_change(struct path *pp, struct vectors *vecs) - } - rescan_path(udd); - sysfs_attr_set_value(udd, "uevent", "add", strlen("add")); -- trigger_partitions_udev_change(udd, "add", strlen("add")); - udev_device_unref(udd); - } - --- -2.17.2 - diff --git a/SOURCES/0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch b/SOURCES/0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch deleted file mode 100644 index 0d39a77..0000000 --- a/SOURCES/0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch +++ /dev/null @@ -1,165 +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. - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 40 ++++++++++++++++++++-------------------- - 1 file changed, 20 insertions(+), 20 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index 2f4f3eaf..5f2285ab 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,36 +315,36 @@ 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 - HAVE_FOREIGN=2 -@@ -352,9 +352,9 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then - 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 -@@ -427,14 +427,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 +448,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 +456,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 +467,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 +484,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,7 +501,7 @@ 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 --- -2.30.2 - diff --git a/SOURCES/0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch b/SOURCES/0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch deleted file mode 100644 index 849186f..0000000 --- a/SOURCES/0073-multipath.conf-fix-typo-in-checker_timeout-descripti.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:48:15 -0500 -Subject: [PATCH] multipath.conf: fix typo in checker_timeout 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 6da15aad..0c04c7e4 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -638,7 +638,7 @@ Specify the timeout to use for path checkers and prioritizers, in seconds. - Only prioritizers that issue scsi commands use checker_timeout. Checkers - that support an asynchronous mode (\fItur\fR and \fIdirectio\fR), will - return shortly after being called by multipathd, regardless of whether the --storage array responds. If the storage array hasn't responded, mulitpathd will -+storage array responds. If the storage array hasn't responded, multipathd will - check for a response every second, until \fIchecker_timeout\fR seconds have - elapsed. - .RS diff --git a/SOURCES/0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch b/SOURCES/0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch deleted file mode 100644 index 0834837..0000000 --- a/SOURCES/0074-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, 22 Jul 2021 17:48:06 -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 07a5f17f..d0744773 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -629,7 +629,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, -@@ -688,6 +689,11 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - - active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST); - -+ 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/0075-multipath-print-warning-if-multipathd-is-not-running.patch b/SOURCES/0075-multipath-print-warning-if-multipathd-is-not-running.patch deleted file mode 100644 index 3c42a01..0000000 --- a/SOURCES/0075-multipath-print-warning-if-multipathd-is-not-running.patch +++ /dev/null @@ -1,107 +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 + - multipath/main.c | 5 +++++ - 3 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index f24d9283..9c8d3e34 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1043,7 +1043,8 @@ deadmap (struct multipath * mpp) - return 1; /* dead */ - } - --int check_daemon(void) -+extern int -+check_daemon(void) - { - int fd; - char *reply; -@@ -1097,6 +1098,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - struct config *conf; - int allow_queueing; - uint64_t *size_mismatch_seen; -+ bool map_processed = false; -+ bool no_daemon = false; - - /* ignore refwwid if it's empty */ - if (refwwid && !strlen(refwwid)) -@@ -1239,7 +1242,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, 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 " -@@ -1267,6 +1272,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - else - remove_map(mpp, vecs, 0); - } -+ map_processed = true; - } - /* - * Flush maps with only dead paths (ie not in sysfs) -@@ -1292,6 +1298,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, 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 81090dd4..8a266d31 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -59,3 +59,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/multipath/main.c b/multipath/main.c -index 607cada2..14d045c9 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -254,6 +254,7 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - int i; - struct multipath * mpp; - char params[PARAMS_SIZE], status[PARAMS_SIZE]; -+ bool maps_present = false; - - if (dm_get_maps(curmp)) - return 1; -@@ -302,6 +303,8 @@ 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) { -@@ -311,6 +314,8 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - put_multipath_config(conf); - } - -+ if (maps_present && !check_daemon()) -+ condlog(2, "multipath devices exist, but multipathd service is not running"); - return 0; - } - diff --git a/SOURCES/0076-multipathd-don-t-access-path-if-it-was-deleted.patch b/SOURCES/0076-multipathd-don-t-access-path-if-it-was-deleted.patch deleted file mode 100644 index 88aa305..0000000 --- a/SOURCES/0076-multipathd-don-t-access-path-if-it-was-deleted.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 23 Jul 2021 14:10:06 -0500 -Subject: [PATCH] multipathd: don't access path if it was deleted - -ev_remove_path() could fail and still delete the path. This could cause -problems for handle_path_wwid_change(), which expected that a failure -meant that the path still existed. ev_remove_path now returns a -different error code for failure to reload the multipath device, so that -it can be differentiated from cases where the path was no removed. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e6c19ab2..823b53a2 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -86,6 +86,9 @@ - #define FILE_NAME_SIZE 256 - #define CMDSIZE 160 - -+#define PATH_REMOVE_FAILED 1 -+#define MAP_RELOAD_FAILED 2 -+ - #define LOG_MSG(lvl, verb, pp) \ - do { \ - if (pp->mpp && checker_selected(&pp->checker) && \ -@@ -840,7 +843,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) == PATH_REMOVE_FAILED && pp->mpp) { - pp->dmstate = PSTATE_FAILED; - dm_fail_path(pp->mpp->alias, pp->dev_t); - } -@@ -1226,13 +1229,13 @@ 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 = MAP_RELOAD_FAILED; - } else { - /* - * update our state from kernel - */ - if (setup_multipath(vecs, mpp)) -- return 1; -+ return PATH_REMOVE_FAILED; - sync_map_state(mpp); - - condlog(2, "%s [%s]: path removed from map %s", -@@ -1250,7 +1253,7 @@ out: - - fail: - remove_map_and_stop_waiter(mpp, vecs); -- return 1; -+ return PATH_REMOVE_FAILED; - } - - static int diff --git a/SOURCES/0077-multipathd.socket-add-missing-conditions-from-servic.patch b/SOURCES/0077-multipathd.socket-add-missing-conditions-from-servic.patch deleted file mode 100644 index 3b1fb1c..0000000 --- a/SOURCES/0077-multipathd.socket-add-missing-conditions-from-servic.patch +++ /dev/null @@ -1,43 +0,0 @@ -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 - -Upstream Status: https://github.com/openSUSE/multipath-tools.git -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2008101 -Conflicts: Match the conditions with RHEL-8 multipathd.service unit - -commit 345ccf564ce7d904641bd32baf4fc53c2283d95c -Author: Luca BRUNO -Date: Fri Sep 24 09:34:01 2021 +0000 - - 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..c62c0fc8 100644 ---- a/multipathd/multipathd.socket -+++ b/multipathd/multipathd.socket -@@ -1,6 +1,9 @@ - [Unit] - Description=multipathd control socket - DefaultDependencies=no -+ConditionPathExists=/etc/multipath.conf -+ConditionKernelCommandLine=!nompath -+ConditionKernelCommandLine=!multipath=off - Before=sockets.target - - [Socket] diff --git a/SOURCES/0078-libmulitpath-add-section-name-to-invalid-keyword-out.patch b/SOURCES/0078-libmulitpath-add-section-name-to-invalid-keyword-out.patch deleted file mode 100644 index 8006ecd..0000000 --- a/SOURCES/0078-libmulitpath-add-section-name-to-invalid-keyword-out.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 23 Sep 2021 14:16:51 -0500 -Subject: [PATCH] libmulitpath: 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 and 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 | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 48b54e87..96b95936 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -507,7 +507,8 @@ validate_config_strvec(vector strvec, char *file) - } - - static int --process_stream(struct config *conf, FILE *stream, vector keywords, char *file) -+process_stream(struct config *conf, FILE *stream, vector keywords, -+ const char *section, char *file) - { - int i; - int r = 0, t; -@@ -571,16 +572,22 @@ process_stream(struct config *conf, FILE *stream, vector keywords, char *file) - 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) -@@ -611,7 +618,7 @@ process_file(struct config *conf, 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/0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch b/SOURCES/0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch deleted file mode 100644 index 5b786f0..0000000 --- a/SOURCES/0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch +++ /dev/null @@ -1,97 +0,0 @@ -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 and print - functions - -Don't keep writing out the function type. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/parser.c | 10 +++++----- - libmultipath/parser.h | 25 ++++++++++++------------- - 2 files changed, 17 insertions(+), 18 deletions(-) - -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 96b95936..e511acf9 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -32,8 +32,8 @@ static int line_nr; - - int - keyword_alloc(vector keywords, char *string, -- int (*handler) (struct config *, vector), -- int (*print) (struct config *, char *, int, const void*), -+ handler_fn *handler, -+ print_fn *print, - int unique) - { - struct keyword *keyword; -@@ -71,8 +71,8 @@ install_sublevel_end(void) - - int - _install_keyword(vector keywords, char *string, -- int (*handler) (struct config *, vector), -- int (*print) (struct config *, char *, int, const void*), -+ handler_fn *handler, -+ print_fn *print, - int unique) - { - int i = 0; -@@ -562,7 +562,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 b7917052..e8d89607 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -39,11 +39,15 @@ - #define EOB "}" - #define MAXBUF 1024 - --/* ketword definition */ -+ -+/* keyword definition */ -+typedef int print_fn(struct config *, char *, int, const void *); -+typedef int handler_fn(struct config *, vector); -+ - struct keyword { - char *string; -- int (*handler) (struct config *, vector); -- int (*print) (struct config *, char *, int, const void *); -+ handler_fn *handler; -+ print_fn *print; - vector sub; - int unique; - }; -@@ -58,19 +62,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), -- int (*print) (struct config *, char *, int, -- const void *), -- 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), -- int (*print) (struct config *, char *, int, -- const void *), -- 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/0080-libmultipath-print-the-correct-file-when-parsing-fai.patch b/SOURCES/0080-libmultipath-print-the-correct-file-when-parsing-fai.patch deleted file mode 100644 index 50173e6..0000000 --- a/SOURCES/0080-libmultipath-print-the-correct-file-when-parsing-fai.patch +++ /dev/null @@ -1,27 +0,0 @@ -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 e511acf9..341f2b80 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -565,8 +565,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/0081-libmultipath-pass-file-and-line-number-to-keyword-ha.patch b/SOURCES/0081-libmultipath-pass-file-and-line-number-to-keyword-ha.patch deleted file mode 100644 index e099ea7..0000000 --- a/SOURCES/0081-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +++ /dev/null @@ -1,536 +0,0 @@ -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 | 145 +++++++++++++++++++++++++----------------- - libmultipath/parser.c | 3 +- - libmultipath/parser.h | 2 +- - 3 files changed, 91 insertions(+), 59 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 13698b76..a8872da7 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -28,7 +28,7 @@ - #include "dict.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; -@@ -57,7 +57,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; -@@ -89,7 +89,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; - -@@ -104,7 +104,7 @@ set_str(vector strvec, void *ptr) - } - - static int --set_regex(vector strvec, void *ptr) -+set_regex(vector strvec, void *ptr, const char *file, int line_nr) - { - char **str_ptr = (char **)ptr; - -@@ -119,7 +119,7 @@ set_regex(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; -@@ -138,7 +138,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; -@@ -240,9 +240,10 @@ print_yes_no_undef (char *buff, int len, 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) \ -@@ -277,12 +278,13 @@ snprint_def_ ## option (struct config *conf, char * buff, int len, \ - - #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) \ -@@ -296,11 +298,12 @@ snprint_hw_ ## option (struct config *conf, char * buff, int len, \ - - #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) \ -@@ -313,12 +316,13 @@ snprint_ovr_ ## option (struct config *conf, char * buff, int len, \ - - #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) \ -@@ -330,9 +334,10 @@ snprint_mp_ ## option (struct config *conf, char * buff, int len, \ - return function (buff, len, 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; -@@ -355,9 +360,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; -@@ -387,13 +393,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); -@@ -451,7 +457,8 @@ static int snprint_uid_attrs(struct config *conf, char *buff, int len, - return p - buff; - } - --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; - -@@ -644,7 +651,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; - } -@@ -675,20 +683,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) \ -@@ -702,12 +713,14 @@ snprint_def_ ## option (struct config *conf, char * buff, int len, \ - - #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) \ -@@ -721,7 +734,7 @@ snprint_mp_ ## option (struct config *conf, char * buff, int len, \ - } - - 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; -@@ -742,7 +755,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; -@@ -767,7 +780,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; -@@ -834,7 +847,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; -@@ -876,7 +889,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; -@@ -919,7 +932,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; -@@ -985,7 +998,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; -@@ -1030,7 +1044,7 @@ snprint_max_fds (struct config *conf, char * buff, int len, 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; -@@ -1074,7 +1088,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; -@@ -1124,7 +1138,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; -@@ -1169,7 +1183,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; - -@@ -1243,7 +1258,8 @@ print_reservation_key(char * buff, int len, struct be64 key, uint8_t flags, - } - - 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, -@@ -1260,7 +1276,8 @@ snprint_def_reservation_key (struct config *conf, char * buff, int len, - } - - 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) -@@ -1281,7 +1298,7 @@ snprint_mp_reservation_key (struct config *conf, char * buff, int len, - } - - 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; -@@ -1422,7 +1439,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; -@@ -1442,7 +1460,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; -@@ -1482,7 +1501,8 @@ snprint_hw_vpd_vendor(struct config *conf, char * buff, int len, - * 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(); -@@ -1504,7 +1524,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(); -@@ -1527,7 +1548,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; \ - \ -@@ -1543,7 +1565,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; \ - \ -@@ -1583,13 +1606,15 @@ snprint_ble_simple (struct config *conf, char * buff, int len, - } - - 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); - } -@@ -1623,7 +1648,8 @@ snprint_bled_product (struct config *conf, char * buff, int len, - * 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(); -@@ -1635,7 +1661,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; - -@@ -1672,7 +1699,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(); -@@ -1689,7 +1717,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(); -@@ -1701,7 +1730,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; - -@@ -1730,7 +1760,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 341f2b80..29e8cee0 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -562,7 +562,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 e8d89607..8b424b7a 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -42,7 +42,7 @@ - - /* keyword definition */ - typedef int print_fn(struct config *, char *, int, 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/0082-libmultipath-make-set_int-take-a-range-for-valid-val.patch b/SOURCES/0082-libmultipath-make-set_int-take-a-range-for-valid-val.patch deleted file mode 100644 index 712bceb..0000000 --- a/SOURCES/0082-libmultipath-make-set_int-take-a-range-for-valid-val.patch +++ /dev/null @@ -1,250 +0,0 @@ -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 a8872da7..686f4d5c 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -28,7 +28,8 @@ - #include "dict.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; -@@ -43,11 +44,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; - } -@@ -76,8 +83,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; -@@ -246,6 +253,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, char * buff, int len, \ -@@ -287,6 +302,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, char * buff, int len, \ -@@ -306,6 +333,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, char * buff, int len, \ -@@ -325,6 +363,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, char * buff, int len, \ -@@ -351,7 +400,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) -@@ -528,22 +577,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) -@@ -562,7 +611,7 @@ snprint_def_queue_without_daemon (struct config *conf, - return 0; - } - --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(flush_on_last_del, set_yes_no_undef) -@@ -630,13 +679,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) -@@ -662,19 +711,19 @@ static int snprint_def_disable_changed_wwids(struct config *conf, char *buff, - return print_ignored(buff, len); - } - --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) - -@@ -1437,27 +1486,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/0083-libmultipath-improve-checks-for-set_str.patch b/SOURCES/0083-libmultipath-improve-checks-for-set_str.patch deleted file mode 100644 index f48bda6..0000000 --- a/SOURCES/0083-libmultipath-improve-checks-for-set_str.patch +++ /dev/null @@ -1,177 +0,0 @@ -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 | 89 +++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 78 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 686f4d5c..d547d898 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" -@@ -121,7 +123,72 @@ set_regex(vector strvec, void *ptr, const char *file, int line_nr) - - if (!*str_ptr) - return 1; -+ 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; - } - -@@ -400,19 +467,19 @@ declare_def_snprint(checkint, print_int) - declare_def_handler(max_checkint, set_uint) - declare_def_snprint(max_checkint, print_int) - --declare_def_range_handler(verbosity, 0, MAX_VERBOSITY) -+declare_def_range_handler(verbosity, 0, 4) - 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; -@@ -545,11 +612,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) -@@ -633,13 +700,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) -@@ -738,7 +805,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) - -@@ -1781,7 +1848,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/0084-libmultipath-split-set_int-to-enable-reuse.patch b/SOURCES/0084-libmultipath-split-set_int-to-enable-reuse.patch deleted file mode 100644 index 92fdfec..0000000 --- a/SOURCES/0084-libmultipath-split-set_int-to-enable-reuse.patch +++ /dev/null @@ -1,191 +0,0 @@ -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 d547d898..6330836a 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -30,17 +30,12 @@ - #include "dict.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) -@@ -49,17 +44,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; -@@ -965,6 +973,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; - -@@ -974,10 +983,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); -@@ -1130,14 +1139,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); - -@@ -1206,6 +1213,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; - -@@ -1220,11 +1228,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 -@@ -1256,6 +1264,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; - -@@ -1267,11 +1276,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 -@@ -1416,6 +1425,7 @@ snprint_mp_reservation_key (struct config *conf, char * buff, int len, - 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; - -@@ -1425,11 +1435,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/0085-libmultipath-cleanup-invalid-config-handling.patch b/SOURCES/0085-libmultipath-cleanup-invalid-config-handling.patch deleted file mode 100644 index 7b0d2ff..0000000 --- a/SOURCES/0085-libmultipath-cleanup-invalid-config-handling.patch +++ /dev/null @@ -1,201 +0,0 @@ -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 6330836a..b255322e 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -212,8 +212,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; -@@ -234,7 +237,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; -@@ -523,9 +527,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; -@@ -538,9 +539,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); -@@ -591,8 +597,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; - } -@@ -811,8 +819,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; -+ } - return set_path(strvec, &conf->config_dir, file, line_nr); - } - declare_def_snprint(config_dir, print_str) -@@ -872,7 +883,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; -@@ -897,7 +910,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; -@@ -923,7 +938,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; - } -@@ -1026,7 +1043,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 = 0; -+ condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"", -+ file, line_nr, buff); - - FREE(buff); - return 0; -@@ -1060,13 +1078,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; -@@ -1179,10 +1203,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; -@@ -1318,10 +1343,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; -@@ -1585,7 +1613,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/0086-libmultipath-don-t-return-error-on-invalid-values.patch b/SOURCES/0086-libmultipath-don-t-return-error-on-invalid-values.patch deleted file mode 100644 index 952adb9..0000000 --- a/SOURCES/0086-libmultipath-don-t-return-error-on-invalid-values.patch +++ /dev/null @@ -1,218 +0,0 @@ -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 b255322e..5a0255b0 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -29,7 +29,7 @@ - #include "mpath_cmd.h" - #include "dict.h" - --static int -+static void - do_set_int(vector strvec, void *ptr, int min, int max, const char *file, - int line_nr, char *buff) - { -@@ -44,7 +44,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; -@@ -53,7 +53,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 -@@ -61,16 +61,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 -@@ -79,7 +78,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) -@@ -92,17 +90,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 -@@ -990,7 +985,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; - -@@ -1000,11 +994,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; -@@ -1151,28 +1144,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 -@@ -1238,7 +1227,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; - -@@ -1253,11 +1241,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 -@@ -1289,7 +1277,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; - -@@ -1302,10 +1289,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 -@@ -1453,7 +1440,6 @@ snprint_mp_reservation_key (struct config *conf, char * buff, int len, - 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; - -@@ -1464,10 +1450,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/0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch b/SOURCES/0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch deleted file mode 100644 index 18cb434..0000000 --- a/SOURCES/0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch +++ /dev/null @@ -1,115 +0,0 @@ -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/sysfs.c | 22 ++++++++++++++++++++++ - libmultipath/sysfs.h | 1 + - multipathd/main.c | 31 ++++++++++++++++++++++++++++++- - 3 files changed, 53 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 62ec2ed7..a57bd60e 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 9ae30b39..91092e44 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(const struct path *pp); - #endif -diff --git a/multipathd/main.c b/multipathd/main.c -index 823b53a2..e2b9d546 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1256,6 +1256,35 @@ fail: - return PATH_REMOVE_FAILED; - } - -+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) - { -@@ -1321,7 +1350,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/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch b/SOURCES/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch deleted file mode 100644 index 40b4f0e..0000000 --- a/SOURCES/0088-libmultipath-make-helper-function-to-trigger-path-ue.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 Jan 2022 14:45:38 -0600 -Subject: [PATCH] libmultipath: make helper function to trigger path uevents - -Pull the code that checks if a path needs to trigger a uevent, and -triggers, out of trigger_paths_udev_change() and into a new function, -trigger_path_udev_change(). This function will be used separately by -a future patch. No functional changes. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 79 +++++++++++++++++++++------------------- - libmultipath/configure.h | 1 + - 2 files changed, 43 insertions(+), 37 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 9c8d3e34..9a9890f5 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -545,11 +545,8 @@ unref: - } - - void --trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) -+trigger_path_udev_change(struct path *pp, bool is_mpath) - { -- struct pathgroup *pgp; -- struct path *pp; -- int i, j; - /* - * If a path changes from multipath to non-multipath, we must - * synthesize an artificial "add" event, otherwise the LVM2 rules -@@ -557,6 +554,45 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - * irritate ourselves with an "add", so use "change". - */ - const char *action = is_mpath ? "change" : "add"; -+ const char *env; -+ -+ if (!pp->udev) -+ return; -+ /* -+ * Paths that are already classified as multipath -+ * members don't need another uevent. -+ */ -+ env = udev_device_get_property_value( -+ pp->udev, "DM_MULTIPATH_DEVICE_PATH"); -+ -+ if (is_mpath && env != NULL && !strcmp(env, "1")) { -+ /* -+ * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", -+ * path is in "maybe" state and timer is running -+ * Send uevent now (see multipath.rules). -+ */ -+ env = udev_device_get_property_value( -+ pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); -+ if (env == NULL || !strcmp(env, "0")) -+ return; -+ } else if (!is_mpath && -+ (env == NULL || !strcmp(env, "0"))) -+ return; -+ -+ condlog(3, "triggering %s uevent for %s (is %smultipath member)", -+ action, pp->dev, is_mpath ? "" : "no "); -+ sysfs_attr_set_value(pp->udev, "uevent", -+ action, strlen(action)); -+ trigger_partitions_udev_change(pp->udev, action, -+ strlen(action)); -+} -+ -+void -+trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) -+{ -+ struct pathgroup *pgp; -+ struct path *pp; -+ int i, j; - - if (!mpp || !mpp->pg) - return; -@@ -564,39 +600,8 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) - vector_foreach_slot (mpp->pg, pgp, i) { - if (!pgp->paths) - continue; -- vector_foreach_slot(pgp->paths, pp, j) { -- const char *env; -- -- if (!pp->udev) -- continue; -- /* -- * Paths that are already classified as multipath -- * members don't need another uevent. -- */ -- env = udev_device_get_property_value( -- pp->udev, "DM_MULTIPATH_DEVICE_PATH"); -- -- if (is_mpath && env != NULL && !strcmp(env, "1")) { -- /* -- * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", -- * path is in "maybe" state and timer is running -- * Send uevent now (see multipath.rules). -- */ -- env = udev_device_get_property_value( -- pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); -- if (env == NULL || !strcmp(env, "0")) -- continue; -- } else if (!is_mpath && -- (env == NULL || !strcmp(env, "0"))) -- continue; -- -- condlog(3, "triggering %s uevent for %s (is %smultipath member)", -- action, pp->dev, is_mpath ? "" : "no "); -- sysfs_attr_set_value(pp->udev, "uevent", -- action, strlen(action)); -- trigger_partitions_udev_change(pp->udev, action, -- strlen(action)); -- } -+ vector_foreach_slot(pgp->paths, pp, j) -+ trigger_path_udev_change(pp, is_mpath); - } - - mpp->needs_paths_uevent = 0; -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 8a266d31..5cf08d45 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -56,6 +56,7 @@ int get_refwwid (enum mpath_cmds cmd, char * dev, enum devtypes dev_type, - vector pathvec, char **wwid); - int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh, int is_daemon); - struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); -+void trigger_path_udev_change(struct path *pp, bool is_mpath); - 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); diff --git a/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch b/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch deleted file mode 100644 index 3a8b2a3..0000000 --- a/SOURCES/0089-multipathd-trigger-udev-change-on-path-addition.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 17 Jan 2022 16:46:18 -0600 -Subject: [PATCH] multipathd: trigger udev change on path addition - -When a multipath device is created for the first time, there is a window -where some path devices way be added to the multipath device, but never -claimed in udev. This can allow other device owners, like lvm, to think -they can use the device. - -When a multipath device is first created, all the existing paths that -are not claimed by multipath have a uevent triggered so that they can -get claimed. After that, multipath assumes all future paths added to the -multipath device will have been claimed by multipath, since the device's -WWID is now in the wwids file. This doesn't work for any paths that -have already been processed by the multipath.rules udev rules before -the multipath device was created. - -To close this window, when path device is added, and a matching -multipath device already exists, multipathd now checks if the device is -claimed by multipath, and if not, triggers a uevent to claim it. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index e2b9d546..f4b79882 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1005,6 +1005,8 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - free_path(pp); - return 1; - } -+ if (mpp) -+ trigger_path_udev_change(pp, true); - if (mpp && mpp->wait_for_udev && - (pathcount(mpp, PATH_UP) > 0 || - (pathcount(mpp, PATH_GHOST) > 0 && diff --git a/SOURCES/0090-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch b/SOURCES/0090-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch deleted file mode 100644 index 1e490cb..0000000 --- a/SOURCES/0090-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 2 Feb 2022 17:00:21 -0600 -Subject: [PATCH] RH: add support to mpathconf for setting arbitrary default - options - -mpathconf now supports --option :[] for setting, changing, -or removing options from the defaults section of multipath.conf. - -Signed-off-by: Benjamin Marzinski ---- - multipath/mpathconf | 58 ++++++++++++++++++++++++++++++++++++++++--- - multipath/mpathconf.8 | 7 ++++++ - 2 files changed, 62 insertions(+), 3 deletions(-) - -diff --git a/multipath/mpathconf b/multipath/mpathconf -index 5f2285ab..870512c0 100644 ---- a/multipath/mpathconf -+++ b/multipath/mpathconf -@@ -17,7 +17,7 @@ - # 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 -+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 HAVE_OPTION OPTION_NAME OPTION_VALUE - - DEFAULT_CONFIG="# device-mapper-multipath configuration file - -@@ -57,6 +57,7 @@ function usage - 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 "Add/Change/Remove option in defaults section: --option :" - 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 " -@@ -167,6 +168,20 @@ function parse_args - exit 1 - fi - ;; -+ --option) -+ if [ -n "$2" ]; then -+ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) -+ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) -+ if [ -z "$OPTION_NAME" ]; then -+ usage -+ exit 1 -+ fi -+ shift 2 -+ else -+ usage -+ exit 1 -+ fi -+ ;; - --enable_foreign) - if [ -n "$2" ]; then - FOREIGN=$2 -@@ -213,12 +228,15 @@ function parse_args - - function validate_args - { -- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then - echo "ignoring extra parameters on disable" - FRIENDLY="" - FIND="" - PROPERTY="" - MODULE="" -+ FOREIGN="" -+ OPTION_NAME="" -+ OPTION_VALUE="" - fi - if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then - echo "--user_friendly_names must be either 'y' or 'n'" -@@ -240,7 +258,19 @@ 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" -a -z "$FOREIGN" ]; then -+ if [ -n "$OPTION_NAME" ]; then -+ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then -+ echo "--option name \"$OPTION_NAME\" is invalid" -+ exit 1 -+ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then -+ echo "--option value \"$OPTION_VALUE\" is invalid" -+ exit 1 -+ fi -+ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then -+ OPTION_VALUE=\"$OPTION_VALUE\" -+ fi -+ fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then - SHOW_STATUS=1 - fi - if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then -@@ -349,6 +379,13 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then - elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then - HAVE_FOREIGN=2 - fi -+ if [ -n "$OPTION_NAME" ]; then -+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'[[:space:]][[:space:]]*'"$OPTION_VALUE" ; then -+ HAVE_OPTION=1 -+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q '^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$' ; then -+ HAVE_OPTION=0 -+ fi -+ fi - fi - - if [ "$HAVE_EXCEPTIONS" = "1" ]; then -@@ -523,6 +560,21 @@ elif [ "$FOREIGN" = "n" ]; then - fi - fi - -+if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then -+ if [ -z "$HAVE_OPTION" ]; then -+ sed -i '/^defaults[[:space:]]*{/ a\ -+ '"$OPTION_NAME"' '"$OPTION_VALUE"' -+' $TMPFILE -+ CHANGED_CONFIG=1 -+ elif [ "$HAVE_OPTION" = 0 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE -+ CHANGED_CONFIG=1 -+ fi -+elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE -+ CHANGED_CONFIG=1 -+fi -+ - if [ -f "$OUTPUTFILE" ]; then - cp $OUTPUTFILE $OUTPUTFILE.old - if [ $? != 0 ]; then -diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 -index 83515eb4..63fe633e 100644 ---- a/multipath/mpathconf.8 -+++ b/multipath/mpathconf.8 -@@ -101,6 +101,13 @@ to the - 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 --option \fB:[]\fP -+Sets the defaults section option \fB\fP to \fB\fP. If the -+option was not previously set in the defaults section, it is added. If it was -+set, its value is changed to \fB\fP. If \fB\fP is left blank, -+then the option is removed from the defaults section, if was set there. 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. diff --git a/SOURCES/0091-multipath-tools-add-HPE-MSA-1060-2060-to-hwtable.patch b/SOURCES/0091-multipath-tools-add-HPE-MSA-1060-2060-to-hwtable.patch deleted file mode 100644 index d49cec8..0000000 --- a/SOURCES/0091-multipath-tools-add-HPE-MSA-1060-2060-to-hwtable.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Xose Vazquez Perez -Date: Wed, 9 Sep 2020 17:48:05 +0200 -Subject: [PATCH] multipath-tools: add HPE MSA 1060/2060 to hwtable - -Cc: Martin Wilck -Cc: Christophe Varoqui -Cc: DM-DEVEL ML -Reviewed-by: Martin Wilck -Signed-off-by: Xose Vazquez Perez -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d680bdfc..59bc0d6e 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -181,9 +181,9 @@ static struct hwentry default_hw[] = { - .prio_name = PRIO_ALUA, - }, - { -- /* MSA 1040, 1050, 2040 and 2050 families */ -+ /* MSA 1040, 1050, 1060, 2040, 2050 and 2060 families */ - .vendor = "HP", -- .product = "MSA [12]0[45]0 SA[NS]", -+ .product = "MSA [12]0[456]0 SA[NS]", - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .no_path_retry = 18, diff --git a/SOURCES/0092-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch b/SOURCES/0092-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch deleted file mode 100644 index c432bbc..0000000 --- a/SOURCES/0092-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Uday Shankar -Date: Wed, 9 Mar 2022 13:03:26 -0700 -Subject: [PATCH] multipath-tools: update mpp->force_readonly in ev_add_path - -When NVMe disks are added to the system, no uevent containing the -DISK_RO property is generated. As a result, dm-* nodes backed by -readonly NVMe disks will not have their RO state set properly. The -result looks like this: - -$ multipath -l -eui.00c92c091fd6564424a9376600011bd1 dm-3 NVME,Pure Storage FlashArray -size=1.0T features='0' hwhandler='0' wp=rw -|-+- policy='service-time 0' prio=0 status=active -| `- 0:2:2:72657 nvme0n2 259:4 active undef running -`-+- policy='service-time 0' prio=0 status=enabled - `- 1:0:2:72657 nvme1n2 259:1 active undef running -$ cat /sys/block/dm-3/ro -0 -$ cat /sys/block/nvme*n2/ro -1 -1 - -This is not a problem for SCSI disks, since the kernel will emit change -uevents containing the DISK_RO property when the disk is added to the -system. See the following thread for my initial attempt to fix this -issue at the kernel level: -https://lore.kernel.org/linux-block/Yib8GqCA5e3SQYty@infradead.org/T/#t - -Fix the issue by picking up the path ro state from sysfs in ev_add_path, -setting the mpp->force_readonly accordingly, and changing -dm_addmap_create to be aware of mpp->force_readonly. - -Signed-off-by: Uday Shankar -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - multipathd/main.c | 6 ++++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 3f70e576..e3c3c119 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -420,7 +420,7 @@ int dm_addmap_create (struct multipath *mpp, char * params) - int ro; - uint16_t udev_flags = build_udev_flags(mpp, 0); - -- for (ro = 0; ro <= 1; ro++) { -+ for (ro = mpp->force_readonly ? 1 : 0; ro <= 1; ro++) { - int err; - - if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, ro, -diff --git a/multipathd/main.c b/multipathd/main.c -index f4b79882..eeded52b 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -988,6 +988,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int retries = 3; - int start_waiter = 0; - int ret; -+ int ro; - - /* - * need path UID to go any further -@@ -1051,6 +1052,11 @@ rescan: - /* persistent reservation check*/ - mpath_pr_event_handle(pp); - -+ /* ro check - if new path is ro, force map to be ro as well */ -+ ro = sysfs_get_ro(pp); -+ if (ro == 1) -+ mpp->force_readonly = 1; -+ - if (!need_do_map) - return 0; - diff --git a/SOURCES/0093-updated-HPE-MSA-builtin-config.patch b/SOURCES/0093-updated-HPE-MSA-builtin-config.patch deleted file mode 100644 index 0c61ec3..0000000 --- a/SOURCES/0093-updated-HPE-MSA-builtin-config.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 29 Apr 2022 15:57:12 -0500 -Subject: [PATCH] updated HPE MSA builtin config - -Make the config better align to MSA 4th, 5th and 6th Generation systems. - -Cc: Jon.Paul@hpe.com -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 59bc0d6e..d6325864 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -182,8 +182,8 @@ static struct hwentry default_hw[] = { - }, - { - /* MSA 1040, 1050, 1060, 2040, 2050 and 2060 families */ -- .vendor = "HP", -- .product = "MSA [12]0[456]0 SA[NS]", -+ .vendor = "(HP|HPE)", -+ .product = "MSA [12]0[456]0 (SAN|SAS|FC|iSCSI)", - .pgpolicy = GROUP_BY_PRIO, - .pgfailback = -FAILBACK_IMMEDIATE, - .no_path_retry = 18, diff --git a/SOURCES/0094-multipath-return-failure-on-an-invalid-remove-comman.patch b/SOURCES/0094-multipath-return-failure-on-an-invalid-remove-comman.patch deleted file mode 100644 index add7207..0000000 --- a/SOURCES/0094-multipath-return-failure-on-an-invalid-remove-comman.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 30 Mar 2022 15:14:56 -0500 -Subject: [PATCH] multipath: return failure on an invalid remove command - -When "multipath -f" is run on a device that doesn't exist or isn't a -multipath device, the command will not remove any device, but it will -still return success. Multiple functions rely on _dm_flush_map() -returning success when called with name that doesn't match any -multipath device. So before calling _dm_flush_map(), call dm_is_mpath(), -to check if the device exists and is a multipath device, and return -failure if it's not. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck remove_retries; - if (cmd == CMD_FLUSH_ONE) { -+ if (dm_is_mpath(dev) != 1) { -+ condlog(0, "%s is not a multipath device", dev); -+ r = RTVL_FAIL; -+ goto out; -+ } - r = dm_suspend_and_flush_map(dev, retries) ? - RTVL_FAIL : RTVL_OK; - goto out; diff --git a/SOURCES/0095-libmultipath-steal-the-src-string-pointer-in-merge_s.patch b/SOURCES/0095-libmultipath-steal-the-src-string-pointer-in-merge_s.patch deleted file mode 100644 index 5de4eaf..0000000 --- a/SOURCES/0095-libmultipath-steal-the-src-string-pointer-in-merge_s.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:35 -0500 -Subject: [PATCH] libmultipath: steal the src string pointer in merge_str() - -Instead of allocating a copy when the original string is going to be -freed right after the merge, just steal the pointer. Also, merge_mpe() -can't get called with NULL arguments. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 16 +++++----------- - 1 file changed, 5 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index abbddaf1..aa79561e 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -323,9 +323,9 @@ set_param_str(const char * str) - } - - #define merge_str(s) \ -- if (!dst->s && src->s) { \ -- if (!(dst->s = set_param_str(src->s))) \ -- return 1; \ -+ if (!dst->s && src->s && strlen(src->s)) { \ -+ dst->s = src->s; \ -+ src->s = NULL; \ - } - - #define merge_num(s) \ -@@ -333,7 +333,7 @@ set_param_str(const char * str) - dst->s = src->s - - --static int -+static void - merge_hwe (struct hwentry * dst, struct hwentry * src) - { - char id[SCSI_VENDOR_SIZE+PATH_PRODUCT_SIZE]; -@@ -385,15 +385,11 @@ merge_hwe (struct hwentry * dst, struct hwentry * src) - reconcile_features_with_options(id, &dst->features, - &dst->no_path_retry, - &dst->retain_hwhandler); -- return 0; - } - --static int -+static void - merge_mpe(struct mpentry *dst, struct mpentry *src) - { -- if (!dst || !src) -- return 1; -- - merge_str(alias); - merge_str(uid_attribute); - merge_str(getuid); -@@ -435,8 +431,6 @@ merge_mpe(struct mpentry *dst, struct mpentry *src) - merge_num(uid); - merge_num(gid); - merge_num(mode); -- -- return 0; - } - - void merge_mptable(vector mptable) diff --git a/SOURCES/0096-libmultipath-enable-linear-ordering-of-bus-proto-tup.patch b/SOURCES/0096-libmultipath-enable-linear-ordering-of-bus-proto-tup.patch deleted file mode 100644 index 76a9407..0000000 --- a/SOURCES/0096-libmultipath-enable-linear-ordering-of-bus-proto-tup.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 17 Feb 2022 17:22:32 +0100 -Subject: [PATCH] libmultipath: enable linear ordering of bus/proto tuple - -We categorized protocols by bus/proto_id, while we only differentiate -protocol IDs for SCSI. Allow transforming this into a linear sequence -of bus/protocol IDs by having non-SCSI first, and follwing up with -the different SCSI protocols. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.c | 10 ++++++++++ - libmultipath/structs.h | 14 ++++++++++++-- - 2 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index dda9884c..aaf85297 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -722,3 +722,13 @@ out: - - return 0; - } -+ -+unsigned int bus_protocol_id(const struct path *pp) { -+ if (!pp || pp->bus < 0 || pp->bus > SYSFS_BUS_SCSI) -+ return SYSFS_BUS_UNDEF; -+ if (pp->bus != SYSFS_BUS_SCSI) -+ return pp->bus; -+ if ((int)pp->sg_id.proto_id < 0 || pp->sg_id.proto_id > SCSI_PROTOCOL_UNSPEC) -+ return SYSFS_BUS_UNDEF; -+ return SYSFS_BUS_SCSI + pp->sg_id.proto_id; -+} -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index a5dbad5b..5e29ae38 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -57,12 +57,13 @@ enum failback_mode { - FAILBACK_FOLLOWOVER - }; - -+/* SYSFS_BUS_SCSI should be last, see bus_protocol_id() */ - enum sysfs_buses { - SYSFS_BUS_UNDEF, -- SYSFS_BUS_SCSI, - SYSFS_BUS_CCW, - SYSFS_BUS_CCISS, - SYSFS_BUS_NVME, -+ SYSFS_BUS_SCSI, - }; - - enum pathstates { -@@ -190,9 +191,18 @@ enum scsi_protocol { - SCSI_PROTOCOL_SAS = 6, - SCSI_PROTOCOL_ADT = 7, /* Media Changers */ - SCSI_PROTOCOL_ATA = 8, -- SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ -+ SCSI_PROTOCOL_USB = 9, /* USB Attached SCSI (UAS), and others */ -+ SCSI_PROTOCOL_UNSPEC = 0xa, /* No specific protocol */ - }; - -+/* -+ * Linear ordering of bus/protocol -+ * This assumes that SYSFS_BUS_SCSI is last in enum sysfs_buses -+ * SCSI is the only bus type for which we distinguish protocols. -+ */ -+#define LAST_BUS_PROTOCOL_ID (SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC) -+unsigned int bus_protocol_id(const struct path *pp); -+ - enum no_undef_states { - NU_NO = -1, - NU_UNDEF = 0, diff --git a/SOURCES/0097-libmultipath-use-bus_protocol_id-in-snprint_path_pro.patch b/SOURCES/0097-libmultipath-use-bus_protocol_id-in-snprint_path_pro.patch deleted file mode 100644 index 31976e7..0000000 --- a/SOURCES/0097-libmultipath-use-bus_protocol_id-in-snprint_path_pro.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 17 Feb 2022 17:24:25 +0100 -Subject: [PATCH] libmultipath: use bus_protocol_id() in - snprint_path_protocol() - -Simplify bus_protocol_id() by using the linear ordering. - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 56 +++++++++++++++++--------------------------- - 1 file changed, 21 insertions(+), 35 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 298b3764..ff4d1854 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -662,41 +662,27 @@ snprint_path_failures(char * buff, size_t len, const struct path * pp) - int - snprint_path_protocol(char * buff, size_t len, const struct path * pp) - { -- switch (pp->bus) { -- case SYSFS_BUS_SCSI: -- switch (pp->sg_id.proto_id) { -- case SCSI_PROTOCOL_FCP: -- return snprintf(buff, len, "scsi:fcp"); -- case SCSI_PROTOCOL_SPI: -- return snprintf(buff, len, "scsi:spi"); -- case SCSI_PROTOCOL_SSA: -- return snprintf(buff, len, "scsi:ssa"); -- case SCSI_PROTOCOL_SBP: -- return snprintf(buff, len, "scsi:sbp"); -- case SCSI_PROTOCOL_SRP: -- return snprintf(buff, len, "scsi:srp"); -- case SCSI_PROTOCOL_ISCSI: -- return snprintf(buff, len, "scsi:iscsi"); -- case SCSI_PROTOCOL_SAS: -- return snprintf(buff, len, "scsi:sas"); -- case SCSI_PROTOCOL_ADT: -- return snprintf(buff, len, "scsi:adt"); -- case SCSI_PROTOCOL_ATA: -- return snprintf(buff, len, "scsi:ata"); -- case SCSI_PROTOCOL_UNSPEC: -- default: -- return snprintf(buff, len, "scsi:unspec"); -- } -- case SYSFS_BUS_CCW: -- return snprintf(buff, len, "ccw"); -- case SYSFS_BUS_CCISS: -- return snprintf(buff, len, "cciss"); -- case SYSFS_BUS_NVME: -- return snprintf(buff, len, "nvme"); -- case SYSFS_BUS_UNDEF: -- default: -- return snprintf(buff, len, "undef"); -- } -+ static const char * const protocol_name[LAST_BUS_PROTOCOL_ID + 1] = { -+ [SYSFS_BUS_UNDEF] = "undef", -+ [SYSFS_BUS_CCW] = "ccw", -+ [SYSFS_BUS_CCISS] = "cciss", -+ [SYSFS_BUS_NVME] = "nvme", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_FCP] = "scsi:fcp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SPI] = "scsi:spi", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SSA] = "scsi:ssa", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SBP] = "scsi:sbp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SRP] = "scsi:srp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ISCSI] = "scsi:iscsi", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SAS] = "scsi:sas", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ADT] = "scsi:adt", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ATA] = "scsi:ata", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_USB] = "scsi:usb", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC] = "scsi:unspec", -+ }; -+ const char *pn = protocol_name[bus_protocol_id(pp)]; -+ -+ assert(pn != NULL); -+ return snprintf(buff, len, "%s", pn); - } - - int diff --git a/SOURCES/0098-libmultipath-make-protocol_name-global.patch b/SOURCES/0098-libmultipath-make-protocol_name-global.patch deleted file mode 100644 index 9d6a329..0000000 --- a/SOURCES/0098-libmultipath-make-protocol_name-global.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:36 -0500 -Subject: [PATCH] libmultipath: make protocol_name global - -Future patches will make use of this, so move it out of -snprint_path_protocol() - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/print.c | 17 ----------------- - libmultipath/structs.c | 18 ++++++++++++++++++ - libmultipath/structs.h | 1 + - 3 files changed, 19 insertions(+), 17 deletions(-) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index ff4d1854..1f6d27bd 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -662,23 +662,6 @@ snprint_path_failures(char * buff, size_t len, const struct path * pp) - int - snprint_path_protocol(char * buff, size_t len, const struct path * pp) - { -- static const char * const protocol_name[LAST_BUS_PROTOCOL_ID + 1] = { -- [SYSFS_BUS_UNDEF] = "undef", -- [SYSFS_BUS_CCW] = "ccw", -- [SYSFS_BUS_CCISS] = "cciss", -- [SYSFS_BUS_NVME] = "nvme", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_FCP] = "scsi:fcp", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SPI] = "scsi:spi", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SSA] = "scsi:ssa", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SBP] = "scsi:sbp", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SRP] = "scsi:srp", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ISCSI] = "scsi:iscsi", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SAS] = "scsi:sas", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ADT] = "scsi:adt", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ATA] = "scsi:ata", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_USB] = "scsi:usb", -- [SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC] = "scsi:unspec", -- }; - const char *pn = protocol_name[bus_protocol_id(pp)]; - - assert(pn != NULL); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index aaf85297..19099bed 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -20,6 +20,24 @@ - #include "prioritizers/alua_spc3.h" - #include "dm-generic.h" - -+const char * const protocol_name[LAST_BUS_PROTOCOL_ID + 1] = { -+ [SYSFS_BUS_UNDEF] = "undef", -+ [SYSFS_BUS_CCW] = "ccw", -+ [SYSFS_BUS_CCISS] = "cciss", -+ [SYSFS_BUS_NVME] = "nvme", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_FCP] = "scsi:fcp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SPI] = "scsi:spi", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SSA] = "scsi:ssa", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SBP] = "scsi:sbp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SRP] = "scsi:srp", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ISCSI] = "scsi:iscsi", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SAS] = "scsi:sas", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ADT] = "scsi:adt", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ATA] = "scsi:ata", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_USB] = "scsi:usb", -+ [SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC] = "scsi:unspec", -+}; -+ - struct adapter_group * - alloc_adaptergroup(void) - { -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 5e29ae38..ab99852f 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -202,6 +202,7 @@ enum scsi_protocol { - */ - #define LAST_BUS_PROTOCOL_ID (SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC) - unsigned int bus_protocol_id(const struct path *pp); -+extern const char * const protocol_name[]; - - enum no_undef_states { - NU_NO = -1, diff --git a/SOURCES/0099-libmultipath-add-a-protocol-subsection-to-multipath..patch b/SOURCES/0099-libmultipath-add-a-protocol-subsection-to-multipath..patch deleted file mode 100644 index ae16fa9..0000000 --- a/SOURCES/0099-libmultipath-add-a-protocol-subsection-to-multipath..patch +++ /dev/null @@ -1,419 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:37 -0500 -Subject: [PATCH] libmultipath: add a protocol subsection to multipath.conf - -Some storage arrays can be accessed using multiple protocols at the same -time. In these cases, users may want to set path attributes -differently, depending on the protocol that the path is using. To allow -this, add a protocol subsection to the overrides section in -multipath.conf, which allows select path-specific options to be set. -This commit simply adds the subsection, and handles merging matching -entries. Future patches will make use of the section. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 83 ++++++++++++++++++++++++++++++++++++ - libmultipath/config.h | 10 +++++ - libmultipath/dict.c | 99 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/print.c | 44 +++++++++++++++++++ - 4 files changed, 236 insertions(+) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index aa79561e..88975323 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -173,6 +173,18 @@ char *get_mpe_wwid(vector mptable, char *alias) - return NULL; - } - -+static void -+free_pctable (vector pctable) -+{ -+ int i; -+ struct pcentry *pce; -+ -+ vector_foreach_slot(pctable, pce, i) -+ free(pce); -+ -+ vector_free(pctable); -+} -+ - void - free_hwe (struct hwentry * hwe) - { -@@ -218,6 +230,9 @@ free_hwe (struct hwentry * hwe) - if (hwe->bl_product) - FREE(hwe->bl_product); - -+ if (hwe->pctable) -+ free_pctable(hwe->pctable); -+ - FREE(hwe); - } - -@@ -299,6 +314,15 @@ alloc_hwe (void) - return hwe; - } - -+struct pcentry * -+alloc_pce (void) -+{ -+ struct pcentry *pce = (struct pcentry *) -+ calloc(1, sizeof(struct pcentry)); -+ pce->type = -1; -+ return pce; -+} -+ - static char * - set_param_str(const char * str) - { -@@ -332,6 +356,13 @@ set_param_str(const char * str) - if (!dst->s && src->s) \ - dst->s = src->s - -+static void -+merge_pce(struct pcentry *dst, struct pcentry *src) -+{ -+ merge_num(fast_io_fail); -+ merge_num(dev_loss); -+ merge_num(eh_deadline); -+} - - static void - merge_hwe (struct hwentry * dst, struct hwentry * src) -@@ -538,6 +569,51 @@ out: - return 1; - } - -+static void -+validate_pctable(struct hwentry *ovr, int idx, const char *table_desc) -+{ -+ struct pcentry *pce; -+ -+ if (!ovr || !ovr->pctable) -+ return; -+ -+ vector_foreach_slot_after(ovr->pctable, pce, idx) { -+ if (pce->type < 0) { -+ condlog(0, "protocol section in %s missing type", -+ table_desc); -+ vector_del_slot(ovr->pctable, idx--); -+ free(pce); -+ } -+ } -+ -+ if (VECTOR_SIZE(ovr->pctable) == 0) { -+ vector_free(ovr->pctable); -+ ovr->pctable = NULL; -+ } -+} -+ -+static void -+merge_pctable(struct hwentry *ovr) -+{ -+ struct pcentry *pce1, *pce2; -+ int i, j; -+ -+ if (!ovr || !ovr->pctable) -+ return; -+ -+ vector_foreach_slot(ovr->pctable, pce1, i) { -+ j = i + 1; -+ vector_foreach_slot_after(ovr->pctable, pce2, j) { -+ if (pce1->type != pce2->type) -+ continue; -+ merge_pce(pce2,pce1); -+ vector_del_slot(ovr->pctable, i--); -+ free(pce1); -+ break; -+ } -+ } -+} -+ - static void - factorize_hwtable (vector hw, int n, const char *table_desc) - { -@@ -666,6 +742,7 @@ process_config_dir(struct config *conf, char *dir) - int i, n; - char path[LINE_MAX]; - int old_hwtable_size; -+ int old_pctable_size = 0; - - if (dir[0] != '/') { - condlog(1, "config_dir '%s' must be a fully qualified path", -@@ -692,11 +769,15 @@ process_config_dir(struct config *conf, char *dir) - continue; - - old_hwtable_size = VECTOR_SIZE(conf->hwtable); -+ old_pctable_size = conf->overrides ? -+ VECTOR_SIZE(conf->overrides->pctable) : 0; - snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name); - path[LINE_MAX-1] = '\0'; - process_file(conf, path); - factorize_hwtable(conf->hwtable, old_hwtable_size, - namelist[i]->d_name); -+ validate_pctable(conf->overrides, old_pctable_size, -+ namelist[i]->d_name); - } - pthread_cleanup_pop(1); - } -@@ -784,6 +865,7 @@ load_config (char * file) - goto out; - } - factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); -+ validate_pctable(conf->overrides, 0, file); - } else { - condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); - condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); -@@ -898,6 +980,7 @@ load_config (char * file) - goto out; - } - -+ merge_pctable(conf->overrides); - merge_mptable(conf->mptable); - merge_blacklist(conf->blist_devnode); - merge_blacklist(conf->blist_property); -diff --git a/libmultipath/config.h b/libmultipath/config.h -index e2e3f143..143116b3 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -41,6 +41,13 @@ enum force_reload_types { - FORCE_RELOAD_WEAK, - }; - -+struct pcentry { -+ int type; -+ int fast_io_fail; -+ unsigned int dev_loss; -+ int eh_deadline; -+}; -+ - struct hwentry { - char * vendor; - char * product; -@@ -86,6 +93,8 @@ struct hwentry { - int vpd_vendor_id; - int recheck_wwid; - char * bl_product; -+ -+ vector pctable; - }; - - struct mpentry { -@@ -240,6 +249,7 @@ char * get_mpe_wwid (vector mptable, char * alias); - - struct hwentry * alloc_hwe (void); - struct mpentry * alloc_mpe (void); -+struct pcentry * alloc_pce (void); - - void free_hwe (struct hwentry * hwe); - void free_hwtable (vector hwtable); -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 5a0255b0..8321ec1e 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -457,6 +457,29 @@ snprint_mp_ ## option (struct config *conf, char * buff, int len, \ - return function (buff, len, mpe->option); \ - } - -+#define declare_pc_handler(option, function) \ -+static int \ -+pc_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ struct pcentry *pce; \ -+ if (!conf->overrides || !conf->overrides->pctable) \ -+ return 1; \ -+ pce = VECTOR_LAST_SLOT(conf->overrides->pctable); \ -+ if (!pce) \ -+ return 1; \ -+ return function (strvec, &pce->option, file, line_nr); \ -+} -+ -+#define declare_pc_snprint(option, function) \ -+static int \ -+snprint_pc_ ## option (struct config *conf, char * buff, int len, \ -+ const void *data) \ -+{ \ -+ const struct pcentry *pce = (const struct pcentry *)data; \ -+ return function(buff, len, pce->option); \ -+} -+ - static int checkint_handler(struct config *conf, vector strvec, - const char *file, int line_nr) - { -@@ -1022,6 +1045,8 @@ declare_ovr_handler(fast_io_fail, set_undef_off_zero) - declare_ovr_snprint(fast_io_fail, print_undef_off_zero) - declare_hw_handler(fast_io_fail, set_undef_off_zero) - declare_hw_snprint(fast_io_fail, print_undef_off_zero) -+declare_pc_handler(fast_io_fail, set_undef_off_zero) -+declare_pc_snprint(fast_io_fail, print_undef_off_zero) - - static int - set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) -@@ -1059,6 +1084,8 @@ declare_ovr_handler(dev_loss, set_dev_loss) - declare_ovr_snprint(dev_loss, print_dev_loss) - declare_hw_handler(dev_loss, set_dev_loss) - declare_hw_snprint(dev_loss, print_dev_loss) -+declare_pc_handler(dev_loss, set_dev_loss) -+declare_pc_snprint(dev_loss, print_dev_loss) - - declare_def_handler(eh_deadline, set_undef_off_zero) - declare_def_snprint(eh_deadline, print_undef_off_zero) -@@ -1066,6 +1093,8 @@ declare_ovr_handler(eh_deadline, set_undef_off_zero) - declare_ovr_snprint(eh_deadline, print_undef_off_zero) - declare_hw_handler(eh_deadline, set_undef_off_zero) - declare_hw_snprint(eh_deadline, print_undef_off_zero) -+declare_pc_handler(eh_deadline, set_undef_off_zero) -+declare_pc_snprint(eh_deadline, print_undef_off_zero) - - static int - set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) -@@ -1876,6 +1905,69 @@ declare_mp_snprint(wwid, print_str) - declare_mp_handler(alias, set_str_noslash) - declare_mp_snprint(alias, print_str) - -+ -+static int -+protocol_handler(struct config *conf, vector strvec, const char *file, -+ int line_nr) -+{ -+ struct pcentry *pce; -+ -+ if (!conf->overrides) -+ return 1; -+ -+ if (!conf->overrides->pctable && -+ !(conf->overrides->pctable = vector_alloc())) -+ return 1; -+ -+ if (!(pce = alloc_pce())) -+ return 1; -+ -+ if (!vector_alloc_slot(conf->overrides->pctable)) { -+ free(pce); -+ return 1; -+ } -+ vector_set_slot(conf->overrides->pctable, pce); -+ -+ return 0; -+} -+ -+static int -+set_protocol_type(vector strvec, void *ptr, const char *file, int line_nr) -+{ -+ int *int_ptr = (int *)ptr; -+ char *buff; -+ int i; -+ -+ buff = set_value(strvec); -+ -+ if (!buff) -+ return 1; -+ -+ for (i = 0; i <= LAST_BUS_PROTOCOL_ID; i++) { -+ if (protocol_name[i] && !strcmp(buff, protocol_name[i])) { -+ *int_ptr = i; -+ break; -+ } -+ } -+ if (i > LAST_BUS_PROTOCOL_ID) -+ condlog(1, "%s line %d, invalid value for type: \"%s\"", -+ file, line_nr, buff); -+ -+ free(buff); -+ return 0; -+} -+ -+static int -+print_protocol_type(char *buff, int len, int type) -+{ -+ if (type < 0) -+ return 0; -+ return snprintf(buff, len, "\"%s\"", protocol_name[type]); -+} -+ -+declare_pc_handler(type, set_protocol_type) -+declare_pc_snprint(type, print_protocol_type) -+ - /* - * deprecated handlers - */ -@@ -2117,6 +2209,13 @@ init_keywords(vector keywords) - install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay); - install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt); - install_keyword("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid); -+ install_keyword_multi("protocol", &protocol_handler, NULL); -+ install_sublevel(); -+ install_keyword("type", &pc_type_handler, &snprint_pc_type); -+ install_keyword("fast_io_fail_tmo", &pc_fast_io_fail_handler, &snprint_pc_fast_io_fail); -+ install_keyword("dev_loss_tmo", &pc_dev_loss_handler, &snprint_pc_dev_loss); -+ install_keyword("eh_deadline", &pc_eh_deadline_handler, &snprint_pc_eh_deadline); -+ install_sublevel_end(); - - install_keyword_root("multipaths", &multipaths_handler); - install_keyword_multi("multipath", &multipath_handler, NULL); -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 1f6d27bd..8a6fbe83 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1392,6 +1392,39 @@ snprint_multipath_topology_json (char * buff, int len, const struct vectors * ve - return fwd; - } - -+static int -+snprint_pcentry (const struct config *conf, char *buff, int len, -+ const struct pcentry *pce) -+{ -+ int i; -+ int fwd = 0; -+ struct keyword *kw; -+ struct keyword *rootkw; -+ -+ rootkw = find_keyword(conf->keywords, NULL, "overrides"); -+ if (!rootkw || !rootkw->sub) -+ return 0; -+ -+ rootkw = find_keyword(conf->keywords, rootkw->sub, "protocol"); -+ if (!rootkw) -+ return 0; -+ -+ fwd += snprintf(buff + fwd, len - fwd, "\tprotocol {\n"); -+ if (fwd >= len) -+ return len; -+ -+ iterate_sub_keywords(rootkw, kw, i) { -+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n", -+ kw, pce); -+ if (fwd >= len) -+ return len; -+ } -+ fwd += snprintf(buff + fwd, len - fwd, "\t}\n"); -+ if (fwd >= len) -+ return len; -+ return fwd; -+} -+ - static int - snprint_hwentry (const struct config *conf, - char * buff, int len, const struct hwentry * hwe) -@@ -1575,6 +1608,17 @@ static int snprint_overrides(const struct config *conf, char * buff, int len, - if (fwd >= len) - return len; - } -+ -+ if (overrides->pctable) { -+ struct pcentry *pce; -+ -+ vector_foreach_slot(overrides->pctable, pce, i) { -+ fwd += snprint_pcentry(conf, buff + fwd, len - fwd, -+ pce); -+ if (fwd >= len) -+ return len; -+ } -+ } - out: - fwd += snprintf(buff + fwd, len - fwd, "}\n"); - if (fwd >= len) diff --git a/SOURCES/0100-libmultipath-Set-the-scsi-timeout-parameters-by-path.patch b/SOURCES/0100-libmultipath-Set-the-scsi-timeout-parameters-by-path.patch deleted file mode 100644 index 368e52e..0000000 --- a/SOURCES/0100-libmultipath-Set-the-scsi-timeout-parameters-by-path.patch +++ /dev/null @@ -1,472 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:38 -0500 -Subject: [PATCH] libmultipath: Set the scsi timeout parameters by path - -Instead of dev_loss, fast_io_fail, and eh_deadline belonging to the -multipath structure, have them belong to the path structure. This means -that they are selected per path, and that sysfs_set_scsi_tmo() doesn't -assume that all paths of a multipath device will have the same value. -Currently they will all be the same, but a future patch will make it -possible for paths to have different values based on their protocol. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 5 +- - libmultipath/discovery.c | 149 +++++++++++++++++++++++---------------- - libmultipath/discovery.h | 2 +- - libmultipath/propsel.c | 42 +++++------ - libmultipath/propsel.h | 6 +- - libmultipath/structs.c | 1 - - libmultipath/structs.h | 6 +- - 7 files changed, 118 insertions(+), 93 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 9a9890f5..6cad0468 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -338,9 +338,6 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_mode(conf, mpp); - select_uid(conf, mpp); - select_gid(conf, mpp); -- select_fast_io_fail(conf, mpp); -- select_dev_loss(conf, mpp); -- select_eh_deadline(conf, mpp); - select_reservation_key(conf, mpp); - select_deferred_remove(conf, mpp); - select_marginal_path_err_sample_time(conf, mpp); -@@ -356,7 +353,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - select_ghost_delay(conf, mpp); - select_flush_on_last_del(conf, mpp); - -- sysfs_set_scsi_tmo(mpp, conf->checkint); -+ sysfs_set_scsi_tmo(conf, mpp); - marginal_pathgroups = conf->marginal_pathgroups; - pthread_cleanup_pop(1); - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 2404cb87..36cc389e 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -581,13 +581,13 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen) - } - - static int --sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp) -+sysfs_set_eh_deadline(struct path *pp) - { - struct udev_device *hostdev; - char host_name[HOST_NAME_LEN], value[16]; - int ret; - -- if (mpp->eh_deadline == EH_DEADLINE_UNSET) -+ if (pp->eh_deadline == EH_DEADLINE_UNSET) - return 0; - - sprintf(host_name, "host%d", pp->sg_id.host_no); -@@ -596,12 +596,12 @@ sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp) - if (!hostdev) - return 1; - -- if (mpp->eh_deadline == EH_DEADLINE_OFF) -+ if (pp->eh_deadline == EH_DEADLINE_OFF) - sprintf(value, "off"); -- else if (mpp->eh_deadline == EH_DEADLINE_ZERO) -+ else if (pp->eh_deadline == EH_DEADLINE_ZERO) - sprintf(value, "0"); - else -- snprintf(value, 16, "%u", mpp->eh_deadline); -+ snprintf(value, 16, "%u", pp->eh_deadline); - - ret = sysfs_attr_set_value(hostdev, "eh_deadline", - value, strlen(value)); -@@ -625,6 +625,9 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - unsigned int tmo; - int ret; - -+ if (!pp->dev_loss && pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ return; -+ - sprintf(rport_id, "rport-%d:%d-%d", - pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); - rport_dev = udev_device_new_from_subsystem_sysname(udev, -@@ -664,14 +667,14 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - * then set fast_io_fail, and _then_ set dev_loss_tmo - * to the correct value. - */ -- if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET && -- mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO && -- mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { -+ if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET && -+ pp->fast_io_fail != MP_FAST_IO_FAIL_ZERO && -+ pp->fast_io_fail != MP_FAST_IO_FAIL_OFF) { - /* Check if we need to temporarily increase dev_loss_tmo */ -- if ((unsigned int)mpp->fast_io_fail >= tmo) { -+ if ((unsigned int)pp->fast_io_fail >= tmo) { - /* Increase dev_loss_tmo temporarily */ - snprintf(value, sizeof(value), "%u", -- (unsigned int)mpp->fast_io_fail + 1); -+ (unsigned int)pp->fast_io_fail + 1); - ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", - value, strlen(value)); - if (ret <= 0) { -@@ -685,20 +688,20 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - goto out; - } - } -- } else if (mpp->dev_loss > DEFAULT_DEV_LOSS_TMO && -- mpp->no_path_retry != NO_PATH_RETRY_QUEUE) { -+ } else if (pp->dev_loss > DEFAULT_DEV_LOSS_TMO && -+ mpp->no_path_retry != NO_PATH_RETRY_QUEUE) { - condlog(3, "%s: limiting dev_loss_tmo to %d, since " - "fast_io_fail is not set", - rport_id, DEFAULT_DEV_LOSS_TMO); -- mpp->dev_loss = DEFAULT_DEV_LOSS_TMO; -+ pp->dev_loss = DEFAULT_DEV_LOSS_TMO; - } -- if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -- if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) -+ if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -+ if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) - sprintf(value, "off"); -- else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) -+ else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) - sprintf(value, "0"); - else -- snprintf(value, 16, "%u", mpp->fast_io_fail); -+ snprintf(value, 16, "%u", pp->fast_io_fail); - ret = sysfs_attr_set_value(rport_dev, "fast_io_fail_tmo", - value, strlen(value)); - if (ret <= 0) { -@@ -709,8 +712,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp) - rport_id, value, -ret); - } - } -- if (mpp->dev_loss > 0) { -- snprintf(value, 16, "%u", mpp->dev_loss); -+ if (pp->dev_loss > 0) { -+ snprintf(value, 16, "%u", pp->dev_loss); - ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo", - value, strlen(value)); - if (ret <= 0) { -@@ -726,7 +729,7 @@ out: - } - - static void --sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) -+sysfs_set_session_tmo(struct path *pp) - { - struct udev_device *session_dev = NULL; - char session_id[64]; -@@ -743,18 +746,18 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) - condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no, - pp->sg_id.channel, pp->sg_id.scsi_id, session_id); - -- if (mpp->dev_loss) { -+ if (pp->dev_loss) { - condlog(3, "%s: ignoring dev_loss_tmo on iSCSI", pp->dev); - } -- if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -- if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF) { -+ if (pp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -+ if (pp->fast_io_fail == MP_FAST_IO_FAIL_OFF) { - condlog(3, "%s: can't switch off fast_io_fail_tmo " - "on iSCSI", pp->dev); -- } else if (mpp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) { -+ } else if (pp->fast_io_fail == MP_FAST_IO_FAIL_ZERO) { - condlog(3, "%s: can't set fast_io_fail_tmo to '0'" - "on iSCSI", pp->dev); - } else { -- snprintf(value, 11, "%u", mpp->fast_io_fail); -+ snprintf(value, 11, "%u", pp->fast_io_fail); - if (sysfs_attr_set_value(session_dev, "recovery_tmo", - value, strlen(value)) <= 0) { - condlog(3, "%s: Failed to set recovery_tmo, " -@@ -767,12 +770,15 @@ sysfs_set_session_tmo(struct multipath *mpp, struct path *pp) - } - - static void --sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) -+sysfs_set_nexus_loss_tmo(struct path *pp) - { - struct udev_device *sas_dev = NULL; - char end_dev_id[64]; - char value[11]; - -+ if (!pp->udev || !pp->dev_loss) -+ return; -+ - sprintf(end_dev_id, "end_device-%d:%d", - pp->sg_id.host_no, pp->sg_id.transport_id); - sas_dev = udev_device_new_from_subsystem_sysname(udev, -@@ -785,8 +791,8 @@ sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) - condlog(4, "target%d:%d:%d -> %s", pp->sg_id.host_no, - pp->sg_id.channel, pp->sg_id.scsi_id, end_dev_id); - -- if (mpp->dev_loss) { -- snprintf(value, 11, "%u", mpp->dev_loss); -+ if (pp->dev_loss) { -+ snprintf(value, 11, "%u", pp->dev_loss); - if (sysfs_attr_set_value(sas_dev, "I_T_nexus_loss_timeout", - value, strlen(value)) <= 0) - condlog(3, "%s: failed to update " -@@ -798,53 +804,76 @@ sysfs_set_nexus_loss_tmo(struct multipath *mpp, struct path *pp) - } - - int --sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint) -+sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp) - { - struct path *pp; - int i; -- unsigned int dev_loss_tmo = mpp->dev_loss; -+ unsigned int min_dev_loss = 0; -+ bool warn_dev_loss = false; -+ bool warn_fast_io_fail = false; - - if (mpp->no_path_retry > 0) { - uint64_t no_path_retry_tmo = -- (uint64_t)mpp->no_path_retry * checkint; -+ (uint64_t)mpp->no_path_retry * conf->checkint; - - if (no_path_retry_tmo > MAX_DEV_LOSS_TMO) -- no_path_retry_tmo = MAX_DEV_LOSS_TMO; -- if (no_path_retry_tmo > dev_loss_tmo) -- dev_loss_tmo = no_path_retry_tmo; -- condlog(3, "%s: update dev_loss_tmo to %u", -- mpp->alias, dev_loss_tmo); -- } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) { -- dev_loss_tmo = MAX_DEV_LOSS_TMO; -- condlog(3, "%s: update dev_loss_tmo to %u", -- mpp->alias, dev_loss_tmo); -- } -- mpp->dev_loss = dev_loss_tmo; -- if (mpp->dev_loss && mpp->fast_io_fail > 0 && -- (unsigned int)mpp->fast_io_fail >= mpp->dev_loss) { -- condlog(3, "%s: turning off fast_io_fail (%d is not smaller than dev_loss_tmo)", -- mpp->alias, mpp->fast_io_fail); -- mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF; -- } -- if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET && -- mpp->eh_deadline == EH_DEADLINE_UNSET) -- return 0; -+ min_dev_loss = MAX_DEV_LOSS_TMO; -+ else -+ min_dev_loss = no_path_retry_tmo; -+ } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) -+ min_dev_loss = MAX_DEV_LOSS_TMO; - - vector_foreach_slot(mpp->paths, pp, i) { -+ select_fast_io_fail(conf, pp); -+ select_dev_loss(conf, pp); -+ select_eh_deadline(conf, pp); -+ -+ if (!pp->dev_loss && pp->eh_deadline == EH_DEADLINE_UNSET && -+ pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ continue; -+ - if (pp->bus != SYSFS_BUS_SCSI) - continue; -+ sysfs_set_eh_deadline(pp); -+ -+ if (!pp->dev_loss && pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET) -+ continue; -+ -+ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP && -+ pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI && -+ pp->sg_id.proto_id != SCSI_PROTOCOL_SAS) -+ continue; -+ -+ if (pp->dev_loss > 0 && pp->dev_loss < min_dev_loss) { -+ warn_dev_loss = true; -+ pp->dev_loss = min_dev_loss; -+ } -+ if (pp->dev_loss > 0 && pp->fast_io_fail > 0 && -+ (unsigned int)pp->fast_io_fail >= pp->dev_loss) { -+ warn_fast_io_fail = true; -+ pp->fast_io_fail = MP_FAST_IO_FAIL_OFF; -+ } - -- if (mpp->dev_loss || -- mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) { -- if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) -- sysfs_set_rport_tmo(mpp, pp); -- else if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI) -- sysfs_set_session_tmo(mpp, pp); -- else if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS) -- sysfs_set_nexus_loss_tmo(mpp, pp); -+ switch (pp->sg_id.proto_id) { -+ case SCSI_PROTOCOL_FCP: -+ sysfs_set_rport_tmo(mpp, pp); -+ break; -+ case SCSI_PROTOCOL_ISCSI: -+ sysfs_set_session_tmo(pp); -+ break; -+ case SCSI_PROTOCOL_SAS: -+ sysfs_set_nexus_loss_tmo(pp); -+ break; -+ default: -+ break; - } -- sysfs_set_eh_deadline(mpp, pp); - } -+ if (warn_dev_loss) -+ condlog(2, "%s: Raising dev_loss_tmo to %u because of no_path_retry setting", -+ mpp->alias, min_dev_loss); -+ if (warn_fast_io_fail) -+ condlog(3, "%s: turning off fast_io_fail (not smaller than dev_loss_tmo)", -+ mpp->alias); - return 0; - } - -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index a5446b4d..b6eea258 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -42,7 +42,7 @@ int alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice, - int store_pathinfo (vector pathvec, struct config *conf, - struct udev_device *udevice, int flag, - struct path **pp_ptr); --int sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint); -+int sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp); - int sysfs_get_timeout(const struct path *pp, unsigned int *timeout); - int sysfs_get_host_pci_name(const struct path *pp, char *pci_name); - int sysfs_get_iscsi_ip_address(const struct path *pp, char *ip_address); -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 127b3370..25326eb6 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -766,51 +766,51 @@ int select_minio(struct config *conf, struct multipath *mp) - return select_minio_bio(conf, mp); - } - --int select_fast_io_fail(struct config *conf, struct multipath *mp) -+int select_fast_io_fail(struct config *conf, struct path *pp) - { - const char *origin; - char buff[12]; - -- mp_set_ovr(fast_io_fail); -- mp_set_hwe(fast_io_fail); -- mp_set_conf(fast_io_fail); -- mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); -+ pp_set_ovr(fast_io_fail); -+ pp_set_hwe(fast_io_fail); -+ pp_set_conf(fast_io_fail); -+ pp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); - out: -- print_undef_off_zero(buff, 12, mp->fast_io_fail); -- condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin); -+ print_undef_off_zero(buff, 12, pp->fast_io_fail); -+ condlog(3, "%s: fast_io_fail_tmo = %s %s", pp->dev, buff, origin); - return 0; - } - --int select_dev_loss(struct config *conf, struct multipath *mp) -+int select_dev_loss(struct config *conf, struct path *pp) - { - const char *origin; - char buff[12]; - -- mp_set_ovr(dev_loss); -- mp_set_hwe(dev_loss); -- mp_set_conf(dev_loss); -- mp->dev_loss = 0; -+ pp_set_ovr(dev_loss); -+ pp_set_hwe(dev_loss); -+ pp_set_conf(dev_loss); -+ pp->dev_loss = 0; - return 0; - out: -- print_dev_loss(buff, 12, mp->dev_loss); -- condlog(3, "%s: dev_loss_tmo = %s %s", mp->alias, buff, origin); -+ print_dev_loss(buff, 12, pp->dev_loss); -+ condlog(3, "%s: dev_loss_tmo = %s %s", pp->dev, buff, origin); - return 0; - } - --int select_eh_deadline(struct config *conf, struct multipath *mp) -+int select_eh_deadline(struct config *conf, struct path *pp) - { - const char *origin; - char buff[12]; - -- mp_set_ovr(eh_deadline); -- mp_set_hwe(eh_deadline); -- mp_set_conf(eh_deadline); -- mp->eh_deadline = EH_DEADLINE_UNSET; -+ pp_set_ovr(eh_deadline); -+ pp_set_hwe(eh_deadline); -+ pp_set_conf(eh_deadline); -+ pp->eh_deadline = EH_DEADLINE_UNSET; - /* not changing sysfs in default cause, so don't print anything */ - return 0; - out: -- print_undef_off_zero(buff, 12, mp->eh_deadline); -- condlog(3, "%s: eh_deadline = %s %s", mp->alias, buff, origin); -+ print_undef_off_zero(buff, 12, pp->eh_deadline); -+ condlog(3, "%s: eh_deadline = %s %s", pp->dev, buff, origin); - return 0; - } - -diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h -index 72a7e33c..152ca44c 100644 ---- a/libmultipath/propsel.h -+++ b/libmultipath/propsel.h -@@ -16,9 +16,9 @@ int select_minio(struct config *conf, struct multipath *mp); - int select_mode(struct config *conf, struct multipath *mp); - int select_uid(struct config *conf, struct multipath *mp); - int select_gid(struct config *conf, struct multipath *mp); --int select_fast_io_fail(struct config *conf, struct multipath *mp); --int select_dev_loss(struct config *conf, struct multipath *mp); --int select_eh_deadline(struct config *conf, struct multipath *mp); -+int select_fast_io_fail(struct config *conf, struct path *pp); -+int select_dev_loss(struct config *conf, struct path *pp); -+int select_eh_deadline(struct config *conf, struct path *pp); - int select_reservation_key(struct config *conf, struct multipath *mp); - int select_retain_hwhandler (struct config *conf, struct multipath * mp); - int select_detect_prio(struct config *conf, struct path * pp); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 19099bed..9f86eb69 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -230,7 +230,6 @@ alloc_multipath (void) - mpp->bestpg = 1; - mpp->mpcontext = NULL; - mpp->no_path_retry = NO_PATH_RETRY_UNDEF; -- mpp->fast_io_fail = MP_FAST_IO_FAIL_UNSET; - dm_multipath_to_gen(mpp)->ops = &dm_gen_multipath_ops; - } - return mpp; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index ab99852f..875e726e 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -344,6 +344,9 @@ struct path { - int marginal; - int vpd_vendor_id; - int recheck_wwid; -+ int fast_io_fail; -+ unsigned int dev_loss; -+ int eh_deadline; - /* configlet pointers */ - vector hwe; - struct gen_path generic_path; -@@ -371,7 +374,6 @@ struct multipath { - int minio; - int flush_on_last_del; - int attribute_flags; -- int fast_io_fail; - int retain_hwhandler; - int deferred_remove; - bool in_recovery; -@@ -389,8 +391,6 @@ struct multipath { - int needs_paths_uevent; - int ghost_delay; - int ghost_delay_tick; -- unsigned int dev_loss; -- int eh_deadline; - uid_t uid; - gid_t gid; - mode_t mode; diff --git a/SOURCES/0101-libmultipath-check-the-overrides-pctable-for-path-va.patch b/SOURCES/0101-libmultipath-check-the-overrides-pctable-for-path-va.patch deleted file mode 100644 index 369ab5a..0000000 --- a/SOURCES/0101-libmultipath-check-the-overrides-pctable-for-path-va.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:39 -0500 -Subject: [PATCH] libmultipath: check the overrides pctable for path variables - -Paths will now also check the pctable when checking for attribtes that -exists in both the overrides section and the protocol subsection. Values -in a matching pcentry will be used in preference to values in the -overrides hwentry. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/propsel.c | 29 ++++++++++++++++++++++++++--- - 1 file changed, 26 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 25326eb6..209c1d67 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -79,6 +79,8 @@ static const char conf_origin[] = - "(setting: multipath.conf defaults/devices section)"; - static const char overrides_origin[] = - "(setting: multipath.conf overrides section)"; -+static const char overrides_pce_origin[] = -+ "(setting: multipath.conf overrides protocol section)"; - static const char cmdline_origin[] = - "(setting: multipath command line [-p] flag)"; - static const char autodetect_origin[] = -@@ -144,6 +146,27 @@ do { \ - } \ - } while (0) - -+#define pp_set_ovr_pce(var) \ -+do { \ -+ struct pcentry *_pce; \ -+ int _i; \ -+ \ -+ if (conf->overrides) { \ -+ vector_foreach_slot(conf->overrides->pctable, _pce, _i) { \ -+ if (_pce->type == (int)bus_protocol_id(pp) && _pce->var) { \ -+ pp->var = _pce->var; \ -+ origin = overrides_pce_origin; \ -+ goto out; \ -+ } \ -+ } \ -+ if (conf->overrides->var) { \ -+ pp->var = conf->overrides->var; \ -+ origin = overrides_origin; \ -+ goto out; \ -+ } \ -+ } \ -+} while (0) -+ - int select_mode(struct config *conf, struct multipath *mp) - { - const char *origin; -@@ -771,7 +794,7 @@ int select_fast_io_fail(struct config *conf, struct path *pp) - const char *origin; - char buff[12]; - -- pp_set_ovr(fast_io_fail); -+ pp_set_ovr_pce(fast_io_fail); - pp_set_hwe(fast_io_fail); - pp_set_conf(fast_io_fail); - pp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL); -@@ -786,7 +809,7 @@ int select_dev_loss(struct config *conf, struct path *pp) - const char *origin; - char buff[12]; - -- pp_set_ovr(dev_loss); -+ pp_set_ovr_pce(dev_loss); - pp_set_hwe(dev_loss); - pp_set_conf(dev_loss); - pp->dev_loss = 0; -@@ -802,7 +825,7 @@ int select_eh_deadline(struct config *conf, struct path *pp) - const char *origin; - char buff[12]; - -- pp_set_ovr(eh_deadline); -+ pp_set_ovr_pce(eh_deadline); - pp_set_hwe(eh_deadline); - pp_set_conf(eh_deadline); - pp->eh_deadline = EH_DEADLINE_UNSET; diff --git a/SOURCES/0102-libmultipath-fix-eh_deadline-documentation.patch b/SOURCES/0102-libmultipath-fix-eh_deadline-documentation.patch deleted file mode 100644 index 167590b..0000000 --- a/SOURCES/0102-libmultipath-fix-eh_deadline-documentation.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:40 -0500 -Subject: [PATCH] libmultipath: fix eh_deadline documentation - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/multipath.conf.5 | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 0c04c7e4..b14fd215 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1602,6 +1602,8 @@ section: - .TP - .B dev_loss_tmo - .TP -+.B eh_deadline -+.TP - .B flush_on_last_del - .TP - .B user_friendly_names -@@ -1688,6 +1690,8 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections: - .TP - .B dev_loss_tmo - .TP -+.B eh_deadline -+.TP - .B user_friendly_names - .TP - .B retain_attached_hw_handler diff --git a/SOURCES/0103-libmultipath-Add-documentation-for-the-protocol-subs.patch b/SOURCES/0103-libmultipath-Add-documentation-for-the-protocol-subs.patch deleted file mode 100644 index 114f02e..0000000 --- a/SOURCES/0103-libmultipath-Add-documentation-for-the-protocol-subs.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 Apr 2022 23:27:41 -0500 -Subject: [PATCH] libmultipath: Add documentation for the protocol subsection - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/multipath.conf.5 | 32 ++++++++++++++++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index b14fd215..abbc89af 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1730,6 +1730,38 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections: - .RE - .PD - .LP -+The overrides section also recognizes the optional \fIprotocol\fR subsection, -+and can contain multiple protocol subsections. Path devices are matched against -+the protocol subsection using the mandatory \fItype\fR attribute. Attributes -+in a matching protocol subsection take precedence over attributes in the rest -+of the overrides section. If there are multiple matching protocol subsections, -+later entries take precedence. -+.TP -+.B protocol subsection -+The protocol subsection recognizes the following mandatory attribute: -+.RS -+.TP -+.B type -+The protocol string of the path device. The possible values are \fIscsi:fcp\fR, -+\fIscsi:spi\fR, \fIscsi:ssa\fR, \fIscsi:sbp\fR, \fIscsi:srp\fR, -+\fIscsi:iscsi\fR, \fIscsi:sas\fR, \fIscsi:adt\fR, \fIscsi:ata\fR, -+\fIscsi:unspec\fR, \fIccw\fR, \fIcciss\fR, \fInvme\fR, and \fIundef\fR. This is -+\fBnot\fR a regular expression. the path device protcol string must match -+exactly. The protocol that a path is using can be viewed by running -+\fBmultipathd show paths format "%d %P"\fR -+.LP -+The following attributes are optional; if not set, the default values are taken -+from the \fIoverrides\fR, \fIdevices\fR, or \fIdefaults\fR section: -+.sp 1 -+.PD .1v -+.RS -+.TP -+.B fast_io_fail_tmo -+.TP -+.B dev_loss_tmo -+.TP -+.B eh_deadline -+.PD - . - . - .\" ---------------------------------------------------------------------------- diff --git a/SOURCES/0104-libmultipath-use-symbolic-value-for-invalid-pcentry.patch b/SOURCES/0104-libmultipath-use-symbolic-value-for-invalid-pcentry.patch deleted file mode 100644 index da6eb9d..0000000 --- a/SOURCES/0104-libmultipath-use-symbolic-value-for-invalid-pcentry.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 14 Apr 2022 16:11:10 -0500 -Subject: [PATCH] libmultipath: use symbolic value for invalid pcentry - -Suggested-by: Martin Wilck -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/config.c | 4 ++-- - libmultipath/config.h | 1 + - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 88975323..bcd8b541 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -319,7 +319,7 @@ alloc_pce (void) - { - struct pcentry *pce = (struct pcentry *) - calloc(1, sizeof(struct pcentry)); -- pce->type = -1; -+ pce->type = PCE_INVALID; - return pce; - } - -@@ -578,7 +578,7 @@ validate_pctable(struct hwentry *ovr, int idx, const char *table_desc) - return; - - vector_foreach_slot_after(ovr->pctable, pce, idx) { -- if (pce->type < 0) { -+ if (pce->type == PCE_INVALID) { - condlog(0, "protocol section in %s missing type", - table_desc); - vector_del_slot(ovr->pctable, idx--); -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 143116b3..477f8bfa 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -41,6 +41,7 @@ enum force_reload_types { - FORCE_RELOAD_WEAK, - }; - -+#define PCE_INVALID -1 - struct pcentry { - int type; - int fast_io_fail; diff --git a/SOURCES/0105-multipathd-handle-fpin-events.patch b/SOURCES/0105-multipathd-handle-fpin-events.patch deleted file mode 100644 index e8fa26a..0000000 --- a/SOURCES/0105-multipathd-handle-fpin-events.patch +++ /dev/null @@ -1,1037 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muneendra Kumar -Date: Wed, 9 Feb 2022 19:28:10 -0800 -Subject: [PATCH] multipathd: handle fpin events - -This patch incorporates the functionality to handle -FPIN ELS events present as part of FCTransport daemon -(available in EPEL8) into the multipathd. This helps us to -reduce the response time to react and take the necessary actions -on receiving the FPIN events. - -This patch currently support FPIN-Li Events. - -It adds a new thread to listen for ELS frames from driver and on -receiving the frame payload, push the payload to a list and notify the -fpin_els_li_consumer thread to process it.Once consumer thread is -notified, it returns to listen for more ELS frames from driver. - -The consumer thread process the ELS frames and moves the devices paths -which are affected due to link integrity to marginal path groups. -This also sets the associated portstate to marginal. -The paths which are set to marginal path group will be unset -on receiving the RSCN events - -[ MW: minor fixup for 32bit compilation ] - -Signed-off-by: Muneendra Kumar -Signed-off-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Reviewed-by: Martin Wilck ---- - Makefile.inc | 13 + - libmultipath/Makefile | 5 + - libmultipath/dict.c | 56 +++- - libmultipath/propsel.c | 47 +++- - libmultipath/structs.h | 7 + - multipath/multipath.conf.5 | 19 +- - multipathd/Makefile | 10 + - multipathd/fpin.h | 20 ++ - multipathd/fpin_handlers.c | 541 +++++++++++++++++++++++++++++++++++++ - multipathd/main.c | 35 ++- - 10 files changed, 738 insertions(+), 15 deletions(-) - create mode 100644 multipathd/fpin.h - create mode 100644 multipathd/fpin_handlers.c - -diff --git a/Makefile.inc b/Makefile.inc -index 220009e0..25c16f4e 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -146,6 +146,19 @@ check_file = $(shell \ - echo "$$found" \ - ) - -+# Check whether a file contains a variable with name $1 in header file $2 -+check_var = $(shell \ -+ if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ -+ found=1; \ -+ status="yes"; \ -+ else \ -+ found=0; \ -+ status="no"; \ -+ fi; \ -+ echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ -+ echo "$$found" \ -+ ) -+ - %.o: %.c - @echo building $@ because of $? - $(CC) $(CFLAGS) -c -o $@ $< -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index ad690a49..49f71dfa 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -40,6 +40,11 @@ ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) - CFLAGS += -DLIBDM_API_HOLD_CONTROL - endif - -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,/usr/include/scsi/fc/fc_els.h),0) -+ CFLAGS += -DFPIN_EVENT_HANDLER -+endif -+ -+ - OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - hwtable.o blacklist.o util.o dmparser.o config.o \ - structs.o discovery.o propsel.o dict.o \ -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 8321ec1e..d7cd94a5 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -579,6 +579,59 @@ snprint_def_find_multipaths(struct config *conf, char *buff, int len, - find_multipaths_optvals[conf->find_multipaths]); - } - -+static const char * const marginal_pathgroups_optvals[] = { -+ [MARGINAL_PATHGROUP_OFF] = "off", -+ [MARGINAL_PATHGROUP_ON] = "on", -+#ifdef FPIN_EVENT_HANDLER -+ [MARGINAL_PATHGROUP_FPIN] = "fpin", -+#endif -+}; -+ -+static int -+def_marginal_pathgroups_handler(struct config *conf, vector strvec, -+ const char *file, int line_nr) -+{ -+ char *buff; -+ unsigned int i; -+ -+ buff = set_value(strvec); -+ if (!buff) -+ return 1; -+ for (i = MARGINAL_PATHGROUP_OFF; -+ i < ARRAY_SIZE(marginal_pathgroups_optvals); i++) { -+ if (marginal_pathgroups_optvals[i] != NULL && -+ !strcmp(buff, marginal_pathgroups_optvals[i])) { -+ conf->marginal_pathgroups = i; -+ break; -+ } -+ } -+ -+ if (i >= ARRAY_SIZE(marginal_pathgroups_optvals)) { -+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) -+ conf->marginal_pathgroups = MARGINAL_PATHGROUP_OFF; -+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) -+ conf->marginal_pathgroups = MARGINAL_PATHGROUP_ON; -+ /* This can only be true if FPIN_EVENT_HANDLER isn't defined, -+ * otherwise this check will have already happened above */ -+ else if (strcmp(buff, "fpin") == 0) -+ condlog(1, "%s line %d, support for \"fpin\" is not compiled in for marginal_pathgroups", file, line_nr); -+ else -+ condlog(1, "%s line %d, invalid value for marginal_pathgroups: \"%s\"", -+ file, line_nr, buff); -+ } -+ free(buff); -+ return 0; -+} -+ -+static int -+snprint_def_marginal_pathgroups(struct config *conf, char *buff, int len, -+ const void *data) -+{ -+ return snprintf(buff, len, "\"%s\"", -+ marginal_pathgroups_optvals[conf->marginal_pathgroups]); -+} -+ -+ - declare_def_handler(selector, set_str) - declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR) - declare_hw_handler(selector, set_str) -@@ -1596,9 +1649,6 @@ declare_ovr_snprint(all_tg_pt, print_yes_no_undef) - declare_hw_handler(all_tg_pt, set_yes_no_undef) - declare_hw_snprint(all_tg_pt, print_yes_no_undef) - --declare_def_handler(marginal_pathgroups, set_yes_no) --declare_def_snprint(marginal_pathgroups, print_yes_no) -- - declare_def_handler(recheck_wwid, set_yes_no_undef) - declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID) - declare_ovr_handler(recheck_wwid, set_yes_no_undef) -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 209c1d67..be79902f 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -85,6 +85,8 @@ static const char cmdline_origin[] = - "(setting: multipath command line [-p] flag)"; - static const char autodetect_origin[] = - "(setting: storage device autodetected)"; -+static const char fpin_marginal_path_origin[] = -+ "(setting: overridden by marginal_path_fpin)"; - static const char marginal_path_origin[] = - "(setting: implied by marginal_path check)"; - static const char delay_watch_origin[] = -@@ -1052,9 +1054,12 @@ int select_san_path_err_threshold(struct config *conf, struct multipath *mp) - const char *origin; - char buff[12]; - -- if (marginal_path_check_enabled(mp)) { -+ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { - mp->san_path_err_threshold = NU_NO; -- origin = marginal_path_origin; -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -+ origin = fpin_marginal_path_origin; -+ else -+ origin = marginal_path_origin; - goto out; - } - mp_set_mpe(san_path_err_threshold); -@@ -1075,9 +1080,12 @@ int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp) - const char *origin; - char buff[12]; - -- if (marginal_path_check_enabled(mp)) { -+ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { - mp->san_path_err_forget_rate = NU_NO; -- origin = marginal_path_origin; -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -+ origin = fpin_marginal_path_origin; -+ else -+ origin = marginal_path_origin; - goto out; - } - mp_set_mpe(san_path_err_forget_rate); -@@ -1099,9 +1107,12 @@ int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp) - const char *origin; - char buff[12]; - -- if (marginal_path_check_enabled(mp)) { -+ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { - mp->san_path_err_recovery_time = NU_NO; -- origin = marginal_path_origin; -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -+ origin = fpin_marginal_path_origin; -+ else -+ origin = marginal_path_origin; - goto out; - } - mp_set_mpe(san_path_err_recovery_time); -@@ -1123,6 +1134,12 @@ int select_marginal_path_err_sample_time(struct config *conf, struct multipath * - const char *origin; - char buff[12]; - -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { -+ mp->marginal_path_err_sample_time = NU_NO; -+ origin = fpin_marginal_path_origin; -+ goto out; -+ } -+ - mp_set_mpe(marginal_path_err_sample_time); - mp_set_ovr(marginal_path_err_sample_time); - mp_set_hwe(marginal_path_err_sample_time); -@@ -1141,6 +1158,12 @@ int select_marginal_path_err_rate_threshold(struct config *conf, struct multipat - const char *origin; - char buff[12]; - -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { -+ mp->marginal_path_err_rate_threshold = NU_NO; -+ origin = fpin_marginal_path_origin; -+ goto out; -+ } -+ - mp_set_mpe(marginal_path_err_rate_threshold); - mp_set_ovr(marginal_path_err_rate_threshold); - mp_set_hwe(marginal_path_err_rate_threshold); -@@ -1159,6 +1182,12 @@ int select_marginal_path_err_recheck_gap_time(struct config *conf, struct multip - const char *origin; - char buff[12]; - -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { -+ mp->marginal_path_err_recheck_gap_time = NU_NO; -+ origin = fpin_marginal_path_origin; -+ goto out; -+ } -+ - mp_set_mpe(marginal_path_err_recheck_gap_time); - mp_set_ovr(marginal_path_err_recheck_gap_time); - mp_set_hwe(marginal_path_err_recheck_gap_time); -@@ -1177,6 +1206,12 @@ int select_marginal_path_double_failed_time(struct config *conf, struct multipat - const char *origin; - char buff[12]; - -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { -+ mp->marginal_path_double_failed_time = NU_NO; -+ origin = fpin_marginal_path_origin; -+ goto out; -+ } -+ - mp_set_mpe(marginal_path_double_failed_time); - mp_set_ovr(marginal_path_double_failed_time); - mp_set_hwe(marginal_path_double_failed_time); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 875e726e..3ed5cfc1 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -128,6 +128,12 @@ enum find_multipaths_states { - __FIND_MULTIPATHS_LAST, - }; - -+enum marginal_pathgroups_mode { -+ MARGINAL_PATHGROUP_OFF = YN_NO, -+ MARGINAL_PATHGROUP_ON = YN_YES, -+ MARGINAL_PATHGROUP_FPIN, -+}; -+ - enum flush_states { - FLUSH_UNDEF = YNU_UNDEF, - FLUSH_DISABLED = YNU_NO, -@@ -429,6 +435,7 @@ struct multipath { - unsigned char prflag; - int all_tg_pt; - struct gen_multipath generic_mp; -+ bool fpin_must_reload; - }; - - static inline int marginal_path_check_enabled(const struct multipath *mpp) -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index abbc89af..805b7a5e 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1063,20 +1063,26 @@ The default is: \fBno\fR - . - .TP - .B marginal_pathgroups --If set to \fIno\fR, the \fIdelay_*_checks\fR, \fImarginal_path_*\fR, and -+If set to \fIoff\fR, the \fIdelay_*_checks\fR, \fImarginal_path_*\fR, and - \fIsan_path_err_*\fR options will keep marginal, or \(dqshaky\(dq, paths from - being reinstated until they have been monitored for some time. This can cause - situations where all non-marginal paths are down, and no paths are usable - until multipathd detects this and reinstates a marginal path. If the multipath - device is not configured to queue IO in this case, it can cause IO errors to - occur, even though there are marginal paths available. However, if this --option is set to \fIyes\fR, when one of the marginal path detecting methods -+option is set to \fIon\fR, when one of the marginal path detecting methods - determines that a path is marginal, it will be reinstated and placed in a - seperate pathgroup that will only be used after all the non-marginal pathgroups - have been tried first. This prevents the possibility of IO errors occuring - while marginal paths are still usable. After the path has been monitored - for the configured time, and is declared healthy, it will be returned to its --normal pathgroup. See "Shaky paths detection" below for more information. -+normal pathgroup. -+However if this option is set to \fIfpin\fR multipathd will receive fpin -+notifications, set path states to "marginal" accordingly, and regroup paths -+as described for "marginal_pathgroups yes". This option can't be used in combination -+with other options for "Shaky path detection" (see below).If it is set to fpin, -+marginal_path_xyz and san_path_err_xyz parameters are implicitly set to 0. -+See "Shaky paths detection" below for more information. - .RS - .TP - The default is: \fBno\fR -@@ -1852,6 +1858,13 @@ increase and the threshold is never reached. Ticks are the time between - path checks by multipathd, which is variable and controlled by the - \fIpolling_interval\fR and \fImax_polling_interval\fR parameters. - . -+.TP -+.B \(dqFPIN \(dq failure tracking -+Fibre channel fabrics can notify hosts about fabric-level issues such -+as integrity failures or congestion with so-called Fabric Performance -+Impact Notifications (FPINs).On receiving the fpin notifications through ELS -+multipathd will move the affected path and port states to marginal. -+. - .RS 8 - .LP - This method is \fBdeprecated\fR in favor of the \(dqmarginal_path\(dq failure -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 8d901178..835edd93 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -1,5 +1,9 @@ - include ../Makefile.inc - -+ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,/usr/include/scsi/fc/fc_els.h),0) -+ CFLAGS += -DFPIN_EVENT_HANDLER -+ FPIN_SUPPORT = 1 -+endif - # - # debugging stuff - # -@@ -28,6 +32,12 @@ endif - OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ - dmevents.o - -+ifeq ($(FPIN_SUPPORT),1) -+OBJS += fpin_handlers.o -+endif -+ -+ -+ - EXEC = multipathd - - all : $(EXEC) -diff --git a/multipathd/fpin.h b/multipathd/fpin.h -new file mode 100644 -index 00000000..bfcc1ce2 ---- /dev/null -+++ b/multipathd/fpin.h -@@ -0,0 +1,20 @@ -+#ifndef __FPIN_H__ -+#define __FPIN_H__ -+ -+#ifdef FPIN_EVENT_HANDLER -+void *fpin_fabric_notification_receiver(void *unused); -+void *fpin_els_li_consumer(void *data); -+void fpin_clean_marginal_dev_list(__attribute__((unused)) void *arg); -+#else -+static void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) -+{ -+ return NULL; -+} -+static void *fpin_els_li_consumer(__attribute__((unused))void *data) -+{ -+ return NULL; -+} -+/* fpin_clean_marginal_dev_list() is never called */ -+#endif -+ -+#endif -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -new file mode 100644 -index 00000000..b14366d7 ---- /dev/null -+++ b/multipathd/fpin_handlers.c -@@ -0,0 +1,541 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "parser.h" -+#include "vector.h" -+#include "structs.h" -+#include "structs_vec.h" -+#include "main.h" -+#include "debug.h" -+#include "util.h" -+#include "sysfs.h" -+ -+#include "fpin.h" -+#include "devmapper.h" -+ -+static pthread_cond_t fpin_li_cond = PTHREAD_COND_INITIALIZER; -+static pthread_mutex_t fpin_li_mutex = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t fpin_li_marginal_dev_mutex = PTHREAD_MUTEX_INITIALIZER; -+ -+static LIST_HEAD(els_marginal_list_head); -+static LIST_HEAD(fpin_li_marginal_dev_list_head); -+ -+ -+#define DEF_RX_BUF_SIZE 4096 -+#define DEV_NAME_LEN 128 -+#define FCH_EVT_LINKUP 0x2 -+#define FCH_EVT_LINK_FPIN 0x501 -+#define FCH_EVT_RSCN 0x5 -+ -+#define list_first_entry(ptr, type, member) \ -+ list_entry((ptr)->next, type, member) -+ -+/* max ELS frame Size */ -+#define FC_PAYLOAD_MAXLEN 2048 -+ -+struct els_marginal_list { -+ uint32_t event_code; -+ uint16_t host_num; -+ uint16_t length; -+ char payload[FC_PAYLOAD_MAXLEN]; -+ struct list_head node; -+}; -+/* Structure to store the marginal devices info */ -+struct marginal_dev_list { -+ char dev_t[BLK_DEV_SIZE]; -+ uint32_t host_num; -+ struct list_head node; -+}; -+ -+static void _udev_device_unref(void *p) -+{ -+ udev_device_unref(p); -+} -+ -+ -+/*set/unset the path state to marginal*/ -+static int fpin_set_pathstate(struct path *pp, bool set) -+{ -+ const char *action = set ? "set" : "unset"; -+ -+ if (!pp || !pp->mpp || !pp->mpp->alias) -+ return -1; -+ -+ condlog(3, "\n%s: %s marginal path %s (fpin)", -+ action, pp->mpp->alias, pp->dev_t); -+ pp->marginal = set; -+ pp->mpp->fpin_must_reload = true; -+ return 0; -+} -+ -+/* This will unset marginal state of a device*/ -+static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) -+{ -+ struct path *pp; -+ -+ pp = find_path_by_dev(vecs->pathvec, devname); -+ if (!pp) -+ pp = find_path_by_devt(vecs->pathvec, devname); -+ -+ fpin_set_pathstate(pp, false); -+} -+ -+/*This will set the marginal state of a device*/ -+static int fpin_path_setmarginal(struct path *pp) -+{ -+ return fpin_set_pathstate(pp, true); -+} -+ -+/* Unsets all the devices in the list from marginal state */ -+static void -+fpin_unset_marginal_dev(uint32_t host_num, struct vectors *vecs) -+{ -+ struct marginal_dev_list *tmp_marg = NULL; -+ struct marginal_dev_list *marg = NULL; -+ struct multipath *mpp; -+ int ret = 0; -+ int i; -+ -+ pthread_cleanup_push(cleanup_lock, &vecs->lock); -+ lock(&vecs->lock); -+ pthread_testcancel(); -+ -+ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); -+ pthread_cleanup_push(cleanup_mutex, &fpin_li_marginal_dev_mutex); -+ pthread_testcancel(); -+ if (list_empty(&fpin_li_marginal_dev_list_head)) { -+ condlog(4, "Marginal List is empty\n"); -+ goto empty; -+ } -+ list_for_each_entry_safe(marg, tmp_marg, &fpin_li_marginal_dev_list_head, node) { -+ if (marg->host_num != host_num) -+ continue; -+ condlog(4, " unsetting marginal dev: is %s %d\n", -+ tmp_marg->dev_t, tmp_marg->host_num); -+ fpin_path_unsetmarginal(marg->dev_t, vecs); -+ list_del(&marg->node); -+ free(marg); -+ } -+empty: -+ pthread_cleanup_pop(1); -+ /* walk backwards because update_path_groups() can remove mpp */ -+ vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { -+ if (mpp->fpin_must_reload) { -+ ret = update_path_groups(mpp, vecs, 0); -+ if (ret == 2) -+ condlog(2, "map removed during reload"); -+ else -+ mpp->fpin_must_reload = false; -+ } -+ } -+ pthread_cleanup_pop(1); -+} -+ -+/* -+ * On Receiving the frame from HBA driver, insert the frame into link -+ * integrity frame list which will be picked up later by consumer thread for -+ * processing. -+ */ -+static int -+fpin_els_add_li_frame(struct fc_nl_event *fc_event) -+{ -+ struct els_marginal_list *els_mrg = NULL; -+ int ret = 0; -+ -+ if (fc_event->event_datalen > FC_PAYLOAD_MAXLEN) -+ return -EINVAL; -+ -+ pthread_mutex_lock(&fpin_li_mutex); -+ pthread_cleanup_push(cleanup_mutex, &fpin_li_mutex); -+ pthread_testcancel(); -+ els_mrg = calloc(1, sizeof(struct els_marginal_list)); -+ if (els_mrg != NULL) { -+ els_mrg->host_num = fc_event->host_no; -+ els_mrg->event_code = fc_event->event_code; -+ els_mrg->length = fc_event->event_datalen; -+ memcpy(els_mrg->payload, &(fc_event->event_data), fc_event->event_datalen); -+ list_add_tail(&els_mrg->node, &els_marginal_list_head); -+ pthread_cond_signal(&fpin_li_cond); -+ } else -+ ret = -ENOMEM; -+ pthread_cleanup_pop(1); -+ return ret; -+ -+} -+ -+/*Sets the rport port_state to marginal*/ -+static void fpin_set_rport_marginal(struct udev_device *rport_dev) -+{ -+ sysfs_attr_set_value(rport_dev, "port_state", -+ "Marginal", strlen("Marginal")); -+} -+ -+/*Add the marginal devices info into the list*/ -+static void -+fpin_add_marginal_dev_info(uint32_t host_num, char *devname) -+{ -+ struct marginal_dev_list *newdev = NULL; -+ -+ newdev = calloc(1, sizeof(struct marginal_dev_list)); -+ if (newdev != NULL) { -+ newdev->host_num = host_num; -+ strlcpy(newdev->dev_t, devname, BLK_DEV_SIZE); -+ condlog(4, "\n%s hostno %d devname %s\n", __func__, -+ host_num, newdev->dev_t); -+ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); -+ list_add_tail(&(newdev->node), -+ &fpin_li_marginal_dev_list_head); -+ pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); -+ } -+} -+ -+/* -+ * This function goes through the vecs->pathvec, and for -+ * each path, check that the host number, -+ * the target WWPN associated with the path matches -+ * with the els wwpn and sets the path and port state to -+ * Marginal -+ */ -+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+ uint64_t els_wwpn) -+{ -+ struct path *pp; -+ struct multipath *mpp; -+ int i, k; -+ char rport_id[42]; -+ const char *value = NULL; -+ struct udev_device *rport_dev = NULL; -+ uint64_t wwpn; -+ int ret = 0; -+ -+ pthread_cleanup_push(cleanup_lock, &vecs->lock); -+ lock(&vecs->lock); -+ pthread_testcancel(); -+ -+ vector_foreach_slot(vecs->pathvec, pp, k) { -+ /* Checks the host number and also for the SCSI FCP */ -+ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) -+ continue; -+ sprintf(rport_id, "rport-%d:%d-%d", -+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -+ rport_dev = udev_device_new_from_subsystem_sysname(udev, -+ "fc_remote_ports", rport_id); -+ if (!rport_dev) { -+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -+ rport_id); -+ continue; -+ } -+ pthread_cleanup_push(_udev_device_unref, rport_dev); -+ value = udev_device_get_sysattr_value(rport_dev, "port_name"); -+ if (!value) -+ goto unref; -+ -+ if (value) -+ wwpn = strtol(value, NULL, 16); -+ /* -+ * If the port wwpn matches sets the path and port state -+ * to marginal -+ */ -+ if (wwpn == els_wwpn) { -+ ret = fpin_path_setmarginal(pp); -+ if (ret < 0) -+ goto unref; -+ fpin_set_rport_marginal(rport_dev); -+ fpin_add_marginal_dev_info(host_num, pp->dev); -+ } -+unref: -+ pthread_cleanup_pop(1); -+ } -+ /* walk backwards because update_path_groups() can remove mpp */ -+ vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { -+ if (mpp->fpin_must_reload) { -+ ret = update_path_groups(mpp, vecs, 0); -+ if (ret == 2) -+ condlog(2, "map removed during reload"); -+ else -+ mpp->fpin_must_reload = false; -+ } -+ } -+ pthread_cleanup_pop(1); -+ return ret; -+} -+ -+/* -+ * This function loops around all the impacted wwns received as part of els -+ * frame and sets the associated path and port states to marginal. -+ */ -+static int -+fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, -+ struct vectors *vecs) -+{ -+ uint32_t wwn_count = 0, iter = 0; -+ uint64_t wwpn; -+ struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; -+ int count = 0; -+ int ret = 0; -+ -+ /* Update the wwn to list */ -+ wwn_count = be32_to_cpu(li_desc->pname_count); -+ condlog(4, "Got wwn count as %d\n", wwn_count); -+ -+ for (iter = 0; iter < wwn_count; iter++) { -+ wwpn = be64_to_cpu(li_desc->pname_list[iter]); -+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); -+ if (ret < 0) -+ condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); -+ -+ count++; -+ } -+ return count; -+} -+ -+/* -+ * This function process the ELS frame received from HBA driver, -+ * and sets the path associated with the port wwn to marginal -+ * and also set the port state to marginal. -+ */ -+static int -+fpin_process_els_frame(uint16_t host_num, char *fc_payload, struct vectors *vecs) -+{ -+ -+ int count = -1; -+ struct fc_els_fpin *fpin = (struct fc_els_fpin *)fc_payload; -+ struct fc_tlv_desc *tlv; -+ -+ tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0]; -+ -+ /* -+ * Parse the els frame and set the affected paths and port -+ * state to marginal -+ */ -+ count = fpin_parse_li_els_setpath_marginal(host_num, tlv, vecs); -+ if (count <= 0) -+ condlog(4, "Could not find any WWNs, ret = %d\n", -+ count); -+ return count; -+} -+ -+/* -+ * This function process the FPIN ELS frame received from HBA driver, -+ * and push the frame to appropriate frame list. Currently we have only FPIN -+ * LI frame list. -+ */ -+static int -+fpin_handle_els_frame(struct fc_nl_event *fc_event) -+{ -+ int ret = -1; -+ uint32_t els_cmd; -+ struct fc_els_fpin *fpin = (struct fc_els_fpin *)&fc_event->event_data; -+ struct fc_tlv_desc *tlv; -+ uint32_t dtag; -+ -+ els_cmd = (uint32_t)fc_event->event_data; -+ tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0]; -+ dtag = be32_to_cpu(tlv->desc_tag); -+ condlog(4, "Got CMD in add as 0x%x fpin_cmd 0x%x dtag 0x%x\n", -+ els_cmd, fpin->fpin_cmd, dtag); -+ -+ if ((fc_event->event_code == FCH_EVT_LINK_FPIN) || -+ (fc_event->event_code == FCH_EVT_LINKUP) || -+ (fc_event->event_code == FCH_EVT_RSCN)) { -+ -+ if (els_cmd == ELS_FPIN) { -+ /* -+ * Check the type of fpin by checking the tag info -+ * At present we are supporting only LI events -+ */ -+ if (dtag == ELS_DTAG_LNK_INTEGRITY) { -+ /*Push the Payload to FPIN frame queue. */ -+ ret = fpin_els_add_li_frame(fc_event); -+ if (ret != 0) -+ condlog(0, "Failed to process LI frame with error %d\n", -+ ret); -+ } else { -+ condlog(4, "Unsupported FPIN received 0x%x\n", dtag); -+ return ret; -+ } -+ } else { -+ /*Push the Payload to FPIN frame queue. */ -+ ret = fpin_els_add_li_frame(fc_event); -+ if (ret != 0) -+ condlog(0, "Failed to process Linkup/RSCN event with error %d evnt %d\n", -+ ret, fc_event->event_code); -+ } -+ } else -+ condlog(4, "Invalid command received: 0x%x\n", els_cmd); -+ return ret; -+} -+ -+/*cleans the global marginal dev list*/ -+void fpin_clean_marginal_dev_list(__attribute__((unused)) void *arg) -+{ -+ struct marginal_dev_list *tmp_marg = NULL; -+ -+ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); -+ while (!list_empty(&fpin_li_marginal_dev_list_head)) { -+ tmp_marg = list_first_entry(&fpin_li_marginal_dev_list_head, -+ struct marginal_dev_list, node); -+ list_del(&tmp_marg->node); -+ free(tmp_marg); -+ } -+ pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); -+} -+ -+/* Cleans the global els marginal list */ -+static void fpin_clean_els_marginal_list(void *arg) -+{ -+ struct list_head *head = (struct list_head *)arg; -+ struct els_marginal_list *els_marg; -+ -+ while (!list_empty(head)) { -+ els_marg = list_first_entry(head, struct els_marginal_list, -+ node); -+ list_del(&els_marg->node); -+ free(els_marg); -+ } -+} -+ -+static void rcu_unregister(__attribute__((unused)) void *param) -+{ -+ rcu_unregister_thread(); -+} -+/* -+ * This is the FPIN ELS consumer thread. The thread sleeps on pthread cond -+ * variable unless notified by fpin_fabric_notification_receiver thread. -+ * This thread is only to process FPIN-LI ELS frames. A new thread and frame -+ * list will be added if any more ELS frames types are to be supported. -+ */ -+void *fpin_els_li_consumer(void *data) -+{ -+ struct list_head marginal_list_head; -+ int ret = 0; -+ uint16_t host_num; -+ struct els_marginal_list *els_marg; -+ uint32_t event_code; -+ struct vectors *vecs = (struct vectors *)data; -+ -+ pthread_cleanup_push(rcu_unregister, NULL); -+ rcu_register_thread(); -+ pthread_cleanup_push(fpin_clean_marginal_dev_list, NULL); -+ INIT_LIST_HEAD(&marginal_list_head); -+ pthread_cleanup_push(fpin_clean_els_marginal_list, -+ (void *)&marginal_list_head); -+ for ( ; ; ) { -+ pthread_mutex_lock(&fpin_li_mutex); -+ pthread_cleanup_push(cleanup_mutex, &fpin_li_mutex); -+ pthread_testcancel(); -+ while (list_empty(&els_marginal_list_head)) -+ pthread_cond_wait(&fpin_li_cond, &fpin_li_mutex); -+ -+ if (!list_empty(&els_marginal_list_head)) { -+ condlog(4, "Invoke List splice tail\n"); -+ list_splice_tail_init(&els_marginal_list_head, &marginal_list_head); -+ } -+ pthread_cleanup_pop(1); -+ -+ while (!list_empty(&marginal_list_head)) { -+ els_marg = list_first_entry(&marginal_list_head, -+ struct els_marginal_list, node); -+ host_num = els_marg->host_num; -+ event_code = els_marg->event_code; -+ /* Now finally process FPIN LI ELS Frame */ -+ condlog(4, "Got a new Payload buffer, processing it\n"); -+ if ((event_code == FCH_EVT_LINKUP) || (event_code == FCH_EVT_RSCN)) -+ fpin_unset_marginal_dev(host_num, vecs); -+ else { -+ ret = fpin_process_els_frame(host_num, els_marg->payload, vecs); -+ if (ret <= 0) -+ condlog(0, "ELS frame processing failed with ret %d\n", ret); -+ } -+ list_del(&els_marg->node); -+ free(els_marg); -+ -+ } -+ } -+ -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ return NULL; -+} -+ -+static void receiver_cleanup_list(__attribute__((unused)) void *arg) -+{ -+ pthread_mutex_lock(&fpin_li_mutex); -+ fpin_clean_els_marginal_list(&els_marginal_list_head); -+ pthread_mutex_unlock(&fpin_li_mutex); -+} -+ -+/* -+ * Listen for ELS frames from driver. on receiving the frame payload, -+ * push the payload to a list, and notify the fpin_els_li_consumer thread to -+ * process it. Once consumer thread is notified, return to listen for more ELS -+ * frames from driver. -+ */ -+void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) -+{ -+ int ret; -+ long fd; -+ uint32_t els_cmd; -+ struct fc_nl_event *fc_event = NULL; -+ struct sockaddr_nl fc_local; -+ unsigned char buf[DEF_RX_BUF_SIZE] __attribute__((aligned(sizeof(uint64_t)))); -+ size_t plen = 0; -+ -+ pthread_cleanup_push(rcu_unregister, NULL); -+ rcu_register_thread(); -+ -+ pthread_cleanup_push(receiver_cleanup_list, NULL); -+ fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_SCSITRANSPORT); -+ if (fd < 0) { -+ condlog(0, "fc socket error %ld", fd); -+ return NULL; -+ } -+ -+ pthread_cleanup_push(close_fd, (void *)fd); -+ memset(&fc_local, 0, sizeof(fc_local)); -+ fc_local.nl_family = AF_NETLINK; -+ fc_local.nl_groups = ~0; -+ fc_local.nl_pid = getpid(); -+ ret = bind(fd, (struct sockaddr *)&fc_local, sizeof(fc_local)); -+ if (ret == -1) { -+ condlog(0, "fc socket bind error %d\n", ret); -+ goto out; -+ } -+ for ( ; ; ) { -+ condlog(4, "Waiting for ELS...\n"); -+ ret = read(fd, buf, DEF_RX_BUF_SIZE); -+ if (ret < 0) { -+ condlog(0, "failed to read the els frame (%d)", ret); -+ continue; -+ } -+ condlog(4, "Got a new request %d\n", ret); -+ if (!NLMSG_OK((struct nlmsghdr *)buf, (unsigned int)ret)) { -+ condlog(0, "bad els frame read (%d)", ret); -+ continue; -+ } -+ /* Push the frame to appropriate frame list */ -+ plen = NLMSG_PAYLOAD((struct nlmsghdr *)buf, 0); -+ fc_event = (struct fc_nl_event *)NLMSG_DATA(buf); -+ if (plen < sizeof(*fc_event)) { -+ condlog(0, "too short (%d) to be an FC event", ret); -+ continue; -+ } -+ els_cmd = (uint32_t)fc_event->event_data; -+ condlog(4, "Got host no as %d, event 0x%x, len %d evntnum %d evntcode %d\n", -+ fc_event->host_no, els_cmd, fc_event->event_datalen, -+ fc_event->event_num, fc_event->event_code); -+ fpin_handle_els_frame(fc_event); -+ } -+out: -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ return NULL; -+} -diff --git a/multipathd/main.c b/multipathd/main.c -index eeded52b..4cf5bc41 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include "fpin.h" - #ifdef USE_SYSTEMD - #include - #endif -@@ -2704,7 +2705,9 @@ reconfigure (struct vectors * vecs) - conf->sequence_nr = old->sequence_nr + 1; - rcu_assign_pointer(multipath_conf, conf); - call_rcu(&old->rcu, rcu_free_config); -- -+#ifdef FPIN_EVENT_HANDLER -+ fpin_clean_marginal_dev_list(NULL); -+#endif - configure(vecs); - - -@@ -2878,7 +2881,8 @@ set_oom_adj (void) - static int - child (__attribute__((unused)) void *param) - { -- pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; -+ pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr, -+ fpin_thr, fpin_consumer_thr; - pthread_attr_t log_attr, misc_attr, uevent_attr; - struct vectors * vecs; - struct multipath * mpp; -@@ -2892,6 +2896,7 @@ child (__attribute__((unused)) void *param) - char *envp; - int queue_without_daemon; - enum daemon_status state; -+ int fpin_marginal_paths = 0; - - mlockall(MCL_CURRENT | MCL_FUTURE); - signal_init(); -@@ -2959,7 +2964,10 @@ child (__attribute__((unused)) void *param) - - setscheduler(); - set_oom_adj(); -- -+#ifdef FPIN_EVENT_HANDLER -+ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) -+ fpin_marginal_paths = 1; -+#endif - /* - * Startup done, invalidate configuration - */ -@@ -3020,6 +3028,19 @@ child (__attribute__((unused)) void *param) - condlog(0, "failed to create uevent dispatcher: %d", rc); - goto failed; - } -+ if (fpin_marginal_paths) { -+ if ((rc = pthread_create(&fpin_thr, &misc_attr, -+ fpin_fabric_notification_receiver, NULL))) { -+ condlog(0, "failed to create the fpin receiver thread: %d", rc); -+ goto failed; -+ } -+ -+ if ((rc = pthread_create(&fpin_consumer_thr, -+ &misc_attr, fpin_els_li_consumer, vecs))) { -+ condlog(0, "failed to create the fpin consumer thread thread: %d", rc); -+ goto failed; -+ } -+ } - pthread_attr_destroy(&misc_attr); - - while (1) { -@@ -3070,6 +3091,10 @@ child (__attribute__((unused)) void *param) - pthread_cancel(uevq_thr); - if (poll_dmevents) - pthread_cancel(dmevent_thr); -+ if (fpin_marginal_paths) { -+ pthread_cancel(fpin_thr); -+ pthread_cancel(fpin_consumer_thr); -+ } - - pthread_join(check_thr, NULL); - pthread_join(uevent_thr, NULL); -@@ -3077,6 +3102,10 @@ child (__attribute__((unused)) void *param) - pthread_join(uevq_thr, NULL); - if (poll_dmevents) - pthread_join(dmevent_thr, NULL); -+ if (fpin_marginal_paths) { -+ pthread_join(fpin_thr, NULL); -+ pthread_join(fpin_consumer_thr, NULL); -+ } - - stop_io_err_stat_thread(); - diff --git a/SOURCES/0106-multipathd-disallow-changing-to-from-fpin-marginal-p.patch b/SOURCES/0106-multipathd-disallow-changing-to-from-fpin-marginal-p.patch deleted file mode 100644 index 7245625..0000000 --- a/SOURCES/0106-multipathd-disallow-changing-to-from-fpin-marginal-p.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 11 Feb 2022 17:23:39 -0600 -Subject: [PATCH] multipathd: disallow changing to/from fpin marginal paths on - reconfig - -Setting marginal_pathgroups to fpin causes two new threads to be created -when multipathd starts. Turning it on after multipathd starts up won't -cause the theads to start, and turing it off won't keep the threads from -working. So disallow changing marginal_pathgroups to/from "fpin" on -reconfigure. - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 13 ++++++++----- - multipathd/main.c | 9 +++++++++ - 2 files changed, 17 insertions(+), 5 deletions(-) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 805b7a5e..8e418372 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1077,15 +1077,18 @@ have been tried first. This prevents the possibility of IO errors occuring - while marginal paths are still usable. After the path has been monitored - for the configured time, and is declared healthy, it will be returned to its - normal pathgroup. --However if this option is set to \fIfpin\fR multipathd will receive fpin -+If this option is set to \fIfpin\fR, multipathd will receive fpin - notifications, set path states to "marginal" accordingly, and regroup paths --as described for "marginal_pathgroups yes". This option can't be used in combination --with other options for "Shaky path detection" (see below).If it is set to fpin, --marginal_path_xyz and san_path_err_xyz parameters are implicitly set to 0. -+as described for \fIon\fR. This option can't be used in combination -+with other options for "Shaky path detection" (see below). \fBNote:\fR If this -+is set to \fIfpin\fR, the \fImarginal_path_*\fR and \fIsan_path_err_*\fR -+options are implicitly set to \fIno\fP. Also, this option cannot be switched -+either to or from \fIfpin\fR on a multipathd reconfigure. multipathd must be -+restarted for the change to take effect. - See "Shaky paths detection" below for more information. - .RS - .TP --The default is: \fBno\fR -+The default is: \fBoff\fR - .RE - . - . -diff --git a/multipathd/main.c b/multipathd/main.c -index 4cf5bc41..a6ffbe32 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2675,6 +2675,7 @@ int - reconfigure (struct vectors * vecs) - { - struct config * old, *conf; -+ int old_marginal_pathgroups; - - conf = load_config(DEFAULT_CONFIGFILE); - if (!conf) -@@ -2702,6 +2703,14 @@ reconfigure (struct vectors * vecs) - uxsock_timeout = conf->uxsock_timeout; - - old = rcu_dereference(multipath_conf); -+ old_marginal_pathgroups = old->marginal_pathgroups; -+ if ((old_marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) != -+ (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { -+ condlog(1, "multipathd must be restarted to turn %s fpin marginal paths", -+ (old_marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)? -+ "off" : "on"); -+ conf->marginal_pathgroups = old_marginal_pathgroups; -+ } - conf->sequence_nr = old->sequence_nr + 1; - rcu_assign_pointer(multipath_conf, conf); - call_rcu(&old->rcu, rcu_free_config); diff --git a/SOURCES/0107-libmultipath-unset-detect_checker-for-clariion-Unity.patch b/SOURCES/0107-libmultipath-unset-detect_checker-for-clariion-Unity.patch deleted file mode 100644 index 5c82cc8..0000000 --- a/SOURCES/0107-libmultipath-unset-detect_checker-for-clariion-Unity.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 10 May 2022 14:17:22 -0500 -Subject: [PATCH] libmultipath: unset detect_checker for clariion / Unity - arrays - -Dell EMC would like to always use the emc_clariion checker. Currently -detect_checker will switch the checker to TUR for Unity arrays. -This can cause problems on some setups with replicated Unity LUNs, -which are handled correctly the the emc_checker, but not the TUR -checker. - -Cc: vincent.chen1@dell.com -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d6325864..2bb274c5 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -343,6 +343,7 @@ static struct hwentry default_hw[] = { - .no_path_retry = (300 / DEFAULT_CHECKINT), - .checker_name = EMC_CLARIION, - .prio_name = PRIO_EMC, -+ .detect_checker = DETECT_CHECKER_OFF, - }, - { - /* Invista / VPLEX */ diff --git a/SOURCES/0108-multipathd-Add-missing-ctype-include.patch b/SOURCES/0108-multipathd-Add-missing-ctype-include.patch deleted file mode 100644 index 7e2d464..0000000 --- a/SOURCES/0108-multipathd-Add-missing-ctype-include.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Bastian Germann -Date: Thu, 14 Oct 2021 00:34:33 +0200 -Subject: [PATCH] multipathd: Add missing ctype include - -In uxclnt.c, there are isspace calls. Add an explicit include. - -Signed-off-by: Bastian Germann -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/uxclnt.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index a76f8e29..f16a7309 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/SOURCES/0109-multipathd-replace-libreadline-with-libedit.patch b/SOURCES/0109-multipathd-replace-libreadline-with-libedit.patch deleted file mode 100644 index c256ef4..0000000 --- a/SOURCES/0109-multipathd-replace-libreadline-with-libedit.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 12 Aug 2022 18:58:15 +0200 -Subject: [PATCH] multipathd: replace libreadline with libedit - -Linking multipathd with libreadline may cause a license conflict, -because libreadline is licensed under GPL-3.0-or-later, and -libmultipath contains several files under GPL-2.0. - -See: - https://github.com/opensvc/multipath-tools/issues/36 - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=979095 - https://www.gnu.org/licenses/gpl-faq.html#AllCompatibility - -Replace the readline functionality with libedit, which comes under -a BSD license. The readline library can still be enabled (e.g. for -binaries not intended to be distributed) by running -"make READLINE=libreadline". - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 5 +++++ - multipathd/Makefile | 11 ++++++++++- - multipathd/cli.c | 5 +++++ - multipathd/uxclnt.c | 6 ++++++ - 4 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 25c16f4e..d471f045 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -14,6 +14,11 @@ - # - # Uncomment to disable dmevents polling support - # ENABLE_DMEVENTS_POLL = 0 -+# -+# Readline library to use, libedit or libreadline -+# Caution: Using libreadline may make the multipathd binary undistributable, -+# see https://github.com/opensvc/multipath-tools/issues/36 -+READLINE = libedit - - ifeq ($(TOPDIR),) - TOPDIR = .. -diff --git a/multipathd/Makefile b/multipathd/Makefile -index 835edd93..4874ec3a 100644 ---- a/multipathd/Makefile -+++ b/multipathd/Makefile -@@ -15,7 +15,16 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) \ - LDFLAGS += $(BIN_LDFLAGS) - LIBDEPS += -L$(multipathdir) -lmultipath -L$(mpathpersistdir) -lmpathpersist \ - -L$(mpathcmddir) -lmpathcmd -ludev -ldl -lurcu -lpthread \ -- -ldevmapper -lreadline -+ -ldevmapper -+ -+ifeq ($(READLINE),libedit) -+CFLAGS += -DUSE_LIBEDIT -+LIBDEPS += -ledit -+endif -+ifeq ($(READLINE),libreadline) -+CFLAGS += -DUSE_LIBREADLINE -+LIBDEPS += -lreadline -+endif - - ifdef SYSTEMD - CFLAGS += -DUSE_SYSTEMD=$(SYSTEMD) -diff --git a/multipathd/cli.c b/multipathd/cli.c -index bdc9fb10..85d73dfb 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -11,7 +11,12 @@ - #include "parser.h" - #include "util.h" - #include "version.h" -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include -+#endif - - #include "mpath_cmd.h" - #include "cli.h" -diff --git a/multipathd/uxclnt.c b/multipathd/uxclnt.c -index f16a7309..2c17d8fc 100644 ---- a/multipathd/uxclnt.c -+++ b/multipathd/uxclnt.c -@@ -16,8 +16,14 @@ - #include - #include - #include -+ -+#ifdef USE_LIBEDIT -+#include -+#endif -+#ifdef USE_LIBREADLINE - #include - #include -+#endif - - #include "mpath_cmd.h" - #include "uxsock.h" diff --git a/SOURCES/0110-multipath-fix-systemd-timers-in-the-initramfs.patch b/SOURCES/0110-multipath-fix-systemd-timers-in-the-initramfs.patch deleted file mode 100644 index 2d7f6d7..0000000 --- a/SOURCES/0110-multipath-fix-systemd-timers-in-the-initramfs.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 5 Aug 2022 18:16:03 -0500 -Subject: [PATCH] multipath: fix systemd timers in the initramfs - -The systemd timers created for "find_multipaths smart" conflict with -shutdown.target, but not with initrd-cleanup.service. This can make -these timers trigger after the inirtd has started shutting down, -restarting multipathd (which then stops initrd-cleanup.service, since it -conflicts). To avoid this, make sure the timers and the unit they -trigger conflict with inird-cleanup.service. Also don't make them start -multipathd. "multipath -u" will not return "maybe" if multipathd isn't -running or set to run, and since we no longer wait for udev-settle, -multipathd starts up pretty quickly, so it shouldn't be a problem to -not trigger it here. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipath/multipath.rules | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 0486bf70..68c30644 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules -@@ -72,7 +72,7 @@ ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath" - # - # We must trigger an "add" event because LVM2 will only act on those. - --RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Wants=multipathd.service --property After=multipathd.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" -+RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath" - - LABEL="pretend_mpath" - ENV{DM_MULTIPATH_DEVICE_PATH}="1" diff --git a/SOURCES/0111-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch b/SOURCES/0111-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch deleted file mode 100644 index 27f4b98..0000000 --- a/SOURCES/0111-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:26 -0500 -Subject: [PATCH] multipathd: factor out the code to flush a map with no paths - -The code to flush a multipath device because all of its paths have -been removed will be used by another caller, so factor it out of -ev_remove_path(). - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 56 ++++++++++++++++++++++++----------------------- - 1 file changed, 29 insertions(+), 27 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index a6ffbe32..9b1098f6 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -487,6 +487,30 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) - return 0; - } - -+static bool -+flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { -+ char alias[WWID_SIZE]; -+ -+ /* -+ * flush_map will fail if the device is open -+ */ -+ strlcpy(alias, mpp->alias, WWID_SIZE); -+ if (mpp->flush_on_last_del == FLUSH_ENABLED) { -+ condlog(2, "%s Last path deleted, disabling queueing", -+ mpp->alias); -+ mpp->retry_tick = 0; -+ mpp->no_path_retry = NO_PATH_RETRY_FAIL; -+ mpp->disable_queueing = 1; -+ mpp->stat_map_failures++; -+ dm_queue_if_no_path(mpp->alias, 0); -+ } -+ if (!flush_map(mpp, vecs, 1)) { -+ condlog(2, "%s: removed map after removing all paths", alias); -+ return true; -+ } -+ return false; -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { -@@ -1185,34 +1209,12 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - vector_del_slot(mpp->paths, i); - - /* -- * remove the map IF removing the last path -+ * remove the map IF removing the last path. If -+ * flush_map_nopaths succeeds, the path has been removed. - */ -- if (VECTOR_SIZE(mpp->paths) == 0) { -- char alias[WWID_SIZE]; -- -- /* -- * flush_map will fail if the device is open -- */ -- strlcpy(alias, mpp->alias, WWID_SIZE); -- if (mpp->flush_on_last_del == FLUSH_ENABLED) { -- condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); -- mpp->retry_tick = 0; -- mpp->no_path_retry = NO_PATH_RETRY_FAIL; -- mpp->disable_queueing = 1; -- mpp->stat_map_failures++; -- dm_queue_if_no_path(mpp->alias, 0); -- } -- if (!flush_map(mpp, vecs, 1)) { -- condlog(2, "%s: removed map after" -- " removing all paths", -- alias); -- retval = 0; -- goto out; -- } -- /* -- * Not an error, continue -- */ -- } -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ goto out; - - if (mpp->hwe == NULL) - extract_hwe_from_path(mpp); diff --git a/SOURCES/0112-libmultipath-return-success-if-we-raced-to-remove-a-.patch b/SOURCES/0112-libmultipath-return-success-if-we-raced-to-remove-a-.patch deleted file mode 100644 index ce2a539..0000000 --- a/SOURCES/0112-libmultipath-return-success-if-we-raced-to-remove-a-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:27 -0500 -Subject: [PATCH] libmultipath: return success if we raced to remove a map and - lost - -_dm_flush_map() was returning failure if it failed to remove a map, -even if that was because the map had already been removed. Return -success in this case. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/devmapper.c | 4 ++++ - multipathd/main.c | 4 ---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index e3c3c119..ee81acc3 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -916,6 +916,10 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove, - } - condlog(4, "multipath map %s removed", mapname); - return 0; -+ } else if (dm_is_mpath(mapname) != 1) { -+ condlog(4, "multipath map %s removed externally", -+ mapname); -+ return 0; /*we raced with someone else removing it */ - } else { - condlog(2, "failed to remove multipath map %s", - mapname); -diff --git a/multipathd/main.c b/multipathd/main.c -index 9b1098f6..9eafd5b7 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -673,10 +673,6 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths) - * the spurious uevent we may generate with the dm_flush_map call below - */ - if (r) { -- /* -- * May not really be an error -- if the map was already flushed -- * from the device mapper by dmsetup(8) for instance. -- */ - if (r == 1) - condlog(0, "%s: can't flush", mpp->alias); - else { diff --git a/SOURCES/0113-multipathd-Handle-losing-all-path-in-update_map.patch b/SOURCES/0113-multipathd-Handle-losing-all-path-in-update_map.patch deleted file mode 100644 index 28878dd..0000000 --- a/SOURCES/0113-multipathd-Handle-losing-all-path-in-update_map.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 9 Aug 2022 16:46:28 -0500 -Subject: [PATCH] multipathd: Handle losing all path in update_map - -Its possible that when a multipath device is being updated, it will end -up that all the paths for it are gone. This can happen if paths are -added and then removed again before multipathd processes the uevent for -the newly created multipath device. In this case multipathd wasn't -taking the proper action for the case where all the paths had been -removed. If flush_on_last_del was set, multipathd wasn't disabling -flushing and if deferred_remove was set, it wasn't doing a deferred -remove. Multipathd should call flush_map_nopaths(), just like -ev_remove_path() does when the last path is removed. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 9eafd5b7..870ae7d8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -526,6 +526,10 @@ retry: - goto fail; - } - verify_paths(mpp, vecs); -+ if (VECTOR_SIZE(mpp->paths) == 0 && -+ flush_map_nopaths(mpp, vecs)) -+ return 1; -+ - mpp->action = ACT_RELOAD; - - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { diff --git a/SOURCES/0114-multipathd-ignore-duplicated-multipathd-command-keys.patch b/SOURCES/0114-multipathd-ignore-duplicated-multipathd-command-keys.patch deleted file mode 100644 index 4192095..0000000 --- a/SOURCES/0114-multipathd-ignore-duplicated-multipathd-command-keys.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 8 Sep 2022 11:54:49 -0500 -Subject: [PATCH] multipathd: ignore duplicated multipathd command keys - -multipath adds rather than or-s the values of command keys. Fix this. -Also, return an invalid fingerprint if a key is used more than once. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli.c | 8 ++-- - multipathd/main.c | 106 +++++++++++++++++++++++----------------------- - 2 files changed, 58 insertions(+), 56 deletions(-) - -diff --git a/multipathd/cli.c b/multipathd/cli.c -index 85d73dfb..45e80197 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -341,9 +341,11 @@ fingerprint(vector vec) - if (!vec) - return 0; - -- vector_foreach_slot(vec, kw, i) -- fp += kw->code; -- -+ vector_foreach_slot(vec, kw, i) { -+ if (fp & kw->code) -+ return (uint64_t)-1; -+ fp |= kw->code; -+ } - return fp; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index 870ae7d8..cd68a9d2 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1628,62 +1628,62 @@ uxlsnrloop (void * ap) - /* Tell main thread that thread has started */ - post_config_state(DAEMON_CONFIGURE); - -- set_handler_callback(LIST+PATHS, cli_list_paths); -- set_handler_callback(LIST+PATHS+FMT, cli_list_paths_fmt); -- set_handler_callback(LIST+PATHS+RAW+FMT, cli_list_paths_raw); -- set_handler_callback(LIST+PATH, cli_list_path); -- set_handler_callback(LIST+MAPS, cli_list_maps); -- set_handler_callback(LIST+STATUS, cli_list_status); -- set_unlocked_handler_callback(LIST+DAEMON, cli_list_daemon); -- set_handler_callback(LIST+MAPS+STATUS, cli_list_maps_status); -- set_handler_callback(LIST+MAPS+STATS, cli_list_maps_stats); -- set_handler_callback(LIST+MAPS+FMT, cli_list_maps_fmt); -- set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw); -- set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology); -- set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology); -- set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json); -- set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology); -- set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt); -- set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt); -- set_handler_callback(LIST+MAP+JSON, cli_list_map_json); -- set_handler_callback(LIST+CONFIG+LOCAL, cli_list_config_local); -- set_handler_callback(LIST+CONFIG, cli_list_config); -- set_handler_callback(LIST+BLACKLIST, cli_list_blacklist); -- set_handler_callback(LIST+DEVICES, cli_list_devices); -- set_handler_callback(LIST+WILDCARDS, cli_list_wildcards); -- set_handler_callback(RESET+MAPS+STATS, cli_reset_maps_stats); -- set_handler_callback(RESET+MAP+STATS, cli_reset_map_stats); -- set_handler_callback(ADD+PATH, cli_add_path); -- set_handler_callback(DEL+PATH, cli_del_path); -- set_handler_callback(ADD+MAP, cli_add_map); -- set_handler_callback(DEL+MAP, cli_del_map); -- set_handler_callback(DEL+MAPS, cli_del_maps); -- set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group); -+ set_handler_callback(LIST|PATHS, cli_list_paths); -+ set_handler_callback(LIST|PATHS|FMT, cli_list_paths_fmt); -+ set_handler_callback(LIST|PATHS|RAW|FMT, cli_list_paths_raw); -+ set_handler_callback(LIST|PATH, cli_list_path); -+ set_handler_callback(LIST|MAPS, cli_list_maps); -+ set_handler_callback(LIST|STATUS, cli_list_status); -+ set_unlocked_handler_callback(LIST|DAEMON, cli_list_daemon); -+ set_handler_callback(LIST|MAPS|STATUS, cli_list_maps_status); -+ set_handler_callback(LIST|MAPS|STATS, cli_list_maps_stats); -+ set_handler_callback(LIST|MAPS|FMT, cli_list_maps_fmt); -+ set_handler_callback(LIST|MAPS|RAW|FMT, cli_list_maps_raw); -+ set_handler_callback(LIST|MAPS|TOPOLOGY, cli_list_maps_topology); -+ set_handler_callback(LIST|TOPOLOGY, cli_list_maps_topology); -+ set_handler_callback(LIST|MAPS|JSON, cli_list_maps_json); -+ set_handler_callback(LIST|MAP|TOPOLOGY, cli_list_map_topology); -+ set_handler_callback(LIST|MAP|FMT, cli_list_map_fmt); -+ set_handler_callback(LIST|MAP|RAW|FMT, cli_list_map_fmt); -+ set_handler_callback(LIST|MAP|JSON, cli_list_map_json); -+ set_handler_callback(LIST|CONFIG|LOCAL, cli_list_config_local); -+ set_handler_callback(LIST|CONFIG, cli_list_config); -+ set_handler_callback(LIST|BLACKLIST, cli_list_blacklist); -+ set_handler_callback(LIST|DEVICES, cli_list_devices); -+ set_handler_callback(LIST|WILDCARDS, cli_list_wildcards); -+ set_handler_callback(RESET|MAPS|STATS, cli_reset_maps_stats); -+ set_handler_callback(RESET|MAP|STATS, cli_reset_map_stats); -+ set_handler_callback(ADD|PATH, cli_add_path); -+ set_handler_callback(DEL|PATH, cli_del_path); -+ set_handler_callback(ADD|MAP, cli_add_map); -+ set_handler_callback(DEL|MAP, cli_del_map); -+ set_handler_callback(DEL|MAPS, cli_del_maps); -+ set_handler_callback(SWITCH|MAP|GROUP, cli_switch_group); - set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure); -- set_handler_callback(SUSPEND+MAP, cli_suspend); -- set_handler_callback(RESUME+MAP, cli_resume); -- set_handler_callback(RESIZE+MAP, cli_resize); -- set_handler_callback(RELOAD+MAP, cli_reload); -- set_handler_callback(RESET+MAP, cli_reassign); -- set_handler_callback(REINSTATE+PATH, cli_reinstate); -- set_handler_callback(FAIL+PATH, cli_fail); -- set_handler_callback(DISABLEQ+MAP, cli_disable_queueing); -- set_handler_callback(RESTOREQ+MAP, cli_restore_queueing); -- set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing); -- set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing); -+ set_handler_callback(SUSPEND|MAP, cli_suspend); -+ set_handler_callback(RESUME|MAP, cli_resume); -+ set_handler_callback(RESIZE|MAP, cli_resize); -+ set_handler_callback(RELOAD|MAP, cli_reload); -+ set_handler_callback(RESET|MAP, cli_reassign); -+ set_handler_callback(REINSTATE|PATH, cli_reinstate); -+ set_handler_callback(FAIL|PATH, cli_fail); -+ set_handler_callback(DISABLEQ|MAP, cli_disable_queueing); -+ set_handler_callback(RESTOREQ|MAP, cli_restore_queueing); -+ set_handler_callback(DISABLEQ|MAPS, cli_disable_all_queueing); -+ set_handler_callback(RESTOREQ|MAPS, cli_restore_all_queueing); - set_unlocked_handler_callback(QUIT, cli_quit); - set_unlocked_handler_callback(SHUTDOWN, cli_shutdown); -- set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus); -- set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus); -- set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus); -- set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q); -- set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q); -- set_handler_callback(GETPRKEY+MAP, cli_getprkey); -- set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey); -- set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey); -- set_handler_callback(SETMARGINAL+PATH, cli_set_marginal); -- set_handler_callback(UNSETMARGINAL+PATH, cli_unset_marginal); -- set_handler_callback(UNSETMARGINAL+MAP, cli_unset_all_marginal); -+ set_handler_callback(GETPRSTATUS|MAP, cli_getprstatus); -+ set_handler_callback(SETPRSTATUS|MAP, cli_setprstatus); -+ set_handler_callback(UNSETPRSTATUS|MAP, cli_unsetprstatus); -+ set_handler_callback(FORCEQ|DAEMON, cli_force_no_daemon_q); -+ set_handler_callback(RESTOREQ|DAEMON, cli_restore_no_daemon_q); -+ set_handler_callback(GETPRKEY|MAP, cli_getprkey); -+ set_handler_callback(SETPRKEY|MAP|KEY, cli_setprkey); -+ set_handler_callback(UNSETPRKEY|MAP, cli_unsetprkey); -+ set_handler_callback(SETMARGINAL|PATH, cli_set_marginal); -+ set_handler_callback(UNSETMARGINAL|PATH, cli_unset_marginal); -+ set_handler_callback(UNSETMARGINAL|MAP, cli_unset_all_marginal); - - umask(077); - uxsock_listen(&uxsock_trigger, ux_sock, ap); diff --git a/SOURCES/0115-multipath-tools-use-run-instead-of-dev-shm.patch b/SOURCES/0115-multipath-tools-use-run-instead-of-dev-shm.patch deleted file mode 100644 index f7a05fc..0000000 --- a/SOURCES/0115-multipath-tools-use-run-instead-of-dev-shm.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 1 Sep 2022 19:21:30 +0200 -Subject: [PATCH] multipath-tools: use /run instead of /dev/shm - -/dev/shm may have unsafe permissions. Use /run instead. -Use systemd's tmpfiles.d mechanism to create /run/multipath -early during boot. - -For backward compatibilty, make the runtime directory configurable -via the "runtimedir" make variable. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - .gitignore | 2 ++ - Makefile.inc | 4 +++- - libmultipath/defaults.h | 2 +- - multipath/Makefile | 9 +++++++-- - multipath/{multipath.rules => multipath.rules.in} | 4 ++-- - multipath/tmpfiles.conf.in | 1 + - 6 files changed, 16 insertions(+), 6 deletions(-) - rename multipath/{multipath.rules => multipath.rules.in} (96%) - create mode 100644 multipath/tmpfiles.conf.in - -diff --git a/.gitignore b/.gitignore -index 9926756b..f90b0350 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -8,6 +8,8 @@ - *.d - kpartx/kpartx - multipath/multipath -+multipath/multipath.rules -+multipath/tmpfiles.conf - multipathd/multipathd - mpathpersist/mpathpersist - .nfs* -diff --git a/Makefile.inc b/Makefile.inc -index d471f045..287f0e7b 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -60,6 +60,7 @@ exec_prefix = $(prefix) - usr_prefix = $(prefix) - bindir = $(exec_prefix)/usr/sbin - libudevdir = $(prefix)/$(SYSTEMDPATH)/udev -+tmpfilesdir = $(prefix)/$(SYSTEMDPATH)/tmpfiles.d - udevrulesdir = $(libudevdir)/rules.d - multipathdir = $(TOPDIR)/libmultipath - man8dir = $(prefix)/usr/share/man/man8 -@@ -76,6 +77,7 @@ libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme - includedir = $(prefix)/usr/include - pkgconfdir = $(usrlibdir)/pkgconfig -+runtimedir = /$(RUN) - - GZIP = gzip -9 -c - RM = rm -f -@@ -117,7 +119,7 @@ OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \ - -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ - --param=ssp-buffer-size=4 - --CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -+CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" -DRUNTIME_DIR=\"$(runtimedir)\" \ - -MMD -MP $(CFLAGS) - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index f1cb000d..dcd9f5a7 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -65,7 +65,7 @@ - #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" - #define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys" - #define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d" --#define MULTIPATH_SHM_BASE "/dev/shm/multipath/" -+#define MULTIPATH_SHM_BASE RUNTIME_DIR "/multipath/" - - - static inline char *set_default(char *str) -diff --git a/multipath/Makefile b/multipath/Makefile -index e720c7f6..f3d98012 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -12,7 +12,7 @@ EXEC = multipath - - OBJS = main.o - --all: $(EXEC) -+all: $(EXEC) multipath.rules tmpfiles.conf - - $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so - $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) -@@ -27,6 +27,8 @@ install: - $(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 -+ $(INSTALL_PROGRAM) -d $(DESTDIR)$(tmpfilesdir) -+ $(INSTALL_PROGRAM) -m 644 tmpfiles.conf $(DESTDIR)$(tmpfilesdir)/multipath.conf - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -@@ -43,9 +45,12 @@ uninstall: - $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz - - clean: dep_clean -- $(RM) core *.o $(EXEC) *.gz -+ $(RM) core *.o $(EXEC) *.gz multipath.rules tmpfiles.conf - - include $(wildcard $(OBJS:.o=.d)) - - dep_clean: - $(RM) $(OBJS:.o=.d) -+ -+%: %.in -+ sed 's,@RUNTIME_DIR@,$(runtimedir),' $< >$@ -diff --git a/multipath/multipath.rules b/multipath/multipath.rules.in -similarity index 96% -rename from multipath/multipath.rules -rename to multipath/multipath.rules.in -index 68c30644..5c4447a2 100644 ---- a/multipath/multipath.rules -+++ b/multipath/multipath.rules.in -@@ -1,8 +1,8 @@ - # Set DM_MULTIPATH_DEVICE_PATH if the device should be handled by multipath - SUBSYSTEM!="block", GOTO="end_mpath" - KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath" --ACTION=="remove", TEST=="/dev/shm/multipath/find_multipaths/$major:$minor", \ -- RUN+="/usr/bin/rm -f /dev/shm/multipath/find_multipaths/$major:$minor" -+ACTION=="remove", TEST=="@RUNTIME_DIR@/multipath/find_multipaths/$major:$minor", \ -+ RUN+="/usr/bin/rm -f @RUNTIME_DIR@/multipath/find_multipaths/$major:$minor" - ACTION!="add|change", GOTO="end_mpath" - - IMPORT{cmdline}="nompath" -diff --git a/multipath/tmpfiles.conf.in b/multipath/tmpfiles.conf.in -new file mode 100644 -index 00000000..21be438a ---- /dev/null -+++ b/multipath/tmpfiles.conf.in -@@ -0,0 +1 @@ -+d @RUNTIME_DIR@/multipath 0700 root root - diff --git a/SOURCES/0116-kpartx-hold-device-open-until-partitions-have-been-c.patch b/SOURCES/0116-kpartx-hold-device-open-until-partitions-have-been-c.patch deleted file mode 100644 index fa9033a..0000000 --- a/SOURCES/0116-kpartx-hold-device-open-until-partitions-have-been-c.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 19 Oct 2022 12:57:10 -0500 -Subject: [PATCH] kpartx: hold device open until partitions have been created - -kpartx was closing the whole device after it read the partition -information off it. This allowed a race, where the device could be -removed and another one created with the same major:minor, after kpartx -read the partition information but before it created the partition -devices. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - kpartx/kpartx.c | 11 +++-------- - 1 file changed, 3 insertions(+), 8 deletions(-) - -diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c -index a337a07b..e62b764f 100644 ---- a/kpartx/kpartx.c -+++ b/kpartx/kpartx.c -@@ -426,12 +426,7 @@ main(int argc, char **argv){ - if (n >= 0) - printf("%s: %d slices\n", ptp->type, n); - #endif -- -- if (n > 0) { -- close(fd); -- fd = -1; -- } -- else -+ if (n <= 0) - continue; - - switch(what) { -@@ -649,9 +644,9 @@ main(int argc, char **argv){ - if (n > 0) - break; - } -+ if (fd != -1) -+ close(fd); - if (what == LIST && loopcreated) { -- if (fd != -1) -- close(fd); - if (del_loop(device)) { - if (verbose) - fprintf(stderr, "can't del loop : %s\n", diff --git a/SOURCES/0117-libmultipath-cleanup-remove_feature.patch b/SOURCES/0117-libmultipath-cleanup-remove_feature.patch deleted file mode 100644 index 4ed7925..0000000 --- a/SOURCES/0117-libmultipath-cleanup-remove_feature.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:37 -0500 -Subject: [PATCH] libmultipath: cleanup remove_feature - -remove_feature() didn't correctly handle feature strings that used -whitespace other than spaces, which the kernel allows. It also didn't -check if the feature string to be removed was part of a larger feature -token. Finally, it did a lot of unnecessary work. By failing if the -feature string to be removed contains leading or trailing whitespace, -the function can be significanly simplified. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 82 +++++++++++++++--------------------------- - 1 file changed, 29 insertions(+), 53 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 9f86eb69..471087e2 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #include "checkers.h" - #include "memory.h" -@@ -633,7 +634,7 @@ int add_feature(char **f, const char *n) - - int remove_feature(char **f, const char *o) - { -- int c = 0, d, l; -+ int c = 0, d; - char *e, *p, *n; - const char *q; - -@@ -644,33 +645,35 @@ int remove_feature(char **f, const char *o) - if (!o || *o == '\0') - return 0; - -- /* Check if not present */ -- if (!strstr(*f, o)) -+ d = strlen(o); -+ if (isspace(*o) || isspace(*(o + d - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", o); -+ return 1; -+ } -+ -+ /* Check if present and not part of a larger feature token*/ -+ p = *f + 1; /* the size must be at the start of the features string */ -+ while ((p = strstr(p, o)) != NULL) { -+ if (isspace(*(p - 1)) && -+ (isspace(*(p + d)) || *(p + d) == '\0')) -+ break; -+ p += d; -+ } -+ if (!p) - return 0; - - /* Get feature count */ - c = strtoul(*f, &e, 10); -- if (*f == e) -- /* parse error */ -+ if (*f == e || !isspace(*e)) { -+ condlog(0, "parse error in feature string \"%s\"", *f); - return 1; -- -- /* Normalize features */ -- while (*o == ' ') { -- o++; - } -- /* Just spaces, return */ -- if (*o == '\0') -- return 0; -- q = o + strlen(o); -- while (*q == ' ') -- q--; -- d = (int)(q - o); - - /* Update feature count */ - c--; - q = o; -- while (q[0] != '\0') { -- if (q[0] == ' ' && q[1] != ' ' && q[1] != '\0') -+ while (*q != '\0') { -+ if (isspace(*q) && !isspace(*(q + 1)) && *(q + 1) != '\0') - c--; - q++; - } -@@ -684,15 +687,8 @@ int remove_feature(char **f, const char *o) - goto out; - } - -- /* Search feature to be removed */ -- e = strstr(*f, o); -- if (!e) -- /* Not found, return */ -- return 0; -- - /* Update feature count space */ -- l = strlen(*f) - d; -- n = MALLOC(l + 1); -+ n = MALLOC(strlen(*f) - d + 1); - if (!n) - return 1; - -@@ -702,36 +698,16 @@ int remove_feature(char **f, const char *o) - * Copy existing features up to the feature - * about to be removed - */ -- p = strchr(*f, ' '); -- if (!p) { -- /* Internal error, feature string inconsistent */ -- FREE(n); -- return 1; -- } -- while (*p == ' ') -- p++; -- p--; -- if (e != p) { -- do { -- e--; -- d++; -- } while (*e == ' '); -- e++; d--; -- strncat(n, p, (size_t)(e - p)); -- p += (size_t)(e - p); -- } -+ strncat(n, e, (size_t)(p - e)); - /* Skip feature to be removed */ - p += d; -- - /* Copy remaining features */ -- if (strlen(p)) { -- while (*p == ' ') -- p++; -- if (strlen(p)) { -- p--; -- strcat(n, p); -- } -- } -+ while (isspace(*p)) -+ p++; -+ if (*p != '\0') -+ strcat(n, p); -+ else -+ strchop(n); - - out: - FREE(*f); diff --git a/SOURCES/0118-libmultipath-cleanup-add_feature.patch b/SOURCES/0118-libmultipath-cleanup-add_feature.patch deleted file mode 100644 index 85e1656..0000000 --- a/SOURCES/0118-libmultipath-cleanup-add_feature.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:38 -0500 -Subject: [PATCH] libmultipath: cleanup add_feature - -add_feature() didn't correctly handle feature strings that used -whitespace other than spaces, which the kernel allows. It also didn't -allow adding features with multiple tokens. When it looked to see if the -feature string to be added already existed, it didn't check if the match -was part of a larger token. Finally, it did unnecessary work. By using -asprintf() to create the string, the function can be signifcantly -simplified. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/structs.c | 49 +++++++++++++++++++++--------------------- - 1 file changed, 24 insertions(+), 25 deletions(-) - -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 471087e2..84f9c959 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -572,23 +572,33 @@ int add_feature(char **f, const char *n) - { - int c = 0, d, l; - char *e, *t; -+ const char *p; - - if (!f) - return 1; - - /* Nothing to do */ -- if (!n || *n == '0') -+ if (!n || *n == '\0') - return 0; - -- if (strchr(n, ' ') != NULL) { -- condlog(0, "internal error: feature \"%s\" contains spaces", n); -+ l = strlen(n); -+ if (isspace(*n) || isspace(*(n + l - 1))) { -+ condlog(0, "internal error: feature \"%s\" has leading or trailing spaces", n); - return 1; - } - -+ p = n; -+ d = 1; -+ while (*p != '\0') { -+ if (isspace(*p) && !isspace(*(p + 1)) && *(p + 1) != '\0') -+ d++; -+ p++; -+ } -+ - /* default feature is null */ - if(!*f) - { -- l = asprintf(&t, "1 %s", n); -+ l = asprintf(&t, "%0d %s", d, n); - if(l == -1) - return 1; - -@@ -597,35 +607,24 @@ int add_feature(char **f, const char *n) - } - - /* Check if feature is already present */ -- if (strstr(*f, n)) -- return 0; -+ e = *f; -+ while ((e = strstr(e, n)) != NULL) { -+ if (isspace(*(e - 1)) && -+ (isspace(*(e + l)) || *(e + l) == '\0')) -+ return 0; -+ e += l; -+ } - - /* Get feature count */ - c = strtoul(*f, &e, 10); -- if (*f == e || (*e != ' ' && *e != '\0')) { -+ if (*f == e || (!isspace(*e) && *e != '\0')) { - condlog(0, "parse error in feature string \"%s\"", *f); - return 1; - } -- -- /* Add 1 digit and 1 space */ -- l = strlen(e) + strlen(n) + 2; -- -- c++; -- /* Check if we need more digits for feature count */ -- for (d = c; d >= 10; d /= 10) -- l++; -- -- t = MALLOC(l + 1); -- if (!t) -+ c += d; -+ if (asprintf(&t, "%0d%s %s", c, e, n) < 0) - return 1; - -- /* e: old feature string with leading space, or "" */ -- if (*e == ' ') -- while (*(e + 1) == ' ') -- e++; -- -- snprintf(t, l + 1, "%0d%s %s", c, e, n); -- - FREE(*f); - *f = t; - diff --git a/SOURCES/0119-multipath-tests-tests-for-adding-and-removing-featur.patch b/SOURCES/0119-multipath-tests-tests-for-adding-and-removing-featur.patch deleted file mode 100644 index d450d48..0000000 --- a/SOURCES/0119-multipath-tests-tests-for-adding-and-removing-featur.patch +++ /dev/null @@ -1,350 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:39 -0500 -Subject: [PATCH] multipath tests: tests for adding and removing features - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - tests/Makefile | 2 +- - tests/features.c | 318 +++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 319 insertions(+), 1 deletion(-) - create mode 100644 tests/features.c - -diff --git a/tests/Makefile b/tests/Makefile -index 77ff3249..914413b8 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio -+ alias directio features - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -diff --git a/tests/features.c b/tests/features.c -new file mode 100644 -index 00000000..1e2e6bff ---- /dev/null -+++ b/tests/features.c -@@ -0,0 +1,318 @@ -+#include -+#include -+#include -+#include -+ -+#include "structs.h" -+#include "globals.c" -+ -+static void test_af_null_features_ptr(void **state) -+{ -+ assert_int_equal(add_feature(NULL, "test"), 1); -+} -+ -+static void af_helper(const char *features_start, const char *addition, -+ const char *features_end, int result) -+{ -+ char *f = NULL, *orig = NULL; -+ -+ if (features_start) { -+ f = strdup(features_start); -+ assert_non_null(f); -+ orig = f; -+ } -+ assert_int_equal(add_feature(&f, addition), result); -+ if (result != 0 || features_end == NULL) -+ assert_ptr_equal(orig, f); -+ else -+ assert_string_equal(f, features_end); -+ free(f); -+} -+ -+static void test_af_null_addition1(void **state) -+{ -+ af_helper("0", NULL, NULL, 0); -+} -+ -+static void test_af_null_addition2(void **state) -+{ -+ af_helper("1 queue_if_no_path", NULL, NULL, 0); -+} -+ -+static void test_af_empty_addition(void **state) -+{ -+ af_helper("2 pg_init_retries 5", "", NULL, 0); -+} -+ -+static void test_af_invalid_addition1(void **state) -+{ -+ af_helper("2 pg_init_retries 5", " ", NULL, 1); -+} -+ -+static void test_af_invalid_addition2(void **state) -+{ -+ af_helper("2 pg_init_retries 5", "\tbad", NULL, 1); -+} -+ -+static void test_af_invalid_addition3(void **state) -+{ -+ af_helper("2 pg_init_retries 5", "bad ", NULL, 1); -+} -+ -+static void test_af_invalid_addition4(void **state) -+{ -+ af_helper("2 pg_init_retries 5", " bad ", NULL, 1); -+} -+ -+static void test_af_null_features1(void **state) -+{ -+ af_helper(NULL, "test", "1 test", 0); -+} -+ -+static void test_af_null_features2(void **state) -+{ -+ af_helper(NULL, "test\t more", "2 test\t more", 0); -+} -+ -+static void test_af_null_features3(void **state) -+{ -+ af_helper(NULL, "test\neven\tmore", "3 test\neven\tmore", 0); -+} -+ -+static void test_af_already_exists1(void **state) -+{ -+ af_helper("4 this is a test", "test", NULL, 0); -+} -+ -+static void test_af_already_exists2(void **state) -+{ -+ af_helper("5 contest testy intestine test retest", "test", NULL, 0); -+} -+ -+static void test_af_almost_exists(void **state) -+{ -+ af_helper("3 contest testy intestine", "test", -+ "4 contest testy intestine test", 0); -+} -+ -+static void test_af_bad_features1(void **state) -+{ -+ af_helper("bad", "test", NULL, 1); -+} -+ -+static void test_af_bad_features2(void **state) -+{ -+ af_helper("1bad", "test", NULL, 1); -+} -+ -+static void test_af_add1(void **state) -+{ -+ af_helper("0", "test", "1 test", 0); -+} -+ -+static void test_af_add2(void **state) -+{ -+ af_helper("0", "this is a test", "4 this is a test", 0); -+} -+ -+static void test_af_add3(void **state) -+{ -+ af_helper("1 features", "more values", "3 features more values", 0); -+} -+ -+static void test_af_add4(void **state) -+{ -+ af_helper("2 one\ttwo", "three\t four", "4 one\ttwo three\t four", 0); -+} -+ -+static int test_add_features(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_af_null_features_ptr), -+ cmocka_unit_test(test_af_null_addition1), -+ cmocka_unit_test(test_af_null_addition2), -+ cmocka_unit_test(test_af_empty_addition), -+ cmocka_unit_test(test_af_invalid_addition1), -+ cmocka_unit_test(test_af_invalid_addition2), -+ cmocka_unit_test(test_af_invalid_addition3), -+ cmocka_unit_test(test_af_invalid_addition4), -+ cmocka_unit_test(test_af_null_features1), -+ cmocka_unit_test(test_af_null_features2), -+ cmocka_unit_test(test_af_null_features3), -+ cmocka_unit_test(test_af_already_exists1), -+ cmocka_unit_test(test_af_already_exists2), -+ cmocka_unit_test(test_af_almost_exists), -+ cmocka_unit_test(test_af_bad_features1), -+ cmocka_unit_test(test_af_bad_features2), -+ cmocka_unit_test(test_af_add1), -+ cmocka_unit_test(test_af_add2), -+ cmocka_unit_test(test_af_add3), -+ cmocka_unit_test(test_af_add4), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ -+static void test_rf_null_features_ptr(void **state) -+{ -+ assert_int_equal(remove_feature(NULL, "test"), 1); -+} -+ -+static void test_rf_null_features(void **state) -+{ -+ char *f = NULL; -+ assert_int_equal(remove_feature(&f, "test"), 1); -+} -+ -+static void rf_helper(const char *features_start, const char *removal, -+ const char *features_end, int result) -+{ -+ char *f = strdup(features_start); -+ char *orig = f; -+ -+ assert_non_null(f); -+ assert_int_equal(remove_feature(&f, removal), result); -+ if (result != 0 || features_end == NULL) -+ assert_ptr_equal(orig, f); -+ else -+ assert_string_equal(f, features_end); -+ free(f); -+} -+ -+static void test_rf_null_removal(void **state) -+{ -+ rf_helper("1 feature", NULL, NULL, 0); -+} -+ -+static void test_rf_empty_removal(void **state) -+{ -+ rf_helper("1 feature", "", NULL, 0); -+} -+ -+static void test_rf_invalid_removal1(void **state) -+{ -+ rf_helper("1 feature", " ", NULL, 1); -+} -+ -+static void test_rf_invalid_removal2(void **state) -+{ -+ rf_helper("1 feature", " bad", NULL, 1); -+} -+ -+static void test_rf_invalid_removal3(void **state) -+{ -+ rf_helper("1 feature", "bad\n", NULL, 1); -+} -+ -+static void test_rf_invalid_removal4(void **state) -+{ -+ rf_helper("1 feature", "\tbad \n", NULL, 1); -+} -+ -+static void test_rf_bad_features1(void **state) -+{ -+ rf_helper("invalid feature test string", "test", NULL, 1); -+} -+ -+static void test_rf_bad_features2(void **state) -+{ -+ rf_helper("2no space test", "test", NULL, 1); -+} -+ -+static void test_rf_missing_removal1(void **state) -+{ -+ rf_helper("0", "test", NULL, 0); -+} -+ -+static void test_rf_missing_removal2(void **state) -+{ -+ rf_helper("1 detest", "test", NULL, 0); -+} -+ -+static void test_rf_missing_removal3(void **state) -+{ -+ rf_helper("4 testing one two three", "test", NULL, 0); -+} -+ -+static void test_rf_missing_removal4(void **state) -+{ -+ rf_helper("1 contestant", "test", NULL, 0); -+} -+ -+static void test_rf_missing_removal5(void **state) -+{ -+ rf_helper("3 testament protest detestable", "test", NULL, 0); -+} -+ -+static void test_rf_remove_all_features1(void **state) -+{ -+ rf_helper("1 test", "test", "0", 0); -+} -+ -+static void test_rf_remove_all_features2(void **state) -+{ -+ rf_helper("2 another\t test", "another\t test", "0", 0); -+} -+ -+static void test_rf_remove1(void **state) -+{ -+ rf_helper("2 feature1 feature2", "feature2", "1 feature1", 0); -+} -+ -+static void test_rf_remove2(void **state) -+{ -+ rf_helper("2 feature1 feature2", "feature1", "1 feature2", 0); -+} -+ -+static void test_rf_remove3(void **state) -+{ -+ rf_helper("3 test1 test\ttest2", "test", "2 test1 test2", 0); -+} -+ -+static void test_rf_remove4(void **state) -+{ -+ rf_helper("4 this\t is a test", "is a", "2 this\t test", 0); -+} -+ -+static void test_rf_remove5(void **state) -+{ -+ rf_helper("3 one more test", "more test", "1 one", 0); -+} -+ -+static int test_remove_features(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_rf_null_features_ptr), -+ cmocka_unit_test(test_rf_null_features), -+ cmocka_unit_test(test_rf_null_removal), -+ cmocka_unit_test(test_rf_empty_removal), -+ cmocka_unit_test(test_rf_invalid_removal1), -+ cmocka_unit_test(test_rf_invalid_removal2), -+ cmocka_unit_test(test_rf_invalid_removal3), -+ cmocka_unit_test(test_rf_invalid_removal4), -+ cmocka_unit_test(test_rf_bad_features1), -+ cmocka_unit_test(test_rf_bad_features2), -+ cmocka_unit_test(test_rf_missing_removal1), -+ cmocka_unit_test(test_rf_missing_removal2), -+ cmocka_unit_test(test_rf_missing_removal3), -+ cmocka_unit_test(test_rf_missing_removal4), -+ cmocka_unit_test(test_rf_missing_removal5), -+ cmocka_unit_test(test_rf_remove_all_features1), -+ cmocka_unit_test(test_rf_remove_all_features2), -+ cmocka_unit_test(test_rf_remove1), -+ cmocka_unit_test(test_rf_remove2), -+ cmocka_unit_test(test_rf_remove3), -+ cmocka_unit_test(test_rf_remove4), -+ cmocka_unit_test(test_rf_remove5), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ -+ ret += test_add_features(); -+ ret += test_remove_features(); -+ -+ return ret; -+} diff --git a/SOURCES/0120-libmultipath-fix-queue_mode-feature-handling.patch b/SOURCES/0120-libmultipath-fix-queue_mode-feature-handling.patch deleted file mode 100644 index b5b8b02..0000000 --- a/SOURCES/0120-libmultipath-fix-queue_mode-feature-handling.patch +++ /dev/null @@ -1,212 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:40 -0500 -Subject: [PATCH] libmultipath: fix queue_mode feature handling - -device-mapper is not able to change the queue_mode on a table reload. -Make sure that when multipath sets up the map, both on regular reloads -and reconfigures, it keeps the queue_mode the same. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 4 +++ - libmultipath/dmparser.c | 2 ++ - libmultipath/propsel.c | 55 ++++++++++++++++++++++++++++++++++++++ - libmultipath/structs.h | 7 +++++ - libmultipath/util.c | 10 +++++++ - libmultipath/util.h | 1 + - multipath/multipath.conf.5 | 7 +++-- - 7 files changed, 84 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6cad0468..287289f7 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1102,6 +1102,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - uint64_t *size_mismatch_seen; - bool map_processed = false; - bool no_daemon = false; -+ struct multipath * cmpp; - - /* ignore refwwid if it's empty */ - if (refwwid && !strlen(refwwid)) -@@ -1197,6 +1198,9 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - } - verify_paths(mpp, vecs); - -+ cmpp = find_mp_by_wwid(curmp, mpp->wwid); -+ if (cmpp) -+ mpp->queue_mode = cmpp->queue_mode; - params[0] = '\0'; - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { - remove_map(mpp, vecs, 0); -diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c -index b856a07f..b9c4dabc 100644 ---- a/libmultipath/dmparser.c -+++ b/libmultipath/dmparser.c -@@ -164,6 +164,8 @@ int disassemble_map(vector pathvec, char *params, struct multipath *mpp, - - FREE(word); - } -+ mpp->queue_mode = strstr(mpp->features, "queue_mode bio") ? -+ QUEUE_MODE_BIO : QUEUE_MODE_RQ; - - /* - * hwhandler -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index be79902f..3f119dd9 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -26,6 +26,7 @@ - #include "propsel.h" - #include - #include -+#include - - pgpolicyfn *pgpolicies[] = { - NULL, -@@ -413,6 +414,59 @@ void reconcile_features_with_options(const char *id, char **features, int* no_pa - } - } - -+static void reconcile_features_with_queue_mode(struct multipath *mp) -+{ -+ char *space = NULL, *val = NULL, *mode_str = NULL, *feat; -+ int features_mode = QUEUE_MODE_UNDEF; -+ -+ if (!mp->features) -+ return; -+ -+ pthread_cleanup_push(cleanup_free_ptr, &space); -+ pthread_cleanup_push(cleanup_free_ptr, &val); -+ pthread_cleanup_push(cleanup_free_ptr, &mode_str); -+ -+ if (!(feat = strstr(mp->features, "queue_mode")) || -+ feat == mp->features || !isspace(*(feat - 1)) || -+ sscanf(feat, "queue_mode%m[ \f\n\r\t\v]%ms", &space, &val) != 2) -+ goto sync_mode; -+ if (asprintf(&mode_str, "queue_mode%s%s", space, val) < 0) { -+ condlog(1, "failed to allocate space for queue_mode feature string"); -+ mode_str = NULL; /* value undefined on failure */ -+ goto exit; -+ } -+ -+ if (!strcmp(val, "rq") || !strcmp(val, "mq")) -+ features_mode = QUEUE_MODE_RQ; -+ else if (!strcmp(val, "bio")) -+ features_mode = QUEUE_MODE_BIO; -+ if (features_mode == QUEUE_MODE_UNDEF) { -+ condlog(2, "%s: ignoring invalid feature '%s'", -+ mp->alias, mode_str); -+ goto sync_mode; -+ } -+ -+ if (mp->queue_mode == QUEUE_MODE_UNDEF) -+ mp->queue_mode = features_mode; -+ if (mp->queue_mode == features_mode) -+ goto exit; -+ -+ condlog(2, -+ "%s: ignoring feature '%s' because queue_mode is set to '%s'", -+ mp->alias, mode_str, -+ (mp->queue_mode == QUEUE_MODE_RQ)? "rq" : "bio"); -+ -+sync_mode: -+ if (mode_str) -+ remove_feature(&mp->features, mode_str); -+ if (mp->queue_mode == QUEUE_MODE_BIO) -+ add_feature(&mp->features, "queue_mode bio"); -+exit: -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+ pthread_cleanup_pop(1); -+} -+ - int select_features(struct config *conf, struct multipath *mp) - { - const char *origin; -@@ -428,6 +482,7 @@ out: - reconcile_features_with_options(mp->alias, &mp->features, - &mp->no_path_retry, - &mp->retain_hwhandler); -+ reconcile_features_with_queue_mode(mp); - condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin); - return 0; - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 3ed5cfc1..9a404da7 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -187,6 +187,12 @@ enum max_sectors_kb_states { - MAX_SECTORS_KB_MIN = 4, /* can't be smaller than page size */ - }; - -+enum queue_mode_states { -+ QUEUE_MODE_UNDEF = 0, -+ QUEUE_MODE_BIO, -+ QUEUE_MODE_RQ, -+}; -+ - enum scsi_protocol { - SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ - SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ -@@ -397,6 +403,7 @@ struct multipath { - int needs_paths_uevent; - int ghost_delay; - int ghost_delay_tick; -+ int queue_mode; - uid_t uid; - gid_t gid; - mode_t mode; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index dd30a46e..e04d20ab 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -465,6 +465,16 @@ void free_scandir_result(struct scandir_result *res) - FREE(res->di); - } - -+void cleanup_free_ptr(void *arg) -+{ -+ void **p = arg; -+ -+ if (p && *p) { -+ free(*p); -+ *p = NULL; -+ } -+} -+ - void close_fd(void *arg) - { - close((long)arg); -diff --git a/libmultipath/util.h b/libmultipath/util.h -index ce277680..f898c829 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -44,6 +44,7 @@ void set_max_fds(rlim_t max_fds); - pthread_cleanup_push(((void (*)(void *))&f), (arg)) - - void close_fd(void *arg); -+void cleanup_free_ptr(void *arg); - void cleanup_mutex(void *arg); - - struct scandir_result { -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 8e418372..61d2712b 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -458,8 +458,11 @@ precedence. See KNOWN ISSUES. - can be \fIbio\fR, \fIrq\fR or \fImq\fR, which corresponds to - bio-based, request-based, and block-multiqueue (blk-mq) request-based, - respectively. --The default depends on the kernel parameter \fBdm_mod.use_blk_mq\fR. It is --\fImq\fR if the latter is set, and \fIrq\fR otherwise. -+Before kernel 4.20 The default depends on the kernel parameter -+\fBdm_mod.use_blk_mq\fR. It is \fImq\fR if the latter is set, and \fIrq\fR -+otherwise. Since kernel 4.20, \fIrq\fR and \fImq\fR both correspond to -+block-multiqueue. Once a multipath device has been created, its queue_mode -+cannot be changed. - .TP - The default is: \fB\fR - .RE diff --git a/SOURCES/0121-multipath-tests-tests-for-reconcile_features_with_qu.patch b/SOURCES/0121-multipath-tests-tests-for-reconcile_features_with_qu.patch deleted file mode 100644 index d8da724..0000000 --- a/SOURCES/0121-multipath-tests-tests-for-reconcile_features_with_qu.patch +++ /dev/null @@ -1,290 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:41 -0500 -Subject: [PATCH] multipath tests: tests for reconcile_features_with_queue_mode - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - tests/Makefile | 2 + - tests/features.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 233 insertions(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 914413b8..f3e49487 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -29,6 +29,7 @@ endif - ifneq ($(DIO_TEST_DEV),) - directio-test_FLAGS := -DDIO_TEST_DEV=\"$(DIO_TEST_DEV)\" - endif -+features-test_FLAGS := -I$(multipathdir)/nvme - - # test-specific linker flags - # XYZ-test_TESTDEPS: test libraries containing __wrap_xyz functions -@@ -53,6 +54,7 @@ alias-test_LIBDEPS := -lpthread -ldl - ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif -+features-test_LIBDEPS := -ludev -lpthread - - %.o: %.c - $(CC) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $< -diff --git a/tests/features.c b/tests/features.c -index 1e2e6bff..01fbccb7 100644 ---- a/tests/features.c -+++ b/tests/features.c -@@ -1,9 +1,10 @@ -+#define _GNU_SOURCE - #include - #include - #include - #include - --#include "structs.h" -+#include "../libmultipath/propsel.c" - #include "globals.c" - - static void test_af_null_features_ptr(void **state) -@@ -307,12 +308,241 @@ static int test_remove_features(void) - return cmocka_run_group_tests(tests, NULL, NULL); - } - -+static void test_cf_null_features(void **state) -+{ -+ struct multipath mp = { -+ .alias = "test", -+ }; -+ reconcile_features_with_queue_mode(&mp); -+ assert_null(mp.features); -+} -+ -+static void cf_helper(const char *features_start, const char *features_end, -+ int queue_mode_start, int queue_mode_end) -+{ -+ struct multipath mp = { -+ .alias = "test", -+ .features = strdup(features_start), -+ .queue_mode = queue_mode_start, -+ }; -+ char *orig = mp.features; -+ -+ assert_non_null(orig); -+ reconcile_features_with_queue_mode(&mp); -+ if (!features_end) -+ assert_ptr_equal(orig, mp.features); -+ else -+ assert_string_equal(mp.features, features_end); -+ free(mp.features); -+ assert_int_equal(mp.queue_mode, queue_mode_end); -+} -+ -+static void test_cf_unset_unset1(void **state) -+{ -+ cf_helper("0", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_unset_unset2(void **state) -+{ -+ cf_helper("1 queue_mode", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_unset_unset3(void **state) -+{ -+ cf_helper("queue_mode", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_unset_unset4(void **state) -+{ -+ cf_helper("2 queue_model bio", NULL, QUEUE_MODE_UNDEF, -+ QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_unset_unset5(void **state) -+{ -+ cf_helper("1 queue_if_no_path", NULL, QUEUE_MODE_UNDEF, -+ QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_invalid_unset1(void **state) -+{ -+ cf_helper("2 queue_mode biop", "0", QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_invalid_unset2(void **state) -+{ -+ cf_helper("3 queue_mode rqs queue_if_no_path", "1 queue_if_no_path", -+ QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF); -+} -+ -+static void test_cf_rq_unset1(void **state) -+{ -+ cf_helper("2 queue_mode rq", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_rq_unset2(void **state) -+{ -+ cf_helper("2 queue_mode mq", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_bio_unset(void **state) -+{ -+ cf_helper("2 queue_mode bio", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_unset_bio1(void **state) -+{ -+ cf_helper("1 queue_if_no_path", "3 queue_if_no_path queue_mode bio", -+ QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_unset_bio2(void **state) -+{ -+ cf_helper("0", "2 queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_unset_bio3(void **state) -+{ -+ cf_helper("2 pg_init_retries 50", "4 pg_init_retries 50 queue_mode bio", -+ QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_invalid_bio1(void **state) -+{ -+ cf_helper("2 queue_mode bad", "2 queue_mode bio", -+ QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_invalid_bio2(void **state) -+{ -+ cf_helper("3 queue_if_no_path queue_mode\tbad", "3 queue_if_no_path queue_mode bio", -+ QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_bio_bio1(void **state) -+{ -+ cf_helper("2 queue_mode bio", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_bio_bio2(void **state) -+{ -+ cf_helper("3 queue_if_no_path queue_mode bio", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_bio_bio3(void **state) -+{ -+ cf_helper("3 queue_mode\nbio queue_if_no_path", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_bio_rq1(void **state) -+{ -+ cf_helper("2\nqueue_mode\tbio", "0", QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_bio_rq2(void **state) -+{ -+ cf_helper("3 queue_if_no_path\nqueue_mode bio", "1 queue_if_no_path", -+ QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_bio_rq3(void **state) -+{ -+ cf_helper("4 queue_mode bio pg_init_retries 20", "2 pg_init_retries 20", -+ QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_unset_rq1(void **state) -+{ -+ cf_helper("0", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_unset_rq2(void **state) -+{ -+ cf_helper("2 pg_init_retries 15", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_invalid_rq1(void **state) -+{ -+ cf_helper("2 queue_mode bionic", "0", QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_invalid_rq2(void **state) -+{ -+ cf_helper("3 queue_mode b\nqueue_if_no_path", "1 queue_if_no_path", -+ QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_rq_rq1(void **state) -+{ -+ cf_helper("2 queue_mode rq", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_rq_rq2(void **state) -+{ -+ cf_helper("3 queue_mode\t \trq\nqueue_if_no_path", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ); -+} -+ -+static void test_cf_rq_bio1(void **state) -+{ -+ cf_helper("2 queue_mode rq", "2 queue_mode bio", QUEUE_MODE_BIO, -+ QUEUE_MODE_BIO); -+} -+ -+static void test_cf_rq_bio2(void **state) -+{ -+ cf_helper("3 queue_if_no_path\nqueue_mode rq", "3 queue_if_no_path queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static void test_cf_rq_bio3(void **state) -+{ -+ cf_helper("3 queue_mode rq\nqueue_if_no_path", "3 queue_if_no_path queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO); -+} -+ -+static int test_reconcile_features(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_cf_null_features), -+ cmocka_unit_test(test_cf_unset_unset1), -+ cmocka_unit_test(test_cf_unset_unset2), -+ cmocka_unit_test(test_cf_unset_unset3), -+ cmocka_unit_test(test_cf_unset_unset4), -+ cmocka_unit_test(test_cf_unset_unset5), -+ cmocka_unit_test(test_cf_invalid_unset1), -+ cmocka_unit_test(test_cf_invalid_unset2), -+ cmocka_unit_test(test_cf_rq_unset1), -+ cmocka_unit_test(test_cf_rq_unset2), -+ cmocka_unit_test(test_cf_bio_unset), -+ cmocka_unit_test(test_cf_unset_bio1), -+ cmocka_unit_test(test_cf_unset_bio2), -+ cmocka_unit_test(test_cf_unset_bio3), -+ cmocka_unit_test(test_cf_invalid_bio1), -+ cmocka_unit_test(test_cf_invalid_bio2), -+ cmocka_unit_test(test_cf_bio_bio1), -+ cmocka_unit_test(test_cf_bio_bio2), -+ cmocka_unit_test(test_cf_bio_bio3), -+ cmocka_unit_test(test_cf_bio_rq1), -+ cmocka_unit_test(test_cf_bio_rq2), -+ cmocka_unit_test(test_cf_bio_rq3), -+ cmocka_unit_test(test_cf_unset_rq1), -+ cmocka_unit_test(test_cf_unset_rq2), -+ cmocka_unit_test(test_cf_invalid_rq1), -+ cmocka_unit_test(test_cf_invalid_rq2), -+ cmocka_unit_test(test_cf_rq_rq1), -+ cmocka_unit_test(test_cf_rq_rq2), -+ cmocka_unit_test(test_cf_rq_bio1), -+ cmocka_unit_test(test_cf_rq_bio2), -+ cmocka_unit_test(test_cf_rq_bio3), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ - int main(void) - { - int ret = 0; - - ret += test_add_features(); - ret += test_remove_features(); -+ ret += test_reconcile_features(); - - return ret; - } diff --git a/SOURCES/0122-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch b/SOURCES/0122-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch deleted file mode 100644 index b725c15..0000000 --- a/SOURCES/0122-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:42 -0500 -Subject: [PATCH] libmultipath: prepare proto_id for use by non-scsi devivces - -Make sure that when we are checking for a scsi protocol, we are first -checking that we are working with a scsi path. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 9 +++++---- - libmultipath/discovery.c | 13 ++++++++----- - libmultipath/print.c | 6 ++++-- - libmultipath/structs.c | 2 +- - libmultipath/structs.h | 4 +++- - multipathd/fpin_handlers.c | 2 +- - 6 files changed, 22 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 287289f7..8e1bc488 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -223,10 +223,11 @@ int rr_optimize_path_order(struct pathgroup *pgp) - - total_paths = VECTOR_SIZE(pgp->paths); - vector_foreach_slot(pgp->paths, pp, i) { -- if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP && -- pp->sg_id.proto_id != SCSI_PROTOCOL_SAS && -- pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI && -- pp->sg_id.proto_id != SCSI_PROTOCOL_SRP) { -+ if (pp->bus != SYSFS_BUS_SCSI || -+ (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP && -+ pp->sg_id.proto_id != SCSI_PROTOCOL_SAS && -+ pp->sg_id.proto_id != SCSI_PROTOCOL_ISCSI && -+ pp->sg_id.proto_id != SCSI_PROTOCOL_SRP)) { - /* return success as default path order - * is maintained in path group - */ -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 36cc389e..5f4e0794 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -468,10 +468,11 @@ int sysfs_get_host_adapter_name(const struct path *pp, char *adapter_name) - - proto_id = pp->sg_id.proto_id; - -- if (proto_id != SCSI_PROTOCOL_FCP && -- proto_id != SCSI_PROTOCOL_SAS && -- proto_id != SCSI_PROTOCOL_ISCSI && -- proto_id != SCSI_PROTOCOL_SRP) { -+ if (pp->bus != SYSFS_BUS_SCSI || -+ (proto_id != SCSI_PROTOCOL_FCP && -+ proto_id != SCSI_PROTOCOL_SAS && -+ proto_id != SCSI_PROTOCOL_ISCSI && -+ proto_id != SCSI_PROTOCOL_SRP)) { - return 1; - } - /* iscsi doesn't have adapter info in sysfs -@@ -1722,8 +1723,10 @@ sysfs_pathinfo(struct path * pp, vector hwtable) - pp->bus = SYSFS_BUS_CCISS; - if (!strncmp(pp->dev,"dasd", 4)) - pp->bus = SYSFS_BUS_CCW; -- if (!strncmp(pp->dev,"sd", 2)) -+ if (!strncmp(pp->dev,"sd", 2)) { - pp->bus = SYSFS_BUS_SCSI; -+ pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC; -+ } - if (!strncmp(pp->dev,"nvme", 4)) - pp->bus = SYSFS_BUS_NVME; - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 8a6fbe83..8a85df66 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -558,7 +558,8 @@ snprint_host_attr (char * buff, size_t len, const struct path * pp, char *attr) - const char *value = NULL; - int ret; - -- if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) -+ if (pp->bus != SYSFS_BUS_SCSI || -+ pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) - return snprintf(buff, len, "[undef]"); - sprintf(host_id, "host%d", pp->sg_id.host_no); - host_dev = udev_device_new_from_subsystem_sysname(udev, "fc_host", -@@ -597,7 +598,8 @@ snprint_tgt_wwpn (char * buff, size_t len, const struct path * pp) - const char *value = NULL; - int ret; - -- if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) -+ if (pp->bus != SYSFS_BUS_SCSI || -+ pp->sg_id.proto_id != SCSI_PROTOCOL_FCP) - return snprintf(buff, len, "[undef]"); - sprintf(rport_id, "rport-%d:%d-%d", - pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 84f9c959..1122cfae 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -115,7 +115,7 @@ alloc_path (void) - pp->sg_id.channel = -1; - pp->sg_id.scsi_id = -1; - pp->sg_id.lun = -1; -- pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC; -+ pp->sg_id.proto_id = PROTOCOL_UNSET; - pp->fd = -1; - pp->tpgs = TPGS_UNDEF; - pp->priority = PRIO_UNDEF; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9a404da7..960ea024 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -193,6 +193,8 @@ enum queue_mode_states { - QUEUE_MODE_RQ, - }; - -+#define PROTOCOL_UNSET -1 -+ - enum scsi_protocol { - SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ - SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ -@@ -294,7 +296,7 @@ struct sg_id { - int lun; - short h_cmd_per_lun; - short d_queue_depth; -- enum scsi_protocol proto_id; -+ int proto_id; - int transport_id; - }; - -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index b14366d7..599f2893 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -220,7 +220,7 @@ static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *ve - - vector_foreach_slot(vecs->pathvec, pp, k) { - /* Checks the host number and also for the SCSI FCP */ -- if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) -+ if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) - continue; - sprintf(rport_id, "rport-%d:%d-%d", - pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); diff --git a/SOURCES/0123-libmultipath-get-nvme-path-transport-protocol.patch b/SOURCES/0123-libmultipath-get-nvme-path-transport-protocol.patch deleted file mode 100644 index b64c392..0000000 --- a/SOURCES/0123-libmultipath-get-nvme-path-transport-protocol.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:43 -0500 -Subject: [PATCH] libmultipath: get nvme path transport protocol - -Read the transport protocol from /sys/block/nvmeXnY/device/transport. -Update protocol_name[] and bus_protocol_id() to store the nvme protocol -names after the scsi protocol names. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/discovery.c | 18 ++++++++++++++++-- - libmultipath/structs.c | 22 +++++++++++++++++----- - libmultipath/structs.h | 33 +++++++++++++++++++++------------ - multipath/multipath.conf.5 | 10 +++++++--- - 4 files changed, 61 insertions(+), 22 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 5f4e0794..eb7a634b 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1455,6 +1455,7 @@ nvme_sysfs_pathinfo (struct path * pp, vector hwtable) - struct udev_device *parent; - const char *attr_path = NULL; - const char *attr; -+ int i; - - attr_path = udev_device_get_sysname(pp->udev); - if (!attr_path) -@@ -1476,6 +1477,18 @@ nvme_sysfs_pathinfo (struct path * pp, vector hwtable) - attr = udev_device_get_sysattr_value(parent, "cntlid"); - pp->sg_id.channel = attr ? atoi(attr) : 0; - -+ attr = udev_device_get_sysattr_value(parent, "transport"); -+ if (attr) { -+ for (i = 0; i < NVME_PROTOCOL_UNSPEC; i++){ -+ if (protocol_name[SYSFS_BUS_NVME + i] && -+ !strcmp(attr, -+ protocol_name[SYSFS_BUS_NVME + i] + 5)) { -+ pp->sg_id.proto_id = i; -+ break; -+ } -+ } -+ } -+ - snprintf(pp->vendor_id, SCSI_VENDOR_SIZE, "NVME"); - snprintf(pp->product_id, PATH_PRODUCT_SIZE, "%s", - udev_device_get_sysattr_value(parent, "model")); -@@ -1727,9 +1740,10 @@ sysfs_pathinfo(struct path * pp, vector hwtable) - pp->bus = SYSFS_BUS_SCSI; - pp->sg_id.proto_id = SCSI_PROTOCOL_UNSPEC; - } -- if (!strncmp(pp->dev,"nvme", 4)) -+ if (!strncmp(pp->dev,"nvme", 4)) { - pp->bus = SYSFS_BUS_NVME; -- -+ pp->sg_id.proto_id = NVME_PROTOCOL_UNSPEC; -+ } - switch (pp->bus) { - case SYSFS_BUS_SCSI: - return scsi_sysfs_pathinfo(pp, hwtable); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 1122cfae..7bdf9152 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -25,7 +25,6 @@ const char * const protocol_name[LAST_BUS_PROTOCOL_ID + 1] = { - [SYSFS_BUS_UNDEF] = "undef", - [SYSFS_BUS_CCW] = "ccw", - [SYSFS_BUS_CCISS] = "cciss", -- [SYSFS_BUS_NVME] = "nvme", - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_FCP] = "scsi:fcp", - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SPI] = "scsi:spi", - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_SSA] = "scsi:ssa", -@@ -37,6 +36,13 @@ const char * const protocol_name[LAST_BUS_PROTOCOL_ID + 1] = { - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_ATA] = "scsi:ata", - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_USB] = "scsi:usb", - [SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC] = "scsi:unspec", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_PCIE] = "nvme:pcie", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_RDMA] = "nvme:rdma", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_FC] = "nvme:fc", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_TCP] = "nvme:tcp", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_LOOP] = "nvme:loop", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_APPLE_NVME] = "nvme:apple-nvme", -+ [SYSFS_BUS_NVME + NVME_PROTOCOL_UNSPEC] = "nvme:unspec", - }; - - struct adapter_group * -@@ -716,11 +722,17 @@ out: - } - - unsigned int bus_protocol_id(const struct path *pp) { -- if (!pp || pp->bus < 0 || pp->bus > SYSFS_BUS_SCSI) -+ if (!pp || pp->bus < 0 || pp->bus > SYSFS_BUS_NVME) - return SYSFS_BUS_UNDEF; -- if (pp->bus != SYSFS_BUS_SCSI) -+ if (pp->bus != SYSFS_BUS_SCSI && pp->bus != SYSFS_BUS_NVME) - return pp->bus; -- if ((int)pp->sg_id.proto_id < 0 || pp->sg_id.proto_id > SCSI_PROTOCOL_UNSPEC) -+ if (pp->sg_id.proto_id < 0) - return SYSFS_BUS_UNDEF; -- return SYSFS_BUS_SCSI + pp->sg_id.proto_id; -+ if (pp->bus == SYSFS_BUS_SCSI && -+ pp->sg_id.proto_id > SCSI_PROTOCOL_UNSPEC) -+ return SYSFS_BUS_UNDEF; -+ if (pp->bus == SYSFS_BUS_NVME && -+ pp->sg_id.proto_id > NVME_PROTOCOL_UNSPEC) -+ return SYSFS_BUS_UNDEF; -+ return pp->bus + pp->sg_id.proto_id; - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 960ea024..9130efb5 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -57,15 +57,6 @@ enum failback_mode { - FAILBACK_FOLLOWOVER - }; - --/* SYSFS_BUS_SCSI should be last, see bus_protocol_id() */ --enum sysfs_buses { -- SYSFS_BUS_UNDEF, -- SYSFS_BUS_CCW, -- SYSFS_BUS_CCISS, -- SYSFS_BUS_NVME, -- SYSFS_BUS_SCSI, --}; -- - enum pathstates { - PSTATE_UNDEF, - PSTATE_FAILED, -@@ -207,14 +198,32 @@ enum scsi_protocol { - SCSI_PROTOCOL_ATA = 8, - SCSI_PROTOCOL_USB = 9, /* USB Attached SCSI (UAS), and others */ - SCSI_PROTOCOL_UNSPEC = 0xa, /* No specific protocol */ -+ SCSI_PROTOCOL_END = 0xb, /* offset of the next sysfs_buses entry */ -+}; -+ -+/* values from /sys/class/nvme/nvmeX */ -+enum nvme_protocol { -+ NVME_PROTOCOL_PCIE = 0, -+ NVME_PROTOCOL_RDMA = 1, -+ NVME_PROTOCOL_FC = 2, -+ NVME_PROTOCOL_TCP = 3, -+ NVME_PROTOCOL_LOOP = 4, -+ NVME_PROTOCOL_APPLE_NVME = 5, -+ NVME_PROTOCOL_UNSPEC = 6, /* unknown protocol */ -+}; -+ -+enum sysfs_buses { -+ SYSFS_BUS_UNDEF, -+ SYSFS_BUS_CCW, -+ SYSFS_BUS_CCISS, -+ SYSFS_BUS_SCSI, -+ SYSFS_BUS_NVME = SYSFS_BUS_SCSI + SCSI_PROTOCOL_END, - }; - - /* - * Linear ordering of bus/protocol -- * This assumes that SYSFS_BUS_SCSI is last in enum sysfs_buses -- * SCSI is the only bus type for which we distinguish protocols. - */ --#define LAST_BUS_PROTOCOL_ID (SYSFS_BUS_SCSI + SCSI_PROTOCOL_UNSPEC) -+#define LAST_BUS_PROTOCOL_ID (SYSFS_BUS_NVME + NVME_PROTOCOL_UNSPEC) - unsigned int bus_protocol_id(const struct path *pp); - extern const char * const protocol_name[]; - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 61d2712b..1f5a40b6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1369,7 +1369,9 @@ Regular expression for the protocol of a device to be excluded/included. - The protocol strings that multipath recognizes are \fIscsi:fcp\fR, - \fIscsi:spi\fR, \fIscsi:ssa\fR, \fIscsi:sbp\fR, \fIscsi:srp\fR, - \fIscsi:iscsi\fR, \fIscsi:sas\fR, \fIscsi:adt\fR, \fIscsi:ata\fR, --\fIscsi:unspec\fR, \fIccw\fR, \fIcciss\fR, \fInvme\fR, and \fIundef\fR. -+\fIscsi:unspec\fR, \fInvme:pcie\fR, \fInvme:rdma\fR, \fInvme:fc\fR, -+\fInvme:tcp\fR, \fInvme:loop\fR, \fInvme:apple-nvme\fR, \fInvme:unspec\fR, -+\fIccw\fR, \fIcciss\fR, and \fIundef\fR. - The protocol that a path is using can be viewed by running - \fBmultipathd show paths format "%d %P"\fR - .RE -@@ -1757,8 +1759,10 @@ The protocol subsection recognizes the following mandatory attribute: - The protocol string of the path device. The possible values are \fIscsi:fcp\fR, - \fIscsi:spi\fR, \fIscsi:ssa\fR, \fIscsi:sbp\fR, \fIscsi:srp\fR, - \fIscsi:iscsi\fR, \fIscsi:sas\fR, \fIscsi:adt\fR, \fIscsi:ata\fR, --\fIscsi:unspec\fR, \fIccw\fR, \fIcciss\fR, \fInvme\fR, and \fIundef\fR. This is --\fBnot\fR a regular expression. the path device protcol string must match -+\fIscsi:unspec\fR, \fInvme:pcie\fR, \fInvme:rdma\fR, \fInvme:fc\fR, -+\fInvme:tcp\fR, \fInvme:loop\fR, \fInvme:apple-nvme\fR, \fInvme:unspec\fR, -+\fIccw\fR, \fIcciss\fR, and \fIundef\fR. This is -+\fBnot\fR a regular expression. the path device protocol string must match - exactly. The protocol that a path is using can be viewed by running - \fBmultipathd show paths format "%d %P"\fR - .LP diff --git a/SOURCES/0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch b/SOURCES/0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch deleted file mode 100644 index 61169b6..0000000 --- a/SOURCES/0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 7 Oct 2022 12:35:44 -0500 -Subject: [PATCH] libmultipath: enforce queue_mode bio for nmve:tcp paths - -nvme:tcp devices set BLK_MQ_F_BLOCKING (they are the only block devices -which multipath supports that do so), meaning that block_mq expects that -they can block at certain points while servicing a request. However, -due to the way device-mapper sets up its queue, it is not able to set -BLK_MQ_F_BLOCKING when it includes paths that set this flag. Patches -were written to address this issue but they were rejected upstream - -https://lore.kernel.org/linux-block/YcH%2FE4JNag0QYYAa@infradead.org/T/#t - -The proposed solution was to have multipath use the bio queue_mode for -multipath devices that include nvme:tcp paths. - -Multipath devices now automatically add the "queue_mode bio" feature if -they include nvme:tcp paths. If a multipath devices was created with -"queue_mode rq", it will disallow the addition of nvme:tcp paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/configure.c | 17 ++++++++++++++++- - libmultipath/structs_vec.c | 7 +++++++ - multipath/multipath.conf.5 | 4 +++- - 3 files changed, 26 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 8e1bc488..c341793c 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -297,6 +297,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - struct vectors *vecs) - { - struct pathgroup * pgp; -+ struct path *pp; - struct config *conf; - int i, n_paths, marginal_pathgroups; - -@@ -308,6 +309,14 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - return 1; - } - -+ /* Force QUEUE_MODE_BIO for maps with nvme:tcp paths */ -+ vector_foreach_slot(mpp->paths, pp, i) { -+ if (pp->bus == SYSFS_BUS_NVME && -+ pp->sg_id.proto_id == NVME_PROTOCOL_TCP) { -+ mpp->queue_mode = QUEUE_MODE_BIO; -+ break; -+ } -+ } - /* - * free features, selector, and hwhandler properties if they are being reused - */ -@@ -1161,6 +1170,13 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - continue; - } - -+ cmpp = find_mp_by_wwid(curmp, pp1->wwid); -+ if (cmpp && cmpp->queue_mode == QUEUE_MODE_RQ && -+ pp1->bus == SYSFS_BUS_NVME && pp1->sg_id.proto_id == -+ NVME_PROTOCOL_TCP) { -+ orphan_path(pp1, "nvme:tcp path not allowed with request queue_mode multipath device"); -+ continue; -+ } - /* - * at this point, we know we really got a new mp - */ -@@ -1199,7 +1215,6 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - } - verify_paths(mpp, vecs); - -- cmpp = find_mp_by_wwid(curmp, mpp->wwid); - if (cmpp) - mpp->queue_mode = cmpp->queue_mode; - params[0] = '\0'; -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 8137ea21..24ac022e 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -68,6 +68,13 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - pp->dev, mpp->alias); - continue; - } -+ if (mpp->queue_mode == QUEUE_MODE_RQ && -+ pp->bus == SYSFS_BUS_NVME && -+ pp->sg_id.proto_id == NVME_PROTOCOL_TCP) { -+ condlog(2, "%s: mulitpath device %s created with request queue_mode. Unable to add nvme:tcp paths", -+ pp->dev, mpp->alias); -+ continue; -+ } - condlog(3, "%s: ownership set to %s", - pp->dev, mpp->alias); - pp->mpp = mpp; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 1f5a40b6..cb07a62c 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -462,7 +462,9 @@ Before kernel 4.20 The default depends on the kernel parameter - \fBdm_mod.use_blk_mq\fR. It is \fImq\fR if the latter is set, and \fIrq\fR - otherwise. Since kernel 4.20, \fIrq\fR and \fImq\fR both correspond to - block-multiqueue. Once a multipath device has been created, its queue_mode --cannot be changed. -+cannot be changed. \fInvme:tcp\fR paths are only supported in multipath -+devices with queue_mode set to \fIbio\fR. multipath will automatically -+set this when creating a device with \fInvme:tcp\fR paths. - .TP - The default is: \fB\fR - .RE diff --git a/SOURCES/0125-multipath-add-historical-service-time-to-the-man-pag.patch b/SOURCES/0125-multipath-add-historical-service-time-to-the-man-pag.patch deleted file mode 100644 index 78fc931..0000000 --- a/SOURCES/0125-multipath-add-historical-service-time-to-the-man-pag.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 15 Nov 2022 09:01:36 -0600 -Subject: [PATCH] multipath: add historical-service-time to the man page - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index cb07a62c..d8a98435 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -205,6 +205,11 @@ of outstanding I/O to the path. - (Since 2.6.31 kernel) Choose the path for the next bunch of I/O based on the amount - of outstanding I/O to the path and its relative throughput. - .TP -+.I "historical-service-time 0" -+(Since 4.18.0-305.3.el8 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 - The default is: \fBservice-time 0\fR - .RE - . diff --git a/SOURCES/0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch b/SOURCES/0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch deleted file mode 100644 index c176bdd..0000000 --- a/SOURCES/0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch +++ /dev/null @@ -1,215 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 16 Sep 2020 22:22:36 +0200 -Subject: [PATCH] libmultipath: copy mpp->hwe from pp->hwe - -Since f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe"), -we've been trying to fix issues caused by paths getting freed and mpp->hwe -dangling. This approach couldn't work because we need mpp->hwe to persist, -even if all paths are removed from the map. Before f0462f0, a simple -assignment worked, because the lifetime of the hwe wasn't bound to the -path. But now, we need to copy the vector. It turns out that we need to set -mpp->hwe only in two places, add_map_with_path() and setup_map(), and -that the code is simplified overall. - -Even now, it can happen that a map is added with add_map_without_paths(), -and has no paths. In that case, calling do_set_from_hwe() with a NULL -pointer is not a bug, so remove the message. - -Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe") -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 8 ++++++++ - libmultipath/propsel.c | 2 +- - libmultipath/structs.c | 15 ++++++++++++++ - libmultipath/structs.h | 1 + - libmultipath/structs_vec.c | 41 +++++++++++++++++++------------------- - multipathd/main.c | 10 ---------- - 6 files changed, 45 insertions(+), 32 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index c341793c..6e06fea2 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -324,6 +324,14 @@ int setup_map(struct multipath *mpp, char *params, int params_size, - if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0) - mpp->disable_queueing = 0; - -+ /* -+ * If this map was created with add_map_without_path(), -+ * mpp->hwe might not be set yet. -+ */ -+ if (!mpp->hwe) -+ extract_hwe_from_path(mpp); -+ -+ - /* - * properties selectors - * -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index 3f119dd9..bc5c27ab 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -66,7 +66,7 @@ do { \ - __do_set_from_vec(struct hwentry, var, (src)->hwe, dest) - - #define do_set_from_hwe(var, src, dest, msg) \ -- if (__do_set_from_hwe(var, src, dest)) { \ -+ if (src->hwe && __do_set_from_hwe(var, src, dest)) { \ - origin = msg; \ - goto out; \ - } -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 7bdf9152..5bb6caf8 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -242,6 +242,17 @@ alloc_multipath (void) - return mpp; - } - -+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp) -+{ -+ if (!mpp || !pp || !pp->hwe) -+ return NULL; -+ if (mpp->hwe) -+ return mpp->hwe; -+ mpp->hwe = vector_convert(NULL, pp->hwe, -+ struct hwentry, identity); -+ return mpp->hwe; -+} -+ - void free_multipath_attributes(struct multipath *mpp) - { - if (!mpp) -@@ -283,6 +294,10 @@ free_multipath (struct multipath * mpp, enum free_path_mode free_paths) - - free_pathvec(mpp->paths, free_paths); - free_pgvec(mpp->pg, free_paths); -+ if (mpp->hwe) { -+ vector_free(mpp->hwe); -+ mpp->hwe = NULL; -+ } - FREE_PTR(mpp->mpcontext); - FREE(mpp); - } -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9130efb5..44980b4e 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -499,6 +499,7 @@ struct host_group { - struct path * alloc_path (void); - struct pathgroup * alloc_pathgroup (void); - struct multipath * alloc_multipath (void); -+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp); - void free_path (struct path *); - void free_pathvec (vector vec, enum free_path_mode free_paths); - void free_pathgroup (struct pathgroup * pgp, enum free_path_mode free_paths); -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 24ac022e..9613252f 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -180,24 +180,24 @@ extract_hwe_from_path(struct multipath * mpp) - if (mpp->hwe || !mpp->paths) - return; - -- condlog(3, "%s: searching paths for valid hwe", mpp->alias); -+ condlog(4, "%s: searching paths for valid hwe", mpp->alias); - /* doing this in two passes seems like paranoia to me */ - vector_foreach_slot(mpp->paths, pp, i) { -- if (pp->state != PATH_UP) -- continue; -- if (pp->hwe) { -- mpp->hwe = pp->hwe; -- return; -- } -+ if (pp->state == PATH_UP && pp->hwe) -+ goto done; - } - vector_foreach_slot(mpp->paths, pp, i) { -- if (pp->state == PATH_UP) -- continue; -- if (pp->hwe) { -- mpp->hwe = pp->hwe; -- return; -- } -+ if (pp->state != PATH_UP && pp->hwe) -+ goto done; - } -+done: -+ if (i < VECTOR_SIZE(mpp->paths)) -+ (void)set_mpp_hwe(mpp, pp); -+ -+ if (mpp->hwe) -+ condlog(3, "%s: got hwe from path %s", mpp->alias, pp->dev); -+ else -+ condlog(2, "%s: no hwe found", mpp->alias); - } - - int -@@ -445,9 +445,15 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp, - - conf = get_multipath_config(); - mpp->mpe = find_mpe(conf->mptable, pp->wwid); -- mpp->hwe = pp->hwe; - put_multipath_config(conf); - -+ /* -+ * We need to call this before select_alias(), -+ * because that accesses hwe properties. -+ */ -+ if (pp->hwe && !set_mpp_hwe(mpp, pp)) -+ goto out; -+ - strcpy(mpp->wwid, pp->wwid); - find_existing_alias(mpp, vecs); - if (select_alias(conf, mpp)) -@@ -497,12 +503,6 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - vector_del_slot(mpp->paths, i); - i--; - -- /* Make sure mpp->hwe doesn't point to freed memory. -- * We call extract_hwe_from_path() below to restore -- * mpp->hwe -- */ -- if (mpp->hwe == pp->hwe) -- mpp->hwe = NULL; - if ((j = find_slot(vecs->pathvec, - (void *)pp)) != -1) - vector_del_slot(vecs->pathvec, j); -@@ -512,7 +512,6 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - mpp->alias, pp->dev, pp->dev_t); - } - } -- extract_hwe_from_path(mpp); - return count; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index cd68a9d2..769dcaee 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1198,13 +1198,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - goto fail; - } - -- /* -- * Make sure mpp->hwe doesn't point to freed memory -- * We call extract_hwe_from_path() below to restore mpp->hwe -- */ -- if (mpp->hwe == pp->hwe) -- mpp->hwe = NULL; -- - if ((i = find_slot(mpp->paths, (void *)pp)) != -1) - vector_del_slot(mpp->paths, i); - -@@ -1216,9 +1209,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) - flush_map_nopaths(mpp, vecs)) - goto out; - -- if (mpp->hwe == NULL) -- extract_hwe_from_path(mpp); -- - if (setup_map(mpp, params, PARAMS_SIZE, vecs)) { - condlog(0, "%s: failed to setup map for" - " removal of path %s", mpp->alias, pp->dev); diff --git a/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch b/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch deleted file mode 100644 index ded6361..0000000 --- a/SOURCES/0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 14 Dec 2022 15:38:19 -0600 -Subject: [PATCH] libmultipath: don't leak memory on invalid strings - -If set_path() or set_str_noslash() are called with a bad value, they -ignore it and continue to use the old value. But they weren't freeing -the bad value, causing a memory leak. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index d7cd94a5..a8c9e989 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -169,6 +169,7 @@ set_path(vector strvec, void *ptr, const char *file, int line_nr) - if ((*str_ptr)[0] != '/'){ - condlog(1, "%s line %d, %s is not an absolute path. Ignoring", - file, line_nr, *str_ptr); -+ free(*str_ptr); - *str_ptr = old_str; - } else - free(old_str); -@@ -189,6 +190,7 @@ set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) - if (strchr(*str_ptr, '/')) { - condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", - file, line_nr, *str_ptr); -+ free(*str_ptr); - *str_ptr = old_str; - } else - free(old_str); diff --git a/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch b/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch deleted file mode 100644 index ced384f..0000000 --- a/SOURCES/0128-libmutipath-validate-the-argument-count-of-config-st.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 14 Dec 2022 15:38:20 -0600 -Subject: [PATCH] libmutipath: validate the argument count of config strings - -The features, path_selector, and hardware_handler config options pass -their strings directly into the kernel. If users omit the argument -counts from these strings, or use the wrong value, the kernel's table -parsing gets completely messed up, and the error messages it prints -don't reflect what actully went wrong. To avoid messing up the -kernel table parsing, verify that these strings correctly set the -argument count to the number of arguments they have. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmultipath/dict.c | 110 ++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 101 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index a8c9e989..952b33d0 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -155,6 +155,58 @@ set_dir(vector strvec, void *ptr, const char *file, int line_nr) - return 0; - } - -+static int -+set_arg_str(vector strvec, void *ptr, int count_idx, const char *file, -+ int line_nr) -+{ -+ char **str_ptr = (char **)ptr; -+ char *old_str = *str_ptr; -+ const char * const spaces = " \f\r\t\v"; -+ char *p, *end; -+ int idx = -1; -+ long int count = -1; -+ -+ *str_ptr = set_value(strvec); -+ if (!*str_ptr) { -+ free(old_str); -+ return 1; -+ } -+ p = *str_ptr; -+ while (*p != '\0') { -+ p += strspn(p, spaces); -+ if (*p == '\0') -+ break; -+ idx += 1; -+ if (idx == count_idx) { -+ errno = 0; -+ count = strtol(p, &end, 10); -+ if (errno == ERANGE || end == p || -+ !(isspace(*end) || *end == '\0')) { -+ count = -1; -+ break; -+ } -+ } -+ p += strcspn(p, spaces); -+ } -+ if (count < 0) { -+ condlog(1, "%s line %d, missing argument count for %s", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0)); -+ goto fail; -+ } -+ if (count != idx - count_idx) { -+ condlog(1, "%s line %d, invalid argument count for %s:, got '%ld' expected '%d'", -+ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), count, -+ idx - count_idx); -+ goto fail; -+ } -+ free(old_str); -+ return 0; -+fail: -+ free(*str_ptr); -+ *str_ptr = old_str; -+ return 0; -+} -+ - static int - set_path(vector strvec, void *ptr, const char *file, int line_nr) - { -@@ -337,6 +389,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ - return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ - } - -+#define declare_def_arg_str_handler(option, count_idx) \ -+static int \ -+def_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ return set_arg_str(strvec, &conf->option, count_idx, file, line_nr); \ -+} -+ - #define declare_def_snprint(option, function) \ - static int \ - snprint_def_ ## option (struct config *conf, char * buff, int len, \ -@@ -389,6 +449,17 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ - return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ - } - -+#define declare_hw_arg_str_handler(option, count_idx) \ -+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_arg_str(strvec, &hwe->option, count_idx, file, line_nr); \ -+} -+ - - #define declare_hw_snprint(option, function) \ - static int \ -@@ -420,6 +491,16 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ - file, line_nr); \ - } - -+#define declare_ovr_arg_str_handler(option, count_idx) \ -+static int \ -+ovr_ ## option ## _handler (struct config *conf, vector strvec, \ -+ const char *file, int line_nr) \ -+{ \ -+ if (!conf->overrides) \ -+ return 1; \ -+ return set_arg_str(strvec, &conf->overrides->option, count_idx, file, line_nr); \ -+} -+ - #define declare_ovr_snprint(option, function) \ - static int \ - snprint_ovr_ ## option (struct config *conf, char * buff, int len, \ -@@ -450,6 +531,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ - return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ - } - -+#define declare_mp_arg_str_handler(option, count_idx) \ -+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_arg_str(strvec, &mpe->option, count_idx, file, line_nr); \ -+} -+ - #define declare_mp_snprint(option, function) \ - static int \ - snprint_mp_ ## option (struct config *conf, char * buff, int len, \ -@@ -634,13 +726,13 @@ snprint_def_marginal_pathgroups(struct config *conf, char *buff, int len, - } - - --declare_def_handler(selector, set_str) -+declare_def_arg_str_handler(selector, 1) - declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR) --declare_hw_handler(selector, set_str) -+declare_hw_arg_str_handler(selector, 1) - declare_hw_snprint(selector, print_str) --declare_ovr_handler(selector, set_str) -+declare_ovr_arg_str_handler(selector, 1) - declare_ovr_snprint(selector, print_str) --declare_mp_handler(selector, set_str) -+declare_mp_arg_str_handler(selector, 1) - declare_mp_snprint(selector, print_str) - - static int snprint_uid_attrs(struct config *conf, char *buff, int len, -@@ -717,13 +809,13 @@ declare_hw_snprint(prio_args, print_str) - declare_mp_handler(prio_args, set_str) - declare_mp_snprint(prio_args, print_str) - --declare_def_handler(features, set_str) -+declare_def_arg_str_handler(features, 0) - declare_def_snprint_defstr(features, print_str, DEFAULT_FEATURES) --declare_ovr_handler(features, set_str) -+declare_ovr_arg_str_handler(features, 0) - declare_ovr_snprint(features, print_str) --declare_hw_handler(features, set_str) -+declare_hw_arg_str_handler(features, 0) - declare_hw_snprint(features, print_str) --declare_mp_handler(features, set_str) -+declare_mp_arg_str_handler(features, 0) - declare_mp_snprint(features, print_str) - - declare_def_handler(checker_name, set_str) -@@ -1894,7 +1986,7 @@ declare_hw_snprint(revision, print_str) - declare_hw_handler(bl_product, set_regex) - declare_hw_snprint(bl_product, print_str) - --declare_hw_handler(hwhandler, set_str) -+declare_hw_arg_str_handler(hwhandler, 0) - declare_hw_snprint(hwhandler, print_str) - - /* diff --git a/SOURCES/0129-libmultipath-select-resize-action-even-if-reload-is-.patch b/SOURCES/0129-libmultipath-select-resize-action-even-if-reload-is-.patch deleted file mode 100644 index 97fd724..0000000 --- a/SOURCES/0129-libmultipath-select-resize-action-even-if-reload-is-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 09:58:55 -0600 -Subject: [PATCH] libmultipath: select resize action even if reload is forced - -The ACT_RESIZE action is the same as the ACT_RELOAD action, except that -it flushes outstanding IO because the device size is changing and -the new size might be too small for some of the outstanding IO. If we've -detected a size change, and a forced reload is requested, we still need -to flush the IO because the reload will change the device size. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 6e06fea2..ecf24f95 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -734,17 +734,18 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - return; - } - -- if (force_reload) { -+ if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -- condlog(3, "%s: set ACT_RELOAD (forced by user)", -+ mpp->action = ACT_RESIZE; -+ condlog(3, "%s: set ACT_RESIZE (size change)", - mpp->alias); - return; - } -- if (cmpp->size != mpp->size) { -+ -+ if (force_reload) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RESIZE; -- condlog(3, "%s: set ACT_RESIZE (size change)", -+ mpp->action = ACT_RELOAD; -+ condlog(3, "%s: set ACT_RELOAD (forced by user)", - mpp->alias); - return; - } diff --git a/SOURCES/0130-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch b/SOURCES/0130-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch deleted file mode 100644 index 0b8473b..0000000 --- a/SOURCES/0130-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 10:35:10 -0600 -Subject: [PATCH] libmultipath: cleanup ACT_CREATE code in select_action - -Combine the two separate blocks that set ACT_CREATE into one. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 38 +++++++++++++++++--------------------- - 1 file changed, 17 insertions(+), 21 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index ecf24f95..303d2380 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -693,33 +693,29 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - cmpp = find_mp_by_wwid(curmp, mpp->wwid); - cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); - -- if (!cmpp_by_name) { -- if (cmpp) { -- condlog(2, "%s: rename %s to %s", mpp->wwid, -- cmpp->alias, mpp->alias); -- strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -- mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -+ if (!cmpp) { -+ if (cmpp_by_name) { -+ condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -+ mpp->wwid, mpp->alias, cmpp_by_name->wwid); -+ /* We can do this because wwid wasn't found */ -+ free(mpp->alias); -+ mpp->alias = strdup(mpp->wwid); - } - mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist)", -- mpp->alias); -+ condlog(3, "%s: set ACT_CREATE (map does not exist%s)", -+ mpp->alias, cmpp_by_name ? ", name changed" : ""); - return; - } - -- if (!cmpp) { -- condlog(1, "%s: can't use alias \"%s\" used by %s, falling back to WWID", -- mpp->wwid, mpp->alias, cmpp_by_name->wwid); -- /* We can do this because wwid wasn't found */ -- free(mpp->alias); -- mpp->alias = strdup(mpp->wwid); -- mpp->action = ACT_CREATE; -- condlog(3, "%s: set ACT_CREATE (map does not exist, name changed)", -+ if (!cmpp_by_name) { -+ condlog(2, "%s: rename %s to %s", mpp->wwid, cmpp->alias, - mpp->alias); -+ strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); -+ mpp->action = ACT_RENAME; -+ if (force_reload) { -+ mpp->force_udev_reload = 1; -+ mpp->action = ACT_FORCERENAME; -+ } - return; - } - diff --git a/SOURCES/0131-libmultipath-keep-renames-from-stopping-other-multip.patch b/SOURCES/0131-libmultipath-keep-renames-from-stopping-other-multip.patch deleted file mode 100644 index c57ab7e..0000000 --- a/SOURCES/0131-libmultipath-keep-renames-from-stopping-other-multip.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 31 Jan 2023 12:00:31 -0600 -Subject: [PATCH] libmultipath: keep renames from stopping other multipath - actions - -If select_action() is called and a multipath device needs to be renamed, -the code currently checks if force_reload is set, and if so, does the -reload after the rename. But if force_reload isn't set, only the rename -happens, regardless of what other actions are needed. This can happen if -multipathd starts up and a device needs both a reload and a rename. - -Make multipath check for resize, reload, and switch pathgroup along with -rename, and do both if necessary. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/configure.c | 92 +++++++++++++++++++++------------------- - libmultipath/configure.h | 4 +- - 2 files changed, 51 insertions(+), 45 deletions(-) - -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 303d2380..65a0b208 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -690,6 +690,7 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - struct multipath * cmpp_by_name; - char * mpp_feat, * cmpp_feat; - -+ mpp->action = ACT_NOTHING; - cmpp = find_mp_by_wwid(curmp, mpp->wwid); - cmpp_by_name = find_mp_by_alias(curmp, mpp->alias); - -@@ -712,14 +713,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - mpp->alias); - strlcpy(mpp->alias_old, cmpp->alias, WWID_SIZE); - mpp->action = ACT_RENAME; -- if (force_reload) { -- mpp->force_udev_reload = 1; -- mpp->action = ACT_FORCERENAME; -- } -- return; -- } -- -- if (cmpp != cmpp_by_name) { -+ /* don't return here. Check for other needed actions */ -+ } else if (cmpp != cmpp_by_name) { - condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", - mpp->wwid, cmpp->alias, mpp->alias, - mpp->alias, cmpp_by_name->wwid); -@@ -727,12 +722,13 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - FREE(mpp->alias); - mpp->alias = STRDUP(cmpp->alias); - mpp->action = ACT_IMPOSSIBLE; -- return; -+ /* don't return here. Check for other needed actions */ - } - - if (cmpp->size != mpp->size) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RESIZE; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RESIZE_RENAME : -+ ACT_RESIZE; - condlog(3, "%s: set ACT_RESIZE (size change)", - mpp->alias); - return; -@@ -740,7 +736,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - - if (force_reload) { - mpp->force_udev_reload = 1; -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (forced by user)", - mpp->alias); - return; -@@ -749,7 +746,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF && - !!strstr(mpp->features, "queue_if_no_path") != - !!strstr(cmpp->features, "queue_if_no_path")) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (no_path_retry change)", - mpp->alias); - return; -@@ -759,7 +757,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - (strlen(cmpp->hwhandler) != strlen(mpp->hwhandler) || - strncmp(cmpp->hwhandler, mpp->hwhandler, - strlen(mpp->hwhandler)))) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (hwhandler change)", - mpp->alias); - return; -@@ -769,7 +768,8 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - !!strstr(mpp->features, "retain_attached_hw_handler") != - !!strstr(cmpp->features, "retain_attached_hw_handler") && - get_linux_version_code() < KERNEL_VERSION(4, 3, 0)) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (retain_hwhandler change)", - mpp->alias); - return; -@@ -783,9 +783,13 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - remove_feature(&cmpp_feat, "queue_if_no_path"); - remove_feature(&cmpp_feat, "retain_attached_hw_handler"); - if (strncmp(mpp_feat, cmpp_feat, PARAMS_SIZE)) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? -+ ACT_RELOAD_RENAME : ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (features change)", - mpp->alias); -+ FREE(cmpp_feat); -+ FREE(mpp_feat); -+ return; - } - } - FREE(cmpp_feat); -@@ -793,44 +797,49 @@ select_action (struct multipath * mpp, vector curmp, int force_reload) - - if (!cmpp->selector || strncmp(cmpp->selector, mpp->selector, - strlen(mpp->selector))) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (selector change)", - mpp->alias); - return; - } - if (cmpp->minio != mpp->minio) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (minio change, %u->%u)", - mpp->alias, cmpp->minio, mpp->minio); - return; - } - if (!cmpp->pg || VECTOR_SIZE(cmpp->pg) != VECTOR_SIZE(mpp->pg)) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (path group number change)", - mpp->alias); - return; - } - if (pgcmp(mpp, cmpp)) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_RELOAD_RENAME : -+ ACT_RELOAD; - condlog(3, "%s: set ACT_RELOAD (path group topology change)", - mpp->alias); - return; - } - if (cmpp->nextpg != mpp->bestpg) { -- mpp->action = ACT_SWITCHPG; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : -+ ACT_SWITCHPG; - condlog(3, "%s: set ACT_SWITCHPG (next path group change)", - mpp->alias); - return; - } - if (!is_mpp_known_to_udev(cmpp)) { -- mpp->action = ACT_RELOAD; -+ mpp->action = mpp->action == ACT_RENAME ? ACT_SWITCHPG_RENAME : -+ ACT_SWITCHPG; - condlog(3, "%s: set ACT_RELOAD (udev device not initialized)", - mpp->alias); - return; - } -- mpp->action = ACT_NOTHING; -- condlog(3, "%s: set ACT_NOTHING (map unchanged)", -- mpp->alias); -+ if (mpp->action == ACT_NOTHING) -+ condlog(3, "%s: set ACT_NOTHING (map unchanged)", mpp->alias); - return; - } - -@@ -924,6 +933,17 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - mpp->action = ACT_RELOAD; - } - -+ if (mpp->action == ACT_RENAME || mpp->action == ACT_SWITCHPG_RENAME || -+ mpp->action == ACT_RELOAD_RENAME || -+ mpp->action == ACT_RESIZE_RENAME) { -+ conf = get_multipath_config(); -+ pthread_cleanup_push(put_multipath_config, conf); -+ r = dm_rename(mpp->alias_old, mpp->alias, -+ conf->partition_delim, mpp->skip_kpartx); -+ pthread_cleanup_pop(1); -+ if (r == DOMAP_FAIL) -+ return r; -+ } - switch (mpp->action) { - case ACT_REJECT: - case ACT_NOTHING: -@@ -931,6 +951,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - return DOMAP_EXIST; - - case ACT_SWITCHPG: -+ case ACT_SWITCHPG_RENAME: - dm_switchgroup(mpp->alias, mpp->bestpg); - /* - * we may have avoided reinstating paths because there where in -@@ -957,6 +978,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RELOAD: -+ case ACT_RELOAD_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -964,6 +986,7 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RESIZE: -+ case ACT_RESIZE_RENAME: - sysfs_set_max_sectors_kb(mpp, 1); - if (mpp->ghost_delay_tick > 0 && pathcount(mpp, PATH_UP)) - mpp->ghost_delay_tick = 0; -@@ -971,29 +994,10 @@ int domap(struct multipath *mpp, char *params, int is_daemon) - break; - - case ACT_RENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- break; -- -- case ACT_FORCERENAME: -- conf = get_multipath_config(); -- pthread_cleanup_push(put_multipath_config, conf); -- r = dm_rename(mpp->alias_old, mpp->alias, -- conf->partition_delim, mpp->skip_kpartx); -- pthread_cleanup_pop(1); -- if (r) { -- sysfs_set_max_sectors_kb(mpp, 1); -- if (mpp->ghost_delay_tick > 0 && -- pathcount(mpp, PATH_UP)) -- mpp->ghost_delay_tick = 0; -- r = dm_addmap_reload(mpp, params, 0); -- } - break; - - default: -+ r = DOMAP_FAIL; - break; - } - -diff --git a/libmultipath/configure.h b/libmultipath/configure.h -index 5cf08d45..1a93f49d 100644 ---- a/libmultipath/configure.h -+++ b/libmultipath/configure.h -@@ -18,9 +18,11 @@ enum actions { - ACT_RENAME, - ACT_CREATE, - ACT_RESIZE, -- ACT_FORCERENAME, -+ ACT_RELOAD_RENAME, - ACT_DRY_RUN, - ACT_IMPOSSIBLE, -+ ACT_RESIZE_RENAME, -+ ACT_SWITCHPG_RENAME, - }; - - /* diff --git a/SOURCES/0132-multipathd-make-pr-registration-consistent.patch b/SOURCES/0132-multipathd-make-pr-registration-consistent.patch deleted file mode 100644 index 2a3320f..0000000 --- a/SOURCES/0132-multipathd-make-pr-registration-consistent.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:10 -0600 -Subject: [PATCH] multipathd: make pr registration consistent - -multipathd was inconsistent on what it did with persistent reservations -when a multipath device was created. If a multipath device with a -configured reservation key was created during configure(), multipathd -would try to read the registered keys using an active path. If it saw a -matching key, it would set the prflag, but not attempt to register the -key on any of the other paths. This means that if a new path had -appeared while multipathd was not running, it wouldn't register the key -on this path. - -If the multipath device was created during ev_add_path(), multipathd -would used the added path to check if there was a matching key and if -there was, register the key only on the added path and then set the -prflag. This could be problematic if the device was created with -multiple paths, for instance because find_mutipaths was set to "yes" and -a second path just appeared. In this case, if the device happened to be -only registered on the second path, it would not get registered on the -first path. - -If the multipath device was added to multipathd during a call to -ev_add_map(), multipathd wouldn't set the prflag or register the key on -any paths. - -After a device was created with the prflag set, if a new path appeared -before the creation uevent, and multipathd was forced to delay adding -it, when it finally updated the multipath device, the key would be -registered on all paths, fixing any paths missed during creation. -However, if a new path appeared after the creation uevent, the key would -only be registered on that new path. Any paths that were missed on -creation would stay missed. - -persistent key registration needs to be handled consistently. This -patch does so by making sure that however a multipath device is added to -multipathd, it will check to see if the configured key is registered. If -it is, multipathd will set the prflag and register the key on all the -currently active paths. - -When a new path is added, multipathd will use it to check for active -keys, as before. But if it finds a matching key and prflag isn't -currently set, it will register the key on all paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/main.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 769dcaee..d84027dc 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -511,6 +511,21 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) { - return false; - } - -+static void -+pr_register_active_paths(struct multipath *mpp) -+{ -+ unsigned int i, j; -+ struct path *pp; -+ struct pathgroup *pgp; -+ -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) -+ mpath_pr_event_handle(pp); -+ } -+ } -+} -+ - static int - update_map (struct multipath *mpp, struct vectors *vecs, int new_map) - { -@@ -556,6 +571,11 @@ fail: - - sync_map_state(mpp); - -+ if (!mpp->prflag) -+ update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); -+ - if (retries < 0) - condlog(0, "%s: failed reload in new map update", mpp->alias); - return 0; -@@ -1014,6 +1034,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -+ unsigned char prflag = 0; - - /* - * need path UID to go any further -@@ -1056,6 +1077,8 @@ rescan: - - verify_paths(mpp, vecs); - mpp->action = ACT_RELOAD; -+ prflag = mpp->prflag; -+ mpath_pr_event_handle(pp); - } else { - if (!should_multipath(pp, vecs->pathvec, vecs->mpvec)) { - orphan_path(pp, "only one path"); -@@ -1074,9 +1097,6 @@ rescan: - goto fail; /* leave path added to pathvec */ - } - -- /* persistent reservation check*/ -- mpath_pr_event_handle(pp); -- - /* ro check - if new path is ro, force map to be ro as well */ - ro = sysfs_get_ro(pp); - if (ro == 1) -@@ -1140,6 +1160,10 @@ rescan: - sync_map_state(mpp); - - if (retries >= 0) { -+ if (start_waiter) -+ update_map_pr(mpp); -+ if (mpp->prflag && !prflag) -+ pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); - return 0; -@@ -2608,6 +2632,8 @@ configure (struct vectors * vecs) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -+ if (mpp->prflag) -+ pr_register_active_paths(mpp); - } - - /* diff --git a/SOURCES/0133-libmultipath-make-prflag-an-enum.patch b/SOURCES/0133-libmultipath-make-prflag-an-enum.patch deleted file mode 100644 index 547b9bc..0000000 --- a/SOURCES/0133-libmultipath-make-prflag-an-enum.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:11 -0600 -Subject: [PATCH] libmultipath: make prflag an enum - -In preparation for a future patch, make prflag an enum, and change the -reply of cli_getprstatus() to a string. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 2 +- - libmultipath/structs.h | 8 +++++++- - multipathd/cli_handlers.c | 16 +++++++++------- - multipathd/main.c | 14 +++++++------- - 4 files changed, 24 insertions(+), 16 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index d0744773..e361435a 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -949,7 +949,7 @@ int update_map_pr(struct multipath *mpp) - - if (isFound) - { -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 44980b4e..8acea3cb 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -377,6 +377,12 @@ struct path { - - typedef int (pgpolicyfn) (struct multipath *, vector); - -+ -+enum prflag_value { -+ PRFLAG_UNSET, -+ PRFLAG_SET, -+}; -+ - struct multipath { - char wwid[WWID_SIZE]; - char alias_old[WWID_SIZE]; -@@ -450,7 +456,7 @@ struct multipath { - int prkey_source; - struct be64 reservation_key; - uint8_t sa_flags; -- unsigned char prflag; -+ int prflag; - int all_tg_pt; - struct gen_multipath generic_mp; - bool fpin_must_reload; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 8b4bd187..6dbbb7e2 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1407,6 +1407,10 @@ cli_shutdown (void * v, char ** reply, int * len, void * data) - int - cli_getprstatus (void * v, char ** reply, int * len, void * data) - { -+ static const char * const prflag_str[] = { -+ [PRFLAG_UNSET] = "unset\n", -+ [PRFLAG_SET] = "set\n", -+ }; - struct multipath * mpp; - struct vectors * vecs = (struct vectors *)data; - char * param = get_keyparam(v, MAP); -@@ -1418,9 +1422,7 @@ cli_getprstatus (void * v, char ** reply, int * len, void * data) - if (!mpp) - return 1; - -- condlog(3, "%s: prflag = %u", param, (unsigned int)mpp->prflag); -- -- *len = asprintf(reply, "%d", mpp->prflag); -+ *len = asprintf(reply, "%s", prflag_str[mpp->prflag]); - if (*len < 0) - return 1; - -@@ -1443,8 +1445,8 @@ cli_setprstatus(void * v, char ** reply, int * len, void * data) - if (!mpp) - return 1; - -- if (!mpp->prflag) { -- mpp->prflag = 1; -+ if (mpp->prflag != PRFLAG_SET) { -+ mpp->prflag = PRFLAG_SET; - condlog(2, "%s: prflag set", param); - } - -@@ -1466,8 +1468,8 @@ cli_unsetprstatus(void * v, char ** reply, int * len, void * data) - if (!mpp) - return 1; - -- if (mpp->prflag) { -- mpp->prflag = 0; -+ if (mpp->prflag != PRFLAG_UNSET) { -+ mpp->prflag = PRFLAG_UNSET; - condlog(2, "%s: prflag unset", param); - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index d84027dc..81bb0deb 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -571,9 +571,9 @@ fail: - - sync_map_state(mpp); - -- if (!mpp->prflag) -+ if (mpp->prflag == PRFLAG_UNSET) - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - - if (retries < 0) -@@ -1034,7 +1034,7 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) - int start_waiter = 0; - int ret; - int ro; -- unsigned char prflag = 0; -+ unsigned char prflag = PRFLAG_UNSET; - - /* - * need path UID to go any further -@@ -1162,7 +1162,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag && !prflag) -+ if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2306,7 +2306,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag) { -+ if (pp->mpp->prflag == PRFLAG_SET) { - /* - * Check Persistent Reservation. - */ -@@ -2632,7 +2632,7 @@ configure (struct vectors * vecs) - if (remember_wwid(mpp->wwid) == 1) - trigger_paths_udev_change(mpp, true); - update_map_pr(mpp); -- if (mpp->prflag) -+ if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); - } - -@@ -3438,7 +3438,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - { - condlog(0,"%s: Reservation registration failed. Error: %d", pp->dev, ret); - } -- mpp->prflag = 1; -+ mpp->prflag = PRFLAG_SET; - - free(param); - out: diff --git a/SOURCES/0134-multipathd-handle-no-active-paths-in-update_map_pr.patch b/SOURCES/0134-multipathd-handle-no-active-paths-in-update_map_pr.patch deleted file mode 100644 index f6110db..0000000 --- a/SOURCES/0134-multipathd-handle-no-active-paths-in-update_map_pr.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 20 Dec 2022 17:41:12 -0600 -Subject: [PATCH] multipathd: handle no active paths in update_map_pr - -When a multipath device is first created, if it has a reservation key -configured, update_map_pr() will check for a matching key on the active -paths. If there were no active paths to check with, multipathd was -leaving mpp->prflag in PRFLAG_UNSET, as if there were no matching keys. -It's possible that when update_map_pr() is called, all the paths will be -in the PATH_PENDING state because the checkers haven't completed yet. In -this case, multipathd was treating the device as having no registered -keys without ever checking. - -To solve this, multipath devices now start with prflag = PRFLAG_UNKNOWN. -It will remain in this state until multipathd actually tries to get the -registered keys down a path. If the map is in this state, it will check -newly active paths, and if it finds a matching key, it will register -the key down all active paths. - -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - libmpathpersist/mpath_persist.c | 8 ++++++++ - libmultipath/structs.h | 1 + - multipathd/cli_handlers.c | 1 + - multipathd/main.c | 19 ++++++++++++++----- - 4 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index e361435a..440a329f 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -904,6 +904,7 @@ int update_map_pr(struct multipath *mpp) - if (!get_be64(mpp->reservation_key)) - { - /* Nothing to do. Assuming pr mgmt feature is disabled*/ -+ mpp->prflag = PRFLAG_UNSET; - condlog(4, "%s: reservation_key not set in multipath.conf", - mpp->alias); - return MPATH_PR_SUCCESS; -@@ -915,6 +916,13 @@ int update_map_pr(struct multipath *mpp) - condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); - return MPATH_PR_OTHER; - } -+ if (count_active_paths(mpp) == 0) -+ { -+ condlog(0,"%s: No available paths to check pr status", -+ mpp->alias); -+ return MPATH_PR_OTHER; -+ } -+ mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); - - if (ret != MPATH_PR_SUCCESS ) -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 8acea3cb..7f2fb944 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -379,6 +379,7 @@ typedef int (pgpolicyfn) (struct multipath *, vector); - - - enum prflag_value { -+ PRFLAG_UNKNOWN, - PRFLAG_UNSET, - PRFLAG_SET, - }; -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index 6dbbb7e2..260b7a17 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -1408,6 +1408,7 @@ int - cli_getprstatus (void * v, char ** reply, int * len, void * data) - { - static const char * const prflag_str[] = { -+ [PRFLAG_UNKNOWN] = "unknown\n", - [PRFLAG_UNSET] = "unset\n", - [PRFLAG_SET] = "set\n", - }; -diff --git a/multipathd/main.c b/multipathd/main.c -index 81bb0deb..e7dad6b9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -571,7 +571,7 @@ fail: - - sync_map_state(mpp); - -- if (mpp->prflag == PRFLAG_UNSET) -+ if (mpp->prflag != PRFLAG_SET) - update_map_pr(mpp); - if (mpp->prflag == PRFLAG_SET) - pr_register_active_paths(mpp); -@@ -1162,7 +1162,7 @@ rescan: - if (retries >= 0) { - if (start_waiter) - update_map_pr(mpp); -- if (mpp->prflag == PRFLAG_SET && prflag == PRFLAG_UNSET) -+ if (mpp->prflag == PRFLAG_SET && prflag != PRFLAG_SET) - pr_register_active_paths(mpp); - condlog(2, "%s [%s]: path added to devmap %s", - pp->dev, pp->dev_t, mpp->alias); -@@ -2306,13 +2306,17 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) - } - - if (newstate == PATH_UP || newstate == PATH_GHOST) { -- if (pp->mpp->prflag == PRFLAG_SET) { -+ if (pp->mpp->prflag != PRFLAG_UNSET) { -+ int prflag = pp->mpp->prflag; - /* - * Check Persistent Reservation. - */ - condlog(2, "%s: checking persistent " - "reservation registration", pp->dev); - mpath_pr_event_handle(pp); -+ if (pp->mpp->prflag == PRFLAG_SET && -+ prflag != PRFLAG_SET) -+ pr_register_active_paths(pp->mpp); - } - } - -@@ -3386,6 +3390,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) - goto out; - } - -+ mpp->prflag = PRFLAG_UNSET; - ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, 0); - if (ret != MPATH_PR_SUCCESS ) - { -@@ -3456,12 +3461,12 @@ int mpath_pr_event_handle(struct path *pp) - struct multipath * mpp; - - if (pp->bus != SYSFS_BUS_SCSI) -- return 0; -+ goto no_pr; - - mpp = pp->mpp; - - if (!get_be64(mpp->reservation_key)) -- return -1; -+ goto no_pr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); -@@ -3474,4 +3479,8 @@ int mpath_pr_event_handle(struct path *pp) - pthread_attr_destroy(&attr); - rc = pthread_join(thread, NULL); - return 0; -+ -+no_pr: -+ pp->mpp->prflag = PRFLAG_UNSET; -+ return 0; - } diff --git a/SOURCES/0135-libmpathpersist-fix-resource-leak-in-update_map_pr.patch b/SOURCES/0135-libmpathpersist-fix-resource-leak-in-update_map_pr.patch deleted file mode 100644 index 15182f6..0000000 --- a/SOURCES/0135-libmpathpersist-fix-resource-leak-in-update_map_pr.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 Feb 2023 09:20:35 +0100 -Subject: [PATCH] libmpathpersist: fix resource leak in update_map_pr() - -The "no available paths" case would leak the memory resp points to. -Found by coverity. - -Fixes: 50e2c16 ("multipathd: handle no active paths in update_map_pr") - -Signed-off-by: Martin Wilck -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 440a329f..a4c1461f 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -899,7 +899,7 @@ int update_map_pr(struct multipath *mpp) - int noisy=0; - struct prin_resp *resp; - unsigned int i; -- int ret, isFound; -+ int ret = MPATH_PR_OTHER, isFound; - - if (!get_be64(mpp->reservation_key)) - { -@@ -920,7 +920,7 @@ int update_map_pr(struct multipath *mpp) - { - condlog(0,"%s: No available paths to check pr status", - mpp->alias); -- return MPATH_PR_OTHER; -+ goto out; - } - mpp->prflag = PRFLAG_UNSET; - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); -@@ -928,15 +928,15 @@ int update_map_pr(struct multipath *mpp) - if (ret != MPATH_PR_SUCCESS ) - { - condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); -- free(resp); -- return ret; -+ goto out; - } - -+ ret = MPATH_PR_SUCCESS; -+ - if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) - { - condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); -- free(resp); -- return MPATH_PR_SUCCESS; -+ goto out; - } - - condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, -@@ -961,6 +961,7 @@ int update_map_pr(struct multipath *mpp) - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - -+out: - free(resp); -- return MPATH_PR_SUCCESS; -+ return ret; - } diff --git a/SOURCES/0136-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch b/SOURCES/0136-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch deleted file mode 100644 index 1e593f7..0000000 --- a/SOURCES/0136-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Muneendra -Date: Wed, 20 Sep 2023 20:41:15 -0700 -Subject: [PATCH] multipathd: Added support to handle FPIN-Li events for - FC-NVMe - - This patch adds the support to handle FPIN-Li for FC-NVMe. - On receiving the FPIN-Li events this patch moves the devices paths - which are affected due to link integrity to marginal path groups. - The paths which are set to marginal path group will be unset - on receiving the RSCN events - -(mwilck: minor compile fix for 32-bit architectures) - -Signed-off-by: Muneendra -Signed-off-by: Benjamin Marzinski -Reviewed-by: Martin Wilck ---- - multipathd/fpin_handlers.c | 206 +++++++++++++++++++++++++++---------- - 1 file changed, 151 insertions(+), 55 deletions(-) - -diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c -index 599f2893..6b90cded 100644 ---- a/multipathd/fpin_handlers.c -+++ b/multipathd/fpin_handlers.c -@@ -60,18 +60,15 @@ static void _udev_device_unref(void *p) - - - /*set/unset the path state to marginal*/ --static int fpin_set_pathstate(struct path *pp, bool set) -+static void fpin_set_pathstate(struct path *pp, bool set) - { - const char *action = set ? "set" : "unset"; - -- if (!pp || !pp->mpp || !pp->mpp->alias) -- return -1; -- -- condlog(3, "\n%s: %s marginal path %s (fpin)", -- action, pp->mpp->alias, pp->dev_t); -+ condlog(3, "%s: %s marginal path %s (fpin)", -+ pp->mpp ? pp->mpp->alias : "orphan", action, pp->dev_t); - pp->marginal = set; -- pp->mpp->fpin_must_reload = true; -- return 0; -+ if (pp->mpp) -+ pp->mpp->fpin_must_reload = true; - } - - /* This will unset marginal state of a device*/ -@@ -82,14 +79,14 @@ static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) - pp = find_path_by_dev(vecs->pathvec, devname); - if (!pp) - pp = find_path_by_devt(vecs->pathvec, devname); -- -- fpin_set_pathstate(pp, false); -+ if (pp) -+ fpin_set_pathstate(pp, false); - } - - /*This will set the marginal state of a device*/ --static int fpin_path_setmarginal(struct path *pp) -+static void fpin_path_setmarginal(struct path *pp) - { -- return fpin_set_pathstate(pp, true); -+ fpin_set_pathstate(pp, true); - } - - /* Unsets all the devices in the list from marginal state */ -@@ -176,8 +173,8 @@ static void fpin_set_rport_marginal(struct udev_device *rport_dev) - "Marginal", strlen("Marginal")); - } - --/*Add the marginal devices info into the list*/ --static void -+/*Add the marginal devices info into the list and return 0 on success*/ -+static int - fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - { - struct marginal_dev_list *newdev = NULL; -@@ -192,65 +189,160 @@ fpin_add_marginal_dev_info(uint32_t host_num, char *devname) - list_add_tail(&(newdev->node), - &fpin_li_marginal_dev_list_head); - pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); -- } -+ } else -+ return -ENOMEM; -+ return 0; - } - - /* -- * This function goes through the vecs->pathvec, and for -- * each path, check that the host number, -- * the target WWPN associated with the path matches -- * with the els wwpn and sets the path and port state to -+ * This function compares Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn with the els wwpn ,attached_wwpn -+ * and return 1 (match) or 0 (no match) or a negative error code -+ */ -+static int extract_nvme_addresses_chk_path_pwwn(const char *address, -+ uint64_t els_wwpn, uint64_t els_attached_wwpn) -+ -+{ -+ uint64_t traddr; -+ uint64_t host_traddr; -+ -+ /* -+ * Find the position of "traddr=" and "host_traddr=" -+ * and the address will be in the below format -+ * "traddr=nn-0x200400110dff9400:pn-0x200400110dff9400, -+ * host_traddr=nn-0x200400110dff9400:pn-0x200400110dff9400" -+ */ -+ const char *traddr_start = strstr(address, "traddr="); -+ const char *host_traddr_start = strstr(address, "host_traddr="); -+ -+ if (!traddr_start || !host_traddr_start) -+ return -EINVAL; -+ -+ /* Extract traddr pn */ -+ if (sscanf(traddr_start, "traddr=nn-%*[^:]:pn-%" SCNx64, &traddr) != 1) -+ return -EINVAL; -+ -+ /* Extract host_traddr pn*/ -+ if (sscanf(host_traddr_start, "host_traddr=nn-%*[^:]:pn-%" SCNx64, -+ &host_traddr) != 1) -+ return -EINVAL; -+ condlog(4, "traddr 0x%" PRIx64 " hosttraddr 0x%" PRIx64 " els_wwpn 0x%" -+ PRIx64" els_host_traddr 0x%" PRIx64, -+ traddr, host_traddr, -+ els_wwpn, els_attached_wwpn); -+ if ((host_traddr == els_attached_wwpn) && (traddr == els_wwpn)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * This function check that the Transport Address Controller Port pn, -+ * Host Transport Address Controller Port pn associated with the path matches -+ * with the els wwpn ,attached_wwpn and sets the path state to - * Marginal - */ --static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+static void fpin_check_set_nvme_path_marginal(uint16_t host_num, struct path *pp, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct udev_device *ctl = NULL; -+ const char *address = NULL; -+ int ret = 0; -+ -+ ctl = udev_device_get_parent_with_subsystem_devtype(pp->udev, "nvme", NULL); -+ if (ctl == NULL) { -+ condlog(2, "%s: No parent device for ", pp->dev); -+ return; -+ } -+ address = udev_device_get_sysattr_value(ctl, "address"); -+ if (!address) { -+ condlog(2, "%s: unable to get the address ", pp->dev); -+ return; -+ } -+ condlog(4, "\n address %s: dev :%s\n", address, pp->dev); -+ ret = extract_nvme_addresses_chk_path_pwwn(address, els_wwpn, attached_wwpn); -+ if (ret <= 0) -+ return; -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ return; -+ fpin_path_setmarginal(pp); -+} -+ -+/* -+ * This function check the host number, the target WWPN -+ * associated with the path matches with the els wwpn and -+ * sets the path and port state to Marginal -+ */ -+static void fpin_check_set_scsi_path_marginal(uint16_t host_num, struct path *pp, - uint64_t els_wwpn) - { -- struct path *pp; -- struct multipath *mpp; -- int i, k; - char rport_id[42]; - const char *value = NULL; - struct udev_device *rport_dev = NULL; - uint64_t wwpn; - int ret = 0; -+ sprintf(rport_id, "rport-%d:%d-%d", -+ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -+ rport_dev = udev_device_new_from_subsystem_sysname(udev, -+ "fc_remote_ports", rport_id); -+ if (!rport_dev) { -+ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -+ rport_id); -+ return; -+ } -+ pthread_cleanup_push(_udev_device_unref, rport_dev); -+ value = udev_device_get_sysattr_value(rport_dev, "port_name"); -+ if (!value) -+ goto unref; -+ -+ wwpn = strtol(value, NULL, 16); -+ /* -+ * If the port wwpn matches sets the path and port state -+ * to marginal -+ */ -+ if (wwpn == els_wwpn) { -+ ret = fpin_add_marginal_dev_info(host_num, pp->dev); -+ if (ret < 0) -+ goto unref; -+ fpin_path_setmarginal(pp); -+ fpin_set_rport_marginal(rport_dev); -+ } -+unref: -+ pthread_cleanup_pop(1); -+ return; -+ -+} -+ -+/* -+ * This function goes through the vecs->pathvec, and for -+ * each path, it checks and sets the path state to marginal -+ * if the path's associated port wwpn ,hostnum matches with -+ * els wwnpn ,attached_wwpn -+ */ -+static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, -+ uint64_t els_wwpn, uint64_t attached_wwpn) -+{ -+ struct path *pp; -+ struct multipath *mpp; -+ int i, k; -+ int ret = 0; - - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); - - vector_foreach_slot(vecs->pathvec, pp, k) { -- /* Checks the host number and also for the SCSI FCP */ -- if (pp->bus != SYSFS_BUS_SCSI || pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) -+ if (!pp->mpp) - continue; -- sprintf(rport_id, "rport-%d:%d-%d", -- pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); -- rport_dev = udev_device_new_from_subsystem_sysname(udev, -- "fc_remote_ports", rport_id); -- if (!rport_dev) { -- condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, -- rport_id); -- continue; -- } -- pthread_cleanup_push(_udev_device_unref, rport_dev); -- value = udev_device_get_sysattr_value(rport_dev, "port_name"); -- if (!value) -- goto unref; -- -- if (value) -- wwpn = strtol(value, NULL, 16); -- /* -- * If the port wwpn matches sets the path and port state -- * to marginal -- */ -- if (wwpn == els_wwpn) { -- ret = fpin_path_setmarginal(pp); -- if (ret < 0) -- goto unref; -- fpin_set_rport_marginal(rport_dev); -- fpin_add_marginal_dev_info(host_num, pp->dev); -+ /*checks if the bus type is nvme and the protocol is FC-NVMe*/ -+ if ((pp->bus == SYSFS_BUS_NVME) && (pp->sg_id.proto_id == NVME_PROTOCOL_FC)) { -+ fpin_check_set_nvme_path_marginal(host_num, pp, els_wwpn, attached_wwpn); -+ } else if ((pp->bus == SYSFS_BUS_SCSI) && -+ (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP) && -+ (host_num == pp->sg_id.host_no)) { -+ /* Checks the host number and also for the SCSI FCP */ -+ fpin_check_set_scsi_path_marginal(host_num, pp, els_wwpn); - } --unref: -- pthread_cleanup_pop(1); - } - /* walk backwards because update_path_groups() can remove mpp */ - vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { -@@ -279,14 +371,18 @@ fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, - struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; - int count = 0; - int ret = 0; -+ uint64_t attached_wwpn; - - /* Update the wwn to list */ - wwn_count = be32_to_cpu(li_desc->pname_count); -- condlog(4, "Got wwn count as %d\n", wwn_count); -+ attached_wwpn = be64_to_cpu(li_desc->attached_wwpn); -+ condlog(4, "Got wwn count as %d detecting wwn 0x%" PRIx64 -+ " attached_wwpn 0x%" PRIx64 "\n", -+ wwn_count, be64_to_cpu(li_desc->detecting_wwpn), attached_wwpn); - - for (iter = 0; iter < wwn_count; iter++) { - wwpn = be64_to_cpu(li_desc->pname_list[iter]); -- ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); -+ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn, attached_wwpn); - if (ret < 0) - condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); - diff --git a/SOURCES/0137-multipathd-Make-sure-to-disable-queueing-if-recovery.patch b/SOURCES/0137-multipathd-Make-sure-to-disable-queueing-if-recovery.patch deleted file mode 100644 index 1f87568..0000000 --- a/SOURCES/0137-multipathd-Make-sure-to-disable-queueing-if-recovery.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 22 Nov 2023 16:41:22 -0500 -Subject: [PATCH] multipathd: Make sure to disable queueing if recovery has - failed. - -If a multipath device has no_path_retry set to a number and has lost all -paths, gone into recovery mode, and timed out, it will disable -queue_if_no_paths. After that, if the device is reloaded by multipath -outside of multipathd, it will re-enable queuieng on the device. When -multipathd later calls set_no_path_retry() to update the queueing state, -it will not disable queue_if_no_paths, since the device is still in the -recovery state, so it believes no work needs to be done. The device will -remain in the recovery state, with retry_ticks at 0, and queueing -enabled, even though there are no usable paths. - -To fix this, in set_no_path_retry(), if no_path_retry is set to a number -and the device is queueing but it is in recovery mode and out of -retries with no usable paths, manually disable queue_if_no_path. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 26 ++++++++++++++++++++++++-- - 1 file changed, 24 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 9613252f..0304777b 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -377,8 +377,19 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features) - !mpp->in_recovery) - dm_queue_if_no_path(mpp->alias, 1); - leave_recovery_mode(mpp); -- } else -- enter_recovery_mode(mpp); -+ } else { -+ /* -+ * If in_recovery is set, enter_recovery_mode does -+ * nothing. If the device is already in recovery -+ * mode and has already timed out, manually call -+ * dm_queue_if_no_path to stop it from queueing. -+ */ -+ if ((!mpp->features || is_queueing) && -+ mpp->in_recovery && mpp->retry_tick == 0) -+ dm_queue_if_no_path(mpp->alias, 0); -+ if (pathcount(mpp, PATH_PENDING) == 0) -+ enter_recovery_mode(mpp); -+ } - break; - } - } -@@ -521,6 +532,11 @@ int verify_paths(struct multipath *mpp, struct vectors *vecs) - * -1 (FAIL) : fail_if_no_path - * 0 (UNDEF) : nothing - * >0 : queue_if_no_path enabled, turned off after polling n times -+ * -+ * Since this will only be called when fail_path(), update_multipath(), or -+ * io_err_stat_handle_pathfail() are failing a previously active path, the -+ * device cannot already be in recovery mode, so there will never be a need -+ * to disable queueing here. - */ - void update_queue_mode_del_path(struct multipath *mpp) - { -@@ -534,6 +550,12 @@ void update_queue_mode_del_path(struct multipath *mpp) - condlog(2, "%s: remaining active paths: %d", mpp->alias, active); - } - -+/* -+ * Since this will only be called from check_path() -> reinstate_path() after -+ * the queueing state has been updated in set_no_path_retry, this does not -+ * need to worry about modifying the queueing state except when actually -+ * leaving recovery mode. -+ */ - void update_queue_mode_add_path(struct multipath *mpp) - { - int active = count_active_paths(mpp); diff --git a/SPECS/device-mapper-multipath.spec b/device-mapper-multipath.spec similarity index 67% rename from SPECS/device-mapper-multipath.spec rename to device-mapper-multipath.spec index 004b3d4..27106ea 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,172 +1,63 @@ +Name: device-mapper-multipath +Version: 0.9.9 +Release: 6%{?dist} Summary: Tools to manage multipath devices using device-mapper -Name: device-mapper-multipath -Version: 0.8.4 -Release: 42%{?dist} License: GPLv2 -Group: System Environment/Base -URL: http://christophe.varoqui.free.fr/ +URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -#curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.4;sf=tgz" -o multipath-tools-0.8.4.tgz -Source0: multipath-tools-0.8.4.tgz +# curl -L https://github.com/opensvc/multipath-tools/archive/0.9.9.tar.gz -o multipath-tools-0.9.9.tgz +Source0: multipath-tools-0.9.9.tgz Source1: multipath.conf -Patch00001: 0001-libmultipath-assign-variable-to-make-gcc-happy.patch -Patch00002: 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch -Patch00003: 0003-libmultipath-allow-force-reload-with-no-active-paths.patch -Patch00004: 0004-libmpathpersist-depend-on-libmultipath.patch -Patch00005: 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch -Patch00006: 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch -Patch00007: 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch -Patch00008: 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch -Patch00009: 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch -Patch00010: 0010-multipath-tools-Makefile-add-install-dependency.patch -Patch00011: 0011-RH-fixup-udev-rules-for-redhat.patch -Patch00012: 0012-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch00013: 0013-RH-don-t-start-without-a-config-file.patch -Patch00014: 0014-RH-use-rpm-optflags-if-present.patch -Patch00015: 0015-RH-add-mpathconf.patch -Patch00016: 0016-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch00017: 0017-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch00018: 0018-RH-reset-default-find_mutipaths-value-to-off.patch -Patch00019: 0019-RH-Fix-nvme-compilation-warning.patch -Patch00020: 0020-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch00021: 0021-libmultipath-remove-_blacklist_exceptions-functions.patch -Patch00022: 0022-libmultipath-fix-parser-issue-with-comments-in-strin.patch -Patch00023: 0023-libmultipath-invert-regexes-that-start-with-exclamat.patch -Patch00024: 0024-libmultipath-make-dm_get_map-status-return-codes-sym.patch -Patch00025: 0025-multipathd-fix-check_path-errors-with-removed-map.patch -Patch00026: 0026-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch -Patch00027: 0027-multipathd-add-del-maps-multipathd-command.patch -Patch00028: 0028-multipath-make-flushing-maps-work-like-other-command.patch -Patch00029: 0029-multipath-delegate-flushing-maps-to-multipathd.patch -Patch00030: 0030-multipath-add-option-to-skip-multipathd-delegation.patch -Patch00031: 0031-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch -Patch00032: 0032-kpartx-read-devices-with-direct-IO.patch -Patch00033: 0033-kpartx-handle-alternate-bsd-disklabel-location.patch -Patch00034: 0034-libmultipath-fix-checker-detection-for-nvme-devices.patch -Patch00035: 0035-Makefile.inc-trim-extra-information-from-systemd-ver.patch -Patch00036: 0036-kpartx-fix-Wsign-compare-error.patch -Patch00037: 0037-libmultipath-count-pending-paths-as-active-on-loads.patch -Patch00038: 0038-multipath-deal-with-failures-flushing-maps.patch -Patch00039: 0039-libmultipath-factor-out-code-to-get-vpd-page-data.patch -Patch00040: 0040-libmultipath-limit-reading-0xc9-vpd-page.patch -Patch00041: 0041-libmultipath-add-device-to-hwtable.c.patch -Patch00042: 0042-libmultipath-move-fast_io_fail-defines-to-structs.h.patch -Patch00043: 0043-libmultipath-add-eh_deadline-multipath.conf-paramete.patch -Patch00044: 0044-libmultipath-don-t-dlclose-tur-checker-DSO.patch -Patch00045: 0045-libmultipath-warn-about-missing-braces-at-end-of-mul.patch -Patch00046: 0046-libmultipath-ignore-multipaths-sections-without-wwid.patch -Patch00047: 0047-tests-fix-missing-priority-blacklist-test.patch -Patch00048: 0048-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch -Patch00049: 0049-mpathpersist-update-prkeys-file-on-changing-registra.patch -Patch00050: 0050-multipathd-Fix-multipathd-stopping-on-shutdown.patch -Patch00051: 0051-multipath.conf.5-Improve-checker_timeout-description.patch -Patch00052: 0052-libmultipath-check-for-null-wwid-before-strcmp.patch -Patch00053: 0053-libmultipath-make-find_err_path_by_dev-static.patch -Patch00054: 0054-multipathd-avoid-io_err_stat-crash-during-shutdown.patch -Patch00055: 0055-multipathd-avoid-io_err_stat-ABBA-deadlock.patch -Patch00056: 0056-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch -Patch00057: 0057-multipathd-combine-free_io_err_stat_path-and-destroy.patch -Patch00058: 0058-multipathd-cleanup-logging-for-marginal-paths.patch -Patch00059: 0059-libmpathpersist-fix-thread-safety-of-default-functio.patch -Patch00060: 0060-kpartx-free-loop-device-after-listing-partitions.patch -Patch00061: 0061-RH-fix-find_multipaths-in-mpathconf.patch -Patch00062: 0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch -Patch00063: 0063-libmultipath-check-if-user_friendly_name-is-in-use.patch -Patch00064: 0064-libmultipath-check-udev_device_get_-return-value-to-.patch -Patch00065: 0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch -Patch00066: 0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch -Patch00067: 0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch -Patch00068: 0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch -Patch00069: 0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -Patch00070: 0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch -Patch00071: 0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch -Patch00072: 0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch -Patch00073: 0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch -Patch00074: 0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch -Patch00075: 0075-multipath-print-warning-if-multipathd-is-not-running.patch -Patch00076: 0076-multipathd-don-t-access-path-if-it-was-deleted.patch -Patch00077: 0077-multipathd.socket-add-missing-conditions-from-servic.patch -Patch00078: 0078-libmulitpath-add-section-name-to-invalid-keyword-out.patch -Patch00079: 0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch -Patch00080: 0080-libmultipath-print-the-correct-file-when-parsing-fai.patch -Patch00081: 0081-libmultipath-pass-file-and-line-number-to-keyword-ha.patch -Patch00082: 0082-libmultipath-make-set_int-take-a-range-for-valid-val.patch -Patch00083: 0083-libmultipath-improve-checks-for-set_str.patch -Patch00084: 0084-libmultipath-split-set_int-to-enable-reuse.patch -Patch00085: 0085-libmultipath-cleanup-invalid-config-handling.patch -Patch00086: 0086-libmultipath-don-t-return-error-on-invalid-values.patch -Patch00087: 0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch -Patch00088: 0088-libmultipath-make-helper-function-to-trigger-path-ue.patch -Patch00089: 0089-multipathd-trigger-udev-change-on-path-addition.patch -Patch00090: 0090-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch -Patch00091: 0091-multipath-tools-add-HPE-MSA-1060-2060-to-hwtable.patch -Patch00092: 0092-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch -Patch00093: 0093-updated-HPE-MSA-builtin-config.patch -Patch00094: 0094-multipath-return-failure-on-an-invalid-remove-comman.patch -Patch00095: 0095-libmultipath-steal-the-src-string-pointer-in-merge_s.patch -Patch00096: 0096-libmultipath-enable-linear-ordering-of-bus-proto-tup.patch -Patch00097: 0097-libmultipath-use-bus_protocol_id-in-snprint_path_pro.patch -Patch00098: 0098-libmultipath-make-protocol_name-global.patch -Patch00099: 0099-libmultipath-add-a-protocol-subsection-to-multipath..patch -Patch00100: 0100-libmultipath-Set-the-scsi-timeout-parameters-by-path.patch -Patch00101: 0101-libmultipath-check-the-overrides-pctable-for-path-va.patch -Patch00102: 0102-libmultipath-fix-eh_deadline-documentation.patch -Patch00103: 0103-libmultipath-Add-documentation-for-the-protocol-subs.patch -Patch00104: 0104-libmultipath-use-symbolic-value-for-invalid-pcentry.patch -Patch00105: 0105-multipathd-handle-fpin-events.patch -Patch00106: 0106-multipathd-disallow-changing-to-from-fpin-marginal-p.patch -Patch00107: 0107-libmultipath-unset-detect_checker-for-clariion-Unity.patch -Patch00108: 0108-multipathd-Add-missing-ctype-include.patch -Patch00109: 0109-multipathd-replace-libreadline-with-libedit.patch -Patch00110: 0110-multipath-fix-systemd-timers-in-the-initramfs.patch -Patch00111: 0111-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch -Patch00112: 0112-libmultipath-return-success-if-we-raced-to-remove-a-.patch -Patch00113: 0113-multipathd-Handle-losing-all-path-in-update_map.patch -Patch00114: 0114-multipathd-ignore-duplicated-multipathd-command-keys.patch -Patch00115: 0115-multipath-tools-use-run-instead-of-dev-shm.patch -Patch00116: 0116-kpartx-hold-device-open-until-partitions-have-been-c.patch -Patch00117: 0117-libmultipath-cleanup-remove_feature.patch -Patch00118: 0118-libmultipath-cleanup-add_feature.patch -Patch00119: 0119-multipath-tests-tests-for-adding-and-removing-featur.patch -Patch00120: 0120-libmultipath-fix-queue_mode-feature-handling.patch -Patch00121: 0121-multipath-tests-tests-for-reconcile_features_with_qu.patch -Patch00122: 0122-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch -Patch00123: 0123-libmultipath-get-nvme-path-transport-protocol.patch -Patch00124: 0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch -Patch00125: 0125-multipath-add-historical-service-time-to-the-man-pag.patch -Patch00126: 0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch -Patch00127: 0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch -Patch00128: 0128-libmutipath-validate-the-argument-count-of-config-st.patch -Patch00129: 0129-libmultipath-select-resize-action-even-if-reload-is-.patch -Patch00130: 0130-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch -Patch00131: 0131-libmultipath-keep-renames-from-stopping-other-multip.patch -Patch00132: 0132-multipathd-make-pr-registration-consistent.patch -Patch00133: 0133-libmultipath-make-prflag-an-enum.patch -Patch00134: 0134-multipathd-handle-no-active-paths-in-update_map_pr.patch -Patch00135: 0135-libmpathpersist-fix-resource-leak-in-update_map_pr.patch -Patch00136: 0136-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch -Patch00137: 0137-multipathd-Make-sure-to-disable-queueing-if-recovery.patch -Patch00138: 0138-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +Patch0001: 0001-multipathd-fix-flush-check-in-flush_map.patch +Patch0002: 0002-RH-fixup-udev-rules-for-redhat.patch +Patch0003: 0003-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0004: 0004-RH-don-t-start-without-a-config-file.patch +Patch0005: 0005-RH-Fix-nvme-function-missing-argument.patch +Patch0006: 0006-RH-use-rpm-optflags-if-present.patch +Patch0007: 0007-RH-add-mpathconf.patch +Patch0008: 0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0009: 0009-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0010: 0010-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0011: 0011-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0012: 0012-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0013: 0013-RH-compile-with-libreadline-support.patch +Patch0014: 0014-RH-Add-mpathcleanup.patch +Patch0015: 0015-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch +Patch0016: 0016-multipathd-checker-port_state-before-setting-it.patch +Patch0017: 0017-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu -Requires: libedit +Requires: readline +Requires: libmount Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units +# Starting with 0.7.7-1, 62-multipath.rules changed in a way that is +# incompatible with 65-md-incremental.rules in earlier mdadm packages. +# Later mdadm packages are compatible with any version of +# device-mapper-multipath. See bz #1628192 for more details +Conflicts: mdadm < 4.1-rc2.0.2 +# Starting with 0.7.7-1, 62-multipath.rules changed in a way that is +# incompatible with 80-udisks2.rules in earlier udisks2 packages. +# Later udisks2 packages are compatible with any version of +# device-mapper-multipath. See bz #1628192 for more details +Conflicts: udisks2 < 2.8.0-2 # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 BuildRequires: libselinux-devel, libsepol-devel -BuildRequires: libedit-devel, ncurses-devel +BuildRequires: readline-devel, ncurses-devel BuildRequires: systemd-units, systemd-devel BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc BuildRequires: userspace-rcu-devel +BuildRequires: libmount-devel +BuildRequires: make %description %{name} provides tools to manage multipath devices by @@ -177,7 +68,6 @@ The tools are : %package libs Summary: The %{name} modules and shared library -Group: System Environment/Libraries # only libmpathcmd is LGPLv2+ License: GPLv2 and LGPLv2+ @@ -189,7 +79,6 @@ libmultipath. %package devel Summary: Development libraries and headers for %{name} -Group: Development/Libraries Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} @@ -199,14 +88,12 @@ device-mapper-multipath's lbmpathpersist and libmpathcmd libraries. %package -n kpartx Summary: Partition device manager for device-mapper devices -Group: System Environment/Base %description -n kpartx kpartx manages partition creation and removal for device-mapper devices. %package -n libdmmp Summary: device-mapper-multipath C API library -Group: System Environment/Libraries License: GPLv3+ Requires: json-c Requires: %{name} = %{version}-%{release} @@ -218,7 +105,6 @@ C API library. %package -n libdmmp-devel Summary: device-mapper-multipath C API library headers -Group: Development/Libraries Requires: pkgconfig Requires: libdmmp = %{version}-%{release} @@ -227,7 +113,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.4 -p1 +%autosetup -n multipath-tools-0.9.9 -p1 cp %{SOURCE1} . %build @@ -235,16 +121,15 @@ cp %{SOURCE1} . %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig -make %{?_smp_mflags} LIB=%{_lib} +%make_build LIB=%{_lib} %install -make install \ - DESTDIR=%{buildroot} \ +%make_install \ bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ - libdir=%{_libmpathdir} \ - rcdir=%{_initrddir} \ + plugindir=%{_libmpathdir} \ + mandir=%{_mandir} \ unitdir=%{_unitdir} \ includedir=%{_includedir} \ pkgconfdir=%{_pkgconfdir} \ @@ -273,412 +158,426 @@ fi /bin/systemctl --quiet is-enabled multipathd.service >/dev/null 2>&1 && /bin/systemctl reenable multipathd.service ||: %files -%defattr(-,root,root,-) +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/GPL-3.0 %{_sbindir}/multipath %{_sbindir}/multipathd +%{_sbindir}/multipathc %{_sbindir}/mpathconf +%{_sbindir}/mpathcleanup %{_sbindir}/mpathpersist %{_unitdir}/multipathd.service %{_unitdir}/multipathd.socket -%{_mandir}/man5/multipath.conf.5.gz -%{_mandir}/man8/multipath.8.gz -%{_mandir}/man8/multipathd.8.gz -%{_mandir}/man8/mpathconf.8.gz -%{_mandir}/man8/mpathpersist.8.gz -%config %{_udevrulesdir}/62-multipath.rules -%config %{_udevrulesdir}/11-dm-mpath.rules +%{_mandir}/man5/multipath.conf.5* +%{_mandir}/man8/multipath.8* +%{_mandir}/man8/multipathd.8* +%{_mandir}/man8/multipathc.8* +%{_mandir}/man8/mpathconf.8* +%{_mandir}/man8/mpathpersist.8* +%config /usr/lib/udev/rules.d/62-multipath.rules +%config /usr/lib/udev/rules.d/11-dm-mpath.rules +%config /usr/lib/udev/rules.d/99-z-dm-mpath-late.rules +%dir %{_modulesloaddir} +%{_modulesloaddir}/scsi_dh.conf %{_tmpfilesdir}/multipath.conf -%{!?_licensedir:%global license %%doc} -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 -%doc README -%doc README.alua +%doc README.md %doc multipath.conf %dir /etc/multipath %files libs -%defattr(-,root,root,-) -%doc README -%{!?_licensedir:%global license %%doc} -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 LICENSES/LGPL-2.1 +%doc README.md %{_libdir}/libmultipath.so %{_libdir}/libmultipath.so.* +%{_libdir}/libmpathutil.so +%{_libdir}/libmpathutil.so.* %{_libdir}/libmpathpersist.so.* %{_libdir}/libmpathcmd.so.* +%{_libdir}/libmpathvalid.so.* %dir %{_libmpathdir} %{_libmpathdir}/* -%post libs -p /sbin/ldconfig - -%postun libs -p /sbin/ldconfig +%ldconfig_scriptlets libs %files devel -%defattr(-,root,root,-) -%doc README LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%doc README.md %{_libdir}/libmpathpersist.so %{_libdir}/libmpathcmd.so +%{_libdir}/libmpathvalid.so %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h -%{_mandir}/man3/mpath_persistent_reserve_in.3.gz -%{_mandir}/man3/mpath_persistent_reserve_out.3.gz +%{_includedir}/mpath_valid.h +%{_mandir}/man3/mpath_persistent_reserve_in.3* +%{_mandir}/man3/mpath_persistent_reserve_out.3* %files -n kpartx -%defattr(-,root,root,-) -%doc README -%{!?_licensedir:%global license %%doc} %license LICENSES/GPL-2.0 +%doc README.md %{_sbindir}/kpartx -%{_udevrulesdir}/../kpartx_id -%{_mandir}/man8/kpartx.8.gz -%config %{_udevrulesdir}/11-dm-parts.rules -%config %{_udevrulesdir}/66-kpartx.rules -%config %{_udevrulesdir}/68-del-part-nodes.rules +/usr/lib/udev/kpartx_id +%{_mandir}/man8/kpartx.8* +%config /usr/lib/udev/rules.d/11-dm-parts.rules +%config /usr/lib/udev/rules.d/66-kpartx.rules +%config /usr/lib/udev/rules.d/68-del-part-nodes.rules %files -n libdmmp -%defattr(-,root,root,-) -%doc README LICENSES/GPL-3.0 +%license LICENSES/GPL-3.0 +%doc README.md %{_libdir}/libdmmp.so.* -%post -n libdmmp -p /sbin/ldconfig - -%postun -n libdmmp -p /sbin/ldconfig +%ldconfig_scriptlets -n libdmmp %files -n libdmmp-devel -%defattr(-,root,root,-) -%doc README LICENSES/GPL-3.0 +%doc README.md %{_libdir}/libdmmp.so %dir %{_includedir}/libdmmp %{_includedir}/libdmmp/* %{_mandir}/man3/dmmp_* -%{_mandir}/man3/libdmmp.h.3.gz +%{_mandir}/man3/libdmmp.h.3* %{_pkgconfdir}/libdmmp.pc %changelog -* Thu Jan 9 2025 Benjamin Marzinski 0.8.4-42 -- Add 0138-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch -- Resolves: RHEL-72573 +* Thu Jan 9 2025 Benjamin Marzinski - 0.9.9-6 +- Add 0017-libmultipath-foreign-fix-memory-leak-in-nvme-foreign.patch +- Resolves: RHEL-73410 -* Fri Jan 5 2024 Benjamin Marzinski 0.8.4-41 -- Add 0137-multipathd-Make-sure-to-disable-queueing-if-recovery.patch -- Resolves: RHEL-16563 +* Mon Nov 11 2024 Benjamin Marzinski - 0.9.9-5 +- Add 0016-multipathd-checker-port_state-before-setting-it.patch +- Resolves: RHEL-53995 -* Thu Nov 2 2023 Benjamin Marzinski 0.8.4-40 -- Add 0136-multipathd-Added-support-to-handle-FPIN-Li-events-fo.patch - * Add support in multipathd for NVMe to listen for FPIN-Li events and - mark effected paths as marginal -- Resolves: RHEL-6677 +* Tue Oct 29 2024 Troy Dawson - 0.9.9-4 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 -* Thu Mar 16 2023 Benjamin Marzinski 0.8.4-39 -- Add OSCI tests directory -- Make kpartx_id installation location relative to %{_udevrulesdir} -- Resolves: bz #2164871 +* Fri Sep 13 2024 Benjamin Marzinski - 0.9.9-3 +- Add 0015-libmultipath-fix-ontap-prioritizer-snprintf-limits.patch +- Resolves: RHEL-49747 -* Wed Mar 15 2023 Benjamin Marzinski 0.8.4-38 -- Add 0132-multipathd-make-pr-registration-consistent.patch -- Add 0133-libmultipath-make-prflag-an-enum.patch -- Add 0134-multipathd-handle-no-active-paths-in-update_map_pr.patch -- Add 0135-libmpathpersist-fix-resource-leak-in-update_map_pr.patch -- Resolves: bz #2164871 +* Thu Sep 12 2024 Benjamin Marzinski - 0.9.9-2 +- Improve multiple OSCI tests -* Fri Feb 3 2023 Benjamin Marzinski 0.8.4-37 -- Fix bugzilla linked to the changes (was previously linked to - the wrong bug, 2162537) -- Resolves: bz #2166468 +* Fri Jul 26 2024 Benjamin Marzinski - 0.9.9-1 +- Update source to upstream version 0.9.9 + * Previous patches 0014-0015 are included in the soruce tarball + * Patch 0001 is from the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0013 are now 0002-0014 +- Install /lib/udev/rules.d/99-z-dm-mpath-late.rules +- Resolves: RHEL-50698 -* Wed Feb 1 2023 Benjamin Marzinski 0.8.4-36 -- Add 0129-libmultipath-select-resize-action-even-if-reload-is-.patch -- Add 0130-libmultipath-cleanup-ACT_CREATE-code-in-select_actio.patch -- Add 0131-libmultipath-keep-renames-from-stopping-other-multip.patch -- Resolves: bz #2166468 +* Fri Jun 28 2024 Benjamin Marzinski - 0.9.7-10 +- Fix CI tests -* Mon Jan 16 2023 Benjamin Marzinski 0.8.4-35 -- Add 0127-libmultipath-don-t-leak-memory-on-invalid-strings.patch -- Add 0128-libmutipath-validate-the-argument-count-of-config-st.patch -- Resolves: bz #2155560 +* Mon Jun 24 2024 Benjamin Marzinski - 0.9.7-9 +- Add gating.yaml -* Tue Nov 29 2022 Benjamin Marzinski 0.8.4-34 -- Add 0126-libmultipath-copy-mpp-hwe-from-pp-hwe.patch - * Fixes bz #2126714 -- Cleanup multiple CI tests -- Resolves: bz #2126714 +* Mon Jun 24 2024 Troy Dawson - 0.9.7-8 +- Bump release for June 2024 mass rebuild -* Wed Nov 23 2022 Benjamin Marzinski 0.8.4-33 -- Add 0125-multipath-add-historical-service-time-to-the-man-pag.patch - * Fixes bz #2141996 -- Modify tests/multipath_conf_syntax/main.sh - * fix unrelated test error -- Resolves: bz #2141996 +* Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Thu Nov 10 2022 Benjamin Marzinski 0.8.4-32 -- Add 0116-kpartx-hold-device-open-until-partitions-have-been-c.patch - * Fixes bz #2128885 -- Add 0117-libmultipath-cleanup-remove_feature.patch -- Add 0118-libmultipath-cleanup-add_feature.patch -- Add 0119-multipath-tests-tests-for-adding-and-removing-featur.patch -- Add 0120-libmultipath-fix-queue_mode-feature-handling.patch -- Add 0121-multipath-tests-tests-for-reconcile_features_with_qu.patch -- Add 0122-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch -- Add 0123-libmultipath-get-nvme-path-transport-protocol.patch -- Add 0124-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch - * Fixes bz #2022359 -- Resolves: bz #2022359, #2128885 +* Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild -* Thu Oct 13 2022 Benjamin Marzinski 0.8.4-31 -- Add 0114-multipathd-ignore-duplicated-multipathd-command-keys.patch - * Fixes bz #2133996 -- Add 0115-multipath-tools-use-run-instead-of-dev-shm.patch - * Fixes bz #2133990 -- Resolves: bz #2133990, #2133996 +* Tue Jan 16 2024 Benjamin Marzinski - 0.9.7-5 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * Fix auto_resize code to avoid a segfault +- Add 0015-multipathd-fix-auto-resize-configuration.patch + * Fix auto_resize default value -* Fri Sep 9 2022 Benjamin Marzinski 0.8.4-30 -- Add 0111-multipathd-factor-out-the-code-to-flush-a-map-with-n.patch -- Add 0112-libmultipath-return-success-if-we-raced-to-remove-a-.patch -- Add 0113-multipathd-Handle-losing-all-path-in-update_map.patch -- Resolves: bz #2110485 +* Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 +- Use modulesloaddir macro for installing scsi_dh.conf -* Fri Sep 2 2022 Benjamin Marzinski 0.8.4-29 -- Rebuild for rhel-8.8.0 -- Resolves: bz #2123446 +* Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 +- Fix multipath_conf_syntax test +- Fix restate_module test -* Wed Aug 24 2022 Benjamin Marzinski 0.8.4-28 -- Add 0110-multipath-fix-systemd-timers-in-the-initramfs.patch -- Resolves: bz #1916168 +* Tue Nov 28 2023 Paul Donohue - 0.9.7-2 +- Modify 0006-RH-add-mpathconf.patch +- Modify 0008-RH-reset-default-find_mutipaths-value-to-off.patch + * Fix find_multipaths values in docs and mpathconf -* Fri Aug 19 2022 Benjamin Marzinski 0.8.4-27 -- Add 0108-multipathd-Add-missing-ctype-include.patch -- Add 0109-multipathd-replace-libreadline-with-libedit.patch - * replace readline with libedit, to avoid license conflicts -- Resolves: bz #2119887 +* Tue Nov 21 2023 Benjamin Marzinski - 0.9.7-1 +- Update source to upstream version 0.9.7 + * Previous patches 0001-0040 are included in the source tarball +- Rename redhat patches + * Previous patches 0041-0053 are now patches 0001-0013 +- Remove /usr/lib/modules-load.d/multipath.conf + * has been replaced with modprobe@dm_multipath.service unit Wants. -* Wed Jun 8 2022 Benjamin Marzinski 0.8.4-26 -- Add 0107-libmultipath-unset-detect_checker-for-clariion-Unity.patch -- Resolves: bz #2082205 +* Fri Sep 22 2023 Benjamin Marzinski - 0.9.6-1 +- Update to the head of the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0012 are now patches 0041-0052 +- Add 0053-RH-Add-mpathcleanup.patch + * add mpathcleanup program -* Tue May 17 2022 Benjamin Marzinski 0.8.4-25 -- Add 0105-multipathd-handle-fpin-events.patch -- Add 0106-multipathd-disallow-changing-to-from-fpin-marginal-p.patch -- Resolves: bz #2083077 +* Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild -* Mon May 16 2022 Benjamin Marzinski 0.8.4-24 -- Add 0094-multipath-return-failure-on-an-invalid-remove-comman.patch - * Fixes bz #2052054 -- Add 0095-libmultipath-steal-the-src-string-pointer-in-merge_s.patch -- Add 0096-libmultipath-enable-linear-ordering-of-bus-proto-tup.patch -- Add 0097-libmultipath-use-bus_protocol_id-in-snprint_path_pro.patch -- Add 0098-libmultipath-make-protocol_name-global.patch -- Add 0099-libmultipath-add-a-protocol-subsection-to-multipath..patch -- Add 0100-libmultipath-Set-the-scsi-timeout-parameters-by-path.patch -- Add 0101-libmultipath-check-the-overrides-pctable-for-path-va.patch -- Add 0102-libmultipath-fix-eh_deadline-documentation.patch -- Add 0103-libmultipath-Add-documentation-for-the-protocol-subs.patch -- Add 0104-libmultipath-use-symbolic-value-for-invalid-pcentry.patch - * The above 10 patches implement feature from bz #2065477 -- Resolves: bz #2052054, #2065477 +* Tue May 16 2023 Benjamin Marzinski - 0.9.5-1 +- Update to the latest upstream release + * Previous patches 0001-0015 are included in the source tarball +- Rename redhat patches + * Previous patches 0016-0027 are now patches 0001-0012 -* Tue May 10 2022 Benjamin Marzinski 0.8.4-23 -- Add 0091-multipath-tools-add-HPE-MSA-1060-2060-to-hwtable.patch - * Partial fix for bz #2058222 -- Add 0092-multipath-tools-update-mpp-force_readonly-in-ev_add_.patch - * Fixes bz #2065468 -- Add 0093-updated-HPE-MSA-builtin-config.patch - * Fixes bz #2058222 -- Resolves bz #2065468, #2058222 +* Thu Feb 2 2023 Benjamin Marzinski - 0.9.4-2 +- Update to the head of the upstream staging branch + * Patches 0011-0015 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0011-0022 are now patches 0016-0027 -* Mon Feb 7 2022 Benjamin Marzinski 0.8.4-22 -- Add 0090-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch -- Resolves: bz #1981240 +* Thu Jan 26 2023 Benjamin Marzinski - 0.9.4-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0032 are included in the source tarball + * Patches 0001-0010 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0033-0044 are now patches 0011-0022 +- Add dependency on libmount -* Tue Jan 18 2022 Benjamin Marzinski 0.8.4-21 -- Add 0088-libmultipath-make-helper-function-to-trigger-path-ue.patch -- Add 0089-multipathd-trigger-udev-change-on-path-addition.patch -- Resolves: bz #1862032 +* Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild -* Thu Nov 18 2021 Benjamin Marzinski 0.8.4-20 -- Add 0079-libmultipath-use-typedef-for-keyword-handler-and-pri.patch -- Add 0080-libmultipath-print-the-correct-file-when-parsing-fai.patch -- Add 0081-libmultipath-pass-file-and-line-number-to-keyword-ha.patch -- Add 0082-libmultipath-make-set_int-take-a-range-for-valid-val.patch -- Add 0083-libmultipath-improve-checks-for-set_str.patch -- Add 0084-libmultipath-split-set_int-to-enable-reuse.patch -- Add 0085-libmultipath-cleanup-invalid-config-handling.patch -- Add 0086-libmultipath-don-t-return-error-on-invalid-values.patch - * Above 8 patches fix bz #1900595 -- Add 0087-multipathd-avoid-unnecessary-path-read-only-reloads.patch - * Fixes bz #2009624 -- Resolves: bz #1900595, #2009624, #2021823 +* Tue Nov 15 2022 Benjamin Marzinski - 0.9.3-1 +- Update to the head of the upstream staging branch + * Previous patches 0001-0042 are included in the source tarball + * Patches 0001-0032 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0043-0053 are now patches 0033-0043 +- Change back to using readline instead of libedit + * The code the uses readline has been isolated from the code that + is licensed gpl v2 only. +- Add libmpathutil libraries to spec file +- Add multipathc program to spec file +- Add multipath.conf systemd tempfile configuration to spec file +- Misc spec file cleanups -* Thu Oct 28 2021 Benjamin Marzinski 0.8.4-19 -- Fix multipath_conf_syntax test to work with bz #1918150 -- Resolves: bz #1918150 +* Fri Aug 19 2022 Benjamin Marzinski - 0.9.0-3 +- Update to the head of the upstream staging branch + * Patches 0005-0042 are from the upstream staging branch + * Previous patches 0005 & 0006 are now patches 0023 & 0005 +- Rename redhat patches + * Previous patches 0007-0017 are now patches 0043-0053 +- Change from using readline to libedit + * readline is licensed GPL v3, and multipathd includes code + licensed gpl v2. +- Remove README.alua + * information moved to README.md -* Thu Oct 7 2021 Benjamin Marzinski 0.8.4-18 -- Add 0077-multipathd.socket-add-missing-conditions-from-servic.patch - * Fixes bz #2008101 -- Add 0078-libmulitpath-add-section-name-to-invalid-keyword-out.patch - * Fixes bz #1918150 -- Resolves: bz #1918150, #2008101 +* Thu Jul 21 2022 Fedora Release Engineering - 0.9.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild -* Fri Jul 23 2021 Benjamin Marzinski 0.8.4-17 -- Add 0074-mpathpersist-fail-commands-when-no-usable-paths-exis.patch - * Fixes bz #1984723 -- Add 0075-multipath-print-warning-if-multipathd-is-not-running.patch - * Fixes bz #1973592 -- Add 0076-multipathd-don-t-access-path-if-it-was-deleted.patch - * Found by coverity -- Resolves: bz #1973592, #1984723 +* Wed Jul 13 2022 Benjamin Marzinski - 0.9.0-1 +- Update source to upstream version 0.9.0 + * Previous patches 0001-0005 are included in the commit. + * This version deprecates multiple options: mutlipath_dir, config_dir, and + getuid_callout, along with the "default_" prefixed alternate names for the + default section parameters. +- Add patches from upstream staging branch + * Patches 0001-0006 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0006-0016 are now patches 0007-0017 -* Thu Jul 22 2021 Benjamin Marzinski 0.8.4-16 -- Add missing patch -- Related: bz #1982598 +* Mon Mar 28 2022 Benjamin Marzinski - 0.8.9-1 +- Update source to upstream version 0.8.9 + * Previous patches 0001-0024 & 0035 are included in the commit. +- Add patches from upstream staging branch + * Patches 0001-0005 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0025-0034 are now patches 0006-0015 +- Combine redhat patches + * Previous patches 0036 & 0037 are now part of patch 0011 +- Add 0016-RH-add-scsi-device-handlers-to-modules-load.d.patch +- Spec file changes + * Install multipath.conf and scsi_dh.conf to /usr/lib/modules-load.d -* Thu Jul 22 2021 Benjamin Marzinski 0.8.4-15 -- Add 0073-multipath.conf-fix-typo-in-checker_timeout-descripti.patch -- Resolves: bz #1982598 +* Mon Feb 7 2022 Benjamin Marzinski - 0.8.7-8 +- Add 0036-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch + * add the ability for mpathconf to set arbitray options with --option +- Add 0037-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch + * add --recheck_wwid option to mpathconf -* Mon Jul 12 2021 Benjamin Marzinski 0.8.4-14 -- Add 0072-RH-mpathconf-correctly-handle-spaces-after-option-na.patch -- Resolves: bz #1979470 +* Wed Jan 26 2022 Benjamin Marzinski - 0.8.7-7 +- Add 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch +- Resolves: bz #2045309 -* Wed Apr 28 2021 Benjamin Marzinski 0.8.4-13 -- Add 0065-libmultipath-cleanup-code-to-strip-wwid-trailing-spa.patch -- Add 0066-multipathd-add-recheck_wwid-option-to-verify-the-pat.patch -- Add 0067-libmultipath-avoid-infinite-loop-with-bad-vpd-page-8.patch -- Add 0068-libmultipath-fix-priorities-in-parse_vpd_pg83.patch -- Add 0069-RH-make-parse_vpd_pg83-match-scsi_id-output.patch -- Add 0070-multipathd-improve-getting-parent-udevice-in-rescan_.patch -- Add 0071-multipathd-don-t-trigger-uevent-for-partitions-on-ww.patch - * add recheck_wwid option - * Fixes bz #1907904 -- Resolves: bz #1907904 +* Thu Jan 20 2022 Fedora Release Engineering - 0.8.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild -* Wed Apr 21 2021 Benjamin Marzinski 0.8.4-12 -- Add 0064-libmultipath-check-udev_device_get_-return-value-to-.patch - * Fixes bz #1946940 -- Resolves: bz #1946940 +* Thu Jan 6 2022 Benjamin Marzinski - 0.8.7-5 +- Modify 0030-RH-add-mpathconf.patch + * fix setting property_blacklist with no blacklist_exceptions section -* Fri Mar 12 2021 Benjamin Marzinski 0.8.4-11 -- Add 0062-libmultipath-select_action-don-t-drop-map-if-alias-c.patch - * Fall back to WWID names instead of removing existing device -- Add 0063-libmultipath-check-if-user_friendly_name-is-in-use.patch - * make sure to choose a user_friendly_name that isn't in use - * Fixes bz #1937832 -- Add alias_clash CI test -- Remove unused multipath.conf -- Resolves: bz #1937832 +* Mon Dec 13 2021 Benjamin Marzinski - 0.8.7-4 +- Update to the head of the upstream staging branch + * Patches 0013 - 0024 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0013-0022 are now patches 0025-0034 -* Wed Feb 10 2021 Benjamin Marzinski 0.8.4-9 -- Add 0060-kpartx-free-loop-device-after-listing-partitions.patch - * Fixes bz #1925490 -- Add 0061-RH-fix-find_multipaths-in-mpathconf.patch - * Fixes bz #1921651 -- Resolves: bz #1921651, #1925490 +* Thu Oct 28 2021 Benjamin Marzinski - 0.8.7-3 +- Update to the head of the upstream staging branch + * Patches 0011 & 0012 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0011-0020 are now patches 0013-0022 -* Wed Jan 27 2021 Benjamin Marzinski 0.8.4-7 -- Add 0052-libmultipath-check-for-null-wwid-before-strcmp.patch - * Missing part of fix for bz #1897815 -- Add 0053-libmultipath-make-find_err_path_by_dev-static.patch -- Add 0054-multipathd-avoid-io_err_stat-crash-during-shutdown.patch -- Add 0055-multipathd-avoid-io_err_stat-ABBA-deadlock.patch -- Add 0056-multipathd-use-get_monotonic_time-in-io_err_stat-cod.patch -- Add 0057-multipathd-combine-free_io_err_stat_path-and-destroy.patch -- Add 0058-multipathd-cleanup-logging-for-marginal-paths.patch - * The above 6 patches fix bz #1920795 -- Add 0059-libmpathpersist-fix-thread-safety-of-default-functio.patch - * Fixes bz #1913549 -- Resolves: bz #1897815, #1913549, #1920795 +* Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-2 +- Modify 0013-RH-don-t-start-without-a-config-file.patch + * add condtion to multipathd.socket as well -* Tue Dec 15 2020 Benjamin Marzinski 0.8.4-6 -- Add 0050-multipathd-Fix-multipathd-stopping-on-shutdown.patch - * Fixes bz #1892496 -- Add 0051-multipath.conf.5-Improve-checker_timeout-description.patch - * Fixes bz #1906073 -- Resolves: bz #1892496, #1906073 +* Wed Oct 6 2021 Benjamin Marzinski - 0.8.7-1 +- Update source to upstream version 0.8.7 + * Previous patches 0001-0023 are included in the commit. +- Add patches from upstream staging branch + * Patches 0001-0010 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0024-0033 are now patches 0011-0020 -* Tue Nov 10 2020 Benjamin Marzinski 0.8.4-6 -- Add 0039-libmultipath-factor-out-code-to-get-vpd-page-data.patch -- Add 0040-libmultipath-limit-reading-0xc9-vpd-page.patch - * Only check for rdac support on configured devices, or devices where - vpd page 0x00 indicates support for vpd page 0xc9 - * Fixes bz #1877415 -- Add 0041-libmultipath-add-device-to-hwtable.c.patch - * Add support for Fujitsu Eternus AB/HB - * Fixes bz #1857429 -- Add 0042-libmultipath-move-fast_io_fail-defines-to-structs.h.patch -- Add 0043-libmultipath-add-eh_deadline-multipath.conf-paramete.patch - * Fixes bz #1819897 -- Add 0044-libmultipath-don-t-dlclose-tur-checker-DSO.patch - * Fixes bz #1875384 -- Add 0045-libmultipath-warn-about-missing-braces-at-end-of-mul.patch - * Fixes bz #1897530 -- Add 0046-libmultipath-ignore-multipaths-sections-without-wwid.patch - * Fixes bz #1897815 -- Add 0047-tests-fix-missing-priority-blacklist-test.patch -- Add 0048-mpathpersist-Fix-Register-and-Ignore-with-0x00-SARK.patch - * Make mpathpersist Register and Ignore command clear the registration - with a 0x0 SARK, like sg_persist does. - * Fixes bz #1894103 -- Add 0049-mpathpersist-update-prkeys-file-on-changing-registra.patch - * Fixes bz #1900522 - * The above 11 patches have all been submitted upstream -- Resolves: bz #1819897, #1857429, #1875384, #1877415, #1894103, #1897530 -- Resolves: bz #1897815, #1900522 - -* Mon Jul 13 2020 Benjamin Marzinski 0.8.4-5 -- Add 0038-multipath-deal-with-failures-flushing-maps.patch - * Don't print "fail" if multipath needs to failback to removing - a device itself. - * Fixes bz #1845875 -- Modify multipath_conf_syntax CI test - * It started failing because "multpath -F" can now start multipathd - via the socket, and the test expected multipathd to not be running -- Resolves: bz #1845875 - -* Fri Jul 10 2020 Benjamin Marzinski 0.8.4-4 -- Add 0037-libmultipath-count-pending-paths-as-active-on-loads.patch - * make udev treat the device as having paths, so it will run kpartx - * Fixes bz #1846866 -- Resolves: bz #1846866 - -* Mon Jul 6 2020 Benjamin Marzinski 0.8.4-3 -- Add 0024-libmultipath-make-dm_get_map-status-return-codes-sym.patch -- Add 0025-multipathd-fix-check_path-errors-with-removed-map.patch -- Add 0026-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch -- Add 0027-multipathd-add-del-maps-multipathd-command.patch -- Add 0028-multipath-make-flushing-maps-work-like-other-command.patch -- Add 0029-multipath-delegate-flushing-maps-to-multipathd.patch -- Add 0030-multipath-add-option-to-skip-multipathd-delegation.patch - * The above 7 patches fix bz #1845875. Multipath now attempts to - delegate device removal to multipathd, and multipathd handles - external device removal better. -- Add 0031-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch - * Fixes bz #1852843 -- Add 0032-kpartx-read-devices-with-direct-IO.patch - * Fixes bz #1814858 -- Add 0033-kpartx-handle-alternate-bsd-disklabel-location.patch -- Add 0034-libmultipath-fix-checker-detection-for-nvme-devices.patch - * fixes bz #1845915 -- Add 0035-Makefile.inc-trim-extra-information-from-systemd-ver.patch -- Add 0036-kpartx-fix-Wsign-compare-error.patch -- Resolves: bz #1814858, #1845875, #1845915, #1852843 - -* Tue Jun 9 2020 Benjamin Marzinski 0.8.4-2 -- Add 0021-libmultipath-remove-_blacklist_exceptions-functions.patch -- Add 0022-libmultipath-fix-parser-issue-with-comments-in-strin.patch -- Add 0023-libmultipath-invert-regexes-that-start-with-exclamat.patch - * This commit also changes the default devnode blacklist to - blacklist all devices except scsi, dasd, and nvme. -- Resolves: bz #1828180 - -* Wed May 27 2020 Benjamin Marzinski 0.8.4-1 -- Update Source to upstream version 0.8.4 - * This version includes the fixes for bz #1768894 & #1821214 - * Previous patches 0001-0009 are included in this version +* Fri Jul 30 2021 Benjamin Marzinski - 0.8.6-5 +- Update to the head of the upstream staging branch plus redhat patches + * Patches 0016-0018 are from the upstream staging branch + * Patches 0019-0024 have been submitted upstream - Rename files - * Previous patches 0010-0019 are now 0011-0020 + * Previous patches 0016-0025 are now patches 0024-0033 + +* Wed Jul 21 2021 Fedora Release Engineering - 0.8.6-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Sat Jul 10 2021 Björn Esser - 0.8.6-3 +- Rebuild for versioned symbols in json-c + +* Thu Jul 1 2021 Benjamin Marzinski - 0.8.6-2 +- Pull in latest upstream post-tag commits + * Patches 0001-0015 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream +- Rename files + * Previous patches 0001-0010 and now patches 0016-0025 + +* Wed Jun 23 2021 Cole Robinson - 0.8.6-1.fc35.1 +- Rebuild for userspace-rcu soname bump + +* Mon Apr 5 2021 Benjamin Marzinski - 0.8.6-1 +- Update Source to upstream version 0.8.6 + * Previous patches 0001-0146 are included in the commit +- Rename files + * Previous patches 0147-0156 are now patches 0001-0010 +- sync tests with RHEL repository + +* Fri Mar 26 2021 Benjamin Marzinski - 0.8.5-6 +- Change patch format to remove Git version + * Patches 0001-0122 only have the patch format modified +- Update to the head of the upstream staging branch plus redhat patches + * Patches 0123-0134 & 1036-0142 are from the upstream staging branch + * Patches 0143-1046 have been submitted upstream + * Patch 0156 is a Red Hat only patch. Red Hat udev rules set ID_SERIAL + from 60-persistent-storage.rules instead of 55-scsi-sg3_id.rules. + Multipath's parse_vpd_pg83() function needs to match the ID_SERIAL + value from udev. +- Rename files + * Previous patches 0123-0132 are now patches 1035 & 0147-0155 + +* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 0.8.5-5 +- Rebuilt for updated systemd-rpm-macros + See https://pagure.io/fesco/issue/2583. + +* Thu Feb 11 2021 Benjamin Marzinski - 0.8.5-4 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0121 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream + * Patches 0122&0123 have been posted for upstream inclusion +- Rename files + * Previous patches 0103-0111 are now patches 0124-0132 + +* Tue Jan 26 2021 Fedora Release Engineering - 0.8.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-2 +- Fix build issues + +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-1 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0102 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream. +- Rename files + * Previous patches 0059-0068 are now patches 0103-0111 + + +* Sun Sep 27 2020 Benjamin Marzinski - 0.8.4-7 +- Add 0073-libmultipath-util-constify-function-arguments.patch +- Add 0074-libmultipath-constify-file-argument-in-config-parser.patch +- Add 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +- Add 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +- Add 0077-multipath-use-get_put-_multipath_config-from-libmult.patch +- Add 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +- Add 0079-libmultipath-add-udev-and-logsink-symbols.patch +- Add 0080-multipath-remove-logsink-and-udev.patch +- Add 0081-libmpathpersist-call-libmultipath_-init-exit.patch +- Add 0082-mpathpersist-remove-logsink-and-udev.patch +- Add 0083-multipathd-remove-logsink-and-udev.patch + * Pull in upsteam library changes +- Add 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +- Add 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +- Add 0086-libmultipath-change-log-level-for-null-uid_attribute.patch +- Add 0087-libmultipath-orphan_paths-avoid-BUG-message.patch + * update libmpathvalid to use upstream library changes. changes + submitted upstream + +* Mon Jul 27 2020 Fedora Release Engineering - 0.8.4-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-5 +- Update CI tests to match RHEL + * This commit also pulls in changes from Lin Li + and Bruno Goncalves + +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-4 +- Rebased on top of additional commits staged for upstream + * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 +- Add 0048-libmultipath-add-device-to-hwtable.c.patch +- Add 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +- Add 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +- Add 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +- Add 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +- Add 0055-libmultipath-remove-code-duplication-in-path-countin.patch +- Add 0056-libmultipath-count-pending-paths-as-active-on-loads.patch +- Add 0057-libmultipath-deal-with-flushing-no-maps.patch +- Add 0058-multipath-deal-with-delegation-failures-correctly.patch +- Add 0070-multipath-add-libmpathvalid-library.patch + * adds the libmpathvalid.so library to determine if devices are + valid multipath paths. +- Add 0071-libmultipath-add-uid-failback-for-dasd-devices.patch +- Add 0072-libmultipath-add-ignore_udev_uid-option.patch + +* Mon Jul 13 2020 Tom Stellard - 0.8.4-3 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + +* Wed Jul 8 2020 Benjamin Marzinski - 0.8.4-2 +- Rebased on top of Martin Wilck's queue of ACKed upstream commits + * https://github.com/openSUSE/multipath-tools/tree/upstream-queue + * All previous patches have been reordered, with the exception of + 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch + which has been replaced with + 0029-fix-boolean-value-with-json-c-0.14.patch +- Modify 0054-RH-add-mpathconf.patch + * remove default enable_foreign and property blacklist_exceptions + settings, and deal with the builtin default change from + 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch. + Fixes bz #1853668 +- Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch +- Add 0049-kpartx-fix-Wsign-compare-error.patch + * The above two patches have been submitted upstream + +* Fri May 29 2020 Benjamin Marzinski - 0.8.4-1 +- Update Source to upstream version 0.8.4 + * Previoud patches 0001-0020 & 0031 are included in this commit +- Rename files + * Previous patches 0021-0032 are now patches 0012-0022 - Add 0001-libmultipath-assign-variable-to-make-gcc-happy.patch - Add 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch - Add 0003-libmultipath-allow-force-reload-with-no-active-paths.patch - * make multipath and multipathd reload maps with no active paths - (bz #1814858) - Add 0004-libmpathpersist-depend-on-libmultipath.patch - Add 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch - Add 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch @@ -686,153 +585,194 @@ fi - Add 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch - Add 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch - Add 0010-multipath-tools-Makefile-add-install-dependency.patch +- Add 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +- Add 0023-RH-work-around-gcc-10-format-truncation-issue.patch * The above 10 patches have been submitted upstream -- Resolves: bz #1768894, #1814858, #1821214 -* Fri Nov 8 2019 Benjamin Marzinski 0.8.3-3 +* Tue Apr 21 2020 Björn Esser - 0.8.2-6 +- Rebuild (json-c) + +* Mon Apr 13 2020 Björn Esser - 0.8.2-5 +- Add 0032-add-support-for-upcoming-json-c-0.14.0.patch + +* Mon Apr 13 2020 Björn Esser - 0.8.2-4 +- Fix macro escaping in %%changelog + +* Wed Feb 12 2020 Benjamin Marzinski - 0.8.2-3 +- Add 0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch + * Patch submitted upstream +- Resolves bz #1799276 + +* Tue Jan 28 2020 Fedora Release Engineering - 0.8.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Sep 11 2019 Benjamin Marzinski - 0.8.2-1 +- Update Source to upstream version 0.8.2 + * Previoud patches 0001-0017 & 0027 are included in this commit - Rename files - * Previous patches 0004-0013 are now 0010-0019 - * 0014-RH-add-mpathconf.patch now makes mpathconf default to not - printing foreign devices (bz #1760709) -- Add 0004-libmultipath-remove-unused-path-prio_args.patch -- Add 0005-libmultipath-constify-get_unaligned_be.patch -- Add 0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch -- Add 0007-libmultipath-fix-sgio_get_vpd-looping.patch -- Add 0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch -- Add 0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch - * Add the '%g' maps and paths format wildcard, and the vpd_vendor - multipath.conf devices section parameter. (bz #1527212) -- Resolves: bz #1527212, #1760709 + * Previous patches 0018-0026 & 0028 are not patches 0021-0030 +- Add 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch +- Add 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch +- Add 0003-tests-add-path-grouping-policy-unit-tests.patch +- Add 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch +- Add 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch +- Add 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch +- Add 0007-libmultipath-consolidate-group_by_-functions.patch +- Add 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch +- Add 0009-libmultipath-make-group_paths-handle-marginal-paths.patch +- Add 0010-tests-add-tests-for-grouping-marginal-paths.patch +- Add 0011-libmultipath-add-marginal_pathgroups-config-option.patch +- Add 0012-libmutipath-deprecate-delay_-_checks.patch +- Add 0013-multipathd-use-marginal_pathgroups.patch +- Add 0014-multipath-update-man-pages.patch + * The above 13 patches add the marinal_pathgroups option +- Add 0015-multipath.conf-add-enable_foreign-parameter.patch +- Add 0016-multipath.conf.5-document-foreign-library-support.patch + * The above 2 patches add the enable_foreign option +- Add 0017-mpathpersist-remove-broken-unused-code.patch +- Add 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch +- Add 0019-mpathpersist-fix-leaks.patch +- Add 0020-libmultipath-fix-mpcontext-initialization.patch + * The above 20 patches have been submitted upstream -* Mon Oct 14 2019 Benjamin Marzinski 0.8.3-2 -- Update CI tests -- Related: bz #1690515 +* Wed Jul 24 2019 Fedora Release Engineering - 0.8.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild -* Tue Oct 8 2019 Benjamin Marzinski 0.8.3-1 -- Update Source to upstream version 0.8.3 - * This version includes the fixes for bz #1690515, #1703439, - #1719562 & #1747534 - * Previous patches 0001-0017 & 0031-0036 are included in this version -- Rename files - * Previous patches 0018-0026 & 0028 are now 0004-0013 - * 0008-RH-add-mpathconf.patch has been modified to add a - --property_blacklist option to fix bz #1753729 -- Add 0001-multipathd-warn-when-configuration-has-been-changed.patch - * Multipath now logs a warning message when the configuration file - has been changed to fix bz #1750594 -- Add 0002-libmultipath-fix-leak-in-foreign-code.patch -- Add 0003-Fix-leak-in-mpathpersist.patch - * The above 3 patches have been submitted upstream -- Resolves: bz #1690515, #1703439, #1719562, #1747534, #1750594, #1753729 +* Fri Apr 12 2019 Benjamin Marzinski - 0.8.0-2 +- Add 0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch + * try to get ANA state from sysfs first, with the ioctl as a fallback -* Mon Jun 3 2019 Benjamin Marzinski 0.8.0-5 -- Bump release number for test fix commit 0b68e623 -- Related: bz #1666322 - -* Tue May 28 2019 Benjamin Marzinski 0.8.0-4 -- Add 0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch -- Add 0036-libmultipath-make-vector_foreach_slot_backwards-work.patch - * Fix for bz #1713459 -- Fixes for bz #1666322 and #1669097 were included in 0.8.0 upstream - code -- Resolves: bz #1666322, #1669097, #1700911, #1713459 - -* Thu May 16 2019 Benjamin Marzinski 0.8.0-3 -- Add 0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch -- Add 0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch -- Add 0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch -- Add 0034-multipathd-handle-NULL-return-from-genhelp_handler.patch - * The above 4 patches have been submitted upstream -- Related: bz #1498546 - -* Tue Apr 30 2019 Benjamin Marzinski 0.8.0-2 -- Add 0029-BZ-1700451-check-on-multipathd-without-starting-it.patch -- Add 0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch - * the "multipath -u" call in 62-multipath.rules should no longer hang - on multipathd startup. -- Resolves: bz #1700451 - -* Mon Apr 8 2019 Benjamin Marzinski 0.8.0-1 +* Thu Apr 4 2019 Benjamin Marzinski - 0.8.0-1 - Update Source to upstream version 0.8.0 - * Previous patches 0001-0006 & 0015-0019 are included in this commit + * Previous patches 0006 & 0007 are included in this commit - Rename files - * Previous patches 0007-0014 are now 0018-0025 - * Previous patches 0020-0023 are now 0001, 0006 & 0007 -- Add 0002-libmultipath-handle-existing-paths-in-marginal_path-.patch -- Add 0003-multipathd-cleanup-marginal-paths-checking-timers.patch -- Add 0004-libmultipath-fix-marginal-paths-queueing-errors.patch -- Add 0005-libmultipath-fix-marginal_paths-nr_active-check.patch + * Previous patches 0008-0016 & 0100 are now patches 0018-0027 +- Add 0006-multipathd-Fix-miscounting-active-paths.patch +- Add 0007-multipathd-ignore-failed-wwid-recheck.patch + * multipathd will no longer disable paths if it is unable to + get their wwid on a change event - Add 0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch - Add 0009-multipathd-use-update_path_groups-instead-of-reload_.patch - Add 0010-multipath.conf-add-missing-options-to-man-page.patch - Add 0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch - Add 0012-libmulitpath-cleanup-uid_fallback-code.patch - Add 0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch - * Multipath will now automatically remove and re-add paths if - their wwid changes + * if a path device changes wwid, it will now be removed and re-added + to the correct multipath device. - Add 0014-multipathd-remove-wwid_changed-path-attribute.patch - Add 0015-multipathd-ignore-disable_changed_wwids.patch - * Since paths are now getting removed and re-added there is - no need to disable them. - Add 0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch - Add 0017-libmultipath-silence-dm_is_mpath-error-messages.patch -- Add 0026-RH-Fix-nvme-compilation-warning.patch -- Add 0027-Fix-systemd-version-detection.patch - * The above 16 patches have been submitted upstream -- Add 0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch - * Red Hat has a sysfs method to access the ANA state, which isn't - upstream, and will not be. This will probably go away in the - future. -- Resolves: bz #1498546 + * The above 12 patches have been submitted upstream -* Mon Feb 25 2019 Benjamin Marzinski 0.7.8-7 -- Add 0023-BZ-1673167-fixup-wwid-recheck.patch -- Resolves: bz #1673167 +* Sun Feb 17 2019 Igor Gnatenko - 0.7.9-6.git2df6110 +- Rebuild for readline 8.0 -* Sun Feb 24 2019 Benjamin Marzinski 0.7.8-6 -- Fix multipath_conf_syntax CI test - * need to wait for udev to settle before removing multipath device -- Resolves: bz #1673167 +* Thu Jan 31 2019 Benjamin Marzinski - 0.7.9-5.git2df6110 +- Rename files + * Previous patch 0006-0014 are now patches 0008-0016 +- Add 0006-multipathd-avoid-null-pointer-dereference-in-LOG_MSG.patch +- Add 0007-multipath-blacklist-zram-devices.patch + * The above 2 patches have been submitted upstream +- Resolves: bz #1672761 -* Mon Feb 18 2019 Benjamin Marzinski 0.7.8-5 -- Add 0021-BZ-1673167-Fix-miscounting-active-paths.patch -- Add 0022-BZ-1673167-ignore-failed-wwid-recheck.patch -- Resolves: bz #1673167 +* Thu Jan 31 2019 Benjamin Marzinski - 0.7.9-4.git2df6110 +- Update Source to latest upstream commit + * previous patch 0001-libmultipath-dm_is_mpath-cleanup.patch is included + in this commit +- Rename files + * Previous patches 0002-0009 are now patches 0006-0013 +- Add 0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch +- Add 0002-libmultipath-handle-existing-paths-in-marginal_path-.patch +- Add 0003-multipathd-cleanup-marginal-paths-checking-timers.patch +- Add 0004-libmultipath-fix-marginal-paths-queueing-errors.patch +- Add 0005-libmultipath-fix-marginal_paths-nr_active-check.patch + * The above 5 patches have been submitted upstream +- Add 0014-RH-Fix-nvme-compilation-warning.patch + * This change is only necessary because of Red Hat compilation + differences. -* Thu Jan 24 2019 Benjamin Marzinski 0.7.8-4 -- Add 0020-BZ-1668693-disable-user_friendly_names-for-NetApp.patch -- Resolves: bz #1668693 +* Thu Jan 31 2019 Fedora Release Engineering - 0.7.9-3.git17a6101 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild -* Tue Dec 11 2018 Benjamin Marzinski 0.7.8-3 -- Add 0017-BZ-1648397-fix-mpp-hwe-handling-when-paths-are-freed.patch - * Fix crash by deleting in use hardware entry list pointer -- Add 0018-libmultipath-cleanup-pthread_cleanup_pop-call.patch - * Fix compiler warning -- Add 0019-libmultipath-fix-false-removes-in-dmevents-polling-c.patch - * The above 3 patches have been accepted upstream -- Resolves: bz #1648397 +* Tue Jan 15 2019 Benjamin Marzinski 0.7.9-2.git17a6101 +- Update Source to latest upstream commit + * Previous patches 0001-0003 are included in this version +- Rename files + * Previous patches 0004-0011 are now patches 0002-0009 +- Add 0001-libmultipath-dm_is_mpath-cleanup.patch + * This patch has been submitted upstream -* Wed Oct 10 2018 Benjamin Marzinski 0.7.8-2 -- Add 0015-libmultipath-free-allocated-value-in-set_int.patch -- Add 0016-kpartx-fix-new-memory-leak-in-dm_find_part.patch -- change hardcoded /usr/lib/udev/rules.d to _udevrulesdir -- Resolves: bz #1606947 +* Mon Dec 3 2018 Benjamin Marzinski 0.7.9-1 +- Update Source to upstream version 0.7.9 + * Previous patches 0001-0006 are included in this version +- Rename files + * Previous patches 0007-0014 are now patches 0004-0011 +- Add 0001-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch +- Add 0002-libmultipath-cleanup-pthread_cleanup_pop-call.patch +- Add 0003-libmultipath-fix-false-removes-in-dmevents-polling-c.patch + * The above 3 patches have been submitted upstream * Wed Oct 10 2018 Benjamin Marzinski 0.7.8-1 - Update Source to upstream version 0.7.8 - * Previous patches 0001-0011 are included in this version + * Previous patches 0001-0020 are included in this version - Rename files - * Previous patches 0012-0019 are now patches 0007-0014 -- Add 0001-multipath-tweak-logging-style.patch -- Add 0002-multipathd-check-for-NULL-udevice-in-cli_add_path.patch -- Add 0003-libmultipath-remove-max_fds-code-duplication.patch -- Add 0004-multipathd-set-return-code-for-multipathd-commands.patch -- Add 0005-mpathpersist-fix-registration-rollback-issue.patch + * Previous patches 0021-0025 are now patches 0001-0005 + * Previous patches 0026-0033 are now patches 0007-0014 - Add 0006-libmultipath-timeout-on-unresponsive-tur-thread.patch - * The above 6 patches have been submitted upstream -- Resolves: bz #1606947, #1631883 + * has been submitted upstream -* Tue Jul 17 2018 Benjamin Marzinski 0.7.7-2.gitef6d98b +* Tue Oct 9 2018 Benjamin Marzinski 0.7.7-7.gitb80318b +- Update Source to latest upstream commit +- Rename files + * Previous patches 0001-0020 are now patches 0002-0021 + * Previous patches 0021-0028 are now patches 0026-0033 +- Add 0001-kpartx-Use-absolute-paths-to-create-mappings.patch +- Add 0022-multipathd-check-for-NULL-udevice-in-cli_add_path.patch +- Add 0023-libmultipath-remove-max_fds-code-duplication.patch +- Add 0024-multipathd-set-return-code-for-multipathd-commands.patch +- Add 0025-mpathpersist-fix-registration-rollback-issue.patch + * The above 5 patches have been submitted upstream + +* Thu Sep 27 2018 Benjamin Marzinski 0.7.7-6.git1a8625a +- Update Source to latest upstream commit + * Previous patches 0001-0011 are included in this commit +- Rename files + * Previous patches 0012-0019 are now patches 0021-0028 +- Add 0001-libmultipath-fix-tur-checker-timeout.patch +- Add 0002-libmultipath-fix-tur-checker-double-locking.patch +- Add 0003-libmultipath-fix-tur-memory-misuse.patch +- Add 0004-libmultipath-cleanup-tur-locking.patch +- Add 0005-libmultipath-fix-tur-checker-timeout-issue.patch + * The above 5 patches cleanup locking issues with the + tur checker threads +- Add 0006-libmultipath-fix-set_int-error-path.patch +- Add 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch +- Add 0008-libmultipath-_install_keyword-cleanup.patch +- Add 0009-libmultipath-remove-unused-code.patch +- Add 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch +- Add 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch +- Add 0012-libmutipath-don-t-use-malformed-uevents.patch +- Add 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch +- Add 0014-multipathd-function-return-value-tweaks.patch +- Add 0015-multipathd-minor-fixes.patch +- Add 0016-multipathd-remove-useless-check-and-fix-format.patch +- Add 0017-multipathd-fix-memory-leak-on-error-in-configure.patch + * The above 12 patches fix minor issues found by coverity +- Add 0018-libmultipath-Don-t-blank-intialized-paths.patch +- Add 0019-libmultipath-Fixup-updating-paths.patch + * Fix issues with paths whose wwid was not set or later changes +- Add 0020-multipath-tweak-logging-style.patch + * multipathd interactive commands now send errors to stderr, instead + of syslog + * The above 20 patches have been submitted upstream + +* Fri Sep 14 2018 Benjamin Marzinski 0.7.7-5.gitef6d98b +- Add Conflicts for mdadm < 4.1-rc2.0.2 and udisks2 < 2.8.0-2 + * Multipath udev rule update from 0.7.7-1 is incompatible with older versions + (bz #1628192) + +* Thu Jul 12 2018 Benjamin Marzinski 0.7.7-4.gitef6d98b - Update Source to latest upstream commit * Previous patches 0001-0018 are included in this commit - Rename files @@ -842,7 +782,8 @@ fi * mpathpersist now accepts --param-alltgpt - Add 0005-libmutipath-remove-unused-IDE-bus-type.patch - Add 0006-multipathd-add-new-protocol-path-wildcard.patch - * multipathd show paths format now accepts %%P for the path protocol/transport + * multipathd show paths format now accepts %%P for the path + protocol/transport - Add 0007-libmultipath-add-protocol-blacklist-option.patch * You can now use the "protocol" blacklist section parameter to blacklist by protocol/transport @@ -853,19 +794,18 @@ fi - Refresh 0013-RH-Remove-the-property-blacklist-exception-builtin.patch - Modify 0016-RH-add-mpathconf.patch * improve usage message and man page -- Modify device-mapper-multipath.spec - * updated dependencies + +* Thu Jul 12 2018 Fedora Release Engineering - 0.7.7-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Sat Jun 30 2018 Peter Robinson 0.7.7-2 +- Spec cleanups, drop remains of initscripts dependencies * Tue Jun 12 2018 Benjamin Marzinski 0.7.7-1 - Update Source to 0.7.7 - * Previous patches 0001-0009 & 0016 are included in this commit + * Previous patches 0001-0009 & 0018 are included in this commit - Add upstream patches since 0.7.7 * patches 0001-0012 are from upstream commits since 0.7.7 -- Add 0013-libmultipath-print-correct-default-for-delay_-_check.patch - * fix minor configuration printing issue. posted upstream -- Add 0014-multipath.conf.5-clarify-property-whitelist-handling.patch - * clarify property blacklist_excecptions handling in man page - posted upstream - Add 0015-mpathpersist-add-all_tg_pt-option.patch * add new all_tg_pt multpiath.conf option. posted upstream - Add 0016-libmultipath-remove-rbd-code.patch @@ -879,21 +819,26 @@ fi * fix alua detection with retain_hardware_handler set to off. posted upstream - Add 0020-multipath-fix-setting-conf-version.patch - * multipath wasn't setting the kernel version correctly. posted - upstream + * multipath wasn't setting the kernel version correctly. posted upstream - Add 0028-RH-reset-default-find_mutipaths-value-to-off.patch - * default to RHEL7 and older device detection style. Redhat specific, - to keep customer experience the same. + * default to RHEL7 and older device detection style. Redhat specific, to + keep customer experience the same. - Rename files - * Previous patches 0010-0015 & 0017 are now patches 0021-0027 + * Previous patches 0010-0011 are now patches 0013-0014 + * Previous patches 0012-0017 & 0019 are now patches 0021-0027 - Modify 0021-RH-fixup-udev-rules-for-redhat.patch * Fix spurious compile warning with redhat compile options -- Modify 0022-RH-Remove-the-property-blacklist-exception-builtin.patch - * clarify changes in man page + * Tue May 15 2018 Benjamin Marzinski 0.7.6-4.git1cb704b +- Add 0010-libmultipath-print-correct-default-for-delay_-_check.patch + * fix minor configuration printing issue +- Add 0011-multipath.conf.5-clarify-property-whitelist-handling.patch + * clarify property blacklist_excecptions handling in man page - Rename files * Previous patches 0010-0017 are now patches 0012-0019 +- Modify 0013-RH-Remove-the-property-blacklist-exception-builtin.patch + * clarify changes in man page * Tue Apr 24 2018 Benjamin Marzinski 0.7.6-3.git1cb704b - Add 0008-multipathd-add-failures-path-format-wildcard.patch @@ -907,7 +852,7 @@ fi - Rename files * Previous patches 0007-0014 are now patches 0008-0015 -* Mon Apr 02 2018 Benjamin Marzinski - 0.7.6-1.git1cb704b +* Mon Apr 02 2018 Benjamin Marzinski 0.7.6-1.git1cb704b - Update Source to the latest upstream commit * Previous patches 0001-0014 are included in this commit * Previous patches 0015-0022 are now patches 0007-0014 diff --git a/SOURCES/multipath.conf b/multipath.conf similarity index 100% rename from SOURCES/multipath.conf rename to multipath.conf diff --git a/sources b/sources new file mode 100644 index 0000000..7b7892a --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (multipath-tools-0.9.9.tgz) = 65b5d5c48792f6041d700968c87675bc349ede475fe178a203814dbb0325f69895782a22c5c35f6c0157f694951714de9e83cc1464a6c062d911a58faed8960a