commit b785613d511f79568ed75975c57b047adeb2bb8e Author: CentOS Sources Date: Tue May 17 06:27:14 2022 -0400 import device-mapper-multipath-0.8.7-7.el9 diff --git a/.device-mapper-multipath.metadata b/.device-mapper-multipath.metadata new file mode 100644 index 0000000..dc57af5 --- /dev/null +++ b/.device-mapper-multipath.metadata @@ -0,0 +1 @@ +067d668de8e3a70b7c176bbf0c0616d5835bbe44 SOURCES/multipath-tools-0.8.7.tgz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2b966c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/multipath-tools-0.8.7.tgz diff --git a/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch b/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch new file mode 100644 index 0000000..559d5a5 --- /dev/null +++ b/SOURCES/0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Wed, 8 Sep 2021 22:33:54 +0200 +Subject: [PATCH] multipath-tools: add info about IO affinity path selector to + manpage + +Added in 5.11: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e4d2e82b2300b03f66b3ca8417590c86e661fab1 + +Cc: Mike Christie +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez + +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index d6b8c7f6..42a15ffd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -6,7 +6,7 @@ + .\" + .\" ---------------------------------------------------------------------------- + . +-.TH MULTIPATH.CONF 5 2018-05-21 Linux ++.TH MULTIPATH.CONF 5 2021-09-08 Linux + . + . + .\" ---------------------------------------------------------------------------- +@@ -210,6 +210,10 @@ of outstanding I/O to the path and its relative throughput. + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP ++.I "io-affinity 0" ++(Since 5.11 kernel) Choose the path for the next bunch of I/O based on a CPU to ++path mapping the user passes in and what CPU we are executing on. ++.TP + The default is: \fBservice-time 0\fR + .RE + . diff --git a/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch b/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch new file mode 100644 index 0000000..5312160 --- /dev/null +++ b/SOURCES/0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: lixiaokeng +Date: Mon, 13 Sep 2021 10:43:14 +0800 +Subject: [PATCH] multipathd: fix missing persistent reseravtion for active + path + +There are two paths(sucu as sda and adb) for one LUN. The two +paths log in, but before the two uevents have been processed +(for example there are many uevent), users use multipathd add +path /dev/sda to cause mpatha and use mpathpersist -o -I to +register prkey for mpatha. The add map uevent is after add path +uevent, the the uevent(add sdb) will delay and missing persistent +reseravtion check. + +Here, we add persistent reseravtion check in update_map() which +is called ev_add_map(). + +Signed-off-by: Lixiaokeng +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3aff241d..1defeaf1 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -490,6 +490,8 @@ update_map (struct multipath *mpp, struct vectors *vecs, int new_map) + { + int retries = 3; + char *params __attribute__((cleanup(cleanup_charp))) = NULL; ++ struct path *pp; ++ int i; + + retry: + condlog(4, "%s: updating new map", mpp->alias); +@@ -502,6 +504,15 @@ retry: + verify_paths(mpp); + mpp->action = ACT_RELOAD; + ++ if (mpp->prflag) { ++ vector_foreach_slot(mpp->paths, pp, i) { ++ if ((pp->state == PATH_UP) || (pp->state == PATH_GHOST)) { ++ /* persistent reseravtion check*/ ++ mpath_pr_event_handle(pp); ++ } ++ } ++ } ++ + if (setup_map(mpp, ¶ms, vecs)) { + condlog(0, "%s: failed to setup new map in update", mpp->alias); + retries = -1; diff --git a/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch b/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch new file mode 100644 index 0000000..ddad7b0 --- /dev/null +++ b/SOURCES/0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Thu, 16 Sep 2021 00:44:49 +0200 +Subject: [PATCH] multipath-tools: minor fixes to multipath.conf.5 man page + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 42a15ffd..c74129bd 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1,9 +1,9 @@ + .\" ---------------------------------------------------------------------------- +-.\" Update the date below if you make any significant change. + .\" Make sure there are no errors with: + .\" groff -z -wall -b -e -t multipath/multipath.conf.5 + .\" man --warnings -E UTF-8 -l -Tutf8 -Z multipath/multipath.conf.5 >/dev/null + .\" ++.\" Update the date below if you make any significant change. + .\" ---------------------------------------------------------------------------- + . + .TH MULTIPATH.CONF 5 2021-09-08 Linux +@@ -189,7 +189,7 @@ The default is: \fB\fR + .TP + .B path_selector + The default path selector algorithm to use; they are offered by the +-kernel multipath target. There are three selector algorithms: ++kernel multipath target: + .RS + .TP 12 + .I "round-robin 0" +@@ -206,7 +206,7 @@ of outstanding I/O to the path. + of outstanding I/O to the path and its relative throughput. + .TP + .I "historical-service-time 0" +-(Since 5.8 kernel) Choose the path for the next bunch of IOs based on the ++(Since 5.8 kernel) Choose the path for the next bunch of I/O based on the + estimation of future service time based on the history of previous I/O submitted + to each path. + .TP diff --git a/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch b/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch new file mode 100644 index 0000000..da06d58 --- /dev/null +++ b/SOURCES/0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Sat, 25 Sep 2021 00:27:36 +0200 +Subject: [PATCH] multipath-tools: make IBM/XIV config work with alua and + multibus + +And add recommended pgfailback value. + +ALUA is supported since XIV_Gen2 and microcode 10.2.1 +(All ports across all controllers in single Target Port Group) + +https://www.ibm.com/support/pages/ibm-flashsystem%C2%AE-a9000-and-a9000r-hyperswap-solution-deployment-linux%C2%AE-ibm-z-systems%C2%AE +https://www.google.com/search?q=%222810XIV%22+%22path_grouping_policy%22+site%3Aibm.com + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 0caac0da..72f81c60 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -712,7 +712,8 @@ static struct hwentry default_hw[] = { + .vendor = "(XIV|IBM)", + .product = "(NEXTRA|2810XIV)", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = 15, + }, + { + /* TMS RamSan / FlashSystem 710/720/810/820/840/900 */ diff --git a/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch b/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch new file mode 100644 index 0000000..e6b34a2 --- /dev/null +++ b/SOURCES/0005-multipathd.socket-add-missing-conditions-from-servic.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Luca BRUNO +Date: Fri, 24 Sep 2021 09:34:01 +0000 +Subject: [PATCH] multipathd.socket: add missing conditions from service unit + +This aligns 'multipathd' socket and service units, by adding the +start conditions that are set on the service but not on the socket. +It should help avoiding situations where the socket unit ends up +marked as failed after hitting its retry-limit. + +Fixes: https://github.com/opensvc/multipath-tools/issues/15 +Signed-off-by: Luca BRUNO +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + multipathd/multipathd.socket | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index 0ed4a1f7..c777e5e3 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,9 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionKernelCommandLine=!nompath ++ConditionKernelCommandLine=!multipath=off ++ConditionVirtualization=!container + Before=sockets.target + + [Socket] diff --git a/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch b/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch new file mode 100644 index 0000000..97cc8ef --- /dev/null +++ b/SOURCES/0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 18:52:10 +0200 +Subject: [PATCH] multipath-tools: make IBM/2107900 (DS8000) config work with + alua and multibus + +ALUA is supported since the beginning: +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/device_handler/scsi_dh_alua.c?id=057ea7c9683c3d684128cced796f03c179ecf1c2#n683 + +... the DS8000 is an Asymmetric Logical Unit Access (ALUA) capable storage array, +pag#160(144): https://www.redbooks.ibm.com/redbooks/pdfs/sg248887.pdf + +kernel log: +https://marc.info/?l=linux-scsi&m=156407413807511&q=mbox + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 72f81c60..f115c4f9 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -656,7 +656,8 @@ static struct hwentry default_hw[] = { + .vendor = "IBM", + .product = "^2107900", + .no_path_retry = NO_PATH_RETRY_QUEUE, +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + // Storwize V5000 and V7000 lines / SAN Volume Controller (SVC) / Flex System V7000 / diff --git a/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch b/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch new file mode 100644 index 0000000..201232a --- /dev/null +++ b/SOURCES/0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:20:59 +0200 +Subject: [PATCH] multipath-tools: make EMC/SYMMETRIX config work with alua and + multibus + +ALUA is supported since VMAX3 and HYPERMAX OS 5977.811.784, pag#113: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index f115c4f9..7095aaf1 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,8 +329,9 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 6, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch b/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch new file mode 100644 index 0000000..723f023 --- /dev/null +++ b/SOURCES/0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 19:31:21 +0200 +Subject: [PATCH] multipath-tools: make EMC/Invista config work with alua and + multibus + +Optimal Path Management (OPM) was introduced with VPLEX 5.5 to improve VPLEX +performance. OPM uses the ALUA mechanism to spread the I/O load across VPLEX directors +while gaining cache locality, pag #187: +https://www.delltechnologies.com/en-us/collaterals/unauth/technical-guides-support-information/products/storage-2/docu5128.pdf + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7095aaf1..4e8b52ff 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,8 +350,9 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, + .no_path_retry = 5, ++ .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch b/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch new file mode 100644 index 0000000..e2a93ee --- /dev/null +++ b/SOURCES/0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:15:56 +0200 +Subject: [PATCH] multipath-tools: make "COMPELNT/Compellent Vol" config work + with alua and multibus + +ALUA is needed by SAS arrays, pag#124: +https://downloads.dell.com/manuals/all-products/esuprt_solutions_int/esuprt_solutions_int_solutions_resources/general-solution-resources_white-papers2_en-us.pdf + +Cc: Sean McGinnis +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 4e8b52ff..7fc5bc04 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -368,7 +368,8 @@ static struct hwentry default_hw[] = { + */ + .vendor = "COMPELNT", + .product = "Compellent Vol", +- .pgpolicy = MULTIBUS, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, + .no_path_retry = NO_PATH_RETRY_QUEUE, + }, + { diff --git a/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch b/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch new file mode 100644 index 0000000..f8e9cc0 --- /dev/null +++ b/SOURCES/0010-multipath-tools-remove-Compellent-maintainer.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Xose Vazquez Perez +Date: Tue, 28 Sep 2021 22:39:17 +0200 +Subject: [PATCH] multipath-tools: remove Compellent maintainer + +e-mail was bounced: 550 5.1.1 User Unknown + +Cc: Martin Wilck +Cc: Benjamin Marzinski +Cc: Christophe Varoqui +Cc: DM-DEVEL ML +Signed-off-by: Xose Vazquez Perez +Reviewed-by: Martin Wilck +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 7fc5bc04..763982cd 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -361,11 +361,7 @@ static struct hwentry default_hw[] = { + .pgpolicy = MULTIBUS, + }, + { +- /* +- * SC Series, formerly Compellent +- * +- * Maintainer: Sean McGinnis +- */ ++ /* SC Series, formerly Compellent */ + .vendor = "COMPELNT", + .product = "Compellent Vol", + .pgpolicy = GROUP_BY_PRIO, diff --git a/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch b/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch new file mode 100644 index 0000000..1912f80 --- /dev/null +++ b/SOURCES/0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:44:54 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/Invista config work with + alua and multibus" + +This reverts commit 309ff281aaa07e862540d3d645a8263f3e9baaed. + +Mail from , 20210930: + +"OPM is no longer supported in the Dell VPLEX product. If we at Dell had +wished to change the default device stanzas for any of our products they +would have been done when the product and/or feature is released. +Please remove this patch as well. It is not needed." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 763982cd..211087ad 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -350,9 +350,8 @@ static struct hwentry default_hw[] = { + .vendor = "EMC", + .product = "Invista", + .bl_product = "LUNZ", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 5, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* XtremIO */ diff --git a/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch b/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch new file mode 100644 index 0000000..b889ea8 --- /dev/null +++ b/SOURCES/0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Wed, 20 Oct 2021 20:46:09 +0200 +Subject: [PATCH] Revert "multipath-tools: make EMC/SYMMETRIX config work with + alua and multibus" + +This reverts commit 831af0dbfa171cd39d968ba6174669f11a278be9. + +Mail from "berthiaume, wayne" , 210930: + +"As a representative of Dell I request this patch be withdrawn. If we had +wanted the default stanza changed we would have already implemented it. +Also for your information we only advertise the entire enterprise storage +product line (DMX, VMAX, VMAX AFA, PowerMax) as SYMMETRIX in the VPD page. +The ALUA capability is only used for mobility devices in an SRDF/Metro +configuration and the current device stanza still works well in all of our +testing." + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/hwtable.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c +index 211087ad..a8ba28e3 100644 +--- a/libmultipath/hwtable.c ++++ b/libmultipath/hwtable.c +@@ -329,9 +329,8 @@ static struct hwentry default_hw[] = { + /* Symmetrix / DMX / VMAX / PowerMax */ + .vendor = "EMC", + .product = "SYMMETRIX", +- .pgpolicy = GROUP_BY_PRIO, ++ .pgpolicy = MULTIBUS, + .no_path_retry = 6, +- .pgfailback = -FAILBACK_IMMEDIATE, + }, + { + /* DGC CLARiiON CX/AX / VNX and Unity */ diff --git a/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..df4455e --- /dev/null +++ b/SOURCES/0013-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 13 Apr 2017 07:22:23 -0500 +Subject: [PATCH] RH: fixup udev rules for redhat + +The multipath rules need to run after scsi_id is run. This means moving +them after 60-persistent-storage.rules for redhat. Redhat also uses a +different naming scheme for partitions than SuSE. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 2 +- + kpartx/kpartx.rules | 2 +- + multipath/Makefile | 4 ++-- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index d0ec9b44..2a75dc9c 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -55,7 +55,7 @@ endif + prefix = + exec_prefix = $(prefix) + usr_prefix = $(prefix) +-bindir = $(exec_prefix)/sbin ++bindir = $(exec_prefix)/usr/sbin + libudevdir = $(prefix)/$(SYSTEMDPATH)/udev + udevrulesdir = $(libudevdir)/rules.d + multipathdir = $(TOPDIR)/libmultipath +diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules +index d7527d7d..0e0d70d5 100644 +--- a/kpartx/kpartx.rules ++++ b/kpartx/kpartx.rules +@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end" + GOTO="kpartx_end" + + LABEL="run_kpartx" +-RUN+="/sbin/kpartx -un -p -part /dev/$name" ++RUN+="/sbin/kpartx -un /dev/$name" + + LABEL="kpartx_end" +diff --git a/multipath/Makefile b/multipath/Makefile +index 0828a8f7..b9bbb3cf 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -24,7 +24,7 @@ install: + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) +- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) +@@ -33,7 +33,7 @@ install: + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules +- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules ++ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz + diff --git a/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch new file mode 100644 index 0000000..c1cdc10 --- /dev/null +++ b/SOURCES/0014-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -0,0 +1,101 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Jul 2014 12:49:53 -0500 +Subject: [PATCH] RH: Remove the property blacklist exception builtin + +Multipath set the default property blacklist exceptions to +(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal +devices. These devices may never have multiple paths, but it is nice +to be able to set multipath up on them all the same. This patch simply +removes the default, and makes it so that if no property +blacklist_exception is given, then devices aren't failed for not matching +it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/blacklist.c | 6 ++---- + multipath/multipath.conf.5 | 11 ++++++----- + tests/blacklist.c | 7 ++----- + 3 files changed, 10 insertions(+), 14 deletions(-) + +diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c +index 4e315c97..1e463ef6 100644 +--- a/libmultipath/blacklist.c ++++ b/libmultipath/blacklist.c +@@ -202,9 +202,6 @@ setup_default_blist (struct config * conf) + if (store_ble(conf->blist_devnode, "!^(sd[a-z]|dasd[a-z]|nvme[0-9])", ORIGIN_DEFAULT)) + return 1; + +- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT)) +- return 1; +- + vector_foreach_slot (conf->hwtable, hwe, i) { + if (hwe->bl_product) { + if (find_blacklist_device(conf->blist_device, +@@ -410,7 +407,8 @@ filter_property(const struct config *conf, struct udev_device *udev, + *uid_attribute != '\0'; + bool uid_attr_seen = false; + +- r = MATCH_PROPERTY_BLIST_MISSING; ++ if (VECTOR_SIZE(conf->elist_property)) ++ r = MATCH_PROPERTY_BLIST_MISSING; + udev_list_entry_foreach(list_entry, + udev_device_get_properties_list_entry(udev)) { + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index c74129bd..dd9f4dc7 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1351,9 +1351,14 @@ keywords. Both are regular expressions. For a full description of these keywords + Regular expression for an udev property. All + devices that have matching udev properties will be excluded/included. + The handling of the \fIproperty\fR keyword is special, +-because devices \fBmust\fR have at least one whitelisted udev property; ++because if a property blacklist_exception is set, devices \fBmust\fR have at ++least one whitelisted udev property; + otherwise they're treated as blacklisted, and the message + "\fIblacklisted, udev property missing\fR" is displayed in the logs. ++For example, setting the property blacklist_exception to ++\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices ++that provide a WWN (World Wide Number) to be included, and all others to be ++excluded. This works to exclude most non-multipathable devices. + . + .RS + .PP +@@ -1364,10 +1369,6 @@ Blacklisting by missing properties is only applied to devices which do have the + property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) + set. Previously, it was applied to every device, possibly causing devices to be + blacklisted because of temporary I/O error conditions. +-.PP +-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing +-well-behaved SCSI devices and devices that provide a WWN (World Wide Number) +-to be included, and all others to be excluded. + .RE + .TP + .B protocol +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 882aa3a1..6a22b660 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -375,9 +375,8 @@ static void test_property_missing(void **state) + { + static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", "ID_SERIAL", NULL } }; + conf.blist_property = blist_property_wwn; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), +- MATCH_PROPERTY_BLIST_MISSING); ++ MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), + MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, ""), +@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state) + conf.blist_device = blist_device_foo_bar; + conf.blist_protocol = blist_protocol_fcp; + conf.blist_wwid = blist_wwid_xyzzy; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); +- assert_int_equal(filter_path(&conf, &miss1_pp), +- MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING); + } + + /* This one matches the property whitelist, to test the other missing diff --git a/SOURCES/0015-RH-don-t-start-without-a-config-file.patch b/SOURCES/0015-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..8061a99 --- /dev/null +++ b/SOURCES/0015-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,107 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 15 Oct 2014 10:39:30 -0500 +Subject: [PATCH] RH: don't start without a config file + +If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist +all devices when running multipath. A completely blank configuration file +is almost never what users want. Also, people may have the multipath +packages installed but don't want to use them. This patch provides a +simple way to disable multipath. Simply removing or renaming +/etc/multipath.conf will keep multipath from doing anything. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 13 +++++++++++++ + libmultipath/config.h | 1 + + multipath/multipath.rules | 1 + + multipathd/multipathd.8 | 2 ++ + multipathd/multipathd.service | 1 + + multipathd/multipathd.socket | 1 + + 6 files changed, 19 insertions(+) + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 30046a17..5f35c3d3 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf) + goto out; + } + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); ++ } else { ++ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ if (conf->blist_devnode == NULL) { ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_devnode) { ++ condlog(0, "cannot allocate blacklist\n"); ++ goto out; ++ } ++ } ++ if (store_ble(conf->blist_devnode, ".*", ORIGIN_NO_CONFIG)) { ++ condlog(0, "cannot store default no-config blacklist\n"); ++ goto out; ++ } + } + + conf->processed_main_config = 1; +diff --git a/libmultipath/config.h b/libmultipath/config.h +index 933fe0d1..5f01c1fc 100644 +--- a/libmultipath/config.h ++++ b/libmultipath/config.h +@@ -9,6 +9,7 @@ + + #define ORIGIN_DEFAULT 0 + #define ORIGIN_CONFIG 1 ++#define ORIGIN_NO_CONFIG 2 + + enum devtypes { + DEV_NONE, +diff --git a/multipath/multipath.rules b/multipath/multipath.rules +index 9df11a95..0486bf70 100644 +--- a/multipath/multipath.rules ++++ b/multipath/multipath.rules +@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" + ENV{nompath}=="?*", GOTO="end_mpath" + IMPORT{cmdline}="multipath" + ENV{multipath}=="off", GOTO="end_mpath" ++TEST!="/etc/multipath.conf", GOTO="end_mpath" + + ENV{DEVTYPE}!="partition", GOTO="test_dev" + IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" +diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 +index 048a838d..8bd47a80 100644 +--- a/multipathd/multipathd.8 ++++ b/multipathd/multipathd.8 +@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. + This daemon executes the external \fBmultipath\fR tool when events occur. + In turn, the multipath tool signals the multipathd daemon when it is done with + devmap reconfiguration, so that it can refresh its failed path list. ++ ++In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists. + . + . + .\" ---------------------------------------------------------------------------- +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index 0b2ac814..6d57c7e8 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service + Before=iscsi.service iscsid.service lvm2-activation-early.service + Before=local-fs-pre.target blk-availability.service shutdown.target + After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service ++ConditionPathExists=/etc/multipath.conf + DefaultDependencies=no + Conflicts=shutdown.target + ConditionKernelCommandLine=!nompath +diff --git a/multipathd/multipathd.socket b/multipathd/multipathd.socket +index c777e5e3..3c20a2ff 100644 +--- a/multipathd/multipathd.socket ++++ b/multipathd/multipathd.socket +@@ -1,6 +1,7 @@ + [Unit] + Description=multipathd control socket + DefaultDependencies=no ++ConditionPathExists=/etc/multipath.conf + ConditionKernelCommandLine=!nompath + ConditionKernelCommandLine=!multipath=off + ConditionVirtualization=!container diff --git a/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch b/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch new file mode 100644 index 0000000..ced7159 --- /dev/null +++ b/SOURCES/0016-RH-Fix-nvme-function-missing-argument.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Jan 2019 14:54:56 -0600 +Subject: [PATCH] RH: Fix nvme function missing argument + +A future patch will change the compilation options to error when +function declarations have unspecified arguments. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/nvme/argconfig.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h +index adb192b6..bfd10ef8 100644 +--- a/libmultipath/nvme/argconfig.h ++++ b/libmultipath/nvme/argconfig.h +@@ -76,7 +76,7 @@ struct argconfig_commandline_options { + extern "C" { + #endif + +-typedef void argconfig_help_func(); ++typedef void argconfig_help_func(void); + void argconfig_append_usage(const char *str); + void argconfig_print_help(const char *program_desc, + const struct argconfig_commandline_options *options); diff --git a/SOURCES/0017-RH-use-rpm-optflags-if-present.patch b/SOURCES/0017-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..a1c081c --- /dev/null +++ b/SOURCES/0017-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 19 Apr 2017 06:10:01 -0500 +Subject: [PATCH] RH: use rpm optflags if present + +Use the passed in optflags when compiling as an RPM, and keep the +default flags as close as possible to the current fedora flags, while +still being generic. + +Signed-off-by: Benjamin Marzinski +--- + Makefile.inc | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/Makefile.inc b/Makefile.inc +index 2a75dc9c..5ac660de 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -92,23 +92,35 @@ TEST_CC_OPTION = $(shell \ + echo "$(2)"; \ + fi) + +-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) + WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,) + WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,) + +-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4 +-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ ++ifndef RPM_OPT_FLAGS ++ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) ++ OPTFLAGS := -O2 -g -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \ ++ $(STACKPROT) -grecord-gcc-switches \ ++ -fasynchronous-unwind-tables --param=ssp-buffer-size=4 ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ++ endif ++ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1) ++ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ++ endif ++else ++ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4 ++endif ++WARNFLAGS := -Werror -Wextra -Wformat=2 $(WFORMATOVERFLOW) -Werror=implicit-int \ + -Werror=implicit-function-declaration -Werror=format-security \ +- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) +-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2 ++ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ ++ -Wstrict-prototypes + CFLAGS := --std=gnu99 $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \ + -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ + -MMD -MP + BIN_CFLAGS = -fPIE -DPIE + LIB_CFLAGS = -fPIC + SHARED_FLAGS = -shared +-LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs ++LDFLAGS := $(LDFLAGS) $(RPM_LD_FLAGS) -Wl,-z,relro -Wl,-z,now -Wl,-z,defs + BIN_LDFLAGS = -pie + + # Check whether a function with name $1 has been declared in header file $2. +@@ -139,4 +151,4 @@ check_file = $(shell \ + + %.o: %.c + @echo building $@ because of $? +- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< ++ $(CC) $(CFLAGS) -c -o $@ $< diff --git a/SOURCES/0018-RH-add-mpathconf.patch b/SOURCES/0018-RH-add-mpathconf.patch new file mode 100644 index 0000000..f7bbecb --- /dev/null +++ b/SOURCES/0018-RH-add-mpathconf.patch @@ -0,0 +1,772 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 16 Oct 2014 15:49:01 -0500 +Subject: [PATCH] RH: add mpathconf + +mpathconf is a program (largely based on lvmcomf) to help users +configure /etc/multipath.conf and enable or disable multipathing. It +has a couple of built-in options that can be set directly from the +command line. But, mostly it is used to get a multipath.conf file +with the OS defaults, and to enable and disable multipathing via +a single command. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/config.c | 2 + + multipath/Makefile | 5 + + multipath/mpathconf | 556 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 135 ++++++++++ + 4 files changed, 698 insertions(+) + create mode 100644 multipath/mpathconf + create mode 100644 multipath/mpathconf.8 + +diff --git a/libmultipath/config.c b/libmultipath/config.c +index 5f35c3d3..cee3bbb7 100644 +--- a/libmultipath/config.c ++++ b/libmultipath/config.c +@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf) + factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); + } else { + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); ++ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create"); ++ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details"); + if (conf->blist_devnode == NULL) { + conf->blist_devnode = vector_alloc(); + if (!conf->blist_devnode) { +diff --git a/multipath/Makefile b/multipath/Makefile +index b9bbb3cf..e720c7f6 100644 +--- a/multipath/Makefile ++++ b/multipath/Makefile +@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so + $(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS) + $(GZIP) $(EXEC).8 > $(EXEC).8.gz + $(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz ++ $(GZIP) mpathconf.8 > mpathconf.8.gz + + install: + $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) + $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/ ++ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/ + $(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules +@@ -29,13 +31,16 @@ install: + $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir) + $(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir) + $(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir) ++ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir) + + uninstall: + $(RM) $(DESTDIR)$(bindir)/$(EXEC) + $(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules + $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules ++ $(RM) $(DESTDIR)$(bindir)/mpathconf + $(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz + $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz ++ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz + + clean: dep_clean + $(RM) core *.o $(EXEC) *.gz +diff --git a/multipath/mpathconf b/multipath/mpathconf +new file mode 100644 +index 00000000..c00d2555 +--- /dev/null ++++ b/multipath/mpathconf +@@ -0,0 +1,556 @@ ++#!/bin/bash ++# ++# Copyright (C) 2010 Red Hat, Inc. All rights reserved. ++# ++# This file is part of the device-mapper-multipath package. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++# ++# Simple editting of /etc/multipath.conf ++# This program was largely ripped off from lvmconf ++# ++ ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++ ++DEFAULT_CONFIG="# device-mapper-multipath configuration file ++ ++# For a complete list of the default configuration values, run either: ++# # multipath -t ++# or ++# # multipathd show config ++ ++# For a list of configuration options with descriptions, see the ++# multipath.conf man page. ++ ++defaults { ++ user_friendly_names yes ++ find_multipaths yes ++}" ++ ++CONFIGFILE="/etc/multipath.conf" ++OUTPUTFILE="/etc/multipath.conf" ++MULTIPATHDIR="/etc/multipath" ++TMPFILE="/etc/multipath/.multipath.conf.tmp" ++WWIDS=0 ++ ++function usage ++{ ++ echo "usage: $0 " ++ echo "" ++ echo "Commands:" ++ echo "Enable: --enable " ++ echo "Disable: --disable" ++ echo "Only allow certain wwids (instead of enable): --allow " ++ echo "Set user_friendly_names (Default y): --user_friendly_names " ++ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set default property blacklist (Default n): --property_blacklist " ++ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Load the dm-multipath modules on enable (Default y): --with_module " ++ echo "start/stop/reload multipathd (Default n): --with_multipathd " ++ echo "select output file (Default /etc/multipath.conf): --outfile " ++ echo "" ++} ++ ++function add_wwid ++{ ++ INDEX=0 ++ while [ "$INDEX" -lt "$WWIDS" ] ; do ++ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then ++ return ++ fi ++ ((INDEX++)) ++ done ++ WWID_LIST[$WWIDS]="$1" ++ ((WWIDS++)) ++} ++ ++function get_dm_deps ++{ ++ shift 3 ++ while [ -n "$1" -a -n "$2" ]; do ++ MAJOR=$(echo $1 | tr -d '(,') ++ MINOR=$(echo $2 | tr -d ')') ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ fi ++ shift 2 ++ done ++} ++ ++function set_dm_wwid ++{ ++ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then ++ add_wwid "${1##part*-mpath-}" ++ elif [[ "$1" =~ ^mpath- ]] ; then ++ add_wwid "${1##mpath-}" ++ else ++ get_dm_deps `dmsetup deps -u $1` ++ fi ++} ++ ++function set_wwid ++{ ++ UUID="" ++ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then ++ MAJOR=${1%%:*} ++ MINOR=${1##*:} ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ else ++ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null` ++ fi ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ else ++ add_wwid "$1" ++ fi ++} ++ ++function parse_args ++{ ++ while [ -n "$1" ]; do ++ case $1 in ++ --enable) ++ ENABLE=1 ++ shift ++ ;; ++ --disable) ++ ENABLE=0 ++ shift ++ ;; ++ --allow) ++ ENABLE=2 ++ if [ -n "$2" ]; then ++ set_wwid $2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --user_friendly_names) ++ if [ -n "$2" ]; then ++ FRIENDLY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --find_multipaths) ++ if [ -n "$2" ]; then ++ FIND=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --property_blacklist) ++ if [ -n "$2" ]; then ++ PROPERTY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --enable_foreign) ++ if [ -n "$2" ]; then ++ FOREIGN=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --with_module) ++ if [ -n "$2" ]; then ++ MODULE=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --with_multipathd) ++ if [ -n "$2" ]; then ++ MULTIPATHD=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --outfile) ++ if [ -n "$2" ]; then ++ OUTPUTFILE=$2 ++ HAVE_OUTFILE=1 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ *) ++ usage ++ exit ++ esac ++ done ++} ++ ++function validate_args ++{ ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ echo "ignoring extra parameters on disable" ++ FRIENDLY="" ++ FIND="" ++ PROPERTY="" ++ MODULE="" ++ fi ++ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then ++ echo "--user_friendly_names must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ "$FIND" = "y" ]; then ++ FIND="yes" ++ elif [ "$FIND" = "n" ]; then ++ FIND="no" ++ elif [ -n "$FIND" ] && [ "$FIND" != "yes" -a "$FIND" != "no" -a "$FIND" != "strict" -a "$FIND" != "greedy" -a "$FIND" != "smart" ]; then ++ echo "--find_multipaths must be one of 'yes' 'no' 'strict' 'greedy' or 'smart'" ++ exit 1 ++ fi ++ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then ++ echo "--property_blacklist must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then ++ echo "--enable_foreign must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then ++ SHOW_STATUS=1 ++ fi ++ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then ++ echo "--with_module must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then ++ echo "--with_multipathd must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then ++ echo "Because --allow makes changes that cannot be automatically reversed," ++ echo "you must set --outfile when you set --allow" ++ exit 1 ++ fi ++} ++ ++function add_blacklist_exceptions ++{ ++ INDEX=0 ++ while [ "$INDEX" -lt "$WWIDS" ] ; do ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ wwid '"\"${WWID_LIST[$INDEX]}\""' ++' $TMPFILE ++ ((INDEX++)) ++ done ++} ++ ++umask 0077 ++ ++parse_args "$@" ++ ++validate_args ++ ++if [ ! -d "$MULTIPATHDIR" ]; then ++ echo "/etc/multipath/ does not exist. failing" ++ exit 1 ++fi ++ ++rm $TMPFILE 2> /dev/null ++echo "$DEFAULT_CONFIG" > $TMPFILE ++if [ -f "$CONFIGFILE" ]; then ++ cp $CONFIGFILE $TMPFILE ++fi ++ ++if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then ++ HAVE_BLACKLIST=1 ++fi ++ ++if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then ++ HAVE_EXCEPTIONS=1 ++fi ++ ++if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then ++ HAVE_DEFAULTS=1 ++fi ++ ++if [ -z "$MODULE" -o "$MODULE" = "y" ]; then ++ if lsmod | grep -q "dm_multipath" ; then ++ HAVE_MODULE=1 ++ else ++ HAVE_MODULE=0 ++ fi ++fi ++ ++if [ "$MULTIPATHD" = "y" ]; then ++ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then ++ HAVE_MULTIPATHD=1 ++ else ++ HAVE_MULTIPATHD=0 ++ fi ++fi ++ ++if [ "$HAVE_BLACKLIST" = "1" ]; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_DISABLE=0 ++ fi ++fi ++ ++if [ "$HAVE_BLACKLIST" = "1" ]; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=0 ++ fi ++fi ++ ++if [ "$HAVE_DEFAULTS" = "1" ]; then ++ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p` ++ if [ "$HAVE_FIND" = "1" ]; then ++ HAVE_FIND="yes" ++ elif [ "$HAVE_FIND" = "0" ]; then ++ HAVE_FIND="no" ++ fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then ++ HAVE_FRIENDLY=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then ++ HAVE_FRIENDLY=0 ++ fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=0 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\^\$\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"NONE\"" ; then ++ HAVE_FOREIGN=2 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=3 ++ fi ++fi ++ ++if [ "$HAVE_EXCEPTIONS" = "1" ]; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=1 ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=0 ++ fi ++fi ++ ++if [ -n "$SHOW_STATUS" ]; then ++ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then ++ echo "multipath is enabled" ++ else ++ echo "multipath is disabled" ++ fi ++ if [ -z "$HAVE_FIND" ]; then ++ echo "find_multipaths is no" ++ else ++ echo "find_multipaths is $HAVE_FIND" ++ fi ++ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then ++ echo "user_friendly_names is disabled" ++ else ++ echo "user_friendly_names is enabled" ++ fi ++ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then ++ echo "default property blacklist is disabled" ++ else ++ echo "default property blacklist is enabled" ++ fi ++ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then ++ echo "enable_foreign is not set (no foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 2 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ else ++ echo "enable_foreign is set (foreign multipath devices may not be shown)" ++ fi ++ if [ -n "$HAVE_MODULE" ]; then ++ if [ "$HAVE_MODULE" = 1 ]; then ++ echo "dm_multipath module is loaded" ++ else ++ echo "dm_multipath module is not loaded" ++ fi ++ fi ++ if [ -z "$HAVE_MULTIPATHD" ]; then ++ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then ++ HAVE_MULTIPATHD=1 ++ else ++ HAVE_MULTIPATHD=0 ++ fi ++ fi ++ if [ "$HAVE_MULTIPATHD" = 1 ]; then ++ echo "multipathd is running" ++ else ++ echo "multipathd is not running" ++ fi ++ exit 0 ++fi ++ ++if [ -z "$HAVE_BLACKLIST" ]; then ++ cat >> $TMPFILE <<- _EOF_ ++ ++blacklist { ++} ++_EOF_ ++fi ++ ++if [ -z "$HAVE_DEFAULTS" ]; then ++ cat >> $TMPFILE <<- _EOF_ ++ ++defaults { ++} ++_EOF_ ++fi ++ ++if [ "$ENABLE" = 2 ]; then ++ if [ "$HAVE_DISABLE" = 1 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ fi ++ if [ -z "$HAVE_WWID_DISABLE" ]; then ++ sed -i '/^blacklist[[:space:]]*{/ a\ ++ wwid ".*" ++' $TMPFILE ++ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE ++ fi ++ if [ "$HAVE_EXCEPTIONS" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE ++ else ++ cat >> $TMPFILE <<- _EOF_ ++ ++blacklist_exceptions { ++} ++_EOF_ ++ fi ++ add_blacklist_exceptions ++elif [ "$ENABLE" = 1 ]; then ++ if [ "$HAVE_DISABLE" = 1 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ fi ++elif [ "$ENABLE" = 0 ]; then ++ if [ -z "$HAVE_DISABLE" ]; then ++ sed -i '/^blacklist[[:space:]]*{/ a\ ++ devnode ".*" ++' $TMPFILE ++ elif [ "$HAVE_DISABLE" = 0 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE ++ fi ++fi ++ ++if [ -n "$FIND" ]; then ++ if [ -z "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ find_multipaths '"$FIND"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$FIND" != "$HAVE_FIND" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FRIENDLY" = "n" ]; then ++ if [ "$HAVE_FRIENDLY" = 1 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FRIENDLY" = "y" ]; then ++ if [ -z "$HAVE_FRIENDLY" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ user_friendly_names yes ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FRIENDLY" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$PROPERTY" = "n" ]; then ++ if [ "$HAVE_PROPERTY" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$PROPERTY" = "y" ]; then ++ if [ -z "$HAVE_PROPERTY" ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ property "(SCSI_IDENT_|ID_WWN)" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_PROPERTY" = 0 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FOREIGN" = "n" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "y" ]; then ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign ".*" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ -f "$OUTPUTFILE" ]; then ++ cp $OUTPUTFILE $OUTPUTFILE.old ++ if [ $? != 0 ]; then ++ echo "failed to backup old config file, $OUTPUTFILE not updated" ++ exit 1 ++ fi ++fi ++ ++cp $TMPFILE $OUTPUTFILE ++if [ $? != 0 ]; then ++ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK" ++ exit 1 ++fi ++ ++rm -f $TMPFILE ++ ++if [ "$ENABLE" = 1 ]; then ++ if [ "$HAVE_MODULE" = 0 ]; then ++ modprobe dm_multipath ++ fi ++ if [ "$HAVE_MULTIPATHD" = 0 ]; then ++ systemctl start multipathd.service ++ fi ++elif [ "$ENABLE" = 0 ]; then ++ if [ "$HAVE_MULTIPATHD" = 1 ]; then ++ systemctl stop multipathd.service ++ fi ++elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then ++ systemctl reload multipathd.service ++fi +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +new file mode 100644 +index 00000000..a14d831e +--- /dev/null ++++ b/multipath/mpathconf.8 +@@ -0,0 +1,135 @@ ++.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" ++.SH NAME ++mpathconf - A tool for configuring device-mapper-multipath ++.SH SYNOPSIS ++.B mpathconf ++.RB [\| commands \|] ++.RB [\| options \|] ++.SH DESCRIPTION ++.B mpathconf ++is a utility that creates or modifies ++.B /etc/multipath.conf. ++It can enable or disable multipathing and configure some common options. ++.B mpathconf ++can also load the ++.B dm_multipath ++module, start and stop the ++.B multipathd ++daemon, and configure the ++.B multipathd ++service to start automatically or not. If ++.B mpathconf ++is called with no commands, it will display the current configuration, but ++will not create of modify ++.B /etc/multipath.conf ++ ++The default options for mpathconf are ++.B --with_module ++The ++.B --with_multipathd ++option is not set by default. Enabling multipathing will load the ++.B dm_multipath ++module but it will not immediately start it. This is so ++that users can manually edit their config file if necessary, before starting ++.B multipathd. ++ ++If ++.B /etc/multipath.conf ++already exists, mpathconf will edit it. If it does not exist, mpathconf will ++create a default file with ++.B user_friendly_names ++set and ++.B find_multipaths ++set to \fByes\fP. To disable these, use the ++.B --user_friendly_names n ++and ++.B --find_multipaths n ++options ++.SH COMMANDS ++.TP ++.B --enable ++Removes any line that blacklists all device nodes from the ++.B /etc/multipath.conf ++blacklist section. Also, creates ++.B /etc/multipath.conf ++if it doesn't exist. ++.TP ++.B --disable ++Adds a line that blacklists all device nodes to the ++.B /etc/multipath.conf ++blacklist section. If no blacklist section exists, it will create one. ++.TP ++.B --allow \fB\fP ++Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all ++wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\fP ++can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper ++device, either a multipath device, or any device on stacked on top of one or ++more multipath devices. This command can be used multiple times to allow ++multiple devices. \fBNOTE:\fP This action will create a configuration file that ++mpathconf will not be able to revert back to its previous state. Because ++of this, \fB--outfile\fP is required when using \fB--allow\fP. ++.TP ++.B --user_friendly_names \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B user_friendly_names yes ++to the ++.B /etc/multipath.conf ++defaults section. If set to \fBn\fP, this removes the line, if present. This ++command can be used along with any other command. ++.TP ++.B --find_multipaths\fP { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } ++If set to \fB\fP, this adds the line ++.B find_multipaths ++to the ++.B /etc/multipath.conf ++defaults section. This command can be used along with any other command. ++\fBy\fP and \fBn\fP can be used instead of \fByes\fP and \fBno\fP. ++.TP ++.B --property_blacklist \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B property "(SCSI_IDENT_|ID_WWN)" ++to the ++.B /etc/multipath.conf ++blacklist_exceptions section. If set to \fBn\fP, this removes the line, if ++present. This command can be used along with any other command. ++.TP ++.B --enable_foreign\fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B enable_foreign ".*" ++to the ++.B /etc/multipath.conf ++defaults section. if set to \fBn\fP, this removes the line, if present. This ++command can be used along with any other command. ++.TP ++.B --outfile \fB\fP ++Write the resulting multipath configuration to \fB\fP instead of ++\fB/etc/multipath.conf\fP. ++.SH OPTIONS ++.TP ++.B --with_module\fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this runs ++.B modprobe dm_multipath ++to install the multipath modules. This option only works with the ++.B --enable ++command. This option is set to \fBy\fP by default. ++.TP ++.B --with_multipathd { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this runs ++.B service multipathd start ++to start the multipathd daemon on \fB--enable\fP, ++.B service multipathd stop ++to stop the multipathd daemon on \fB--disable\fP, and ++.B service multipathd reload ++to reconfigure multipathd on \fB--user_frindly_names\fP and ++\fB--find_multipaths\fP. ++This option is set to \fBn\fP by default. ++.SH FILES ++.BR /etc/multipath.conf ++.SH "SEE ALSO" ++.BR multipath.conf (5), ++.BR modprobe (8), ++.BR multipath (8), ++.BR multipathd (8), ++.BR service (8), ++.SH AUTHOR ++Benjamin Marzinski diff --git a/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch new file mode 100644 index 0000000..055eeb6 --- /dev/null +++ b/SOURCES/0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -0,0 +1,151 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 17 Oct 2014 11:20:34 -0500 +Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A + +This patch adds another option to multipath, "-A", which reads +/proc/cmdline for mpath.wwid= options, and adds any wwids it finds +to /etc/multipath/wwids. While this isn't usually important during +normal operation, since these wwids should already be added, it can be +helpful during installation, to make sure that multipath can claim +devices as its own, before LVM or something else makes use of them. The +patch also execs "/sbin/multipath -A" before running multipathd in +multipathd.service + +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 54 +++++++++++++++++++++++++++++++++-- + multipath/multipath.8 | 7 ++++- + multipathd/multipathd.service | 1 + + 3 files changed, 59 insertions(+), 3 deletions(-) + +diff --git a/multipath/main.c b/multipath/main.c +index 65ece830..748e7902 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -122,7 +122,7 @@ usage (char * progname) + fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); + fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); + fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); +- fprintf (stderr, " %s [-v level] -W\n", progname); ++ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); + fprintf (stderr, " %s [-h|-t|-T]\n", progname); +@@ -136,6 +136,8 @@ usage (char * progname) + " -f flush a multipath device map\n" + " -F flush all multipath device maps\n" + " -a add a device wwid to the wwids file\n" ++ " -A add devices from kernel command line mpath.wwids\n" ++ " parameters to wwids file\n" + " -c check if a device should be a path in a multipath device\n" + " -C check if a multipath device has usable paths\n" + " -q allow queue_if_no_path when multipathd is not running\n" +@@ -450,6 +452,50 @@ static void cleanup_vecs(void) + free_pathvec(vecs.pathvec, FREE_PATHS); + } + ++static int remember_cmdline_wwid(void) ++{ ++ FILE *f = NULL; ++ char buf[LINE_MAX], *next, *ptr; ++ int ret = 0; ++ ++ f = fopen("/proc/cmdline", "re"); ++ if (!f) { ++ condlog(0, "can't open /proc/cmdline : %s", strerror(errno)); ++ return -1; ++ } ++ ++ if (!fgets(buf, sizeof(buf), f)) { ++ if (ferror(f)) ++ condlog(0, "read of /proc/cmdline failed : %s", ++ strerror(errno)); ++ else ++ condlog(0, "couldn't read /proc/cmdline"); ++ fclose(f); ++ return -1; ++ } ++ fclose(f); ++ next = buf; ++ while((ptr = strstr(next, "mpath.wwid="))) { ++ ptr += 11; ++ next = strpbrk(ptr, " \t\n"); ++ if (next) { ++ *next = '\0'; ++ next++; ++ } ++ if (strlen(ptr)) { ++ if (remember_wwid(ptr) != 0) ++ ret = -1; ++ } ++ else { ++ condlog(0, "empty mpath.wwid kernel command line option"); ++ ret = -1; ++ } ++ if (!next) ++ break; ++ } ++ return ret; ++} ++ + static int + configure (struct config *conf, enum mpath_cmds cmd, + enum devtypes dev_type, char *devpath) +@@ -838,7 +884,7 @@ main (int argc, char *argv[]) + conf->retrigger_tries = 0; + conf->force_sync = 1; + atexit(cleanup_vecs); +- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) { + switch(arg) { + case 1: printf("optarg : %s\n",optarg); + break; +@@ -915,6 +961,10 @@ main (int argc, char *argv[]) + case 'T': + cmd = CMD_DUMP_CONFIG; + break; ++ case 'A': ++ if (remember_cmdline_wwid() != 0) ++ exit(RTVL_FAIL); ++ exit(RTVL_OK); + case 'h': + usage(argv[0]); + exit(RTVL_OK); +diff --git a/multipath/multipath.8 b/multipath/multipath.8 +index 17df59f5..5ca75359 100644 +--- a/multipath/multipath.8 ++++ b/multipath/multipath.8 +@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. + .B multipath + .RB [\| \-v\ \c + .IR level \|] +-.B -W ++.RB [\| \-A | \-W \|] + . + .LP + .B multipath +@@ -145,6 +145,11 @@ device mapper, path checkers ...). + Add the WWID for the specified device to the WWIDs file. + . + .TP ++.B \-A ++Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the ++WWIDs file. ++. ++.TP + .B \-w + Remove the WWID for the specified device from the WWIDs file. + . +diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service +index 6d57c7e8..dfc1e962 100644 +--- a/multipathd/multipathd.service ++++ b/multipathd/multipathd.service +@@ -16,6 +16,7 @@ Type=notify + NotifyAccess=main + LimitCORE=infinity + ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath ++ExecStartPre=-/sbin/multipath -A + ExecStart=/sbin/multipathd -d -s + ExecReload=/sbin/multipathd reconfigure + TasksMax=infinity diff --git a/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch new file mode 100644 index 0000000..d5b5601 --- /dev/null +++ b/SOURCES/0020-RH-reset-default-find_mutipaths-value-to-off.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 7 Jun 2018 17:43:52 -0500 +Subject: [PATCH] RH: reset default find_mutipaths value to off + +Upstream has changed to default find_multipaths to "strict". For now +Redhat will retain the previous default of "off". + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/defaults.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h +index c27946c7..e0dd32ad 100644 +--- a/libmultipath/defaults.h ++++ b/libmultipath/defaults.h +@@ -23,7 +23,7 @@ + #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF + #define DEFAULT_VERBOSITY 2 + #define DEFAULT_REASSIGN_MAPS 0 +-#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT ++#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF + #define DEFAULT_FAST_IO_FAIL 5 + #define DEFAULT_DEV_LOSS_TMO 600 + #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON diff --git a/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch new file mode 100644 index 0000000..06233ff --- /dev/null +++ b/SOURCES/0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Apr 2019 13:25:42 -0500 +Subject: [PATCH] RH: attempt to get ANA info via sysfs first + +When the ANA prioritizer is run, first see if the "ana_state" sysfs file +exists, and if it does, try to read the state from there. If that fails, +fallback to using an ioctl. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c +index b5c7873d..e139360c 100644 +--- a/libmultipath/prioritizers/ana.c ++++ b/libmultipath/prioritizers/ana.c +@@ -24,6 +24,7 @@ + #include "prio.h" + #include "util.h" + #include "structs.h" ++#include "sysfs.h" + + enum { + ANA_ERR_GETCTRL_FAILED = 1, +@@ -36,6 +37,7 @@ enum { + ANA_ERR_GETNS_FAILED, + ANA_ERR_NO_MEMORY, + ANA_ERR_NO_INFORMATION, ++ ANA_ERR_INVALID_STATE, + }; + + static const char *ana_errmsg[] = { +@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = { + [ANA_ERR_GETNS_FAILED] = "couldn't get namespace info", + [ANA_ERR_NO_MEMORY] = "out of memory", + [ANA_ERR_NO_INFORMATION] = "invalid fd", ++ [ANA_ERR_INVALID_STATE] = "invalid state", + }; + + static const char *anas_string[] = { +@@ -107,6 +110,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log, + return -ANA_ERR_GETANAS_NOTFOUND; + } + ++static int get_ana_info_sysfs(struct path *pp) ++{ ++ char state[32]; ++ ++ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state, ++ sizeof(state)) <= 0) ++ return -ANA_ERR_NO_INFORMATION; ++ ++ if (strcmp(state, "optimized") == 0) ++ return NVME_ANA_OPTIMIZED; ++ if (strcmp(state, "non-optimized") == 0) ++ return NVME_ANA_NONOPTIMIZED; ++ if (strcmp(state, "inaccessible") == 0) ++ return NVME_ANA_INACCESSIBLE; ++ if (strcmp(state, "persistent-loss") == 0) ++ return NVME_ANA_PERSISTENT_LOSS; ++ if (strcmp(state, "change") == 0) ++ return NVME_ANA_CHANGE; ++ return -ANA_ERR_INVALID_STATE; ++} ++ + static int get_ana_info(struct path * pp) + { + int rc; +@@ -210,8 +234,11 @@ int getprio(struct path *pp, __attribute__((unused)) char *args, + + if (pp->fd < 0) + rc = -ANA_ERR_NO_INFORMATION; +- else +- rc = get_ana_info(pp); ++ else { ++ rc = get_ana_info_sysfs(pp); ++ if (rc < 0) ++ rc = get_ana_info(pp); ++ } + + switch (rc) { + case NVME_ANA_OPTIMIZED: diff --git a/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch b/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch new file mode 100644 index 0000000..1d10c09 --- /dev/null +++ b/SOURCES/0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch @@ -0,0 +1,102 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 25 Mar 2021 13:05:10 -0500 +Subject: [PATCH] RH: make parse_vpd_pg83 match scsi_id output + +Red Hat sets ID_SERIAL based on the result of scsi_id, instead of using +the result of sg_inq and 55-scsi-sg3_id.rules. Make parse_vpd_pg83 match +that. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 18 ++---------------- + tests/vpd.c | 6 ++++++ + 2 files changed, 8 insertions(+), 16 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index f25fe9e3..6fb81c28 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1136,12 +1136,9 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + naa_prio = 7; + break; + case 2: +- /* IEEE Extended: Prio 6 */ +- naa_prio = 6; +- break; + case 3: +- /* IEEE Locally assigned: Prio 1 */ +- naa_prio = 1; ++ /* IEEE Extended or Locally assigned: Prio 6 */ ++ naa_prio = 6; + break; + default: + /* Default: no priority */ +@@ -1160,17 +1157,6 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len, + vpd = d; + } + break; +- case 0x8: +- /* SCSI Name: Prio 3 */ +- if (memcmp(d + 4, "eui.", 4) && +- memcmp(d + 4, "naa.", 4) && +- memcmp(d + 4, "iqn.", 4)) +- break; +- if (prio < 3) { +- prio = 3; +- vpd = d; +- } +- break; + case 0x1: + /* T-10 Vendor ID: Prio 2 */ + if (prio < 2) { +diff --git a/tests/vpd.c b/tests/vpd.c +index 8e730d37..7bf7990f 100644 +--- a/tests/vpd.c ++++ b/tests/vpd.c +@@ -230,11 +230,13 @@ static const char * const str_prefix[] = { + [STR_IQN] = "iqn.", + }; + ++#if 0 + static const char byte0[] = { + [STR_EUI] = '2', + [STR_NAA] = '3', + [STR_IQN] = '8', + }; ++#endif + + /** + * create_scsi_string_desc() - create a SCSI name string descriptor. +@@ -659,6 +661,7 @@ make_test_vpd_naa(2, 18); + make_test_vpd_naa(2, 17); + make_test_vpd_naa(2, 16); + ++#if 0 + /* SCSI Name string: EUI64, WWID size: 17 */ + make_test_vpd_str(0, 20, 18) + make_test_vpd_str(0, 20, 17) +@@ -694,6 +697,7 @@ make_test_vpd_str(18, 20, 18) + make_test_vpd_str(18, 20, 17) + make_test_vpd_str(18, 20, 16) + make_test_vpd_str(18, 20, 15) ++#endif + + static int test_vpd(void) + { +@@ -767,6 +771,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_naa_2_18), + cmocka_unit_test(test_vpd_naa_2_17), + cmocka_unit_test(test_vpd_naa_2_16), ++/* + cmocka_unit_test(test_vpd_str_0_20_18), + cmocka_unit_test(test_vpd_str_0_20_17), + cmocka_unit_test(test_vpd_str_0_20_16), +@@ -791,6 +796,7 @@ static int test_vpd(void) + cmocka_unit_test(test_vpd_str_18_20_17), + cmocka_unit_test(test_vpd_str_18_20_16), + cmocka_unit_test(test_vpd_str_18_20_15), ++*/ + }; + return cmocka_run_group_tests(tests, setup, teardown); + } diff --git a/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch b/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch new file mode 100644 index 0000000..f79a876 --- /dev/null +++ b/SOURCES/0023-libmultipath-add-section-name-to-invalid-keyword-out.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 23 Sep 2021 14:16:51 -0500 +Subject: [PATCH] libmultipath: add section name to invalid keyword output + +If users forget the closing brace for a section in multipath.conf, +multipath has no way to detect that. When it sees the keyword at the +start of the next section, it will complain that there is an invalid +keyword, because that keyword doesn't belong in previous section (which +was never ended with a closing brace). This can confuse users. To make +this easier to understand, when multipath prints an invalid keyword +message, it now also prints the current section name, which can give +users a hint that they didn't end the previous section. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 8ca91bf2..611054f7 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -504,7 +504,7 @@ validate_config_strvec(vector strvec, const char *file) + + static int + process_stream(struct config *conf, FILE *stream, vector keywords, +- const char *file) ++ const char *section, const char *file) + { + int i; + int r = 0, t; +@@ -568,16 +568,22 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + if (keyword->sub) { + kw_level++; + r += process_stream(conf, stream, +- keyword->sub, file); ++ keyword->sub, ++ keyword->string, ++ file); + kw_level--; + } + break; + } + } +- if (i >= VECTOR_SIZE(keywords)) +- condlog(1, "%s line %d, invalid keyword: %s", +- file, line_nr, str); +- ++ if (i >= VECTOR_SIZE(keywords)) { ++ if (section) ++ condlog(1, "%s line %d, invalid keyword in the %s section: %s", ++ file, line_nr, section, str); ++ else ++ condlog(1, "%s line %d, invalid keyword: %s", ++ file, line_nr, str); ++ } + free_strvec(strvec); + } + if (kw_level == 1) +@@ -608,7 +614,7 @@ process_file(struct config *conf, const char *file) + + /* Stream handling */ + line_nr = 0; +- r = process_stream(conf, stream, conf->keywords, file); ++ r = process_stream(conf, stream, conf->keywords, NULL, file); + fclose(stream); + //free_keywords(keywords); + diff --git a/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch b/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch new file mode 100644 index 0000000..c96a932 --- /dev/null +++ b/SOURCES/0024-libmultipath-use-typedef-for-keyword-handler-functio.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 23 Sep 2021 21:39:36 -0500 +Subject: [PATCH] libmultipath: use typedef for keyword handler function + +Don't keep writing out the function type. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 6 +++--- + libmultipath/parser.h | 15 ++++++--------- + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index 611054f7..ebe1cbd9 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -33,7 +33,7 @@ static int line_nr; + + int + keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -72,7 +72,7 @@ install_sublevel_end(void) + + int + _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), ++ handler_fn *handler, + print_fn *print, + int unique) + { +@@ -558,7 +558,7 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = (*keyword->handler) (conf, strvec); ++ t = keyword->handler(conf, strvec); + r += t; + if (t) + condlog(1, "multipath.conf +%d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index b43d46f8..3452bde1 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,10 +43,11 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); ++typedef int handler_fn(struct config *, vector); + + struct keyword { + char *string; +- int (*handler) (struct config *, vector); ++ handler_fn *handler; + print_fn *print; + vector sub; + int unique; +@@ -62,18 +63,14 @@ struct keyword { + for (i = 0; i < (k)->sub->allocated && ((p) = (k)->sub->slot[i]); i++) + + /* Prototypes */ +-extern int keyword_alloc(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int keyword_alloc(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword_root(str, h) keyword_alloc(keywords, str, h, NULL, 1) + extern void install_sublevel(void); + extern void install_sublevel_end(void); + +-extern int _install_keyword(vector keywords, char *string, +- int (*handler) (struct config *, vector), +- print_fn *print, +- int unique); ++extern int _install_keyword(vector keywords, char *string, handler_fn *handler, ++ print_fn *print, int unique); + #define install_keyword(str, vec, pri) _install_keyword(keywords, str, vec, pri, 1) + #define install_keyword_multi(str, vec, pri) _install_keyword(keywords, str, vec, pri, 0) + extern void dump_keywords(vector keydump, int level); diff --git a/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch b/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch new file mode 100644 index 0000000..6374e20 --- /dev/null +++ b/SOURCES/0025-libmultipath-print-the-correct-file-when-parsing-fai.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 24 Sep 2021 13:13:31 -0500 +Subject: [PATCH] libmultipath: print the correct file when parsing fails + +Don't assume that parsing failed on multipath.conf + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index ebe1cbd9..d5595fb0 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -561,8 +561,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + t = keyword->handler(conf, strvec); + r += t; + if (t) +- condlog(1, "multipath.conf +%d, parsing failed: %s", +- line_nr, buf); ++ condlog(1, "%s line %d, parsing failed: %s", ++ file, line_nr, buf); + } + + if (keyword->sub) { diff --git a/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch b/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch new file mode 100644 index 0000000..a3e51f2 --- /dev/null +++ b/SOURCES/0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch @@ -0,0 +1,527 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 24 Sep 2021 17:59:12 -0500 +Subject: [PATCH] libmultipath: pass file and line number to keyword handlers + +This will make it possible for the keyword handlers to print more useful +warning messages. It will be used by future patches. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 143 +++++++++++++++++++++++++----------------- + libmultipath/parser.c | 3 +- + libmultipath/parser.h | 2 +- + 3 files changed, 90 insertions(+), 58 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 7a727389..eb2c44c0 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,7 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr) ++set_int(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -58,7 +58,7 @@ set_int(vector strvec, void *ptr) + } + + static int +-set_uint(vector strvec, void *ptr) ++set_uint(vector strvec, void *ptr, const char *file, int line_nr) + { + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; +@@ -90,7 +90,7 @@ set_uint(vector strvec, void *ptr) + } + + static int +-set_str(vector strvec, void *ptr) ++set_str(vector strvec, void *ptr, const char *file, int line_nr) + { + char **str_ptr = (char **)ptr; + +@@ -105,7 +105,7 @@ set_str(vector strvec, void *ptr) + } + + static int +-set_yes_no(vector strvec, void *ptr) ++set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -124,7 +124,7 @@ set_yes_no(vector strvec, void *ptr) + } + + static int +-set_yes_no_undef(vector strvec, void *ptr) ++set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -187,9 +187,10 @@ static int print_yes_no_undef(struct strbuf *buff, long v) + + #define declare_def_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option); \ ++ return function (strvec, &conf->option, file, line_nr); \ + } + + #define declare_def_snprint(option, function) \ +@@ -224,12 +225,13 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_hw_handler(option, function) \ + static int \ +-hw_ ## option ## _handler (struct config *conf, vector strvec) \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ + if (!hwe) \ + return 1; \ +- return function (strvec, &hwe->option); \ ++ return function (strvec, &hwe->option, file, line_nr); \ + } + + #define declare_hw_snprint(option, function) \ +@@ -243,11 +245,12 @@ snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_ovr_handler(option, function) \ + static int \ +-ovr_ ## option ## _handler (struct config *conf, vector strvec) \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + if (!conf->overrides) \ + return 1; \ +- return function (strvec, &conf->overrides->option); \ ++ return function (strvec, &conf->overrides->option, file, line_nr); \ + } + + #define declare_ovr_snprint(option, function) \ +@@ -260,12 +263,13 @@ snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option); \ ++ return function (strvec, &mpe->option, file, line_nr); \ + } + + #define declare_mp_snprint(option, function) \ +@@ -277,9 +281,10 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + return function(buff, mpe->option); \ + } + +-static int checkint_handler(struct config *conf, vector strvec) ++static int checkint_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_uint(strvec, &conf->checkint); ++ int rc = set_uint(strvec, &conf->checkint, file, line_nr); + + if (rc) + return rc; +@@ -302,9 +307,10 @@ declare_def_snprint(reassign_maps, print_yes_no) + declare_def_handler(multipath_dir, set_str) + declare_def_snprint(multipath_dir, print_str) + +-static int def_partition_delim_handler(struct config *conf, vector strvec) ++static int def_partition_delim_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim); ++ int rc = set_str(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -334,13 +340,13 @@ static const char * const find_multipaths_optvals[] = { + }; + + static int +-def_find_multipaths_handler(struct config *conf, vector strvec) ++def_find_multipaths_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths) == 0 && +- conf->find_multipaths != FIND_MULTIPATHS_UNDEF) ++ if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) + return 0; + + buff = set_value(strvec); +@@ -396,7 +402,8 @@ static int snprint_uid_attrs(struct config *conf, struct strbuf *buff, + return total; + } + +-static int uid_attrs_handler(struct config *conf, vector strvec) ++static int uid_attrs_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char *val; + +@@ -597,7 +604,8 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef) + declare_hw_snprint(skip_kpartx, print_yes_no_undef) + declare_mp_handler(skip_kpartx, set_yes_no_undef) + declare_mp_snprint(skip_kpartx, print_yes_no_undef) +-static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) ++static int def_disable_changed_wwids_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return 0; + } +@@ -629,20 +637,23 @@ declare_def_snprint_defstr(enable_foreign, print_str, + DEFAULT_ENABLE_FOREIGN) + + static int +-def_config_dir_handler(struct config *conf, vector strvec) ++def_config_dir_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir); ++ return set_str(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + + #define declare_def_attr_handler(option, function) \ + static int \ +-def_ ## option ## _handler (struct config *conf, vector strvec) \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ +- return function (strvec, &conf->option, &conf->attribute_flags);\ ++ return function (strvec, &conf->option, &conf->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_def_attr_snprint(option, function) \ +@@ -655,12 +666,14 @@ snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ + + #define declare_mp_attr_handler(option, function) \ + static int \ +-mp_ ## option ## _handler (struct config *conf, vector strvec) \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ + if (!mpe) \ + return 1; \ +- return function (strvec, &mpe->option, &mpe->attribute_flags); \ ++ return function (strvec, &mpe->option, &mpe->attribute_flags, \ ++ file, line_nr); \ + } + + #define declare_mp_attr_snprint(option, function) \ +@@ -673,7 +686,7 @@ snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ + } + + static int +-set_mode(vector strvec, void *ptr, int *flags) ++set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + mode_t mode; + mode_t *mode_ptr = (mode_t *)ptr; +@@ -694,7 +707,7 @@ set_mode(vector strvec, void *ptr, int *flags) + } + + static int +-set_uid(vector strvec, void *ptr, int *flags) ++set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + uid_t uid; + uid_t *uid_ptr = (uid_t *)ptr; +@@ -719,7 +732,7 @@ set_uid(vector strvec, void *ptr, int *flags) + } + + static int +-set_gid(vector strvec, void *ptr, int *flags) ++set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + { + gid_t gid; + gid_t *gid_ptr = (gid_t *)ptr; +@@ -786,7 +799,7 @@ declare_mp_attr_handler(gid, set_gid) + declare_mp_attr_snprint(gid, print_gid) + + static int +-set_undef_off_zero(vector strvec, void *ptr) ++set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -827,7 +840,7 @@ declare_hw_handler(fast_io_fail, set_undef_off_zero) + declare_hw_snprint(fast_io_fail, print_undef_off_zero) + + static int +-set_dev_loss(vector strvec, void *ptr) ++set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + unsigned int *uint_ptr = (unsigned int *)ptr; +@@ -870,7 +883,7 @@ declare_hw_handler(eh_deadline, set_undef_off_zero) + declare_hw_snprint(eh_deadline, print_undef_off_zero) + + static int +-set_pgpolicy(vector strvec, void *ptr) ++set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; + int *int_ptr = (int *)ptr; +@@ -936,7 +949,8 @@ get_sys_max_fds(int *max_fds) + + + static int +-max_fds_handler(struct config *conf, vector strvec) ++max_fds_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + int r = 0, max_fds; +@@ -981,7 +995,7 @@ snprint_max_fds (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-set_rr_weight(vector strvec, void *ptr) ++set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1025,7 +1039,7 @@ declare_mp_handler(rr_weight, set_rr_weight) + declare_mp_snprint(rr_weight, print_rr_weight) + + static int +-set_pgfailback(vector strvec, void *ptr) ++set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1075,7 +1089,7 @@ declare_mp_handler(pgfailback, set_pgfailback) + declare_mp_snprint(pgfailback, print_pgfailback) + + static int +-no_path_retry_helper(vector strvec, void *ptr) ++no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1120,7 +1134,8 @@ declare_mp_handler(no_path_retry, no_path_retry_helper) + declare_mp_snprint(no_path_retry, print_no_path_retry) + + static int +-def_log_checker_err_handler(struct config *conf, vector strvec) ++def_log_checker_err_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + char * buff; + +@@ -1193,7 +1208,8 @@ print_reservation_key(struct strbuf *buff, + } + + static int +-def_reservation_key_handler(struct config *conf, vector strvec) ++def_reservation_key_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + return set_reservation_key(strvec, &conf->reservation_key, + &conf->sa_flags, +@@ -1209,7 +1225,8 @@ snprint_def_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-mp_reservation_key_handler(struct config *conf, vector strvec) ++mp_reservation_key_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); + if (!mpe) +@@ -1229,7 +1246,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + } + + static int +-set_off_int_undef(vector strvec, void *ptr) ++set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { + int *int_ptr = (int *)ptr; + char * buff; +@@ -1370,7 +1387,8 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef) + + + static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec) ++def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + unsigned int uxsock_timeout; + char *buff; +@@ -1390,7 +1408,8 @@ def_uxsock_timeout_handler(struct config *conf, vector strvec) + } + + static int +-hw_vpd_vendor_handler(struct config *conf, vector strvec) ++hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + int i; + char *buff; +@@ -1430,7 +1449,8 @@ snprint_hw_vpd_vendor(struct config *conf, struct strbuf *buff, + * blacklist block handlers + */ + static int +-blacklist_handler(struct config *conf, vector strvec) ++blacklist_handler(struct config *conf, vector strvec, const char*file, ++ int line_nr) + { + if (!conf->blist_devnode) + conf->blist_devnode = vector_alloc(); +@@ -1452,7 +1472,8 @@ blacklist_handler(struct config *conf, vector strvec) + } + + static int +-blacklist_exceptions_handler(struct config *conf, vector strvec) ++blacklist_exceptions_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) + { + if (!conf->elist_devnode) + conf->elist_devnode = vector_alloc(); +@@ -1475,7 +1496,8 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) + + #define declare_ble_handler(option) \ + static int \ +-ble_ ## option ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char *buff; \ + int rc; \ +@@ -1494,7 +1516,8 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ + + #define declare_ble_device_handler(name, option, vend, prod) \ + static int \ +-ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ ++ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ + { \ + char * buff; \ + int rc; \ +@@ -1536,13 +1559,15 @@ snprint_ble_simple (struct config *conf, struct strbuf *buff, const void *data) + } + + static int +-ble_device_handler(struct config *conf, vector strvec) ++ble_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->blist_device); + } + + static int +-ble_except_device_handler(struct config *conf, vector strvec) ++ble_except_device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + return alloc_ble_device(conf->elist_device); + } +@@ -1574,7 +1599,8 @@ static int snprint_bled_product(struct config *conf, struct strbuf *buff, + * devices block handlers + */ + static int +-devices_handler(struct config *conf, vector strvec) ++devices_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->hwtable) + conf->hwtable = vector_alloc(); +@@ -1586,7 +1612,8 @@ devices_handler(struct config *conf, vector strvec) + } + + static int +-device_handler(struct config *conf, vector strvec) ++device_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct hwentry * hwe; + +@@ -1623,7 +1650,8 @@ declare_hw_snprint(hwhandler, print_str) + * overrides handlers + */ + static int +-overrides_handler(struct config *conf, vector strvec) ++overrides_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->overrides) + conf->overrides = alloc_hwe(); +@@ -1640,7 +1668,8 @@ overrides_handler(struct config *conf, vector strvec) + * multipaths block handlers + */ + static int +-multipaths_handler(struct config *conf, vector strvec) ++multipaths_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + if (!conf->mptable) + conf->mptable = vector_alloc(); +@@ -1652,7 +1681,8 @@ multipaths_handler(struct config *conf, vector strvec) + } + + static int +-multipath_handler(struct config *conf, vector strvec) ++multipath_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + struct mpentry * mpe; + +@@ -1681,7 +1711,8 @@ declare_mp_snprint(alias, print_str) + */ + + static int +-deprecated_handler(struct config *conf, vector strvec) ++deprecated_handler(struct config *conf, vector strvec, const char *file, ++ int line_nr) + { + char * buff; + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index d5595fb0..68262d0e 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -558,7 +558,8 @@ process_stream(struct config *conf, FILE *stream, vector keywords, + goto out; + } + if (keyword->handler) { +- t = keyword->handler(conf, strvec); ++ t = keyword->handler(conf, strvec, file, ++ line_nr); + r += t; + if (t) + condlog(1, "%s line %d, parsing failed: %s", +diff --git a/libmultipath/parser.h b/libmultipath/parser.h +index 3452bde1..11ea2278 100644 +--- a/libmultipath/parser.h ++++ b/libmultipath/parser.h +@@ -43,7 +43,7 @@ struct strbuf; + + /* keyword definition */ + typedef int print_fn(struct config *, struct strbuf *, const void *); +-typedef int handler_fn(struct config *, vector); ++typedef int handler_fn(struct config *, vector, const char *file, int line_nr); + + struct keyword { + char *string; diff --git a/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch b/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch new file mode 100644 index 0000000..eda393f --- /dev/null +++ b/SOURCES/0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch @@ -0,0 +1,250 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 28 Sep 2021 15:59:19 -0500 +Subject: [PATCH] libmultipath: make set_int take a range for valid values + +If a value outside of the valid range is passed to set_int, it caps the +value at appropriate limit, and issues a warning. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 121 +++++++++++++++++++++++++++----------------- + 1 file changed, 75 insertions(+), 46 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index eb2c44c0..57b6a7b6 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -29,7 +29,8 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, const char *file, int line_nr) ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) + { + int *int_ptr = (int *)ptr; + char *buff, *eptr; +@@ -44,11 +45,17 @@ set_int(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || res > INT_MAX || res < INT_MIN) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ if (*buff == '\0' || *eptr != '\0') { ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), ++ (res == max)? "large" : "small", res); ++ } + rc = 0; + *int_ptr = res; + } +@@ -77,8 +84,8 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + while (isspace(*eptr)) + eptr++; + if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { +- condlog(1, "%s: invalid value for %s: \"%s\"", +- __func__, (char*)VECTOR_SLOT(strvec, 0), buff); ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + rc = 1; + } else { + rc = 0; +@@ -193,6 +200,14 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_range_handler(option, minval, maxval) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_def_snprint(option, function) \ + static int \ + snprint_def_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -234,6 +249,18 @@ hw_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &hwe->option, file, line_nr); \ + } + ++#define declare_hw_range_handler(option, minval, maxval) \ ++static int \ ++hw_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); \ ++ if (!hwe) \ ++ return 1; \ ++ return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \ ++} ++ ++ + #define declare_hw_snprint(option, function) \ + static int \ + snprint_hw_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -253,6 +280,17 @@ ovr_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->overrides->option, file, line_nr); \ + } + ++#define declare_ovr_range_handler(option, minval, maxval) \ ++static int \ ++ovr_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ if (!conf->overrides) \ ++ return 1; \ ++ return set_int(strvec, &conf->overrides->option, minval, maxval, \ ++ file, line_nr); \ ++} ++ + #define declare_ovr_snprint(option, function) \ + static int \ + snprint_ovr_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -272,6 +310,17 @@ mp_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &mpe->option, file, line_nr); \ + } + ++#define declare_mp_range_handler(option, minval, maxval) \ ++static int \ ++mp_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable); \ ++ if (!mpe) \ ++ return 1; \ ++ return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \ ++} ++ + #define declare_mp_snprint(option, function) \ + static int \ + snprint_mp_ ## option (struct config *conf, struct strbuf *buff, \ +@@ -298,7 +347,7 @@ declare_def_snprint(checkint, print_int) + declare_def_handler(max_checkint, set_uint) + declare_def_snprint(max_checkint, print_int) + +-declare_def_handler(verbosity, set_int) ++declare_def_range_handler(verbosity, 0, MAX_VERBOSITY) + declare_def_snprint(verbosity, print_int) + + declare_def_handler(reassign_maps, set_yes_no) +@@ -473,22 +522,22 @@ declare_ovr_snprint(checker_name, print_str) + declare_hw_handler(checker_name, set_str) + declare_hw_snprint(checker_name, print_str) + +-declare_def_handler(minio, set_int) ++declare_def_range_handler(minio, 0, INT_MAX) + declare_def_snprint_defint(minio, print_int, DEFAULT_MINIO) +-declare_ovr_handler(minio, set_int) ++declare_ovr_range_handler(minio, 0, INT_MAX) + declare_ovr_snprint(minio, print_nonzero) +-declare_hw_handler(minio, set_int) ++declare_hw_range_handler(minio, 0, INT_MAX) + declare_hw_snprint(minio, print_nonzero) +-declare_mp_handler(minio, set_int) ++declare_mp_range_handler(minio, 0, INT_MAX) + declare_mp_snprint(minio, print_nonzero) + +-declare_def_handler(minio_rq, set_int) ++declare_def_range_handler(minio_rq, 0, INT_MAX) + declare_def_snprint_defint(minio_rq, print_int, DEFAULT_MINIO_RQ) +-declare_ovr_handler(minio_rq, set_int) ++declare_ovr_range_handler(minio_rq, 0, INT_MAX) + declare_ovr_snprint(minio_rq, print_nonzero) +-declare_hw_handler(minio_rq, set_int) ++declare_hw_range_handler(minio_rq, 0, INT_MAX) + declare_hw_snprint(minio_rq, print_nonzero) +-declare_mp_handler(minio_rq, set_int) ++declare_mp_range_handler(minio_rq, 0, INT_MAX) + declare_mp_snprint(minio_rq, print_nonzero) + + declare_def_handler(queue_without_daemon, set_yes_no) +@@ -512,7 +561,7 @@ snprint_def_queue_without_daemon(struct config *conf, struct strbuf *buff, + return append_strbuf_quoted(buff, qwd); + } + +-declare_def_handler(checker_timeout, set_int) ++declare_def_range_handler(checker_timeout, 0, INT_MAX) + declare_def_snprint(checker_timeout, print_nonzero) + + declare_def_handler(allow_usb_devices, set_yes_no) +@@ -583,13 +632,13 @@ declare_hw_snprint(deferred_remove, print_yes_no_undef) + declare_mp_handler(deferred_remove, set_yes_no_undef) + declare_mp_snprint(deferred_remove, print_yes_no_undef) + +-declare_def_handler(retrigger_tries, set_int) ++declare_def_range_handler(retrigger_tries, 0, INT_MAX) + declare_def_snprint(retrigger_tries, print_int) + +-declare_def_handler(retrigger_delay, set_int) ++declare_def_range_handler(retrigger_delay, 0, INT_MAX) + declare_def_snprint(retrigger_delay, print_int) + +-declare_def_handler(uev_wait_timeout, set_int) ++declare_def_range_handler(uev_wait_timeout, 0, INT_MAX) + declare_def_snprint(uev_wait_timeout, print_int) + + declare_def_handler(strict_timing, set_yes_no) +@@ -616,19 +665,19 @@ static int snprint_def_disable_changed_wwids(struct config *conf, + return print_ignored(buff); + } + +-declare_def_handler(remove_retries, set_int) ++declare_def_range_handler(remove_retries, 0, INT_MAX) + declare_def_snprint(remove_retries, print_int) + +-declare_def_handler(max_sectors_kb, set_int) ++declare_def_range_handler(max_sectors_kb, 0, INT_MAX) + declare_def_snprint(max_sectors_kb, print_nonzero) +-declare_ovr_handler(max_sectors_kb, set_int) ++declare_ovr_range_handler(max_sectors_kb, 0, INT_MAX) + declare_ovr_snprint(max_sectors_kb, print_nonzero) +-declare_hw_handler(max_sectors_kb, set_int) ++declare_hw_range_handler(max_sectors_kb, 0, INT_MAX) + declare_hw_snprint(max_sectors_kb, print_nonzero) +-declare_mp_handler(max_sectors_kb, set_int) ++declare_mp_range_handler(max_sectors_kb, 0, INT_MAX) + declare_mp_snprint(max_sectors_kb, print_nonzero) + +-declare_def_handler(find_multipaths_timeout, set_int) ++declare_def_range_handler(find_multipaths_timeout, INT_MIN, INT_MAX) + declare_def_snprint_defint(find_multipaths_timeout, print_int, + DEFAULT_FIND_MULTIPATHS_TIMEOUT) + +@@ -1385,27 +1434,7 @@ declare_ovr_snprint(recheck_wwid, print_yes_no_undef) + declare_hw_handler(recheck_wwid, set_yes_no_undef) + declare_hw_snprint(recheck_wwid, print_yes_no_undef) + +- +-static int +-def_uxsock_timeout_handler(struct config *conf, vector strvec, const char *file, +- int line_nr) +-{ +- unsigned int uxsock_timeout; +- char *buff; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; +- +- if (sscanf(buff, "%u", &uxsock_timeout) == 1 && +- uxsock_timeout > DEFAULT_REPLY_TIMEOUT) +- conf->uxsock_timeout = uxsock_timeout; +- else +- conf->uxsock_timeout = DEFAULT_REPLY_TIMEOUT; +- +- free(buff); +- return 0; +-} ++declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX) + + static int + hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, diff --git a/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch b/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch new file mode 100644 index 0000000..eb8c5a6 --- /dev/null +++ b/SOURCES/0028-libmultipath-improve-checks-for-set_str.patch @@ -0,0 +1,170 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 29 Sep 2021 12:56:04 -0500 +Subject: [PATCH] libmultipath: improve checks for set_str + +multipath always requires absolute pathnames, so make sure all file and +directory names start with a slash. Also check that the directories +exist. Finally, some strings, like the alias, will be used in paths. +These must not contain the slash character '/', since it is a forbidden +character in file/directory names. This patch adds seperate handlers for +these three cases. If a config line is invalid, these handlers retain +the existing config string, if any. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 88 +++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 78 insertions(+), 10 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 57b6a7b6..149d3348 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -5,6 +5,8 @@ + * Copyright (c) 2005 Kiyoshi Ueda, NEC + */ + #include ++#include ++#include + #include + #include + #include "checkers.h" +@@ -111,6 +113,72 @@ set_str(vector strvec, void *ptr, const char *file, int line_nr) + return 0; + } + ++static int ++set_dir(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ struct stat sb; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute directory path. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else { ++ if (stat(*str_ptr, &sb) == 0 && S_ISDIR(sb.st_mode)) ++ free(old_str); ++ else { ++ condlog(1, "%s line %d, %s is not an existing directory. Ignoring", file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } ++ } ++ return 0; ++} ++ ++static int ++set_path(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if ((*str_ptr)[0] != '/'){ ++ condlog(1, "%s line %d, %s is not an absolute path. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ ++static int ++set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr) ++{ ++ char **str_ptr = (char **)ptr; ++ char *old_str = *str_ptr; ++ ++ *str_ptr = set_value(strvec); ++ if (!*str_ptr) { ++ free(old_str); ++ return 1; ++ } ++ if (strchr(*str_ptr, '/')) { ++ condlog(1, "%s line %d, %s cannot contain a slash. Ignoring", ++ file, line_nr, *str_ptr); ++ *str_ptr = old_str; ++ } else ++ free(old_str); ++ return 0; ++} ++ + static int + set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + { +@@ -353,13 +421,13 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_str) ++declare_def_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, + const char *file, int line_nr) + { +- int rc = set_str(strvec, &conf->partition_delim, file, line_nr); ++ int rc = set_str_noslash(strvec, &conf->partition_delim, file, line_nr); + + if (rc != 0) + return rc; +@@ -490,11 +558,11 @@ declare_hw_snprint(prio_name, print_str) + declare_mp_handler(prio_name, set_str) + declare_mp_snprint(prio_name, print_str) + +-declare_def_handler(alias_prefix, set_str) ++declare_def_handler(alias_prefix, set_str_noslash) + declare_def_snprint_defstr(alias_prefix, print_str, DEFAULT_ALIAS_PREFIX) +-declare_ovr_handler(alias_prefix, set_str) ++declare_ovr_handler(alias_prefix, set_str_noslash) + declare_ovr_snprint(alias_prefix, print_str) +-declare_hw_handler(alias_prefix, set_str) ++declare_hw_handler(alias_prefix, set_str_noslash) + declare_hw_snprint(alias_prefix, print_str) + + declare_def_handler(prio_args, set_str) +@@ -586,13 +654,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_str) ++declare_def_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_str) ++declare_def_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_str) ++declare_def_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -692,7 +760,7 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; +- return set_str(strvec, &conf->config_dir, file, line_nr); ++ return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) + +@@ -1732,7 +1800,7 @@ multipath_handler(struct config *conf, vector strvec, const char *file, + declare_mp_handler(wwid, set_str) + declare_mp_snprint(wwid, print_str) + +-declare_mp_handler(alias, set_str) ++declare_mp_handler(alias, set_str_noslash) + declare_mp_snprint(alias, print_str) + + /* diff --git a/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch b/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch new file mode 100644 index 0000000..103dcac --- /dev/null +++ b/SOURCES/0029-libmultipath-deprecate-file-and-directory-config-opt.patch @@ -0,0 +1,114 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 10 Nov 2021 18:34:08 -0600 +Subject: [PATCH] libmultipath: deprecate file and directory config options + +Having multipath able to select pathnames for the files and directories +it needs causes unnecessary maintainer headaches. Mark these as +deprecated, but still support them for now. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 19 +++++++++++++++---- + multipath/multipath.conf.5 | 5 +++++ + 2 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 149d3348..d14be340 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -268,6 +268,15 @@ def_ ## option ## _handler (struct config *conf, vector strvec, \ + return function (strvec, &conf->option, file, line_nr); \ + } + ++#define declare_def_warn_handler(option, function) \ ++static int \ ++def_ ## option ## _handler (struct config *conf, vector strvec, \ ++ const char *file, int line_nr) \ ++{ \ ++ condlog(2, "%s line %d, \"" #option "\" is deprecated and will be disabled in a future release", file, line_nr); \ ++ return function (strvec, &conf->option, file, line_nr); \ ++} ++ + #define declare_def_range_handler(option, minval, maxval) \ + static int \ + def_ ## option ## _handler (struct config *conf, vector strvec, \ +@@ -421,7 +430,7 @@ declare_def_snprint(verbosity, print_int) + declare_def_handler(reassign_maps, set_yes_no) + declare_def_snprint(reassign_maps, print_yes_no) + +-declare_def_handler(multipath_dir, set_dir) ++declare_def_warn_handler(multipath_dir, set_dir) + declare_def_snprint(multipath_dir, print_str) + + static int def_partition_delim_handler(struct config *conf, vector strvec, +@@ -654,13 +663,13 @@ declare_hw_snprint(user_friendly_names, print_yes_no_undef) + declare_mp_handler(user_friendly_names, set_yes_no_undef) + declare_mp_snprint(user_friendly_names, print_yes_no_undef) + +-declare_def_handler(bindings_file, set_path) ++declare_def_warn_handler(bindings_file, set_path) + declare_def_snprint(bindings_file, print_str) + +-declare_def_handler(wwids_file, set_path) ++declare_def_warn_handler(wwids_file, set_path) + declare_def_snprint(wwids_file, print_str) + +-declare_def_handler(prkeys_file, set_path) ++declare_def_warn_handler(prkeys_file, set_path) + declare_def_snprint(prkeys_file, print_str) + + declare_def_handler(retain_hwhandler, set_yes_no_undef) +@@ -760,6 +769,8 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + /* this is only valid in the main config file */ + if (conf->processed_main_config) + return 0; ++ condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", ++ file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); + } + declare_def_snprint(config_dir, print_str) +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index dd9f4dc7..7f85f766 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -178,6 +178,7 @@ The default is: \fBno\fR + . + .TP + .B multipath_dir ++This option is deprecated, and will be removed in a future release. + Directory where the dynamic shared objects are stored. Defined at compile time, + commonly \fI/lib64/multipath/\fR or \fI/lib/multipath/\fR. + .RS +@@ -742,6 +743,7 @@ The default is: \fB\fR + . + .TP + .B bindings_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the binding file to be used when the user_friendly_names + option is set. + .RS +@@ -752,6 +754,7 @@ The default is: \fB/etc/multipath/bindings\fR + . + .TP + .B wwids_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the WWIDs file, which is used by multipath to keep track + of the WWIDs for LUNs it has created multipath devices on in the past. + .RS +@@ -762,6 +765,7 @@ The default is: \fB/etc/multipath/wwids\fR + . + .TP + .B prkeys_file ++This option is deprecated, and will be removed in a future release. + The full pathname of the prkeys file, which is used by multipathd to keep + track of the persistent reservation key used for a specific WWID, when + \fIreservation_key\fR is set to \fBfile\fR. +@@ -933,6 +937,7 @@ The default is: \fB\fR + . + .TP + .B config_dir ++This option is deprecated, and will be removed in a future release. + If set to anything other than "", multipath will search this directory + alphabetically for file ending in ".conf" and it will read configuration + information from them, just as if it was in \fI/etc/multipath.conf\fR. diff --git a/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch b/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch new file mode 100644 index 0000000..9f33473 --- /dev/null +++ b/SOURCES/0030-libmultipath-split-set_int-to-enable-reuse.patch @@ -0,0 +1,191 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Oct 2021 15:27:36 -0500 +Subject: [PATCH] libmultipath: split set_int to enable reuse + +Split the code that does the actual value parsing out of set_int(), into +a helper function, do_set_int(), so that it can be used by other +handlers. These functions no longer set the config value at all, when +they have invalid input. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 82 +++++++++++++++++++++++++-------------------- + 1 file changed, 46 insertions(+), 36 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index d14be340..68647061 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -31,17 +31,12 @@ + #include "strbuf.h" + + static int +-set_int(vector strvec, void *ptr, int min, int max, const char *file, +- int line_nr) ++do_set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr, char *buff) + { + int *int_ptr = (int *)ptr; +- char *buff, *eptr; ++ char *eptr; + long res; +- int rc; +- +- buff = set_value(strvec); +- if (!buff) +- return 1; + + res = strtol(buff, &eptr, 10); + if (eptr > buff) +@@ -50,17 +45,30 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- if (res > max || res < min) { +- res = (res > max) ? max : min; +- condlog(1, "%s line %d, value for %s too %s, capping at %ld", ++ return 1; ++ } ++ if (res > max || res < min) { ++ res = (res > max) ? max : min; ++ condlog(1, "%s line %d, value for %s too %s, capping at %ld", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), +- (res == max)? "large" : "small", res); +- } +- rc = 0; +- *int_ptr = res; ++ (res == max)? "large" : "small", res); + } ++ *int_ptr = res; ++ return 0; ++} ++ ++static int ++set_int(vector strvec, void *ptr, int min, int max, const char *file, ++ int line_nr) ++{ ++ char *buff; ++ int rc; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); + return rc; +@@ -929,6 +937,7 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -938,10 +947,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else if (sscanf(buff, "%d", int_ptr) != 1 || +- *int_ptr < UOZ_ZERO) +- *int_ptr = UOZ_UNDEF; +- else if (*int_ptr == 0) ++ else ++ rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, ++ buff); ++ if (rc == 0 && *int_ptr == 0) + *int_ptr = UOZ_ZERO; + + FREE(buff); +@@ -1093,14 +1102,12 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + /* Assume safe limit */ + max_fds = 4096; + } +- if (strlen(buff) == 3 && +- !strcmp(buff, "max")) +- conf->max_fds = max_fds; +- else +- conf->max_fds = atoi(buff); +- +- if (conf->max_fds > max_fds) ++ if (!strcmp(buff, "max")) { + conf->max_fds = max_fds; ++ r = 0; ++ } else ++ r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, ++ line_nr, buff); + + FREE(buff); + +@@ -1169,6 +1176,7 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1183,11 +1191,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- *int_ptr = atoi(buff); ++ rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return 0; ++ return rc; + } + + int +@@ -1219,6 +1227,7 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1230,11 +1239,11 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + *int_ptr = NO_PATH_RETRY_FAIL; + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NO_PATH_RETRY_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int +@@ -1376,6 +1385,7 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { ++ int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1385,11 +1395,11 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; +- else if ((*int_ptr = atoi(buff)) < 1) +- *int_ptr = NU_UNDEF; ++ else ++ rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return 0; ++ return rc; + } + + int diff --git a/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch b/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch new file mode 100644 index 0000000..c8978f2 --- /dev/null +++ b/SOURCES/0031-libmultipath-cleanup-invalid-config-handling.patch @@ -0,0 +1,201 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 4 Oct 2021 16:52:55 -0500 +Subject: [PATCH] libmultipath: cleanup invalid config handling + +Add error reporting to the remaining config handlers. If the value is +invalid, do not change the existing config option's value. Also print +an error whenever 0 is returned for an invalid value. When the handler +returns 1, config processing already fails with an error message. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 73 +++++++++++++++++++++++++++++++-------------- + 1 file changed, 51 insertions(+), 22 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 68647061..c534d703 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -199,8 +199,11 @@ set_yes_no(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YN_YES; +- else ++ else if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) + *int_ptr = YN_NO; ++ else ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -221,7 +224,8 @@ set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr) + else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) + *int_ptr = YNU_YES; + else +- *int_ptr = YNU_UNDEF; ++ condlog(1, "%s line %d, invalid value for %s: \"%s\"", ++ file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); + + FREE(buff); + return 0; +@@ -480,9 +484,6 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + char *buff; + int i; + +- if (set_yes_no_undef(strvec, &conf->find_multipaths, file, line_nr) == 0 && conf->find_multipaths != FIND_MULTIPATHS_UNDEF) +- return 0; +- + buff = set_value(strvec); + if (!buff) + return 1; +@@ -495,9 +496,14 @@ def_find_multipaths_handler(struct config *conf, vector strvec, + } + } + +- if (conf->find_multipaths == YNU_UNDEF) { +- condlog(0, "illegal value for find_multipaths: %s", buff); +- conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; ++ if (i >= __FIND_MULTIPATHS_LAST) { ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_OFF; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ conf->find_multipaths = FIND_MULTIPATHS_ON; ++ else ++ condlog(1, "%s line %d, invalid value for find_multipaths: \"%s\"", ++ file, line_nr, buff); + } + + FREE(buff); +@@ -546,8 +552,10 @@ static int uid_attrs_handler(struct config *conf, vector strvec, + if (!val) + return 1; + if (parse_uid_attrs(val, conf)) +- condlog(1, "error parsing uid_attrs: \"%s\"", val); +- condlog(3, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); ++ condlog(1, "%s line %d,error parsing uid_attrs: \"%s\"", file, ++ line_nr, val); ++ else ++ condlog(4, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs)); + FREE(val); + return 0; + } +@@ -775,8 +783,11 @@ def_config_dir_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + /* this is only valid in the main config file */ +- if (conf->processed_main_config) ++ if (conf->processed_main_config) { ++ condlog(1, "%s line %d, config_dir option only valid in /etc/multipath.conf", ++ file, line_nr); + return 0; ++ } + condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release", + file, line_nr); + return set_path(strvec, &conf->config_dir, file, line_nr); +@@ -836,7 +847,9 @@ set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) { + *flags |= (1 << ATTR_MODE); + *mode_ptr = mode; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for mode: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -861,7 +874,9 @@ set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &uid) == 1){ + *flags |= (1 << ATTR_UID); + *uid_ptr = uid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for uid: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -887,7 +902,9 @@ set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr) + else if (sscanf(buff, "%u", &gid) == 1){ + *flags |= (1 << ATTR_GID); + *gid_ptr = gid; +- } ++ } else ++ condlog(1, "%s line %d, invalid value for gid: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + return 0; + } +@@ -989,7 +1006,8 @@ set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "infinity")) + *uint_ptr = MAX_DEV_LOSS_TMO; + else if (sscanf(buff, "%u", uint_ptr) != 1) +- *uint_ptr = DEV_LOSS_TMO_UNSET; ++ condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"", ++ file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1023,13 +1041,19 @@ static int + set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr) + { + char * buff; ++ int policy; + int *int_ptr = (int *)ptr; + + buff = set_value(strvec); + if (!buff) + return 1; + +- *int_ptr = get_pgpolicy_id(buff); ++ policy = get_pgpolicy_id(buff); ++ if (policy != IOPOLICY_UNDEF) ++ *int_ptr = policy; ++ else ++ condlog(1, "%s line %d, invalid value for path_grouping_policy: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1142,10 +1166,11 @@ set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr) + + if (!strcmp(buff, "priorities")) + *int_ptr = RR_WEIGHT_PRIO; +- +- if (!strcmp(buff, "uniform")) ++ else if (!strcmp(buff, "uniform")) + *int_ptr = RR_WEIGHT_NONE; +- ++ else ++ condlog(1, "%s line %d, invalid value for rr_weight: \"%s\"", ++ file, line_nr, buff); + FREE(buff); + + return 0; +@@ -1281,10 +1306,13 @@ def_log_checker_err_handler(struct config *conf, vector strvec, + if (!buff) + return 1; + +- if (strlen(buff) == 4 && !strcmp(buff, "once")) ++ if (!strcmp(buff, "once")) + conf->log_checker_err = LOG_CHKR_ERR_ONCE; +- else if (strlen(buff) == 6 && !strcmp(buff, "always")) ++ else if (!strcmp(buff, "always")) + conf->log_checker_err = LOG_CHKR_ERR_ALWAYS; ++ else ++ condlog(1, "%s line %d, invalid value for log_checker_err: \"%s\"", ++ file, line_nr, buff); + + free(buff); + return 0; +@@ -1545,7 +1573,8 @@ hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file, + goto out; + } + } +- hwe->vpd_vendor_id = 0; ++ condlog(1, "%s line %d, invalid value for vpd_vendor: \"%s\"", ++ file, line_nr, buff); + out: + FREE(buff); + return 0; diff --git a/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch b/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch new file mode 100644 index 0000000..5ce85d4 --- /dev/null +++ b/SOURCES/0032-libmultipath-don-t-return-error-on-invalid-values.patch @@ -0,0 +1,218 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 11 Nov 2021 17:37:05 -0600 +Subject: [PATCH] libmultipath: don't return error on invalid values + +do_set_int and set_uint return 1 for invalid values. This can cause +multipath to fail completely, while reading the config. The config +handlers should only return a non-zero value if there is an internal +error, not if there is just an invalid value. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 64 ++++++++++++++++++--------------------------- + 1 file changed, 25 insertions(+), 39 deletions(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index c534d703..1b75be47 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -30,7 +30,7 @@ + #include "dict.h" + #include "strbuf.h" + +-static int ++static void + do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr, char *buff) + { +@@ -45,7 +45,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + if (*buff == '\0' || *eptr != '\0') { + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- return 1; ++ return; + } + if (res > max || res < min) { + res = (res > max) ? max : min; +@@ -54,7 +54,7 @@ do_set_int(vector strvec, void *ptr, int min, int max, const char *file, + (res == max)? "large" : "small", res); + } + *int_ptr = res; +- return 0; ++ return; + } + + static int +@@ -62,16 +62,15 @@ set_int(vector strvec, void *ptr, int min, int max, const char *file, + int line_nr) + { + char *buff; +- int rc; + + buff = set_value(strvec); + if (!buff) + return 1; + +- rc = do_set_int(strvec, ptr, min, max, file, line_nr, buff); ++ do_set_int(strvec, ptr, min, max, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -80,7 +79,6 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + unsigned int *uint_ptr = (unsigned int *)ptr; + char *buff, *eptr, *p; + unsigned long res; +- int rc; + + buff = set_value(strvec); + if (!buff) +@@ -93,17 +91,14 @@ set_uint(vector strvec, void *ptr, const char *file, int line_nr) + if (eptr > buff) + while (isspace(*eptr)) + eptr++; +- if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) { ++ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) + condlog(1, "%s line %d, invalid value for %s: \"%s\"", + file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff); +- rc = 1; +- } else { +- rc = 0; ++ else + *uint_ptr = res; +- } + + FREE(buff); +- return rc; ++ return 0; + } + + static int +@@ -954,7 +949,6 @@ declare_mp_attr_snprint(gid, print_gid) + static int + set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + char * buff; + int *int_ptr = (int *)ptr; + +@@ -964,11 +958,10 @@ set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr) + + if (strcmp(buff, "off") == 0) + *int_ptr = UOZ_OFF; +- else +- rc = do_set_int(strvec, int_ptr, 0, INT_MAX, file, line_nr, +- buff); +- if (rc == 0 && *int_ptr == 0) ++ else if (strcmp(buff, "0") == 0) + *int_ptr = UOZ_ZERO; ++ else ++ do_set_int(strvec, int_ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); + return 0; +@@ -1114,28 +1107,24 @@ max_fds_handler(struct config *conf, vector strvec, const char *file, + int line_nr) + { + char * buff; +- int r = 0, max_fds; ++ int max_fds; + + buff = set_value(strvec); + + if (!buff) + return 1; + +- r = get_sys_max_fds(&max_fds); +- if (r) { +- /* Assume safe limit */ +- max_fds = 4096; +- } +- if (!strcmp(buff, "max")) { ++ if (get_sys_max_fds(&max_fds) != 0) ++ max_fds = 4096; /* Assume safe limit */ ++ if (!strcmp(buff, "max")) + conf->max_fds = max_fds; +- r = 0; +- } else +- r = do_set_int(strvec, &conf->max_fds, 0, max_fds, file, +- line_nr, buff); ++ else ++ do_set_int(strvec, &conf->max_fds, 0, max_fds, file, line_nr, ++ buff); + + FREE(buff); + +- return r; ++ return 0; + } + + static int +@@ -1201,7 +1190,6 @@ declare_mp_snprint(rr_weight, print_rr_weight) + static int + set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1216,11 +1204,11 @@ set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr) + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) + *int_ptr = -FAILBACK_FOLLOWOVER; + else +- rc = do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff); + + FREE(buff); + +- return rc; ++ return 0; + } + + int +@@ -1252,7 +1240,6 @@ declare_mp_snprint(pgfailback, print_pgfailback) + static int + no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc = 0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1265,10 +1252,10 @@ no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr) + else if (!strcmp(buff, "queue")) + *int_ptr = NO_PATH_RETRY_QUEUE; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int +@@ -1413,7 +1400,6 @@ snprint_mp_reservation_key (struct config *conf, struct strbuf *buff, + static int + set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + { +- int rc =0; + int *int_ptr = (int *)ptr; + char * buff; + +@@ -1424,10 +1410,10 @@ set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr) + if (!strcmp(buff, "no") || !strcmp(buff, "0")) + *int_ptr = NU_NO; + else +- rc = do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); ++ do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff); + + FREE(buff); +- return rc; ++ return 0; + } + + int diff --git a/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch b/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch new file mode 100644 index 0000000..7bbe406 --- /dev/null +++ b/SOURCES/0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch @@ -0,0 +1,129 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 15 Nov 2021 10:54:35 -0600 +Subject: [PATCH] multipathd: avoid unnecessary path read-only reloads + +A mulitpath device can only be reloaded read/write when all paths are +read/write. Also, whenever a read-only device is rescanned, the scsi +subsystem will first unconditionally issue a uevent with DISK_RO=0 +before checking the read-only status, and if it the device is still +read-only, issuing another uevent with DISK_RO=1. These uevents cause +pointless reloads when read-only paths are rescanned. To avoid this, +check to see if all paths are read/write before changing a multipath +device from read-only to read/write. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 5 +++++ + libmultipath/sysfs.c | 22 ++++++++++++++++++++++ + libmultipath/sysfs.h | 1 + + multipathd/main.c | 31 ++++++++++++++++++++++++++++++- + 4 files changed, 58 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index eb5b5b55..dd1b4122 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -287,3 +287,8 @@ global: + local: + *; + }; ++ ++LIBMULTIPATH_9.1.0 { ++global: ++ sysfs_get_ro; ++} LIBMULTIPATH_9.0.0; +diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c +index 9ff145f2..24c12b6a 100644 +--- a/libmultipath/sysfs.c ++++ b/libmultipath/sysfs.c +@@ -236,6 +236,28 @@ sysfs_get_size (struct path *pp, unsigned long long * size) + return 0; + } + ++int ++sysfs_get_ro (struct path *pp) ++{ ++ int ro; ++ char buff[3]; /* Either "0\n\0" or "1\n\0" */ ++ ++ if (!pp->udev) ++ return -1; ++ ++ if (sysfs_attr_get_value(pp->udev, "ro", buff, sizeof(buff)) <= 0) { ++ condlog(3, "%s: Cannot read ro attribute in sysfs", pp->dev); ++ return -1; ++ } ++ ++ if (sscanf(buff, "%d\n", &ro) != 1 || ro < 0 || ro > 1) { ++ condlog(3, "%s: Cannot parse ro attribute", pp->dev); ++ return -1; ++ } ++ ++ return ro; ++} ++ + int sysfs_check_holders(char * check_devt, char * new_devt) + { + unsigned int major, new_minor, table_minor; +diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h +index 72b39ab2..c948c467 100644 +--- a/libmultipath/sysfs.h ++++ b/libmultipath/sysfs.h +@@ -13,6 +13,7 @@ ssize_t sysfs_attr_get_value(struct udev_device *dev, const char *attr_name, + ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name, + unsigned char * value, size_t value_len); + int sysfs_get_size (struct path *pp, unsigned long long * size); ++int sysfs_get_ro(struct path *pp); + int sysfs_check_holders(char * check_devt, char * new_devt); + bool sysfs_is_multipathed(struct path *pp, bool set_wwid); + #endif +diff --git a/multipathd/main.c b/multipathd/main.c +index 1defeaf1..6145e512 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1324,6 +1324,35 @@ fail: + return REMOVE_PATH_MAP_ERROR; + } + ++static bool ++needs_ro_update(struct multipath *mpp, int ro) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ unsigned int i, j; ++ struct dm_info *dmi = NULL; ++ ++ if (!mpp || ro < 0) ++ return false; ++ dm_get_info(mpp->alias, &dmi); ++ if (!dmi) /* assume we do need to reload the device */ ++ return true; ++ if (dmi->read_only == ro) { ++ free(dmi); ++ return false; ++ } ++ free(dmi); ++ if (ro == 1) ++ return true; ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ vector_foreach_slot (pgp->paths, pp, j) { ++ if (sysfs_get_ro(pp) == 1) ++ return false; ++ } ++ } ++ return true; ++} ++ + static int + uev_update_path (struct uevent *uev, struct vectors * vecs) + { +@@ -1388,7 +1417,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + } + + ro = uevent_get_disk_ro(uev); +- if (mpp && ro >= 0) { ++ if (needs_ro_update(mpp, ro)) { + condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); + + if (mpp->wait_for_udev) diff --git a/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch b/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch new file mode 100644 index 0000000..66a18f5 --- /dev/null +++ b/SOURCES/0034-multipath-fix-exit-status-of-multipath-T.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Wilck +Date: Fri, 22 Oct 2021 12:58:11 +0200 +Subject: [PATCH] multipath: fix exit status of multipath -T + +We must set the return value in configure(). + +Signed-off-by: Martin Wilck +Reviewed-by: Benjamin Marzinski +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/multipath/main.c b/multipath/main.c +index 748e7902..80fa68e5 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -606,6 +606,7 @@ configure (struct config *conf, enum mpath_cmds cmd, + + dump_config(conf, hwes, curmp); + vector_free(hwes); ++ r = RTVL_OK; + goto out; + } + diff --git a/SOURCES/0035-RH-mpathconf-fix-setting-property_blacklist.patch b/SOURCES/0035-RH-mpathconf-fix-setting-property_blacklist.patch new file mode 100644 index 0000000..846ba28 --- /dev/null +++ b/SOURCES/0035-RH-mpathconf-fix-setting-property_blacklist.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 13 Dec 2021 14:26:30 -0600 +Subject: [PATCH] RH: mpathconf: fix setting property_blacklist + +If there was no blacklist_exceptions section, setting property_blacklist +didn't work correctly. Fix it. + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index c00d2555..0de6b121 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -496,7 +496,15 @@ if [ "$PROPERTY" = "n" ]; then + CHANGED_CONFIG=1 + fi + elif [ "$PROPERTY" = "y" ]; then +- if [ -z "$HAVE_PROPERTY" ]; then ++ if [ -z "$HAVE_PROPERTY" -a -z "$HAVE_EXCEPTIONS" ]; then ++ cat >> $TMPFILE << _EOF_ ++ ++blacklist_exceptions { ++ property "(SCSI_IDENT_|ID_WWN)" ++} ++_EOF_ ++ CHANGED_CONFIG=1 ++ elif [ -z "$HAVE_PROPERTY" ]; then + sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ + property "(SCSI_IDENT_|ID_WWN)" + ' $TMPFILE diff --git a/SOURCES/0036-libmultipath-fix-disassemble-status-for-historical-s.patch b/SOURCES/0036-libmultipath-fix-disassemble-status-for-historical-s.patch new file mode 100644 index 0000000..bd96ede --- /dev/null +++ b/SOURCES/0036-libmultipath-fix-disassemble-status-for-historical-s.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 12 Jan 2022 12:26:12 -0600 +Subject: [PATCH] libmultipath: fix disassemble status for + historical-service-time PS + +The historical-service-time path selector prints out 2 path group status +arguments. This is the only path selector that uses the group status +arguments. All the others only have path status arguments. +disassemble_status() was expecting the number of group status arguments +to always be zero, causing it to fail at disassembling the status of +devices that use historical-service-time path selector. Now multipath +actually checks the number of group arguments, and skips them. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dmparser.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c +index 4ba7f339..bc311421 100644 +--- a/libmultipath/dmparser.c ++++ b/libmultipath/dmparser.c +@@ -437,9 +437,19 @@ int disassemble_status(const char *params, struct multipath *mpp) + FREE(word); + + /* +- * PG Status (discarded, would be '0' anyway) ++ * Path Selector Group Arguments + */ +- p += get_word(p, NULL); ++ p += get_word(p, &word); ++ ++ if (!word) ++ return 1; ++ ++ num_pg_args = atoi(word); ++ free(word); ++ ++ /* Ignore ps group arguments */ ++ for (j = 0; j < num_pg_args; j++) ++ p += get_word(p, NULL); + + p += get_word(p, &word); + diff --git a/SOURCES/0037-libmultipath-make-helper-function-to-trigger-path-ue.patch b/SOURCES/0037-libmultipath-make-helper-function-to-trigger-path-ue.patch new file mode 100644 index 0000000..116893c --- /dev/null +++ b/SOURCES/0037-libmultipath-make-helper-function-to-trigger-path-ue.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 Jan 2022 14:45:38 -0600 +Subject: [PATCH] libmultipath: make helper function to trigger path uevents + +Pull the code that checks if a path needs to trigger a uevent, and +triggers, out of trigger_paths_udev_change() and into a new function, +trigger_path_udev_change(). This function will be used separately by +a future patch. No functional changes. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/configure.c | 79 +++++++++++++++++++++------------------- + libmultipath/configure.h | 1 + + 2 files changed, 43 insertions(+), 37 deletions(-) + +diff --git a/libmultipath/configure.c b/libmultipath/configure.c +index 7edb355b..043e4232 100644 +--- a/libmultipath/configure.c ++++ b/libmultipath/configure.c +@@ -565,11 +565,8 @@ unref: + } + + void +-trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) ++trigger_path_udev_change(struct path *pp, bool is_mpath) + { +- struct pathgroup *pgp; +- struct path *pp; +- int i, j; + /* + * If a path changes from multipath to non-multipath, we must + * synthesize an artificial "add" event, otherwise the LVM2 rules +@@ -577,6 +574,45 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + * irritate ourselves with an "add", so use "change". + */ + const char *action = is_mpath ? "change" : "add"; ++ const char *env; ++ ++ if (!pp->udev) ++ return; ++ /* ++ * Paths that are already classified as multipath ++ * members don't need another uevent. ++ */ ++ env = udev_device_get_property_value( ++ pp->udev, "DM_MULTIPATH_DEVICE_PATH"); ++ ++ if (is_mpath && env != NULL && !strcmp(env, "1")) { ++ /* ++ * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", ++ * path is in "maybe" state and timer is running ++ * Send uevent now (see multipath.rules). ++ */ ++ env = udev_device_get_property_value( ++ pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); ++ if (env == NULL || !strcmp(env, "0")) ++ return; ++ } else if (!is_mpath && ++ (env == NULL || !strcmp(env, "0"))) ++ return; ++ ++ condlog(3, "triggering %s uevent for %s (is %smultipath member)", ++ action, pp->dev, is_mpath ? "" : "no "); ++ sysfs_attr_set_value(pp->udev, "uevent", ++ action, strlen(action)); ++ trigger_partitions_udev_change(pp->udev, action, ++ strlen(action)); ++} ++ ++void ++trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) ++{ ++ struct pathgroup *pgp; ++ struct path *pp; ++ int i, j; + + if (!mpp || !mpp->pg) + return; +@@ -584,39 +620,8 @@ trigger_paths_udev_change(struct multipath *mpp, bool is_mpath) + vector_foreach_slot (mpp->pg, pgp, i) { + if (!pgp->paths) + continue; +- vector_foreach_slot(pgp->paths, pp, j) { +- const char *env; +- +- if (!pp->udev) +- continue; +- /* +- * Paths that are already classified as multipath +- * members don't need another uevent. +- */ +- env = udev_device_get_property_value( +- pp->udev, "DM_MULTIPATH_DEVICE_PATH"); +- +- if (is_mpath && env != NULL && !strcmp(env, "1")) { +- /* +- * If FIND_MULTIPATHS_WAIT_UNTIL is not "0", +- * path is in "maybe" state and timer is running +- * Send uevent now (see multipath.rules). +- */ +- env = udev_device_get_property_value( +- pp->udev, "FIND_MULTIPATHS_WAIT_UNTIL"); +- if (env == NULL || !strcmp(env, "0")) +- continue; +- } else if (!is_mpath && +- (env == NULL || !strcmp(env, "0"))) +- continue; +- +- condlog(3, "triggering %s uevent for %s (is %smultipath member)", +- action, pp->dev, is_mpath ? "" : "no "); +- sysfs_attr_set_value(pp->udev, "uevent", +- action, strlen(action)); +- trigger_partitions_udev_change(pp->udev, action, +- strlen(action)); +- } ++ vector_foreach_slot(pgp->paths, pp, j) ++ trigger_path_udev_change(pp, is_mpath); + } + + mpp->needs_paths_uevent = 0; +diff --git a/libmultipath/configure.h b/libmultipath/configure.h +index efe18b7d..2bf73e65 100644 +--- a/libmultipath/configure.h ++++ b/libmultipath/configure.h +@@ -56,6 +56,7 @@ int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int forc + int get_refwwid (enum mpath_cmds cmd, const char *dev, enum devtypes dev_type, + vector pathvec, char **wwid); + struct udev_device *get_udev_device(const char *dev, enum devtypes dev_type); ++void trigger_path_udev_change(struct path *pp, bool is_mpath); + void trigger_paths_udev_change(struct multipath *mpp, bool is_mpath); + void trigger_partitions_udev_change(struct udev_device *dev, const char *action, + int len); diff --git a/SOURCES/0038-multipathd-trigger-udev-change-on-path-addition.patch b/SOURCES/0038-multipathd-trigger-udev-change-on-path-addition.patch new file mode 100644 index 0000000..1386f0e --- /dev/null +++ b/SOURCES/0038-multipathd-trigger-udev-change-on-path-addition.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 17 Jan 2022 16:46:18 -0600 +Subject: [PATCH] multipathd: trigger udev change on path addition + +When a multipath device is created for the first time, there is a window +where some path devices way be added to the multipath device, but never +claimed in udev. This can allow other device owners, like lvm, to think +they can use the device. + +When a multipath device is first created, all the existing paths that +are not claimed by multipath have a uevent triggered so that they can +get claimed. After that, multipath assumes all future paths added to the +multipath device will have been claimed by multipath, since the device's +WWID is now in the wwids file. This doesn't work for any paths that +have already been processed by the multipath.rules udev rules before +the multipath device was created. + +To close this window, when path device is added, and a matching +multipath device already exists, multipathd now checks if the device is +claimed by multipath, and if not, triggers a uevent to claim it. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/libmultipath.version | 5 +++++ + multipathd/main.c | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index dd1b4122..0d89e9e1 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -292,3 +292,8 @@ LIBMULTIPATH_9.1.0 { + global: + sysfs_get_ro; + } LIBMULTIPATH_9.0.0; ++ ++LIBMULTIPATH_9.1.1 { ++global: ++ trigger_path_udev_change; ++} LIBMULTIPATH_9.1.0; +diff --git a/multipathd/main.c b/multipathd/main.c +index 6145e512..5def5301 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1062,6 +1062,8 @@ ev_add_path (struct path * pp, struct vectors * vecs, int need_do_map) + free_path(pp); + return 1; + } ++ if (mpp) ++ trigger_path_udev_change(pp, true); + if (mpp && mpp->wait_for_udev && + (pathcount(mpp, PATH_UP) > 0 || + (pathcount(mpp, PATH_GHOST) > 0 && diff --git a/SOURCES/0039-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch b/SOURCES/0039-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch new file mode 100644 index 0000000..dff41f8 --- /dev/null +++ b/SOURCES/0039-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch @@ -0,0 +1,149 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 2 Feb 2022 17:00:21 -0600 +Subject: [PATCH] RH: add support to mpathconf for setting arbitrary default + options + +mpathconf now supports --option :[] for setting, changing, +or removing options from the defaults section of multipath.conf. + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 58 ++++++++++++++++++++++++++++++++++++++++--- + multipath/mpathconf.8 | 7 ++++++ + 2 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index 0de6b121..6e33fb99 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -17,7 +17,7 @@ + # This program was largely ripped off from lvmconf + # + +-unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE + + DEFAULT_CONFIG="# device-mapper-multipath configuration file + +@@ -52,6 +52,7 @@ function usage + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "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 " +@@ -162,6 +163,20 @@ function parse_args + exit 1 + fi + ;; ++ --option) ++ if [ -n "$2" ]; then ++ OPTION_NAME=$(echo $2 | cut -s -f1 -d:) ++ OPTION_VALUE=$(echo $2 | cut -s -f2 -d:) ++ if [ -z "$OPTION_NAME" ]; then ++ usage ++ exit 1 ++ fi ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --enable_foreign) + if [ -n "$2" ]; then + FOREIGN=$2 +@@ -208,12 +223,15 @@ function parse_args + + function validate_args + { +- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" + PROPERTY="" + MODULE="" ++ FOREIGN="" ++ OPTION_NAME="" ++ OPTION_VALUE="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then + echo "--user_friendly_names must be either 'y' or 'n'" +@@ -235,7 +253,19 @@ function validate_args + echo "--enable_foreign must be either 'y' or 'n'" + exit 1 + fi +- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then ++ if [ -n "$OPTION_NAME" ]; then ++ if [[ $OPTION_NAME =~ [[:space:]]|#|\"|!|\{|\} ]]; then ++ echo "--option name \"$OPTION_NAME\" is invalid" ++ exit 1 ++ elif [[ $OPTION_VALUE =~ \"|#|!|\{|\} ]]; then ++ echo "--option value \"$OPTION_VALUE\" is invalid" ++ exit 1 ++ fi ++ if [[ $OPTION_VALUE =~ [[:space:]] ]]; then ++ OPTION_VALUE=\"$OPTION_VALUE\" ++ fi ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then +@@ -348,6 +378,13 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then + 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 +@@ -532,6 +569,21 @@ elif [ "$FOREIGN" = "y" ]; then + fi + fi + ++if [ -n "$OPTION_NAME" -a -n "$OPTION_VALUE" ]; then ++ if [ -z "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ '"$OPTION_NAME"' '"$OPTION_VALUE"' ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_OPTION" = 0 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/ '"$OPTION_NAME"' '"$OPTION_VALUE"'/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ -n "$OPTION_NAME" -a -n "$HAVE_OPTION" ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/{/^[[:space:]]*'"$OPTION_NAME"'\([[:space:]].*\)\?$/d}' $TMPFILE ++ CHANGED_CONFIG=1 ++fi ++ + if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +index a14d831e..496383b7 100644 +--- a/multipath/mpathconf.8 ++++ b/multipath/mpathconf.8 +@@ -101,6 +101,13 @@ to the + defaults section. if set to \fBn\fP, this removes the line, if present. This + command can be used along with any other command. + .TP ++.B --option \fB:[]\fP ++Sets the defaults section option \fB\fP to \fB\fP. If the ++option was not previously set in the defaults section, it is added. If it was ++set, its value is changed to \fB\fP. If \fB\fP is left blank, ++then the option is removed from the defaults section, if was set there. This ++command can be used along with any other command. ++.TP + .B --outfile \fB\fP + Write the resulting multipath configuration to \fB\fP instead of + \fB/etc/multipath.conf\fP. diff --git a/SOURCES/0040-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch b/SOURCES/0040-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch new file mode 100644 index 0000000..5330d38 --- /dev/null +++ b/SOURCES/0040-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch @@ -0,0 +1,154 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 3 Feb 2022 13:26:18 -0600 +Subject: [PATCH] RH: add support to mpathconf for setting recheck_wwid + +mpathconf now supports --recheck_wwid for setthing the +recheck_wwid option + +Signed-off-by: Benjamin Marzinski +--- + multipath/mpathconf | 48 ++++++++++++++++++++++++++++++++++++++++--- + multipath/mpathconf.8 | 9 ++++++++ + 2 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/multipath/mpathconf b/multipath/mpathconf +index 6e33fb99..319664b1 100644 +--- a/multipath/mpathconf ++++ b/multipath/mpathconf +@@ -17,7 +17,7 @@ + # This program was largely ripped off from lvmconf + # + +-unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST HAVE_OPTION OPTION_NAME OPTION_VALUE ++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 + +@@ -52,6 +52,7 @@ function usage + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Set default property blacklist (Default n): --property_blacklist " + echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "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 " +@@ -145,6 +146,15 @@ function parse_args + 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 +@@ -223,7 +233,7 @@ function parse_args + + function validate_args + { +- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" -o -n "$OPTION_NAME" ]; 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="" +@@ -232,11 +242,16 @@ function validate_args + 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 "$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="yes" + elif [ "$FIND" = "n" ]; then +@@ -265,7 +280,7 @@ function validate_args + OPTION_VALUE=\"$OPTION_VALUE\" + fi + fi +- if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" -a -z "$OPTION_NAME" ]; then ++ 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 +@@ -367,6 +382,11 @@ if [ "$HAVE_DEFAULTS" = "1" ]; 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:]][[:space:]]*\"\.\*\"" ; then +@@ -411,6 +431,11 @@ if [ -n "$SHOW_STATUS" ]; then + 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 +@@ -527,6 +552,23 @@ elif [ "$FRIENDLY" = "y" ]; then + 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:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE +diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 +index 496383b7..9c2fb835 100644 +--- a/multipath/mpathconf.8 ++++ b/multipath/mpathconf.8 +@@ -77,6 +77,15 @@ to the + defaults section. If set to \fBn\fP, this removes the line, if present. This + command can be used along with any other command. + .TP ++.B --recheck_wwid \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B recheck_wwid yes ++to the ++.B /etc/multipath.conf ++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 { \fByes\fP | \fBno\fP | \fBstrict\fP | \fBgreedy\fP | \fBsmart\fP } + If set to \fB\fP, this adds the line + .B find_multipaths diff --git a/SOURCES/0041-multipathd-handle-fpin-events.patch b/SOURCES/0041-multipathd-handle-fpin-events.patch new file mode 100644 index 0000000..4a5a931 --- /dev/null +++ b/SOURCES/0041-multipathd-handle-fpin-events.patch @@ -0,0 +1,1060 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Muneendra Kumar +Date: Wed, 9 Feb 2022 19:28:10 -0800 +Subject: [PATCH] multipathd: handle fpin events + +This patch incorporates the functionality to handle +FPIN ELS events present as part of FCTransport daemon +(available in EPEL8) into the multipathd. This helps us to +reduce the response time to react and take the necessary actions +on receiving the FPIN events. + +This patch currently support FPIN-Li Events. + +It adds a new thread to listen for ELS frames from driver and on +receiving the frame payload, push the payload to a list and notify the +fpin_els_li_consumer thread to process it.Once consumer thread is +notified, it returns to listen for more ELS frames from driver. + +The consumer thread process the ELS frames and moves the devices paths +which are affected due to link integrity to marginal path groups. +This also sets the associated portstate to marginal. +The paths which are set to marginal path group will be unset +on receiving the RSCN events + +[ MW: minor fixup for 32bit compilation ] + +Signed-off-by: Muneendra Kumar +Signed-off-by: Benjamin Marzinski +Signed-off-by: Martin Wilck +Reviewed-by: Martin Wilck +--- + Makefile.inc | 13 + + libmultipath/Makefile | 5 + + libmultipath/dict.c | 56 +++- + libmultipath/libmultipath.version | 5 + + libmultipath/propsel.c | 47 ++- + libmultipath/structs.h | 7 + + multipath/multipath.conf.5 | 19 +- + multipathd/Makefile | 10 + + multipathd/fpin.h | 20 ++ + multipathd/fpin_handlers.c | 540 ++++++++++++++++++++++++++++++ + multipathd/main.c | 43 ++- + 11 files changed, 749 insertions(+), 16 deletions(-) + create mode 100644 multipathd/fpin.h + create mode 100644 multipathd/fpin_handlers.c + +diff --git a/Makefile.inc b/Makefile.inc +index 5ac660de..688c4599 100644 +--- a/Makefile.inc ++++ b/Makefile.inc +@@ -149,6 +149,19 @@ check_file = $(shell \ + echo "$$found" \ + ) + ++# Check whether a file contains a variable with name $1 in header file $2 ++check_var = $(shell \ ++ if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \ ++ found=1; \ ++ status="yes"; \ ++ else \ ++ found=0; \ ++ status="no"; \ ++ fi; \ ++ echo 1>&2 "Checking for .. $1 in $2 ... $$status"; \ ++ echo "$$found" \ ++ ) ++ + %.o: %.c + @echo building $@ because of $? + $(CC) $(CFLAGS) -c -o $@ $< +diff --git a/libmultipath/Makefile b/libmultipath/Makefile +index 7f3921c5..8a960419 100644 +--- a/libmultipath/Makefile ++++ b/libmultipath/Makefile +@@ -45,6 +45,11 @@ ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0) + CFLAGS += -DLIBDM_API_HOLD_CONTROL + endif + ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,/usr/include/scsi/fc/fc_els.h),0) ++ CFLAGS += -DFPIN_EVENT_HANDLER ++endif ++ ++ + OBJS = memory.o parser.o vector.o devmapper.o callout.o \ + hwtable.o blacklist.o util.o dmparser.o config.o \ + structs.o discovery.o propsel.o dict.o \ +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 1b75be47..eb5a8083 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -513,6 +513,59 @@ snprint_def_find_multipaths(struct config *conf, struct strbuf *buff, + find_multipaths_optvals[conf->find_multipaths]); + } + ++static const char * const marginal_pathgroups_optvals[] = { ++ [MARGINAL_PATHGROUP_OFF] = "off", ++ [MARGINAL_PATHGROUP_ON] = "on", ++#ifdef FPIN_EVENT_HANDLER ++ [MARGINAL_PATHGROUP_FPIN] = "fpin", ++#endif ++}; ++ ++static int ++def_marginal_pathgroups_handler(struct config *conf, vector strvec, ++ const char *file, int line_nr) ++{ ++ char *buff; ++ unsigned int i; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ for (i = MARGINAL_PATHGROUP_OFF; ++ i < ARRAY_SIZE(marginal_pathgroups_optvals); i++) { ++ if (marginal_pathgroups_optvals[i] != NULL && ++ !strcmp(buff, marginal_pathgroups_optvals[i])) { ++ conf->marginal_pathgroups = i; ++ break; ++ } ++ } ++ ++ if (i >= ARRAY_SIZE(marginal_pathgroups_optvals)) { ++ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0) ++ conf->marginal_pathgroups = MARGINAL_PATHGROUP_OFF; ++ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0) ++ conf->marginal_pathgroups = MARGINAL_PATHGROUP_ON; ++ /* This can only be true if FPIN_EVENT_HANDLER isn't defined, ++ * otherwise this check will have already happened above */ ++ else if (strcmp(buff, "fpin") == 0) ++ condlog(1, "%s line %d, support for \"fpin\" is not compiled in for marginal_pathgroups", file, line_nr); ++ else ++ condlog(1, "%s line %d, invalid value for marginal_pathgroups: \"%s\"", ++ file, line_nr, buff); ++ } ++ free(buff); ++ return 0; ++} ++ ++static int ++snprint_def_marginal_pathgroups(struct config *conf, struct strbuf *buff, ++ const void *data) ++{ ++ return append_strbuf_quoted(buff, ++ marginal_pathgroups_optvals[conf->marginal_pathgroups]); ++} ++ ++ + declare_def_handler(selector, set_str) + declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR) + declare_hw_handler(selector, set_str) +@@ -1527,9 +1580,6 @@ declare_ovr_snprint(all_tg_pt, print_yes_no_undef) + declare_hw_handler(all_tg_pt, set_yes_no_undef) + declare_hw_snprint(all_tg_pt, print_yes_no_undef) + +-declare_def_handler(marginal_pathgroups, set_yes_no) +-declare_def_snprint(marginal_pathgroups, print_yes_no) +- + declare_def_handler(recheck_wwid, set_yes_no_undef) + declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID) + declare_ovr_handler(recheck_wwid, set_yes_no_undef) +diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version +index 0d89e9e1..1d018eab 100644 +--- a/libmultipath/libmultipath.version ++++ b/libmultipath/libmultipath.version +@@ -297,3 +297,8 @@ LIBMULTIPATH_9.1.1 { + global: + trigger_path_udev_change; + } LIBMULTIPATH_9.1.0; ++ ++LIBMULTIPATH_9.1.2 { ++global: ++ cleanup_mutex; ++} LIBMULTIPATH_9.1.1; +diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c +index b2876670..677ab9e1 100644 +--- a/libmultipath/propsel.c ++++ b/libmultipath/propsel.c +@@ -84,6 +84,8 @@ static const char cmdline_origin[] = + "(setting: multipath command line [-p] flag)"; + static const char autodetect_origin[] = + "(setting: storage device autodetected)"; ++static const char fpin_marginal_path_origin[] = ++ "(setting: overridden by marginal_path_fpin)"; + static const char marginal_path_origin[] = + "(setting: implied by marginal_path check)"; + static const char delay_watch_origin[] = +@@ -1036,9 +1038,12 @@ int select_san_path_err_threshold(struct config *conf, struct multipath *mp) + const char *origin; + STRBUF_ON_STACK(buff); + +- if (marginal_path_check_enabled(mp)) { ++ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { + mp->san_path_err_threshold = NU_NO; +- origin = marginal_path_origin; ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) ++ origin = fpin_marginal_path_origin; ++ else ++ origin = marginal_path_origin; + goto out; + } + mp_set_mpe(san_path_err_threshold); +@@ -1059,9 +1064,12 @@ int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp) + const char *origin; + STRBUF_ON_STACK(buff); + +- if (marginal_path_check_enabled(mp)) { ++ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { + mp->san_path_err_forget_rate = NU_NO; +- origin = marginal_path_origin; ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) ++ origin = fpin_marginal_path_origin; ++ else ++ origin = marginal_path_origin; + goto out; + } + mp_set_mpe(san_path_err_forget_rate); +@@ -1083,9 +1091,12 @@ int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp) + const char *origin; + STRBUF_ON_STACK(buff); + +- if (marginal_path_check_enabled(mp)) { ++ if (marginal_path_check_enabled(mp) || (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { + mp->san_path_err_recovery_time = NU_NO; +- origin = marginal_path_origin; ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) ++ origin = fpin_marginal_path_origin; ++ else ++ origin = marginal_path_origin; + goto out; + } + mp_set_mpe(san_path_err_recovery_time); +@@ -1107,6 +1118,12 @@ int select_marginal_path_err_sample_time(struct config *conf, struct multipath * + const char *origin; + STRBUF_ON_STACK(buff); + ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { ++ mp->marginal_path_err_sample_time = NU_NO; ++ origin = fpin_marginal_path_origin; ++ goto out; ++ } ++ + mp_set_mpe(marginal_path_err_sample_time); + mp_set_ovr(marginal_path_err_sample_time); + mp_set_hwe(marginal_path_err_sample_time); +@@ -1130,6 +1147,12 @@ int select_marginal_path_err_rate_threshold(struct config *conf, struct multipat + const char *origin; + STRBUF_ON_STACK(buff); + ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { ++ mp->marginal_path_err_rate_threshold = NU_NO; ++ origin = fpin_marginal_path_origin; ++ goto out; ++ } ++ + mp_set_mpe(marginal_path_err_rate_threshold); + mp_set_ovr(marginal_path_err_rate_threshold); + mp_set_hwe(marginal_path_err_rate_threshold); +@@ -1147,6 +1170,12 @@ int select_marginal_path_err_recheck_gap_time(struct config *conf, struct multip + const char *origin; + STRBUF_ON_STACK(buff); + ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { ++ mp->marginal_path_err_recheck_gap_time = NU_NO; ++ origin = fpin_marginal_path_origin; ++ goto out; ++ } ++ + mp_set_mpe(marginal_path_err_recheck_gap_time); + mp_set_ovr(marginal_path_err_recheck_gap_time); + mp_set_hwe(marginal_path_err_recheck_gap_time); +@@ -1165,6 +1194,12 @@ int select_marginal_path_double_failed_time(struct config *conf, struct multipat + const char *origin; + STRBUF_ON_STACK(buff); + ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) { ++ mp->marginal_path_double_failed_time = NU_NO; ++ origin = fpin_marginal_path_origin; ++ goto out; ++ } ++ + mp_set_mpe(marginal_path_double_failed_time); + mp_set_ovr(marginal_path_double_failed_time); + mp_set_hwe(marginal_path_double_failed_time); +diff --git a/libmultipath/structs.h b/libmultipath/structs.h +index 399540e7..1188363e 100644 +--- a/libmultipath/structs.h ++++ b/libmultipath/structs.h +@@ -110,6 +110,12 @@ enum find_multipaths_states { + __FIND_MULTIPATHS_LAST, + }; + ++enum marginal_pathgroups_mode { ++ MARGINAL_PATHGROUP_OFF = YN_NO, ++ MARGINAL_PATHGROUP_ON = YN_YES, ++ MARGINAL_PATHGROUP_FPIN, ++}; ++ + enum flush_states { + FLUSH_UNDEF = YNU_UNDEF, + FLUSH_DISABLED = YNU_NO, +@@ -409,6 +415,7 @@ struct multipath { + unsigned char prflag; + int all_tg_pt; + struct gen_multipath generic_mp; ++ bool fpin_must_reload; + }; + + static inline int marginal_path_check_enabled(const struct multipath *mpp) +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 7f85f766..5ed2cd3c 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1088,20 +1088,26 @@ The default is: \fBno\fR + . + .TP + .B marginal_pathgroups +-If set to \fIno\fR, the \fIdelay_*_checks\fR, \fImarginal_path_*\fR, and ++If set to \fIoff\fR, the \fIdelay_*_checks\fR, \fImarginal_path_*\fR, and + \fIsan_path_err_*\fR options will keep marginal, or \(dqshaky\(dq, paths from + being reinstated until they have been monitored for some time. This can cause + situations where all non-marginal paths are down, and no paths are usable + until multipathd detects this and reinstates a marginal path. If the multipath + device is not configured to queue IO in this case, it can cause IO errors to + occur, even though there are marginal paths available. However, if this +-option is set to \fIyes\fR, when one of the marginal path detecting methods ++option is set to \fIon\fR, when one of the marginal path detecting methods + determines that a path is marginal, it will be reinstated and placed in a + seperate pathgroup that will only be used after all the non-marginal pathgroups + have been tried first. This prevents the possibility of IO errors occuring + while marginal paths are still usable. After the path has been monitored + for the configured time, and is declared healthy, it will be returned to its +-normal pathgroup. See "Shaky paths detection" below for more information. ++normal pathgroup. ++However if this option is set to \fIfpin\fR multipathd will receive fpin ++notifications, set path states to "marginal" accordingly, and regroup paths ++as described for "marginal_pathgroups yes". This option can't be used in combination ++with other options for "Shaky path detection" (see below).If it is set to fpin, ++marginal_path_xyz and san_path_err_xyz parameters are implicitly set to 0. ++See "Shaky paths detection" below for more information. + .RS + .TP + The default is: \fBno\fR +@@ -1842,6 +1848,13 @@ increase and the threshold is never reached. Ticks are the time between + path checks by multipathd, which is variable and controlled by the + \fIpolling_interval\fR and \fImax_polling_interval\fR parameters. + . ++.TP ++.B \(dqFPIN \(dq failure tracking ++Fibre channel fabrics can notify hosts about fabric-level issues such ++as integrity failures or congestion with so-called Fabric Performance ++Impact Notifications (FPINs).On receiving the fpin notifications through ELS ++multipathd will move the affected path and port states to marginal. ++. + .RS 8 + .LP + This method is \fBdeprecated\fR in favor of the \(dqmarginal_path\(dq failure +diff --git a/multipathd/Makefile b/multipathd/Makefile +index 393b6cbb..cd6f7e6d 100644 +--- a/multipathd/Makefile ++++ b/multipathd/Makefile +@@ -4,6 +4,10 @@ ifneq ($(call check_func,dm_task_get_errno,/usr/include/libdevmapper.h),0) + CFLAGS += -DLIBDM_API_GET_ERRNO + endif + ++ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,/usr/include/scsi/fc/fc_els.h),0) ++ CFLAGS += -DFPIN_EVENT_HANDLER ++ FPIN_SUPPORT = 1 ++endif + # + # debugging stuff + # +@@ -34,6 +38,12 @@ endif + OBJS = main.o pidfile.o uxlsnr.o uxclnt.o cli.o cli_handlers.o waiter.o \ + dmevents.o init_unwinder.o + ++ifeq ($(FPIN_SUPPORT),1) ++OBJS += fpin_handlers.o ++endif ++ ++ ++ + EXEC = multipathd + + all : $(EXEC) +diff --git a/multipathd/fpin.h b/multipathd/fpin.h +new file mode 100644 +index 00000000..bfcc1ce2 +--- /dev/null ++++ b/multipathd/fpin.h +@@ -0,0 +1,20 @@ ++#ifndef __FPIN_H__ ++#define __FPIN_H__ ++ ++#ifdef FPIN_EVENT_HANDLER ++void *fpin_fabric_notification_receiver(void *unused); ++void *fpin_els_li_consumer(void *data); ++void fpin_clean_marginal_dev_list(__attribute__((unused)) void *arg); ++#else ++static void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) ++{ ++ return NULL; ++} ++static void *fpin_els_li_consumer(__attribute__((unused))void *data) ++{ ++ return NULL; ++} ++/* fpin_clean_marginal_dev_list() is never called */ ++#endif ++ ++#endif +diff --git a/multipathd/fpin_handlers.c b/multipathd/fpin_handlers.c +new file mode 100644 +index 00000000..aaf5655d +--- /dev/null ++++ b/multipathd/fpin_handlers.c +@@ -0,0 +1,540 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "parser.h" ++#include "vector.h" ++#include "structs.h" ++#include "structs_vec.h" ++#include "main.h" ++#include "debug.h" ++#include "util.h" ++#include "sysfs.h" ++ ++#include "fpin.h" ++#include "devmapper.h" ++ ++static pthread_cond_t fpin_li_cond = PTHREAD_COND_INITIALIZER; ++static pthread_mutex_t fpin_li_mutex = PTHREAD_MUTEX_INITIALIZER; ++static pthread_mutex_t fpin_li_marginal_dev_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static LIST_HEAD(els_marginal_list_head); ++static LIST_HEAD(fpin_li_marginal_dev_list_head); ++ ++ ++#define DEF_RX_BUF_SIZE 4096 ++#define DEV_NAME_LEN 128 ++#define FCH_EVT_LINKUP 0x2 ++#define FCH_EVT_LINK_FPIN 0x501 ++#define FCH_EVT_RSCN 0x5 ++ ++#define list_first_entry(ptr, type, member) \ ++ list_entry((ptr)->next, type, member) ++ ++/* max ELS frame Size */ ++#define FC_PAYLOAD_MAXLEN 2048 ++ ++struct els_marginal_list { ++ uint32_t event_code; ++ uint16_t host_num; ++ uint16_t length; ++ char payload[FC_PAYLOAD_MAXLEN]; ++ struct list_head node; ++}; ++/* Structure to store the marginal devices info */ ++struct marginal_dev_list { ++ char dev_t[BLK_DEV_SIZE]; ++ uint32_t host_num; ++ struct list_head node; ++}; ++ ++static void _udev_device_unref(void *p) ++{ ++ udev_device_unref(p); ++} ++ ++ ++/*set/unset the path state to marginal*/ ++static int fpin_set_pathstate(struct path *pp, bool set) ++{ ++ const char *action = set ? "set" : "unset"; ++ ++ if (!pp || !pp->mpp || !pp->mpp->alias) ++ return -1; ++ ++ condlog(3, "\n%s: %s marginal path %s (fpin)", ++ action, pp->mpp->alias, pp->dev_t); ++ pp->marginal = set; ++ pp->mpp->fpin_must_reload = true; ++ return 0; ++} ++ ++/* This will unset marginal state of a device*/ ++static void fpin_path_unsetmarginal(char *devname, struct vectors *vecs) ++{ ++ struct path *pp; ++ ++ pp = find_path_by_dev(vecs->pathvec, devname); ++ if (!pp) ++ pp = find_path_by_devt(vecs->pathvec, devname); ++ ++ fpin_set_pathstate(pp, false); ++} ++ ++/*This will set the marginal state of a device*/ ++static int fpin_path_setmarginal(struct path *pp) ++{ ++ return fpin_set_pathstate(pp, true); ++} ++ ++/* Unsets all the devices in the list from marginal state */ ++static void ++fpin_unset_marginal_dev(uint32_t host_num, struct vectors *vecs) ++{ ++ struct marginal_dev_list *tmp_marg = NULL; ++ struct marginal_dev_list *marg = NULL; ++ struct multipath *mpp; ++ int ret = 0; ++ int i; ++ ++ pthread_cleanup_push(cleanup_lock, &vecs->lock); ++ lock(&vecs->lock); ++ pthread_testcancel(); ++ ++ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); ++ pthread_cleanup_push(cleanup_mutex, &fpin_li_marginal_dev_mutex); ++ pthread_testcancel(); ++ if (list_empty(&fpin_li_marginal_dev_list_head)) { ++ condlog(4, "Marginal List is empty\n"); ++ goto empty; ++ } ++ list_for_each_entry_safe(marg, tmp_marg, &fpin_li_marginal_dev_list_head, node) { ++ if (marg->host_num != host_num) ++ continue; ++ condlog(4, " unsetting marginal dev: is %s %d\n", ++ tmp_marg->dev_t, tmp_marg->host_num); ++ fpin_path_unsetmarginal(marg->dev_t, vecs); ++ list_del(&marg->node); ++ free(marg); ++ } ++empty: ++ pthread_cleanup_pop(1); ++ /* walk backwards because reload_and_sync_map() can remove mpp */ ++ vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { ++ if (mpp->fpin_must_reload) { ++ ret = reload_and_sync_map(mpp, vecs, 0); ++ if (ret == 2) ++ condlog(2, "map removed during reload"); ++ else ++ mpp->fpin_must_reload = false; ++ } ++ } ++ pthread_cleanup_pop(1); ++} ++ ++/* ++ * On Receiving the frame from HBA driver, insert the frame into link ++ * integrity frame list which will be picked up later by consumer thread for ++ * processing. ++ */ ++static int ++fpin_els_add_li_frame(struct fc_nl_event *fc_event) ++{ ++ struct els_marginal_list *els_mrg = NULL; ++ int ret = 0; ++ ++ if (fc_event->event_datalen > FC_PAYLOAD_MAXLEN) ++ return -EINVAL; ++ ++ pthread_mutex_lock(&fpin_li_mutex); ++ pthread_cleanup_push(cleanup_mutex, &fpin_li_mutex); ++ pthread_testcancel(); ++ els_mrg = calloc(1, sizeof(struct els_marginal_list)); ++ if (els_mrg != NULL) { ++ els_mrg->host_num = fc_event->host_no; ++ els_mrg->event_code = fc_event->event_code; ++ els_mrg->length = fc_event->event_datalen; ++ memcpy(els_mrg->payload, &(fc_event->event_data), fc_event->event_datalen); ++ list_add_tail(&els_mrg->node, &els_marginal_list_head); ++ pthread_cond_signal(&fpin_li_cond); ++ } else ++ ret = -ENOMEM; ++ pthread_cleanup_pop(1); ++ return ret; ++ ++} ++ ++/*Sets the rport port_state to marginal*/ ++static void fpin_set_rport_marginal(struct udev_device *rport_dev) ++{ ++ sysfs_attr_set_value(rport_dev, "port_state", ++ "Marginal", strlen("Marginal")); ++} ++ ++/*Add the marginal devices info into the list*/ ++static void ++fpin_add_marginal_dev_info(uint32_t host_num, char *devname) ++{ ++ struct marginal_dev_list *newdev = NULL; ++ ++ newdev = calloc(1, sizeof(struct marginal_dev_list)); ++ if (newdev != NULL) { ++ newdev->host_num = host_num; ++ strlcpy(newdev->dev_t, devname, BLK_DEV_SIZE); ++ condlog(4, "\n%s hostno %d devname %s\n", __func__, ++ host_num, newdev->dev_t); ++ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); ++ list_add_tail(&(newdev->node), ++ &fpin_li_marginal_dev_list_head); ++ pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); ++ } ++} ++ ++/* ++ * This function goes through the vecs->pathvec, and for ++ * each path, check that the host number, ++ * the target WWPN associated with the path matches ++ * with the els wwpn and sets the path and port state to ++ * Marginal ++ */ ++static int fpin_chk_wwn_setpath_marginal(uint16_t host_num, struct vectors *vecs, ++ uint64_t els_wwpn) ++{ ++ struct path *pp; ++ struct multipath *mpp; ++ int i, k; ++ char rport_id[42]; ++ const char *value = NULL; ++ struct udev_device *rport_dev = NULL; ++ uint64_t wwpn; ++ int ret = 0; ++ ++ pthread_cleanup_push(cleanup_lock, &vecs->lock); ++ lock(&vecs->lock); ++ pthread_testcancel(); ++ ++ vector_foreach_slot(vecs->pathvec, pp, k) { ++ /* Checks the host number and also for the SCSI FCP */ ++ if (pp->sg_id.proto_id != SCSI_PROTOCOL_FCP || host_num != pp->sg_id.host_no) ++ continue; ++ sprintf(rport_id, "rport-%d:%d-%d", ++ pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.transport_id); ++ rport_dev = udev_device_new_from_subsystem_sysname(udev, ++ "fc_remote_ports", rport_id); ++ if (!rport_dev) { ++ condlog(2, "%s: No fc_remote_port device for '%s'", pp->dev, ++ rport_id); ++ continue; ++ } ++ pthread_cleanup_push(_udev_device_unref, rport_dev); ++ value = udev_device_get_sysattr_value(rport_dev, "port_name"); ++ if (!value) ++ goto unref; ++ ++ if (value) ++ wwpn = strtol(value, NULL, 16); ++ /* ++ * If the port wwpn matches sets the path and port state ++ * to marginal ++ */ ++ if (wwpn == els_wwpn) { ++ ret = fpin_path_setmarginal(pp); ++ if (ret < 0) ++ goto unref; ++ fpin_set_rport_marginal(rport_dev); ++ fpin_add_marginal_dev_info(host_num, pp->dev); ++ } ++unref: ++ pthread_cleanup_pop(1); ++ } ++ /* walk backwards because reload_and_sync_map() can remove mpp */ ++ vector_foreach_slot_backwards(vecs->mpvec, mpp, i) { ++ if (mpp->fpin_must_reload) { ++ ret = reload_and_sync_map(mpp, vecs, 0); ++ if (ret == 2) ++ condlog(2, "map removed during reload"); ++ else ++ mpp->fpin_must_reload = false; ++ } ++ } ++ pthread_cleanup_pop(1); ++ return ret; ++} ++ ++/* ++ * This function loops around all the impacted wwns received as part of els ++ * frame and sets the associated path and port states to marginal. ++ */ ++static int ++fpin_parse_li_els_setpath_marginal(uint16_t host_num, struct fc_tlv_desc *tlv, ++ struct vectors *vecs) ++{ ++ uint32_t wwn_count = 0, iter = 0; ++ uint64_t wwpn; ++ struct fc_fn_li_desc *li_desc = (struct fc_fn_li_desc *)tlv; ++ int count = 0; ++ int ret = 0; ++ ++ /* Update the wwn to list */ ++ wwn_count = be32_to_cpu(li_desc->pname_count); ++ condlog(4, "Got wwn count as %d\n", wwn_count); ++ ++ for (iter = 0; iter < wwn_count; iter++) { ++ wwpn = be64_to_cpu(li_desc->pname_list[iter]); ++ ret = fpin_chk_wwn_setpath_marginal(host_num, vecs, wwpn); ++ if (ret < 0) ++ condlog(2, "failed to set the path marginal associated with wwpn: 0x%" PRIx64 "\n", wwpn); ++ ++ count++; ++ } ++ return count; ++} ++ ++/* ++ * This function process the ELS frame received from HBA driver, ++ * and sets the path associated with the port wwn to marginal ++ * and also set the port state to marginal. ++ */ ++static int ++fpin_process_els_frame(uint16_t host_num, char *fc_payload, struct vectors *vecs) ++{ ++ ++ int count = -1; ++ struct fc_els_fpin *fpin = (struct fc_els_fpin *)fc_payload; ++ struct fc_tlv_desc *tlv; ++ ++ tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0]; ++ ++ /* ++ * Parse the els frame and set the affected paths and port ++ * state to marginal ++ */ ++ count = fpin_parse_li_els_setpath_marginal(host_num, tlv, vecs); ++ if (count <= 0) ++ condlog(4, "Could not find any WWNs, ret = %d\n", ++ count); ++ return count; ++} ++ ++/* ++ * This function process the FPIN ELS frame received from HBA driver, ++ * and push the frame to appropriate frame list. Currently we have only FPIN ++ * LI frame list. ++ */ ++static int ++fpin_handle_els_frame(struct fc_nl_event *fc_event) ++{ ++ int ret = -1; ++ uint32_t els_cmd; ++ struct fc_els_fpin *fpin = (struct fc_els_fpin *)&fc_event->event_data; ++ struct fc_tlv_desc *tlv; ++ uint32_t dtag; ++ ++ els_cmd = (uint32_t)fc_event->event_data; ++ tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0]; ++ dtag = be32_to_cpu(tlv->desc_tag); ++ condlog(4, "Got CMD in add as 0x%x fpin_cmd 0x%x dtag 0x%x\n", ++ els_cmd, fpin->fpin_cmd, dtag); ++ ++ if ((fc_event->event_code == FCH_EVT_LINK_FPIN) || ++ (fc_event->event_code == FCH_EVT_LINKUP) || ++ (fc_event->event_code == FCH_EVT_RSCN)) { ++ ++ if (els_cmd == ELS_FPIN) { ++ /* ++ * Check the type of fpin by checking the tag info ++ * At present we are supporting only LI events ++ */ ++ if (dtag == ELS_DTAG_LNK_INTEGRITY) { ++ /*Push the Payload to FPIN frame queue. */ ++ ret = fpin_els_add_li_frame(fc_event); ++ if (ret != 0) ++ condlog(0, "Failed to process LI frame with error %d\n", ++ ret); ++ } else { ++ condlog(4, "Unsupported FPIN received 0x%x\n", dtag); ++ return ret; ++ } ++ } else { ++ /*Push the Payload to FPIN frame queue. */ ++ ret = fpin_els_add_li_frame(fc_event); ++ if (ret != 0) ++ condlog(0, "Failed to process Linkup/RSCN event with error %d evnt %d\n", ++ ret, fc_event->event_code); ++ } ++ } else ++ condlog(4, "Invalid command received: 0x%x\n", els_cmd); ++ return ret; ++} ++ ++/*cleans the global marginal dev list*/ ++void fpin_clean_marginal_dev_list(__attribute__((unused)) void *arg) ++{ ++ struct marginal_dev_list *tmp_marg = NULL; ++ ++ pthread_mutex_lock(&fpin_li_marginal_dev_mutex); ++ while (!list_empty(&fpin_li_marginal_dev_list_head)) { ++ tmp_marg = list_first_entry(&fpin_li_marginal_dev_list_head, ++ struct marginal_dev_list, node); ++ list_del(&tmp_marg->node); ++ free(tmp_marg); ++ } ++ pthread_mutex_unlock(&fpin_li_marginal_dev_mutex); ++} ++ ++/* Cleans the global els marginal list */ ++static void fpin_clean_els_marginal_list(void *arg) ++{ ++ struct list_head *head = (struct list_head *)arg; ++ struct els_marginal_list *els_marg; ++ ++ while (!list_empty(head)) { ++ els_marg = list_first_entry(head, struct els_marginal_list, ++ node); ++ list_del(&els_marg->node); ++ free(els_marg); ++ } ++} ++ ++static void rcu_unregister(__attribute__((unused)) void *param) ++{ ++ rcu_unregister_thread(); ++} ++/* ++ * This is the FPIN ELS consumer thread. The thread sleeps on pthread cond ++ * variable unless notified by fpin_fabric_notification_receiver thread. ++ * This thread is only to process FPIN-LI ELS frames. A new thread and frame ++ * list will be added if any more ELS frames types are to be supported. ++ */ ++void *fpin_els_li_consumer(void *data) ++{ ++ struct list_head marginal_list_head; ++ int ret = 0; ++ uint16_t host_num; ++ struct els_marginal_list *els_marg; ++ uint32_t event_code; ++ struct vectors *vecs = (struct vectors *)data; ++ ++ pthread_cleanup_push(rcu_unregister, NULL); ++ rcu_register_thread(); ++ pthread_cleanup_push(fpin_clean_marginal_dev_list, NULL); ++ INIT_LIST_HEAD(&marginal_list_head); ++ pthread_cleanup_push(fpin_clean_els_marginal_list, ++ (void *)&marginal_list_head); ++ for ( ; ; ) { ++ pthread_mutex_lock(&fpin_li_mutex); ++ pthread_cleanup_push(cleanup_mutex, &fpin_li_mutex); ++ pthread_testcancel(); ++ while (list_empty(&els_marginal_list_head)) ++ pthread_cond_wait(&fpin_li_cond, &fpin_li_mutex); ++ ++ if (!list_empty(&els_marginal_list_head)) { ++ condlog(4, "Invoke List splice tail\n"); ++ list_splice_tail_init(&els_marginal_list_head, &marginal_list_head); ++ } ++ pthread_cleanup_pop(1); ++ ++ while (!list_empty(&marginal_list_head)) { ++ els_marg = list_first_entry(&marginal_list_head, ++ struct els_marginal_list, node); ++ host_num = els_marg->host_num; ++ event_code = els_marg->event_code; ++ /* Now finally process FPIN LI ELS Frame */ ++ condlog(4, "Got a new Payload buffer, processing it\n"); ++ if ((event_code == FCH_EVT_LINKUP) || (event_code == FCH_EVT_RSCN)) ++ fpin_unset_marginal_dev(host_num, vecs); ++ else { ++ ret = fpin_process_els_frame(host_num, els_marg->payload, vecs); ++ if (ret <= 0) ++ condlog(0, "ELS frame processing failed with ret %d\n", ret); ++ } ++ list_del(&els_marg->node); ++ free(els_marg); ++ ++ } ++ } ++ ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ return NULL; ++} ++ ++static void receiver_cleanup_list(__attribute__((unused)) void *arg) ++{ ++ pthread_mutex_lock(&fpin_li_mutex); ++ fpin_clean_els_marginal_list(&els_marginal_list_head); ++ pthread_mutex_unlock(&fpin_li_mutex); ++} ++ ++/* ++ * Listen for ELS frames from driver. on receiving the frame payload, ++ * push the payload to a list, and notify the fpin_els_li_consumer thread to ++ * process it. Once consumer thread is notified, return to listen for more ELS ++ * frames from driver. ++ */ ++void *fpin_fabric_notification_receiver(__attribute__((unused))void *unused) ++{ ++ int ret; ++ long fd; ++ uint32_t els_cmd; ++ struct fc_nl_event *fc_event = NULL; ++ struct sockaddr_nl fc_local; ++ unsigned char buf[DEF_RX_BUF_SIZE] __attribute__((aligned(sizeof(uint64_t)))); ++ size_t plen = 0; ++ ++ pthread_cleanup_push(rcu_unregister, NULL); ++ rcu_register_thread(); ++ ++ pthread_cleanup_push(receiver_cleanup_list, NULL); ++ fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_SCSITRANSPORT); ++ if (fd < 0) { ++ condlog(0, "fc socket error %ld", fd); ++ return NULL; ++ } ++ ++ pthread_cleanup_push(close_fd, (void *)fd); ++ memset(&fc_local, 0, sizeof(fc_local)); ++ fc_local.nl_family = AF_NETLINK; ++ fc_local.nl_groups = ~0; ++ fc_local.nl_pid = getpid(); ++ ret = bind(fd, (struct sockaddr *)&fc_local, sizeof(fc_local)); ++ if (ret == -1) { ++ condlog(0, "fc socket bind error %d\n", ret); ++ goto out; ++ } ++ for ( ; ; ) { ++ condlog(4, "Waiting for ELS...\n"); ++ ret = read(fd, buf, DEF_RX_BUF_SIZE); ++ if (ret < 0) { ++ condlog(0, "failed to read the els frame (%d)", ret); ++ continue; ++ } ++ condlog(4, "Got a new request %d\n", ret); ++ if (!NLMSG_OK((struct nlmsghdr *)buf, (unsigned int)ret)) { ++ condlog(0, "bad els frame read (%d)", ret); ++ continue; ++ } ++ /* Push the frame to appropriate frame list */ ++ plen = NLMSG_PAYLOAD((struct nlmsghdr *)buf, 0); ++ fc_event = (struct fc_nl_event *)NLMSG_DATA(buf); ++ if (plen < sizeof(*fc_event)) { ++ condlog(0, "too short (%d) to be an FC event", ret); ++ continue; ++ } ++ els_cmd = (uint32_t)fc_event->event_data; ++ condlog(4, "Got host no as %d, event 0x%x, len %d evntnum %d evntcode %d\n", ++ fc_event->host_no, els_cmd, fc_event->event_datalen, ++ fc_event->event_num, fc_event->event_code); ++ fpin_handle_els_frame(fc_event); ++ } ++out: ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ pthread_cleanup_pop(1); ++ return NULL; ++} +diff --git a/multipathd/main.c b/multipathd/main.c +index 5def5301..53be9b95 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include "fpin.h" + #ifdef USE_SYSTEMD + #include + #endif +@@ -130,9 +131,11 @@ static volatile enum daemon_status running_state = DAEMON_INIT; + pid_t daemon_pid; + static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER; + static pthread_cond_t config_cond; +-static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr; ++static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr, ++ fpin_thr, fpin_consumer_thr; + static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started, +- uevq_thr_started, dmevent_thr_started; ++ uevq_thr_started, dmevent_thr_started, fpin_thr_started, ++ fpin_consumer_thr_started; + static int pid_fd = -1; + + static inline enum daemon_status get_running_state(void) +@@ -2819,7 +2822,9 @@ reconfigure (struct vectors * vecs) + conf->sequence_nr = old->sequence_nr + 1; + rcu_assign_pointer(multipath_conf, conf); + call_rcu(&old->rcu, rcu_free_config); +- ++#ifdef FPIN_EVENT_HANDLER ++ fpin_clean_marginal_dev_list(NULL); ++#endif + configure(vecs); + + +@@ -3060,6 +3065,11 @@ static void cleanup_threads(void) + pthread_cancel(uevq_thr); + if (dmevent_thr_started) + pthread_cancel(dmevent_thr); ++ if (fpin_thr_started) ++ pthread_cancel(fpin_thr); ++ if (fpin_consumer_thr_started) ++ pthread_cancel(fpin_consumer_thr); ++ + + if (check_thr_started) + pthread_join(check_thr, NULL); +@@ -3071,6 +3081,11 @@ static void cleanup_threads(void) + pthread_join(uevq_thr, NULL); + if (dmevent_thr_started) + pthread_join(dmevent_thr, NULL); ++ if (fpin_thr_started) ++ pthread_join(fpin_thr, NULL); ++ if (fpin_consumer_thr_started) ++ pthread_join(fpin_consumer_thr, NULL); ++ + + /* + * As all threads are joined now, and we're in DAEMON_SHUTDOWN +@@ -3168,6 +3183,7 @@ child (__attribute__((unused)) void *param) + char *envp; + enum daemon_status state; + int exit_code = 1; ++ int fpin_marginal_paths = 0; + + init_unwinder(); + mlockall(MCL_CURRENT | MCL_FUTURE); +@@ -3246,7 +3262,10 @@ child (__attribute__((unused)) void *param) + + setscheduler(); + set_oom_adj(); +- ++#ifdef FPIN_EVENT_HANDLER ++ if (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) ++ fpin_marginal_paths = 1; ++#endif + /* + * Startup done, invalidate configuration + */ +@@ -3314,6 +3333,22 @@ child (__attribute__((unused)) void *param) + goto failed; + } else + uevq_thr_started = true; ++ ++ if (fpin_marginal_paths) { ++ if ((rc = pthread_create(&fpin_thr, &misc_attr, ++ fpin_fabric_notification_receiver, NULL))) { ++ condlog(0, "failed to create the fpin receiver thread: %d", rc); ++ goto failed; ++ } else ++ fpin_thr_started = true; ++ ++ if ((rc = pthread_create(&fpin_consumer_thr, ++ &misc_attr, fpin_els_li_consumer, vecs))) { ++ condlog(0, "failed to create the fpin consumer thread thread: %d", rc); ++ goto failed; ++ } else ++ fpin_consumer_thr_started = true; ++ } + pthread_attr_destroy(&misc_attr); + + while (1) { diff --git a/SOURCES/0042-multipathd-disallow-changing-to-from-fpin-marginal-p.patch b/SOURCES/0042-multipathd-disallow-changing-to-from-fpin-marginal-p.patch new file mode 100644 index 0000000..dda0f30 --- /dev/null +++ b/SOURCES/0042-multipathd-disallow-changing-to-from-fpin-marginal-p.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 11 Feb 2022 17:23:39 -0600 +Subject: [PATCH] multipathd: disallow changing to/from fpin marginal paths on + reconfig + +Setting marginal_pathgroups to fpin causes two new threads to be created +when multipathd starts. Turning it on after multipathd starts up won't +cause the theads to start, and turing it off won't keep the threads from +working. So disallow changing marginal_pathgroups to/from "fpin" on +reconfigure. + +Signed-off-by: Benjamin Marzinski +--- + multipath/multipath.conf.5 | 13 ++++++++----- + multipathd/main.c | 9 +++++++++ + 2 files changed, 17 insertions(+), 5 deletions(-) + +diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 +index 5ed2cd3c..58ad5c9c 100644 +--- a/multipath/multipath.conf.5 ++++ b/multipath/multipath.conf.5 +@@ -1102,15 +1102,18 @@ have been tried first. This prevents the possibility of IO errors occuring + while marginal paths are still usable. After the path has been monitored + for the configured time, and is declared healthy, it will be returned to its + normal pathgroup. +-However if this option is set to \fIfpin\fR multipathd will receive fpin ++If this option is set to \fIfpin\fR, multipathd will receive fpin + notifications, set path states to "marginal" accordingly, and regroup paths +-as described for "marginal_pathgroups yes". This option can't be used in combination +-with other options for "Shaky path detection" (see below).If it is set to fpin, +-marginal_path_xyz and san_path_err_xyz parameters are implicitly set to 0. ++as described for \fIon\fR. This option can't be used in combination ++with other options for "Shaky path detection" (see below). \fBNote:\fR If this ++is set to \fIfpin\fR, the \fImarginal_path_*\fR and \fIsan_path_err_*\fR ++options are implicitly set to \fIno\fP. Also, this option cannot be switched ++either to or from \fIfpin\fR on a multipathd reconfigure. multipathd must be ++restarted for the change to take effect. + See "Shaky paths detection" below for more information. + .RS + .TP +-The default is: \fBno\fR ++The default is: \fBoff\fR + .RE + . + . +diff --git a/multipathd/main.c b/multipathd/main.c +index 53be9b95..45b9572f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2792,6 +2792,7 @@ int + reconfigure (struct vectors * vecs) + { + struct config * old, *conf; ++ int old_marginal_pathgroups; + + conf = load_config(DEFAULT_CONFIGFILE); + if (!conf) +@@ -2819,6 +2820,14 @@ reconfigure (struct vectors * vecs) + uxsock_timeout = conf->uxsock_timeout; + + old = rcu_dereference(multipath_conf); ++ old_marginal_pathgroups = old->marginal_pathgroups; ++ if ((old_marginal_pathgroups == MARGINAL_PATHGROUP_FPIN) != ++ (conf->marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)) { ++ condlog(1, "multipathd must be restarted to turn %s fpin marginal paths", ++ (old_marginal_pathgroups == MARGINAL_PATHGROUP_FPIN)? ++ "off" : "on"); ++ conf->marginal_pathgroups = old_marginal_pathgroups; ++ } + conf->sequence_nr = old->sequence_nr + 1; + rcu_assign_pointer(multipath_conf, conf); + call_rcu(&old->rcu, rcu_free_config); diff --git a/SOURCES/0043-libmultipath-fix-printing-native-nvme-multipath-topo.patch b/SOURCES/0043-libmultipath-fix-printing-native-nvme-multipath-topo.patch new file mode 100644 index 0000000..2b04627 --- /dev/null +++ b/SOURCES/0043-libmultipath-fix-printing-native-nvme-multipath-topo.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 16 Feb 2022 00:12:29 -0600 +Subject: [PATCH] libmultipath: fix printing native nvme multipath topology. + +Since commit 2f05df4 ("libmultipath: use strbuf in print.c"), when +multipath prints the topology of native nvme devices, instead of +printing the multipath device information, it prints "w [G]:d s". This +is because nvme_style() switched from calling snprintf(), which supports +format specifiers, to append_strbuf_str(), which doesn't, while still +keeping the same string, "%%w [%%G]:%%d %%s". Remove the extra percent +signs, since they don't need to be escaped in append_strbuf_str(). + +Fixes: 2f05df4 ("libmultipath: use strbuf in print.c") +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +--- + libmultipath/foreign/nvme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/foreign/nvme.c b/libmultipath/foreign/nvme.c +index d40c0869..23355ca5 100644 +--- a/libmultipath/foreign/nvme.c ++++ b/libmultipath/foreign/nvme.c +@@ -335,7 +335,7 @@ static int snprint_nvme_pg(const struct gen_pathgroup *gmp, + static int nvme_style(__attribute__((unused)) const struct gen_multipath* gm, + struct strbuf *buf, __attribute__((unused)) int verbosity) + { +- return append_strbuf_str(buf, "%%w [%%G]:%%d %%s"); ++ return append_strbuf_str(buf, "%w [%G]:%d %s"); + } + + static const struct gen_multipath_ops nvme_map_ops = { diff --git a/SOURCES/multipath.conf b/SOURCES/multipath.conf new file mode 100644 index 0000000..c7684fe --- /dev/null +++ b/SOURCES/multipath.conf @@ -0,0 +1,93 @@ +# This is a basic configuration file with some examples, for device mapper +# multipath. +# +# For a complete list of the default configuration values, run either +# multipath -t +# or +# multipathd show config +# +# For a list of configuration options with descriptions, see the multipath.conf +# man page + +## By default, devices with vendor = "IBM" and product = "S/390.*" are +## blacklisted. To enable mulitpathing on these devies, uncomment the +## following lines. +#blacklist_exceptions { +# device { +# vendor "IBM" +# product "S/390.*" +# } +#} + +## Use user friendly names, instead of using WWIDs as names. +defaults { + user_friendly_names yes + find_multipaths yes +} +## +## Here is an example of how to configure some standard options. +## +# +#defaults { +# udev_dir /dev +# polling_interval 10 +# selector "round-robin 0" +# path_grouping_policy multibus +# prio alua +# path_checker readsector0 +# rr_min_io 100 +# max_fds 8192 +# rr_weight priorities +# failback immediate +# no_path_retry fail +# user_friendly_names yes +#} +## +## The wwid line in the following blacklist section is shown as an example +## of how to blacklist devices by wwid. The 2 devnode lines are the +## compiled in default blacklist. If you want to blacklist entire types +## of devices, such as all scsi devices, you should use a devnode line. +## However, if you want to blacklist specific devices, you should use +## a wwid line. Since there is no guarantee that a specific device will +## not change names on reboot (from /dev/sda to /dev/sdb for example) +## devnode lines are not recommended for blacklisting specific devices. +## +#blacklist { +# wwid 26353900f02796769 +# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +# devnode "^hd[a-z]" +#} +#multipaths { +# multipath { +# wwid 3600508b4000156d700012000000b0000 +# alias yellow +# path_grouping_policy multibus +# path_checker readsector0 +# path_selector "round-robin 0" +# failback manual +# rr_weight priorities +# no_path_retry 5 +# } +# multipath { +# wwid 1DEC_____321816758474 +# alias red +# } +#} +#devices { +# device { +# vendor "COMPAQ " +# product "HSV110 (C)COMPAQ" +# path_grouping_policy multibus +# path_checker readsector0 +# path_selector "round-robin 0" +# hardware_handler "0" +# failback 15 +# rr_weight priorities +# no_path_retry queue +# } +# device { +# vendor "COMPAQ " +# product "MSA1000 " +# path_grouping_policy multibus +# } +#} diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec new file mode 100644 index 0000000..7a88f74 --- /dev/null +++ b/SPECS/device-mapper-multipath.spec @@ -0,0 +1,2004 @@ +Name: device-mapper-multipath +Version: 0.8.7 +Release: 7%{?dist} +Summary: Tools to manage multipath devices using device-mapper +License: GPLv2 +URL: http://christophe.varoqui.free.fr/ + +# The source for this package was pulled from upstream's git repo. Use the +# following command to generate the tarball +# curl -L https://github.com/opensvc/multipath-tools/archive/0.8.7.tar.gz -o multipath-tools-0.8.7.tgz +Source0: multipath-tools-0.8.7.tgz +Source1: multipath.conf +Patch0001: 0001-multipath-tools-add-info-about-IO-affinity-path-sele.patch +Patch0002: 0002-multipathd-fix-missing-persistent-reseravtion-for-ac.patch +Patch0003: 0003-multipath-tools-minor-fixes-to-multipath.conf.5-man-.patch +Patch0004: 0004-multipath-tools-make-IBM-XIV-config-work-with-alua-a.patch +Patch0005: 0005-multipathd.socket-add-missing-conditions-from-servic.patch +Patch0006: 0006-multipath-tools-make-IBM-2107900-DS8000-config-work-.patch +Patch0007: 0007-multipath-tools-make-EMC-SYMMETRIX-config-work-with-.patch +Patch0008: 0008-multipath-tools-make-EMC-Invista-config-work-with-al.patch +Patch0009: 0009-multipath-tools-make-COMPELNT-Compellent-Vol-config-.patch +Patch0010: 0010-multipath-tools-remove-Compellent-maintainer.patch +Patch0011: 0011-Revert-multipath-tools-make-EMC-Invista-config-work-.patch +Patch0012: 0012-Revert-multipath-tools-make-EMC-SYMMETRIX-config-wor.patch +Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch +Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0015: 0015-RH-don-t-start-without-a-config-file.patch +Patch0016: 0016-RH-Fix-nvme-function-missing-argument.patch +Patch0017: 0017-RH-use-rpm-optflags-if-present.patch +Patch0018: 0018-RH-add-mpathconf.patch +Patch0019: 0019-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0021: 0021-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +Patch0022: 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch +Patch0023: 0023-libmultipath-add-section-name-to-invalid-keyword-out.patch +Patch0024: 0024-libmultipath-use-typedef-for-keyword-handler-functio.patch +Patch0025: 0025-libmultipath-print-the-correct-file-when-parsing-fai.patch +Patch0026: 0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +Patch0027: 0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch +Patch0028: 0028-libmultipath-improve-checks-for-set_str.patch +Patch0029: 0029-libmultipath-deprecate-file-and-directory-config-opt.patch +Patch0030: 0030-libmultipath-split-set_int-to-enable-reuse.patch +Patch0031: 0031-libmultipath-cleanup-invalid-config-handling.patch +Patch0032: 0032-libmultipath-don-t-return-error-on-invalid-values.patch +Patch0033: 0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch +Patch0034: 0034-multipath-fix-exit-status-of-multipath-T.patch +Patch0035: 0035-RH-mpathconf-fix-setting-property_blacklist.patch +Patch0036: 0036-libmultipath-fix-disassemble-status-for-historical-s.patch +Patch0037: 0037-libmultipath-make-helper-function-to-trigger-path-ue.patch +Patch0038: 0038-multipathd-trigger-udev-change-on-path-addition.patch +Patch0039: 0039-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch +Patch0040: 0040-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch +Patch0041: 0041-multipathd-handle-fpin-events.patch +Patch0042: 0042-multipathd-disallow-changing-to-from-fpin-marginal-p.patch +Patch0043: 0043-libmultipath-fix-printing-native-nvme-multipath-topo.patch + + +# runtime +Requires: %{name}-libs = %{version}-%{release} +Requires: kpartx = %{version}-%{release} +Requires: device-mapper >= 1.02.96 +Requires: userspace-rcu +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +# Starting with 0.7.7-1, 62-multipath.rules changed in a way that is +# incompatible with 65-md-incremental.rules in earlier mdadm packages. +# Later mdadm packages are compatible with any version of +# device-mapper-multipath. See bz #1628192 for more details +Conflicts: mdadm < 4.1-rc2.0.2 +# Starting with 0.7.7-1, 62-multipath.rules changed in a way that is +# incompatible with 80-udisks2.rules in earlier udisks2 packages. +# Later udisks2 packages are compatible with any version of +# device-mapper-multipath. See bz #1628192 for more details +Conflicts: udisks2 < 2.8.0-2 + +# build/setup +BuildRequires: libaio-devel, device-mapper-devel >= 1.02.89 +BuildRequires: libselinux-devel, libsepol-devel +BuildRequires: readline-devel, ncurses-devel +BuildRequires: systemd-units, systemd-devel +BuildRequires: json-c-devel, perl-interpreter, pkgconfig, gcc +BuildRequires: userspace-rcu-devel +BuildRequires: make + +%description +%{name} provides tools to manage multipath devices by +instructing the device-mapper multipath kernel module what to do. +The tools are : +* multipath - Scan the system for multipath devices and assemble them. +* multipathd - Detects when paths fail and execs multipath to update things. + +%package libs +Summary: The %{name} modules and shared library +# only libmpathcmd is LGPLv2+ +License: GPLv2 and LGPLv2+ + +%description libs +The %{name}-libs provides the path checker +and prioritizer modules. It also contains the libmpathpersist and +libmpathcmd shared libraries, as well as multipath's internal library, +libmultipath. + +%package devel +Summary: Development libraries and headers for %{name} +Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} + +%description devel +This package contains the files need to develop applications that use +device-mapper-multipath's lbmpathpersist and libmpathcmd libraries. + +%package -n kpartx +Summary: Partition device manager for device-mapper devices + +%description -n kpartx +kpartx manages partition creation and removal for device-mapper devices. + +%package -n libdmmp +Summary: device-mapper-multipath C API library +License: GPLv3+ +Requires: json-c +Requires: %{name} = %{version}-%{release} +Requires: %{name}-libs = %{version}-%{release} + +%description -n libdmmp +This package contains the shared library for the device-mapper-multipath +C API library. + +%package -n libdmmp-devel +Summary: device-mapper-multipath C API library headers +Requires: pkgconfig +Requires: libdmmp = %{version}-%{release} + +%description -n libdmmp-devel +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.7 -p1 +cp %{SOURCE1} . + +%build +%define _sbindir /usr/sbin +%define _libdir /usr/%{_lib} +%define _udevdir /usr/lib/udev +%define _libmpathdir %{_libdir}/multipath +%define _pkgconfdir %{_libdir}/pkgconfig +%make_build LIB=%{_lib} + +%install +%make_install \ + bindir=%{_sbindir} \ + syslibdir=%{_libdir} \ + usrlibdir=%{_libdir} \ + libdir=%{_libmpathdir} \ + rcdir=%{_initrddir} \ + unitdir=%{_unitdir} \ + includedir=%{_includedir} \ + pkgconfdir=%{_pkgconfdir} + +# tree fix up +install -d %{buildroot}/etc/multipath +rm -rf %{buildroot}/%{_initrddir} + + +%post +%systemd_post multipathd.service + +%preun +%systemd_preun multipathd.service + +%postun +if [ $1 -ge 1 ] ; then + /sbin/multipathd forcequeueing daemon > /dev/null 2>&1 || : +fi +%systemd_postun_with_restart multipathd.service + +%triggerun -- %{name} < 0.4.9-37 +# make sure old systemd symlinks are removed after changing the [Install] +# section in multipathd.service from multi-user.target to sysinit.target +/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 +%{_sbindir}/multipath +%{_sbindir}/multipathd +%{_sbindir}/mpathconf +%{_sbindir}/mpathpersist +%{_unitdir}/multipathd.service +%{_unitdir}/multipathd.socket +%{_mandir}/man5/multipath.conf.5.gz +%{_mandir}/man8/multipath.8.gz +%{_mandir}/man8/multipathd.8.gz +%{_mandir}/man8/mpathconf.8.gz +%{_mandir}/man8/mpathpersist.8.gz +%config %{_udevrulesdir}/62-multipath.rules +%config %{_udevrulesdir}/11-dm-mpath.rules +%doc README.md +%doc README.alua +%doc multipath.conf +%dir /etc/multipath + +%files libs +%license LICENSES/GPL-2.0 LICENSES/LGPL-2.0 +%doc README.md +%{_libdir}/libmultipath.so +%{_libdir}/libmultipath.so.* +%{_libdir}/libmpathpersist.so.* +%{_libdir}/libmpathcmd.so.* +%{_libdir}/libmpathvalid.so.* +%dir %{_libmpathdir} +%{_libmpathdir}/* + +%ldconfig_scriptlets libs + +%files devel +%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 + +%files -n kpartx +%license LICENSES/GPL-2.0 +%doc README.md +%{_sbindir}/kpartx +%{_udevdir}/kpartx_id +%{_mandir}/man8/kpartx.8.gz +%config %{_udevrulesdir}/11-dm-parts.rules +%config %{_udevrulesdir}/66-kpartx.rules +%config %{_udevrulesdir}/68-del-part-nodes.rules + +%files -n libdmmp +%license LICENSES/GPL-3.0 +%doc README.md +%{_libdir}/libdmmp.so.* + +%ldconfig_scriptlets -n libdmmp + +%files -n libdmmp-devel +%doc README.md +%{_libdir}/libdmmp.so +%dir %{_includedir}/libdmmp +%{_includedir}/libdmmp/* +%{_mandir}/man3/dmmp_* +%{_mandir}/man3/libdmmp.h.3.gz +%{_pkgconfdir}/libdmmp.pc + +%changelog +* Wed Feb 16 2022 Benjamin Marzinski - 0.8.7-7 +- Add 0043-libmultipath-fix-printing-native-nvme-multipath-topo.patch +- Resolves: bz #2054839 + +* Wed Feb 9 2022 Benjamin Marzinski - 0.8.7-6 +- Add 0041-multipathd-handle-fpin-events.patch +- Add 0042-multipathd-disallow-changing-to-from-fpin-marginal-p.patch + * Add "marginal_pathgroups fpin" for responding to PFIN-Li events + * Fixes bz #2053642 +- Modify tests/restate_module + * Always offline the path with the lowest priority + * Fixes bz #2052633 +- Resolves: bz #2052633, #2053642 + +* Mon Feb 7 2022 Benjamin Marzinski - 0.8.7-5 +- Add 0039-RH-add-support-to-mpathconf-for-setting-arbitrary-de.patch + * Fixes bz #2050421 +- Add 0040-RH-add-support-to-mpathconf-for-setting-recheck_wwid.patch + * Fixes bz #2039749 +- Resolves: bz #2039749, #2050421 + +* Tue Jan 18 2022 Benjamin Marzinski - 0.8.7-4 +- Add 0035-RH-mpathconf-fix-setting-property_blacklist.patch +- Add 0036-libmultipath-fix-disassemble-status-for-historical-s.patch + * Fixes bz #2042032 +- Add 0037-libmultipath-make-helper-function-to-trigger-path-ue.patch +- Add 0038-multipathd-trigger-udev-change-on-path-addition.patch + * Fixes bz #2028835 +- Resolves: bz #2028835, #2042032 + +* Fri Nov 19 2021 Benjamin Marzinski - 0.8.7-3 +- Add 0024-libmultipath-use-typedef-for-keyword-handler-functio.patch +- Add 0025-libmultipath-print-the-correct-file-when-parsing-fai.patch +- Add 0026-libmultipath-pass-file-and-line-number-to-keyword-ha.patch +- Add 0027-libmultipath-make-set_int-take-a-range-for-valid-val.patch +- Add 0028-libmultipath-improve-checks-for-set_str.patch +- Add 0029-libmultipath-deprecate-file-and-directory-config-opt.patch +- Add 0030-libmultipath-split-set_int-to-enable-reuse.patch +- Add 0031-libmultipath-cleanup-invalid-config-handling.patch +- Add 0032-libmultipath-don-t-return-error-on-invalid-values.patch + * The above 9 patches fix bz #2017969 +- Add 0033-multipathd-avoid-unnecessary-path-read-only-reloads.patch + * Fixes bz #2017979 +- Add 0034-multipath-fix-exit-status-of-multipath-T.patch +- Resolves: bz #2017969, #2017979 + +* Mon Nov 08 2021 Benjamin Marzinski - 0.8.7-2 +- Modify 0017-RH-use-rpm-optflags-if-present.patch + * use RPM_LF_FLAGS +- Modify 0018-RH-add-mpathconf.patch + * update default config to match multipath changes +- Modify 0022-RH-make-parse_vpd_pg83-match-scsi_id-output.patch + * fix cmocka vpd tests +- Rename 0023-libmulitpath-add-section-name-to-invalid-keyword-out.patch to + 0023-libmultipath-add-section-name-to-invalid-keyword-out.patch +- Resolves: bz#2017592 + +* Fri Oct 29 2021 Benjamin Marzinski - 0.8.7-1 +- Update Source to upstream version 0.8.7 plus upstream staged commits + * Previous patches 0011-0016 & 0018-0022 are included in the source tarball + * Fixes bz#2017592 +- Rename files + * Previous patches 0001-0010 are now patches 0013-0022 +- Modify 0018-RH-add-mpathconf.patch + * merged with previous patch 0017 +- Add 0023-libmulitpath-add-section-name-to-invalid-keyword-out.patch + * Fixes bz#1984303 +- Fix multipath_conf_syntax test to work with bz #1984303 +- Resolves: bz #1984303, #2017592 + +* Mon Aug 09 2021 Mohan Boddu - 0.8.6-7 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Fri Jul 23 2021 Benjamin Marzinski - 0.8.6-6 +- Add 0022-multipathd-cli_handlers-cleanup-setting-reply-length.patch + * Found by corosync +- Related: bz #1984921 + +* Fri Jul 23 2021 Benjamin Marzinski - 0.8.6-5 +- Add 0018-multipath.conf-fix-typo-in-ghost_delay-description.patch +- Add 0019-mpathpersist-fail-commands-when-no-usable-paths-exis.patch + * Fixes bz #1982613 +- Add 0020-multipath-print-warning-if-multipathd-is-not-running.patch + * Fixes bz #1982615 +- Add 0021-libmultipath-deal-with-dynamic-PTHREAD_STACK_MIN.patch + * Fixes bz #1984921 +- Resolves: bz #1982613, #1982615, #1984921 + +* Mon Jul 12 2021 Benjamin Marzinski - 0.8.6-4 +- Add 0017-RH-mpathconf-correctly-handle-spaces-after-option-na.patch +- Resolves: bz #1981594 + +* Wed May 19 2021 Benjamin Marzinski - 0.8.6-3 +- Add 0011-multipathd-don-t-fail-to-remove-path-once-the-map-is.patch +- Add 0012-multipathd-remove-duplicate-orphan_paths-in-flush_ma.patch +- Add 0013-multipathd-fix-ev_remove_path-return-code-handling.patch +- Add 0014-multipath-free-vectors-in-configure.patch +- Add 0015-kpartx-Don-t-leak-memory-when-getblock-returns-NULL.patch +- Add 0016-multipathd-don-t-rescan_path-on-wwid-change-in-uev_u.patch + * Above patches Fix bz #1938704 +- Resolves: bz #1938704 + +* Wed Apr 21 2021 Benjamin Marzinski - 0.8.6-2 +- Update spec file +- Related: bz #1951336 + + +* Mon Apr 19 2021 Benjamin Marzinski - 0.8.6-1 +- Update Source to upstream version 0.8.6 + * Previous patches 0001-0123 are included in the commit + * Fixes bz #1951336 +- Rename files + * Previous patches 0124-0132 are now patches 0001-0009 +- Add 0010-RH-make-parse_vpd_pg83-match-scsi_id-output.patch + * make scsi wwid fallback code result match the default udev wwid + code result (Red Hat specific patch) +- Sync tests with RHEL-8 +- Resolves: bz #1951336 + +* Thu Apr 15 2021 Mohan Boddu - 0.8.5-5 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Thu Feb 11 2021 Benjamin Marzinski - 0.8.5-4 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0121 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream + * Patches 0122&0123 have been posted for upstream inclusion +- Rename files + * Previous patches 0103-0111 are now patches 0124-0132 + +* Tue Jan 26 2021 Fedora Release Engineering - 0.8.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-2 +- Fix build issues + +* Tue Jan 19 2021 Benjamin Marzinski - 0.8.5-1 +- Update Source to upstream version 0.8.5 plus post tag commits + * Patches 0001-0102 are from + https://github.com/openSUSE/multipath-tools/tree/queue and are + already queued for upstream. +- Rename files + * Previous patches 0059-0068 are now patches 0103-0111 + + +* Sun Sep 27 2020 Benjamin Marzinski - 0.8.4-7 +- Add 0073-libmultipath-util-constify-function-arguments.patch +- Add 0074-libmultipath-constify-file-argument-in-config-parser.patch +- Add 0075-libmultipath-provide-defaults-for-get-put-_multipath.patch +- Add 0076-libmpathpersist-allow-using-libmultipath-get-put-_mu.patch +- Add 0077-multipath-use-get_put-_multipath_config-from-libmult.patch +- Add 0078-mpathpersist-use-get-put-_multipath_config-from-libm.patch +- Add 0079-libmultipath-add-udev-and-logsink-symbols.patch +- Add 0080-multipath-remove-logsink-and-udev.patch +- Add 0081-libmpathpersist-call-libmultipath_-init-exit.patch +- Add 0082-mpathpersist-remove-logsink-and-udev.patch +- Add 0083-multipathd-remove-logsink-and-udev.patch + * Pull in upsteam library changes +- Add 0084-libmpathvalid-use-default-_multipath_config-udev-and.patch +- Add 0085-Revert-libmultipath-add-ignore_udev_uid-option.patch +- Add 0086-libmultipath-change-log-level-for-null-uid_attribute.patch +- Add 0087-libmultipath-orphan_paths-avoid-BUG-message.patch + * update libmpathvalid to use upstream library changes. changes + submitted upstream + +* Mon Jul 27 2020 Fedora Release Engineering - 0.8.4-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-5 +- Update CI tests to match RHEL + * This commit also pulls in changes from Lin Li + and Bruno Goncalves + +* Tue Jul 21 2020 Benjamin Marzinski - 0.8.4-4 +- Rebased on top of additional commits staged for upstream + * Previous patches 0048-0060 are now patches 0053-0054 & 0059-0069 +- Add 0048-libmultipath-add-device-to-hwtable.c.patch +- Add 0049-master-libmultipath-fix-use-after-free-when-iscsi-lo.patch +- Add 0050-libmultipath-warn-if-freeing-path-that-holds-mpp-hwe.patch +- Add 0051-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch +- Add 0052-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch +- Add 0055-libmultipath-remove-code-duplication-in-path-countin.patch +- Add 0056-libmultipath-count-pending-paths-as-active-on-loads.patch +- Add 0057-libmultipath-deal-with-flushing-no-maps.patch +- Add 0058-multipath-deal-with-delegation-failures-correctly.patch +- Add 0070-multipath-add-libmpathvalid-library.patch + * adds the libmpathvalid.so library to determine if devices are + valid multipath paths. +- Add 0071-libmultipath-add-uid-failback-for-dasd-devices.patch +- Add 0072-libmultipath-add-ignore_udev_uid-option.patch + +* Mon Jul 13 2020 Tom Stellard - 0.8.4-3 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + +* Wed Jul 8 2020 Benjamin Marzinski - 0.8.4-2 +- Rebased on top of Martin Wilck's queue of ACKed upstream commits + * https://github.com/openSUSE/multipath-tools/tree/upstream-queue + * All previous patches have been reordered, with the exception of + 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch + which has been replaced with + 0029-fix-boolean-value-with-json-c-0.14.patch +- Modify 0054-RH-add-mpathconf.patch + * remove default enable_foreign and property blacklist_exceptions + settings, and deal with the builtin default change from + 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch. + Fixes bz #1853668 +- Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch +- Add 0049-kpartx-fix-Wsign-compare-error.patch + * The above two patches have been submitted upstream + +* Fri May 29 2020 Benjamin Marzinski - 0.8.4-1 +- Update Source to upstream version 0.8.4 + * Previoud patches 0001-0020 & 0031 are included in this commit +- Rename files + * Previous patches 0021-0032 are now patches 0012-0022 +- Add 0001-libmultipath-assign-variable-to-make-gcc-happy.patch +- Add 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch +- Add 0003-libmultipath-allow-force-reload-with-no-active-paths.patch +- Add 0004-libmpathpersist-depend-on-libmultipath.patch +- Add 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch +- Add 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch +- Add 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch +- Add 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch +- Add 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch +- Add 0010-multipath-tools-Makefile-add-install-dependency.patch +- Add 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch +- Add 0023-RH-work-around-gcc-10-format-truncation-issue.patch + * The above 10 patches have been submitted upstream + +* Tue Apr 21 2020 Björn Esser - 0.8.2-6 +- Rebuild (json-c) + +* Mon Apr 13 2020 Björn Esser - 0.8.2-5 +- Add 0032-add-support-for-upcoming-json-c-0.14.0.patch + +* Mon Apr 13 2020 Björn Esser - 0.8.2-4 +- Fix macro escaping in %%changelog + +* Wed Feb 12 2020 Benjamin Marzinski - 0.8.2-3 +- Add 0031-multipath-fix-issues-found-by-compiling-with-gcc-10.patch + * Patch submitted upstream +- Resolves bz #1799276 + +* Tue Jan 28 2020 Fedora Release Engineering - 0.8.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Wed Sep 11 2019 Benjamin Marzinski - 0.8.2-1 +- Update Source to upstream version 0.8.2 + * Previoud patches 0001-0017 & 0027 are included in this commit +- Rename files + * Previous patches 0018-0026 & 0028 are not patches 0021-0030 +- Add 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch +- Add 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch +- Add 0003-tests-add-path-grouping-policy-unit-tests.patch +- Add 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch +- Add 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch +- Add 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch +- Add 0007-libmultipath-consolidate-group_by_-functions.patch +- Add 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch +- Add 0009-libmultipath-make-group_paths-handle-marginal-paths.patch +- Add 0010-tests-add-tests-for-grouping-marginal-paths.patch +- Add 0011-libmultipath-add-marginal_pathgroups-config-option.patch +- Add 0012-libmutipath-deprecate-delay_-_checks.patch +- Add 0013-multipathd-use-marginal_pathgroups.patch +- Add 0014-multipath-update-man-pages.patch + * The above 13 patches add the marinal_pathgroups option +- Add 0015-multipath.conf-add-enable_foreign-parameter.patch +- Add 0016-multipath.conf.5-document-foreign-library-support.patch + * The above 2 patches add the enable_foreign option +- Add 0017-mpathpersist-remove-broken-unused-code.patch +- Add 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch +- Add 0019-mpathpersist-fix-leaks.patch +- Add 0020-libmultipath-fix-mpcontext-initialization.patch + * The above 20 patches have been submitted upstream + +* Wed Jul 24 2019 Fedora Release Engineering - 0.8.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Apr 12 2019 Benjamin Marzinski - 0.8.0-2 +- Add 0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch + * try to get ANA state from sysfs first, with the ioctl as a fallback + +* Thu Apr 4 2019 Benjamin Marzinski - 0.8.0-1 +- Update Source to upstream version 0.8.0 + * Previous patches 0006 & 0007 are included in this commit +- Rename files + * Previous patches 0008-0016 & 0100 are now patches 0018-0027 +- Add 0006-multipathd-Fix-miscounting-active-paths.patch +- Add 0007-multipathd-ignore-failed-wwid-recheck.patch + * multipathd will no longer disable paths if it is unable to + get their wwid on a change event +- Add 0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch +- Add 0009-multipathd-use-update_path_groups-instead-of-reload_.patch +- Add 0010-multipath.conf-add-missing-options-to-man-page.patch +- Add 0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch +- Add 0012-libmulitpath-cleanup-uid_fallback-code.patch +- Add 0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch + * if a path device changes wwid, it will now be removed and re-added + to the correct multipath device. +- Add 0014-multipathd-remove-wwid_changed-path-attribute.patch +- Add 0015-multipathd-ignore-disable_changed_wwids.patch +- Add 0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch +- Add 0017-libmultipath-silence-dm_is_mpath-error-messages.patch + * The above 12 patches have been submitted upstream + +* Sun Feb 17 2019 Igor Gnatenko - 0.7.9-6.git2df6110 +- Rebuild for readline 8.0 + +* Thu Jan 31 2019 Benjamin Marzinski - 0.7.9-5.git2df6110 +- Rename files + * Previous patch 0006-0014 are now patches 0008-0016 +- Add 0006-multipathd-avoid-null-pointer-dereference-in-LOG_MSG.patch +- Add 0007-multipath-blacklist-zram-devices.patch + * The above 2 patches have been submitted upstream +- Resolves: bz #1672761 + +* Thu Jan 31 2019 Benjamin Marzinski - 0.7.9-4.git2df6110 +- Update Source to latest upstream commit + * previous patch 0001-libmultipath-dm_is_mpath-cleanup.patch is included + in this commit +- Rename files + * Previous patches 0002-0009 are now patches 0006-0013 +- Add 0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch +- Add 0002-libmultipath-handle-existing-paths-in-marginal_path-.patch +- Add 0003-multipathd-cleanup-marginal-paths-checking-timers.patch +- Add 0004-libmultipath-fix-marginal-paths-queueing-errors.patch +- Add 0005-libmultipath-fix-marginal_paths-nr_active-check.patch + * The above 5 patches have been submitted upstream +- Add 0014-RH-Fix-nvme-compilation-warning.patch + * This change is only necessary because of Red Hat compilation + differences. + +* Thu Jan 31 2019 Fedora Release Engineering - 0.7.9-3.git17a6101 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Jan 15 2019 Benjamin Marzinski 0.7.9-2.git17a6101 +- Update Source to latest upstream commit + * Previous patches 0001-0003 are included in this version +- Rename files + * Previous patches 0004-0011 are now patches 0002-0009 +- Add 0001-libmultipath-dm_is_mpath-cleanup.patch + * This patch has been submitted upstream + +* Mon Dec 3 2018 Benjamin Marzinski 0.7.9-1 +- Update Source to upstream version 0.7.9 + * Previous patches 0001-0006 are included in this version +- Rename files + * Previous patches 0007-0014 are now patches 0004-0011 +- Add 0001-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch +- Add 0002-libmultipath-cleanup-pthread_cleanup_pop-call.patch +- Add 0003-libmultipath-fix-false-removes-in-dmevents-polling-c.patch + * The above 3 patches have been submitted upstream + +* Wed Oct 10 2018 Benjamin Marzinski 0.7.8-1 +- Update Source to upstream version 0.7.8 + * Previous patches 0001-0020 are included in this version +- Rename files + * Previous patches 0021-0025 are now patches 0001-0005 + * Previous patches 0026-0033 are now patches 0007-0014 +- Add 0006-libmultipath-timeout-on-unresponsive-tur-thread.patch + * has been submitted upstream + +* Tue Oct 9 2018 Benjamin Marzinski 0.7.7-7.gitb80318b +- Update Source to latest upstream commit +- Rename files + * Previous patches 0001-0020 are now patches 0002-0021 + * Previous patches 0021-0028 are now patches 0026-0033 +- Add 0001-kpartx-Use-absolute-paths-to-create-mappings.patch +- Add 0022-multipathd-check-for-NULL-udevice-in-cli_add_path.patch +- Add 0023-libmultipath-remove-max_fds-code-duplication.patch +- Add 0024-multipathd-set-return-code-for-multipathd-commands.patch +- Add 0025-mpathpersist-fix-registration-rollback-issue.patch + * The above 5 patches have been submitted upstream + +* Thu Sep 27 2018 Benjamin Marzinski 0.7.7-6.git1a8625a +- Update Source to latest upstream commit + * Previous patches 0001-0011 are included in this commit +- Rename files + * Previous patches 0012-0019 are now patches 0021-0028 +- Add 0001-libmultipath-fix-tur-checker-timeout.patch +- Add 0002-libmultipath-fix-tur-checker-double-locking.patch +- Add 0003-libmultipath-fix-tur-memory-misuse.patch +- Add 0004-libmultipath-cleanup-tur-locking.patch +- Add 0005-libmultipath-fix-tur-checker-timeout-issue.patch + * The above 5 patches cleanup locking issues with the + tur checker threads +- Add 0006-libmultipath-fix-set_int-error-path.patch +- Add 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch +- Add 0008-libmultipath-_install_keyword-cleanup.patch +- Add 0009-libmultipath-remove-unused-code.patch +- Add 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch +- Add 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch +- Add 0012-libmutipath-don-t-use-malformed-uevents.patch +- Add 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch +- Add 0014-multipathd-function-return-value-tweaks.patch +- Add 0015-multipathd-minor-fixes.patch +- Add 0016-multipathd-remove-useless-check-and-fix-format.patch +- Add 0017-multipathd-fix-memory-leak-on-error-in-configure.patch + * The above 12 patches fix minor issues found by coverity +- Add 0018-libmultipath-Don-t-blank-intialized-paths.patch +- Add 0019-libmultipath-Fixup-updating-paths.patch + * Fix issues with paths whose wwid was not set or later changes +- Add 0020-multipath-tweak-logging-style.patch + * multipathd interactive commands now send errors to stderr, instead + of syslog + * The above 20 patches have been submitted upstream + +* Fri Sep 14 2018 Benjamin Marzinski 0.7.7-5.gitef6d98b +- Add Conflicts for mdadm < 4.1-rc2.0.2 and udisks2 < 2.8.0-2 + * Multipath udev rule update from 0.7.7-1 is incompatible with older versions + (bz #1628192) + +* Thu Jul 12 2018 Benjamin Marzinski 0.7.7-4.gitef6d98b +- Update Source to latest upstream commit + * Previous patches 0001-0018 are included in this commit +- Rename files + * Previous patches 0019-0028 are now patches 0002-0003 & 0012-0019 +- Add 0001-libmultipath-remove-last-of-rbd-code.patch +- Add 0004-mpathpersist-add-param-alltgpt-option.patch + * mpathpersist now accepts --param-alltgpt +- Add 0005-libmutipath-remove-unused-IDE-bus-type.patch +- Add 0006-multipathd-add-new-protocol-path-wildcard.patch + * multipathd show paths format now accepts %%P for the path + protocol/transport +- Add 0007-libmultipath-add-protocol-blacklist-option.patch + * You can now use the "protocol" blacklist section parameter to blacklist + by protocol/transport +- Add 0008-libmultipath-remove-_filter_-blacklist-functions.patch +- Add 0009-multipath-tests-change-to-work-with-old-make-version.patch +- Add 0010-multipath-tests-add-blacklist-tests.patch +- Add 0011-mpathpersist-add-missing-param-rk-usage-info.patch +- Refresh 0013-RH-Remove-the-property-blacklist-exception-builtin.patch +- Modify 0016-RH-add-mpathconf.patch + * improve usage message and man page + +* Thu Jul 12 2018 Fedora Release Engineering - 0.7.7-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Sat Jun 30 2018 Peter Robinson 0.7.7-2 +- Spec cleanups, drop remains of initscripts dependencies + +* Tue Jun 12 2018 Benjamin Marzinski 0.7.7-1 +- Update Source to 0.7.7 + * Previous patches 0001-0009 & 0018 are included in this commit +- Add upstream patches since 0.7.7 + * patches 0001-0012 are from upstream commits since 0.7.7 +- Add 0015-mpathpersist-add-all_tg_pt-option.patch + * add new all_tg_pt multpiath.conf option. posted upstream +- Add 0016-libmultipath-remove-rbd-code.patch + * remove unused rbd code. posted upstream +- Add 0017-mpathpersist-fix-aptpl-support.patch + * add ":aptpl" suffix for reservation_key to fix aptpl support. + posted upstream +- Add 0018-multipath-don-t-check-timestamps-without-a-path.patch + * fix multipath null dereference crash. posted upstream +- Add 0019-libmultipath-fix-detect-alua-corner-case.patch + * fix alua detection with retain_hardware_handler set to off. posted + upstream +- Add 0020-multipath-fix-setting-conf-version.patch + * multipath wasn't setting the kernel version correctly. posted upstream +- Add 0028-RH-reset-default-find_mutipaths-value-to-off.patch + * default to RHEL7 and older device detection style. Redhat specific, to + keep customer experience the same. +- Rename files + * Previous patches 0010-0011 are now patches 0013-0014 + * Previous patches 0012-0017 & 0019 are now patches 0021-0027 +- Modify 0021-RH-fixup-udev-rules-for-redhat.patch + * Fix spurious compile warning with redhat compile options + + +* Tue May 15 2018 Benjamin Marzinski 0.7.6-4.git1cb704b +- Add 0010-libmultipath-print-correct-default-for-delay_-_check.patch + * fix minor configuration printing issue +- Add 0011-multipath.conf.5-clarify-property-whitelist-handling.patch + * clarify property blacklist_excecptions handling in man page +- Rename files + * Previous patches 0010-0017 are now patches 0012-0019 +- Modify 0013-RH-Remove-the-property-blacklist-exception-builtin.patch + * clarify changes in man page + +* Tue Apr 24 2018 Benjamin Marzinski 0.7.6-3.git1cb704b +- Add 0008-multipathd-add-failures-path-format-wildcard.patch +- Add 0009-multipathd-fix-reservation_key-check.patch +- Rename files + * Previous patches 0008-0015 are now patches 0010-0017 + +* Fri Apr 13 2018 Benjamin Marzinski 0.7.6-2.git1cb704b +- Add 0007-libmultipath-Fix-logic-in-should_multipath.patch + * fix bug in identifying multipathable devices. posted upstream +- Rename files + * Previous patches 0007-0014 are now patches 0008-0015 + +* Mon Apr 02 2018 Benjamin Marzinski 0.7.6-1.git1cb704b +- Update Source to the latest upstream commit + * Previous patches 0001-0014 are included in this commit + * Previous patches 0015-0022 are now patches 0007-0014 +- 0001-multipathd-remove-incorrect-pthread_testcancel.patch + * Fixed pthread cancellation issue. posted upstream +- 0002-multipath-add-comments.patch + * Posted upstream +- 0003-multipathd-minor-dmevents-polling-code-cleanups.patch + * Fixed minor polling issues. posted upstream +- 0004-multipathd-remove-unneeded-function-parameter.patch + * Posted upstream +- 0005-mpathcmd-fix-libmpathcmd-license.patch + * License clarification. posted upstream +- 0006-libmultipath-don-t-print-undefined-values.patch + * Fixed bug in 'multipath show config'. posted upstream + +* Tue Mar 06 2018 Björn Esser - 0.7.4-2.git07e7bd5 +- Rebuilt for libjson-c.so.4 (json-c v0.13.1) + +* Thu Feb 15 2018 Benjamin Marzinski 0.7.4-1.git07e7bd5 +- Update Source to the latest upstream commit + * Previous patches 0001-0006 are included in this commit + * Previous patches 0007-0014 are now patches 0015-0022 +- Add 0001-libmultipath-fix-tur-checker-locking.patch + * Fixed spinlock bug. posted upstream +- Add 0002-multipath-fix-DEF_TIMEOUT-use.patch + * Add missing sec to ms conversion. posted upstream +- Add 0003-multipathd-remove-coalesce_paths-from-ev_add_map.patch + * Remove unused code. posted upstream +- Add 0004-multipathd-remove-unused-configure-parameter.patch + * Remove unused code. posted upstream +- Add 0005-Fix-set_no_path_retry-regression.patch + * Fix issue with queueing and path addition. posted upstream +- Add 0006-multipathd-change-spurious-uevent-msg-priority.patch + * Change message priority to Notice. posted upstream +- Add 0007-multipath-print-sysfs-state-in-fast-list-mode.patch + * Show sysfs state correctly in fast list mode (-l). posted upstream +- Add 0008-libmultipath-move-remove_map-waiter-code-to-multipat.patch + * Move code around. posted upstream +- Add 0009-move-waiter-code-from-libmultipath-to-multipathd.patch + * Move code around. posted upstream +- Add 0010-call-start_waiter_thread-before-setup_multipath.patch + * Fix race on multipath device creations. posted upstream +- Add 0011-libmultipath-add-helper-functions.patch + * posted upstream +- Add 0012-multipathd-RFC-add-new-polling-dmevents-waiter-threa.patch + * Add alternate method of getting dmevents, that doesn't + require a thread per device. posted upstream +- Add 0013-libmultipath-condlog-log-to-stderr.patch + * change condlog to log to stderr instead of stdout. posted upstream +- Add 0014-multipathd-fix-compiler-warning-for-uev_pathfail_che.patch + * fix indentation issue. posted upstream + +* Wed Feb 07 2018 Fedora Release Engineering - 0.7.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sun Dec 10 2017 Björn Esser - 0.7.3-2 +- Rebuilt for libjson-c.so.3 + +* Tue Nov 7 2017 Benjamin Marzinski 0.7.3-1 +- Update Source to upstream 0.7.3 release + * Previous patch 0001 is included in this commit, and 0002 was solved in a + different manner causing some change to previous patch 0003 + * Previous patches 0003-0010 are now patches 0007-0014 +- Add 0001-mpathpersist-Fix-invalid-condition-check.patch + * Fix incorrect check. posted upstream +- Add 0002-multipath-add-man-page-info-for-my-prkey-changes.patch + * Add missing man page info. posted upstream +- Add 0003-multipath-there-is-no-none-path-state.patch + * remove incorrect path state. posted upstream +- Add 0004-mutipath-updated-Huawei-storage-config.patch + * update builtin device configuration. posted upstream +- Add 0005-multipath-fix-doc-typo.patch + * fix man page typo. posted upstream +- Add 0006-multipath-add-ghost_delay-parameter.patch + * add new multipath.conf parameter "ghost_delay". posted upstream + + +* Tue Nov 7 2017 Benjamin Marzinski 0.7.1-8.git847cc43 +- Refresh 0001-libmultipath-update-3PARdata-builtin-config.patch +- Add 0010-RH-warn-on-invalid-regex-instead-of-failing.patch + * Change old-style multipath.conf regex "*" to a proper ".*" instead of + failing + +* Wed Aug 2 2017 Benjamin Marzinski 0.7.1-7.git847cc43 +- Modify 0005-RH-don-t-start-without-a-config-file.patch + * Fix man page typos + +* Mon Jul 31 2017 Troy Dawson - 0.7.1-6.git847cc43 +- Clean spec file - remove pre-fedora 23 cruft + +* Wed Jul 26 2017 Fedora Release Engineering - 0.7.1-5.git847cc43 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Jul 21 2017 Benjamin Marzinski 0.7.1-4.git847cc43 +- Update Source to the latest upstream commit + * Previous patches 0001 and 0010-0013 are included in this commit. +- Add 0001-libmultipath-update-3PARdata-builtin-config.patch + * Change for building configuration. Posted upstream +- Modify 0006-RH-use-rpm-optflags-if-present.patch + * Add missing lines to actually use RPM_OPT_FLAGS. + +* Fri Jun 23 2017 Tom Callaway - 0.7.1-3.gitf21166a +- rebuild to resolve broken deps + +* Fri Jun 2 2017 Benjamin Marzinski 0.7.1-2.gitf21166a +- Modify 0004-RH-Remove-the-property-blacklist-exception-builtin.patch + * update multipath.conf.5 man page to remove builtin listing +- Modify 0005-RH-don-t-start-without-a-config-file.patch + * update multipathd.8 man page to note that a config file is necessary +- Modify 0007-RH-add-mpathconf.patch + * add property blacklist-exception to default config file +- Add 0010-libmultipath-change-how-RADOS-checker-is-enabled.patch + * Makefile now autodetects librados. Posted upstream +- Remove related RADOS option from spec file +- Add 0011-multipath-set-verbosity-to-default-during-config.patch + * Allow multipath to print warning messages during configuration. + Posted upstream +- Add 0012-mpath-skip-device-configs-without-vendor-product.patch + * device entries without vendor/product were breaking configurations. + Posted upsteam +- Add 0013-multipathd-fix-show-maps-json-crash.patch + * multipathd crashed showing json output with no devices. Posted + upstream + +* Tue May 23 2017 Benjamin Marzinski 0.7.1-1.gitf21166a +- Update Source to the latest upstream commit +- Add 0001-libmultipath-add-comment-about-resuming.patch + * posted upstream +- Add 0002-multipath-attempt-at-common-multipath.rules.patch + * under discussion upstream +- Add 0003-RH-fixup-udev-rules-for-redhat.patch + * Redhat uses different udev rules that some other distros, so multipath + has run at a different time. Not all upstream distros link /sbin and + /usr/sbin either. +- Add 0004-RH-Remove-the-property-blacklist-exception-builtin.patch + * Allow multipath to be used on devices without multiple paths. NAK'ed + upstream, but requested by Red Hat +- Add 0005-RH-don-t-start-without-a-config-file.patch + * Don't start multipath unless a config file exists. NAK'ed upstream, + but requested by Red Hat +- Add 0006-RH-use-rpm-optflags-if-present.patch + * Make the build system fedora friendly +- Add 0007-RH-add-mpathconf.patch + * Add tool to help configure multipath with Red Hat defaults. +- Add 0008-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch + * Make multipath able to claim devices based on the kernel command line + NAK'ed upstream but requested by Red Hat +- Add 0009-RH-trigger-change-uevent-on-new-device-creation.patch + * under discussion upstream + +* Wed Apr 12 2017 Benjamin Marzinski 0.4.9-87 +- Remove Epoch from device-mapper requires + * The RHEL releases of device-mapper set the Epoch, and this was + accidentally retained in the fedora spec file. + +* Fri Apr 7 2017 Benjamin Marzinski 0.4.9-86 +- Modify 0136-RHBZ-1304687-wait-for-map-add.patch + * switch to missing_uev_wait_timeout to stop waiting for uev +- Refresh 0137-RHBZ-1280524-clear-chkr-msg.patch +- Refresh 0150-RHBZ-1253913-fix-startup-msg.patch +- Refresh 0154-UPBZ-1291406-disable-reinstate.patch +- Refresh 0156-UPBZ-1313324-dont-fail-discovery.patch +- Refresh 0161-RHBZ-1311659-no-kpartx.patch +- Refresh 0167-RHBZ-1335176-fix-show-cmds.patch +- Add 0173-RH-update-man-page.patch +- Add 0174-RHBZ-1362396-modprobe.patch + * make starting the multipathd service modprobe dm-multipath in the + sysvinit scripts +- Add 0175-RHBZ-1357382-ordering.patch + * force multipathd.service to start after systemd-udev-trigger.service +- Add 0176-RHBZ-1363830-fix-rename.patch + * initialized a variable to make dm_rename not fail randomly +- Add 0177-libmultipath-correctly-initialize-pp-sg_id.patch + * This and all the following patches add the rbd patch checker +- Add 0178-libmultipath-add-rbd-discovery.patch +- Add 0179-multipath-tools-add-checker-callout-to-repair-path.patch +- Add 0180-multipath-tools-Add-rbd-checker.patch +- Add 0181-multipath-tools-Add-rbd-to-the-hwtable.patch +- Add 0182-multipath-tools-check-for-initialized-checker-before.patch +- Add 0183-multipathd-Don-t-call-repair-on-blacklisted-path.patch +- Add 0184-rbd-fix-sync-repair-support.patch +- Add 0185-rbd-check-for-nonshared-clients.patch +- Add 0186-rbd-check-for-exclusive-lock-enabled.patch +- Add 0187-rbd-fixup-log-messages.patch +- Add 0188-RHBZ-1368501-dont-exit.patch + * make multipathd not exit if it encounters recoverable errors on startup +- Add 0189-RHBZ-1368211-remove-retries.patch + * add "remove_retries" multipath.conf parameter to make multiple attempts + to remove a multipath device if it is busy. +- Add 0190-RHBZ-1380602-rbd-lock-on-read.patch + * pass lock_on_read when remapping image +- Add 0191-RHBZ-1169168-disable-changed-paths.patch + * add "disabled_changed_wwids" multipath.conf parameter to disable + paths whose wwid changes +- Add 0192-RHBZ-1362409-infinibox-config.patch +- Add 0194-RHBZ-1351964-kpartx-recurse.patch + * fix recursion on corrupt dos partitions +- Add 0195-RHBZ-1359510-no-daemon-msg.patch + * print a messages when multipathd isn't running +- Add 0196-RHBZ-1239173-dont-set-flag.patch + * don't set reload flag on reloads when you gain your first + valid path +- Add 0197-RHBZ-1394059-max-sectors-kb.patch + * add "max_sectors_kb" multipath.conf parameter to set max_sectors_kb + on a multipath device and all its path devices +- Add 0198-RHBZ-1372032-detect-path-checker.patch + * add "detect_checker" multipath.conf parameter to detect ALUA arrays + and set the path checker to TUR +- Add 0199-RHBZ-1279355-3pardata-config.patch +- Add 0200-RHBZ-1402092-orphan-status.patch + * clear status on orphan paths +- Add 0201-RHBZ-1403552-silence-warning.patch +- Add 0202-RHBZ-1362120-skip-prio.patch + * don't run prio on failed paths +- Add 0203-RHBZ-1363718-add-msgs.patch +- Add 0204-RHBZ-1406226-nimble-config.patch +- Add 0205-RHBZ-1416569-reset-stats.patch + * add "reset maps stats" and "reset map stats" multipathd + interactive commands to reset the stats tracked by multipathd +- Add 0206-RHBZ-1239173-pt2-no-paths.patch + * make multipath correctly disable scanning and rules running when + it gets a uevent and there are not valid paths. +- Add 0207-UP-add-libmpathcmd.patch + * New shared library, libmpathcmd, that sends and receives messages from + multipathd. device-mapper-multipath now uses this library internally. +- Add 0208-UPBZ-1430097-multipathd-IPC-changes.patch + * validation that modifying commands are coming from root. +- Add 0209-UPBZ-1430097-multipath-C-API.patch + * New shared library. libdmmp, that presents the information from multipathd + in a structured manner to make it easier for callers to use +- Add 0210-RH-fix-uninstall.patch + * Minor compilation fixes +- Add 0211-RH-strlen-fix.patch + * checks that variables are not NULL before passing them to strlen +- Add 0212-RHBZ-1431562-for-read-only.patch +- Make 3 new subpackages + * device-mapper-multipath-devel, libdmmp, and libdmmp-devel. libmpathcmd + and libmpathprio are in device-mapper-multipath-libs and + device-mapper-multipath-devel. libdmmp is in its own subpackages +- Move libmpathprio devel files to device-mapper-multipath-devel +- Added BuildRequires on librados2-devel + + +* Fri Feb 10 2017 Fedora Release Engineering - 0.4.9-85 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Igor Gnatenko - 0.4.9-84 +- Rebuild for readline 7.x + +* Fri Jul 22 2016 Benjamin Marzinski 0.4.9-83 +- Modify 0135-RHBZ-1299600-path-dev-uevents.patch + * trigger uevents when adding wwids for existing devices during startup +- Refresh 0136-RHBZ-1304687-wait-for-map-add.patch +- Refresh 0150-RHBZ-1253913-fix-startup-msg.patch +- Modify 0159-UPBZ-1255885-udev-waits.patch + * fix bug in failure path +- Add 0160-RH-udev-flags.patch +- Add 0161-RHBZ-1311659-no-kpartx.patch + * skip_kpartx option disables kpartx running on multipath devices +- Add 0162-RHBZ-1333331-huawei-config.patch + * Add default config for Huawei XSG1 array +- Add 0163-UPBZ-1333492-resize-map.patch + * restore old size if resize fails +- Add 0164-RHBZ-1311463-dos-part-rollover.patch + * fix incorrect partition size due to 4k device size rollover +- Add 0165-UPBZ-1341748-MSA-2040-conf.patch + * Add default config for MSA 2040 array +- Add 0166-RHBZ-1323429-dont-allow-new-wwid.patch + * don't allow path wwid to change while it is in use +- Add 0167-RHBZ-1335176-fix-show-cmds.patch + * and new show multipath format wildcard, 'f' to sho number of failures. + This will hopefully be useful for tracking what happens to multipath + devices for bz #1335176 +- Add 0168-RHBZ-1347769-shared-lock.patch + * make multipath lock the path devices with a shared lock +- Add 0169-UPBZ-1353357-json-output.patch + * add mulitpathd json output command +- Add 0170-UPBZ-1352925-fix-typo.patch +- Add 0171-UPBZ-1356651-allow-zero-size.patch + * Allow zero-sized paths to be added to a multipath device +- Add 0172-RHBZ-1350931-no-active-add.patch + * Allow paths to be added to a new map if no active paths exist. Also + fixes 1351430 + + +* Thu Apr 21 2016 Benjamin Marzinski 0.4.9-82 +- Modify 0005-RH-add-mpathconf.patch + * changed warning message +- Modify 0102-RHBZ-1160478-mpathconf-template.patch + * updated man page +- Modify 0104-RHBZ-631009-deferred-remove.patch + * refactor code and minor fix +- Refresh 0107-RHBZ-1169935-no-new-devs.patch +- Refresh 0112-RHBZ-1194917-add-config_dir-option.patch +- Refresh 0126-RHBZ-1211383-alias-collision.patch +- Add 0133-RHBZ-1296979-fix-define.patch + * look for the correct libudev function to set define +- Add 0134-RHBZ-1241528-check-mpath-prefix.patch + * only touch devices with a "mpath-" dm uuid prefix +- Add 0135-RHBZ-1299600-path-dev-uevents.patch + * trigger path uevent the first time a path is claimed by multipath +- Add 0136-RHBZ-1304687-wait-for-map-add.patch + * wait for the device to finish being added before reloading it. +- Add 0137-RHBZ-1280524-clear-chkr-msg.patch +- Add 0138-RHBZ-1288660-fix-mpathconf-allow.patch + * don't remove existing lines from blacklist_exceptions section +- Add 0139-RHBZ-1273173-queue-no-daemon-doc.patch +- Add 0140-RHBZ-1299647-fix-help.patch +- Add 0141-RHBZ-1303953-mpathpersist-typo.patch +- Add 0142-RHBZ-1283750-kpartx-fix.patch + * only remove devices if their uuid says that they are the correct + partition device +- Add 0143-RHBZ-1299648-kpartx-sync.patch + * default to using udev sync mode +- Add 0144-RHBZ-1299652-alua-pref-arg.patch + * allow "exclusive_pref_bit" argument to alua prioritizer +- Add 0145-UP-resize-help-msg.patch +- Add 0146-UPBZ-1299651-raw-output.patch + * allow raw format mutipathd show commands, that remove headers and padding +- Add 0147-RHBZ-1272620-fail-rm-msg.patch +- Add 0148-RHBZ-1292599-verify-before-remove.patch + * verify that all partitions are unused before attempting to remove a device +- Add 0149-RHBZ-1292599-restore-removed-parts.patch + * don't disable kpartx when restoring the first path of a device. +- Add 0150-RHBZ-1253913-fix-startup-msg.patch + * wait for multipathd daemon to write pidfile before returning +- Add 0151-RHBZ-1297456-weighted-fix.patch + * add wwn keyword to weighted prioritizer for persistent naming +- Add 0152-RHBZ-1269293-fix-blk-unit-file.patch + * use "Wants" instead of "Requires" +- Add 0153-RH-fix-i686-size-bug.patch + * use 64-bit keycodes for multipathd client commands +- Add 0154-UPBZ-1291406-disable-reinstate.patch + * don't automatically reinstate ghost paths for implicit alua devices +- Add 0155-UPBZ-1300415-PURE-config.patch + * Add default config for PURE FlashArray +- Add 0156-UPBZ-1313324-dont-fail-discovery.patch + * don't fail discovery because individual paths failed. +- Add 0157-RHBZ-1319853-multipath-c-error-msg.patch + * better error reporting for multipath -c +- Add 0158-RHBZ-1318581-timestamp-doc-fix.patch + * add documentation for -T +- Add 0159-UPBZ-1255885-udev-waits.patch + * make multipath and kpartx wait after for udev after each command + +* Wed Feb 03 2016 Fedora Release Engineering - 0.4.9-81 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Sep 25 2015 Benjamin Marzinski 0.4.9-80 +- Add 0131-RHBZ-1259523-host_name_len.patch + * increase size of host string +- Add 0132-UPBZ-1259831-lock-retry.patch + * retry locking when creating multipath devices + +* Mon Aug 17 2015 Benjamin Marzinski 0.4.9-79 +- Add 0130-UPBZ-1254292-iscsi-targetname.patch + * check for targetname iscsi sysfs value + +* Thu Aug 13 2015 Benjamin Marzinski 0.4.9-78 +- fix triggerun issue and updated requires in spec file. + +* Fri Aug 7 2015 Benjamin Marzinski 0.4.9-77 +- Modify 0104-RHBZ-631009-deferred-remove.patch + * add man page info +- Refresh 0112-RHBZ-1194917-add-config_dir-option.patch +- Refresh 0114-RHBZ-1196394-delayed-reintegration.patch +- Add 0118-UPBZ-1200738-update-eternus-config.patch + * update default config +- Add 0119-RHBZ-1081397-save-alua-info.patch + * make prioritizers save information between calls to speed them up. +- Add 0120-RHBZ-1043093-realloc-fix.patch + * free old memory if realloc fails. +- Add 0121-RHBZ-1197234-rules-fix.patch + * make sure kpartx runs after an DM_ACTIVATION event occurs. +- Add 0122-RHBZ-1212590-dont-use-var.patch + * use /run instead of /var/run +- Add 0123-UPBZ-1166072-fix-path-offline.patch + * Don't mark quiesce and transport-offline paths as offline +- Add 0124-RHBZ-1209275-retrigger-uevents.patch + * Make multipathd retrigger uevents when paths haven't successfully had + their udev_attribute environment variable set by udev and add + "retrigger_ties" and "retrigger_delay" to control this +- Add 0125-RHBZ-1153832-kpartx-delete.patch + * Delete all partition devices with -d (not just the ones in the partition + table) +- Add 0126-RHBZ-1211383-alias-collision.patch + * make multipathd use the old alias, if rename failed and add + "new_bindings_in_boot" to determine if new bindings can be added to + the bindings file in the initramfs +- Add 0127-RHBZ-1201030-use-blk-availability.patch + * Make multipath use blk-availability.service +- Add 0128-RHBZ-1222123-mpathconf-allow.patch + * Add mpathconf --allow for creating specialized config files. +- Add 0129-RHBZ-1241774-sun-partition-numbering.patch + * Make kpartx correctly number sun partitions. + + +* Wed Jun 17 2015 Fedora Release Engineering - 0.4.9-76 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Mar 11 2015 Benjamin Marzinski 0.4.9-75 +- Add 0111-RH-dont-show-pg-timeout.patch + * The kernel doesn't support pg_timeout, so multipath shouldn't + bother to display it +- Add 0112-RHBZ-1194917-add-config_dir-option.patch + * multipath will now also read its configuration from files with + the .conf suffix in the directory specified by config_dir + which defaults to /etc/multipath/conf.d +- Add 0113-RHBZ-1194917-cleanup.patch + * cleanup some unnecessary code +- Add 0114-RHBZ-1196394-delayed-reintegration.patch + * Add "delay_watch_checks" and "delay_wait_checks" options to delay + reintegration of flakey paths. +- Add 0115-RHBZ-1198418-fix-double-free.patch + * multipath was freeing the multipath alias twice if it failed to create the + multipath device. +- Add 0116-UPBZ-1188179-dell-36xxi.patch + * new builtin configurations. +- Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch + * configure multipath to automatically detect alua settings on clariion + devices. + +* Thu Mar 05 2015 Adam Jackson 0.4.9-74 +- Drop sysvinit subpackage from F23+ + +* Wed Feb 18 2015 Benjamin Marzinski 0.4.9-73 +- Add 0110-RHBZ-blacklist-vd-devs.patch + * blacklist vd[a-z] devices, since they don't have a WWID for + multipath to use. + +* Thu Dec 18 2014 Benjamin Marzinski 0.4.9-72 +- Modify 0107-RHBZ-1169935-no-new-devs.patch + * instead of using "-n" there is now a new configuration option, + 'ignore_new_boot_devs'. If set to 'yes', multipath will ignore + devices that aren't in /etc/multipath/wwids when running in the + initramfs. This option does nothing while multipathd is running + in the real root filesystem. +- Update 0109-RH-read-only-bindings.patch + +* Mon Dec 15 2014 Benjamin Marzinski 0.4.9-71 +- Add 0103-RH-cleanup-partmaps-code.patch + * code refactoring to prepare for next patch +- Add 0104-RHBZ-631009-deferred-remove.patch + * add deferred_remove option to /etc/multipath.conf +- Add 0105-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch + * Only run kpartx on device activation +- Add 0106-RHBZ-1159337-fix-double-free.patch + * made ev_remove_path exit immediately after failing setup_multipath, since + it handles cleaning up the device +- Add 0107-RHBZ-1169935-no-new-devs.patch + * Add new multipathd option '-n' which keeps multipathd from creating any + multipath devices that aren't in the /etc/multipath/wwids file. +- Add 0108-RHBZ-1153832-kpartx-remove-devs.patch + * switch from 'kpartx -a' to 'kpartx -u' to remove missing devices as well. +- Add 0109-RH-read-only-bindings.patch + * re-enabled -B option for multipathd + +* Tue Dec 9 2014 Benjamin Marzinski 0.4.9-70 +- Add 0102-RHBZ-1160478-mpathconf-template.patch + * mpathconf no longer copies the default config template for the + docs directory. It simply writes the template itself. +- Resolves: bz# 1160478 + +* Thu Nov 13 2014 Benjmain Marzinski 0.4.9-69 +- Rebuild + +* Tue Sep 16 2014 Benjamin Marzinski 0.4.9-68 +- Modify multipath.conf + * remove getuid_callout example +- Re-add 0050-RH-listing-speedup.patch +- Add 0081-RHBZ-1066264-check-prefix-on-rename.patch + * make multipath check the prefix on kpartx partitions during rename, and + copy the existing behaviour +- Add 0082-UPBZ-1109995-no-sync-turs-on-pthread_cancel.patch + * If async tur checker fails on threads, don't retry with the sync version +- Add 0083-RHBZ-1080055-orphan-paths-on-reload.patch + * Fix case where pathlist wasn't getting updated properly +- Add 0084-RHBZ-1110000-multipath-man.patch + * fix errors in multipath man page +- Add 0085-UPBZ-1110006-datacore-config.patch + * Add support for DataCore Virtual Disk +- Add 0086-RHBZ-1110007-orphan-path-on-failed-add.patch + * If multipathd fails to add path correctly, it now fully orphans the path +- Add 0087-RHBZ-1110013-config-error-checking.patch + * Improve multipath.conf error checking. +- Add 0088-RHBZ-1069811-configurable-prio-timeout.patch + * checker_timeout now adjusts the timeouts of the prioritizers as well. +- Add 0089-RHBZ-1110016-add-noasync-option.patch + * Add a new defaults option, "force_sync", that disables the async mode + of the path checkers. This is for cases where to many parallel checkers + hog the cpu +- Add 0090-UPBZ-1080038-reorder-paths-for-round-robin.patch + * make multipathd order paths for better throughput in round-robin mode +- Add 0091-RHBZ-1069584-fix-empty-values-fast-io-fail-and-dev-loss.patch + * check for null pointers in configuration reading code. +- Add 0092-UPBZ-1104605-reload-on-rename.patch + * Reload table on rename if necessary +- Add 0093-UPBZ-1086825-user-friendly-name-remap.patch + * Keep existing user_friend_name if possible +- Add 0094-RHBZ-1086825-cleanup-remap.patch + * Cleanup issues with upstream patch +- Add 0095-RHBZ-1127944-xtremIO-config.patch + * Add support for EMC ExtremIO devices +- Add 0096-RHBZ-979474-new-wildcards.patch + * Add N, n, R, and r path wildcards to print World Wide ids +- Add 0097-RH-fix-coverity-errors.patch + * Fix a number of unterminated strings and memory leaks on failure + paths. +- Add 0098-UPBZ-1067171-mutipath-i.patch + * Add -i option to ignore wwids file when checking for valid paths +- Add 0099-RH-add-all-devs.patch + * Add new devices config option all_devs. This makes the configuration + overwrite the specified values in all builtin configs +- Add 0100-RHBZ-1067171-multipath-i-update.patch + * make -i work correctly with find_multipaths +- Add 0101-RH-adapter-name-wildcard.patch + * Add 'a' path wildcard to print adapter name + +* Sat Aug 16 2014 Fedora Release Engineering - 0.4.9-67 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Jul 11 2014 Tom Callaway - 0.4.9-66 +- fix license handling + +* Sat Jun 07 2014 Fedora Release Engineering - 0.4.9-65 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Mar 31 2014 Benjamin Marzinski 0.4.9-64 +- Modify 0076-RHBZ-1056686-add-hw_str_match.patch + * free temporary memory used during configuration +- Add 0078-RHBZ-1054044-fix-mpathconf-manpage.patch + * fix typo +- Add 0079-RHBZ-1070581-add-wwid-option.patch + * add multipath option "-a". To add a device's wwid to the wwids file +- Add 0080-RHBZ-1075796-cmdline-wwid.patch + * add multipath option "-A" to add wwids specified by the kernel + command line mapth.wwid options. + +* Fri Jan 24 2014 Benjamin Marzinski 0.4.9-63 +- Add 0074-RHBZ-1056976-dm-mpath-rules.patch + * Add rules to keep from doing work in udev if there are no + active paths, or if the event was for a multipath device + reloading its table due to a path change. +- Add 0075-RHBZ-1056976-reload-flag.patch + * multipath code to identify reloads that the new rules can + ignore +- Add 0076-RHBZ-1056686-add-hw_str_match.patch + * add a new default config paramter, "hw_str_match", to make user + device configs only overwrite builtin device configs if the + identifier strings match exactly, like the default in RHEL6. + +* Fri Jan 10 2014 Benjamin Marzinski 0.4.9-62 +- Modify 0072-RHBZ-1039199-check-loop-control.patch + * only call close on the /dev/loop-control fd the open succeeds +- Add 0073-RH-update-build-flags.patch + * fix print call to work with -Werror=format-security compile flag + +* Tue Dec 10 2013 Benjamin Marzinski 0.4.9-61 +- Add 0072-RHBZ-1039199-check-loop-control.patch + * Make kpartx use LOOP_CTL_GET_FREE and loop-control to find a free + loop device. This will autoload the loop module. + +* Mon Dec 9 2013 Benjamin Marzinski 0.4.9-60 +- Add 0067-RHBZ-1022899-fix-udev-partition-handling.patch + * Make sure to wipe partition devices on change event if they weren't + wiped on the device add event +- Add 0068-RHBZ-1034578-label-partition-devices.patch + * Make sure that partition devices are labeled like the whole device +- Add 0069-UPBZ-1033791-improve-rdac-checker.patch + * Use RTPG data in RDAC checker +- Add 0070-RHBZ-1036503-blacklist-td-devs.patch +- Add 0071-RHBZ-1031546-strip-dev.patch + * make multipathd interactive commands able to handle /dev/ + instead of just + +* Sat Oct 12 2013 Benjamin Marzinski 0.4.9-59 +- Add 0066-UP-dos-4k-partition-fix.patch + * Make kpartx correctly handle 4K sector size devices with dos partitions. + +* Fri Sep 27 2013 Benjamin Marzinski 0.4.9-58 +- Add 0065-UPBZ-995538-fail-rdac-on-unavailable.patch + * make rdac checker always mark paths with asymmetric access state of + unavailable as down + +* Fri Sep 20 2013 Benjamin Marzinski 0.4.9-57 +- Add 0063-RH-fix-warning.patch + * Fix complier warning +- 0064-fix-ID_FS-attrs.patch + * make multipath create a timestamp file /run/multipathd/timestamp, and + add -T: option to shortcut processing if the + timestamp hasn't changed + +* Thu Sep 5 2013 Benjamin Marzinski 0.4.9-56 +- Add 0061-RH-display-find-mpaths.patch + * display the find_multipaths value in show config +- Add 0062-RH-dont-free-vecs.patch + * don't free the vecs structure on shutdown. It's more pain than + it's worth. + +* Thu Jul 25 2013 Benjamin Marzinski 0.4.9-55 +- Modify 0015-RH-fix-output-buffer.patch + * Fix memory leak +- Add 0047-RHBZ-kpartx-read-only-loop-devs.patch + * Fix read only loop device handling +- Add 0048-RH-print-defaults.patch +- Add 0049-RH-remove-ID_FS_TYPE.patch + * remove ID_FS_TYPE udev enviroment variable for multipath devices +- Add 0051-UP-fix-cli-resize.patch + * check before dereferencing variables +- Add 0052-RH-fix-bad-derefs.patch + * setup multipath free the multipath device when it fails, so don't keep + using it. +- Add 0053-UP-fix-failback.patch + * setting failback in the devices section was broken +- Add 0054-UP-keep-udev-ref.patch + * multipathd needs to keep the same udev object across reconfigures +- Add 0055-UP-handle-quiesced-paths.patch + * quiesced paths should be treated as down +- Add 0056-UP-alua-prio-fix.patch + * Don't count the preferred bit for paths that are active/optimized +- Add 0057-UP-fix-tmo.patch + * Cleanup how multipath sets dev_loss_tmo and fast_io_fail_tmo. Also + make multipath get changing values directly from sysfs, instead of + from udev, which caches them. +- Add 0058-UP-fix-failback.patch + * make failback print the default value when you show configs. +- Add 0059-UP-flush-failure-queueing.patch + * If you can't flush a multipath device, restore the queue_if_no_paths + value +- Add 0060-UP-uevent-loop-udev.patch + * make ueventloop grab it's own udev reference, since it is cancelled + asychnrously. + +* Fri Jul 5 2013 Benjamin Marzinski 0.4.9-54 +- Add 0047-RHBZ-980777-kpartx-read-only-loop-devs.patch + * make kpartx support read-only files better +- Resolves: bz #980777 + +* Wed Jul 3 2013 Benjamin Marzinski 0.4.9-53 +- Add 0044-RHBZ-976688-fix-wipe-wwids.patch + * Seek back to the start of the file after truncating it +- Add 0045-RHBZ-977297-man-page-fix.patch + * update man page to match actual defaults +- Add 0046-RHBZ-883981-move-udev-rules.patch + * move udev rules file from /lib to /usr/lib +- Resolves: bz #883981, #976688, #977297 + +* Fri Jun 21 2013 Benjamin Marzinski 0.4.9-52 +- Add 0038-RHBZ-799860-netapp-config.patch +- Add 0039-RH-detect-prio-fix.patch + * Don't autodetect ALUA prioritizer unless it actually can get a priority +- Add 0040-RH-bindings-fix.patch + * Do a better job of trying to get the first free user_friendly_name +- Add 0041-RH-check-for-erofs.patch + * Don't create/reload a device read-only unless doing it read/write fails + with EROFS +- Remove 0017-RH-fix-sigusr1.patch + * fix signal handling upstream way instead +- Add 0042-UP-fix-signal-handling.patch + * uxlsnr now handles all the signals sent to multipathd. This makes its + signal handling posix compliant, and harder to mess up. +- Add 0043-RH-signal-waiter.patch + * ioctl isn't a pthread cancellation point. Send a signal to the waiter + thread to break out of waiting in ioctl for a dm event. + +* Fri May 17 2013 Benjamin Marzinski 0.4.9-51 +- Add 0032-RHBZ-956464-mpathconf-defaults.patch + * fix defaults listed in usage +- Add 0033-RHBZ-829963-e-series-conf.patch +- Add 0034-RHBZ-851416-mpathconf-display.patch + * display whether or not multipathd is running in the status +- Add 0035-RHBZ-891921-list-mpp.patch + * add a new path format wilcard to list the multipath device associated + with a path +- Add 0036-RHBZ-949239-load-multipath-module.patch + * load the dm-multipath kernel module when multipathd starts +- Add 0037-RHBZ-768873-fix-rename.patch + * When deciding on a multipth devices name on reload, don't default to + the existing name if there is no config file alias and user_friendly_names + isn't set. Use the wwid. +- Modify multipath.conf +- Resolves: bz #768873, #950252 + +* Tue Apr 30 2013 Benjamin Marzinski 0.4.9-50 +- Add 0031-RHBZ-957188-kpartx-use-dm-name.patch + * use the basename of the devices that will be created to choose the + delimiter instead of using the device name from the command line +- Resolves: bz #957188 + +* Fri Apr 26 2013 Benjamin Marzinski 0.4.9-49 +- Modify 0020-RHBZ-907360-static-pthread-init.patch + * Don't initialize uevent list twice +- Add 0029-RH-no-prio-put-msg.patch +- Add 0030-RHBZ-916528-override-queue-no-daemon.patch + * Default to "queue_without_daemon no" + * Add "forcequeueing daemon" and "restorequeueing daemon" cli commands +- Modify spec file to force queue_without_daemon when restarting + multipathd on upgrades. + +* Thu Apr 4 2013 Benjamin Marzinski 0.4.9-48 +- Add 0026-fix-checker-time.patch + * Once multipathd hit it max checker interval, it was reverting to + to shortest checker interval +- Add 0027-RH-get-wwid.patch + * Multipath wasn't correctly setting the multipath wwid when it read devices + in from the kernel +- Add 0028-RHBZ-929078-refresh-udev-dev.patch + * Make multipath try to get the UID of down devices. Also, on ev_add_path, + make multipathd reinitialize existing devices that weren't fully + initialized before. + +* Mon Apr 1 2013 Benjamin Marzinski 0.4.9-47 +- Add 0021-RHBZ-919119-respect-kernel-cmdline.patch + * keep the multipath.rules udev file from running and multipathd from + starting if nompath is on the kernel command line +- Add 0022-RH-multipathd-check-wwids.patch + * Whenever multipath runs configure, it will check the wwids, and + add any missing ones to the wwids file +- Add 0023-RH-multipath-wipe-wwid.patch + * multipath's -w command will remove a wwid from the wwids file +- Add 0024-RH-multipath-wipe-wwids.patch + * multipath's -W command will set reset the wwids file to just the current + devices +- Add 0025-UPBZ-916668_add_maj_min.patch +- Resolves: bz #919119 + +* Thu Mar 28 2013 Benjamin Marzinski 0.4.9-46 +- Add 0020-RHBZ-907360-static-pthread-init.patch + * statically initialize the uevent pthread structures + +* Sat Mar 2 2013 Benjamin Marzinski 0.4.9-45 +- Updated to latest upstrem 0.4.9 code: multipath-tools-130222 + (git commit id: 67b82ad6fe280caa1770025a6bb8110b633fa136) +- Refresh 0001-RH-dont_start_with_no_config.patch +- Modify 0002-RH-multipath.rules.patch +- Modify 0003-RH-Make-build-system-RH-Fedora-friendly.patch +- Refresh 0004-RH-multipathd-blacklist-all-by-default.patch +- Refresh 0005-RH-add-mpathconf.patch +- Refresh 0006-RH-add-find-multipaths.patch +- Add 0008-RH-revert-partition-changes.patch +- Rename 0008-RH-RHEL5-style-partitions.patch to + 0009-RH-RHEL5-style-partitions.patch +- Rename 0009-RH-dont-remove-map-on-enomem.patch to + 0010-RH-dont-remove-map-on-enomem.patch +- Rename 0010-RH-deprecate-uid-gid-mode.patch to + 0011-RH-deprecate-uid-gid-mode.patch +- Rename 0013-RH-kpartx-msg.patch to 0012-RH-kpartx-msg.patch +- Rename 0035-RHBZ-883981-cleanup-rpmdiff-issues.patch to + 0013-RHBZ-883981-cleanup-rpmdiff-issues.patch +- Rename 0039-RH-handle-other-sector-sizes.patch to + 0014-RH-handle-other-sector-sizes.patch +- Rename 0040-RH-fix-output-buffer.patch to 0015-RH-fix-output-buffer.patch +- Add 0016-RH-dont-print-ghost-messages.patch +- Add 0017-RH-fix-sigusr1.patch + * Actually this fixes a number of issues related to signals +- Rename 0018-RH-remove-config-dups.patch to 0018-RH-fix-factorize.patch + * just the part that isn't upstream +- Add 0019-RH-fix-sockets.patch + * makes abstract multipathd a cli sockets use the correct name. +- Set find_multipaths in the default config + +* Wed Feb 20 2013 Benjamin Marzinski 0.4.9-44 +- Add 0036-UP-fix-state-handling.patch + * handle transport-offline and quiesce sysfs state +- Add 0037-UP-fix-params-size.patch +- Add 0038-RH-fix-multipath.rules.patch + * make sure multipath's link priority gets increased +- Add 0039-RH-handle-other-sector-sizes.patch + * allow gpt partitions on 4k sector size block devices. +- Add 0040-RH-fix-output-buffer.patch + * fix multipath -ll for large configuration. + +* Wed Feb 13 2013 Fedora Release Engineering - 0.4.9-43 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Dec 21 2012 Benjamin Marzinski 0.4.9-42 +- Add 0034-RHBZ-887737-check-for-null-key.patch +- Add 0035-RHBZ-883981-cleanup-rpmdiff-issues.patch + * Compile multipathd with full RELRO and PIE and install to /usr + +* Mon Dec 17 2012 Benjamin Marzinski 0.4.9-41 +- Add 0033-RH-dont-disable-libdm-failback-for-sync-case.patch + * make kpartx -s and multipath use libdm failback device creation, so + that they work in environments without udev + +* Fri Nov 30 2012 Benjamin Marzinski 0.4.9-40 +- Add 0032-RH-make-path-fd-readonly.patch + * revert change made when adding persistent reservations, so that path fds + are again opened O_RDONLY + +* Fri Nov 30 2012 Benjamin Marzinski 0.4.9-39 +- Add 0031-RHBZ-882060-fix-null-strncmp.patch + +* Fri Nov 30 2012 Benjamin Marzinski 0.4.9-38 +- Add 0026-RH-fix-mpathpersist-fns.patch +- Add 0027-RH-default-partition-delimiters.patch + * Only use the -p delimiter when the device name ends in a number +- Add 0028-RH-storagetek-config.patch +- Add 0029-RH-kpartx-retry.patch + * retry delete on busy loop devices +- Add 0030-RH-early-blacklist.patch + * multipath will now blacklist devices by device type and wwid in + store_pathinfo, so that it doesn't do a bunch of unnecessary work + on paths that it would only be removing later on. + +* Sat Nov 03 2012 Peter Rajnoha 0.4.9-37 +- Install multipathd.service for sysinit.target instead of multi-user.target. + +* Thu Nov 01 2012 Peter Rajnoha 0.4.9-36 +- Start multipathd.service systemd unit before LVM units. + +* Wed Oct 24 2012 Benjamin Marzinski 0.4.9-35 +- Add 0022-RHBZ-864368-disable-libdm-failback.patch + * make kpartx and multiapthd disable libdm failback device creation +- Add 0023-RHBZ-866291-update-documentation.patch +- Resolves: bz #864368, #866291 + +* Tue Oct 23 2012 Benjamin Marzinski 0.4.9-34 +- Add 0021-RH-fix-oom-adj.patch + * don't use OOM_ADJUST_MIN unless you're sure it's defined + +* Tue Oct 23 2012 Benjamin Marzinski 0.4.9-33 +- Modify 0016-RH-retain_hwhandler.patch + * Check the dm-multipath module version, and don't enable + retain_attached_hw_handler if the kernel doesn't support it +- Add 0019-RH-detect-prio.patch + * add detect_prio option, to make multipath check if the device + supports the ALUA prio, before defaulting to the configured prio +- Remove 0017-RH-netapp_config.patch +- Add 0020-RH-netapp-config.patch + * new netapp config that uses retain_attached_hw_handler and + detect_prio to autoconfigure ALUA and non-ALUA devices. + +* Tue Oct 2 2012 Benjamin Marzinski 0.4.9-32 +- Modified 0018-RH-remove-config-dups.patch + * Made modified config remove original only if the vendor/product + exactly match + +* Thu Sep 27 2012 Benjamin Marzinski 0.4.9-31 +- Add 0014-RH-dm_reassign.patch + * Fix reassign_maps option +- Add 0015-RH-selector_change.patch + * devices default to using service-time selector +- Add 0016-RH-retain_hwhandler.patch + * add retain_attached_hw_handler option, to let multipath keep an + already attached scsi device handler +- Add 0017-RH-netapp_config.patch +- Add 0018-RH-remove-config-dups.patch + * Clean up duplicates in the devices and blacklist sections + +* Wed Sep 05 2012 Václav Pavlín - 0.4.9-30 +- Scriptlets replaced with new systemd macros (#850088) + +* Tue Aug 21 2012 Benjamin Marzinski 0.4.9-29 +- Updated to latest upstrem 0.4.9 code: multipath-tools-120821.tgz + (git commit id: 050b24b33d3c60e29f7820d2fb75e84a9edde528) + * includes 0001-RH-remove_callout.patch, 0002-RH-add-wwids-file.patch, + 0003-RH-add-followover.patch, 0004-RH-fix-cciss-names.patch +- Add 0013-RH-kpartx-msg.patch +- Modify 0002-RH-multipath.rules.patch + * removed socket call from rules file + +* Wed Jul 18 2012 Fedora Release Engineering - 0.4.9-28 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jun 28 2012 Benjamin Marzinski 0.4.9-27 +- Updated to latest upstream 0.4.9 code : multipath-tools-120613.tgz + (git commit id: cb0f7127ba90ab5e8e71fc534a0a16cdbe96a88f) +- Add 0001-RH-remove_callout.patch + * multipath no longer uses the getuid callout. It now gets the + wwid from the udev database or the environment variables +- Add 0004-RH-fix-cciss-names.patch + * convert cciss device names from cciss/cXdY to sysfs style cciss!cXdY +- Split 0009-RH-add-find-multipaths.patch into 0002-RH-add-wwids-file.patch + and 0010-RH-add-find-multipaths.patch +- Add 0016-RH-change-configs.patch + * default fast_io_fail to 5 and don't set the path selector in the + builtin configs. +Resolves: bz #831978 + + +* Thu May 17 2012 Benjamin Marzinski 0.4.9-26 +- Add 0025-RHBZ-822714-update-nodes.patch +- Resolves: bz #822714 + +* Mon Apr 30 2012 Benjamin Marzinski 0.4.9-25 +- Modify 0024-RH-libudev-monitor.patch +- Resolves: bz #805493 + +* Mon Apr 30 2012 Benjamin Marzinski 0.4.9-24 +- Add requirements on libudev to spec file +- Resolves: bz #805493 + +* Mon Apr 30 2012 Benjamin Marzinski 0.4.9-23 +- Add 0024-RH-libudev-monitor.patch + +* Fri Feb 10 2012 Benjamin Marzinski 0.4.9-22 +- Add 0012-RH-update-on-show-topology.patch +- Add 0013-RH-manpage-update.patch +- Add 0014-RH-RHEL5-style-partitions.patch +- Add 0015-RH-add-followover.patch +- Add 0016-RH-dont-remove-map-on-enomem.patch +- Add 0017-RH-fix-shutdown-crash.patch +- Add 0018-RH-warn-on-bad-dev-loss-tmo.patch +- Add 0019-RH-deprecate-uid-gid-mode.patch +- Add 0020-RH-dont-remove-map-twice.patch +- Add 0021-RH-validate-guid-partitions.patch +- Add 0022-RH-adjust-messages.patch +- Add 0023-RH-manpage-update.patch + +* Tue Jan 24 2012 Benjamin Marzinski 0.4.9-21 +- Updated to latest upstream 0.4.9 code : multipath-tools-120123.tgz + (git commit id: 63704387009443bdb37d9deaaafa9ab121d45bfb) +- Add 0001-RH-fix-async-tur.patch +- Add 0002-RH-dont_start_with_no_config.patch +- Add 0003-RH-multipath.rules.patch +- Add 0004-RH-update-init-script.patch +- Add 0005-RH-cciss_id.patch +- Add 0006-RH-Make-build-system-RH-Fedora-friendly.patch +- Add 0007-RH-multipathd-blacklist-all-by-default.patch +- Add 0008-RH-add-mpathconf.patch +- Add 0009-RH-add-find-multipaths.patch +- Add 0010-RH-check-if-multipath-owns-path.patch +- Add 0011-RH-add-hp_tur-checker.patch + +* Fri Jan 13 2012 Fedora Release Engineering - 0.4.9-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Sep 20 2011 Benjamin Marzinski -0.4.9-19 +- Modify 0103-add-disable-sync-option.patch +- Add 0104-RHBZ-737989-systemd-unit-fix.patch + * systemd will only start multipathd if /etc/multipath.conf exists +- Add 0105-fix-oom-adj.patch + * first try setting oom_score_adj + +* Mon Aug 15 2011 Kalev Lember - 0.4.9-18 +- Rebuilt for rpm bug #728707 + +* Tue Jul 19 2011 Benjamin Marzinski -0.4.9-17 +- Add 0103-add-disable-sync-option.patch + * add a -n (nosync) option to multipath. This disables synchronous + file creation with udev. + +* Fri Jul 15 2011 Benjamin Marzinski -0.4.9-16 +- Modify 0012-RH-udev-sync-support.patch +- Modify 0021-RHBZ-548874-add-find-multipaths.patch +- Modify 0022-RHBZ-557845-RHEL5-style-partitions.patch +- Add 0025-RHBZ-508827-update-multipathd-manpage.patch through + 0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch + * sync with current state of RHEL6. Next release should include a updated + source tarball with most of these fixes rolled in. +- Add 0102-RHBZ-690828-systemd-unit-file.patch + * Add Jóhann B. Guðmundsson's unit file for systemd. + * Add sub-package sysvinit for SysV init script. +- Resolves: bz #690828 + +* Tue Feb 08 2011 Fedora Release Engineering - 0.4.9-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Feb 16 2010 Benjamin Marzinski -0.4.9-14 +- Modify 0021-RHBZ-548874-add-find-multipaths.patch + * fix bug where mpathconf wouldn't create a multpath.conf file unless one + already existed. + +* Tue Feb 16 2010 Benjamin Marzinski -0.4.9-13 +- Replace 0012-RH-explicitly-disable-dm-udev-sync-support-in-kpartx.patch + with 0012-RH-udev-sync-support.patch + * Add udev sync support to kpartx and multipath. In kpartx it is disabled + unless you use the -s option. +- Refresh 0013-RH-add-weighted_prio-prioritizer.patch +- Refresh 0021-RHBZ-548874-add-find-multipaths.patch +- Modify 0022-RHBZ-557845-RHEL5-style-partitions.patch + * kpartx now creates a 2 sector large device for dos extended + partitions, just like the kernel does on the regular block devices. +- Add 0023-RHBZ-557810-emc-invista-config.patch +- Add 0024-RHBZ-565933-checker-timeout.patch + * Multipath has a new option checker_timeout. If this is not set, + all path checker functions with explicit timeouts use + /sys/block/sd/device/timeout. If this is set, they use it instead. + +* Fri Jan 22 2010 Benjamin Marzinski -0.4.9-12 +- Refresh 0001-RH-queue-without-daemon.patch +- Refresh 0002-RH-path-checker.patch +- Modify 0010-RH-multipath-rules-udev-changes.patch + * Fix udev rules to use DM_SBIN_PATH when calling kpartx + * install udev rules to /lib/udev/rules.d instead of /etc/udev/rules.d +- Modify 0014-RH-add-hp_tur-checker.patch +- Add 0003-for-upstream-default-configs.patch +- Add 0016-RHBZ-554561-fix-init-error-msg.patch +- Add 0017-RHBZ-554592-man-page-note.patch +- Add 0018-RHBZ-554596-SUN-6540-config.patch +- Add 0019-RHBZ-554598-fix-multipath-locking.patch +- Add 0020-RHBZ-554605-fix-manual-failover.patch +- Add 0021-RHBZ-548874-add-find-multipaths.patch + * Added find_multipaths multipath.conf option + * Added /sbin/mpathconf for simple editting of multipath.conf +- Add 0022-RHBZ-557845-RHEL5-style-partitions.patch + * Make kpartx deal with logical partitions like it did in RHEL5. + Don't create a dm-device for the extended partition itself. + Create the logical partitions on top of the dm-device for the whole disk. + +* Mon Nov 16 2009 Benjamin Marzinski -0.4.9-11 +- Add 0002-for-upstream-add-tmo-config-options.patch + * Add fail_io_fail_tmo and dev_loss_tmo multipath.conf options +- Add 0013-RH-add-weighted_prio-prioritizer.patch +- Add 0014-RH-add-hp_tur-checker.patch +- Add 0015-RH-add-multipathd-count-paths-cmd.patch +- rename multipath.conf.redhat to multipath.conf, and remove the default + blacklist. + +* Tue Oct 27 2009 Fabio M. Di Nitto - 0.4.9-10 +- Updated to latest upstream 0.4.9 code : multipath-tools-091027.tar.gz + (git commit id: a946bd4e2a529e5fba9c9547d03d3f91806618a3) +- Drop unrequired for-upstream patches. +- BuildRequires and Requires new device-mapper version for udev sync support. + +* Tue Oct 20 2009 Fabio M. Di Nitto - 0.4.9-9 +- 0012-RH-explicitly-disable-dm-udev-sync-support-in-kpartx.patch + +* Mon Oct 19 2009 Fabio M. Di Nitto - 0.4.9-8 +- Split patches in "for-upstream" and "RH" series. +- Replace 0011-RH-multipathd-blacklist-all-by-default.patch with + version from Benjamin Marzinski. +- Update udev rules 0010-RH-multipath-rules-udev-changes.patch. +- rpmlint cleanup: + * Drop useless-provides kpartx. + * Cleanup tab vs spaces usage. + * Summary not capitalized. + * Missing docs in libs package. + * Fix init script LSB headers. +- Drop README* files from doc sections (they are empty). + +* Thu Oct 15 2009 Fabio M. Di Nitto - 0.4.9-7 +- Add patch 0010-RH-Set-friendly-defaults.patch: + * set rcdir to fedora default. + * do not install kpartx udev bits. + * install redhat init script. + * Cleanup spec file install target. +- Add patch 0011-RH-multipathd-blacklist-all-by-default.patch: + * Fix BZ#528059 + * Stop installing default config in /etc and move it to the doc dir. + +* Tue Oct 13 2009 Fabio M. Di Nitto - 0.4.9-6 +- Updated to latest upstream 0.4.9 code : multipath-tools-091013.tar.gz + (git commit id: aa0a885e1f19359c41b63151bfcface38ccca176) +- Drop, now upstream, patches: + * fix_missed_uevs.patch. + * log_all_messages.patch. + * uninstall.patch. + * select_lib.patch. + * directio_message_cleanup.patch. + * stop_warnings.patch. +- Drop redhatification.patch in favour of spec file hacks. +- Drop mpath_wait.patch: no longer required. +- Merge multipath_rules.patch and udev_change.patch. +- Rename all patches based on source. +- Add patch 0009-RH-fix-hp-sw-hardware-table-entries.patch to fix + default entry for hp_sw and match current kernel. +- Add multipath.conf.redhat as source instead of patch. +- spec file: + * divide runtime and build/setup bits. + * update BuildRoot. + * update install section to apply all the little hacks here and there, + in favour of patches against upstream. + * move ldconfig invokation to libs package where it belong. + * fix libs package directory ownership and files. + +* Thu Aug 20 2009 Benjamin Marzinski - 0.4.9-5 +- Fixed problem where maps were being added and then removed. +- Changed the udev rules to fix some issues. + +* Thu Jul 30 2009 Benjamin Marzinski - 0.4.9-4 +- Fixed build issue on i686 machines. + +* Wed Jul 29 2009 Benjamin Marzinski - 0.4.9-3 +- Updated to latest upstream 0.4.9 code : multipath-tools-090729.tgz + (git commit id: d678c139719d5631194b50e49f16ca97162ecd0f) +- moved multipath bindings file from /var/lib/multipath to /etc/multipath +- Fixed 354961, 432520 + +* Fri Jul 24 2009 Fedora Release Engineering - 0.4.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed May 6 2009 Mike Snitzer - 0.4.9-1 +- Updated to latest upstream 0.4.9 code: multipath-tools-090429.tgz + (git commit id: 7395bcda3a218df2eab1617df54628af0dc3456e) +- split the multipath libs out to a device-mapper-multipath-libs package +- if appropriate, install multipath libs in /lib64 and /lib64/multipath + +* Tue Apr 7 2009 Milan Broz - 0.4.8-10 +- Fix insecure permissions on multipathd.sock (CVE-2009-0115) + +* Fri Mar 6 2009 Milan Broz - 0.4.8-9 +- Fix kpartx extended partition handling (475283) + +* Tue Feb 24 2009 Fedora Release Engineering - 0.4.8-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Sep 26 2008 Benjamin Marzinski 0.4.8-7 +- Since libaio is now in /lib, not /usr/lib, multipath no longer needs to + statically link against it. Fixed an error with binding file and WWIDs + that include spaces. Cleaned up the messages from the directio checker + function. Fixed the udev rules. Fixed a regression in multipath.conf + parsing +- Fixed 457530, 457589 + +* Wed Aug 20 2008 Benjamin Marzinski 0.4.8-6 +- Updated to latest upstream 0.4.8 code: multipath-tools-080804.tgz + (git commit id: eb87cbd0df8adf61d1c74c025f7326d833350f78) +- fixed 451817, 456397 (scsi_id_change.patch), 457530 (config_space_fix.patch) + 457589 (static_libaio.patch) + +* Fri Jun 13 2008 Alasdair Kergon - 0.4.8-5 +- Rebuild (rogue vendor tag). (451292) + +* Mon May 19 2008 Benjamin Marzinksi 0.4.8-4 +- Fixed Makefile issues. + +* Mon May 19 2008 Benjamin Marzinksi 0.4.8-3 +- Fixed ownership build error. + +* Mon May 19 2008 Benjamin Marzinksi 0.4.8-2 +- Forgot to commit some patches. + +* Mon May 19 2008 Benjamin Marzinski 0.4.8-1 +- Updated to latest Upstream 0.4.8 code: multipath-tools-080519.tgz + (git commit id: 42704728855376d2f7da2de1967d7bc71bc54a2f) + +* Tue May 06 2008 Alasdair Kergon - 0.4.7-15 +- Remove unnecessary multipath & kpartx static binaries. (bz 234928) + +* Fri Feb 29 2008 Tom "spot" Callaway - 0.4.7-14 +- fix sparc64 +- fix license tag + +* Tue Feb 19 2008 Fedora Release Engineering - 0.4.7-13 +- Autorebuild for GCC 4.3 + +* Wed Nov 14 2007 Benjamin Marzinski - 0.4.7-12 +- Fixed the dist tag so building will work properly. + +* Mon Feb 05 2007 Alasdair Kergon - 0.4.7-11.fc7 +- Add build dependency on new device-mapper-devel package. +- Add dependency on device-mapper. + +* Wed Jan 31 2007 Benjamin Marzinksi - 0.4.7-10.fc7 +- Update BuildRoot and PreReq lines. + +* Mon Jan 15 2007 Benjamin Marzinksi - 0.4.7-9.fc7 +- Fixed spec file. + +* Mon Jan 15 2007 Benjamin Marzinski - 0.4.7-8.fc7 +- Update to latest code (t0_4_7_head2) + +* Wed Dec 13 2006 Benjamin Marzinski - 0.4.7-7.fc7 +- Update to latest code (t0_4_7_head1) + +* Thu Sep 7 2006 Peter Jones - 0.4.7-5 +- Fix kpartx to handle with drives >2TB correctly. + +* Thu Aug 31 2006 Peter Jones - 0.4.7-4.1 +- Split kpartx out into its own package so dmraid can use it without + installing multipathd +- Fix a segfault in kpartx + +* Mon Jul 17 2006 Benjamin Marzinski 0.4.7-4.0 +- Updated to latest source. Fixes bug in default multipath.conf + +* Wed Jul 12 2006 Benjamin Marzinski 0.4.7-3.1 +- Added ncurses-devel to BuildRequires + +* Wed Jul 12 2006 Benjamin Marzinski 0.4.7-3.0 +- Updated to latest source. deals with change in libsysfs API + +* Wed Jul 12 2006 Jesse Keating - 0.4.7-2.2.1 +- rebuild + +* Mon Jul 10 2006 Benjamin Marzinski 0.4.7-2.2 +- fix tagging issue. + +* Mon Jul 10 2006 Benjamin Marzinski 0.4.7-2.1 +- changed BuildRequires from sysfsutils-devel to libsysfs-devel + +* Wed Jun 28 2006 Benjamin Marzinski 0.4.7-2.0 +- Updated to latest upstream source, fixes kpartx udev rule issue + +* Tue Jun 06 2006 Benjamin Marzinski 0.4.7-1.0 +- Updated to Christophe's latest source + +* Mon May 22 2006 Alasdair Kergon - 0.4.5-16.0 +- Newer upstream source (t0_4_5_post59). + +* Mon May 22 2006 Alasdair Kergon - 0.4.5-12.3 +- BuildRequires: libsepol-devel, readline-devel + +* Mon Feb 27 2006 Benjamin Marzinski 0.4.5-12.2 +- Prereq: chkconfig + +* Mon Feb 20 2006 Karsten Hopp 0.4.5-12.1 +- BuildRequires: libselinux-devel + +* Fri Feb 10 2006 Jesse Keating - 0.4.5-12.0.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Benjamin Marzinski -0.4.5-12.0 +- Updated to latest upstream source (t0_4_5_post56) + +* Tue Feb 07 2006 Jesse Keating - 0.4.5-9.1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Mon Dec 19 2005 Benjamin Marzinski - 0.4.5-9.1 +- added patch for fedora changes + +* Fri Dec 16 2005 Benjamin Marzinski - 0.4.5-9.0 +- Updated to latest upstream source (t)_4_5_post52) + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Sun Dec 4 2005 Peter Jones - 0.4.4-2.6 +- rebuild for newer libs + +* Tue Nov 15 2005 Peter Jones - 0.4.4-2.5 +- unsplit kpartx. parted knows how to do this now, so we don't + need this in a separate package. + +* Tue Nov 15 2005 Peter Jones - 0.4.4-2.4 +- split kpartx out into its own package + +* Fri May 06 2005 Bill Nottingham - 0.4.4-2.3 +- Fix last fix. + +* Thu May 05 2005 Alasdair Kergon - 0.4.4-2.2 +- Fix last fix. + +* Wed May 04 2005 Alasdair Kergon - 0.4.4-2.1 +- By default, disable the multipathd service. + +* Tue Apr 19 2005 Alasdair Kergon - 0.4.4-2.0 +- Fix core dump from last build. + +* Tue Apr 19 2005 Alasdair Kergon - 0.4.4-1.0 +- Move cache file into /var/cache/multipath. + +* Fri Apr 08 2005 Alasdair Kergon - 0.4.4-0.pre8.1 +- Remove pp_balance_units. + +* Mon Apr 04 2005 Alasdair Kergon - 0.4.4-0.pre8.0 +- Incorporate numerous upstream fixes. +- Update init script to distribution standards. + +* Tue Mar 01 2005 Alasdair Kergon - 0.4.2-1.0 +- Initial import based on Christophe Varoqui's spec file.