diff --git a/tests/.fmf/version b/.fmf/version similarity index 100% rename from tests/.fmf/version rename to .fmf/version diff --git a/.gitignore b/.gitignore index 703cbe1..c297b30 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,18 @@ multipath-tools-091027.tar.gz /multipath-tools-0.8.0.tgz /multipath-tools-0.8.2.tgz /multipath-tools-0.8.4.tgz +/multipath-tools-0.8.5.tgz +/multipath-tools-0.8.6.tgz +/multipath-tools-0.8.7.tgz +/multipath-tools-0.8.9.tgz +/multipath-tools-0.9.0.tgz +/multipath-tools-0.9.3.tgz +/multipath-tools-0.9.4.tgz +/multipath-tools-0.9.5.tgz +/multipath-tools-0.9.6.tgz +/multipath-tools-0.9.7.tgz +/multipath-tools-0.9.8.tgz +/multipath-tools-0.9.9.tgz +/multipath-tools-0.10.0.tgz +/multipath-tools-0.11.1.tgz +/multipath-tools-0.13.0.tgz diff --git a/0001-RH-fixup-udev-rules-for-redhat.patch b/0001-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..ed5b7e9 --- /dev/null +++ b/0001-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,63 @@ +From 64a07df23affd21842fdc604887276e62e5b41de 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.in | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 9e3dc466..ead89030 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.in b/kpartx/kpartx.rules.in +index 9d879609..2049eb8f 100644 +--- a/kpartx/kpartx.rules.in ++++ b/kpartx/kpartx.rules.in +@@ -39,6 +39,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="@BINDIR@/kpartx -un -p -part /dev/$name" ++RUN+="@BINDIR@/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/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch b/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch deleted file mode 100644 index d40166a..0000000 --- a/0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 21:50:30 +0100 -Subject: [PATCH] libmpathpersist: limit PRIN allocation length to 8192 bytes - -Some targets (notably the qemu-pr-helper) don't support PERSISTENT -RESERVE IN commands with more than 8192 bytes allocation length. -While I have found no explicit requirement in the SCSI specs that -the allocation lengh may not exceed 8k, an 8k limit is also enforced -by sg_persist(8), and actually by mpathpersist itself for the ---allocation-length option, but not for the auto-determined length. - -Fix that. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index 74b26b0c..1a28cba7 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -543,5 +543,7 @@ int get_prin_length(int rq_servact) - mx_resp_len = 0; - break; - } -+ if (mx_resp_len > MPATH_MAX_PARAM_LEN) -+ mx_resp_len = MPATH_MAX_PARAM_LEN; - return mx_resp_len; - } --- -2.17.2 - diff --git a/0060-RH-Remove-the-property-blacklist-exception-builtin.patch b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 72% rename from 0060-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0002-RH-Remove-the-property-blacklist-exception-builtin.patch index f760f87..b8e580a 100644 --- a/0060-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/0002-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f7be16ac9fce97585a4552d49f3d3c54a93c9c17 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Wed, 2 Jul 2014 12:49:53 -0500 Subject: [PATCH] RH: Remove the property blacklist exception builtin @@ -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 db58ccca..0c58aa32 100644 +index 17e1b54a..10d13e98 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c -@@ -187,12 +187,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, -@@ -394,7 +388,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 db58ccca..0c58aa32 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 5adaced6..42a192f6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1296,9 +1296,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 3c9ae097..ba291e11 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1470,9 +1470,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 5adaced6..42a192f6 100644 . .RS .PP -@@ -1309,10 +1314,6 @@ Blacklisting by missing properties is only applied to devices which do have the +@@ -1483,10 +1488,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 5adaced6..42a192f6 100644 .TP .B protocol diff --git a/tests/blacklist.c b/tests/blacklist.c -index d5c40898..d20e97af 100644 +index ab3da619..52ae03e0 100644 --- a/tests/blacklist.c +++ b/tests/blacklist.c -@@ -380,7 +380,7 @@ static void test_property_missing(void **state) +@@ -371,9 +371,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, ""), -@@ -472,9 +472,7 @@ static void test_filter_path_missing1(void **state) +@@ -465,9 +464,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 d5c40898..d20e97af 100644 } /* This one matches the property whitelist, to test the other missing --- -2.17.2 - diff --git a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch b/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch deleted file mode 100644 index 6164b26..0000000 --- a/0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 23:33:04 +0100 -Subject: [PATCH] libmpathpersist: format_transportids(): avoid PROUT overflow - -This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index 1a28cba7..c78e8000 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -1,5 +1,6 @@ - #include - #include -+#include - - #include - #include -@@ -138,38 +139,64 @@ retry : - return status; - } - -+/* -+ * Helper macro to avoid overflow of prout_param_descriptor in -+ * format_transportids(). Data must not be written past -+ * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor. -+ */ -+#define check_overflow(ofs, n, start, label) \ -+ do { \ -+ if ((ofs) + (n) + \ -+ offsetof(struct prout_param_descriptor, private_buffer) \ -+ > MPATH_MAX_PARAM_LEN) \ -+ { \ -+ (ofs) = (start); \ -+ goto label; \ -+ } \ -+ } while(0) -+ - uint32_t format_transportids(struct prout_param_descriptor *paramp) - { - unsigned int i = 0, len; - uint32_t buff_offset = 4; -- memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN); -+ memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer)); - for (i=0; i < paramp->num_transportid; i++ ) - { -+ uint32_t start_offset = buff_offset; -+ -+ check_overflow(buff_offset, 1, start_offset, end_loop); - paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)| - (paramp->trnptid_list[i]->protocol_id & 0xff)); - buff_offset += 1; - switch(paramp->trnptid_list[i]->protocol_id) - { - case MPATH_PROTOCOL_ID_FC: -+ check_overflow(buff_offset, 7 + 8 + 8, -+ start_offset, end_loop); - buff_offset += 7; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8); - buff_offset +=8 ; - buff_offset +=8 ; - break; - case MPATH_PROTOCOL_ID_SAS: -+ check_overflow(buff_offset, 3 + 12, -+ start_offset, end_loop); - buff_offset += 3; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8); - buff_offset += 12; - break; - case MPATH_PROTOCOL_ID_ISCSI: -- buff_offset += 1; - len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2; -+ check_overflow(buff_offset, 1 + len, -+ start_offset, end_loop); -+ buff_offset += 1; - memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len); - buff_offset += len ; - break; - } - - } -+end_loop: - buff_offset -= 4; - paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff); - paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff); --- -2.17.2 - diff --git a/0003-RH-don-t-start-without-a-config-file.patch b/0003-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..05d4e7a --- /dev/null +++ b/0003-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,137 @@ +From 5613e07ce9cabf2fdc402f6f102cc54bd1059800 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.in | 1 + + 7 files changed, 25 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 8b424d18..b8317f4d 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -937,6 +937,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 5b4ebf8c..2302eacc 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 f2adcdeb..31012874 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -834,11 +834,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)) +@@ -1092,6 +1095,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 2ac1972f..cc248231 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 8815e099..342e363e 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 eb58943c..ab166435 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -6,6 +6,7 @@ Wants=systemd-udevd-kernel.socket multipathd-queueing.service @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.in b/multipathd/multipathd.socket.in +index 11002fce..5ed24757 100644 +--- a/multipathd/multipathd.socket.in ++++ b/multipathd/multipathd.socket.in +@@ -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/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch b/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch deleted file mode 100644 index 6d0cf1e..0000000 --- a/0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 6 Mar 2020 23:46:47 +0100 -Subject: [PATCH] libmpathpersist: mpath_format_readfullstatus(): use real - buffer size - -This changes no semantics, but it will allow changing the size of -prin_readfd.private_buffer in a follow-up patch. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index c78e8000..fadc9e10 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -238,6 +238,8 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - uint32_t additional_length, k, tid_len_len = 0; - char tempbuff[MPATH_MAX_PARAM_LEN]; - struct prin_fulldescr fdesc; -+ static const int pbuf_size = -+ sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); - - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor); -@@ -249,16 +251,18 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - } - - additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; -- if (additional_length > MPATH_MAX_PARAM_LEN) { -+ if (additional_length > pbuf_size) { - condlog(3, "PRIN length %u exceeds max length %d", additional_length, -- MPATH_MAX_PARAM_LEN); -+ pbuf_size); - return; - } - - memset(&fdesc, 0, sizeof(struct prin_fulldescr)); - -- memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN ); -- memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN); -+ memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer, -+ pbuf_size); -+ memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, -+ pbuf_size); - - p =(unsigned char *)tempbuff; - ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer; --- -2.17.2 - diff --git a/0067-RH-Fix-nvme-compilation-warning.patch b/0004-RH-Fix-nvme-function-missing-argument.patch similarity index 66% rename from 0067-RH-Fix-nvme-compilation-warning.patch rename to 0004-RH-Fix-nvme-function-missing-argument.patch index fc6ccd7..33a8d5f 100644 --- a/0067-RH-Fix-nvme-compilation-warning.patch +++ b/0004-RH-Fix-nvme-function-missing-argument.patch @@ -1,7 +1,10 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 283b5dd645663a2cf16f2813581772d7a84db6ad 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 --- @@ -9,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index adb192b6..bfd10ef8 100644 +index b3caa7be..f91504c9 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h -@@ -76,7 +76,7 @@ struct argconfig_commandline_options { +@@ -63,7 +63,7 @@ struct argconfig_commandline_options { extern "C" { #endif @@ -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/0004-libmultipath-assign-variable-to-make-gcc-happy.patch b/0004-libmultipath-assign-variable-to-make-gcc-happy.patch deleted file mode 100644 index 8db8dd9..0000000 --- a/0004-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: Wed, 25 Mar 2020 23:22:46 -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/0005-RH-use-rpm-optflags-if-present.patch b/0005-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..7a6f57f --- /dev/null +++ b/0005-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,67 @@ +From bf46f8029998498045bb055415ba3ff515c79eaa 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 | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index ead89030..03aee175 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -102,17 +102,29 @@ 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 ++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 + + # Set WARN_ONLY=1 to avoid compilation erroring out due to warnings. Useful during development. + WARN_ONLY := + ERROR := $(if $(WARN_ONLY),,error=) + WERROR := $(if $(WARN_ONLY),,-Werror) +-WARNFLAGS := $(WERROR) -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ ++WARNFLAGS := $(WERROR) -Wextra -Wformat=2 $(WFORMATOVERFLOW) -W$(ERROR)implicit-int \ + -W$(ERROR)implicit-function-declaration -W$(ERROR)format-security \ +- $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) ++ $(WNOCLOBBERED) -W$(ERROR)cast-qual $(ERROR_DISCARDED_QUALIFIERS) $(W_URCU_TYPE_LIMITS) -Wstrict-prototypes + +-CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ ++CPPFLAGS := $(CPPFLAGS) $(D_URCU_VERSION) \ + -D_FILE_OFFSET_BITS=64 \ + -DBIN_DIR=\"$(bindir)\" -DMULTIPATH_DIR=\"$(TGTDIR)$(plugindir)\" \ + -DRUNTIME_DIR=\"$(runtimedir)\" -DCONFIG_DIR=\"$(TGTDIR)$(configdir)\" \ +@@ -121,12 +133,11 @@ CPPFLAGS := $(FORTIFY_OPT) $(CPPFLAGS) $(D_URCU_VERSION) \ + -DABSTRACT_SOCKET=\"$(abstract_socket)\" -DPATHNAME_SOCKET=\"$(pathname_socket)\" \ + -DWSTRINGOP_TRUNCATION=$(if $(WSTRINGOP_TRUNCATION),1,0) \ + -MMD -MP +-CFLAGS := -std=$(C_STD) $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ +- -fexceptions ++CFLAGS := -std=$(C_STD) $(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/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch b/0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch deleted file mode 100644 index dd4af7e..0000000 --- a/0005-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: Wed, 25 Mar 2020 23:22:47 -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/0063-RH-add-mpathconf.patch b/0006-RH-add-mpathconf.patch similarity index 65% rename from 0063-RH-add-mpathconf.patch rename to 0006-RH-add-mpathconf.patch index 6480711..46f1126 100644 --- a/0063-RH-add-mpathconf.patch +++ b/0006-RH-add-mpathconf.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 29e5c6d6e2177e73d1be2ed2af66c1007487bf60 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 16 Oct 2014 15:49:01 -0500 Subject: [PATCH] RH: add mpathconf @@ -10,22 +10,48 @@ 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 | 565 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 135 ++++++++++ - 4 files changed, 707 insertions(+) + .github/actions/spelling/expect.txt | 3 + + libmultipath/config.c | 2 + + multipath/Makefile | 4 + + multipath/mpathconf | 658 ++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 151 +++++++ + 5 files changed, 818 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 +diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt +index a5856bcc..5c9113ba 100644 +--- a/.github/actions/spelling/expect.txt ++++ b/.github/actions/spelling/expect.txt +@@ -131,9 +131,11 @@ Marzinski + misdetection + mpath + mpathb ++mpathconf + mpathpersist + mpathvalid + msecs ++multipathable + multipathc + multipathd + multipathed +@@ -154,6 +156,7 @@ ontap + OOM + opensvc + OPTFLAGS ++outfile + paramp + partx + pathgroup diff --git a/libmultipath/config.c b/libmultipath/config.c -index 1c02e230..a253a936 100644 +index b8317f4d..0bbaa981 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); +@@ -939,6 +939,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 +60,46 @@ index 1c02e230..a253a936 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..f0d09cbb +index 00000000..ce430075 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,565 @@ +@@ -0,0 +1,658 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -92,7 +119,7 @@ index 00000000..f0d09cbb +# 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,7 +133,7 @@ index 00000000..f0d09cbb + +defaults { + user_friendly_names yes -+ find_multipaths yes ++ find_multipaths on +}" + +CONFIGFILE="/etc/multipath.conf" @@ -124,9 +151,11 @@ index 00000000..f0d09cbb + 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 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 " @@ -219,6 +248,15 @@ index 00000000..f0d09cbb + 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 @@ -237,6 +275,20 @@ index 00000000..f0d09cbb + 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 @@ -283,20 +335,31 @@ index 00000000..f0d09cbb + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" ]; 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 @@ -307,7 +370,19 @@ index 00000000..f0d09cbb + 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" -a -z "$RECHECK_WWID" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -382,49 +457,62 @@ index 00000000..f0d09cbb +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[[:space:]]*\"NONE\"" ; then -+ HAVE_FOREIGN=1 -+ 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=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,16 +523,21 @@ index 00000000..f0d09cbb + 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 @@ -453,9 +546,9 @@ index 00000000..f0d09cbb + if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then + echo "enable_foreign is not set (no foreign multipath devices will be shown)" + elif [ "$HAVE_FOREIGN" = 1 ]; then -+ echo "enable_foreign is set (no foreign multipath devices will be shown)" -+ elif [ "$HAVE_FOREIGN" = 2 ]; then + echo "enable_foreign is set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" + else + echo "enable_foreign is set (foreign multipath devices may not be shown)" + fi @@ -499,14 +592,14 @@ index 00000000..f0d09cbb + +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 @@ -520,7 +613,7 @@ index 00000000..f0d09cbb + 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 @@ -528,30 +621,25 @@ index 00000000..f0d09cbb + 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 @@ -561,14 +649,31 @@ index 00000000..f0d09cbb +' $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 @@ -586,26 +691,41 @@ index 00000000..f0d09cbb +' $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 [ "$FOREIGN" = "n" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "y" ]; then + if [ -z "$HAVE_FOREIGN" ]; then + sed -i '/^defaults[[:space:]]*{/ a\ + enable_foreign ".*" +' $TMPFILE + CHANGED_CONFIG=1 -+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ 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 -+elif [ "$FOREIGN" = "n" ]; then -+ if [ "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then -+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++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 @@ -640,10 +760,10 @@ index 00000000..f0d09cbb +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 00000000..b82961d6 +index 00000000..ec4e5c56 --- /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 @@ -684,12 +804,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 @@ -723,13 +843,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 @@ -740,11 +869,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 @@ -766,7 +902,7 @@ index 00000000..b82961d6 +.B service multipathd stop +to stop the multipathd daemon on \fB--disable\fP, and +.B service multipathd reload -+to reconfigure multipathd on \fB--user_frindly_names\fP and ++to reconfigure multipathd on \fB--user_friendly_names\fP and +\fB--find_multipaths\fP. +This option is set to \fBn\fP by default. +.SH FILES @@ -779,6 +915,3 @@ index 00000000..b82961d6 +.BR service (8), +.SH AUTHOR +Benjamin Marzinski --- -2.17.2 - diff --git a/0006-libmultipath-allow-force-reload-with-no-active-paths.patch b/0006-libmultipath-allow-force-reload-with-no-active-paths.patch deleted file mode 100644 index 77d5474..0000000 --- a/0006-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: Wed, 25 Mar 2020 23:22:48 -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/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 61% rename from 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 0b95ee6..cef8b56 100644 --- a/0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From d6ad888bad3850bb0a342ebcdc9fd78773eb3b2a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 17 Oct 2014 11:20:34 -0500 Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A @@ -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 61d9c39e..c7a16636 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -451,3 +451,47 @@ int unmark_failed_wwid(const char *wwid) - print_failed_wwid_result("unmark_failed", wwid, r); - return r; +diff --git a/multipath/main.c b/multipath/main.c +index 31012874..a667c2ee 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -111,7 +111,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); +@@ -125,6 +125,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" +@@ -440,6 +442,50 @@ static void cleanup_vecs(void) + free_pathvec(vecs.pathvec, FREE_PATHS); } -+ -+int remember_cmdline_wwid(void) + ++static int remember_cmdline_wwid(void) +{ + FILE *f = NULL; + char buf[LINE_MAX], *next, *ptr; @@ -73,50 +88,20 @@ index 61d9c39e..c7a16636 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 3da692dc..ce48a932 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -135,7 +135,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); -@@ -149,6 +149,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" -@@ -896,7 +898,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) +@@ -851,7 +897,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; -@@ -973,6 +975,10 @@ main (int argc, char *argv[]) + case 'v': + if (!isdigit(optarg[0])) { +@@ -922,6 +968,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -127,11 +112,11 @@ index 3da692dc..ce48a932 100644 case 'h': usage(argv[0]); exit(RTVL_OK); -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 5b29a5d9..0478f4e7 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. +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 5b29a5d9..0478f4e7 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 5b29a5d9..0478f4e7 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 ab166435..1ec08c6e 100644 +--- a/multipathd/multipathd.service.in ++++ b/multipathd/multipathd.service.in +@@ -19,6 +19,7 @@ StartLimitBurst=3 + [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 - ++ExecStartPre=-@BINDIR@/multipath -A + ExecStart=@BINDIR@/multipathd -d -s + ExecReload=@BINDIR@/multipathd reconfigure + Restart=on-failure diff --git a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch b/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch deleted file mode 100644 index 6c33439..0000000 --- a/0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Fri, 3 Apr 2020 13:03:01 +0200 -Subject: [PATCH] kpartx.rules: honor DM_UDEV_DISABLE_OTHER_RULES_FLAG - -10-dm.rules sets DM_UDEV_DISABLE_OTHER_RULES_FLAG for spurious -events that should be ignored by other layers. This means devices -with DISK_RO set, and devices that have never been set up properly -by device-mapper before. This flag should be respected by kpartx. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8f990494..f1bf31ca 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -7,6 +7,7 @@ - KERNEL!="dm-*", GOTO="kpartx_end" - ACTION!="add|change", GOTO="kpartx_end" - ENV{DM_UUID}!="?*", GOTO="kpartx_end" -+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" - - # Create dm tables for partitions on multipath devices. - ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" --- -2.17.2 - diff --git a/0066-RH-reset-default-find_mutipaths-value-to-off.patch b/0008-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 52% rename from 0066-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0008-RH-reset-default-find_mutipaths-value-to-off.patch index 2dfb52e..fdc90d4 100644 --- a/0066-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/0008-RH-reset-default-find_mutipaths-value-to-off.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 064d761121e7e2c7b63ab280e341d8010a413119 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 7 Jun 2018 17:43:52 -0500 Subject: [PATCH] RH: reset default find_mutipaths value to off @@ -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 01a501bd..984d8dd8 100644 +index 134b690a..e2fe7ac4 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -22,7 +22,7 @@ +@@ -24,7 +24,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 @@ -24,6 +26,16 @@ index 01a501bd..984d8dd8 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 ba291e11..b8389db3 100644 +--- a/multipath/multipath.conf.5.in ++++ b/multipath/multipath.conf.5.in +@@ -1227,7 +1227,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/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch b/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch deleted file mode 100644 index 2a18b15..0000000 --- a/0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 2 Apr 2020 18:12:48 +0200 -Subject: [PATCH] kpartx.rules: check for skip_kpartx on synthetic uevents - -The current test to detect "spurious" uevents, and thus whether to -import DM_SUBSYSTEM_UDEV_FLAG1 (the flag for the "skip_kpartx" option) -from the udev db is wrong. In 10-dm.rules, DM_UDEV_PRIMARY_SOURCE_FLAG -is imported from the db if it isn't set, meaning that it's always 1 -for active maps. The only events for which DM_SUBSYSTEM_UDEV_FLAG1 -must not be loaded from the db are the real "primary" events, which -are "change" events with DM_ACTIVATION=="1". - -11-dm-mpath.rules resets DM_ACTIVATION to 0 if nothing should change in upper -layers. In this case importing DM_SUBSYSTEM_UDEV_FLAG1 is correct, too. kpartx -will not be called anyway, because 11-dm-mpath.rules also sets MPATH_UNCHANGED=1. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/kpartx.rules | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index f1bf31ca..d7527d7d 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -13,8 +13,11 @@ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end" - ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end" - - # DM_SUBSYSTEM_UDEV_FLAG1 is the "skip_kpartx" flag. --# For events not generated by libdevmapper, we need to fetch it from db. --ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" -+# For events not generated by libdevmapper, we need to fetch it from db: -+# - "change" events with DM_ACTIVATION!="1" (e.g. partition table changes) -+# - "add" events for which rules are not disabled ("coldplug" case) -+ENV{DM_ACTIVATION}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" -+ACTION=="add", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1" - ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end" - - # 11-dm-mpath.rules sets MPATH_UNCHANGED for events that can be ignored. --- -2.17.2 - diff --git a/0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 85% rename from 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 14b3367..8065e9f 100644 --- a/0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 335b8eb2773b07a602e84e14c1f3e289a9b25b5a Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 11 Apr 2019 13:25:42 -0500 Subject: [PATCH] RH: attempt to get ANA info via sysfs first @@ -13,10 +13,10 @@ 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 34527b22..4eaa3cc3 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c -@@ -24,6 +24,7 @@ +@@ -23,6 +23,7 @@ #include "prio.h" #include "util.h" #include "structs.h" @@ -24,7 +24,7 @@ index b5c7873d..e139360c 100644 enum { ANA_ERR_GETCTRL_FAILED = 1, -@@ -36,6 +37,7 @@ enum { +@@ -35,6 +36,7 @@ enum { ANA_ERR_GETNS_FAILED, ANA_ERR_NO_MEMORY, ANA_ERR_NO_INFORMATION, @@ -32,7 +32,7 @@ index b5c7873d..e139360c 100644 }; static const char *ana_errmsg[] = { -@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { +@@ -48,6 +50,7 @@ static const char *ana_errmsg[] = { [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", [ANA_ERR_NO_MEMORY] = "out of memory", [ANA_ERR_NO_INFORMATION] = "invalid fd", @@ -40,7 +40,7 @@ index b5c7873d..e139360c 100644 }; static const char *anas_string[] = { -@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, +@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, return -ANA_ERR_GETANAS_NOTFOUND; } @@ -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, +@@ -208,8 +232,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/0009-libmpathpersist-depend-on-libmultipath.patch b/0009-libmpathpersist-depend-on-libmultipath.patch deleted file mode 100644 index 47aad9b..0000000 --- a/0009-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/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch new file mode 100644 index 0000000..f7bca92 --- /dev/null +++ b/0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -0,0 +1,96 @@ +From 137c96d16b6bb03d8a52854e152db4ee36b7d9e4 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 31db8758..21cfcc73 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1225,13 +1225,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: +@@ -1249,10 +1245,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/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch b/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch deleted file mode 100644 index c4f0b3e..0000000 --- a/0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 14:24:37 +0200 -Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel - build - -Extend the late fixes from Christian. - -Cc: Christian Hesse -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/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch new file mode 100644 index 0000000..3fe7c25 --- /dev/null +++ b/0011-RH-add-scsi-device-handlers-to-modules-load.d.patch @@ -0,0 +1,25 @@ +From 374755791536be4870ab2e93ae36549cbaaeb800 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 03aee175..936a622f 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/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch b/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch deleted file mode 100644 index 2082970..0000000 --- a/0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 15:27:34 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: separate out OPTFLAGS - -OPTFLAGS is what distribution builds would typically override. That -should not include the warning flags we use. - -Moreover, in the definition of CFLAGS, put $(CFLAGS) first to make it -easier for the user to spot her input in the build logs. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index d4d1e0dd..7a59db85 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -93,14 +93,14 @@ 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,) - --OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -+OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 -+WARNFLAGS := -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 -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) - CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 --CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -- -MMD -MP $(CFLAGS) -+CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ -+ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -+ -MMD -MP - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared --- -2.17.2 - diff --git a/0012-RH-compile-with-libreadline-support.patch b/0012-RH-compile-with-libreadline-support.patch new file mode 100644 index 0000000..0964c42 --- /dev/null +++ b/0012-RH-compile-with-libreadline-support.patch @@ -0,0 +1,26 @@ +From cc15379130e8aa068e97c64afd46be212b456d4f 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 936a622f..f475f70f 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/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch b/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch deleted file mode 100644 index ba2ec42..0000000 --- a/0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:00:04 +0200 -Subject: [PATCH] multipath-tools: Makefile.inc: allow user settings for - LDFLAGS - -This allows e.g. setting LDFLAGS="-m32 -Wl,-b,elf32-i386" to compile -for a 32bit target on a 64bit system. - -Note that, like CFLAGS, the variable needs to be set in the environment, -not on the "make" command line. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 7a59db85..671dd1ca 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -104,7 +104,7 @@ CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - BIN_CFLAGS = -fPIE -DPIE - LIB_CFLAGS = -fPIC - SHARED_FLAGS = -shared --LDFLAGS = -Wl,-z,relro -Wl,-z,now -+LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now - BIN_LDFLAGS = -pie - - # Check whether a function with name $1 has been declared in header file $2. --- -2.17.2 - diff --git a/0013-RH-Add-mpathcleanup.patch b/0013-RH-Add-mpathcleanup.patch new file mode 100644 index 0000000..d1a8e84 --- /dev/null +++ b/0013-RH-Add-mpathcleanup.patch @@ -0,0 +1,186 @@ +From 2ef5bd86052ba0b22f4d3a16e69cdf268d90a53a 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/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch b/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch deleted file mode 100644 index 3de6cb6..0000000 --- a/0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 17:19:37 +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: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 671dd1ca..e7256e3a 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 $(STACKPROT) --param=ssp-buffer-size=4 - WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ --- -2.17.2 - diff --git a/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch b/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch deleted file mode 100644 index 749bef2..0000000 --- a/0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:02:25 +0200 -Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t - -Otherwise compilation for 32bit targets spits out warnings. - -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/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch b/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch deleted file mode 100644 index a97c202..0000000 --- a/0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 16:03:58 +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: Benjamin Marzinski ---- - libmpathpersist/mpath_pr_ioctl.c | 2 +- - libmultipath/print.c | 12 ++++++------ - libmultipath/prioritizers/alua_spc3.h | 2 +- - multipathd/cli_handlers.c | 20 ++++++++++---------- - multipathd/main.c | 2 +- - 5 files changed, 19 insertions(+), 19 deletions(-) - -diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c -index fadc9e10..126601c3 100644 ---- a/libmpathpersist/mpath_pr_ioctl.c -+++ b/libmpathpersist/mpath_pr_ioctl.c -@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff) - uint32_t additional_length, k, tid_len_len = 0; - char tempbuff[MPATH_MAX_PARAM_LEN]; - struct prin_fulldescr fdesc; -- static const int pbuf_size = -+ static const unsigned int pbuf_size = - sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer); - - convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration); -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/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch b/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch deleted file mode 100644 index c621937..0000000 --- a/0016-libmultipath-set_uint-fix-parsing-for-32bit.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 22:22:25 +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: 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/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch b/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch deleted file mode 100644 index 282aa38..0000000 --- a/0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 18:24:19 +0200 -Subject: [PATCH] multipath-tools tests/Makefile: add -lmpathcmd to LIBDEPS - -Make sure the linker finds libmpathcmd. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 77ff3249..028c9ea7 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS) - - CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - -Wno-unused-parameter $(W_MISSING_INITIALIZERS) --LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka -+LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ - alias directio --- -2.17.2 - diff --git a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch b/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch deleted file mode 100644 index 5835089..0000000 --- a/0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 23:44:19 +0200 -Subject: [PATCH] multipath tools tests/Makefile: Fix OBJDEPS for hwtable-test - -OBJDEPS needs to list object files that _call_ functions we want -to wrap, but it should _not_ list the object files where these -functions are defined; otherwise the linker might resolve these -symbols before they can be wrapped. - -(Observed on i586 with gcc 9.3.1, ld 2.34.0, where wrapping -prio_getprio() doesn't work with prio.o in OBJDEPS). - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 028c9ea7..1b8706a7 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -41,7 +41,7 @@ endif - dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu - hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ -- ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o -+ ../libmultipath/structs.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl - blacklist-test_TESTDEPS := test-log.o - blacklist-test_OBJDEPS := ../libmultipath/blacklist.o --- -2.17.2 - diff --git a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch b/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch deleted file mode 100644 index e5882f6..0000000 --- a/0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 11 May 2020 23:43:02 +0200 -Subject: [PATCH] multipath-tools tests/test-lib.c: drop - __wrap_is_claimed_by_foreign - -is_claimed_by_foreign() is an inline function and can't be wrapped. - -Signed-off-by: Benjamin Marzinski ---- - tests/test-lib.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/tests/test-lib.c b/tests/test-lib.c -index 59275163..00bae58e 100644 ---- a/tests/test-lib.c -+++ b/tests/test-lib.c -@@ -56,12 +56,6 @@ int __wrap_execute_program(char *path, char *value, int len) - return 0; - } - --bool __wrap_is_claimed_by_foreign(struct udev_device *ud) --{ -- condlog(5, "%s: %p", __func__, ud); -- return false; --} -- - struct udev_list_entry - *__wrap_udev_device_get_properties_list_entry(struct udev_device *ud) - { --- -2.17.2 - diff --git a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch b/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch deleted file mode 100644 index 3bf6f75..0000000 --- a/0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 00:11:39 +0200 -Subject: [PATCH] multipath-tools tests/directio: fix -Wmaybe-uninitalized - warning - -Initialize aio_grp to satisfy gcc. - -Signed-off-by: Benjamin Marzinski ---- - tests/directio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/directio.c b/tests/directio.c -index 3cd7a520..66aaf0eb 100644 ---- a/tests/directio.c -+++ b/tests/directio.c -@@ -316,7 +316,7 @@ static void test_init_free(void **state) - { - int i, count = 0; - struct checker c[4096] = {0}; -- struct aio_group *aio_grp; -+ struct aio_group *aio_grp = NULL; - - assert_true(list_empty(&aio_grp_list)); - will_return(__wrap_io_setup, 0); --- -2.17.2 - diff --git a/0021-libmultipath-move-libsg-into-libmultipath.patch b/0021-libmultipath-move-libsg-into-libmultipath.patch deleted file mode 100644 index e7cf278..0000000 --- a/0021-libmultipath-move-libsg-into-libmultipath.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 16:46:15 +0200 -Subject: [PATCH] libmultipath: move libsg into libmultipath - -sg_read() is called from readsector0 and emc_clariion. Move it -to libmultipath/, where all common code resides. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 3 ++- - libmultipath/checkers/Makefile | 6 +++--- - libmultipath/{checkers => }/libsg.c | 0 - libmultipath/{checkers => }/libsg.h | 0 - libmultipath/prioritizers/Makefile | 2 +- - 5 files changed, 6 insertions(+), 5 deletions(-) - rename libmultipath/{checkers => }/libsg.c (100%) - rename libmultipath/{checkers => }/libsg.h (100%) - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index ad690a49..f19b7ad2 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -47,7 +47,8 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - switchgroup.o uxsock.o print.o alias.o log_pthread.o \ - log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ -- io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o -+ io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ -+ libsg.o - - all: $(LIBS) - -diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile -index 02caea64..01c04510 100644 ---- a/libmultipath/checkers/Makefile -+++ b/libmultipath/checkers/Makefile -@@ -17,10 +17,10 @@ LIBS= \ - - all: $(LIBS) - --libcheckdirectio.so: libsg.o directio.o -+libcheckdirectio.so: directio.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio - --libcheck%.so: libsg.o %.o -+libcheck%.so: %.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ - - install: -@@ -32,7 +32,7 @@ uninstall: - clean: dep_clean - $(RM) core *.a *.o *.gz *.so - --OBJS := $(LIBS:libcheck%.so=%.o) libsg.o directio.o -+OBJS := $(LIBS:libcheck%.so=%.o) - .SECONDARY: $(OBJS) - - include $(wildcard $(OBJS:.o=.d)) -diff --git a/libmultipath/checkers/libsg.c b/libmultipath/libsg.c -similarity index 100% -rename from libmultipath/checkers/libsg.c -rename to libmultipath/libsg.c -diff --git a/libmultipath/checkers/libsg.h b/libmultipath/libsg.h -similarity index 100% -rename from libmultipath/checkers/libsg.h -rename to libmultipath/libsg.h -diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile -index 9d0fe03c..fc6e0e0c 100644 ---- a/libmultipath/prioritizers/Makefile -+++ b/libmultipath/prioritizers/Makefile -@@ -28,7 +28,7 @@ endif - - all: $(LIBS) - --libpriopath_latency.so: path_latency.o ../checkers/libsg.o -+libpriopath_latency.so: path_latency.o - $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm - - libprio%.so: %.o --- -2.17.2 - diff --git a/0022-multipath-tools-Makefile-add-install-dependency.patch b/0022-multipath-tools-Makefile-add-install-dependency.patch deleted file mode 100644 index 95c80fd..0000000 --- a/0022-multipath-tools-Makefile-add-install-dependency.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 12 May 2020 22:13:51 +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: 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/0023-libmultipath-make-libmp_dm_init-optional.patch b/0023-libmultipath-make-libmp_dm_init-optional.patch deleted file mode 100644 index 588fd87..0000000 --- a/0023-libmultipath-make-libmp_dm_init-optional.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:40 -0500 -Subject: [PATCH] libmultipath: make libmp_dm_init optional - -Move dm_initialized out of libmp_dm_task_create(), and add -a function skip_libmp_dm_init() so that users of libmultipath can skip -initializing device-mapper. This is needed for other programs that -use libmultipath (or a library that depends on it) but want to control -how device-mapper is set up. - -Also make dm_prereq a global function. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 17 +++++++++++++---- - libmultipath/devmapper.h | 3 ++- - 2 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 13a1cf53..7ed494a1 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -33,6 +33,8 @@ - #define MAX_WAIT 5 - #define LOOPS_PER_SEC 5 - -+static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; -+ - static int dm_conf_verbosity; - - #ifdef LIBDM_API_DEFERRED -@@ -229,7 +231,7 @@ dm_tgt_prereq (unsigned int *ver) - return 1; - } - --static int dm_prereq(unsigned int *v) -+int dm_prereq(unsigned int *v) - { - if (dm_lib_prereq()) - return 1; -@@ -243,7 +245,7 @@ void libmp_udev_set_sync_support(int on) - libmp_dm_udev_sync = !!on; - } - --void libmp_dm_init(void) -+static void libmp_dm_init(void) - { - struct config *conf; - int verbosity; -@@ -262,11 +264,18 @@ void libmp_dm_init(void) - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - -+static void _do_skip_libmp_dm_init(void) -+{ -+} -+ -+void skip_libmp_dm_init(void) -+{ -+ pthread_once(&dm_initialized, _do_skip_libmp_dm_init); -+} -+ - struct dm_task* - libmp_dm_task_create(int task) - { -- static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT; -- - pthread_once(&dm_initialized, libmp_dm_init); - return dm_task_create(task); - } -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 7557a86b..17fc9faf 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -28,7 +28,8 @@ - #define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1) - - void dm_init(int verbosity); --void libmp_dm_init(void); -+int dm_prereq(unsigned int *v); -+void skip_libmp_dm_init(void); - void libmp_udev_set_sync_support(int on); - struct dm_task *libmp_dm_task_create(int task); - int dm_drv_version (unsigned int * version); --- -2.17.2 - diff --git a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch b/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch deleted file mode 100644 index 47c7a80..0000000 --- a/0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:41 -0500 -Subject: [PATCH] libmultipath: make sysfs_is_multipathed able to return wwid - -sysfs_is_multipathed reads the wwid of the dm device holding a path to -check if its a multipath device. Add code to optinally set pp->wwid to -that wwid. This will be used by a future patch. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/sysfs.c | 24 +++++++++++++++++++----- - libmultipath/sysfs.h | 2 +- - multipath/main.c | 7 ++++--- - 3 files changed, 24 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c -index 62ec2ed7..12a82d95 100644 ---- a/libmultipath/sysfs.c -+++ b/libmultipath/sysfs.c -@@ -295,7 +295,7 @@ static int select_dm_devs(const struct dirent *di) - return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0; - } - --bool sysfs_is_multipathed(const struct path *pp) -+bool sysfs_is_multipathed(struct path *pp, bool set_wwid) - { - char pathbuf[PATH_MAX]; - struct scandir_result sr; -@@ -325,7 +325,7 @@ bool sysfs_is_multipathed(const struct path *pp) - for (i = 0; i < r && !found; i++) { - long fd; - int nr; -- char uuid[6]; -+ char uuid[WWID_SIZE + UUID_PREFIX_LEN]; - - if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n, - "/%s/dm/uuid", di[i]->d_name)) -@@ -339,12 +339,26 @@ bool sysfs_is_multipathed(const struct path *pp) - - pthread_cleanup_push(close_fd, (void *)fd); - nr = read(fd, uuid, sizeof(uuid)); -- if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid))) -+ if (nr > (int)UUID_PREFIX_LEN && -+ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN)) - found = true; - else if (nr < 0) { -- condlog(1, "%s: error reading from %s: %s", -- __func__, pathbuf, strerror(errno)); -+ condlog(1, "%s: error reading from %s: %m", -+ __func__, pathbuf); - } -+ if (found && set_wwid) { -+ nr -= UUID_PREFIX_LEN; -+ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr); -+ if (nr == WWID_SIZE) { -+ condlog(4, "%s: overflow while reading from %s", -+ __func__, pathbuf); -+ pp->wwid[0] = '\0'; -+ } else { -+ pp->wwid[nr] = '\0'; -+ strchop(pp->wwid); -+ } -+ } -+ - pthread_cleanup_pop(1); - } - pthread_cleanup_pop(1); -diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h -index 9ae30b39..72b39ab2 100644 ---- a/libmultipath/sysfs.h -+++ b/libmultipath/sysfs.h -@@ -14,5 +14,5 @@ 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_check_holders(char * check_devt, char * new_devt); --bool sysfs_is_multipathed(const struct path *pp); -+bool sysfs_is_multipathed(struct path *pp, bool set_wwid); - #endif -diff --git a/multipath/main.c b/multipath/main.c -index cf9d2a28..545ead87 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -638,7 +638,8 @@ configure (struct config *conf, enum mpath_cmds cmd, - * Shortcut for find_multipaths smart: - * Quick check if path is already multipathed. - */ -- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) { -+ if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -+ false)) { - r = RTVL_YES; - goto print_valid; - } -@@ -747,8 +748,8 @@ configure (struct config *conf, enum mpath_cmds cmd, - /* - * Check if we raced with multipathd - */ -- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)) ? -- RTVL_YES : RTVL_NO; -+ r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -+ false) ? RTVL_YES : RTVL_NO; - } - goto print_valid; - } --- -2.17.2 - diff --git a/0025-multipath-centralize-validation-code.patch b/0025-multipath-centralize-validation-code.patch deleted file mode 100644 index c8f862c..0000000 --- a/0025-multipath-centralize-validation-code.patch +++ /dev/null @@ -1,777 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:42 -0500 -Subject: [PATCH] multipath: centralize validation code - -This code pulls the multipath path validation code out of configure(), -and puts it into its own function, check_path_valid(). This function -calls a new libmultipath function, is_path_valid() to check just path -requested. This seperation exists so that is_path_valid() can be reused -by future code. This code will give almost the same answer as the -existing code, with the exception that now, if a device is currently -multipathed, it will always be a valid multipath path. - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/Makefile | 2 +- - libmultipath/devmapper.c | 45 ++++++ - libmultipath/devmapper.h | 1 + - libmultipath/structs.h | 24 +--- - libmultipath/valid.c | 118 ++++++++++++++++ - libmultipath/valid.h | 42 ++++++ - libmultipath/wwids.c | 10 +- - multipath/main.c | 296 +++++++++++++++++---------------------- - 8 files changed, 343 insertions(+), 195 deletions(-) - create mode 100644 libmultipath/valid.c - create mode 100644 libmultipath/valid.h - -diff --git a/libmultipath/Makefile b/libmultipath/Makefile -index f19b7ad2..e5dac5ea 100644 ---- a/libmultipath/Makefile -+++ b/libmultipath/Makefile -@@ -48,7 +48,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \ - log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ - lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \ - io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \ -- libsg.o -+ libsg.o valid.o - - all: $(LIBS) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 7ed494a1..27d52398 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -770,6 +770,51 @@ out: - return r; - } - -+/* -+ * Return -+ * 1 : map with uuid exists -+ * 0 : map with uuid doesn't exist -+ * -1 : error -+ */ -+int -+dm_map_present_by_uuid(const char *uuid) -+{ -+ struct dm_task *dmt; -+ struct dm_info info; -+ char prefixed_uuid[WWID_SIZE + UUID_PREFIX_LEN]; -+ int r = -1; -+ -+ if (!uuid || uuid[0] == '\0') -+ return 0; -+ -+ if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid)) -+ goto out; -+ -+ if (!(dmt = dm_task_create(DM_DEVICE_INFO))) -+ goto out; -+ -+ dm_task_no_open_count(dmt); -+ -+ if (!dm_task_set_uuid(dmt, prefixed_uuid)) -+ goto out_task; -+ -+ if (!dm_task_run(dmt)) -+ goto out_task; -+ -+ if (!dm_task_get_info(dmt, &info)) -+ goto out_task; -+ -+ r = !!info.exists; -+ -+out_task: -+ dm_task_destroy(dmt); -+out: -+ if (r < 0) -+ condlog(3, "%s: dm command failed in %s: %s", uuid, -+ __FUNCTION__, strerror(errno)); -+ return r; -+} -+ - static int - dm_dev_t (const char * mapname, char * dev_t, int len) - { -diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h -index 17fc9faf..5ed7edc5 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -39,6 +39,7 @@ int dm_simplecmd_noflush (int, const char *, uint16_t); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params, int flush); - int dm_map_present (const char *); -+int dm_map_present_by_uuid(const char *uuid); - int dm_get_map(const char *, unsigned long long *, char *); - int dm_get_status(const char *, char *); - int dm_type(const char *, char *); -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 9bd39eb1..d69bc2e9 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -101,29 +101,13 @@ enum yes_no_undef_states { - YNU_YES, - }; - --#define _FIND_MULTIPATHS_F (1 << 1) --#define _FIND_MULTIPATHS_I (1 << 2) --#define _FIND_MULTIPATHS_N (1 << 3) --/* -- * _FIND_MULTIPATHS_F must have the same value as YNU_YES. -- * Generate a compile time error if that isn't the case. -- */ --extern char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)]; -- --#define find_multipaths_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F)) --#define ignore_wwids_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_I)) --#define ignore_new_devs_on(conf) \ -- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_N)) -- - enum find_multipaths_states { - FIND_MULTIPATHS_UNDEF = YNU_UNDEF, - FIND_MULTIPATHS_OFF = YNU_NO, -- FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F, -- FIND_MULTIPATHS_GREEDY = _FIND_MULTIPATHS_I, -- FIND_MULTIPATHS_SMART = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_I, -- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N, -+ FIND_MULTIPATHS_ON = YNU_YES, -+ FIND_MULTIPATHS_GREEDY, -+ FIND_MULTIPATHS_SMART, -+ FIND_MULTIPATHS_STRICT, - __FIND_MULTIPATHS_LAST, - }; - -diff --git a/libmultipath/valid.c b/libmultipath/valid.c -new file mode 100644 -index 00000000..456b1f6e ---- /dev/null -+++ b/libmultipath/valid.c -@@ -0,0 +1,118 @@ -+/* -+ Copyright (c) 2020 Benjamin Marzinski, IBM -+ -+ This program is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License -+ as published by the Free Software Foundation; either version 2 -+ of the License, or (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+ */ -+#include -+#include -+#include -+ -+#include "vector.h" -+#include "config.h" -+#include "debug.h" -+#include "util.h" -+#include "devmapper.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "sysfs.h" -+#include "blacklist.h" -+#include "mpath_cmd.h" -+#include "valid.h" -+ -+int -+is_path_valid(const char *name, struct config *conf, struct path *pp, -+ bool check_multipathd) -+{ -+ int r; -+ int fd; -+ -+ if (!pp || !name || !conf) -+ return PATH_IS_ERROR; -+ -+ if (conf->find_multipaths <= FIND_MULTIPATHS_UNDEF || -+ conf->find_multipaths >= __FIND_MULTIPATHS_LAST) -+ return PATH_IS_ERROR; -+ -+ if (safe_sprintf(pp->dev, "%s", name)) -+ return PATH_IS_ERROR; -+ -+ if (sysfs_is_multipathed(pp, true)) { -+ if (pp->wwid[0] == '\0') -+ return PATH_IS_ERROR; -+ return PATH_IS_VALID_NO_CHECK; -+ } -+ -+ /* -+ * "multipath -u" may be run before the daemon is started. In this -+ * case, systemd might own the socket but might delay multipathd -+ * startup until some other unit (udev settle!) has finished -+ * starting. With many LUNs, the listen backlog may be exceeded, which -+ * would cause connect() to block. This causes udev workers calling -+ * "multipath -u" to hang, and thus creates a deadlock, until "udev -+ * settle" times out. To avoid this, call connect() in non-blocking -+ * mode here, and take EAGAIN as indication for a filled-up systemd -+ * backlog. -+ */ -+ -+ if (check_multipathd) { -+ fd = __mpath_connect(1); -+ if (fd < 0) { -+ if (errno != EAGAIN && !systemd_service_enabled(name)) { -+ condlog(3, "multipathd not running or enabled"); -+ return PATH_IS_NOT_VALID; -+ } -+ } else -+ mpath_disconnect(fd); -+ } -+ -+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", name); -+ if (!pp->udev) -+ return PATH_IS_ERROR; -+ -+ r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST); -+ if (r == PATHINFO_SKIPPED) -+ return PATH_IS_NOT_VALID; -+ else if (r) -+ return PATH_IS_ERROR; -+ -+ if (pp->wwid[0] == '\0') -+ return PATH_IS_NOT_VALID; -+ -+ if (pp->udev && pp->uid_attribute && -+ filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0) -+ return PATH_IS_NOT_VALID; -+ -+ r = is_failed_wwid(pp->wwid); -+ if (r != WWID_IS_NOT_FAILED) { -+ if (r == WWID_IS_FAILED) -+ return PATH_IS_NOT_VALID; -+ return PATH_IS_ERROR; -+ } -+ -+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) -+ return PATH_IS_VALID; -+ -+ if (check_wwids_file(pp->wwid, 0) == 0) -+ return PATH_IS_VALID_NO_CHECK; -+ -+ if (dm_map_present_by_uuid(pp->wwid) == 1) -+ return PATH_IS_VALID; -+ -+ /* all these act like FIND_MULTIPATHS_STRICT for finding if a -+ * path is valid */ -+ if (conf->find_multipaths != FIND_MULTIPATHS_SMART) -+ return PATH_IS_NOT_VALID; -+ -+ return PATH_IS_MAYBE_VALID; -+} -diff --git a/libmultipath/valid.h b/libmultipath/valid.h -new file mode 100644 -index 00000000..ce1c7cbf ---- /dev/null -+++ b/libmultipath/valid.h -@@ -0,0 +1,42 @@ -+/* -+ Copyright (c) 2020 Benjamin Marzinski, IBM -+ -+ This program is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License -+ as published by the Free Software Foundation; either version 2 -+ of the License, or (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+ */ -+#ifndef _VALID_H -+#define _VALID_H -+ -+/* -+ * PATH_IS_VALID_NO_CHECK is returned when multipath should claim -+ * the path, regardless of whether is has been released to systemd -+ * already. -+ * PATH_IS_VALID is returned by is_path_valid, when the path is -+ * valid only if it hasn't been released to systemd already. -+ * PATH_IS_MAYBE_VALID is returned when the the path would be valid -+ * if other paths with the same wwid existed. It is up to the caller -+ * to check for these other paths. -+ */ -+enum is_path_valid_result { -+ PATH_IS_ERROR = -1, -+ PATH_IS_NOT_VALID, -+ PATH_IS_VALID, -+ PATH_IS_VALID_NO_CHECK, -+ PATH_IS_MAYBE_VALID, -+ PATH_MAX_VALID_RESULT, /* only for bounds checking */ -+}; -+ -+int is_path_valid(const char *name, struct config *conf, struct path *pp, -+ bool check_multipathd); -+ -+#endif /* _VALID_D */ -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 28a2150d..637cb0ab 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -289,19 +289,19 @@ out: - int - should_multipath(struct path *pp1, vector pathvec, vector mpvec) - { -- int i, ignore_new_devs, find_multipaths; -+ int i, find_multipaths; - struct path *pp2; - struct config *conf; - - conf = get_multipath_config(); -- ignore_new_devs = ignore_new_devs_on(conf); -- find_multipaths = find_multipaths_on(conf); -+ find_multipaths = conf->find_multipaths; - put_multipath_config(conf); -- if (!find_multipaths && !ignore_new_devs) -+ if (find_multipaths == FIND_MULTIPATHS_OFF || -+ find_multipaths == FIND_MULTIPATHS_GREEDY) - return 1; - - condlog(4, "checking if %s should be multipathed", pp1->dev); -- if (!ignore_new_devs) { -+ if (find_multipaths != FIND_MULTIPATHS_STRICT) { - char tmp_wwid[WWID_SIZE]; - struct multipath *mp = find_mp_by_wwid(mpvec, pp1->wwid); - -diff --git a/multipath/main.c b/multipath/main.c -index 545ead87..953fab27 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -63,21 +63,18 @@ - #include "propsel.h" - #include "time-util.h" - #include "file.h" -+#include "valid.h" - - int logsink; - struct udev *udev; - struct config *multipath_conf; - - /* -- * Return values of configure(), print_cmd_valid(), and main(). -- * RTVL_{YES,NO} are synonyms for RTVL_{OK,FAIL} for the CMD_VALID_PATH case. -+ * Return values of configure(), check_path_valid(), and main(). - */ - enum { - RTVL_OK = 0, -- RTVL_YES = RTVL_OK, - RTVL_FAIL = 1, -- RTVL_NO = RTVL_FAIL, -- RTVL_MAYBE, /* only used internally, never returned */ - RTVL_RETRY, /* returned by configure(), not by main() */ - }; - -@@ -269,9 +266,6 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid) - continue; - } - -- if (cmd == CMD_VALID_PATH) -- continue; -- - dm_get_map(mpp->alias, &mpp->size, params); - condlog(3, "params = %s", params); - dm_get_status(mpp->alias, status); -@@ -491,10 +485,11 @@ static int print_cmd_valid(int k, const vector pathvec, - struct timespec until; - struct path *pp; - -- if (k != RTVL_YES && k != RTVL_NO && k != RTVL_MAYBE) -- return RTVL_NO; -+ if (k != PATH_IS_VALID && k != PATH_IS_NOT_VALID && -+ k != PATH_IS_MAYBE_VALID) -+ return PATH_IS_NOT_VALID; - -- if (k == RTVL_MAYBE) { -+ if (k == PATH_IS_MAYBE_VALID) { - /* - * Caller ensures that pathvec[0] is the path to - * examine. -@@ -504,7 +499,7 @@ static int print_cmd_valid(int k, const vector pathvec, - wait = find_multipaths_check_timeout( - pp, pp->find_multipaths_timeout, &until); - if (wait != FIND_MULTIPATHS_WAITING) -- k = RTVL_NO; -+ k = PATH_IS_NOT_VALID; - } else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0))) - wait = find_multipaths_check_timeout(pp, 0, &until); - if (wait == FIND_MULTIPATHS_WAITING) -@@ -513,9 +508,9 @@ static int print_cmd_valid(int k, const vector pathvec, - else if (wait == FIND_MULTIPATHS_WAIT_DONE) - printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n"); - printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n", -- k == RTVL_MAYBE ? 2 : k == RTVL_YES ? 1 : 0); -+ k == PATH_IS_MAYBE_VALID ? 2 : k == PATH_IS_VALID ? 1 : 0); - /* Never return RTVL_MAYBE */ -- return k == RTVL_NO ? RTVL_NO : RTVL_YES; -+ return k == PATH_IS_NOT_VALID ? PATH_IS_NOT_VALID : PATH_IS_VALID; - } - - /* -@@ -548,7 +543,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - int di_flag = 0; - char * refwwid = NULL; - char * dev = NULL; -- bool released = released_to_systemd(); - - /* - * allocate core vectors to store paths and multipaths -@@ -573,7 +567,7 @@ configure (struct config *conf, enum mpath_cmds cmd, - cmd != CMD_REMOVE_WWID && - (filter_devnode(conf->blist_devnode, - conf->elist_devnode, dev) > 0)) { -- goto print_valid; -+ goto out; - } - - /* -@@ -581,14 +575,10 @@ configure (struct config *conf, enum mpath_cmds cmd, - * failing the translation is fatal (by policy) - */ - if (devpath) { -- int failed = get_refwwid(cmd, devpath, dev_type, -- pathvec, &refwwid); -+ get_refwwid(cmd, devpath, dev_type, pathvec, &refwwid); - if (!refwwid) { - condlog(4, "%s: failed to get wwid", devpath); -- if (failed == 2 && cmd == CMD_VALID_PATH) -- goto print_valid; -- else -- condlog(3, "scope is null"); -+ condlog(3, "scope is null"); - goto out; - } - if (cmd == CMD_REMOVE_WWID) { -@@ -614,53 +604,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - goto out; - } - condlog(3, "scope limited to %s", refwwid); -- /* If you are ignoring the wwids file and find_multipaths is -- * set, you need to actually check if there are two available -- * paths to determine if this path should be multipathed. To -- * do this, we put off the check until after discovering all -- * the paths. -- * Paths listed in the wwids file are always considered valid. -- */ -- if (cmd == CMD_VALID_PATH) { -- if (is_failed_wwid(refwwid) == WWID_IS_FAILED) { -- r = RTVL_NO; -- goto print_valid; -- } -- if ((!find_multipaths_on(conf) && -- ignore_wwids_on(conf)) || -- check_wwids_file(refwwid, 0) == 0) -- r = RTVL_YES; -- if (!ignore_wwids_on(conf)) -- goto print_valid; -- /* At this point, either r==0 or find_multipaths_on. */ -- -- /* -- * Shortcut for find_multipaths smart: -- * Quick check if path is already multipathed. -- */ -- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -- false)) { -- r = RTVL_YES; -- goto print_valid; -- } -- -- /* -- * DM_MULTIPATH_DEVICE_PATH=="0" means that we have -- * been called for this device already, and have -- * released it to systemd. Unless the device is now -- * already multipathed (see above), we can't try to -- * grab it, because setting SYSTEMD_READY=0 would -- * cause file systems to be unmounted. -- * Leave DM_MULTIPATH_DEVICE_PATH="0". -- */ -- if (released) { -- r = RTVL_NO; -- goto print_valid; -- } -- if (r == RTVL_YES) -- goto print_valid; -- /* find_multipaths_on: Fall through to path detection */ -- } - } - - /* -@@ -701,59 +644,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - goto out; - } - -- if (cmd == CMD_VALID_PATH) { -- struct path *pp; -- int fd; -- -- /* This only happens if find_multipaths and -- * ignore_wwids is set, and the path is not in WWIDs -- * file, not currently multipathed, and has -- * never been released to systemd. -- * If there is currently a multipath device matching -- * the refwwid, or there is more than one path matching -- * the refwwid, then the path is valid */ -- if (VECTOR_SIZE(curmp) != 0) { -- r = RTVL_YES; -- goto print_valid; -- } else if (VECTOR_SIZE(pathvec) > 1) -- r = RTVL_YES; -- else -- r = RTVL_MAYBE; -- -- /* -- * If opening the path with O_EXCL fails, the path -- * is in use (e.g. mounted during initramfs processing). -- * We know that it's not used by dm-multipath. -- * We may not set SYSTEMD_READY=0 on such devices, it -- * might cause systemd to umount the device. -- * Use O_RDONLY, because udevd would trigger another -- * uevent for close-after-write. -- * -- * The O_EXCL check is potentially dangerous, because it may -- * race with other tasks trying to access the device. Therefore -- * this code is only executed if the path hasn't been released -- * to systemd earlier (see above). -- * -- * get_refwwid() above stores the path we examine in slot 0. -- */ -- pp = VECTOR_SLOT(pathvec, 0); -- fd = open(udev_device_get_devnode(pp->udev), -- O_RDONLY|O_EXCL); -- if (fd >= 0) -- close(fd); -- else { -- condlog(3, "%s: path %s is in use: %s", -- __func__, pp->dev, -- strerror(errno)); -- /* -- * Check if we raced with multipathd -- */ -- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0), -- false) ? RTVL_YES : RTVL_NO; -- } -- goto print_valid; -- } -- - if (cmd != CMD_CREATE && cmd != CMD_DRY_RUN) { - r = RTVL_OK; - goto out; -@@ -766,10 +656,6 @@ configure (struct config *conf, enum mpath_cmds cmd, - conf->force_reload, cmd); - r = rc == CP_RETRY ? RTVL_RETRY : rc == CP_OK ? RTVL_OK : RTVL_FAIL; - --print_valid: -- if (cmd == CMD_VALID_PATH) -- r = print_cmd_valid(r, pathvec, conf); -- - out: - if (refwwid) - FREE(refwwid); -@@ -780,6 +666,112 @@ out: - return r; - } - -+static int -+check_path_valid(const char *name, struct config *conf, bool is_uevent) -+{ -+ int fd, r = PATH_IS_ERROR; -+ struct path *pp = NULL; -+ vector pathvec = NULL; -+ -+ pp = alloc_path(); -+ if (!pp) -+ return RTVL_FAIL; -+ -+ r = is_path_valid(name, conf, pp, is_uevent); -+ if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT) -+ goto fail; -+ -+ /* set path values if is_path_valid() didn't */ -+ if (!pp->udev) -+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", -+ name); -+ if (!pp->udev) -+ goto fail; -+ -+ if (!strlen(pp->dev_t)) { -+ dev_t devt = udev_device_get_devnum(pp->udev); -+ if (major(devt) == 0 && minor(devt) == 0) -+ goto fail; -+ snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt), -+ minor(devt)); -+ } -+ -+ pathvec = vector_alloc(); -+ if (!pathvec) -+ goto fail; -+ -+ if (store_path(pathvec, pp) != 0) { -+ free_path(pp); -+ goto fail; -+ } -+ -+ if ((r == PATH_IS_VALID || r == PATH_IS_MAYBE_VALID) && -+ released_to_systemd()) -+ r = PATH_IS_NOT_VALID; -+ -+ /* This state is only used to skip the released_to_systemd() check */ -+ if (r == PATH_IS_VALID_NO_CHECK) -+ r = PATH_IS_VALID; -+ -+ if (r != PATH_IS_MAYBE_VALID) -+ goto out; -+ -+ /* -+ * If opening the path with O_EXCL fails, the path -+ * is in use (e.g. mounted during initramfs processing). -+ * We know that it's not used by dm-multipath. -+ * We may not set SYSTEMD_READY=0 on such devices, it -+ * might cause systemd to umount the device. -+ * Use O_RDONLY, because udevd would trigger another -+ * uevent for close-after-write. -+ * -+ * The O_EXCL check is potentially dangerous, because it may -+ * race with other tasks trying to access the device. Therefore -+ * this code is only executed if the path hasn't been released -+ * to systemd earlier (see above). -+ */ -+ fd = open(udev_device_get_devnode(pp->udev), O_RDONLY|O_EXCL); -+ if (fd >= 0) -+ close(fd); -+ else { -+ condlog(3, "%s: path %s is in use: %m", __func__, pp->dev); -+ /* Check if we raced with multipathd */ -+ if (sysfs_is_multipathed(pp, false)) -+ r = PATH_IS_VALID; -+ else -+ r = PATH_IS_NOT_VALID; -+ goto out; -+ } -+ -+ /* For find_multipaths = SMART, if there is more than one path -+ * matching the refwwid, then the path is valid */ -+ if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0) -+ goto fail; -+ filter_pathvec(pathvec, pp->wwid); -+ if (VECTOR_SIZE(pathvec) > 1) -+ r = PATH_IS_VALID; -+ else -+ r = PATH_IS_MAYBE_VALID; -+ -+out: -+ r = print_cmd_valid(r, pathvec, conf); -+ free_pathvec(pathvec, FREE_PATHS); -+ /* -+ * multipath -u must exit with status 0, otherwise udev won't -+ * import its output. -+ */ -+ if (!is_uevent && r == PATH_IS_NOT_VALID) -+ return RTVL_FAIL; -+ return RTVL_OK; -+ -+fail: -+ if (pathvec) -+ free_pathvec(pathvec, FREE_PATHS); -+ else -+ free_path(pp); -+ return RTVL_FAIL; -+} -+ - static int - get_dev_type(char *dev) { - struct stat buf; -@@ -861,32 +853,6 @@ out: - return r; - } - --static int test_multipathd_socket(void) --{ -- int fd; -- /* -- * "multipath -u" may be run before the daemon is started. In this -- * case, systemd might own the socket but might delay multipathd -- * startup until some other unit (udev settle!) has finished -- * starting. With many LUNs, the listen backlog may be exceeded, which -- * would cause connect() to block. This causes udev workers calling -- * "multipath -u" to hang, and thus creates a deadlock, until "udev -- * settle" times out. To avoid this, call connect() in non-blocking -- * mode here, and take EAGAIN as indication for a filled-up systemd -- * backlog. -- */ -- -- fd = __mpath_connect(1); -- if (fd == -1) { -- if (errno == EAGAIN) -- condlog(3, "daemon backlog exceeded"); -- else -- return 0; -- } else -- close(fd); -- return 1; --} -- - int - main (int argc, char *argv[]) - { -@@ -970,7 +936,11 @@ main (int argc, char *argv[]) - conf->force_reload = FORCE_RELOAD_YES; - break; - case 'i': -- conf->find_multipaths |= _FIND_MULTIPATHS_I; -+ if (conf->find_multipaths == FIND_MULTIPATHS_ON || -+ conf->find_multipaths == FIND_MULTIPATHS_STRICT) -+ conf->find_multipaths = FIND_MULTIPATHS_SMART; -+ else if (conf->find_multipaths == FIND_MULTIPATHS_OFF) -+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; - break; - case 't': - r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK; -@@ -1064,15 +1034,10 @@ main (int argc, char *argv[]) - condlog(0, "the -c option requires a path to check"); - goto out; - } -- if (cmd == CMD_VALID_PATH && -- dev_type == DEV_UEVENT) { -- if (!test_multipathd_socket()) { -- condlog(3, "%s: daemon is not running", dev); -- if (!systemd_service_enabled(dev)) { -- r = print_cmd_valid(RTVL_NO, NULL, conf); -- goto out; -- } -- } -+ if (cmd == CMD_VALID_PATH) { -+ char * name = convert_dev(dev, (dev_type == DEV_DEVNODE)); -+ r = check_path_valid(name, conf, dev_type == DEV_UEVENT); -+ goto out; - } - - if (cmd == CMD_REMOVE_WWID && !dev) { -@@ -1136,13 +1101,6 @@ out: - cleanup_prio(); - cleanup_checkers(); - -- /* -- * multipath -u must exit with status 0, otherwise udev won't -- * import its output. -- */ -- if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT && r == RTVL_NO) -- r = RTVL_OK; -- - if (dev_type == DEV_UEVENT) - closelog(); - --- -2.17.2 - diff --git a/0026-Unit-tests-for-is_path_valid.patch b/0026-Unit-tests-for-is_path_valid.patch deleted file mode 100644 index 9ada368..0000000 --- a/0026-Unit-tests-for-is_path_valid.patch +++ /dev/null @@ -1,530 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:43 -0500 -Subject: [PATCH] Unit tests for is_path_valid() - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 4 +- - tests/valid.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 489 insertions(+), 1 deletion(-) - create mode 100644 tests/valid.c - -diff --git a/tests/Makefile b/tests/Makefile -index 1b8706a7..125553b8 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \ - LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka - - TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \ -- alias directio -+ alias directio valid - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -@@ -50,6 +50,8 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o - vpd-test_LIBDEPS := -ludev -lpthread -ldl - alias-test_TESTDEPS := test-log.o - alias-test_LIBDEPS := -lpthread -ldl -+valid-test_OBJDEPS := ../libmultipath/valid.o -+valid-test_LIBDEPS := -ludev -lpthread -ldl - ifneq ($(DIO_TEST_DEV),) - directio-test_LIBDEPS := -laio - endif -diff --git a/tests/valid.c b/tests/valid.c -new file mode 100644 -index 00000000..693c72c5 ---- /dev/null -+++ b/tests/valid.c -@@ -0,0 +1,486 @@ -+/* -+ * Copyright (c) 2020 Benjamin Marzinski, Redhat -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "globals.c" -+#include "util.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "blacklist.h" -+#include "valid.h" -+ -+int test_fd; -+struct udev_device { -+ int unused; -+} test_udev; -+ -+bool __wrap_sysfs_is_multipathed(struct path *pp, bool set_wwid) -+{ -+ bool is_multipathed = mock_type(bool); -+ assert_non_null(pp); -+ assert_int_not_equal(strlen(pp->dev), 0); -+ if (is_multipathed && set_wwid) -+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); -+ return is_multipathed; -+} -+ -+int __wrap___mpath_connect(int nonblocking) -+{ -+ bool connected = mock_type(bool); -+ assert_int_equal(nonblocking, 1); -+ if (connected) -+ return test_fd; -+ errno = mock_type(int); -+ return -1; -+} -+ -+int __wrap_systemd_service_enabled(const char *dev) -+{ -+ return (int)mock_type(bool); -+} -+ -+/* There's no point in checking the return value here */ -+int __wrap_mpath_disconnect(int fd) -+{ -+ assert_int_equal(fd, test_fd); -+ return 0; -+} -+ -+struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) -+{ -+ bool passed = mock_type(bool); -+ assert_string_equal(sysname, mock_ptr_type(char *)); -+ if (passed) -+ return &test_udev; -+ return NULL; -+} -+ -+int __wrap_pathinfo(struct path *pp, struct config *conf, int mask) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(pp->dev, mock_ptr_type(char *)); -+ assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST); -+ if (ret == PATHINFO_OK) { -+ pp->uid_attribute = "ID_TEST"; -+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE); -+ } else -+ memset(pp->wwid, 0, WWID_SIZE); -+ return ret; -+} -+ -+int __wrap_filter_property(struct config *conf, struct udev_device *udev, -+ int lvl, const char *uid_attribute) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(uid_attribute, "ID_TEST"); -+ return ret; -+} -+ -+int __wrap_is_failed_wwid(const char *wwid) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(wwid, mock_ptr_type(char *)); -+ return ret; -+} -+ -+int __wrap_check_wwids_file(char *wwid, int write_wwid) -+{ -+ bool passed = mock_type(bool); -+ assert_int_equal(write_wwid, 0); -+ assert_string_equal(wwid, mock_ptr_type(char *)); -+ if (passed) -+ return 0; -+ else -+ return -1; -+} -+ -+int __wrap_dm_map_present_by_uuid(const char *uuid) -+{ -+ int ret = mock_type(int); -+ assert_string_equal(uuid, mock_ptr_type(char *)); -+ return ret; -+} -+ -+enum { -+ STAGE_IS_MULTIPATHED, -+ STAGE_CHECK_MULTIPATHD, -+ STAGE_GET_UDEV_DEVICE, -+ STAGE_PATHINFO, -+ STAGE_FILTER_PROPERTY, -+ STAGE_IS_FAILED, -+ STAGE_CHECK_WWIDS, -+ STAGE_UUID_PRESENT, -+}; -+ -+enum { -+ CHECK_MPATHD_RUNNING, -+ CHECK_MPATHD_EAGAIN, -+ CHECK_MPATHD_ENABLED, -+ CHECK_MPATHD_SKIP, -+}; -+ -+/* setup the test to continue past the given stage in is_path_valid() */ -+static void setup_passing(char *name, char *wwid, unsigned int check_multipathd, -+ unsigned int stage) -+{ -+ will_return(__wrap_sysfs_is_multipathed, false); -+ if (stage == STAGE_IS_MULTIPATHED) -+ return; -+ if (check_multipathd == CHECK_MPATHD_RUNNING) -+ will_return(__wrap___mpath_connect, true); -+ else if (check_multipathd == CHECK_MPATHD_EAGAIN) { -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, EAGAIN); -+ } else if (check_multipathd == CHECK_MPATHD_ENABLED) { -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, ECONNREFUSED); -+ will_return(__wrap_systemd_service_enabled, true); -+ } -+ /* nothing for CHECK_MPATHD_SKIP */ -+ if (stage == STAGE_CHECK_MULTIPATHD) -+ return; -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ if (stage == STAGE_GET_UDEV_DEVICE) -+ return; -+ will_return(__wrap_pathinfo, PATHINFO_OK); -+ will_return(__wrap_pathinfo, name); -+ will_return(__wrap_pathinfo, wwid); -+ if (stage == STAGE_PATHINFO) -+ return; -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT); -+ if (stage == STAGE_FILTER_PROPERTY) -+ return; -+ will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ if (stage == STAGE_IS_FAILED) -+ return; -+ will_return(__wrap_check_wwids_file, false); -+ will_return(__wrap_check_wwids_file, wwid); -+ if (stage == STAGE_CHECK_WWIDS) -+ return; -+ will_return(__wrap_dm_map_present_by_uuid, 0); -+ will_return(__wrap_dm_map_present_by_uuid, wwid); -+} -+ -+static void test_bad_arguments(void **state) -+{ -+ struct path pp; -+ char too_long[FILE_NAME_SIZE + 1]; -+ -+ memset(&pp, 0, sizeof(pp)); -+ /* test NULL pointers */ -+ assert_int_equal(is_path_valid("test", &conf, NULL, true), -+ PATH_IS_ERROR); -+ assert_int_equal(is_path_valid("test", NULL, &pp, true), -+ PATH_IS_ERROR); -+ assert_int_equal(is_path_valid(NULL, &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test undefined find_multipaths */ -+ conf.find_multipaths = FIND_MULTIPATHS_UNDEF; -+ assert_int_equal(is_path_valid("test", &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test name too long */ -+ memset(too_long, 'x', sizeof(too_long)); -+ too_long[sizeof(too_long) - 1] = '\0'; -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ assert_int_equal(is_path_valid(too_long, &conf, &pp, true), -+ PATH_IS_ERROR); -+} -+ -+static void test_sysfs_is_multipathed(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test_wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* test for already existing multiapthed device */ -+ will_return(__wrap_sysfs_is_multipathed, true); -+ will_return(__wrap_sysfs_is_multipathed, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID_NO_CHECK); -+ assert_string_equal(pp.dev, name); -+ assert_string_equal(pp.wwid, wwid); -+ /* test for wwid device with empty wwid */ -+ will_return(__wrap_sysfs_is_multipathed, true); -+ will_return(__wrap_sysfs_is_multipathed, ""); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+} -+ -+static void test_check_multipathd(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* test failed check to see if multipathd is active */ -+ will_return(__wrap_sysfs_is_multipathed, false); -+ will_return(__wrap___mpath_connect, false); -+ will_return(__wrap___mpath_connect, ECONNREFUSED); -+ will_return(__wrap_systemd_service_enabled, false); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ /* test pass because service is enabled. fail getting udev */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_ENABLED, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ assert_string_equal(pp.dev, name); -+ /* test pass because connect returned EAGAIN. fail getting udev */ -+ setup_passing(name, NULL, CHECK_MPATHD_EAGAIN, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ /* test pass because connect succeeded. fail getting udev */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false); -+ will_return(__wrap_udev_device_new_from_subsystem_sysname, -+ name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_ERROR); -+ assert_string_equal(pp.dev, name); -+} -+ -+static void test_pathinfo(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* Test pathinfo blacklisting device */ -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_SKIPPED); -+ will_return(__wrap_pathinfo, name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ /* Test pathinfo failing */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_FAILED); -+ will_return(__wrap_pathinfo, name); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_ERROR); -+ /* Test blank wwid */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE); -+ will_return(__wrap_pathinfo, PATHINFO_OK); -+ will_return(__wrap_pathinfo, name); -+ will_return(__wrap_pathinfo, ""); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+} -+ -+static void test_filter_property(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test blacklist property */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test missing property */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test MATCH_NOTHING fail on is_failed_wwid */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO); -+ will_return(__wrap_filter_property, MATCH_NOTHING); -+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+} -+ -+static void test_is_failed_wwid(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ /* Test wwid failed */ -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); -+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test is_failed_wwid error */ -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY); -+ will_return(__wrap_is_failed_wwid, WWID_FAILED_ERROR); -+ will_return(__wrap_is_failed_wwid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_ERROR); -+} -+ -+static void test_greedy(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test greedy success with checking multipathd */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_GREEDY; -+ setup_passing(name, wwid, CHECK_MPATHD_RUNNING, STAGE_IS_FAILED); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test greedy success without checking multiapthd */ -+ memset(&pp, 0, sizeof(pp)); -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_VALID); -+} -+ -+static void test_check_wwids(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_EAGAIN, STAGE_IS_FAILED); -+ will_return(__wrap_check_wwids_file, true); -+ will_return(__wrap_check_wwids_file, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID_NO_CHECK); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+static void test_check_uuid_present(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_ENABLED, STAGE_CHECK_WWIDS); -+ will_return(__wrap_dm_map_present_by_uuid, 1); -+ will_return(__wrap_dm_map_present_by_uuid, wwid); -+ assert_int_equal(is_path_valid(name, &conf, &pp, true), -+ PATH_IS_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+ -+static void test_find_multipaths(void **state) -+{ -+ struct path pp; -+ char *name = "test"; -+ char *wwid = "test-wwid"; -+ -+ /* test find_multipaths = FIND_MULTIPATHS_STRICT */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_STRICT; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+ /* test find_multipaths = FIND_MULTIPATHS_OFF */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_OFF; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test find_multipaths = FIND_MULTIPATHS_ON */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_ON; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_NOT_VALID); -+ /* test find_multipaths = FIND_MULTIPATHS_SMART */ -+ memset(&pp, 0, sizeof(pp)); -+ conf.find_multipaths = FIND_MULTIPATHS_SMART; -+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT); -+ assert_int_equal(is_path_valid(name, &conf, &pp, false), -+ PATH_IS_MAYBE_VALID); -+ assert_string_equal(pp.dev, name); -+ assert_ptr_equal(pp.udev, &test_udev); -+ assert_string_equal(pp.wwid, wwid); -+} -+ -+int test_valid(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_bad_arguments), -+ cmocka_unit_test(test_sysfs_is_multipathed), -+ cmocka_unit_test(test_check_multipathd), -+ cmocka_unit_test(test_pathinfo), -+ cmocka_unit_test(test_filter_property), -+ cmocka_unit_test(test_is_failed_wwid), -+ cmocka_unit_test(test_greedy), -+ cmocka_unit_test(test_check_wwids), -+ cmocka_unit_test(test_check_uuid_present), -+ cmocka_unit_test(test_find_multipaths), -+ }; -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ ret += test_valid(); -+ return ret; -+} --- -2.17.2 - diff --git a/0027-libmultipath-simplify-failed-wwid-code.patch b/0027-libmultipath-simplify-failed-wwid-code.patch deleted file mode 100644 index bb60d21..0000000 --- a/0027-libmultipath-simplify-failed-wwid-code.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 12:08:44 -0500 -Subject: [PATCH] libmultipath: simplify failed wwid code - -The (is|mark|unmark)_failed_wwid code is needlessly complicated. -Locking a file is necssary if multiple processes could otherwise be -writing to it at the same time. That is not the case with the -failed_wwids files. They can simply be empty files in a directory. Even -with all the locking in place, two processes accessing or modifying a -file at the same time will still race. And even without the locking, if -two processes try to access or modify a file at the same time, they will -both see a reasonable result, and will leave the files in a valid state -afterwards. - -Instead of doing all the locking work (which made it necessary to write -a file, even just to check if a file existed), simply check for files -with lstat(), create them with open(), and remove them with unlink(). - -Reviewed-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/wwids.c | 131 ++++++++++++++++++------------------------- - 1 file changed, 56 insertions(+), 75 deletions(-) - -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 637cb0ab..aab5da8a 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #include "util.h" - #include "checkers.h" -@@ -348,109 +349,89 @@ remember_wwid(char *wwid) - } - - static const char shm_dir[] = MULTIPATH_SHM_BASE "failed_wwids"; --static const char shm_lock[] = ".lock"; --static const char shm_header[] = "multipath shm lock file, don't edit"; --static char _shm_lock_path[sizeof(shm_dir)+sizeof(shm_lock)]; --static const char *shm_lock_path = &_shm_lock_path[0]; - --static void init_shm_paths(void) -+static void print_failed_wwid_result(const char * msg, const char *wwid, int r) - { -- snprintf(_shm_lock_path, sizeof(_shm_lock_path), -- "%s/%s", shm_dir, shm_lock); -+ switch(r) { -+ case WWID_FAILED_ERROR: -+ condlog(1, "%s: %s: %m", msg, wwid); -+ return; -+ case WWID_IS_FAILED: -+ case WWID_IS_NOT_FAILED: -+ condlog(4, "%s: %s is %s", msg, wwid, -+ r == WWID_IS_FAILED ? "failed" : "good"); -+ return; -+ case WWID_FAILED_CHANGED: -+ condlog(3, "%s: %s", msg, wwid); -+ } - } - --static pthread_once_t shm_path_once = PTHREAD_ONCE_INIT; -- --static int multipath_shm_open(bool rw) -+int is_failed_wwid(const char *wwid) - { -- int fd; -- int can_write; -- -- pthread_once(&shm_path_once, init_shm_paths); -- fd = open_file(shm_lock_path, &can_write, shm_header); -+ struct stat st; -+ char path[PATH_MAX]; -+ int r; - -- if (fd >= 0 && rw && !can_write) { -- close(fd); -- condlog(1, "failed to open %s for writing", shm_dir); -+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -+ condlog(1, "%s: path name overflow", __func__); - return -1; - } - -- return fd; --} -- --static void multipath_shm_close(void *arg) --{ -- long fd = (long)arg; -+ if (lstat(path, &st) == 0) -+ r = WWID_IS_FAILED; -+ else if (errno == ENOENT) -+ r = WWID_IS_NOT_FAILED; -+ else -+ r = WWID_FAILED_ERROR; - -- close(fd); -- unlink(shm_lock_path); -+ print_failed_wwid_result("is_failed", wwid, r); -+ return r; - } - --static int _failed_wwid_op(const char *wwid, bool rw, -- int (*func)(const char *), const char *msg) -+int mark_failed_wwid(const char *wwid) - { - char path[PATH_MAX]; -- long lockfd; -- int r = -1; -+ int r, fd; - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); - return -1; - } -- -- lockfd = multipath_shm_open(rw); -- if (lockfd == -1) -+ if (ensure_directories_exist(path, 0700) < 0) { -+ condlog(1, "%s: can't setup directories", __func__); - return -1; -+ } - -- pthread_cleanup_push(multipath_shm_close, (void *)lockfd); -- r = func(path); -- pthread_cleanup_pop(1); -- -- if (r == WWID_FAILED_ERROR) -- condlog(1, "%s: %s: %s", msg, wwid, strerror(errno)); -- else if (r == WWID_FAILED_CHANGED) -- condlog(3, "%s: %s", msg, wwid); -- else if (!rw) -- condlog(4, "%s: %s is %s", msg, wwid, -- r == WWID_IS_FAILED ? "failed" : "good"); -+ fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -+ if (fd >= 0) { -+ close(fd); -+ r = WWID_FAILED_CHANGED; -+ } else if (errno == EEXIST) -+ r = WWID_FAILED_UNCHANGED; -+ else -+ r = WWID_FAILED_ERROR; - -+ print_failed_wwid_result("mark_failed", wwid, r); - return r; - } - --static int _is_failed(const char *path) -+int unmark_failed_wwid(const char *wwid) - { -- struct stat st; -+ char path[PATH_MAX]; -+ int r; - -- if (lstat(path, &st) == 0) -- return WWID_IS_FAILED; -+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -+ condlog(1, "%s: path name overflow", __func__); -+ return -1; -+ } -+ -+ if (unlink(path) == 0) -+ r = WWID_FAILED_CHANGED; - else if (errno == ENOENT) -- return WWID_IS_NOT_FAILED; -+ r = WWID_FAILED_UNCHANGED; - else -- return WWID_FAILED_ERROR; --} -- --static int _mark_failed(const char *path) --{ -- /* Called from _failed_wwid_op: we know that shm_lock_path exists */ -- if (_is_failed(path) == WWID_IS_FAILED) -- return WWID_FAILED_UNCHANGED; -- return (link(shm_lock_path, path) == 0 ? WWID_FAILED_CHANGED : -- WWID_FAILED_ERROR); --} -+ r = WWID_FAILED_ERROR; - --static int _unmark_failed(const char *path) --{ -- if (_is_failed(path) == WWID_IS_NOT_FAILED) -- return WWID_FAILED_UNCHANGED; -- return (unlink(path) == 0 ? WWID_FAILED_CHANGED : WWID_FAILED_ERROR); --} -- --#define declare_failed_wwid_op(op, rw) \ --int op ## _wwid(const char *wwid) \ --{ \ -- return _failed_wwid_op(wwid, (rw), _ ## op, #op); \ -+ print_failed_wwid_result("unmark_failed", wwid, r); -+ return r; - } -- --declare_failed_wwid_op(is_failed, false) --declare_failed_wwid_op(mark_failed, true) --declare_failed_wwid_op(unmark_failed, true) --- -2.17.2 - diff --git a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch b/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch deleted file mode 100644 index 6b9941a..0000000 --- a/0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 19 May 2020 12:08:45 -0500 -Subject: [PATCH] libmultipath: use atomic linkat() in mark_failed_wwid() - -This keeps (almost) the simplicity of the previous patch, while -making sure that the return value of mark_failed_wwid() -(WWID_FAILED_CHANGED vs. WWID_FAILED_UNCHANGED) is correct, even -if several processes access this WWID at the same time. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/wwids.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index aab5da8a..61d9c39e 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -374,7 +374,7 @@ int is_failed_wwid(const char *wwid) - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); -- return -1; -+ return WWID_FAILED_ERROR; - } - - if (lstat(path, &st) == 0) -@@ -390,27 +390,43 @@ int is_failed_wwid(const char *wwid) - - int mark_failed_wwid(const char *wwid) - { -- char path[PATH_MAX]; -- int r, fd; -+ char tmpfile[WWID_SIZE + 2 * sizeof(long) + 1]; -+ int r = WWID_FAILED_ERROR, fd, dfd; - -- if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { -- condlog(1, "%s: path name overflow", __func__); -- return -1; -+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); -+ if (dfd == -1 && errno == ENOENT) { -+ char path[sizeof(shm_dir) + 2]; -+ -+ /* arg for ensure_directories_exist() must not end with "/" */ -+ safe_sprintf(path, "%s/_", shm_dir); -+ ensure_directories_exist(path, 0700); -+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY); - } -- if (ensure_directories_exist(path, 0700) < 0) { -- condlog(1, "%s: can't setup directories", __func__); -- return -1; -+ if (dfd == -1) { -+ condlog(1, "%s: can't setup %s: %m", __func__, shm_dir); -+ return WWID_FAILED_ERROR; - } - -- fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -- if (fd >= 0) { -+ safe_sprintf(tmpfile, "%s.%lx", wwid, (long)getpid()); -+ fd = openat(dfd, tmpfile, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR); -+ if (fd >= 0) - close(fd); -+ else -+ goto out_closedir; -+ -+ if (linkat(dfd, tmpfile, dfd, wwid, 0) == 0) - r = WWID_FAILED_CHANGED; -- } else if (errno == EEXIST) -+ else if (errno == EEXIST) - r = WWID_FAILED_UNCHANGED; - else - r = WWID_FAILED_ERROR; - -+ if (unlinkat(dfd, tmpfile, 0) == -1) -+ condlog(2, "%s: failed to unlink %s/%s: %m", -+ __func__, shm_dir, tmpfile); -+ -+out_closedir: -+ close(dfd); - print_failed_wwid_result("mark_failed", wwid, r); - return r; - } -@@ -422,7 +438,7 @@ int unmark_failed_wwid(const char *wwid) - - if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) { - condlog(1, "%s: path name overflow", __func__); -- return -1; -+ return WWID_FAILED_ERROR; - } - - if (unlink(path) == 0) --- -2.17.2 - diff --git a/0029-fix-boolean-value-with-json-c-0.14.patch b/0029-fix-boolean-value-with-json-c-0.14.patch deleted file mode 100644 index 29bb90b..0000000 --- a/0029-fix-boolean-value-with-json-c-0.14.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "mail@eworm.de" -Date: Sat, 25 Apr 2020 21:11:13 +0200 -Subject: [PATCH] fix boolean value with json-c 0.14 - -Upstream json-c removed the TRUE and FALSE defines in commit -0992aac61f8b087efd7094e9ac2b84fa9c040fcd. - -[mwilck]: Use stdbool.h, and keep the log message unchanged. - -Signed-off-by: Christian Hesse -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libdmmp/libdmmp_private.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h -index ac85b63f..b1a6ddea 100644 ---- a/libdmmp/libdmmp_private.h -+++ b/libdmmp/libdmmp_private.h -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - #include - - #include "libdmmp/libdmmp.h" -@@ -82,7 +83,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \ - do { \ - json_type j_type = json_type_null; \ - json_object *j_obj_tmp = NULL; \ -- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \ -+ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != true) { \ - _error(ctx, "Invalid JSON output from multipathd IPC: " \ - "key '%s' not found", key); \ - rc = DMMP_ERR_IPC_ERROR; \ --- -2.17.2 - diff --git a/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch b/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch deleted file mode 100644 index d8ae27d..0000000 --- a/0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 4 Jun 2020 18:20:06 -0500 -Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var - -uevent_get_env_var() could call condlog with p == NULL. On gcc 10, -this triggers warnings like: - -In file included from uevent.c:47: -In function 'uevent_get_env_var', - inlined from 'uevent_get_wwid' at uevent.c:170:8: -debug.h:13:2: error: '%s' directive argument is null -[-Werror=format-overflow=] - 13 | dlog(logsink, prio, fmt "\n", ##args) - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -uevent.c:132:2: note: in expansion of macro 'condlog' - 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); - | ^~~~~~~ -uevent.c: In function 'uevent_get_wwid': -uevent.c:132:25: note: format string is defined here - 132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p); - | ^~ - -If p is NULL, use "(null)" instead. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/uevent.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index d38e8a7f..e0d13b11 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -129,7 +129,7 @@ static const char* uevent_get_env_var(const struct uevent *uev, - } - } - -- condlog(4, "%s: %s -> '%s'", __func__, attr, p); -+ condlog(4, "%s: %s -> '%s'", __func__, attr, p ?: "(null)"); - return p; - - invalid: --- -2.17.2 - diff --git a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch b/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch deleted file mode 100644 index 7d2b886..0000000 --- a/0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 21 Aug 2019 16:07:12 +0200 -Subject: [PATCH] libmultipath: set "enable_foreign" to NONE by default - -This has been requested by NetApp. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 4 ++-- - multipath/multipath.conf.5 | 5 +++-- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index e5ee6afe..01a501bd 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -50,8 +50,8 @@ - #define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10 - #define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1 - #define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF --/* Enable all foreign libraries by default */ --#define DEFAULT_ENABLE_FOREIGN "" -+/* Enable no foreign libraries by default */ -+#define DEFAULT_ENABLE_FOREIGN "NONE" - - #define CHECKINT_UNDEF UINT_MAX - #define DEFAULT_CHECKINT 5 -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 05a5e8ff..28cea88c 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1228,10 +1228,11 @@ Enables or disables foreign libraries (see section - .I FOREIGN MULTIPATH SUPPORT - below). The value is a regular expression; foreign libraries are loaded - if their name (e.g. \(dqnvme\(dq) matches the expression. By default, --all foreign libraries are enabled. -+no foreign libraries are enabled. Set this to \(dqnvme\(dq to enable NVMe native -+multipath support, or \(dq.*\(dq to enable all foreign libraries. - .RS - .TP --The default is: \fB\(dq\(dq\fR (the empty regular expression) -+The default is: \fB\(dqNONE\(dq\fR - .RE - . - . --- -2.17.2 - diff --git a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch b/0032-multipath-add-e-option-to-enable-foreign-libraries.patch deleted file mode 100644 index 6e07152..0000000 --- a/0032-multipath-add-e-option-to-enable-foreign-libraries.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 2 Mar 2020 22:43:27 +0100 -Subject: [PATCH] multipath: add "-e" option to enable foreign libraries - -As we have set "enable_foreign" to "NONE" now by default, users -may find it useful to be able to switch on foreign multipath display -with an extra command line option even if foreign libraries are -not enabled in multipath.conf. Currently this makes only sense -with "multipath -ll", as the nvme library (and foreign libraries -in general) support only the display of status information. - -Suggested-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 11 ++++++++++- - multipath/multipath.8 | 6 ++++++ - 2 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 953fab27..c4740fab 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -145,6 +145,7 @@ usage (char * progname) - " -h print this usage text\n" - " -l show multipath topology (sysfs and DM info)\n" - " -ll show multipath topology (maximum info)\n" -+ " -e enable foreign libraries with -l/-ll\n" - " -f flush a multipath device map\n" - " -F flush all multipath device maps\n" - " -a add a device wwid to the wwids file\n" -@@ -865,6 +866,7 @@ main (int argc, char *argv[]) - char *dev = NULL; - struct config *conf; - int retries = -1; -+ bool enable_foreign = false; - - udev = udev_new(); - logsink = 0; -@@ -874,7 +876,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, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -971,6 +973,9 @@ main (int argc, char *argv[]) - case 'R': - retries = atoi(optarg); - break; -+ case 'e': -+ enable_foreign = true; -+ break; - case ':': - fprintf(stderr, "Missing option argument\n"); - usage(argv[0]); -@@ -1022,6 +1027,10 @@ main (int argc, char *argv[]) - condlog(0, "failed to initialize prioritizers"); - goto out; - } -+ -+ if ((cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) && enable_foreign) -+ conf->enable_foreign = ""; -+ - /* Failing here is non-fatal */ - init_foreign(conf->multipath_dir, conf->enable_foreign); - if (cmd == CMD_USABLE_PATHS) { -diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 9cdd05a3..6fb8645a 100644 ---- a/multipath/multipath.8 -+++ b/multipath/multipath.8 -@@ -223,6 +223,12 @@ The verbosity level also controls the level of log and debug messages printed to - Dry run, do not create or update devmaps. - . - .TP -+.B \-e -+Enable all foreign libraries. This overrides the -+.I enable_foreign -+option from \fBmultipath.conf(5)\fR. -+. -+.TP - .B \-i - Ignore WWIDs file when processing devices. If - \fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in --- -2.17.2 - diff --git a/0033-libmultipath-remove-_blacklist_exceptions-functions.patch b/0033-libmultipath-remove-_blacklist_exceptions-functions.patch deleted file mode 100644 index 5fa6539..0000000 --- a/0033-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: Tue, 9 Jun 2020 16:35:27 -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 00e8dbdb..c21a0e27 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; -@@ -300,9 +268,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; - } - -@@ -316,9 +284,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; - } - -@@ -332,9 +300,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; - } - -@@ -351,9 +319,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; - } - -@@ -422,11 +390,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/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch b/0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch deleted file mode 100644 index 22cc22c..0000000 --- a/0034-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: Tue, 9 Jun 2020 16:35:28 -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 d478b177..11a6168c 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/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch b/0035-libmultipath-invert-regexes-that-start-with-exclamat.patch deleted file mode 100644 index ff1331d..0000000 --- a/0035-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: Tue, 9 Jun 2020 16:35:29 -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 c21a0e27..db58ccca 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 28cea88c..5adaced6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1249,6 +1249,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 -@@ -1265,10 +1275,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 6e7c1864..d5c40898 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 -@@ -484,6 +593,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 00bae58e..b7c09cc2 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/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch b/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch deleted file mode 100644 index f631fdb..0000000 --- a/0036-multipath-Fix-compiler-warnings-when-built-without-s.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Marius Bakke -Date: Wed, 17 Jun 2020 01:11:26 +0200 -Subject: [PATCH] multipath: Fix compiler warnings when built without systemd. - -Add ifdef guards for code that is unused when systemd is not available. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 6 ++++-- - multipathd/main.c | 10 +++++++++- - 2 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index b4d87689..658bec8b 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -696,9 +696,9 @@ process_config_dir(struct config *conf, char *dir) - pthread_cleanup_pop(1); - } - -+#ifdef USE_SYSTEMD - static void set_max_checkint_from_watchdog(struct config *conf) - { --#ifdef USE_SYSTEMD - char *envp = getenv("WATCHDOG_USEC"); - unsigned long checkint; - -@@ -714,8 +714,8 @@ static void set_max_checkint_from_watchdog(struct config *conf) - condlog(3, "enabling watchdog, interval %ld", checkint); - conf->use_watchdog = true; - } --#endif - } -+#endif - - struct config * - load_config (char * file) -@@ -789,7 +789,9 @@ load_config (char * file) - /* - * fill the voids left in the config file - */ -+#ifdef USE_SYSTEMD - set_max_checkint_from_watchdog(conf); -+#endif - if (conf->max_checkint == 0) { - if (conf->checkint == CHECKINT_UNDEF) - conf->checkint = DEFAULT_CHECKINT; -diff --git a/multipathd/main.c b/multipathd/main.c -index 6b7db2c0..205ddb32 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -176,6 +176,7 @@ daemon_status(void) - /* - * I love you too, systemd ... - */ -+#ifdef USE_SYSTEMD - static const char * - sd_notify_status(enum daemon_status state) - { -@@ -195,7 +196,6 @@ sd_notify_status(enum daemon_status state) - return NULL; - } - --#ifdef USE_SYSTEMD - static void do_sd_notify(enum daemon_status old_state, - enum daemon_status new_state) - { -@@ -247,7 +247,9 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate, - static void __post_config_state(enum daemon_status state) - { - if (state != running_state && running_state != DAEMON_SHUTDOWN) { -+#ifdef USE_SYSTEMD - enum daemon_status old_state = running_state; -+#endif - - running_state = state; - pthread_cond_broadcast(&config_cond); -@@ -272,7 +274,9 @@ int set_config_state(enum daemon_status state) - pthread_cleanup_push(config_cleanup, NULL); - pthread_mutex_lock(&config_lock); - if (running_state != state) { -+#ifdef USE_SYSTEMD - enum daemon_status old_state = running_state; -+#endif - - if (running_state == DAEMON_SHUTDOWN) - rc = EINVAL; -@@ -2280,7 +2284,9 @@ checkerloop (void *ap) - struct timespec last_time; - struct config *conf; - int foreign_tick = 0; -+#ifdef USE_SYSTEMD - bool use_watchdog; -+#endif - - pthread_cleanup_push(rcu_unregister, NULL); - rcu_register_thread(); -@@ -2294,7 +2300,9 @@ checkerloop (void *ap) - - /* use_watchdog is set from process environment and never changes */ - conf = get_multipath_config(); -+#ifdef USE_SYSTEMD - use_watchdog = conf->use_watchdog; -+#endif - put_multipath_config(conf); - - while (1) { --- -2.17.2 - diff --git a/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch b/0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch deleted file mode 100644 index 0888750..0000000 --- a/0037-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, 2 Jul 2020 19:38:24 -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: Benjamin Marzinski -Signed-off-by: Martin Wilck ---- - 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/0038-kpartx-read-devices-with-direct-IO.patch b/0038-kpartx-read-devices-with-direct-IO.patch deleted file mode 100644 index eaa91c3..0000000 --- a/0038-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: Thu, 2 Jul 2020 19:38:25 -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/0039-kpartx-handle-alternate-bsd-disklabel-location.patch b/0039-kpartx-handle-alternate-bsd-disklabel-location.patch deleted file mode 100644 index 4b6e7e5..0000000 --- a/0039-kpartx-handle-alternate-bsd-disklabel-location.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:26 -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. - -Reviewed-by: Martin Wilck -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/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch b/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch deleted file mode 100644 index 1054e30..0000000 --- a/0040-libmultipath-fix-checker-detection-for-nvme-devices.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:38:27 -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" -Reviewed-by: Martin Wilck -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/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch b/0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch deleted file mode 100644 index 91c9a8b..0000000 --- a/0041-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: Thu, 2 Jul 2020 19:07:00 -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 27d52398..24cc616a 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -534,36 +534,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; -@@ -637,35 +644,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); -@@ -920,7 +937,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; -@@ -1129,7 +1146,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); -@@ -1313,7 +1330,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 5ed7edc5..b2108638 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); - int dm_prereq(unsigned int *v); - void skip_libmp_dm_init(void); -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 205ddb32..ab141fed 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -418,7 +418,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; - } -@@ -557,9 +557,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)) -@@ -1350,8 +1350,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--; - } -@@ -2091,7 +2091,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/0042-multipathd-fix-check_path-errors-with-removed-map.patch b/0042-multipathd-fix-check_path-errors-with-removed-map.patch deleted file mode 100644 index 155e93a..0000000 --- a/0042-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, 2 Jul 2020 19:07:01 -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 ab141fed..daf19a4e 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1615,22 +1615,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 -@@ -2091,9 +2087,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 */ -@@ -2183,12 +2186,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) -@@ -2204,15 +2203,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/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch b/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch deleted file mode 100644 index 4dce980..0000000 --- a/0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:02 -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. - -Reviewed-by: Martin Wilck -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 24cc616a..4c86b6d4 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1007,13 +1007,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); - -@@ -1026,6 +1026,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/0044-multipathd-add-del-maps-multipathd-command.patch b/0044-multipathd-add-del-maps-multipathd-command.patch deleted file mode 100644 index 9f32eb2..0000000 --- a/0044-multipathd-add-del-maps-multipathd-command.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:03 -0500 -Subject: [PATCH] multipathd: add "del maps" multipathd command - -This will flush all multipath devices. - -Reviewed-by: Martin Wilck -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 4c86b6d4..f597ff8b 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1005,7 +1005,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; -@@ -1028,7 +1028,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 b2108638..6dd178c8 100644 ---- a/libmultipath/devmapper.h -+++ b/libmultipath/devmapper.h -@@ -57,7 +57,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 c4740fab..d89f0a91 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -1096,7 +1096,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 daf19a4e..f014d2a1 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -635,7 +635,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; -@@ -1555,6 +1555,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/0045-multipath-make-flushing-maps-work-like-other-command.patch b/0045-multipath-make-flushing-maps-work-like-other-command.patch deleted file mode 100644 index b7450ee..0000000 --- a/0045-multipath-make-flushing-maps-work-like-other-command.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:04 -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. - -Reviewed-by: Martin Wilck -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 ceecff2d..55569360 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -38,6 +38,8 @@ enum mpath_cmds { - CMD_ADD_WWID, - CMD_USABLE_PATHS, - CMD_DUMP_CONFIG, -+ CMD_FLUSH_ONE, -+ CMD_FLUSH_ALL, - }; - - enum force_reload_types { -@@ -142,7 +144,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 d89f0a91..101fd656 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -909,10 +909,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)) -@@ -1053,6 +1053,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: -@@ -1086,16 +1090,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/0046-multipath-delegate-flushing-maps-to-multipathd.patch b/0046-multipath-delegate-flushing-maps-to-multipathd.patch deleted file mode 100644 index 1a4a771..0000000 --- a/0046-multipath-delegate-flushing-maps-to-multipathd.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:05 -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. - -Reviewed-by: Martin Wilck -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 101fd656..6a24e483 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -820,6 +820,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 6fb8645a..5b29a5d9 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/0047-multipath-add-option-to-skip-multipathd-delegation.patch b/0047-multipath-add-option-to-skip-multipathd-delegation.patch deleted file mode 100644 index 51284aa..0000000 --- a/0047-multipath-add-option-to-skip-multipathd-delegation.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 2 Jul 2020 19:07:06 -0500 -Subject: [PATCH] multipath: add option to skip multipathd delegation - -Add the -D option to allow users to skip delegating commands to -multipathd. - -Reviewed-by: Martin Wilck -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 55569360..92c61a0d 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -190,6 +190,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 6a24e483..4c43314e 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -817,6 +817,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"); - } -@@ -890,7 +893,7 @@ main (int argc, char *argv[]) - multipath_conf = conf; - conf->retrigger_tries = 0; - conf->force_sync = 1; -- while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -+ while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { - switch(arg) { - case 1: printf("optarg : %s\n",optarg); - break; -@@ -922,6 +925,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/0048-libmultipath-add-device-to-hwtable.c.patch b/0048-libmultipath-add-device-to-hwtable.c.patch deleted file mode 100644 index 9d5e780..0000000 --- a/0048-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/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch b/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch deleted file mode 100644 index bfb9f8f..0000000 --- a/0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: lixiaokeng -Date: Mon, 13 Jul 2020 13:07:40 +0200 -Subject: [PATCH] master - libmultipath: fix use after free when iscsi logs in - -When two iscsi ips log in and out alternately and the following scripts run -at the same time, - -#!/bin/bash -interval=5 -while true -do - iscsiadm -m node -p 9.41.147.171 &> /dev/null - iscsiadm -m node -p 9.41.148.172 &> /dev/null - iscsiadm -m session &> /dev/null - rescan-scsi-bus.sh &> /dev/null - multipath -v2 &> /dev/null - multipath -ll &> /dev/null - sleep $interval -done - -multipathd will have a segfault after about 30 mins. - -The reason is that mpp->hwe is accessed after hwe is already freed. In -extract_hwe_from_path func, mpp->hwe is set to pp->hwe, so they points to the -same hwe. For some reasons, pp->mpp will be set to NULL in orphan_path func. -Then, pp and hwe will be freed with (pp->mpp == NULL) in free_path func -called by ev_remove_path func. However, mpp->hwe is not set to NULL while hwe -is already freed. So, when iscsi device logs in and new path is added to mpp, -mpp->hwe will be accessed in select_pgfailback func. Finally, use-after-free -problem occurs. - -The procedure details given as follows, -1.wait_dmevents thread -wait_dmevents - ->dmevent_loop - ->update_multipath - ->__setup_multipath - ->update_multipath_strings - -> sync_paths - ->orphan_path -2.uevqloop thread (iscsi log out, remove path) -uevqloop -->uevent_dispatch - ->service_uevq - ->uev_remove_path - ->ev_remove_path //pp->mpp is NULL - ->free_path(pp) - //pp->hew are freed but mpp->hwe is not set to NULL -3.ev_remove_path (iscsi log in, add path) -uevqloop -->uevent_dispatch - ->service_uevq - ->ev_add_path - ->select_pgfailback //mpp->hwe is accessed - -Here, we will set mpp->hwe to NULL before setting pp->map to NULL in orphan_path -func. - -Signed-off-by: Tianxiong Lu -Signed-off-by: lixiaokeng -Signed-off-by: Zhiqiang Liu -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 8137ea21..430eaad7 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -93,6 +93,8 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); -+ if (pp->mpp && pp->mpp->hwe == pp->hwe) -+ pp->mpp->hwe = NULL; - pp->mpp = NULL; - pp->dmstate = PSTATE_UNDEF; - pp->uid_attribute = NULL; --- -2.17.2 - diff --git a/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch b/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch deleted file mode 100644 index 3c286fa..0000000 --- a/0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:41 +0200 -Subject: [PATCH] libmultipath: warn if freeing path that holds mpp->hwe - -This just adds an error message to the previous patch. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index 430eaad7..cde4dbe6 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -93,8 +93,11 @@ int adopt_paths(vector pathvec, struct multipath *mpp) - void orphan_path(struct path *pp, const char *reason) - { - condlog(3, "%s: orphan path, %s", pp->dev, reason); -- if (pp->mpp && pp->mpp->hwe == pp->hwe) -+ if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) { -+ condlog(0, "BUG: orphaning path %s that holds hwe of %s", -+ pp->dev, pp->mpp->alias); - pp->mpp->hwe = NULL; -+ } - pp->mpp = NULL; - pp->dmstate = PSTATE_UNDEF; - pp->uid_attribute = NULL; --- -2.17.2 - diff --git a/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch b/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch deleted file mode 100644 index a50b9b2..0000000 --- a/0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:42 +0200 -Subject: [PATCH] libmultipath: warn about NULL value of mpp->hwe - -mpp->hwe is only accessed in propsel.c. It may become unset if -all paths of the mpp have been deleted. Access to mpp->hwe in this -case should be avoided. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/propsel.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index d362beb4..68228272 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -65,7 +65,9 @@ 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) { \ -+ condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \ -+ } else if (__do_set_from_hwe(var, src, dest)) { \ - origin = msg; \ - goto out; \ - } --- -2.17.2 - diff --git a/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch b/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch deleted file mode 100644 index b9caf46..0000000 --- a/0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 13 Jul 2020 13:07:43 +0200 -Subject: [PATCH] libmultipath: fix mpp->hwe handling in sync_paths() - -This is anologous to - -1f96269 ("multipathd: fix mpp->hwe handling on path removal") -f6839eb ("multipathd: fix mpp->hwe handling when paths are freed") - -When paths are removed from a map, we need to make sure that -mpp->hwe doesn't become stale. - -Reported-by: Lixiaokeng -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index cde4dbe6..ede14297 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -260,6 +260,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) - } - if (!found) { - condlog(3, "%s dropped path %s", mpp->alias, pp->dev); -+ if (mpp->hwe == pp->hwe) -+ mpp->hwe = NULL; - vector_del_slot(mpp->paths, i--); - orphan_path(pp, "path removed externally"); - } -@@ -267,6 +269,8 @@ void sync_paths(struct multipath *mpp, vector pathvec) - update_mpp_paths(mpp, pathvec); - vector_foreach_slot (mpp->paths, pp, i) - pp->mpp = mpp; -+ if (mpp->hwe == NULL) -+ extract_hwe_from_path(mpp); - } - - int --- -2.17.2 - diff --git a/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch b/0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch deleted file mode 100644 index 5c3f614..0000000 --- a/0053-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 e7256e3a..8ea3352d 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/0054-kpartx-fix-Wsign-compare-error.patch b/0054-kpartx-fix-Wsign-compare-error.patch deleted file mode 100644 index ffaa477..0000000 --- a/0054-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/0055-libmultipath-remove-code-duplication-in-path-countin.patch b/0055-libmultipath-remove-code-duplication-in-path-countin.patch deleted file mode 100644 index 699049a..0000000 --- a/0055-libmultipath-remove-code-duplication-in-path-countin.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:12:05 -0500 -Subject: [PATCH] libmultipath: remove code duplication in path counting - -pathcountgr() is never used except by pathcount(), and neither is the -special case for PATH_WILD. Simplify this and make one function that is -used by both pathcount() and count_active_paths(). This will be used -again in a future patch. - -Also use count_active_paths() in mpath_persist. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 4 +-- - libmultipath/structs.c | 47 +++++++++++++-------------------- - libmultipath/structs.h | 1 - - 3 files changed, 21 insertions(+), 31 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 3da7a6cf..a132f4e9 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -436,7 +436,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - - all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON || - paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK); -- active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST); -+ active_pathcount = count_active_paths(mpp); - - if (active_pathcount == 0) { - condlog (0, "%s: no path available", mpp->wwid); -@@ -648,7 +648,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope, - if (!mpp) - return MPATH_PR_DMMP_ERROR; - -- active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST); -+ active_pathcount = count_active_paths(mpp); - - struct threadinfo thread[active_pathcount]; - memset(thread, 0, sizeof(thread)); -diff --git a/libmultipath/structs.c b/libmultipath/structs.c -index 2dd378c4..3eac3d61 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -455,49 +455,40 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t) - return NULL; - } - --int pathcountgr(const struct pathgroup *pgp, int state) -+static int do_pathcount(const struct multipath *mpp, const int *states, -+ unsigned int nr_states) - { -+ struct pathgroup *pgp; - struct path *pp; - int count = 0; -- int i; -+ unsigned int i, j, k; - -- vector_foreach_slot (pgp->paths, pp, i) -- if ((pp->state == state) || (state == PATH_WILD)) -- count++; -+ if (!mpp->pg || !nr_states) -+ return count; - -+ vector_foreach_slot (mpp->pg, pgp, i) { -+ vector_foreach_slot (pgp->paths, pp, j) { -+ for (k = 0; k < nr_states; k++) { -+ if (pp->state == states[k]) { -+ count++; -+ break; -+ } -+ } -+ } -+ } - return count; - } - - int pathcount(const struct multipath *mpp, int state) - { -- struct pathgroup *pgp; -- int count = 0; -- int i; -- -- if (mpp->pg) { -- vector_foreach_slot (mpp->pg, pgp, i) -- count += pathcountgr(pgp, state); -- } -- return count; -+ return do_pathcount(mpp, &state, 1); - } - - int count_active_paths(const struct multipath *mpp) - { -- struct pathgroup *pgp; -- struct path *pp; -- int count = 0; -- int i, j; -- -- if (!mpp->pg) -- return 0; -+ int states[] = {PATH_UP, PATH_GHOST}; - -- vector_foreach_slot (mpp->pg, pgp, i) { -- vector_foreach_slot (pgp->paths, pp, j) { -- if (pp->state == PATH_UP || pp->state == PATH_GHOST) -- count++; -- } -- } -- return count; -+ return do_pathcount(mpp, states, 2); - } - - int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index d69bc2e9..0c03e711 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -446,7 +446,6 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt - struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev); - 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 pathcmp (const struct pathgroup *, const struct pathgroup *); --- -2.17.2 - diff --git a/0056-libmultipath-count-pending-paths-as-active-on-loads.patch b/0056-libmultipath-count-pending-paths-as-active-on-loads.patch deleted file mode 100644 index 5320297..0000000 --- a/0056-libmultipath-count-pending-paths-as-active-on-loads.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:19:30 -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 | 7 +++++++ - libmultipath/structs.h | 1 + - 3 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f597ff8b..126cd728 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -417,7 +417,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 3eac3d61..0d1f969d 100644 ---- a/libmultipath/structs.c -+++ b/libmultipath/structs.c -@@ -491,6 +491,13 @@ int count_active_paths(const struct multipath *mpp) - return do_pathcount(mpp, states, 2); - } - -+int count_active_pending_paths(const struct multipath *mpp) -+{ -+ int states[] = {PATH_UP, PATH_GHOST, PATH_PENDING}; -+ -+ return do_pathcount(mpp, states, 3); -+} -+ - int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp) - { - int i, j; -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index 0c03e711..917e4083 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -448,6 +448,7 @@ struct path * first_path (const struct multipath *mpp); - - 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/0057-libmultipath-deal-with-flushing-no-maps.patch b/0057-libmultipath-deal-with-flushing-no-maps.patch deleted file mode 100644 index 0aee761..0000000 --- a/0057-libmultipath-deal-with-flushing-no-maps.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:28:22 -0500 -Subject: [PATCH] libmultipath: deal with flushing no 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. - -Fixes: "libmultipath: make dm_flush_maps only return 0 on success" -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 126cd728..b8199cb5 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -1024,10 +1024,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); --- -2.17.2 - diff --git a/0058-multipath-deal-with-delegation-failures-correctly.patch b/0058-multipath-deal-with-delegation-failures-correctly.patch deleted file mode 100644 index e8d0050..0000000 --- a/0058-multipath-deal-with-delegation-failures-correctly.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 21 Jul 2020 01:37:18 -0500 -Subject: [PATCH] multipath: deal with delegation failures correctly - -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. - -Fixes: "multipath: delegate flushing maps to multipathd" -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 4c43314e..3da692dc 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -861,9 +861,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/0059-RH-fixup-udev-rules-for-redhat.patch b/0059-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index b1f5beb..0000000 --- a/0059-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 8ea3352d..873fb62f 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 d7527d7d..0e0d70d5 100644 ---- a/kpartx/kpartx.rules -+++ b/kpartx/kpartx.rules -@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end" - GOTO="kpartx_end" - - LABEL="run_kpartx" --RUN+="/sbin/kpartx -un -p -part /dev/$name" -+RUN+="/sbin/kpartx -un /dev/$name" - - LABEL="kpartx_end" -diff --git a/multipath/Makefile b/multipath/Makefile -index 0828a8f7..b9bbb3cf 100644 ---- a/multipath/Makefile -+++ b/multipath/Makefile -@@ -24,7 +24,7 @@ install: - $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) - $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) -- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) - $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) -@@ -33,7 +33,7 @@ install: - uninstall: - $(RM) $(DESTDIR)$(bindir)/$(EXEC) - $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules -- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules -+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules - $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz - $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz - --- -2.17.2 - diff --git a/0061-RH-don-t-start-without-a-config-file.patch b/0061-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index 4712300..0000000 --- a/0061-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 658bec8b..1c02e230 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 92c61a0d..160867cd 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/0062-RH-use-rpm-optflags-if-present.patch b/0062-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index d6c97c1..0000000 --- a/0062-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 19 Apr 2017 06:10:01 -0500 -Subject: [PATCH] RH: use rpm optflags if present - -Use the passed in optflags when compiling as an RPM, and keep the -default flags as close as possible to the current fedora flags, while -still being generic. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 873fb62f..479523bc 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -89,15 +89,27 @@ TEST_CC_OPTION = $(shell \ - echo "$(2)"; \ - fi) - --STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) - ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) - WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) - --OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 --WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \ -+ifndef RPM_OPT_FLAGS -+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) -+ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ -+ $(STACKPROT) -grecord-gcc-switches \ -+ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -+ endif -+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) -+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -+ endif -+else -+ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 -+endif -+WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ -- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) --CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 -+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -+ -Wstrict-prototypes - CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP -@@ -135,4 +147,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/0065-RH-warn-on-invalid-regex-instead-of-failing.patch b/0065-RH-warn-on-invalid-regex-instead-of-failing.patch deleted file mode 100644 index 4bdd97e..0000000 --- a/0065-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 11a6168c..a7285a35 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -384,6 +384,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/0069-RH-work-around-gcc-10-format-truncation-issue.patch b/0069-RH-work-around-gcc-10-format-truncation-issue.patch deleted file mode 100644 index c501ce9..0000000 --- a/0069-RH-work-around-gcc-10-format-truncation-issue.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 29 May 2020 17:21:21 -0500 -Subject: [PATCH] RH: work around gcc 10 format-truncation issue - -gcc 10 was returning false positives on some architectures, when trying -to determine if a snprintf() function could silently truncate its -output. Instead of changing the code to pretend that this is possible, -make these warnings, instead of errors. - -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 479523bc..e2f5d0dc 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -109,7 +109,7 @@ endif - WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ -- -Wstrict-prototypes -+ -Wstrict-prototypes -Wno-error=format-truncation - CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ - -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ - -MMD -MP --- -2.17.2 - diff --git a/0070-multipath-add-libmpathvalid-library.patch b/0070-multipath-add-libmpathvalid-library.patch deleted file mode 100644 index b3863cd..0000000 --- a/0070-multipath-add-libmpathvalid-library.patch +++ /dev/null @@ -1,369 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 13 May 2020 17:04:24 -0500 -Subject: [PATCH] multipath: add libmpathvalid library - -This library allows other programs to check if a path should be claimed -by multipath. It exports an init and exit function, that need to be -called before any other functions can be called, a pointer to a struct -config, that stores the configuration which is dealt with in the -init and exit functions, and two more functions. - -mpath_get_mode() get the configured find_multipaths mode. -mpath_is_path() returns whether the device is claimed by multipath, and -optionally returns the wwid. This code works slightly different than -the multipath -c/u code for SMART mode. Instead of checking all the -existing paths to see if another has the same wwid, it expects the -caller to pass in an array of the already known path wwids, and checks -if the current path matches any of those. - -The library also doesn't set up the device-mapper log fuctions. It -leaves this up to the caller. - -Signed-off-by: Benjamin Marzinski ---- - Makefile | 3 +- - Makefile.inc | 1 + - libmpathvalid/Makefile | 38 +++++++ - libmpathvalid/libmpathvalid.version | 10 ++ - libmpathvalid/mpath_valid.c | 168 ++++++++++++++++++++++++++++ - libmpathvalid/mpath_valid.h | 57 ++++++++++ - 6 files changed, 276 insertions(+), 1 deletion(-) - create mode 100644 libmpathvalid/Makefile - create mode 100644 libmpathvalid/libmpathvalid.version - create mode 100644 libmpathvalid/mpath_valid.c - create mode 100644 libmpathvalid/mpath_valid.h - -diff --git a/Makefile b/Makefile -index 8bcaba66..f157a549 100644 ---- a/Makefile -+++ b/Makefile -@@ -9,6 +9,7 @@ BUILDDIRS := \ - libmultipath/checkers \ - libmultipath/foreign \ - libmpathpersist \ -+ libmpathvalid \ - multipath \ - multipathd \ - mpathpersist \ -@@ -29,7 +30,7 @@ $(BUILDDIRS): - $(MAKE) -C $@ - - libmultipath libdmmp: libmpathcmd --libmpathpersist multipath multipathd: libmultipath -+libmpathpersist libmpathvalid multipath multipathd: libmultipath - mpathpersist multipathd: libmpathpersist - - libmultipath/checkers.install \ -diff --git a/Makefile.inc b/Makefile.inc -index e2f5d0dc..936e5833 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -66,6 +66,7 @@ libdir = $(prefix)/$(LIB)/multipath - unitdir = $(prefix)/$(SYSTEMDPATH)/systemd/system - mpathpersistdir = $(TOPDIR)/libmpathpersist - mpathcmddir = $(TOPDIR)/libmpathcmd -+mpathvaliddir = $(TOPDIR)/libmpathvalid - thirdpartydir = $(TOPDIR)/third-party - libdmmpdir = $(TOPDIR)/libdmmp - nvmedir = $(TOPDIR)/libmultipath/nvme -diff --git a/libmpathvalid/Makefile b/libmpathvalid/Makefile -new file mode 100644 -index 00000000..70b97eca ---- /dev/null -+++ b/libmpathvalid/Makefile -@@ -0,0 +1,38 @@ -+include ../Makefile.inc -+ -+SONAME = 0 -+DEVLIB = libmpathvalid.so -+LIBS = $(DEVLIB).$(SONAME) -+ -+CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) -+ -+LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) \ -+ -lmultipath -L$(mpathcmddir) -lmpathcmd -ludev -+ -+OBJS = mpath_valid.o -+ -+all: $(LIBS) -+ -+$(LIBS): $(OBJS) -+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS) -Wl,--version-script=libmpathvalid.version -+ $(LN) $(LIBS) $(DEVLIB) -+ -+install: $(LIBS) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir) -+ $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(includedir) -+ $(INSTALL_PROGRAM) -m 644 mpath_valid.h $(DESTDIR)$(includedir) -+ -+uninstall: -+ $(RM) $(DESTDIR)$(syslibdir)/$(LIBS) -+ $(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB) -+ $(RM) $(DESTDIR)$(includedir)/mpath_valid.h -+ -+clean: dep_clean -+ $(RM) core *.a *.o *.so *.so.* *.gz -+ -+include $(wildcard $(OBJS:.o=.d)) -+ -+dep_clean: -+ $(RM) $(OBJS:.o=.d) -diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version -new file mode 100644 -index 00000000..4d8a8ba4 ---- /dev/null -+++ b/libmpathvalid/libmpathvalid.version -@@ -0,0 +1,10 @@ -+MPATH_1.0 { -+ global: -+ mpathvalid_conf; -+ mpathvalid_init; -+ mpathvalid_exit; -+ mpathvalid_is_path; -+ mpathvalid_get_mode; -+ local: -+ *; -+}; -diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c -new file mode 100644 -index 00000000..6153e8b7 ---- /dev/null -+++ b/libmpathvalid/mpath_valid.c -@@ -0,0 +1,168 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "devmapper.h" -+#include "structs.h" -+#include "util.h" -+#include "config.h" -+#include "discovery.h" -+#include "wwids.h" -+#include "sysfs.h" -+#include "mpath_cmd.h" -+#include "valid.h" -+#include "mpath_valid.h" -+ -+static struct config default_config = { .verbosity = -1 }; -+struct config *mpathvalid_conf = &default_config; -+ -+static unsigned int get_conf_mode(struct config *conf) -+{ -+ if (conf->find_multipaths == FIND_MULTIPATHS_SMART) -+ return MPATH_SMART; -+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY) -+ return MPATH_GREEDY; -+ return MPATH_STRICT; -+} -+ -+static void set_conf_mode(struct config *conf, unsigned int mode) -+{ -+ if (mode == MPATH_SMART) -+ conf->find_multipaths = FIND_MULTIPATHS_SMART; -+ else if (mode == MPATH_GREEDY) -+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY; -+ else -+ conf->find_multipaths = FIND_MULTIPATHS_STRICT; -+} -+ -+unsigned int mpathvalid_get_mode(void) -+{ -+ int mode; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ if (!conf) -+ return -1; -+ mode = get_conf_mode(conf); -+ put_multipath_config(conf); -+ return mode; -+} -+ -+static int convert_result(int result) { -+ switch (result) { -+ case PATH_IS_ERROR: -+ return MPATH_IS_ERROR; -+ case PATH_IS_NOT_VALID: -+ return MPATH_IS_NOT_VALID; -+ case PATH_IS_VALID: -+ return MPATH_IS_VALID; -+ case PATH_IS_VALID_NO_CHECK: -+ return MPATH_IS_VALID_NO_CHECK; -+ case PATH_IS_MAYBE_VALID: -+ return MPATH_IS_MAYBE_VALID; -+ } -+ return MPATH_IS_ERROR; -+} -+ -+int -+mpathvalid_init(int verbosity) -+{ -+ unsigned int version[3]; -+ struct config *conf; -+ -+ default_config.verbosity = verbosity; -+ skip_libmp_dm_init(); -+ conf = load_config(DEFAULT_CONFIGFILE); -+ if (!conf) -+ return -1; -+ conf->verbosity = verbosity; -+ if (dm_prereq(version)) -+ goto fail; -+ memcpy(conf->version, version, sizeof(version)); -+ -+ mpathvalid_conf = conf; -+ return 0; -+fail: -+ free_config(conf); -+ return -1; -+} -+ -+int -+mpathvalid_exit(void) -+{ -+ struct config *conf = mpathvalid_conf; -+ -+ default_config.verbosity = -1; -+ if (mpathvalid_conf == &default_config) -+ return 0; -+ mpathvalid_conf = &default_config; -+ free_config(conf); -+ return 0; -+} -+ -+/* -+ * name: name of path to check -+ * mode: mode to use for determination. MPATH_DEFAULT uses configured mode -+ * info: on success, contains the path wwid -+ * paths: array of the returned mpath_info from other claimed paths -+ * nr_paths: the size of the paths array -+ */ -+int -+mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, -+ const char **path_wwids, unsigned int nr_paths) -+{ -+ struct config *conf; -+ int r = MPATH_IS_ERROR; -+ unsigned int i; -+ struct path *pp; -+ -+ if (!name || mode >= MPATH_MAX_MODE) -+ return r; -+ -+ if (nr_paths > 0 && !path_wwids) -+ return r; -+ -+ pp = alloc_path(); -+ if (!pp) -+ return r; -+ -+ if (wwid) { -+ *wwid = (char *)malloc(WWID_SIZE); -+ if (!*wwid) -+ goto out; -+ } -+ -+ conf = get_multipath_config(); -+ if (!conf || conf == &default_config) -+ goto out_wwid; -+ if (mode != MPATH_DEFAULT) -+ set_conf_mode(conf, mode); -+ r = convert_result(is_path_valid(name, conf, pp, true)); -+ put_multipath_config(conf); -+ -+ if (r == MPATH_IS_MAYBE_VALID) { -+ for (i = 0; i < nr_paths; i++) { -+ if (strncmp(path_wwids[i], pp->wwid, WWID_SIZE) == 0) { -+ r = MPATH_IS_VALID; -+ break; -+ } -+ } -+ } -+ -+out_wwid: -+ if (wwid) { -+ if (r == MPATH_IS_VALID || r == MPATH_IS_VALID_NO_CHECK || -+ r == MPATH_IS_MAYBE_VALID) -+ strlcpy(*wwid, pp->wwid, WWID_SIZE); -+ else { -+ free(*wwid); -+ *wwid = NULL; -+ } -+ } -+out: -+ free_path(pp); -+ return r; -+} -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -new file mode 100644 -index 00000000..7fd8aa47 ---- /dev/null -+++ b/libmpathvalid/mpath_valid.h -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (C) 2015 Red Hat, Inc. -+ * -+ * This file is part of the device-mapper multipath userspace tools. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef LIB_MPATH_VALID_H -+#define LIB_MPATH_VALID_H -+ -+#ifdef __cpluscplus -+extern "C" { -+#endif -+ -+enum mpath_valid_mode { -+ MPATH_DEFAULT, -+ MPATH_STRICT, -+ MPATH_SMART, -+ MPATH_GREEDY, -+ MPATH_MAX_MODE, /* used only for bounds checking */ -+}; -+ -+/* MPATH_IS_VALID_NO_CHECK is used to skip checks to see if the device -+ * has already been unclaimed by multipath in the past */ -+enum mpath_valid_result { -+ MPATH_IS_ERROR = -1, -+ MPATH_IS_NOT_VALID, -+ MPATH_IS_VALID, -+ MPATH_IS_VALID_NO_CHECK, -+ MPATH_IS_MAYBE_VALID, -+}; -+ -+struct config; -+extern struct config *mpathvalid_conf; -+int mpathvalid_init(int verbosity); -+int mpathvalid_exit(void); -+unsigned int mpathvalid_get_mode(void); -+int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, -+ const char **path_wwids, unsigned int nr_paths); -+ -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /* LIB_PATH_VALID_H */ --- -2.17.2 - diff --git a/0071-libmultipath-add-uid-failback-for-dasd-devices.patch b/0071-libmultipath-add-uid-failback-for-dasd-devices.patch deleted file mode 100644 index 2515095..0000000 --- a/0071-libmultipath-add-uid-failback-for-dasd-devices.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 19 May 2020 15:55:15 -0500 -Subject: [PATCH] libmultipath: add uid failback for dasd devices - -Add failback code to get the uid for dasd devices from sysfs. Copied -from dasdinfo - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/defaults.h | 1 + - libmultipath/discovery.c | 37 ++++++++++++++++++++++++++++++++++++- - 2 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 984d8dd8..6a678a83 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -8,6 +8,7 @@ - */ - #define DEFAULT_UID_ATTRIBUTE "ID_SERIAL" - #define DEFAULT_NVME_UID_ATTRIBUTE "ID_WWN" -+#define DEFAULT_DASD_UID_ATTRIBUTE "ID_UID" - #define DEFAULT_UDEVDIR "/dev" - #define DEFAULT_MULTIPATHDIR "/" LIB_STRING "/multipath" - #define DEFAULT_SELECTOR "service-time 0" -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index aa5942c3..002d3d18 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1920,12 +1920,44 @@ get_vpd_uid(struct path * pp) - return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); - } - -+/* based on code from s390-tools/dasdinfo/dasdinfo.c */ -+static ssize_t dasd_get_uid(struct path *pp) -+{ -+ struct udev_device *parent; -+ char value[80]; -+ char *p; -+ int i; -+ -+ parent = udev_device_get_parent_with_subsystem_devtype(pp->udev, "ccw", -+ NULL); -+ if (!parent) -+ return -1; -+ -+ if (sysfs_attr_get_value(parent, "uid", value, 80) < 0) -+ return -1; -+ -+ p = value - 1; -+ /* look for the 4th '.' and cut there */ -+ for (i = 0; i < 4; i++) { -+ p = index(p + 1, '.'); -+ if (!p) -+ break; -+ } -+ if (p) -+ *p = '\0'; -+ -+ return strlcpy(pp->wwid, value, WWID_SIZE); -+} -+ - static ssize_t uid_fallback(struct path *pp, int path_state, - const char **origin) - { - ssize_t len = -1; - -- if (pp->bus == SYSFS_BUS_SCSI) { -+ if (pp->bus == SYSFS_BUS_CCW) { -+ len = dasd_get_uid(pp); -+ *origin = "sysfs"; -+ } else if (pp->bus == SYSFS_BUS_SCSI) { - len = get_vpd_uid(pp); - *origin = "sysfs"; - if (len < 0 && path_state == PATH_UP) { -@@ -1970,6 +2002,9 @@ static bool has_uid_fallback(struct path *pp) - !strcmp(pp->uid_attribute, ""))) || - (pp->bus == SYSFS_BUS_NVME && - (!strcmp(pp->uid_attribute, DEFAULT_NVME_UID_ATTRIBUTE) || -+ !strcmp(pp->uid_attribute, ""))) || -+ (pp->bus == SYSFS_BUS_CCW && -+ (!strcmp(pp->uid_attribute, DEFAULT_DASD_UID_ATTRIBUTE) || - !strcmp(pp->uid_attribute, "")))); - } - --- -2.17.2 - diff --git a/0072-libmultipath-add-ignore_udev_uid-option.patch b/0072-libmultipath-add-ignore_udev_uid-option.patch deleted file mode 100644 index d9cf8a7..0000000 --- a/0072-libmultipath-add-ignore_udev_uid-option.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 20 May 2020 16:46:55 -0500 -Subject: [PATCH] libmultipath: add ignore_udev_uid option - -Setting this option to yes will force multipath to get the uid by using -the fallback sysfs methods, instead of getting it from udev. This will -cause devices that can't get their uid from the standard locations to -not get a uid. It will also disable uevent merging. - -It will not stop uevents from being resent for device that failed to -get a WWID, although I'm on the fence about the benefit of this. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 + - libmultipath/dict.c | 4 ++++ - libmultipath/discovery.c | 17 +++++++++++------ - libmultipath/discovery.h | 8 +++++++- - libmultipath/uevent.c | 2 +- - multipath/multipath.conf.5 | 13 +++++++++++++ - multipathd/main.c | 7 ++++++- - 7 files changed, 43 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 160867cd..c7a73fba 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -192,6 +192,7 @@ struct config { - int find_multipaths_timeout; - int marginal_pathgroups; - int skip_delegate; -+ int ignore_udev_uid; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 184d4b22..9a0729bf 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1406,6 +1406,9 @@ 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(ignore_udev_uid, set_yes_no) -+declare_def_snprint(ignore_udev_uid, print_yes_no) -+ - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) - { -@@ -1816,6 +1819,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("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); - __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); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 002d3d18..f0e92227 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) - - int - get_uid (struct path * pp, int path_state, struct udev_device *udev, -- int allow_fallback) -+ int fallback) - { - char *c; - const char *origin = "unknown"; -@@ -2043,7 +2043,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else { -+ } else if (fallback == UID_FALLBACK_FORCE) -+ len = uid_fallback(pp, path_state, &origin); -+ else { - bool udev_available = udev && pp->uid_attribute - && *pp->uid_attribute; - -@@ -2056,8 +2058,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - else - origin = "udev"; - } -- if ((!udev_available || (len <= 0 && allow_fallback)) -- && has_uid_fallback(pp)) { -+ if ((!udev_available || -+ (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && -+ has_uid_fallback(pp)) { - used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } -@@ -2197,8 +2200,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - - if ((mask & DI_WWID) && !strlen(pp->wwid)) { -- get_uid(pp, path_state, pp->udev, -- (pp->retriggers >= conf->retrigger_tries)); -+ int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : -+ (pp->retriggers >= conf->retrigger_tries)? -+ UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; -+ get_uid(pp, path_state, pp->udev, fallback); - if (!strlen(pp->wwid)) { - if (pp->bus == SYSFS_BUS_UNDEF) - return PATHINFO_SKIPPED; -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 6444887d..ca8542d6 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,8 +54,14 @@ 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); -+ -+enum { -+ UID_FALLBACK_NONE, -+ UID_FALLBACK_ALLOW, -+ UID_FALLBACK_FORCE, -+}; - int get_uid(struct path * pp, int path_state, struct udev_device *udev, -- int allow_fallback); -+ int fallback); - - /* - * discovery bitmask -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index e0d13b11..d67129d1 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -179,7 +179,7 @@ uevent_need_merge(void) - bool need_merge = false; - - conf = get_multipath_config(); -- if (VECTOR_SIZE(&conf->uid_attrs) > 0) -+ if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) - need_merge = true; - put_multipath_config(conf); - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 42a192f6..175ca095 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -286,6 +286,19 @@ The default is: \fB\fR - . - . - .TP -+.B ignore_udev_uid -+Setting this option to yes will force multipath to ignore the the uid_attrs -+and uid_attribute settings, and generate the WWID by the \fIsysfs\fR -+method. This will cause devices that cannot get their WWID from the standard -+locations for their device type to not get a WWID; see \fBWWID generation\fR -+below. -+.RS -+.TP -+The default is: \fBno\fR -+.RE -+. -+. -+.TP - .B prio - The name of the path priority routine. The specified routine - should return a numeric value specifying the relative priority -diff --git a/multipathd/main.c b/multipathd/main.c -index f014d2a1..48b62937 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1226,6 +1226,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - if (pp) { - struct multipath *mpp = pp->mpp; - char wwid[WWID_SIZE]; -+ int fallback; - - if (pp->initialized == INIT_REQUESTED_UDEV) { - needs_reinit = 1; -@@ -1237,7 +1238,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- rc = get_uid(pp, pp->state, uev->udev, 0); -+ conf = get_multipath_config(); -+ fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: -+ UID_FALLBACK_NONE; -+ put_multipath_config(conf); -+ rc = get_uid(pp, pp->state, uev->udev, fallback); - - if (rc != 0) - strcpy(pp->wwid, wwid); --- -2.17.2 - diff --git a/0073-libmultipath-util-constify-function-arguments.patch b/0073-libmultipath-util-constify-function-arguments.patch deleted file mode 100644 index d1a0763..0000000 --- a/0073-libmultipath-util-constify-function-arguments.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 8 Jul 2020 09:23:20 +0200 -Subject: [PATCH] libmultipath: util: constify function arguments - -Use "const" for function arguments where possible. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/dmparser.c | 2 +- - libmultipath/util.c | 12 ++++++------ - libmultipath/util.h | 10 +++++----- - 3 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c -index b856a07f..27581cde 100644 ---- a/libmultipath/dmparser.c -+++ b/libmultipath/dmparser.c -@@ -18,7 +18,7 @@ - #define WORD_SIZE 64 - - static int --merge_words(char **dst, char *word) -+merge_words(char **dst, const char *word) - { - char * p = *dst; - int len, dstlen; -diff --git a/libmultipath/util.c b/libmultipath/util.c -index 51c38c87..67e7a42f 100644 ---- a/libmultipath/util.c -+++ b/libmultipath/util.c -@@ -52,7 +52,7 @@ basenamecpy (const char *src, char *dst, size_t size) - } - - int --filepresent (char * run) { -+filepresent (const char *run) { - struct stat buf; - - if(!stat(run, &buf)) -@@ -60,7 +60,7 @@ filepresent (char * run) { - return 0; - } - --char *get_next_string(char **temp, char *split_char) -+char *get_next_string(char **temp, const char *split_char) - { - char *token = NULL; - token = strsep(temp, split_char); -@@ -70,9 +70,9 @@ char *get_next_string(char **temp, char *split_char) - } - - int --get_word (char * sentence, char ** word) -+get_word (const char *sentence, char **word) - { -- char * p; -+ const char *p; - int len; - int skip = 0; - -@@ -381,7 +381,7 @@ int get_linux_version_code(void) - return _linux_version_code; - } - --int parse_prkey(char *ptr, uint64_t *prkey) -+int parse_prkey(const char *ptr, uint64_t *prkey) - { - if (!ptr) - return 1; -@@ -398,7 +398,7 @@ int parse_prkey(char *ptr, uint64_t *prkey) - return 0; - } - --int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) -+int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags) - { - char *flagstr; - -diff --git a/libmultipath/util.h b/libmultipath/util.h -index 56bd78c7..c19c5ac3 100644 ---- a/libmultipath/util.h -+++ b/libmultipath/util.h -@@ -9,9 +9,9 @@ - - size_t strchop(char *); - int basenamecpy (const char *src, char *dst, size_t size); --int filepresent (char * run); --char *get_next_string(char **temp, char *split_char); --int get_word (char * sentence, char ** word); -+int filepresent (const char *run); -+char *get_next_string(char **temp, const char *split_char); -+int get_word (const char * sentence, char ** word); - size_t strlcpy(char *dst, const char *src, size_t size); - size_t strlcat(char *dst, const char *src, size_t size); - int devt2devname (char *, int, char *); -@@ -20,8 +20,8 @@ char *convert_dev(char *dev, int is_path_device); - void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached); - int systemd_service_enabled(const char *dev); - int get_linux_version_code(void); --int parse_prkey(char *ptr, uint64_t *prkey); --int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags); -+int parse_prkey(const char *ptr, uint64_t *prkey); -+int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags); - int safe_write(int fd, const void *buf, size_t count); - void set_max_fds(rlim_t max_fds); - --- -2.17.2 - diff --git a/0074-libmultipath-constify-file-argument-in-config-parser.patch b/0074-libmultipath-constify-file-argument-in-config-parser.patch deleted file mode 100644 index ffef052..0000000 --- a/0074-libmultipath-constify-file-argument-in-config-parser.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:07 +0200 -Subject: [PATCH] libmultipath: constify file argument in config parser - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 3 +-- - libmultipath/config.h | 2 +- - libmultipath/parser.c | 9 +++++---- - libmultipath/parser.h | 2 +- - 4 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index a253a936..1818f8b9 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -718,8 +718,7 @@ static void set_max_checkint_from_watchdog(struct config *conf) - } - #endif - --struct config * --load_config (char * file) -+struct config *load_config(const char *file) - { - struct config *conf = alloc_config(); - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index c7a73fba..78375f2f 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -253,7 +253,7 @@ void free_mptable (vector mptable); - - int store_hwe (vector hwtable, struct hwentry *); - --struct config *load_config (char * file); -+struct config *load_config (const char *file); - struct config * alloc_config (void); - void free_config (struct config * conf); - extern struct config *get_multipath_config(void); -diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index a7285a35..d150e7b2 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -400,7 +400,7 @@ set_regex_value(vector strvec) - /* non-recursive configuration stream handler */ - static int kw_level = 0; - --int warn_on_duplicates(vector uniques, char *str, char *file) -+int warn_on_duplicates(vector uniques, char *str, const char *file) - { - char *tmp; - int i; -@@ -444,7 +444,7 @@ is_sublevel_keyword(char *str) - } - - int --validate_config_strvec(vector strvec, char *file) -+validate_config_strvec(vector strvec, const char *file) - { - char *str; - int i; -@@ -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 *file) - { - int i; - int r = 0, t; -@@ -592,7 +593,7 @@ out: - - /* Data initialization */ - int --process_file(struct config *conf, char *file) -+process_file(struct config *conf, const char *file) - { - int r; - FILE *stream; -diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index b7917052..b385fb9e 100644 ---- a/libmultipath/parser.h -+++ b/libmultipath/parser.h -@@ -78,7 +78,7 @@ 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 int process_file(struct config *conf, const 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, - const void *data); --- -2.17.2 - diff --git a/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch b/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch deleted file mode 100644 index 9fe50d0..0000000 --- a/0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:08 +0200 -Subject: [PATCH] libmultipath: provide defaults for {get,put}_multipath_config - -Add an implementation of get_multipath_config() and put_multipath_config() -to libmultipath. The linker's symbol lookup rules will make sure that -applications can override these functions if they need to. Defining -these functions in libmultipath avoids the need to provide stubs -for these functions in every appliation linking to libmultipath. - -libmultipath's internal functions simply refer to a static "struct config". -It must be initialized with init_config() rather than load_config(), -which always allocates a new struct for backward compatibility, and must -be teared down using uninit_config(). - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 72 +++++++++++++++++++++++++++++++++++++------ - libmultipath/config.h | 21 +++++++++++-- - 2 files changed, 80 insertions(+), 13 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 1818f8b9..422e923d 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -28,6 +28,23 @@ - #include "propsel.h" - #include "version.h" - -+static struct config __internal_config; -+struct config *libmp_get_multipath_config(void) -+{ -+ return &__internal_config; -+} -+ -+struct config *get_multipath_config(void) -+ __attribute__((weak, alias("libmp_get_multipath_config"))); -+ -+void libmp_put_multipath_config(void *conf __attribute__((unused))) -+{ -+ /* empty */ -+} -+ -+void put_multipath_config(void *conf) -+ __attribute__((weak, alias("libmp_put_multipath_config"))); -+ - static int - hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) - { -@@ -575,17 +592,15 @@ restart: - return; - } - --struct config * --alloc_config (void) -+static struct config *alloc_config (void) - { - return (struct config *)MALLOC(sizeof(struct config)); - } - --void --free_config (struct config * conf) -+static void _uninit_config(struct config *conf) - { - if (!conf) -- return; -+ conf = &__internal_config; - - if (conf->multipath_dir) - FREE(conf->multipath_dir); -@@ -649,7 +664,27 @@ free_config (struct config * conf) - free_hwtable(conf->hwtable); - free_hwe(conf->overrides); - free_keywords(conf->keywords); -- FREE(conf); -+ -+ memset(conf, 0, sizeof(*conf)); -+} -+ -+void uninit_config(void) -+{ -+ _uninit_config(&__internal_config); -+} -+ -+void free_config(struct config *conf) -+{ -+ if (!conf) -+ return; -+ else if (conf == &__internal_config) { -+ condlog(0, "ERROR: %s called for internal config. Use uninit_config() instead", -+ __func__); -+ return; -+ } -+ -+ _uninit_config(conf); -+ free(conf); - } - - /* if multipath fails to process the config directory, it should continue, -@@ -718,12 +753,29 @@ static void set_max_checkint_from_watchdog(struct config *conf) - } - #endif - -+static int _init_config (const char *file, struct config *conf); -+ -+int init_config(const char *file) -+{ -+ return _init_config(file, &__internal_config); -+} -+ - struct config *load_config(const char *file) - { - struct config *conf = alloc_config(); - -+ if (conf && !_init_config(file, conf)) -+ return conf; -+ -+ free(conf); -+ return NULL; -+} -+ -+int _init_config (const char *file, struct config *conf) -+{ -+ - if (!conf) -- return NULL; -+ conf = &__internal_config; - - /* - * internal defaults -@@ -911,10 +963,10 @@ struct config *load_config(const char *file) - !conf->wwids_file || !conf->prkeys_file) - goto out; - -- return conf; -+ return 0; - out: -- free_config(conf); -- return NULL; -+ _uninit_config(conf); -+ return 1; - } - - char *get_uid_attribute_by_attrs(struct config *conf, -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 78375f2f..83d179ac 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -254,10 +254,25 @@ void free_mptable (vector mptable); - int store_hwe (vector hwtable, struct hwentry *); - - struct config *load_config (const char *file); --struct config * alloc_config (void); - void free_config (struct config * conf); --extern struct config *get_multipath_config(void); --extern void put_multipath_config(void *); -+int init_config(const char *file); -+void uninit_config(void); -+ -+/* -+ * libmultipath provides default implementations of -+ * get_multipath_config() and put_multipath_config(). -+ * Applications using these should use init_config(file, NULL) -+ * to load the configuration, rather than load_config(file). -+ * Likewise, uninit_config() should be used for teardown, but -+ * using free_config() for that is supported, too. -+ * Applications can define their own {get,put}_multipath_config() -+ * functions, which override the library-internal ones, but -+ * could still call libmp_{get,put}_multipath_config(). -+ */ -+struct config *libmp_get_multipath_config(void); -+struct config *get_multipath_config(void); -+void libmp_put_multipath_config(void *); -+void put_multipath_config(void *); - - int parse_uid_attrs(char *uid_attrs, struct config *conf); - char *get_uid_attribute_by_attrs(struct config *conf, --- -2.17.2 - diff --git a/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch b/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch deleted file mode 100644 index c36aa90..0000000 --- a/0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:09 +0200 -Subject: [PATCH] libmpathpersist: allow using libmultipath - {get,put}_multipath_config - -Provide an alternative init function libmpathpersist_init() which -avoids allocating a new struct config, simply using libmultipath's -internal implementation. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 42 ++++++++++++++++++++++++++++----- - libmpathpersist/mpath_persist.h | 28 ++++++++++++++++++++++ - 2 files changed, 64 insertions(+), 6 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index a132f4e9..9dfc98cd 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -37,6 +37,27 @@ - - extern struct udev *udev; - -+static void adapt_config(struct config *conf) -+{ -+ conf->force_sync = 1; -+ set_max_fds(conf->max_fds); -+} -+ -+int libmpathpersist_init(void) -+{ -+ struct config *conf; -+ int rc = 0; -+ -+ if (init_config(DEFAULT_CONFIGFILE)) { -+ condlog(0, "Failed to initialize multipath config."); -+ return 1; -+ } -+ conf = libmp_get_multipath_config(); -+ adapt_config(conf); -+ libmp_put_multipath_config(conf); -+ return rc; -+} -+ - struct config * - mpath_lib_init (void) - { -@@ -47,21 +68,30 @@ mpath_lib_init (void) - condlog(0, "Failed to initialize multipath config."); - return NULL; - } -- conf->force_sync = 1; -- set_max_fds(conf->max_fds); -- -+ adapt_config(conf); - return conf; - } - --int --mpath_lib_exit (struct config *conf) -+static void libmpathpersist_cleanup(void) - { - dm_lib_release(); - dm_lib_exit(); - cleanup_prio(); - cleanup_checkers(); -+} -+ -+int -+mpath_lib_exit (struct config *conf) -+{ -+ libmpathpersist_cleanup(); - free_config(conf); -- conf = NULL; -+ return 0; -+} -+ -+int libmpathpersist_exit(void) -+{ -+ libmpathpersist_cleanup(); -+ uninit_config(); - return 0; - } - -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 7cf4faf9..91606efc 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -175,6 +175,22 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ - * DESCRIPTION : - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. -+ * Either this function or mpath_lib_init() may be used. -+ * Use this function to work with libmultipath's internal "struct config". -+ * Call libmpathpersist_exit() for cleanup. -+ * RESTRICTIONS: -+ * -+ * RETURNS: 0->Success, 1->Failed. -+ */ -+extern int libmpathpersist_init (void); -+ -+/* -+ * DESCRIPTION : -+ * Initialize device mapper multipath configuration. This function must be invoked first -+ * before performing reservation management functions. -+ * Either this function or libmpathpersist_init() may be used. -+ * Use this function to work with an application-specific "struct config". -+ * Call mpath_lib_exit() for cleanup. - * RESTRICTIONS: - * - * RETURNS: struct config ->Success, NULL->Failed. -@@ -186,12 +202,24 @@ extern struct config * mpath_lib_init (void); - * DESCRIPTION : - * Release device mapper multipath configuration. This function must be invoked after - * performing reservation management functions. -+ * Use this after initialization with mpath_lib_init(). - * RESTRICTIONS: - * - * RETURNS: 0->Success, 1->Failed. - */ - extern int mpath_lib_exit (struct config *conf); - -+/* -+ * DESCRIPTION : -+ * Release device mapper multipath configuration. This function must be invoked after -+ * performing reservation management functions. -+ * Use this after initialization with libmpathpersist_init(). -+ * RESTRICTIONS: -+ * -+ * RETURNS: 0->Success, 1->Failed. -+ */ -+extern int libmpathpersist_exit (void); -+ - - /* - * DESCRIPTION : --- -2.17.2 - diff --git a/0077-multipath-use-get_put-_multipath_config-from-libmult.patch b/0077-multipath-use-get_put-_multipath_config-from-libmult.patch deleted file mode 100644 index 8f0f443..0000000 --- a/0077-multipath-use-get_put-_multipath_config-from-libmult.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:10 +0200 -Subject: [PATCH] multipath: use {get_put}_multipath_config from libmultipath - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 20 ++++---------------- - 1 file changed, 4 insertions(+), 16 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index ce48a932..879d7ac9 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -67,7 +67,6 @@ - - int logsink; - struct udev *udev; --struct config *multipath_conf; - - /* - * Return values of configure(), check_path_valid(), and main(). -@@ -78,16 +77,6 @@ enum { - RTVL_RETRY, /* returned by configure(), not by main() */ - }; - --struct config *get_multipath_config(void) --{ -- return multipath_conf; --} -- --void put_multipath_config(__attribute__((unused)) void *arg) --{ -- /* Noop for now */ --} -- - static int - dump_config (struct config *conf, vector hwes, vector mpvec) - { -@@ -892,10 +881,9 @@ main (int argc, char *argv[]) - - udev = udev_new(); - logsink = 0; -- conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -+ if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); -- multipath_conf = conf; -+ conf = get_multipath_config(); - conf->retrigger_tries = 0; - conf->force_sync = 1; - while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { -@@ -1148,8 +1136,8 @@ out_free_config: - * the logging function (dm_write_log()), which is called there, - * references the config. - */ -- free_config(conf); -- conf = NULL; -+ put_multipath_config(conf); -+ uninit_config(); - udev_unref(udev); - if (dev) - FREE(dev); --- -2.17.2 - diff --git a/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch b/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch deleted file mode 100644 index cc601bb..0000000 --- a/0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:11 +0200 -Subject: [PATCH] mpathpersist: use {get,put}_multipath_config() from - libmultipath - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 16 ++-------------- - 1 file changed, 2 insertions(+), 14 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 28bfe410..0f0db4b8 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -43,17 +43,6 @@ void mpath_print_transport_id(struct prin_fulldescr *fdesc); - int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); - - int logsink; --struct config *multipath_conf; -- --struct config *get_multipath_config(void) --{ -- return multipath_conf; --} -- --void put_multipath_config(__attribute__((unused)) void * arg) --{ -- /* Noop for now */ --} - - void rcu_register_thread_memb(void) {} - -@@ -620,15 +609,14 @@ int main(int argc, char *argv[]) - } - - udev = udev_new(); -- multipath_conf = mpath_lib_init(); -- if(!multipath_conf) { -+ if (libmpathpersist_init()) { - udev_unref(udev); - exit(1); - } - - ret = handle_args(argc, argv, 0); - -- mpath_lib_exit(multipath_conf); -+ libmpathpersist_exit(); - udev_unref(udev); - - return (ret >= 0) ? ret : MPATH_PR_OTHER; --- -2.17.2 - diff --git a/0079-libmultipath-add-udev-and-logsink-symbols.patch b/0079-libmultipath-add-udev-and-logsink-symbols.patch deleted file mode 100644 index 1b17a12..0000000 --- a/0079-libmultipath-add-udev-and-logsink-symbols.patch +++ /dev/null @@ -1,156 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:12 +0200 -Subject: [PATCH] libmultipath: add udev and logsink symbols - -With these symbols added, applications using libmultipath don't -need to define global variables "udev" and "logsink" any more. -This comes at the cost of having to call an init function. -Currently, libmultipath_init() does nothing but initialize -"udev". - -The linker's symbol lookup order still allows applications to use -their own "logsink" and "udev" variables, which will take precendence -over libmultipath's internal ones. In this case, calling -libmultipath_init() can be skipped, but like before, -udev should be initialized (using udev_new()) before making any -libmultipath calls. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 46 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/config.h | 46 ++++++++++++++++++++++++++++++++++++++++++- - libmultipath/debug.c | 2 ++ - 3 files changed, 93 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 422e923d..b3809433 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -28,6 +28,52 @@ - #include "propsel.h" - #include "version.h" - -+/* -+ * We don't support re-initialization after -+ * libmultipath_exit(). -+ */ -+static bool libmultipath_exit_called; -+static pthread_once_t _init_once = PTHREAD_ONCE_INIT; -+static pthread_once_t _exit_once = PTHREAD_ONCE_INIT; -+struct udev *udev; -+ -+static void _udev_init(void) -+{ -+ if (udev) -+ udev_ref(udev); -+ else -+ udev = udev_new(); -+ if (!udev) -+ condlog(0, "%s: failed to initialize udev", __func__); -+} -+ -+static void _libmultipath_init(void) -+{ -+ _udev_init(); -+} -+ -+static bool _is_libmultipath_initialized(void) -+{ -+ return !libmultipath_exit_called && !!udev; -+} -+ -+int libmultipath_init(void) -+{ -+ pthread_once(&_init_once, _libmultipath_init); -+ return !_is_libmultipath_initialized(); -+} -+ -+static void _libmultipath_exit(void) -+{ -+ libmultipath_exit_called = true; -+ udev_unref(udev); -+} -+ -+void libmultipath_exit(void) -+{ -+ pthread_once(&_exit_once, _libmultipath_exit); -+} -+ - static struct config __internal_config; - struct config *libmp_get_multipath_config(void) - { -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 83d179ac..089b2ac2 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -235,7 +235,51 @@ struct config { - char *enable_foreign; - }; - --extern struct udev * udev; -+/** -+ * extern variable: udev -+ * -+ * A &struct udev instance used by libmultipath. libmultipath expects -+ * a valid, initialized &struct udev in this variable. -+ * An application can define this variable itself, in which case -+ * the applications's instance will take precedence. -+ * The application can initialize and destroy this variable by -+ * calling libmultipath_init() and libmultipath_exit(), respectively, -+ * whether or not it defines the variable itself. -+ * An application can initialize udev with udev_new() before calling -+ * libmultipath_init(), e.g. if it has to make libudev calls before -+ * libmultipath calls. If an application wants to keep using the -+ * udev variable after calling libmultipath_exit(), it should have taken -+ * an additional reference on it beforehand. This is the case e.g. -+ * after initiazing udev with udev_new(). -+ */ -+extern struct udev *udev; -+ -+/** -+ * libmultipath_init() - library initialization -+ * -+ * This function initializes libmultipath data structures. -+ * It is light-weight; some other initializations, like device-mapper -+ * initialization, are done lazily when the respective functionality -+ * is required. -+ * -+ * Clean up by libmultipath_exit() when the program terminates. -+ * It is an error to call libmultipath_init() after libmultipath_exit(). -+ * Return: 0 on success, 1 on failure. -+ */ -+int libmultipath_init(void); -+ -+/** -+ * libmultipath_exit() - library un-initialization -+ * -+ * This function un-initializes libmultipath data structures. -+ * It is recommended to call this function at program exit. -+ * -+ * Calls to libmultipath_init() after libmultipath_exit() will fail -+ * (in other words, libmultipath can't be re-initialized). -+ * Any other libmultipath calls after libmultipath_exit() may cause -+ * undefined behavior. -+ */ -+void libmultipath_exit(void); - - int find_hwe (const struct _vector *hwtable, - const char * vendor, const char * product, const char *revision, -diff --git a/libmultipath/debug.c b/libmultipath/debug.c -index 4128cb90..b3a1de9e 100644 ---- a/libmultipath/debug.c -+++ b/libmultipath/debug.c -@@ -15,6 +15,8 @@ - #include "defaults.h" - #include "debug.h" - -+int logsink; -+ - void dlog (int sink, int prio, const char * fmt, ...) - { - va_list ap; --- -2.17.2 - diff --git a/0080-multipath-remove-logsink-and-udev.patch b/0080-multipath-remove-logsink-and-udev.patch deleted file mode 100644 index 9c4b728..0000000 --- a/0080-multipath-remove-logsink-and-udev.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:13 +0200 -Subject: [PATCH] multipath: remove logsink and udev - -We can use libmultipath's symbols now. - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index 879d7ac9..322b30e0 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -65,9 +65,6 @@ - #include "file.h" - #include "valid.h" - --int logsink; --struct udev *udev; -- - /* - * Return values of configure(), check_path_valid(), and main(). - */ -@@ -879,7 +876,7 @@ main (int argc, char *argv[]) - int retries = -1; - bool enable_foreign = false; - -- udev = udev_new(); -+ libmultipath_init(); - logsink = 0; - if (init_config(DEFAULT_CONFIGFILE)) - exit(RTVL_FAIL); -@@ -1138,7 +1135,7 @@ out_free_config: - */ - put_multipath_config(conf); - uninit_config(); -- udev_unref(udev); -+ libmultipath_exit(); - if (dev) - FREE(dev); - #ifdef _DEBUG_ --- -2.17.2 - diff --git a/0081-libmpathpersist-call-libmultipath_-init-exit.patch b/0081-libmpathpersist-call-libmultipath_-init-exit.patch deleted file mode 100644 index 2163f02..0000000 --- a/0081-libmpathpersist-call-libmultipath_-init-exit.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:14 +0200 -Subject: [PATCH] libmpathpersist: call libmultipath_{init,exit}() - -Have libmpathpersist_{init,exit} do the udev initialization, too. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 13 +++++++++---- - libmpathpersist/mpath_persist.h | 9 ++++++--- - 2 files changed, 15 insertions(+), 7 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 9dfc98cd..d1538195 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -48,6 +48,10 @@ int libmpathpersist_init(void) - struct config *conf; - int rc = 0; - -+ if (libmultipath_init()) { -+ condlog(0, "Failed to initialize libmultipath."); -+ return 1; -+ } - if (init_config(DEFAULT_CONFIGFILE)) { - condlog(0, "Failed to initialize multipath config."); - return 1; -@@ -74,24 +78,25 @@ mpath_lib_init (void) - - static void libmpathpersist_cleanup(void) - { -- dm_lib_release(); -- dm_lib_exit(); - cleanup_prio(); - cleanup_checkers(); -+ libmultipath_exit(); -+ dm_lib_release(); -+ dm_lib_exit(); - } - - int - mpath_lib_exit (struct config *conf) - { -- libmpathpersist_cleanup(); - free_config(conf); -+ libmpathpersist_cleanup(); - return 0; - } - - int libmpathpersist_exit(void) - { -- libmpathpersist_cleanup(); - uninit_config(); -+ libmpathpersist_cleanup(); - return 0; - } - -diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h -index 91606efc..5435eae4 100644 ---- a/libmpathpersist/mpath_persist.h -+++ b/libmpathpersist/mpath_persist.h -@@ -176,7 +176,8 @@ struct prout_param_descriptor { /* PROUT parameter descriptor */ - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. - * Either this function or mpath_lib_init() may be used. -- * Use this function to work with libmultipath's internal "struct config". -+ * Use this function to work with libmultipath's internal "struct config" -+ * and "struct udev". The latter will be initialized automatically. - * Call libmpathpersist_exit() for cleanup. - * RESTRICTIONS: - * -@@ -189,7 +190,8 @@ extern int libmpathpersist_init (void); - * Initialize device mapper multipath configuration. This function must be invoked first - * before performing reservation management functions. - * Either this function or libmpathpersist_init() may be used. -- * Use this function to work with an application-specific "struct config". -+ * Use this function to work with an application-specific "struct config" -+ * and "struct udev". The latter must be initialized by the application. - * Call mpath_lib_exit() for cleanup. - * RESTRICTIONS: - * -@@ -211,9 +213,10 @@ extern int mpath_lib_exit (struct config *conf); - - /* - * DESCRIPTION : -- * Release device mapper multipath configuration. This function must be invoked after -+ * Release device mapper multipath configuration a. This function must be invoked after - * performing reservation management functions. - * Use this after initialization with libmpathpersist_init(). -+ * Calling libmpathpersist_init() after libmpathpersist_exit() will fail. - * RESTRICTIONS: - * - * RETURNS: 0->Success, 1->Failed. --- -2.17.2 - diff --git a/0082-mpathpersist-remove-logsink-and-udev.patch b/0082-mpathpersist-remove-logsink-and-udev.patch deleted file mode 100644 index 8dde360..0000000 --- a/0082-mpathpersist-remove-logsink-and-udev.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:15 +0200 -Subject: [PATCH] mpathpersist: remove logsink and udev - -We can use libmultipath's internal symbols now. The libmultipath -initialization is taken care of by libmpathpersist_init(). - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - mpathpersist/main.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 0f0db4b8..a25b08f0 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -42,13 +42,10 @@ void * mpath_alloc_prin_response(int prin_sa); - void mpath_print_transport_id(struct prin_fulldescr *fdesc); - int construct_transportid(const char * inp, struct transportid transid[], int num_transportids); - --int logsink; -- - void rcu_register_thread_memb(void) {} - - void rcu_unregister_thread_memb(void) {} - --struct udev *udev; - - static int verbose, loglevel, noisy; - -@@ -608,16 +605,13 @@ int main(int argc, char *argv[]) - exit (1); - } - -- udev = udev_new(); - if (libmpathpersist_init()) { -- udev_unref(udev); - exit(1); - } - - ret = handle_args(argc, argv, 0); - - libmpathpersist_exit(); -- udev_unref(udev); - - return (ret >= 0) ? ret : MPATH_PR_OTHER; - } --- -2.17.2 - diff --git a/0083-multipathd-remove-logsink-and-udev.patch b/0083-multipathd-remove-logsink-and-udev.patch deleted file mode 100644 index a2b656b..0000000 --- a/0083-multipathd-remove-logsink-and-udev.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Thu, 24 Sep 2020 15:37:16 +0200 -Subject: [PATCH] multipathd: remove logsink and udev - -We can use the symbols from libmultipath now. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 48b62937..6a4b8b83 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -113,7 +113,6 @@ struct mpath_event_param - struct multipath *mpp; - }; - --int logsink; - int uxsock_timeout; - int verbosity; - int bindings_read_only; -@@ -144,8 +143,6 @@ static inline enum daemon_status get_running_state(void) - */ - struct vectors * gvecs; - --struct udev * udev; -- - struct config *multipath_conf; - - /* Local variables */ -@@ -3009,8 +3006,6 @@ child (__attribute__((unused)) void *param) - conf = rcu_dereference(multipath_conf); - rcu_assign_pointer(multipath_conf, NULL); - call_rcu(&conf->rcu, rcu_free_config); -- udev_unref(udev); -- udev = NULL; - pthread_attr_destroy(&waiter_attr); - pthread_attr_destroy(&io_err_stat_attr); - #ifdef _DEBUG_ -@@ -3114,7 +3109,9 @@ main (int argc, char *argv[]) - - pthread_cond_init_mono(&config_cond); - -- udev = udev_new(); -+ libmultipath_init(); -+ if (atexit(libmultipath_exit)) -+ condlog(3, "failed to register exit handler for libmultipath"); - libmp_udev_set_sync_support(0); - - while ((arg = getopt(argc, argv, ":dsv:k::Bniw")) != EOF ) { --- -2.17.2 - diff --git a/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch b/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch deleted file mode 100644 index 114d0f4..0000000 --- a/0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Sat, 26 Sep 2020 23:25:46 -0500 -Subject: [PATCH] libmpathvalid: use default *_multipath_config, udev, and - logsink - -Signed-off-by: Benjamin Marzinski ---- - libmpathvalid/libmpathvalid.version | 2 +- - libmpathvalid/mpath_valid.c | 73 ++++++++++++++++++++--------- - libmpathvalid/mpath_valid.h | 12 +++-- - 3 files changed, 61 insertions(+), 26 deletions(-) - -diff --git a/libmpathvalid/libmpathvalid.version b/libmpathvalid/libmpathvalid.version -index 4d8a8ba4..3bd0d3c5 100644 ---- a/libmpathvalid/libmpathvalid.version -+++ b/libmpathvalid/libmpathvalid.version -@@ -1,7 +1,7 @@ - MPATH_1.0 { - global: -- mpathvalid_conf; - mpathvalid_init; -+ mpathvalid_reload_config; - mpathvalid_exit; - mpathvalid_is_path; - mpathvalid_get_mode; -diff --git a/libmpathvalid/mpath_valid.c b/libmpathvalid/mpath_valid.c -index 6153e8b7..d839dbac 100644 ---- a/libmpathvalid/mpath_valid.c -+++ b/libmpathvalid/mpath_valid.c -@@ -15,9 +15,7 @@ - #include "mpath_cmd.h" - #include "valid.h" - #include "mpath_valid.h" -- --static struct config default_config = { .verbosity = -1 }; --struct config *mpathvalid_conf = &default_config; -+#include "debug.h" - - static unsigned int get_conf_mode(struct config *conf) - { -@@ -68,38 +66,70 @@ static int convert_result(int result) { - } - - int --mpathvalid_init(int verbosity) -+mpathvalid_init(int verbosity, int log_style) - { - unsigned int version[3]; - struct config *conf; - -- default_config.verbosity = verbosity; -- skip_libmp_dm_init(); -- conf = load_config(DEFAULT_CONFIGFILE); -- if (!conf) -+ logsink = log_style; -+ if (libmultipath_init()) - return -1; -+ conf = get_multipath_config(); - conf->verbosity = verbosity; -- if (dm_prereq(version)) -+ put_multipath_config(conf); -+ -+ skip_libmp_dm_init(); -+ if (init_config(DEFAULT_CONFIGFILE)) - goto fail; -- memcpy(conf->version, version, sizeof(version)); -+ if (dm_prereq(version)) -+ goto fail_config; - -- mpathvalid_conf = conf; -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ memcpy(conf->version, version, sizeof(version)); -+ put_multipath_config(conf); - return 0; -+ -+fail_config: -+ uninit_config(); - fail: -- free_config(conf); -+ libmultipath_exit(); - return -1; - } - - int --mpathvalid_exit(void) -+mpathvalid_reload_config(void) - { -- struct config *conf = mpathvalid_conf; -+ int verbosity; -+ unsigned int version[3]; -+ struct config *conf; -+ -+ conf = get_multipath_config(); -+ memcpy(version, conf->version, sizeof(version)); -+ verbosity = conf->verbosity; -+ put_multipath_config(conf); - -- default_config.verbosity = -1; -- if (mpathvalid_conf == &default_config) -- return 0; -- mpathvalid_conf = &default_config; -- free_config(conf); -+ uninit_config(); -+ -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ put_multipath_config(conf); -+ -+ if (init_config(DEFAULT_CONFIGFILE)) -+ return -1; -+ -+ conf = get_multipath_config(); -+ conf->verbosity = verbosity; -+ memcpy(conf->version, version, sizeof(version)); -+ put_multipath_config(conf); -+ return 0; -+} -+ -+int -+mpathvalid_exit(void) -+{ -+ uninit_config(); -+ libmultipath_exit(); - return 0; - } - -@@ -121,9 +151,10 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - - if (!name || mode >= MPATH_MAX_MODE) - return r; -- - if (nr_paths > 0 && !path_wwids) - return r; -+ if (!udev) -+ return r; - - pp = alloc_path(); - if (!pp) -@@ -136,7 +167,7 @@ mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - } - - conf = get_multipath_config(); -- if (!conf || conf == &default_config) -+ if (!conf) - goto out_wwid; - if (mode != MPATH_DEFAULT) - set_conf_mode(conf, mode); -diff --git a/libmpathvalid/mpath_valid.h b/libmpathvalid/mpath_valid.h -index 7fd8aa47..c83b8da5 100644 ---- a/libmpathvalid/mpath_valid.h -+++ b/libmpathvalid/mpath_valid.h -@@ -42,15 +42,19 @@ enum mpath_valid_result { - MPATH_IS_MAYBE_VALID, - }; - --struct config; --extern struct config *mpathvalid_conf; --int mpathvalid_init(int verbosity); -+enum mpath_valid_log_style { -+ MPATH_LOG_STDIO = -1, -+ MPATH_LOG_STDIO_TIMESTAMP, -+ MPATH_LOG_SYSLOG, -+}; -+ -+int mpathvalid_init(int verbosity, int log_style); -+int mpathvalid_reload_config(void); - int mpathvalid_exit(void); - unsigned int mpathvalid_get_mode(void); - int mpathvalid_is_path(const char *name, unsigned int mode, char **wwid, - const char **path_wwids, unsigned int nr_paths); - -- - #ifdef __cplusplus - } - #endif --- -2.17.2 - diff --git a/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch b/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch deleted file mode 100644 index 57ff199..0000000 --- a/0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Sat, 26 Sep 2020 23:26:32 -0500 -Subject: [PATCH] Revert "libmultipath: add ignore_udev_uid option" - -This reverts commit f1350bc5c4aa445804f3f4fc8968fb46d581336e. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.h | 1 - - libmultipath/dict.c | 4 ---- - libmultipath/discovery.c | 17 ++++++----------- - libmultipath/discovery.h | 8 +------- - libmultipath/uevent.c | 2 +- - multipath/multipath.conf.5 | 13 ------------- - multipathd/main.c | 7 +------ - 7 files changed, 9 insertions(+), 43 deletions(-) - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 089b2ac2..576f15d1 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -192,7 +192,6 @@ struct config { - int find_multipaths_timeout; - int marginal_pathgroups; - int skip_delegate; -- int ignore_udev_uid; - unsigned int version[3]; - unsigned int sequence_nr; - -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 9a0729bf..184d4b22 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1406,9 +1406,6 @@ 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(ignore_udev_uid, set_yes_no) --declare_def_snprint(ignore_udev_uid, print_yes_no) -- - static int - def_uxsock_timeout_handler(struct config *conf, vector strvec) - { -@@ -1819,7 +1816,6 @@ 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("ignore_udev_uid", &def_ignore_udev_uid_handler, &snprint_def_ignore_udev_uid); - __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); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index f0e92227..002d3d18 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2010,7 +2010,7 @@ static bool has_uid_fallback(struct path *pp) - - int - get_uid (struct path * pp, int path_state, struct udev_device *udev, -- int fallback) -+ int allow_fallback) - { - char *c; - const char *origin = "unknown"; -@@ -2043,9 +2043,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } else - len = strlen(pp->wwid); - origin = "callout"; -- } else if (fallback == UID_FALLBACK_FORCE) -- len = uid_fallback(pp, path_state, &origin); -- else { -+ } else { - bool udev_available = udev && pp->uid_attribute - && *pp->uid_attribute; - -@@ -2058,9 +2056,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - else - origin = "udev"; - } -- if ((!udev_available || -- (len <= 0 && fallback == UID_FALLBACK_ALLOW)) && -- has_uid_fallback(pp)) { -+ if ((!udev_available || (len <= 0 && allow_fallback)) -+ && has_uid_fallback(pp)) { - used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } -@@ -2200,10 +2197,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - - if ((mask & DI_WWID) && !strlen(pp->wwid)) { -- int fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE : -- (pp->retriggers >= conf->retrigger_tries)? -- UID_FALLBACK_ALLOW : UID_FALLBACK_NONE; -- get_uid(pp, path_state, pp->udev, fallback); -+ get_uid(pp, path_state, pp->udev, -+ (pp->retriggers >= conf->retrigger_tries)); - if (!strlen(pp->wwid)) { - if (pp->bus == SYSFS_BUS_UNDEF) - return PATHINFO_SKIPPED; -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index ca8542d6..6444887d 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -54,14 +54,8 @@ 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); -- --enum { -- UID_FALLBACK_NONE, -- UID_FALLBACK_ALLOW, -- UID_FALLBACK_FORCE, --}; - int get_uid(struct path * pp, int path_state, struct udev_device *udev, -- int fallback); -+ int allow_fallback); - - /* - * discovery bitmask -diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c -index d67129d1..e0d13b11 100644 ---- a/libmultipath/uevent.c -+++ b/libmultipath/uevent.c -@@ -179,7 +179,7 @@ uevent_need_merge(void) - bool need_merge = false; - - conf = get_multipath_config(); -- if (!conf->ignore_udev_uid && VECTOR_SIZE(&conf->uid_attrs) > 0) -+ if (VECTOR_SIZE(&conf->uid_attrs) > 0) - need_merge = true; - put_multipath_config(conf); - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 175ca095..42a192f6 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -286,19 +286,6 @@ The default is: \fB\fR - . - . - .TP --.B ignore_udev_uid --Setting this option to yes will force multipath to ignore the the uid_attrs --and uid_attribute settings, and generate the WWID by the \fIsysfs\fR --method. This will cause devices that cannot get their WWID from the standard --locations for their device type to not get a WWID; see \fBWWID generation\fR --below. --.RS --.TP --The default is: \fBno\fR --.RE --. --. --.TP - .B prio - The name of the path priority routine. The specified routine - should return a numeric value specifying the relative priority -diff --git a/multipathd/main.c b/multipathd/main.c -index 6a4b8b83..94926b57 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1223,7 +1223,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - if (pp) { - struct multipath *mpp = pp->mpp; - char wwid[WWID_SIZE]; -- int fallback; - - if (pp->initialized == INIT_REQUESTED_UDEV) { - needs_reinit = 1; -@@ -1235,11 +1234,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- conf = get_multipath_config(); -- fallback = conf->ignore_udev_uid? UID_FALLBACK_FORCE: -- UID_FALLBACK_NONE; -- put_multipath_config(conf); -- rc = get_uid(pp, pp->state, uev->udev, fallback); -+ rc = get_uid(pp, pp->state, uev->udev, 0); - - if (rc != 0) - strcpy(pp->wwid, wwid); --- -2.17.2 - diff --git a/0086-libmultipath-change-log-level-for-null-uid_attribute.patch b/0086-libmultipath-change-log-level-for-null-uid_attribute.patch deleted file mode 100644 index 8567bc3..0000000 --- a/0086-libmultipath-change-log-level-for-null-uid_attribute.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 22 Sep 2020 16:03:31 -0500 -Subject: [PATCH] libmultipath: change log level for null uid_attribute - -If uid_attribute is explicitly set to an empty string, multipath should -log the uid at the default log level, since using the fallback code is -the expected behavior. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 002d3d18..77468524 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -2058,7 +2058,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev, - } - if ((!udev_available || (len <= 0 && allow_fallback)) - && has_uid_fallback(pp)) { -- used_fallback = 1; -+ if (udev_available || !(udev && pp->uid_attribute)) -+ used_fallback = 1; - len = uid_fallback(pp, path_state, &origin); - } - } --- -2.17.2 - diff --git a/0087-libmultipath-orphan_paths-avoid-BUG-message.patch b/0087-libmultipath-orphan_paths-avoid-BUG-message.patch deleted file mode 100644 index 3dcc3a4..0000000 --- a/0087-libmultipath-orphan_paths-avoid-BUG-message.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Tue, 11 Aug 2020 21:08:27 +0200 -Subject: [PATCH] libmultipath: orphan_paths(): avoid BUG message - -Since c44d769, we print a BUG message when we orphan a path that -holds the mpp->hwe pointer. But if this called via orphan_paths(), -this is expected and we shouldn't warn. - -Fixes: c44d769 ("libmultipath: warn if freeing path that holds mpp->hwe") - -Reviewed-by: Benjamin Marzinski -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs_vec.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c -index ede14297..d70bb6ad 100644 ---- a/libmultipath/structs_vec.c -+++ b/libmultipath/structs_vec.c -@@ -114,6 +114,8 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason) - int i; - struct path * pp; - -+ /* Avoid BUG message from orphan_path() */ -+ mpp->hwe = NULL; - vector_foreach_slot (pathvec, pp, i) { - if (pp->mpp == mpp) { - orphan_path(pp, reason); --- -2.17.2 - diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 7b4fb7a..5d80d4e 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,108 +1,37 @@ Name: device-mapper-multipath -Version: 0.8.4 -Release: 7%{?dist} +Version: 0.13.0 +Release: 2%{?dist} Summary: Tools to manage multipath devices using device-mapper -License: GPLv2 +# readline uses GPL-3.0-only +License: GPL-2.0-only AND GPL-3.0-only 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.13.0.tar.gz -o multipath-tools-0.13.0.tgz +Source0: multipath-tools-0.13.0.tgz Source1: multipath.conf -Patch0001: 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch -Patch0002: 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch -Patch0003: 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch -Patch0004: 0004-libmultipath-assign-variable-to-make-gcc-happy.patch -Patch0005: 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch -Patch0006: 0006-libmultipath-allow-force-reload-with-no-active-paths.patch -Patch0007: 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch -Patch0008: 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch -Patch0009: 0009-libmpathpersist-depend-on-libmultipath.patch -Patch0010: 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch -Patch0011: 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch -Patch0012: 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch -Patch0013: 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch -Patch0014: 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch -Patch0015: 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch -Patch0016: 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch -Patch0017: 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch -Patch0018: 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch -Patch0019: 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch -Patch0020: 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch -Patch0021: 0021-libmultipath-move-libsg-into-libmultipath.patch -Patch0022: 0022-multipath-tools-Makefile-add-install-dependency.patch -Patch0023: 0023-libmultipath-make-libmp_dm_init-optional.patch -Patch0024: 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch -Patch0025: 0025-multipath-centralize-validation-code.patch -Patch0026: 0026-Unit-tests-for-is_path_valid.patch -Patch0027: 0027-libmultipath-simplify-failed-wwid-code.patch -Patch0028: 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch -Patch0029: 0029-fix-boolean-value-with-json-c-0.14.patch -Patch0030: 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch -Patch0031: 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch -Patch0032: 0032-multipath-add-e-option-to-enable-foreign-libraries.patch -Patch0033: 0033-libmultipath-remove-_blacklist_exceptions-functions.patch -Patch0034: 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch -Patch0035: 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch -Patch0036: 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch -Patch0037: 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch -Patch0038: 0038-kpartx-read-devices-with-direct-IO.patch -Patch0039: 0039-kpartx-handle-alternate-bsd-disklabel-location.patch -Patch0040: 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch -Patch0041: 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch -Patch0042: 0042-multipathd-fix-check_path-errors-with-removed-map.patch -Patch0043: 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch -Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch -Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch -Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch -Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch -Patch0048: 0048-libmultipath-add-device-to-hwtable.c.patch -Patch0049: 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch -Patch0050: 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch -Patch0051: 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch -Patch0052: 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch -Patch0053: 0053-Makefile.inc-trim-extra-information-from-systemd-ver.patch -Patch0054: 0054-kpartx-fix-Wsign-compare-error.patch -Patch0055: 0055-libmultipath-remove-code-duplication-in-path-countin.patch -Patch0056: 0056-libmultipath-count-pending-paths-as-active-on-loads.patch -Patch0057: 0057-libmultipath-deal-with-flushing-no-maps.patch -Patch0058: 0058-multipath-deal-with-delegation-failures-correctly.patch -Patch0059: 0059-RH-fixup-udev-rules-for-redhat.patch -Patch0060: 0060-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0061: 0061-RH-don-t-start-without-a-config-file.patch -Patch0062: 0062-RH-use-rpm-optflags-if-present.patch -Patch0063: 0063-RH-add-mpathconf.patch -Patch0064: 0064-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0065: 0065-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0066: 0066-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0067: 0067-RH-Fix-nvme-compilation-warning.patch -Patch0068: 0068-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0069: 0069-RH-work-around-gcc-10-format-truncation-issue.patch -Patch0070: 0070-multipath-add-libmpathvalid-library.patch -Patch0071: 0071-libmultipath-add-uid-failback-for-dasd-devices.patch -Patch0072: 0072-libmultipath-add-ignore_udev_uid-option.patch -Patch0073: 0073-libmultipath-util-constify-function-arguments.patch -Patch0074: 0074-libmultipath-constify-file-argument-in-config-parser.patch -Patch0075: 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch -Patch0076: 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch -Patch0077: 0077-multipath-use-get_put-_multipath_config-from-libmult.patch -Patch0078: 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch -Patch0079: 0079-libmultipath-add-udev-and-logsink-symbols.patch -Patch0080: 0080-multipath-remove-logsink-and-udev.patch -Patch0081: 0081-libmpathpersist-call-libmultipath_-init-exit.patch -Patch0082: 0082-mpathpersist-remove-logsink-and-udev.patch -Patch0083: 0083-multipathd-remove-logsink-and-udev.patch -Patch0084: 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch -Patch0085: 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch -Patch0086: 0086-libmultipath-change-log-level-for-null-uid_attribute.patch -Patch0087: 0087-libmultipath-orphan_paths-avoid-BUG-message.patch +Patch0001: 0001-RH-fixup-udev-rules-for-redhat.patch +Patch0002: 0002-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0003: 0003-RH-don-t-start-without-a-config-file.patch +Patch0004: 0004-RH-Fix-nvme-function-missing-argument.patch +Patch0005: 0005-RH-use-rpm-optflags-if-present.patch +Patch0006: 0006-RH-add-mpathconf.patch +Patch0007: 0007-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0008: 0008-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0009: 0009-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0010: 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0011: 0011-RH-add-scsi-device-handlers-to-modules-load.d.patch +Patch0012: 0012-RH-compile-with-libreadline-support.patch +Patch0013: 0013-RH-Add-mpathcleanup.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.96 Requires: userspace-rcu +Requires: readline +Requires: libmount Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -124,6 +53,8 @@ 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 @@ -134,8 +65,8 @@ The tools are : %package libs Summary: The %{name} modules and shared library -# only libmpathcmd is LGPLv2+ -License: GPLv2 and LGPLv2+ +# only libmpathcmd is LGPL-2.1-or-later AND LGPL-2.0-or-later +License: GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later %description libs The %{name}-libs provides the path checker @@ -160,7 +91,8 @@ kpartx manages partition creation and removal for device-mapper devices. %package -n libdmmp Summary: device-mapper-multipath C API library -License: GPLv3+ +# Automatically converted from old format: GPLv3+ - review is highly recommended. +License: GPL-3.0-or-later Requires: json-c Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} @@ -179,11 +111,10 @@ 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.13.0 -p1 cp %{SOURCE1} . %build -%define _sbindir /usr/sbin %define _libdir /usr/%{_lib} %define _libmpathdir %{_libdir}/multipath %define _pkgconfdir %{_libdir}/pkgconfig @@ -194,11 +125,12 @@ cp %{SOURCE1} . bindir=%{_sbindir} \ syslibdir=%{_libdir} \ usrlibdir=%{_libdir} \ - libdir=%{_libmpathdir} \ - rcdir=%{_initrddir} \ + plugindir=%{_libmpathdir} \ + mandir=%{_mandir} \ unitdir=%{_unitdir} \ includedir=%{_includedir} \ - pkgconfdir=%{_pkgconfdir} + pkgconfdir=%{_pkgconfdir} \ + tmpfilesdir=%{_tmpfilesdir} # tree fix up install -d %{buildroot}/etc/multipath @@ -213,7 +145,7 @@ rm -rf %{buildroot}/%{_initrddir} %postun if [ $1 -ge 1 ] ; then - /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : + multipathd forcequeueing daemon > /dev/null 2>&1 || : fi %systemd_postun_with_restart multipathd.service @@ -223,30 +155,39 @@ fi /bin/systemctl --quiet is-enabled multipathd.service >/dev/null 2>&1 && /bin/systemctl reenable multipathd.service ||: %files -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%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-queueing.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 +%{_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 -%doc README -%doc README.alua +%config /usr/lib/udev/rules.d/99-z-dm-mpath-late.rules +%dir %{_modulesloaddir} +%{_modulesloaddir}/scsi_dh.conf +%{_tmpfilesdir}/multipath.conf +%doc README.md %doc multipath.conf %dir /etc/multipath %files libs -%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 -%doc README +%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.* @@ -256,43 +197,344 @@ fi %ldconfig_scriptlets libs %files devel -%doc README +%doc README.md %{_libdir}/libmpathpersist.so %{_libdir}/libmpathcmd.so %{_libdir}/libmpathvalid.so %{_includedir}/mpath_cmd.h %{_includedir}/mpath_persist.h %{_includedir}/mpath_valid.h -%{_mandir}/man3/mpath_persistent_reserve_in.3.gz -%{_mandir}/man3/mpath_persistent_reserve_out.3.gz +%{_mandir}/man3/mpath_persistent_reserve_in.3* +%{_mandir}/man3/mpath_persistent_reserve_out.3* %files -n kpartx %license LICENSES/GPL-2.0 -%doc README +%doc README.md %{_sbindir}/kpartx /usr/lib/udev/kpartx_id -%{_mandir}/man8/kpartx.8.gz +%{_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 %license LICENSES/GPL-3.0 -%doc README +%doc README.md %{_libdir}/libdmmp.so.* %ldconfig_scriptlets -n libdmmp %files -n libdmmp-devel -%doc README +%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 Nov 13 2025 Benjamin Marzinski - 0.13.0-2 +- Move STI tests to TMT + +* Tue Nov 4 2025 Benjamin Marzinski - 0.13.0-1 +- Update source to upstream release 0.13.0 + * Previous patches 0001-0004 are included in the tarball +- Install /lib/systemd/system/multipathd-queueing.service +- Rename redhat patches + * Previous patches 0005-0017 are now patches 0001-0013 + +* Wed Jul 23 2025 Fedora Release Engineering - 0.11.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Thu Feb 27 2025 Benjamin Marzinski - 0.11.1-1 +- Update source to upstream staging branch for 0.11.1 plus additional + stable branch patches. + * Previous patches 0001-0032 are included in the tarball +- Rename redhat patches + * Previous patches 0033-0045 are now patches 0005-0017 + +* Sat Feb 1 2025 Benjamin Marzinski - 0.10.0-5 +- Update source to upstream staging branch for 0.10.y (will be 0.10.2 when + merged). +- Rebase redhat patches + +* Thu Jan 16 2025 Fedora Release Engineering - 0.10.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 0.10.0-3 +- Rebuilt for the bin-sbin merge (2nd attempt) + +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-2 +- update CI tests. + +* Thu Aug 29 2024 Benjamin Marzinski - 0.10.0-1 +- Update source to upstream version 0.9.9 + * Previous patch 0014-multipathd-fix-flush-check-in-flush_map.patch is + included in the source tarball +- Rebase redhat patches + +* Fri Aug 9 2024 Benjamin Marzinski - 0.9.9-6 +- Add 0014-multipathd-fix-null-pointer-dereference-in-uev_updat.patch + * multipath features tracking on failed removes + +* Mon Jul 29 2024 Miroslav Suchý - 0.9.9-5 +- convert license to SPDX + +* Thu Jul 25 2024 Miroslav Suchý - 0.9.9-4 +- convert license to SPDX + +* Wed Jul 17 2024 Fedora Release Engineering - 0.9.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 0.9.9-2 +- Rebuilt for the bin-sbin merge + +* Thu Jun 13 2024 Benjamin Marzinski - 0.9.9-1 +- Update source to upstream version 0.9.9 + * Previous patches 0001-0044 are included in the source tarball +- Rename redhat patches + * Previous patches 0045-0057 are now patches 0001-0013 + +* Mon May 20 2024 Benjamin Marzinski - 0.9.8-1 +- Update source to upstream version 0.9.8 plus latest staging branch + * Previous patches 0014 & 0015 are included in the source tarball + * patches 0001-0044 are from the upstream staging branch +- Rename redhat patches + * Previous patches 0001-0013 are now patches 0045-0057 +- Install /lib/udev/rules.d/99-z-dm-mpath-late.rules + +* Wed Jan 24 2024 Fedora Release Engineering - 0.9.7-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 19 2024 Fedora Release Engineering - 0.9.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* 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 + +* Thu Nov 30 2023 Benjamin Marzinski - 0.9.7-4 +- Use modulesloaddir macro for installing scsi_dh.conf + +* Wed Nov 29 2023 Benjamin Marzinski - 0.9.7-3 +- Fix multipath_conf_syntax test +- Fix restate_module test + +* 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 + +* 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. + +* 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 + +* Wed Jul 19 2023 Fedora Release Engineering - 0.9.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* 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 + +* 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 + +* 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 + +* Thu Jan 19 2023 Fedora Release Engineering - 0.9.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* 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 + +* 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 Jul 21 2022 Fedora Release Engineering - 0.9.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* 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 + +* 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 + +* 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 + +* Wed Jan 26 2022 Benjamin Marzinski - 0.8.7-7 +- Add 0035-libmultipath-use-asprintf-to-allocate-prefixed_uuid.patch +- Resolves: bz #2045309 + +* Thu Jan 20 2022 Fedora Release Engineering - 0.8.7-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* 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 + +* 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 + +* 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 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 + +* 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 + +* 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 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 diff --git a/plans/multipath.fmf b/plans/multipath.fmf new file mode 100644 index 0000000..876c77a --- /dev/null +++ b/plans/multipath.fmf @@ -0,0 +1,58 @@ +summary: basic functionality tests + +provision: + hardware: + memory: ">= 2 GB" + +prepare: + how: install + package: + - device-mapper-multipath + - perl + +discover: + how: shell + tests: + - name: medium_error_scsi_debug + path: /tests/medium_error_scsi_debug + test: ./main.sh + duration: 15m + - name: squelch_scsi_id + path: /tests/squelch_scsi_id + test: ./main.sh + duration: 15m + - name: multipathd_oom + path: /tests/multipathd_oom + test: ./main.sh + duration: 15m + - name: user_friendly_names + path: /tests/user_friendly_names + test: ./main.sh + duration: 15m + - name: kpartx_4k_aligned + path: /tests/kpartx_4k_aligned + test: ./main.sh + duration: 15m + - name: bindings + path: /tests/bindings + test: ./main.sh + duration: 15m + - name: restate_module + path: /tests/restate_module + test: ./main.sh + duration: 15m + - name: find_multipaths + path: /tests/find_multipaths + test: ./main.sh + duration: 15m + - name: multipath_conf_syntax + path: /tests/multipath_conf_syntax + test: ./main.sh + duration: 15m + - name: alias_clash + path: /tests/alias_clash + test: ./main.sh + duration: 15m + +execute: + how: tmt diff --git a/sources b/sources index 1e028ad..233c4ea 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-0.8.4.tgz) = 130308e61d6dce31085fc2763219f4df0f3ad9153e0e6e7a5a1c3c948a2305cff9413699025c28f9b81dd24d2a9263f9fa825253060e44232c3bb6600cd1f07f +SHA512 (multipath-tools-0.13.0.tgz) = 75c84524ee27590b8b751ea500898a44e5ac3d58d55be6bcab919d0d423049db3a4466fcb9135705cf63ba074416973bb651255063269e9f682f11d21ba57e59 SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942 diff --git a/tests/alias_clash/LICENSE b/tests/alias_clash/LICENSE new file mode 100644 index 0000000..10926e8 --- /dev/null +++ b/tests/alias_clash/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/tests/alias_clash/PURPOSE b/tests/alias_clash/PURPOSE new file mode 100644 index 0000000..ba496c4 --- /dev/null +++ b/tests/alias_clash/PURPOSE @@ -0,0 +1,20 @@ +verify that multipath doesn't try to assign new devices in-use user_friendly +aliases. + +steps: +1. setup config file and remove existing bindings file +2. create scsi_debug devices +3. start multipathd to create devices and bindings file +4. look at path device ordering in multipathd output +5. stop multipathd and remove devices +6. blacklist the devices which were multipathed early in the config file +7. remove the bindings file +8. restart multipathd to create devices, where the later devices grab the + earlier user_friendly_names +9. stop multipathd +10. remove blacklists from the config file and remove bindings file +11. restart multipathd +12. Verify that all devices are there, the previously existing devices + still have the same alias, and all the devices match the bindings file +13. reconfigure multipathd +14. Verify that all devices are still there and still match. diff --git a/tests/alias_clash/main.sh b/tests/alias_clash/main.sh new file mode 100755 index 0000000..6e3b23c --- /dev/null +++ b/tests/alias_clash/main.sh @@ -0,0 +1,122 @@ +#!/bin/bash + +# Copyright (c) 2021 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Author: Benjamin Marzinski + +source ../include/ec.sh || exit 200 +tlog "running $0" + +cleanup () +{ + trun "multipathd disablequeueing maps" + sleep 5 + trun "multipath -DF" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "modprobe -r scsi_debug" +} + +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +tlog "running $0" + +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath + +# cleanup existing devices and restart +cleanup +trun "rm -f /etc/multipath.conf" +trun "rm -f /etc/multipath.conf.bak" +trun "rm -r /etc/multipath/bindings" +trun "mpathconf --enable --with_module y --with_multipathd n --find_multipaths n" +sed -i '/^blacklist[[:space:]]*{/ a\ + device {\n vendor ".*"\n product ".*"\n } +' /etc/multipath.conf +if grep -qw blacklist_exceptions /etc/multipath.conf ; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + device {\n vendor Linux\n product scsi_debug\n } +' /etc/multipath.conf +else + cat << _EOF_ >> /etc/multipath.conf +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ +fi +trun "modprobe scsi_debug num_tgts=20 vpd_use_hostno=0" +sleep 5 +trun "service multipathd start" +sleep 5 +pathcount=`multipathd show paths raw format %w | wc -l` +assert "[[ $pathcount -eq 20 ]]" +wwids=`multipathd show paths raw format " wwid %w" | sed '11,$d'` +wwids="${wwids//$'\n'/\\n}" +trun "multipath -DF" +trun "service multipathd stop" +sleep 5 +tnot "pidof multipathd" +tok "cp /etc/multipath.conf /etc/mulitpath.conf.bak" +sed -i '/^blacklist[[:space:]]*{/ a\ +'"$wwids"' +' /etc/multipath.conf +tok "rm -f /etc/multipath/bindings" +trun "service multipathd start" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 10 ]]" +orig_maps=`multipathd show maps raw format "%n %w"` +trun "service multipathd stop" +sleep 5 +tnot "pidof multipathd" +tok "mv -f /etc/mulitpath.conf.bak /etc/multipath.conf" +tok "rm -f /etc/multipath/bindings" +trun "service multipathd start" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 20 ]]" +new_maps=`multipathd show maps raw format "%n %w" | sort` +tlog "Checking if devices have been renamed" +while IFS= read -r line; do + echo "$new_maps" | grep "$line" + assert "[[ $? -eq 0 ]]" +done <<< "$orig_maps" +bindings=`cat /etc/multipath/bindings | sed '/^#.*$/d' | sort` +tlog "Checking if devices match bindings" +assert "[[ \"$new_maps\" = \"$bindings\" ]]" +trun "service multipathd reload" +sleep 5 +mapcount=`multipathd show maps raw format %w | wc -l` +assert "[[ $mapcount -eq 20 ]]" +reload_maps=`multipathd show maps raw format "%n %w" | sort` +tlog "Checking if devices change on reconfigure" +assert "[[ \"$new_maps\" = \"$reload_maps\" ]]" +cleanup +tend diff --git a/tests/bindings/main.sh b/tests/bindings/main.sh index 2d6f284..76292e4 100755 --- a/tests/bindings/main.sh +++ b/tests/bindings/main.sh @@ -18,40 +18,110 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "service multipathd stop" -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" -trun "service multipathd status" -sleep 5 +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -trun "multipath -F" -sleep 5 -terr "modprobe -r scsi_debug" -terr "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -sleep 60 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -disk_path=$(get_scsi_debug_devices) -disk=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk) +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf + +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + tok "multipathd reconfigure" + sleep 5 +} + +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done + +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ -n $mpath_name ]] && [[ $mpath_name != ok ]]" new_alias="mpath_test_$$" trun "sed -i 's/$mpath_name/$new_alias/' /etc/multipath/bindings" -trun "multipath -r" -sleep 5 -tok "[[ -b /dev/mapper/$new_alias ]]" -tok is_mpath $new_alias -sleep 5 +do_reconfigure +trun 'multipathd show maps raw format "%n"' +mpath_name=`multipathd show maps raw format "%n" | head -1` +assert "[[ $mpath_name = $new_alias ]]" -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" -trun "service multipathd stop" -sleep 3 -trun "multipath -W" -trun "rm /etc/multipath/bindings" +cleanup tend diff --git a/tests/find_multipaths/Makefile b/tests/find_multipaths/Makefile deleted file mode 100644 index b78dc57..0000000 --- a/tests/find_multipaths/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2016 Red Hat, Inc. -# # -# # This program is free software: you can redistribute it and/or modify -# # it under the terms of the GNU General Public License as published by -# # the Free Software Foundation, either version 3 of the License, or -# # (at your option) any later version. -# # -# # This program is distributed in the hope that it will be useful, -# # but WITHOUT ANY WARRANTY; without even the implied warranty of -# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# # GNU General Public License for more details. -# # -# # You should have received a copy of the GNU General Public License -# # along with this program. If not, see . -# -# # Author: Lin Li - -.PHONY: all install download clean - -BUILT_FILES= - -FILES=$(METADATA) Makefile PURPOSE main.sh - -run: $(FILES) build - ./main.sh - -build: $(BUILT_FILES) - chmod a+x ./main.sh - -clean: - rm -f *~ *.rpm $(BUILT_FILES) - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @touch $(METADATA) - @echo "Owner: LiLin " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "License: GPLv3" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Description: find_multipaths" >> $(METADATA) - @echo "TestTime: 15m" >> $(METADATA) - @echo "RunFor: device-mapper-multipath" >> $(METADATA) - @echo "Requires: device-mapper-multipath" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/find_multipaths/main.sh b/tests/find_multipaths/main.sh index ed51e10..28c325c 100755 --- a/tests/find_multipaths/main.sh +++ b/tests/find_multipaths/main.sh @@ -18,77 +18,162 @@ # Author: Lin Li #set -x -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -# which not set find_multipaths yes, so multipath always create a multipath device for single device -# so stop service and reconfig with --find_multipaths y, and reload/start the service again. -trun "service multipathd stop" -rpm -q device-mapper-multipath || yum install -y device-mapper-multipath +remove_devices () +{ + local retries + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + cleanup + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -F" + sleep 2 + done +} -# test with find_multipath=y, will not multipath for the single device; reload/start the service to enable the config -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd y" -trun "service multipathd status" -# use scsi_debug to simulate a drive -trun "multipath -F" -terr "modprobe -r scsi_debug" +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove devices" + tend + fi + tlog "removing multipath devices" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" + trun "rm -f /etc/multipath/wwids" + trun "rm -r /etc/multipath/bindings" +} + +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y --find_multipaths y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf + +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} + +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} + +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config + +# test with find_multipath=y, will not multipath the single device trun "modprobe scsi_debug" -sleep 3 +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices + +# test with find_multipath=n, will multipath the single device +trun 'mpathconf --find_multipaths n' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# test with find_multipath=y, with multipath single device with known WWID +trun 'mpathconf --find_multipaths y' +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" +remove_devices + +# Clear WWID, test with find_multipath=y, will not multipath single device trun "multipath -W" -cat /etc/multipath/wwids -trun "multipath" -disk_path=$(get_scsi_debug_devices) -disk_node=$(basename $disk_path) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ -z $mpath_name ]]' - -# test with find_multipath=n, will multipath for the single device -trun "mpathconf --enable --user_friendly_names y --find_multipaths n --with_multipathd y" -sleep 5 -trun "multipath" -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" - -# flush new created path -sleep 3 -trun "multipath -F" -sleep 3 - -# test with find_multipath=y, A path has the same WWID as a multipath device that was previously created -trun "mpathconf --enable --user_friendly_names y --find_multipaths y --with_multipathd y" -sleep 5 -trun "multipath" -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" - -# Clear wwid, test with find_multipath=y, will not multipath for the single device -trun "multipath -W" -trun "mpathconf --disable --with_multipathd y" -sleep 5 -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok '[[ -z $mpath_name ]]' - -trun "multipath -F" -sleep 5 -trun "modprobe -r scsi_debug" +do_reconfigure +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ $mpath_name = '[orphan]' ]]" +remove_devices +assert 'rmmod scsi_debug' # test find_multipaths=y create device for paths have same wwid -tok "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1" -sleep 10 -disk_paths=$(get_scsi_debug_devices) -disk_node=$(basename $disk_paths) -mpath_name=$(get_mpath_disk_by_scsi_device $disk_node) -tok "is_mpath $mpath_name" - -sleep 10 - -trun "multipath -F" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" sleep 5 -trun "modprobe -r scsi_debug" -# remove the scsi_debug wwid -trun "service multipathd stop" -sleep 3 -trun "multipath -W" -cat /etc/multipath/wwids +trun 'multipathd show paths raw format "%d %m"' +trun 'cat /etc/multipath/wwids' +mpath_name=`multipathd show paths raw format "%m" | head -1` +tok "[[ -n $mpath_name ]] && [[ $mpath_name != '[orphan]' ]]" + +cleanup tend diff --git a/tests/include/ec.sh b/tests/include/ec.sh index 22dfc40..4b0aba9 100755 --- a/tests/include/ec.sh +++ b/tests/include/ec.sh @@ -44,9 +44,12 @@ function _init (){ } function _destroy (){ - sleep 10 - Cmd "multipath -F" + Cmd "multipathd disablequeueing maps" sleep 5 + Cmd "multipath -DF -R2" + Cmd "service multipathd stop" + sleep 5 + Cmd "udevadm settle" Cmd "modprobe -r scsi_debug" } @@ -174,10 +177,7 @@ AA fi #setup scsi_debug echo "INFO: Loading scsi_debug module for simulation of mpath" - modprobe scsi_debug \ - num_tgts=1 vpd_use_hostno=0 \ - add_host=4 delay=20 \ - max_luns=2 no_lun_0=1 2>&1 1>/dev/null + modprobe scsi_debug vpd_use_hostno=0 add_host=2 echo "INFO: Waiting for udev to create /dev/sdX" sleep 15s #wait for udev to create /dev/sdX @@ -189,8 +189,6 @@ AA #enable multipath for scsi_debug. cat << AA > /etc/multipath.conf defaults { -#Enable multibus is for mutlbus testing - path_grouping_policy multibus user_friendly_names yes } blacklist { diff --git a/tests/include/mpath.sh b/tests/include/mpath.sh index 806225e..b894c27 100644 --- a/tests/include/mpath.sh +++ b/tests/include/mpath.sh @@ -78,8 +78,7 @@ get_mpath_disk_by_scsi_device() { # multipathd_running || texit "multipathd is not running" local disk=$1 - wwid=$(get_wwid_of_disk $disk) - local mpath=$(multipathd show maps format %w,%n | grep "^$wwid\s*," \ + local mpath=$(multipathd show paths raw format "%d,%m" | grep "^$disk\s*," \ | awk -F, '{ print $2 }' | sed 's/\s//g') echo $mpath } diff --git a/tests/medium_error_scsi_debug/main.sh b/tests/medium_error_scsi_debug/main.sh index db2f008..35c6e6f 100755 --- a/tests/medium_error_scsi_debug/main.sh +++ b/tests/medium_error_scsi_debug/main.sh @@ -16,47 +16,51 @@ # along with this program. If not, see . # Author: LiLin +source ../include/tc.sh || exit 200 -function cleanup() +cleanup() { sleep 5 udevadm settle - multipath -F + trun "multipath -DF" sleep 5 - modprobe -r scsi_debug - - return 0 + trun "modprobe -r scsi_debug" } -yum -y install device-mapper device-mapper-multipath -mpathconf --enable -service multipathd stop -modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 max_luns=2 no_lun_0=1 opts=2 +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} + +tlog "running $0" +rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath +trun "multipathd disablequeueing maps" +cleanup +trun "service multipathd stop" +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2 opts=2" sleep 5 -multipath > /dev/null +trun "multipath" sleep 5 +trun "multipath -l" mpathdev=`multipath -l | grep scsi_debug | awk '{print $1}' | head -1` -if [ -z "$mpathdev" ]; then - echo "------- FAIL, no multipath device created -----" - cleanup - exit 1 -fi +assert "[[ -n \"$mpathdev\" ]]" before_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "before active = ${before_active}" IO_error=`dd if=/dev/zero of=/dev/mapper/$mpathdev bs=1024 seek=2330 count=10 2>&1 | grep -o "Input/output error" ` -if [ -n "$IO_error" ];then - after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` - if [ "$before_active" -eq "$after_active" ]; then - echo "------- PASS, a medium error, correctly generated an I/O error and did not fail paths -----" - cleanup - exit 0 - else - echo "------- FAIL, paths failed -----" - cleanup - exit 1 - fi -else - echo "------- FAIL, did not generate an I/O error -----" - cleanup - exit 1 -fi +assert "[[ -n \"$IO_error\" ]]" +after_active=`multipath -l $mpathdev | grep "active undef" | wc -l` +tlog "after active = ${after_active}" +assert "[[ \"$before_active\" -eq \"$after_active\" ]]" +cleanup +tend diff --git a/tests/multipath_conf_syntax/main.sh b/tests/multipath_conf_syntax/main.sh index f29109d..fb303c3 100755 --- a/tests/multipath_conf_syntax/main.sh +++ b/tests/multipath_conf_syntax/main.sh @@ -17,96 +17,129 @@ # Author: Lin Li +source ../include/ec.sh || exit 200 +tlog "running $0" -# Include Beaker environment -. /usr/bin/rhts-environment.sh || exit 1 -. /usr/share/beakerlib/beakerlib.sh || exit 1 +cleanup () +{ + trun "multipathd disablequeueing maps" + sleep 5 + trun "multipath -F" + trun "service multipathd stop" + sleep 5 + trun "udevadm settle" + trun "modprobe -r scsi_debug" +} -PACKAGE="device-mapper-multipath" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -rlJournalStart - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun "multipath -F; sleep 5" - rlRun "modprobe -r scsi_debug" 0 "Remove if scsi_debug load before" - rlRun "rm -f /etc/multipath.conf" - rlRun "mpathconf --enable --with_module y --with_multipathd y --find_multipaths n" 0 "Set up multipath" - rlServiceStart multipathd - rlRun "cp /etc/multipath.conf /etc/multipath.conf.bak" 0 "Backup /etc/multipath.conf first" - rlPhaseEnd +rpm -q device-mapper-multipath || yum install -y device-mapper-multipath - rlPhaseStartTest - rlRun "modprobe scsi_debug" - sleep 5 - rlLogInfo "`multipath -ll`" - wwid=`multipathd show maps format %w | grep -v uuid` - # test missing closing quote on alias - cat << _EOF_ >> /etc/multipath.conf -multipaths { - multipath { - wwid "$wwid" - alias "mypath - } +# cleanup existing devices and restart +cleanup +trun "rm -f /etc/multipath.conf" +trun "mpathconf --enable --with_module y --with_multipathd n --find_multipaths n" +sed -i '/^blacklist[[:space:]]*{/ a\ + device {\n vendor ".*"\n product ".*"\n } +' /etc/multipath.conf +if grep -qw blacklist_exceptions /etc/multipath.conf ; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + device {\n vendor Linux\n product scsi_debug\n } +' /etc/multipath.conf +else + cat << _EOF_ >> /etc/multipath.conf +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } } _EOF_ - rlRun "multipath 2>&1 | grep 'missing closing quotes on line'" 0 "test missing closing quote on alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +fi - # test no value for alias - rlRun "sed -i 's/alias.*$/alias/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep \"missing value for option 'alias' on line\"" 0 "test no value for alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" +trun "cp /etc/multipath.conf /etc/multipath.conf.bak" +trun "service multipathd stop" +trun "service multipathd start" - # test missing starting quote on alias - rlRun "sed -i 's/alias.*$/alias mypath\"/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test missing starting quote on alias" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +trun "modprobe scsi_debug" +sleep 5 +trun "multipath -ll" +pathcount=`multipathd show maps format %w | grep -v uuid | wc -l` +assert "[[ $pathcount -eq 1 ]]" +wwid=`multipathd show maps format %w | grep -v uuid` - # test wrong quote on alias - rlRun "sed -i 's/alias.*$/alias /g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r" - rlRun "multipath -ll |grep ''" 0 "check if mpath rename to successfully" +# test missing closing quote on alias +cat << _EOF_ >> /etc/multipath.conf +multipaths { + multipath { + wwid "$wwid" + alias "mypath + } +} +_EOF_ +tok "multipath 2>&1 | grep 'missing closing quotes on line'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - # test value has a space - rlRun "sed -i 's/alias.*$/alias mypath test/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'ignoring extra data starting with'" 0 "test value has a space" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +# test no value for alias +trun "sed -i 's/alias.*$/alias/g' /etc/multipath.conf" +multipath +tok "multipath 2>&1 | grep \"missing value for option 'alias' on line\"" +trun "multipath -r" +tok "multipath -ll | grep mpath" - # test wrong alias keyword - rlRun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" - rlRun "multipath 2>&1 |grep 'invalid keyword: alia'" 0 "invalid keyword: alia" - rlRun "multipath -r" - rlRun "multipath -ll |grep mpath*" 0 "check if mpath rename to mpath* from mypath successfully" - rlRun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" +# test missing starting quote on alias +trun "sed -i 's/alias.*$/alias mypath\"/g' /etc/multipath.conf" +tok "multipath 2>&1 |grep 'ignoring extra data starting with'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - # test no space between the section name and the open bracket that followed it - # fix issue about if a section doesn't have a space between the section name and the open bracket, that section isn't read in. - rlRun "sed -i 's/multipaths.*/multipaths{/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep config" 1 "no warning" - rlRun "multipath -r" - rlRun "multipath -ll |grep mypath" 0 "check if mpath rename to mypath successfully" +# test wrong quote on alias +trun "sed -i 's/alias.*$/alias /g' /etc/multipath.conf" +tnot "multipath 2>&1 | grep config" +trun "multipath -r" +tok "multipath -ll | grep ''" - # test wrong section keywords - rlRun "sed -i 's/multipaths.*/ultipaths {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: ultipaths'" 0 "test wrong multipaths section keyword" - rlRun "sed -i 's/defaults.*/efaults {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: efaults'" 0 "test wrong defaults section keyword" - rlRun "sed -i 's/blacklist {/lacklist {/g' /etc/multipath.conf" - rlRun "multipath 2>&1 | grep 'invalid keyword: lacklist'" 0 "test wrong blacklist section keyword" +# test value has a space +trun "sed -i 's/alias.*$/alias mypath test/g' /etc/multipath.conf" +tok "multipath 2>&1 |grep 'ignoring extra data starting with'" +trun "multipath -r" +tok "multipath -ll | grep mypath" - rlPhaseEnd +# test wrong alias keyword +trun "sed -i 's/alias.*$/alia mypath/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword in the multipath section: alia'" +trun "multipath -r" +tok "multipath -ll | grep mpath" +trun "sed -i 's/alia.*$/alias mypath/g' /etc/multipath.conf" - rlPhaseStartCleanup - rlRun "udevadm settle" - rlRun "multipath -F" 0 "Flush all unused multipath device maps" - rlServiceStop multipathd - rlRun "modprobe -r scsi_debug" 0 "Remove scsi_debug" - rlRun "cp -f /etc/multipath.conf.bak /etc/multipath.conf" 0 "Recovery /etc/multipath.conf" - rlPhaseEnd -rlJournalPrintText -rlJournalEnd +# test no space between the section name and the open bracket that followed it +# fix issue about if a section doesn't have a space between the section name +# and the open bracket, that section isn't read in. +trun "sed -i 's/multipaths.*/multipaths{/g' /etc/multipath.conf" +tnot "multipath 2>&1 | grep config" +trun "multipath -r" +tok "multipath -ll |grep mypath" + +# test wrong section keywords +trun "sed -i 's/multipaths.*/ultipaths {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: ultipaths'" +trun "sed -i 's/defaults.*/efaults {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: efaults'" +trun "sed -i 's/blacklist {/lacklist {/g' /etc/multipath.conf" +tok "multipath 2>&1 | grep 'invalid keyword: lacklist'" +trun "mv /etc/multipath.conf.bak /etc/multipath.conf" + +cleanup +tend diff --git a/tests/provision.fmf b/tests/provision.fmf deleted file mode 100644 index 62a6eba..0000000 --- a/tests/provision.fmf +++ /dev/null @@ -1,5 +0,0 @@ ---- - -standard-inventory-qcow2: - qemu: - m: 2G diff --git a/tests/restate_module/main.sh b/tests/restate_module/main.sh index 6d5b0c5..be60eba 100755 --- a/tests/restate_module/main.sh +++ b/tests/restate_module/main.sh @@ -48,10 +48,8 @@ rpm -q device-mapper-multipath || yum install -y device-mapper-multipath tlog "device-mapper-multipath is installed" # cleanup existing devices trun "rm /etc/multipath.conf" -trun "mpathconf --enable --with_module y" -sed -i '/^defaults[[:space:]]*{/ a\ - max_polling_interval 10 -' /etc/multipath.conf +trun "mpathconf --enable --with_module y --option max_polling_interval:10" +trun "mpathconf --option detect_pgpolicy_use_tpg:yes" trun "service multipathd stop" trun "multipath -F" sleep 5 @@ -69,7 +67,7 @@ tlog "Checking if active path count equals 2" assert "[[ $pathcount -eq 2 ]]" tlog "offline one path device" -pathname=`multipathd show paths raw format "%d %m" | grep ${mpathdev} | head -1 | awk '{print $1}'` +pathname=`multipathd show paths raw format "%d %m %p" | grep ${mpathdev} | sort -k 3n | head -1 | awk '{print $1}'` tlog "path to offline: ${pathname}" trun "echo 'offline' > /sys/block/${pathname}/device/state" tlog "waiting for multipathd to fail path" @@ -93,4 +91,5 @@ path_state=`multipathd show paths raw format "%d %t %T %o" | grep ${pathname} | tlog "Checking state of ${pathname}" assert "[[ $path_state -eq 1 ]]" +cleanup tend diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 4c396d2..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -# No tests suitable for atomic environment -# No tests suitable for container environment - -# Tests suitable for classic environment -- hosts: localhost - roles: - - role: standard-test-basic - tags: - - classic - tests: - - medium_error_scsi_debug: - run: ./main.sh - timeout: 15m - - squelch_scsi_id: - run: ./main.sh - timeout: 15m - - multipathd_oom: - run: ./main.sh - timeout: 15m - - user_friendly_names: - run: ./main.sh - timeout: 15m - - kpartx_4k_aligned: - run: ./main.sh - timeout: 15m - - bindings: - run: ./main.sh - timeout: 15m - required_packages: - - device-mapper-multipath - - perl - - - role: standard-test-beakerlib - tags: - - classic - tests: - - multipath_conf_syntax: - timeout: 15m - required_packages: - - device-mapper-multipath - - perl diff --git a/tests/user_friendly_names/main.sh b/tests/user_friendly_names/main.sh index 56082fd..1d48801 100755 --- a/tests/user_friendly_names/main.sh +++ b/tests/user_friendly_names/main.sh @@ -17,50 +17,125 @@ # Author: Lin Li -source ../include/ec.sh || exit 200 - +source ../include/tc.sh || exit 200 tlog "running $0" -trun "rpm -q device-mapper-multipath || yum install -y device-mapper-multipath" -trun "mpathconf --enable --with_multipathd y --user_friendly_names y" +cleanup () +{ + local retries + if pidof multipathd; then + tlog "stopping multipathd" + trun "systemctl stop multipathd.service || pkill multipathd" + sleep 1 + fi + retries=10 + while pidof multipathd; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to stop multipath" + tend + fi + tlog "waiting for multipathd to stop" + sleep 2 + pidof multipathd && pkill multipathd + done + trun "multipath -l -v1" + retries=10 + while [[ -n `multipath -l -v1` ]]; do + ((retries--)) + if [[ $retries -le 0 ]]; then + tfail_ "failed to remove deviece" + tend + fi + tlog "removing multipath device" + trun "udevadm settle" + trun "multipath -DF" + sleep 2 + done + if lsmod | grep -q "^scsi_debug"; then + tlog "removing scsi_debug module" + tok "rmmod scsi_debug" + fi + trun "rm -f /etc/multipath.conf" +} -# backup the /etc/multipath.conf -trun "cp /etc/multipath.conf /etc/multipath.conf.$$" -trun "multipath -F" +assert () +{ + local cmd="$*" + _trun_ "$cmd" 0 + if test $? -eq 0; then + tpass_ "$cmd" ; + else + tfail_ "$cmd" ; + cleanup ; + tend ; + fi +} -trun "modprobe scsi_debug num_tgts=1 vpd_use_hostno=0 add_host=2 delay=20 \ -max_luns=2 no_lun_0=1" -trun "multipath" -# wwid shown slowly on s390x by the script framework, but normally when run by multipath command directly -# so extend sleep time -sleep 20 +setup_config () +{ + trun "mpathconf --enable --user_friendly_names y" + sed -i '/^blacklist[[:space:]]*{/ a\ + device {\ + vendor ".*"\ + product ".*"\ + } +' /etc/multipath.conf + cat << _EOF_ >> /etc/multipath.conf -disk=$(get_scsi_debug_devices) -disk=$(basename $disk) -wwid=$(get_wwid_of_disk $disk) -mpath=$(get_mpath_disk_by_scsi_device $disk) +blacklist_exceptions { + device { + vendor Linux + product scsi_debug + } +} -# user_friendly_names = yes and mpath=test -#cur_dir=/mnt/tests/kernel/storage/multipath/user_friendly_names/ -#cur_dir=/home/test/scratch/device-mapper-multipath/user_friendly_names -trun "cat multipath.conf.yes | sed "s/your_wwid/$wwid/g" > /etc/multipath.conf" -trun "cat -n /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test ($wwid)' is present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^test\"" +multipaths { + multipath { + wwid TEST_WWID + alias test + } +} +_EOF_ + trun "cat /etc/multipath.conf" +} -# user_friendly_names = no -trun "cat multipath.conf.no > /etc/multipath.conf" -trun "multipath -r" -echo ">>> Verify 'test' is gone but '$wwid' present ..." -trun "multipath -ll" -tok "multipath -ll | egrep \"^$wwid\"" -sleep 10 -tok "multipath -F $wwid" -sleep 10 -trun "modprobe -r scsi_debug" +do_reconfigure () +{ + trun "cat /etc/multipath.conf" + tok "multipathd reconfigure" + sleep 5 +} -trun "cp /etc/multipath.conf.$$ /etc/multipath.conf" -trun "multipath -F; multipath" +trun "rpm -q device-mapper-multipath || dnf install -y device-mapper-multipath" +cleanup +setup_config +trun "rm -r /etc/multipath/bindings" +trun "modprobe scsi_debug vpd_use_hostno=0 add_host=2" +sleep 5 +trun "systemctl start multipathd.service" +while multipathd show daemon | grep -qv idle; do + tlog "waiting for multipathd to start" + sleep 1 +done +trun 'multipathd show maps raw format "%n %w"' +# verify user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q mpath' +wwid=`multipathd show maps raw format "%w" | head -1` +assert "[[ -n $wwid ]] && [[ $wwid != ok ]]" +sed -i 's/TEST_WWID/'"$wwid"'/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over user_friendly_name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +trun "mpathconf --user_friendly_names n" +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +# verify configured alias takes precedence over wwid name +tok 'multipathd show maps raw format "%n" | head -1 | grep -q test' +sed -i 's/'"$wwid"'/TEST_WWID/' /etc/multipath.conf +do_reconfigure +trun 'multipathd show maps raw format "%n %w"' +tok 'multipathd show maps raw format "%n" | head -1 | grep -q '"$wwid" +cleanup tend diff --git a/tests/user_friendly_names/multipath.conf.no b/tests/user_friendly_names/multipath.conf.no deleted file mode 100644 index b916bfb..0000000 --- a/tests/user_friendly_names/multipath.conf.no +++ /dev/null @@ -1,3 +0,0 @@ -defaults { - user_friendly_names no -} diff --git a/tests/user_friendly_names/multipath.conf.yes b/tests/user_friendly_names/multipath.conf.yes deleted file mode 100644 index ffc21bb..0000000 --- a/tests/user_friendly_names/multipath.conf.yes +++ /dev/null @@ -1,11 +0,0 @@ -defaults { - user_friendly_names yes -} - -multipaths { - multipath { - wwid your_wwid - alias test - } -} -