Compare commits
No commits in common. "c9s" and "c8" have entirely different histories.
|
@ -1,2 +1 @@
|
|||
067d668de8e3a70b7c176bbf0c0616d5835bbe44 multipath-tools-0.8.7.tgz
|
||||
5d5e16cccc83fd78cf9b95e5c52cc41dbbeb1da7 multipath.conf
|
||||
b52c2be340449664f0a122070838f6d8edd42e4a SOURCES/multipath-tools-0.8.4.tgz
|
||||
|
|
|
@ -1,25 +1 @@
|
|||
multipath-tools-091027.tar.gz
|
||||
/multipath-tools-120123.tgz
|
||||
/multipath-tools-120613.tgz
|
||||
/multipath-tools-120821.tgz
|
||||
/multipath-tools-130222.tgz
|
||||
/multipath-tools-f21166a.tgz
|
||||
/multipath.conf
|
||||
/multipath-tools-git847cc43.tgz
|
||||
/multipath-tools-0.7.3.tgz
|
||||
/multipath-tools-07e7bd5.tgz
|
||||
/multipath-tools-1cb704b.tgz
|
||||
/multipath-tools-0.7.7.tgz
|
||||
/multipath-tools-ef6d98b.tgz
|
||||
/multipath-tools-1a8625a.tgz
|
||||
/multipath-tools-b80318b.tgz
|
||||
/multipath-tools-0.7.8.tgz
|
||||
/multipath-tools-0.7.9.tgz
|
||||
/multipath-tools-17a6101.tgz
|
||||
/multipath-tools-2df6110.tgz
|
||||
/multipath-tools-0.8.0.tgz
|
||||
/multipath-tools-0.8.2.tgz
|
||||
/multipath-tools-0.8.4.tgz
|
||||
/multipath-tools-0.8.5.tgz
|
||||
/multipath-tools-0.8.6.tgz
|
||||
/multipath-tools-0.8.7.tgz
|
||||
SOURCES/multipath-tools-0.8.4.tgz
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <michael.christie@oracle.com>
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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
|
||||
.
|
|
@ -1,52 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: lixiaokeng <lixiaokeng@huawei.com>
|
||||
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 <lixiaokeng@huawei.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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;
|
|
@ -1,48 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Date: Thu, 16 Sep 2021 00:44:49 +0200
|
||||
Subject: [PATCH] multipath-tools: minor fixes to multipath.conf.5 man page
|
||||
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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<system dependent>\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
|
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 */
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Luca BRUNO <luca.bruno@coreos.com>
|
||||
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 <luca.bruno@coreos.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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]
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 /
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 */
|
|
@ -1,37 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 */
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <sean_mcginnis@dell.com>
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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,
|
||||
},
|
||||
{
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
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 <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 <sean_mcginnis@dell.com>
|
||||
- */
|
||||
+ /* SC Series, formerly Compellent */
|
||||
.vendor = "COMPELNT",
|
||||
.product = "Compellent Vol",
|
||||
.pgpolicy = GROUP_BY_PRIO,
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
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 <Wayne.Berthiaume@dell.com>, 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 <bmarzins@redhat.com>
|
||||
---
|
||||
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 */
|
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
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" <Wayne.Berthiaume@dell.com>, 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 <bmarzins@redhat.com>
|
||||
---
|
||||
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 */
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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 $@ $<
|
|
@ -1,102 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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);
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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<unset>\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<unset>\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.
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
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 <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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
|
|
@ -1,45 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
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);
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <y|n> for setthing the
|
||||
recheck_wwid option
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
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 <yes|no|strict|greedy|smart>"
|
||||
echo "Set default property blacklist (Default n): --property_blacklist <y|n>"
|
||||
echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>"
|
||||
+ echo "Set recheck_wwid (Defaut n): --recheck_wwid <y|n>"
|
||||
echo "Add/Change/Remove option in defaults section: --option <option_name>:<value>"
|
||||
echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
@@ -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<value>\fP, this adds the line
|
||||
.B find_multipaths <value>
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
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 = {
|
|
@ -1,86 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 29 Mar 2022 22:22:10 -0500
|
||||
Subject: [PATCH] multipathd: Don't keep starting TUR threads, if they always
|
||||
hang.
|
||||
|
||||
If tur thead hangs, multipathd was simply creating a new thread, and
|
||||
assuming that the old thread would get cleaned up eventually. I have
|
||||
seen a case recently where there were 26000 multipathd threads on a
|
||||
system, all stuck trying to send TUR commands to path devices. The root
|
||||
cause of the issue was a scsi kernel issue, but it shows that the way
|
||||
multipathd currently deals with stuck threads could use some refinement.
|
||||
|
||||
Now, when one tur thread hangs, multipathd will act as it did before.
|
||||
If a second one in a row hangs, multipathd will instead wait for it to
|
||||
complete before starting another thread. Once the thread completes, the
|
||||
count is reset.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com
|
||||
---
|
||||
libmultipath/checkers/tur.c | 23 +++++++++++++++++++++--
|
||||
1 file changed, 21 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
||||
index a4b4a213..d82f7dbc 100644
|
||||
--- a/libmultipath/checkers/tur.c
|
||||
+++ b/libmultipath/checkers/tur.c
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#define TUR_CMD_LEN 6
|
||||
#define HEAVY_CHECK_COUNT 10
|
||||
+#define MAX_NR_TIMEOUTS 1
|
||||
|
||||
enum {
|
||||
MSG_TUR_RUNNING = CHECKER_FIRST_MSGID,
|
||||
@@ -55,6 +56,7 @@ struct tur_checker_context {
|
||||
int holders; /* uatomic access only */
|
||||
int msgid;
|
||||
struct checker_context ctx;
|
||||
+ unsigned int nr_timeouts;
|
||||
};
|
||||
|
||||
int libcheck_init (struct checker * c)
|
||||
@@ -359,8 +361,23 @@ int libcheck_check(struct checker * c)
|
||||
}
|
||||
} else {
|
||||
if (uatomic_read(&ct->holders) > 1) {
|
||||
+ /* The thread has been cancelled but hasn't quit. */
|
||||
+ if (ct->nr_timeouts == MAX_NR_TIMEOUTS) {
|
||||
+ condlog(2, "%d:%d : waiting for stalled tur thread to finish",
|
||||
+ major(ct->devt), minor(ct->devt));
|
||||
+ ct->nr_timeouts++;
|
||||
+ }
|
||||
/*
|
||||
- * The thread has been cancelled but hasn't quit.
|
||||
+ * Don't start new threads until the last once has
|
||||
+ * finished.
|
||||
+ */
|
||||
+ if (ct->nr_timeouts > MAX_NR_TIMEOUTS) {
|
||||
+ c->msgid = MSG_TUR_TIMEOUT;
|
||||
+ return PATH_TIMEOUT;
|
||||
+ }
|
||||
+ ct->nr_timeouts++;
|
||||
+ /*
|
||||
+ * Start a new thread while the old one is stalled.
|
||||
* We have to prevent it from interfering with the new
|
||||
* thread. We create a new context and leave the old
|
||||
* one with the stale thread, hoping it will clean up
|
||||
@@ -376,13 +393,15 @@ int libcheck_check(struct checker * c)
|
||||
*/
|
||||
if (libcheck_init(c) != 0)
|
||||
return PATH_UNCHECKED;
|
||||
+ ((struct tur_checker_context *)c->context)->nr_timeouts = ct->nr_timeouts;
|
||||
|
||||
if (!uatomic_sub_return(&ct->holders, 1))
|
||||
/* It did terminate, eventually */
|
||||
cleanup_context(ct);
|
||||
|
||||
ct = c->context;
|
||||
- }
|
||||
+ } else
|
||||
+ ct->nr_timeouts = 0;
|
||||
/* Start new TUR checker */
|
||||
pthread_mutex_lock(&ct->lock);
|
||||
tur_status = ct->state = PATH_PENDING;
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 29 Nov 2022 19:56:37 -0600
|
||||
Subject: [PATCH] multipath.conf(5): remove io-affinity information
|
||||
|
||||
The multpath-tools do not support the io-affinity path selector. We
|
||||
always add a repeat count as the path argument. The io-affinity selector
|
||||
doesn't take one. Instead it takes a bit map of CPUs that a path can
|
||||
run on. This isn't something that lends itself to the kind of
|
||||
auto-assembling that multipathd does. But even if we did want to
|
||||
try to support this path-selector, until we do, we shouldn't be listing
|
||||
it in the multipath.conf documentation.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.conf.5 | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 01904feb..5e447e67 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -211,10 +211,6 @@ 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
|
||||
.
|
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 30 Jan 2023 19:54:19 -0600
|
||||
Subject: [PATCH] libmultipath: use select_reload_action in select_action
|
||||
|
||||
Since we have a function to set the action to reload, use it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 193bf27d..09d7de0f 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -771,9 +771,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp,
|
||||
|
||||
if (force_reload) {
|
||||
mpp->force_udev_reload = 1;
|
||||
- mpp->action = ACT_RELOAD;
|
||||
- condlog(3, "%s: set ACT_RELOAD (forced by user)",
|
||||
- mpp->alias);
|
||||
+ select_reload_action(mpp, "forced by user");
|
||||
return;
|
||||
}
|
||||
if (cmpp->size != mpp->size) {
|
||||
@@ -786,9 +784,7 @@ void select_action (struct multipath *mpp, const struct _vector *curmp,
|
||||
|
||||
if (!is_udev_ready(cmpp) && count_active_paths(mpp) > 0) {
|
||||
mpp->force_udev_reload = 1;
|
||||
- mpp->action = ACT_RELOAD;
|
||||
- condlog(3, "%s: set ACT_RELOAD (udev incomplete)",
|
||||
- mpp->alias);
|
||||
+ select_reload_action(mpp, "udev incomplete");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 7 Feb 2023 15:39:26 -0600
|
||||
Subject: [PATCH] multipath.rules: fix "smart" bug with failed valid path check
|
||||
|
||||
If "multipath -u" fails, udev doesn't import any values from the
|
||||
program. This means that multipath.rules will continue to use the values
|
||||
for DM_MULTIPATH_DEVICE_PATH and FIND_MULTIPATHS_WAIT_UNTIL that it has
|
||||
already imported from the database. This is the correct thing to do for
|
||||
every case except the MAYBE case for "find_multipaths smart". In that
|
||||
case, DM_MULTIPATH_DEVICE_PATH will be set to 1, and the rules will
|
||||
assume that the device has been definitively claimed.
|
||||
|
||||
In this case, we know that the device shouldn't have been claimed
|
||||
before, but we don't know if it should be claimed now, or if we have hit
|
||||
the timeout and it should be released, since we didn't get any
|
||||
information from multipath. The safest thing to do is assume that this
|
||||
was the timeout, and the device shouldn't be claimed. The only time when
|
||||
this could be the wrong answer is when we first see a new multipath
|
||||
device, and it could only cause problems if there is metadata on the
|
||||
device that will cause it to get autoassembled by something else, before
|
||||
multipathd can autoassemble it. If we assume that it is a multipath
|
||||
device, or we assume that this wasn't actually the timeout uevent, we
|
||||
can keep a necessary device from getting released to the reset of the
|
||||
system.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.rules.in | 22 ++++++++++++++++------
|
||||
1 file changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in
|
||||
index 5c4447a2..70b69a06 100644
|
||||
--- a/multipath/multipath.rules.in
|
||||
+++ b/multipath/multipath.rules.in
|
||||
@@ -32,7 +32,8 @@ IMPORT{db}="DM_MULTIPATH_DEVICE_PATH"
|
||||
|
||||
# multipath -u sets DM_MULTIPATH_DEVICE_PATH and,
|
||||
# if "find_multipaths smart", also FIND_MULTIPATHS_WAIT_UNTIL.
|
||||
-IMPORT{program}="$env{MPATH_SBIN_PATH}/multipath -u %k"
|
||||
+IMPORT{program}=="$env{MPATH_SBIN_PATH}/multipath -u %k", \
|
||||
+ ENV{.MPATH_CHECK_PASSED}="1"
|
||||
|
||||
# case 1: this is definitely multipath
|
||||
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
|
||||
@@ -83,10 +84,19 @@ LABEL="stop_wait"
|
||||
# If timeout hasn't expired but we're not in "maybe" state any more, stop timer
|
||||
# Do this only once, and only if the timer has been started before
|
||||
IMPORT{db}="FIND_MULTIPATHS_WAIT_CANCELLED"
|
||||
-ENV{FIND_MULTIPATHS_WAIT_CANCELLED}!="?*", \
|
||||
- ENV{FIND_MULTIPATHS_WAIT_UNTIL}=="?*", \
|
||||
- ENV{FIND_MULTIPATHS_WAIT_UNTIL}!="0", \
|
||||
- ENV{FIND_MULTIPATHS_WAIT_CANCELLED}="1", \
|
||||
- RUN+="/usr/bin/systemctl stop cancel-multipath-wait-$kernel.timer"
|
||||
+ENV{FIND_MULTIPATHS_WAIT_CANCELLED}=="?*", GOTO="end_mpath"
|
||||
+ENV{FIND_MULTIPATHS_WAIT_UNTIL}!="?*", GOTO="end_mpath"
|
||||
+ENV{FIND_MULTIPATHS_WAIT_UNTIL}=="0", GOTO="end_mpath"
|
||||
+
|
||||
+ENV{FIND_MULTIPATHS_WAIT_CANCELLED}="1"
|
||||
+RUN+="/usr/bin/systemctl stop cancel-multipath-wait-$kernel.timer"
|
||||
+
|
||||
+# If "multipath -u" failed, no values are imported from the program,
|
||||
+# and we are still using the values for DM_MULTIPATH_DEVICE_PATH and
|
||||
+# FIND_MULTIPATHS_WAIT_UNTIL that were imported from the database.
|
||||
+# If we are in "smart" mode, we need to give up on the path now,
|
||||
+# since this may have been the timeout event. Without the imports
|
||||
+# from "multipath -u", we can't tell.
|
||||
+ENV{.MPATH_CHECK_PASSED}!="?*", ENV{DM_MULTIPATH_DEVICE_PATH}="0"
|
||||
|
||||
LABEL="end_mpath"
|
|
@ -1,64 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 8 Feb 2023 19:31:02 -0600
|
||||
Subject: [PATCH] libmultipath: limit paths that can get wwid from environment
|
||||
|
||||
Currently, whenever getting the uid_attribute from udev database fails,
|
||||
multipath will try to get it from the environment variables. This
|
||||
normally isn't a problem, since either multipath -u is getting called
|
||||
from a uevent, and the environment will have the correct value in that
|
||||
variable, or that variable won't be set. However, when find_multipaths
|
||||
is configured to "smart", this causes problems. For maybe devices,
|
||||
multipath needs to get the WWIDs of all the other block devices, to see
|
||||
if they match the maybe device wwid. If one of those devices doesn't
|
||||
have uid_attribute set in its udev database, multipath will check the
|
||||
environment for it, and it will find that variable set to the WWID
|
||||
of the maybe device that this uevent is for. This means that all
|
||||
devices with no WWID will end up appearing to have the same WWID as
|
||||
the maybe device, causing multipath to incorrectly claim it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 2 +-
|
||||
libmultipath/structs.h | 1 +
|
||||
multipath/main.c | 2 ++
|
||||
3 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index f593a7bf..a592a54e 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -2032,7 +2032,7 @@ get_udev_uid(struct path * pp, char *uid_attribute, struct udev_device *udev)
|
||||
const char *value;
|
||||
|
||||
value = udev_device_get_property_value(udev, uid_attribute);
|
||||
- if (!value || strlen(value) == 0)
|
||||
+ if ((!value || strlen(value) == 0) && pp->can_use_env_uid)
|
||||
value = getenv(uid_attribute);
|
||||
if (value && strlen(value)) {
|
||||
len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 0867b91d..4b308561 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -360,6 +360,7 @@ struct path {
|
||||
int fast_io_fail;
|
||||
unsigned int dev_loss;
|
||||
int eh_deadline;
|
||||
+ bool can_use_env_uid;
|
||||
/* configlet pointers */
|
||||
vector hwe;
|
||||
struct gen_path generic_path;
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 41d01c7e..e056c51c 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -653,6 +653,8 @@ check_path_valid(const char *name, struct config *conf, bool is_uevent)
|
||||
pp = alloc_path();
|
||||
if (!pp)
|
||||
return RTVL_FAIL;
|
||||
+ if (is_uevent)
|
||||
+ pp->can_use_env_uid = true;
|
||||
|
||||
r = is_path_valid(name, conf, pp, is_uevent);
|
||||
if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT)
|
|
@ -1,186 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 7 Jul 2023 15:25:59 -0500
|
||||
Subject: [PATCH] RH: Add mpathcleanup
|
||||
|
||||
mpathcleanup is a program that will remove a multipath device as well as
|
||||
all of the scsi path devices that make it up.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/Makefile | 2 +
|
||||
multipath/mpathcleanup | 145 +++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 147 insertions(+)
|
||||
create mode 100755 multipath/mpathcleanup
|
||||
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index f3d98012..1fc04c8d 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -24,6 +24,7 @@ install:
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||
$(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
|
||||
+ $(INSTALL_PROGRAM) -m 755 mpathcleanup $(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
|
||||
@@ -40,6 +41,7 @@ uninstall:
|
||||
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||
$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||
$(RM) $(DESTDIR)$(bindir)/mpathconf
|
||||
+ $(RM) $(DESTDIR)$(bindir)/mpathcleanup
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
$(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||
diff --git a/multipath/mpathcleanup b/multipath/mpathcleanup
|
||||
new file mode 100755
|
||||
index 00000000..6fd921e4
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathcleanup
|
||||
@@ -0,0 +1,145 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2023 Red Hat, Inc. All rights reserved.
|
||||
+#
|
||||
+# This file is part of the device-mapper-multipath package.
|
||||
+#
|
||||
+# This copyrighted material is made available to anyone wishing to use,
|
||||
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||
+# of the GNU General Public License v.2.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software Foundation,
|
||||
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+
|
||||
+unset PROGRAM FLUSH DEVICE DEVNAME MAJOR MINOR PATHDEVS PATHDEV HAVE_MULTIPATHD QUEUEING
|
||||
+
|
||||
+function usage
|
||||
+{
|
||||
+ echo "usage: $PROGRAM [-h] [--flush] <device>"
|
||||
+ echo ""
|
||||
+ echo "remove a multipath device and its scsi path devices"
|
||||
+ echo ""
|
||||
+ echo "options:"
|
||||
+ echo " -h, --help show this help message and exit"
|
||||
+ echo " --flush disable queuing on the multipath device and"
|
||||
+ echo " flush the path devices before removing"
|
||||
+}
|
||||
+
|
||||
+function parse_args
|
||||
+{
|
||||
+ while [ -n "$1" ]; do
|
||||
+ case $1 in
|
||||
+ --flush)
|
||||
+ FLUSH=1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --help | -h)
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+ *)
|
||||
+ if [ -n "$DEVICE" ]; then
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ DEVICE=$1
|
||||
+ shift
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function validate_device
|
||||
+{
|
||||
+ if [ -z "$DEVICE" ]; then
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [[ "$DEVICE" =~ ^[[:digit:]]+:[[:digit:]]+$ ]]; then
|
||||
+ MAJOR=${DEVICE%%:*}
|
||||
+ MINOR=${DEVICE##*:}
|
||||
+ DEVNAME=`dmsetup ls --target multipath | grep "($MAJOR, $MINOR)$" | awk '{print $1}'`
|
||||
+ else
|
||||
+ DEVNAME=`dmsetup ls --target multipath | awk '{print $1}' | grep "^$DEVICE$"`
|
||||
+ fi
|
||||
+ if [ -z "$DEVNAME" ]; then
|
||||
+ DEVNAME=`multipath -v 1 -l $DEVICE 2>/dev/null`
|
||||
+ if [ -z "$DEVNAME" ]; then
|
||||
+ echo "$DEVICE is not a multipath device"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ # verify that this is not a native nvme multipath device
|
||||
+ dmsetup ls --target multipath | awk '{print $1}' | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 1; then
|
||||
+ echo "$DEVICE is not a device-mapper multipath device"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ fi
|
||||
+ if [ -z "$MINOR" ]; then
|
||||
+ MINOR=`dmsetup info -c --noheadings -o minor $DEVNAME`
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+function get_paths
|
||||
+{
|
||||
+ PATHDEVS=`ls /sys/block/dm-$MINOR/slaves`
|
||||
+ for PATHDEV in $PATHDEVS; do
|
||||
+ if [[ ! "$PATHDEV" =~ ^sd[a-z]+$ ]]; then
|
||||
+ echo "$PATHDEV is not a scsi device. $PROGRAM only works with scsi devices"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function remove_devs
|
||||
+{
|
||||
+ pidof multipathd > /dev/null
|
||||
+ HAVE_MULTIPATHD=$?
|
||||
+ multipath -v2 -l "$DEVNAME" | grep features | grep -q queue_if_no_path
|
||||
+ QUEUEING=$?
|
||||
+ if [ -n "$FLUSH" ] && [ "$QUEUEING" -eq 0 ]; then
|
||||
+ if test $HAVE_MULTIPATHD -eq 0; then
|
||||
+ multipathd disablequeueing map "$DEVNAME" > /dev/null
|
||||
+ else
|
||||
+ dmsetup message "$DEVNAME" 0 fail_if_no_path
|
||||
+ fi
|
||||
+ sleep 1
|
||||
+ fi
|
||||
+ if test $HAVE_MULTIPATHD -eq 0; then
|
||||
+ multipath -f "$DEVNAME"
|
||||
+ else
|
||||
+ multipathd -Df "$DEVNAME"
|
||||
+ fi
|
||||
+ if test $? -eq 1; then
|
||||
+ echo "$DEVICE cannot be removed"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ for PATHDEV in $PATHDEVS; do
|
||||
+ if [ -n "$FLUSH" ]; then
|
||||
+ blockdev --flushbufs /dev/"$PATHDEV"
|
||||
+ fi
|
||||
+ echo 1 > /sys/block/"$PATHDEV"/device/delete
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+function verify_removal
|
||||
+{
|
||||
+ multipath -v 1 -d $DEVNAME | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 0; then
|
||||
+ echo "$DEVICE removed but path devices still exist"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ multipath -v 1 -l $DEVNAME | grep -q "^$DEVNAME$"
|
||||
+ if test $? -eq 0; then
|
||||
+ echo "$DEVICE removal succeeded, but device still exists"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+PROGRAM="$0"
|
||||
+parse_args "$@"
|
||||
+validate_device
|
||||
+get_paths
|
||||
+remove_devs
|
||||
+verify_removal
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 12 Jul 2023 12:56:48 -0500
|
||||
Subject: [PATCH] RH: make listing return an error if the config file is
|
||||
missing
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index e056c51c..f1077421 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -874,11 +874,14 @@ main (int argc, char *argv[])
|
||||
struct config *conf;
|
||||
int retries = -1;
|
||||
bool enable_foreign = false;
|
||||
+ bool have_config;
|
||||
+ struct stat buf;
|
||||
|
||||
libmultipath_init();
|
||||
if (atexit(dm_lib_exit) || atexit(libmultipath_exit))
|
||||
condlog(1, "failed to register cleanup handler for libmultipath: %m");
|
||||
logsink = LOGSINK_STDERR_WITH_TIME;
|
||||
+ have_config = (stat(DEFAULT_CONFIGFILE, &buf) == 0);
|
||||
if (init_config(DEFAULT_CONFIGFILE))
|
||||
exit(RTVL_FAIL);
|
||||
if (atexit(uninit_config))
|
||||
@@ -1129,6 +1132,9 @@ main (int argc, char *argv[])
|
||||
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||
condlog(3, "restart multipath configuration process");
|
||||
|
||||
+ if (!have_config && r == RTVL_OK &&
|
||||
+ (cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG))
|
||||
+ r = RTVL_FAIL;
|
||||
out:
|
||||
put_multipath_config(conf);
|
||||
if (dev)
|
|
@ -1,31 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 26 Oct 2023 13:24:34 -0400
|
||||
Subject: [PATCH] multipath-tools: add HPE Alletra 9000 NVMe to hardware table
|
||||
|
||||
Add config to match configuration in 0.9.6 release
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index 22ff1881..78ac7988 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -119,6 +119,14 @@ static struct hwentry default_hw[] = {
|
||||
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||
.vpd_vendor_id = VPD_VP_HP3PAR,
|
||||
},
|
||||
+ {
|
||||
+ /* Alletra 9000 NVMe */
|
||||
+ .vendor = "NVME",
|
||||
+ .product = "HPE Alletra",
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .no_path_retry = NO_PATH_RETRY_QUEUE,
|
||||
+ },
|
||||
{
|
||||
/* RA8000 / ESA12000 */
|
||||
.vendor = "DEC",
|
|
@ -1,70 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 3 Nov 2023 11:13:04 -0400
|
||||
Subject: [PATCH] RH: multipath: add mpathcleanup man page
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/Makefile | 3 +++
|
||||
multipath/mpathcleanup.8 | 24 ++++++++++++++++++++++++
|
||||
2 files changed, 27 insertions(+)
|
||||
create mode 100644 multipath/mpathcleanup.8
|
||||
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 1fc04c8d..cdfa160b 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -19,6 +19,7 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
||||
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
||||
$(GZIP) mpathconf.8 > mpathconf.8.gz
|
||||
+ $(GZIP) mpathcleanup.8 > mpathcleanup.8.gz
|
||||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||
@@ -35,6 +36,7 @@ install:
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
||||
$(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir)
|
||||
+ $(INSTALL_PROGRAM) -m 644 mpathcleanup.8.gz $(DESTDIR)$(man8dir)
|
||||
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||
@@ -45,6 +47,7 @@ uninstall:
|
||||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
$(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||
+ $(RM) $(DESTDIR)$(man8dir)/mpathcleanup.8.gz
|
||||
|
||||
clean: dep_clean
|
||||
$(RM) core *.o $(EXEC) *.gz multipath.rules tmpfiles.conf
|
||||
diff --git a/multipath/mpathcleanup.8 b/multipath/mpathcleanup.8
|
||||
new file mode 100644
|
||||
index 00000000..184c35c9
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathcleanup.8
|
||||
@@ -0,0 +1,24 @@
|
||||
+.TH MPATHCLEANUP 8 "November 2023" "" "Linux Administrator's Manual"
|
||||
+.SH NAME
|
||||
+mpathcleanup - A tool to remove a multipath device and its scsi path devices
|
||||
+.SH SYNOPSIS
|
||||
+.B mpathcleanup
|
||||
+[\fB\-h\fR] [\fB\-\-flush\fR] \fBdevice\fR
|
||||
+.SH DESCRIPTION
|
||||
+\fBmpathcleanup\fR is a utility that attempts to remove a multipath device and
|
||||
+its underlying paths. It only works for multipath devices built on top of scsi
|
||||
+devices.
|
||||
+.SH OPTIONS
|
||||
+.TP
|
||||
+.B \-\-flush
|
||||
+Disable queueing on the multipath device and flush the path devices before
|
||||
+removing.
|
||||
+.TP
|
||||
+\fB\-h\fR|\fB\-\-help\fR
|
||||
+Display help text.
|
||||
+.SH "SEE ALSO"
|
||||
+.BR multipath.conf (5),
|
||||
+.BR multipath (8),
|
||||
+.BR multipathd (8)
|
||||
+.SH AUTHOR
|
||||
+Benjamin Marzinski <bmarzins@redhat.com>
|
|
@ -1,182 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Nov 2023 18:46:11 -0500
|
||||
Subject: [PATCH] libmultipath: Add max_retries config option
|
||||
|
||||
This option lets multipath set a scsi disk's max_retries sysfs value.
|
||||
Setting this can be helpful for cases where the path checker succeeds,
|
||||
but IO commands hang and timeout. By default, the SCSI layer will retry
|
||||
IOs 5 times. Reducing this value will allow multipath to retry the IO
|
||||
down another path sooner.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
libmultipath/config.h | 1 +
|
||||
libmultipath/dict.c | 25 ++++++++++++++++++++++++
|
||||
libmultipath/discovery.c | 40 +++++++++++++++++++++++++++++++++++++-
|
||||
libmultipath/structs.h | 6 ++++++
|
||||
multipath/multipath.conf.5 | 14 +++++++++++++
|
||||
5 files changed, 85 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index c1e18363..b0ee8241 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -162,6 +162,7 @@ struct config {
|
||||
int fast_io_fail;
|
||||
unsigned int dev_loss;
|
||||
int eh_deadline;
|
||||
+ int max_retries;
|
||||
int log_checker_err;
|
||||
int allow_queueing;
|
||||
int allow_usb_devices;
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index eb2f33a2..0c66c1e1 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -1206,6 +1206,30 @@ declare_hw_snprint(eh_deadline, print_undef_off_zero)
|
||||
declare_pc_handler(eh_deadline, set_undef_off_zero)
|
||||
declare_pc_snprint(eh_deadline, print_undef_off_zero)
|
||||
|
||||
+static int
|
||||
+def_max_retries_handler(struct config *conf, vector strvec, const char *file,
|
||||
+ int line_nr)
|
||||
+{
|
||||
+ char * buff;
|
||||
+
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (strcmp(buff, "off") == 0)
|
||||
+ conf->max_retries = MAX_RETRIES_OFF;
|
||||
+ else if (strcmp(buff, "0") == 0)
|
||||
+ conf->max_retries = MAX_RETRIES_ZERO;
|
||||
+ else
|
||||
+ do_set_int(strvec, &conf->max_retries, 1, 5, file, line_nr,
|
||||
+ buff);
|
||||
+
|
||||
+ free(buff);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+declare_def_snprint(max_retries, print_undef_off_zero)
|
||||
+
|
||||
static int
|
||||
set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr)
|
||||
{
|
||||
@@ -2143,6 +2167,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
|
||||
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
|
||||
install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline);
|
||||
+ install_keyword("max_retries", &def_max_retries_handler, &snprint_def_max_retries);
|
||||
install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file);
|
||||
install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file);
|
||||
install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index a592a54e..adf8bbaa 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -632,6 +632,42 @@ sysfs_set_eh_deadline(struct path *pp)
|
||||
return (ret <= 0);
|
||||
}
|
||||
|
||||
+static int
|
||||
+sysfs_set_max_retries(struct config *conf, struct path *pp)
|
||||
+{
|
||||
+ struct udev_device *parent;
|
||||
+ char value[16];
|
||||
+ STRBUF_ON_STACK(buf);
|
||||
+ int ret, len;
|
||||
+
|
||||
+ if (conf->max_retries == MAX_RETRIES_UNSET)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!pp->udev || pp->sg_id.host_no < 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ len = sprintf(value, "%d", (conf->max_retries == MAX_RETRIES_OFF)? -1 :
|
||||
+ (conf->max_retries == MAX_RETRIES_ZERO)? 0 :
|
||||
+ conf->max_retries);
|
||||
+
|
||||
+ parent = udev_device_get_parent_with_subsystem_devtype(pp->udev,
|
||||
+ "scsi", "scsi_device");
|
||||
+ if (!parent)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (print_strbuf(&buf, "scsi_disk/%i:%i:%i:%" PRIu64 "/max_retries",
|
||||
+ pp->sg_id.host_no, pp->sg_id.channel,
|
||||
+ pp->sg_id.scsi_id, pp->sg_id.lun) < 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ ret = sysfs_attr_set_value(parent, get_strbuf_str(&buf), value, len);
|
||||
+ if (len != ret)
|
||||
+ condlog(3, "%s/%s: failed to set value to %s: %s",
|
||||
+ udev_device_get_sysname(parent), get_strbuf_str(&buf),
|
||||
+ value, (ret < 0)? strerror(-ret) : "write underflow");
|
||||
+ return (len != ret);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
|
||||
{
|
||||
@@ -862,13 +898,15 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
|
||||
|
||||
if (pp->dev_loss == DEV_LOSS_TMO_UNSET &&
|
||||
pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET &&
|
||||
- pp->eh_deadline == EH_DEADLINE_UNSET)
|
||||
+ pp->eh_deadline == EH_DEADLINE_UNSET &&
|
||||
+ conf->max_retries == MAX_RETRIES_UNSET)
|
||||
continue;
|
||||
|
||||
if (pp->bus != SYSFS_BUS_SCSI)
|
||||
continue;
|
||||
|
||||
sysfs_set_eh_deadline(pp);
|
||||
+ sysfs_set_max_retries(conf, pp);
|
||||
|
||||
if (pp->dev_loss == DEV_LOSS_TMO_UNSET &&
|
||||
pp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index c1e93e6e..b4252ab5 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -276,6 +276,12 @@ enum eh_deadline_states {
|
||||
EH_DEADLINE_ZERO = UOZ_ZERO,
|
||||
};
|
||||
|
||||
+enum max_retries_states {
|
||||
+ MAX_RETRIES_UNSET = UOZ_UNDEF,
|
||||
+ MAX_RETRIES_OFF = UOZ_OFF,
|
||||
+ MAX_RETRIES_ZERO = UOZ_ZERO,
|
||||
+};
|
||||
+
|
||||
enum recheck_wwid_states {
|
||||
RECHECK_WWID_UNDEF = YNU_UNDEF,
|
||||
RECHECK_WWID_OFF = YNU_NO,
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 5e447e67..789f0bfc 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -743,6 +743,20 @@ The default is: \fB<unset>\fR
|
||||
.
|
||||
.
|
||||
.TP
|
||||
+.B max_retries
|
||||
+Specify the maximum number of times the SCSI layer will retry IO commands for
|
||||
+some types of SCSI errors before returning failure. Setting this can be helpful
|
||||
+for cases where IO commands hang and timeout. By default, the SCSI layer will
|
||||
+retry IOs 5 times. Reducing this value will allow multipath to retry the IO
|
||||
+down another path sooner. Valid values are
|
||||
+\fB0\fR through \fB5\fR.
|
||||
+.RS
|
||||
+.TP
|
||||
+The default is: \fB<unset>\fR
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
+.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
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Nov 2023 18:46:12 -0500
|
||||
Subject: [PATCH] libmutipath: Retain device size if sysfs_get_size fails.
|
||||
|
||||
When paths are allocated their size is initialized to 0. If they've
|
||||
already set a size, and a future call to sysfs_get_size() fails during
|
||||
the parsing, assume that the size hasn't changed, instead of setting it
|
||||
to 0. All other failures in sysfs_get_size() already retain the existing
|
||||
size.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/sysfs.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
|
||||
index 24c12b6a..41354f91 100644
|
||||
--- a/libmultipath/sysfs.c
|
||||
+++ b/libmultipath/sysfs.c
|
||||
@@ -229,7 +229,6 @@ sysfs_get_size (struct path *pp, unsigned long long * size)
|
||||
|
||||
if (r != 1) {
|
||||
condlog(3, "%s: Cannot parse size attribute", pp->dev);
|
||||
- *size = 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Nov 2023 18:46:13 -0500
|
||||
Subject: [PATCH] multipathd: check and update all paths when in cli_resize
|
||||
|
||||
When resizing a multipath device, make sure that all the paths have
|
||||
been updated to the new size first.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 31 ++++++++++++++++++-------------
|
||||
1 file changed, 18 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index f322f10f..93c32c5b 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -866,9 +866,11 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||
char * mapname = get_keyparam(v, MAP);
|
||||
struct multipath *mpp;
|
||||
int minor;
|
||||
- unsigned long long size;
|
||||
+ unsigned long long size = 0;
|
||||
struct pathgroup *pgp;
|
||||
struct path *pp;
|
||||
+ unsigned int i, j;
|
||||
+ bool mismatch = false;
|
||||
|
||||
mapname = convert_dev(mapname, 0);
|
||||
condlog(2, "%s: resize map (operator)", mapname);
|
||||
@@ -888,21 +890,24 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- pgp = VECTOR_SLOT(mpp->pg, 0);
|
||||
-
|
||||
- if (!pgp){
|
||||
- condlog(0, "%s: couldn't get path group. cannot resize",
|
||||
- mapname);
|
||||
- return 1;
|
||||
+ vector_foreach_slot(mpp->pg, pgp, i) {
|
||||
+ vector_foreach_slot (pgp->paths, pp, j) {
|
||||
+ sysfs_get_size(pp, &pp->size);
|
||||
+ if (!pp->size)
|
||||
+ continue;
|
||||
+ if (!size)
|
||||
+ size = pp->size;
|
||||
+ else if (pp->size != size)
|
||||
+ mismatch = true;
|
||||
+ }
|
||||
}
|
||||
- pp = VECTOR_SLOT(pgp->paths, 0);
|
||||
-
|
||||
- if (!pp){
|
||||
- condlog(0, "%s: couldn't get path. cannot resize", mapname);
|
||||
+ if (!size) {
|
||||
+ condlog(0, "%s: couldn't get size from sysfs. cannot resize",
|
||||
+ mapname);
|
||||
return 1;
|
||||
}
|
||||
- if (!pp->udev || sysfs_get_size(pp, &size)) {
|
||||
- condlog(0, "%s: couldn't get size for sysfs. cannot resize",
|
||||
+ if (mismatch) {
|
||||
+ condlog(0, "%s: path size not consistent. cannot resize",
|
||||
mapname);
|
||||
return 1;
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Nov 2023 18:46:14 -0500
|
||||
Subject: [PATCH] multipathd: move post-reloading commands into resize_map()
|
||||
|
||||
In preparation for reusing resize_map() in other code, move all code
|
||||
necessary to resize the map to the resize_map() function. Also track if
|
||||
map was removed in the function.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 93c32c5b..b08b248f 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -856,6 +856,10 @@ int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
mpp->size = orig_size;
|
||||
return 1;
|
||||
}
|
||||
+ if (setup_multipath(vecs, mpp) != 0)
|
||||
+ return 2;
|
||||
+ sync_map_state(mpp);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -869,7 +873,7 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||
unsigned long long size = 0;
|
||||
struct pathgroup *pgp;
|
||||
struct path *pp;
|
||||
- unsigned int i, j;
|
||||
+ unsigned int i, j, ret;
|
||||
bool mismatch = false;
|
||||
|
||||
mapname = convert_dev(mapname, 0);
|
||||
@@ -919,14 +923,12 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||
condlog(3, "%s old size is %llu, new size is %llu", mapname, mpp->size,
|
||||
size);
|
||||
|
||||
- if (resize_map(mpp, size, vecs) != 0)
|
||||
- return 1;
|
||||
+ ret = resize_map(mpp, size, vecs);
|
||||
|
||||
- if (setup_multipath(vecs, mpp) != 0)
|
||||
- return 1;
|
||||
- sync_map_state(mpp);
|
||||
+ if (ret == 2)
|
||||
+ condlog(0, "%s: map removed while trying to resize", mapname);
|
||||
|
||||
- return 0;
|
||||
+ return (ret != 0);
|
||||
}
|
||||
|
||||
int
|
|
@ -1,106 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 10 Nov 2023 17:59:42 -0500
|
||||
Subject: [PATCH] multipathd: move resize_map() to multipathd/main.c
|
||||
|
||||
No functional changes.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 29 -----------------------------
|
||||
multipathd/main.c | 29 +++++++++++++++++++++++++++++
|
||||
multipathd/main.h | 2 ++
|
||||
3 files changed, 31 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index b08b248f..53bebc8d 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -834,35 +834,6 @@ cli_reload(void *v, char **reply, int *len, void *data)
|
||||
return reload_and_sync_map(mpp, vecs, 0);
|
||||
}
|
||||
|
||||
-int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
- struct vectors * vecs)
|
||||
-{
|
||||
- char *params __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
- unsigned long long orig_size = mpp->size;
|
||||
-
|
||||
- mpp->size = size;
|
||||
- update_mpp_paths(mpp, vecs->pathvec);
|
||||
- if (setup_map(mpp, ¶ms, vecs) != 0) {
|
||||
- condlog(0, "%s: failed to setup map for resize : %s",
|
||||
- mpp->alias, strerror(errno));
|
||||
- mpp->size = orig_size;
|
||||
- return 1;
|
||||
- }
|
||||
- mpp->action = ACT_RESIZE;
|
||||
- mpp->force_udev_reload = 1;
|
||||
- if (domap(mpp, params, 1) == DOMAP_FAIL) {
|
||||
- condlog(0, "%s: failed to resize map : %s", mpp->alias,
|
||||
- strerror(errno));
|
||||
- mpp->size = orig_size;
|
||||
- return 1;
|
||||
- }
|
||||
- if (setup_multipath(vecs, mpp) != 0)
|
||||
- return 2;
|
||||
- sync_map_state(mpp);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int
|
||||
cli_resize(void *v, char **reply, int *len, void *data)
|
||||
{
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 075e7b13..d99cad72 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1379,6 +1379,35 @@ needs_ro_update(struct multipath *mpp, int ro)
|
||||
return true;
|
||||
}
|
||||
|
||||
+int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
+ struct vectors * vecs)
|
||||
+{
|
||||
+ char *params __attribute__((cleanup(cleanup_charp))) = NULL;
|
||||
+ unsigned long long orig_size = mpp->size;
|
||||
+
|
||||
+ mpp->size = size;
|
||||
+ update_mpp_paths(mpp, vecs->pathvec);
|
||||
+ if (setup_map(mpp, ¶ms, vecs) != 0) {
|
||||
+ condlog(0, "%s: failed to setup map for resize : %s",
|
||||
+ mpp->alias, strerror(errno));
|
||||
+ mpp->size = orig_size;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ mpp->action = ACT_RESIZE;
|
||||
+ mpp->force_udev_reload = 1;
|
||||
+ if (domap(mpp, params, 1) == DOMAP_FAIL) {
|
||||
+ condlog(0, "%s: failed to resize map : %s", mpp->alias,
|
||||
+ strerror(errno));
|
||||
+ mpp->size = orig_size;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (setup_multipath(vecs, mpp) != 0)
|
||||
+ return 2;
|
||||
+ sync_map_state(mpp);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
{
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index bc1f938f..dbae4935 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -66,4 +66,6 @@ int reload_and_sync_map(struct multipath *mpp, struct vectors *vecs,
|
||||
|
||||
void handle_path_wwid_change(struct path *pp, struct vectors *vecs);
|
||||
bool check_path_wwid_change(struct path *pp);
|
||||
+int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
+ struct vectors *vecs);
|
||||
#endif /* MAIN_H */
|
|
@ -1,202 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Nov 2023 18:46:16 -0500
|
||||
Subject: [PATCH] multipathd: Add auto_resize config option
|
||||
|
||||
This option gives multipathd the ability to automatically resize a
|
||||
device when it detects that all of the path devices have changed. By
|
||||
default it is set to never, and multipathd will continue to work like it
|
||||
always has, where a users must manually resize a multipath device.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
libmultipath/config.h | 1 +
|
||||
libmultipath/defaults.h | 1 +
|
||||
libmultipath/dict.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
libmultipath/dict.h | 1 +
|
||||
libmultipath/structs.h | 7 +++++++
|
||||
multipath/multipath.conf.5 | 15 +++++++++++++++
|
||||
multipathd/main.c | 28 ++++++++++++++++++++++++++++
|
||||
7 files changed, 91 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index b0ee8241..5807ac68 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -201,6 +201,7 @@ struct config {
|
||||
int skip_delegate;
|
||||
unsigned int sequence_nr;
|
||||
int recheck_wwid;
|
||||
+ int auto_resize;
|
||||
|
||||
char * multipath_dir;
|
||||
char * selector;
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index cec82f07..c3788bbc 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -54,6 +54,7 @@
|
||||
#define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1
|
||||
#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF
|
||||
#define DEFAULT_RECHECK_WWID RECHECK_WWID_OFF
|
||||
+#define DEFAULT_AUTO_RESIZE AUTO_RESIZE_NEVER
|
||||
/* Enable no foreign libraries by default */
|
||||
#define DEFAULT_ENABLE_FOREIGN "NONE"
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 0c66c1e1..c4db60df 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -1736,6 +1736,43 @@ declare_hw_snprint(recheck_wwid, print_yes_no_undef)
|
||||
|
||||
declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX)
|
||||
|
||||
+static int
|
||||
+def_auto_resize_handler(struct config *conf, vector strvec, const char *file,
|
||||
+ int line_nr)
|
||||
+{
|
||||
+ char * buff;
|
||||
+
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (strcmp(buff, "never") == 0)
|
||||
+ conf->auto_resize = AUTO_RESIZE_NEVER;
|
||||
+ else if (strcmp(buff, "grow_only") == 0)
|
||||
+ conf->auto_resize = AUTO_RESIZE_GROW_ONLY;
|
||||
+ else if (strcmp(buff, "grow_shrink") == 0)
|
||||
+ conf->auto_resize = AUTO_RESIZE_GROW_SHRINK;
|
||||
+ else
|
||||
+ condlog(1, "%s line %d, invalid value for auto_resize: \"%s\"",
|
||||
+ file, line_nr, buff);
|
||||
+
|
||||
+ free(buff);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+print_auto_resize(struct strbuf *buff, long v)
|
||||
+{
|
||||
+ if (!v)
|
||||
+ return 0;
|
||||
+ return append_strbuf_quoted(buff,
|
||||
+ v == AUTO_RESIZE_GROW_ONLY ? "grow_only" :
|
||||
+ v == AUTO_RESIZE_GROW_SHRINK ? "grow_shrink" :
|
||||
+ "never");
|
||||
+}
|
||||
+
|
||||
+declare_def_snprint(auto_resize, print_auto_resize)
|
||||
+
|
||||
static int
|
||||
hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file,
|
||||
int line_nr)
|
||||
@@ -2202,6 +2239,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
|
||||
install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb);
|
||||
install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay);
|
||||
+ install_keyword("auto_resize", &def_auto_resize_handler, &snprint_def_auto_resize);
|
||||
install_keyword("find_multipaths_timeout",
|
||||
&def_find_multipaths_timeout_handler,
|
||||
&snprint_def_find_multipaths_timeout);
|
||||
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
|
||||
index d80f990a..d963b4ad 100644
|
||||
--- a/libmultipath/dict.h
|
||||
+++ b/libmultipath/dict.h
|
||||
@@ -19,4 +19,5 @@ int print_dev_loss(struct strbuf *buff, unsigned long v);
|
||||
int print_reservation_key(struct strbuf *buff,
|
||||
struct be64 key, uint8_t flags, int source);
|
||||
int print_off_int_undef(struct strbuf *buff, long v);
|
||||
+int print_auto_resize(struct strbuf *buff, long v);
|
||||
#endif /* _DICT_H */
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index b4252ab5..8c2d7131 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -167,6 +167,13 @@ enum queue_mode_states {
|
||||
QUEUE_MODE_RQ,
|
||||
};
|
||||
|
||||
+enum auto_resize_state {
|
||||
+ AUTO_RESIZE_UNDEF = 0,
|
||||
+ AUTO_RESIZE_NEVER,
|
||||
+ AUTO_RESIZE_GROW_ONLY,
|
||||
+ AUTO_RESIZE_GROW_SHRINK,
|
||||
+};
|
||||
+
|
||||
#define PROTOCOL_UNSET -1
|
||||
|
||||
enum scsi_protocol {
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 789f0bfc..38eb5c90 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1293,6 +1293,21 @@ The default is: \fBno\fR
|
||||
.
|
||||
.
|
||||
.TP
|
||||
+.B auto_resize
|
||||
+Controls when multipathd will automatically resize a multipath device. If set
|
||||
+to \fInever\fR, multipath devices must always be manually resized by either
|
||||
+running \fBmultipathd resize map <name>\fR. If set to \fIgrow_only\fR, when
|
||||
+multipathd detects that all of a multipath device's paths have increased in
|
||||
+size, it will automatically grow the multipath device to the new size. If set
|
||||
+to \fIgrow_shrink\fR, multipathd will also automatically shrink the device
|
||||
+once it detects all of its paths have decreased in size.
|
||||
+.RS
|
||||
+.TP
|
||||
+The default is: \fBnever\fR
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
+.TP
|
||||
.B enable_foreign
|
||||
Enables or disables foreign libraries (see section
|
||||
.I FOREIGN MULTIPATH SUPPORT
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index d99cad72..6d1a5e4e 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1439,6 +1439,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
if (pp) {
|
||||
struct multipath *mpp = pp->mpp;
|
||||
char wwid[WWID_SIZE];
|
||||
+ int auto_resize;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ auto_resize = conf->auto_resize;
|
||||
+ put_multipath_config(conf);
|
||||
|
||||
if (pp->initialized == INIT_REQUESTED_UDEV) {
|
||||
needs_reinit = 1;
|
||||
@@ -1489,6 +1494,29 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (auto_resize != AUTO_RESIZE_NEVER &&
|
||||
+ !mpp->wait_for_udev) {
|
||||
+ struct pathgroup *pgp;
|
||||
+ struct path *pp2;
|
||||
+ unsigned int i, j;
|
||||
+ unsigned long long orig_size = mpp->size;
|
||||
+
|
||||
+ if (!pp->size || pp->size == mpp->size ||
|
||||
+ (pp->size < mpp->size &&
|
||||
+ auto_resize == AUTO_RESIZE_GROW_ONLY))
|
||||
+ goto out;
|
||||
+
|
||||
+ vector_foreach_slot(mpp->pg, pgp, i)
|
||||
+ vector_foreach_slot (pgp->paths, pp2, j)
|
||||
+ if (pp2->size && pp2->size != pp->size)
|
||||
+ goto out;
|
||||
+ retval = resize_map(mpp, pp->size, vecs);
|
||||
+ if (retval == 2)
|
||||
+ condlog(2, "%s: map removed during resize", pp->dev);
|
||||
+ else if (retval == 0)
|
||||
+ condlog(2, "%s: resized map from %llu to %llu",
|
||||
+ mpp->alias, orig_size, pp->size);
|
||||
+ }
|
||||
}
|
||||
out:
|
||||
lock_cleanup_pop(vecs->lock);
|
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Dec 2023 16:30:42 -0500
|
||||
Subject: [PATCH] libmultipath: avoid temporarily enabling queueing on reload
|
||||
|
||||
Instead of always enabling queueing when a map is reloaded with
|
||||
no_path_retry set to a positive number, check if the map has timed out
|
||||
in recovery mode, and only enable queueing if it has not. This saves
|
||||
multipathd from having to disable queueing on the map immediately after
|
||||
the reload.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dmparser.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
|
||||
index 16377c54..1ea2d619 100644
|
||||
--- a/libmultipath/dmparser.c
|
||||
+++ b/libmultipath/dmparser.c
|
||||
@@ -61,9 +61,19 @@ int assemble_map(struct multipath *mp, char **params)
|
||||
nr_priority_groups = VECTOR_SIZE(mp->pg);
|
||||
initial_pg_nr = (nr_priority_groups ? mp->bestpg : 0);
|
||||
|
||||
- if (mp->no_path_retry != NO_PATH_RETRY_UNDEF &&
|
||||
- mp->no_path_retry != NO_PATH_RETRY_FAIL) {
|
||||
+ switch (mp->no_path_retry) {
|
||||
+ case NO_PATH_RETRY_UNDEF:
|
||||
+ case NO_PATH_RETRY_FAIL:
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* don't enable queueing if no_path_retry has timed out */
|
||||
+ if (mp->in_recovery && mp->retry_tick == 0 &&
|
||||
+ count_active_paths(mp) == 0)
|
||||
+ break;
|
||||
+ /* fallthrough */
|
||||
+ case NO_PATH_RETRY_QUEUE:
|
||||
add_feature(&mp->features, no_path_retry);
|
||||
+ break;
|
||||
}
|
||||
if (mp->retain_hwhandler == RETAIN_HWHANDLER_ON &&
|
||||
get_linux_version_code() < KERNEL_VERSION(4, 3, 0))
|
|
@ -1,131 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 17:22:02 -0500
|
||||
Subject: [PATCH] multipathd: remove nopath flushing code from flush_map()
|
||||
|
||||
Instead of flush_map() handling both user requested flushes and
|
||||
automatic flushes when the last path has been deleted, make
|
||||
flush_map_nopaths() handle the automatic flushes itself, since a later
|
||||
patch will change the behavior of flush_map().
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 2 +-
|
||||
multipathd/main.c | 45 +++++++++++++++++----------------------
|
||||
multipathd/main.h | 2 +-
|
||||
3 files changed, 21 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 53bebc8d..f04fb558 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -796,7 +796,7 @@ cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||
|
||||
condlog(2, "remove maps (operator)");
|
||||
vector_foreach_slot(vecs->mpvec, mpp, i) {
|
||||
- if (flush_map(mpp, vecs, 0))
|
||||
+ if (flush_map(mpp, vecs))
|
||||
ret++;
|
||||
else
|
||||
i--;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 6d1a5e4e..1b5f82e7 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -490,12 +490,11 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)
|
||||
|
||||
static bool
|
||||
flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||
- char alias[WWID_SIZE];
|
||||
+ int r;
|
||||
|
||||
/*
|
||||
* flush_map will fail if the device is open
|
||||
*/
|
||||
- strlcpy(alias, mpp->alias, WWID_SIZE);
|
||||
if (mpp->flush_on_last_del == FLUSH_ENABLED) {
|
||||
condlog(2, "%s Last path deleted, disabling queueing",
|
||||
mpp->alias);
|
||||
@@ -505,11 +504,20 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||
mpp->stat_map_failures++;
|
||||
dm_queue_if_no_path(mpp->alias, 0);
|
||||
}
|
||||
- if (!flush_map(mpp, vecs, 1)) {
|
||||
- condlog(2, "%s: removed map after removing all paths", alias);
|
||||
- return true;
|
||||
+ r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||
+ if (r) {
|
||||
+ if (r == 1)
|
||||
+ condlog(0, "%s: can't flush", mpp->alias);
|
||||
+ else {
|
||||
+ condlog(2, "%s: devmap deferred remove", mpp->alias);
|
||||
+ mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
|
||||
+ }
|
||||
+ return false;
|
||||
}
|
||||
- return false;
|
||||
+
|
||||
+ condlog(2, "%s: map flushed after removing all paths", mpp->alias);
|
||||
+ remove_map_and_stop_waiter(mpp, vecs);
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -685,30 +693,15 @@ sync_maps_state(vector mpvec)
|
||||
}
|
||||
|
||||
int
|
||||
-flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||
+flush_map(struct multipath * mpp, struct vectors * vecs)
|
||||
{
|
||||
- int r;
|
||||
-
|
||||
- if (nopaths)
|
||||
- r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||
- else
|
||||
- r = dm_flush_map(mpp->alias);
|
||||
- /*
|
||||
- * clear references to this map before flushing so we can ignore
|
||||
- * the spurious uevent we may generate with the dm_flush_map call below
|
||||
- */
|
||||
+ int r = dm_flush_map(mpp->alias);
|
||||
if (r) {
|
||||
- if (r == 1)
|
||||
- condlog(0, "%s: can't flush", mpp->alias);
|
||||
- else {
|
||||
- condlog(2, "%s: devmap deferred remove", mpp->alias);
|
||||
- mpp->deferred_remove = DEFERRED_REMOVE_IN_PROGRESS;
|
||||
- }
|
||||
+ condlog(0, "%s: can't flush", mpp->alias);
|
||||
return r;
|
||||
}
|
||||
- else
|
||||
- condlog(2, "%s: map flushed", mpp->alias);
|
||||
|
||||
+ condlog(2, "%s: map flushed", mpp->alias);
|
||||
remove_map_and_stop_waiter(mpp, vecs);
|
||||
|
||||
return 0;
|
||||
@@ -866,7 +859,7 @@ ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
|
||||
mpp->alias, mpp->dmi->minor, minor);
|
||||
return 1;
|
||||
}
|
||||
- return flush_map(mpp, vecs, 0);
|
||||
+ return flush_map(mpp, vecs);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index dbae4935..4138faa4 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -43,7 +43,7 @@ int ev_add_path (struct path *, struct vectors *, int);
|
||||
int ev_remove_path (struct path *, struct vectors *, int);
|
||||
int ev_add_map (char *, const char *, struct vectors *);
|
||||
int ev_remove_map (char *, char *, int, struct vectors *);
|
||||
-int flush_map(struct multipath *, struct vectors *, int);
|
||||
+int flush_map(struct multipath *, struct vectors *);
|
||||
int set_config_state(enum daemon_status);
|
||||
void * mpath_alloc_prin_response(int prin_sa);
|
||||
int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp,
|
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 7 Dec 2023 11:23:18 -0500
|
||||
Subject: [PATCH] multipathd: make flush_map() delete maps like the multipath
|
||||
command
|
||||
|
||||
When the multipath command tries to delete a multipath device, it first
|
||||
disables queueing and then suspends the device to force the IOs to get
|
||||
flushed. Then it attempts to delete the device and any kpartx
|
||||
partitions. multipathd, on the other hand, simply tries to delete the
|
||||
device and kpartx partitions, without disabling queueing or suspending.
|
||||
If there are no paths but there is outstanding IO, multipathd will hang
|
||||
trying to delete the last kpartx device. This is because it must be the
|
||||
last opener of the multipath device (multipath won't try to delete the
|
||||
device if it has any openers besides the kpartx devices) and the kernel
|
||||
will not allow the last opener of a block device to close until all the
|
||||
outstanding IO is flushed. This hang can be avoided if multipathd calls
|
||||
dm_suspend_and_flush_map() like the multipath command does, instead of
|
||||
dm_flush_map().
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 1b5f82e7..3eeca82f 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -695,7 +695,7 @@ sync_maps_state(vector mpvec)
|
||||
int
|
||||
flush_map(struct multipath * mpp, struct vectors * vecs)
|
||||
{
|
||||
- int r = dm_flush_map(mpp->alias);
|
||||
+ int r = dm_suspend_and_flush_map(mpp->alias, 0);
|
||||
if (r) {
|
||||
condlog(0, "%s: can't flush", mpp->alias);
|
||||
return r;
|
|
@ -1,83 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 8 Dec 2023 14:50:31 -0500
|
||||
Subject: [PATCH] multipathd: disable queueing when removing unknown maps
|
||||
|
||||
Make cli_del_maps() call dm_suspend_and_flush_map() for the unknown
|
||||
multipath devices as well.
|
||||
|
||||
After this change, all callers of cli_del_maps() set need_suspend, so
|
||||
simplify dm_flush_maps().
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 7 ++-----
|
||||
libmultipath/devmapper.h | 2 +-
|
||||
multipath/main.c | 2 +-
|
||||
multipathd/cli_handlers.c | 2 +-
|
||||
4 files changed, 5 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 4b2e8a15..f9de3358 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -1145,7 +1145,7 @@ dm_flush_map_nopaths(const char * mapname,
|
||||
|
||||
#endif
|
||||
|
||||
-int dm_flush_maps (int need_suspend, int retries)
|
||||
+int dm_flush_maps (int retries)
|
||||
{
|
||||
int r = 1;
|
||||
struct dm_task *dmt;
|
||||
@@ -1170,10 +1170,7 @@ int dm_flush_maps (int need_suspend, int retries)
|
||||
goto out;
|
||||
|
||||
do {
|
||||
- if (need_suspend)
|
||||
- r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
- else
|
||||
- r |= dm_flush_map(names->name);
|
||||
+ r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
next = names->next;
|
||||
names = (void *) names + next;
|
||||
} while (next);
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 45a676de..808da28d 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -55,7 +55,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||
#define dm_suspend_and_flush_map(mapname, retries) \
|
||||
_dm_flush_map(mapname, 1, 0, 1, retries)
|
||||
int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||
-int dm_flush_maps (int need_suspend, int retries);
|
||||
+int dm_flush_maps (int retries);
|
||||
int dm_fail_path(const char * mapname, char * path);
|
||||
int dm_reinstate_path(const char * mapname, char * path);
|
||||
int dm_queue_if_no_path(const char *mapname, int enable);
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index f1077421..e296be6e 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -1126,7 +1126,7 @@ main (int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
else if (cmd == CMD_FLUSH_ALL) {
|
||||
- r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||
+ r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index f04fb558..aca8e2df 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -802,7 +802,7 @@ cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||
i--;
|
||||
}
|
||||
/* flush any multipath maps that aren't currently known by multipathd */
|
||||
- ret |= dm_flush_maps(0, 0);
|
||||
+ ret |= dm_flush_maps(0);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 20:19:11 -0500
|
||||
Subject: [PATCH] multipathd: fix null pointer dereference in uev_update_path
|
||||
|
||||
The Auto-resize code added a check that deferences pp->mpp without
|
||||
checking that it's non-NULL. Fix it.
|
||||
|
||||
Fixes: 981b83ad1 ("multipathd: Add auto_resize config option")
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
multipathd/main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 3eeca82f..26be6dc3 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1487,7 +1487,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (auto_resize != AUTO_RESIZE_NEVER &&
|
||||
+ if (auto_resize != AUTO_RESIZE_NEVER && mpp &&
|
||||
!mpp->wait_for_udev) {
|
||||
struct pathgroup *pgp;
|
||||
struct path *pp2;
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 16 Jan 2024 20:19:12 -0500
|
||||
Subject: [PATCH] multipathd: fix auto-resize configuration
|
||||
|
||||
The code acted like AUTO_RESIZE_UNDEFINED didn't exist, but since
|
||||
conf->auto_resize was never set to AUTO_RESIZE_NEVER, the default was in
|
||||
fact AUTO_RESIZE_UNDEFINED, which ended up getting treated like
|
||||
AUTO_RESIZE_GROW_SHRINK. Remove AUTO_RESIZE_UNDEFINED and explicitly
|
||||
default auto_resize tp AUTO_RESIZE_NEVER.
|
||||
|
||||
Fixes: 981b83ad1 ("multipathd: Add auto_resize config option")
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
libmultipath/config.c | 1 +
|
||||
libmultipath/structs.h | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 61b0dd51..f31200a3 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -940,6 +940,7 @@ int _init_config (const char *file, struct config *conf)
|
||||
conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
|
||||
conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
|
||||
conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
|
||||
+ conf->auto_resize = DEFAULT_AUTO_RESIZE;
|
||||
conf->remove_retries = 0;
|
||||
conf->ghost_delay = DEFAULT_GHOST_DELAY;
|
||||
conf->all_tg_pt = DEFAULT_ALL_TG_PT;
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 8c2d7131..d2ad4867 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -168,7 +168,6 @@ enum queue_mode_states {
|
||||
};
|
||||
|
||||
enum auto_resize_state {
|
||||
- AUTO_RESIZE_UNDEF = 0,
|
||||
AUTO_RESIZE_NEVER,
|
||||
AUTO_RESIZE_GROW_ONLY,
|
||||
AUTO_RESIZE_GROW_SHRINK,
|
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 26 Jan 2024 15:40:42 -0500
|
||||
Subject: [PATCH] libmultipath: fix displaying auto_resize config setting
|
||||
|
||||
When 56476ebd3 ("multipathd: fix auto-resize configuration") removed
|
||||
AUTO_RESIZE_UNDEFINED, it didn't update print_auto_resize() to print
|
||||
a value for when it was set to 0 (which is now AUTO_RESIZE_NEVER).
|
||||
|
||||
Fixes: 56476ebd3 ("multipathd: fix auto-resize configuration")
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index c4db60df..ce1b6c99 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -1763,8 +1763,6 @@ def_auto_resize_handler(struct config *conf, vector strvec, const char *file,
|
||||
int
|
||||
print_auto_resize(struct strbuf *buff, long v)
|
||||
{
|
||||
- if (!v)
|
||||
- return 0;
|
||||
return append_strbuf_quoted(buff,
|
||||
v == AUTO_RESIZE_GROW_ONLY ? "grow_only" :
|
||||
v == AUTO_RESIZE_GROW_SHRINK ? "grow_shrink" :
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 9 Apr 2024 14:09:49 -0400
|
||||
Subject: [PATCH] libmultipath: actually truncate too-large vpd page.
|
||||
|
||||
When multipath notices that the vpd page is too large, it needs to
|
||||
actually truncate it. Also, whe calling parse_vpd_pg83() with a possibly
|
||||
truncated page, multipath needs to check that it actually has a whole
|
||||
vpd entry, before trying to use it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index adf8bbaa..ae7eb7e6 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1164,7 +1164,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
int vpd_type, prio = -1, naa_prio;
|
||||
|
||||
d = in + 4;
|
||||
- while (d < in + in_len) {
|
||||
+ while (d + 4 <= in + in_len && d + d[3] + 4 <= in + in_len) {
|
||||
/* Select 'association: LUN' */
|
||||
if ((d[1] & 0x30) != 0) {
|
||||
d += d[3] + 4;
|
||||
@@ -1363,8 +1363,10 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
|
||||
return -ENODATA;
|
||||
}
|
||||
buff_len = get_unaligned_be16(&buff[2]) + 4;
|
||||
- if (buff_len > 4096)
|
||||
+ if (buff_len > 4096) {
|
||||
condlog(3, "vpd pg%02x page truncated", pg);
|
||||
+ buff_len = 4096;
|
||||
+ }
|
||||
|
||||
if (pg == 0x80)
|
||||
len = parse_vpd_pg80(buff, str, maxlen);
|
|
@ -1,23 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 9 Apr 2024 14:13:34 -0400
|
||||
Subject: [PATCH] kpartx: fix theoretical overflow in loop device name
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/lopart.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpartx/lopart.c b/kpartx/lopart.c
|
||||
index 9b652554..80ce1312 100644
|
||||
--- a/kpartx/lopart.c
|
||||
+++ b/kpartx/lopart.c
|
||||
@@ -159,7 +159,7 @@ char *find_loop_by_file(const char *filename)
|
||||
|
||||
char *find_unused_loop_device(void)
|
||||
{
|
||||
- char dev[20], *next_loop_dev = NULL;
|
||||
+ char dev[21], *next_loop_dev = NULL;
|
||||
int fd, next_loop = 0, somedev = 0, someloop = 0, loop_known = 0;
|
||||
struct stat statbuf;
|
||||
struct loop_info loopinfo;
|
|
@ -1,194 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 Dec 2023 17:51:50 -0500
|
||||
Subject: [PATCH] libmultipath: keep track of queueing state in features
|
||||
|
||||
Make multipathd update mpp->features when in enables or disables
|
||||
queuing. This patch handles all the cases except failed removes by
|
||||
dm_suspend_and_flush_map(), which is never called by multipathd.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
---
|
||||
libmultipath/configure.c | 4 +---
|
||||
libmultipath/devmapper.c | 23 +++++++++++++++++++----
|
||||
libmultipath/devmapper.h | 2 +-
|
||||
libmultipath/structs_vec.c | 10 +++++-----
|
||||
multipathd/main.c | 8 ++++----
|
||||
5 files changed, 30 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index bbdbb8ca..71acb968 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1279,9 +1279,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
mpp->no_path_retry != NO_PATH_RETRY_FAIL)
|
||||
condlog(3, "%s: multipathd not running, unset "
|
||||
"queue_if_no_path feature", mpp->alias);
|
||||
- if (!dm_queue_if_no_path(mpp->alias, 0))
|
||||
- remove_feature(&mpp->features,
|
||||
- "queue_if_no_path");
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
}
|
||||
|
||||
if (!is_daemon && mpp->action != ACT_NOTHING)
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index f9de3358..5711f0ee 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -57,6 +57,7 @@ static int dm_cancel_remove_partmaps(const char * mapname);
|
||||
static int do_foreach_partmaps(const char * mapname,
|
||||
int (*partmap_func)(const char *, void *),
|
||||
void *data);
|
||||
+static int _dm_queue_if_no_path(const char *mapname, int enable);
|
||||
|
||||
#ifndef LIBDM_API_COOKIE
|
||||
static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
|
||||
@@ -1072,7 +1073,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||
if (need_suspend &&
|
||||
dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK &&
|
||||
strstr(params, "queue_if_no_path")) {
|
||||
- if (!dm_queue_if_no_path(mapname, 0))
|
||||
+ if (!_dm_queue_if_no_path(mapname, 0))
|
||||
queue_if_no_path = 1;
|
||||
else
|
||||
/* Leave queue_if_no_path alone if unset failed */
|
||||
@@ -1121,7 +1122,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||
} while (retries-- > 0);
|
||||
|
||||
if (queue_if_no_path == 1)
|
||||
- dm_queue_if_no_path(mapname, 1);
|
||||
+ _dm_queue_if_no_path(mapname, 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1236,8 +1237,8 @@ dm_reinstate_path(const char * mapname, char * path)
|
||||
return dm_message(mapname, message);
|
||||
}
|
||||
|
||||
-int
|
||||
-dm_queue_if_no_path(const char *mapname, int enable)
|
||||
+static int
|
||||
+_dm_queue_if_no_path(const char *mapname, int enable)
|
||||
{
|
||||
char *message;
|
||||
|
||||
@@ -1249,6 +1250,20 @@ dm_queue_if_no_path(const char *mapname, int enable)
|
||||
return dm_message(mapname, message);
|
||||
}
|
||||
|
||||
+int dm_queue_if_no_path(struct multipath *mpp, int enable)
|
||||
+{
|
||||
+ int r;
|
||||
+ static const char no_path_retry[] = "queue_if_no_path";
|
||||
+
|
||||
+ if ((r = _dm_queue_if_no_path(mpp->alias, enable)) == 0) {
|
||||
+ if (enable)
|
||||
+ add_feature(&mpp->features, no_path_retry);
|
||||
+ else
|
||||
+ remove_feature(&mpp->features, no_path_retry);
|
||||
+ }
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
dm_groupmsg (const char * msg, const char * mapname, int index)
|
||||
{
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 808da28d..41b8c31d 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -58,7 +58,7 @@ int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||
int dm_flush_maps (int retries);
|
||||
int dm_fail_path(const char * mapname, char * path);
|
||||
int dm_reinstate_path(const char * mapname, char * path);
|
||||
-int dm_queue_if_no_path(const char *mapname, int enable);
|
||||
+int dm_queue_if_no_path(struct multipath *mpp, int enable);
|
||||
int dm_switchgroup(const char * mapname, int index);
|
||||
int dm_enablegroup(const char * mapname, int index);
|
||||
int dm_disablegroup(const char * mapname, int index);
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 86ad89ca..56915e96 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -579,7 +579,7 @@ static void leave_recovery_mode(struct multipath *mpp)
|
||||
*/
|
||||
if (recovery && (mpp->no_path_retry == NO_PATH_RETRY_QUEUE ||
|
||||
mpp->no_path_retry > 0)) {
|
||||
- dm_queue_if_no_path(mpp->alias, 1);
|
||||
+ dm_queue_if_no_path(mpp, 1);
|
||||
condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
|
||||
condlog(1, "%s: Recovered to normal mode", mpp->alias);
|
||||
}
|
||||
@@ -598,11 +598,11 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||
break;
|
||||
case NO_PATH_RETRY_FAIL:
|
||||
if (!check_features || is_queueing)
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
break;
|
||||
case NO_PATH_RETRY_QUEUE:
|
||||
if (!check_features || !is_queueing)
|
||||
- dm_queue_if_no_path(mpp->alias, 1);
|
||||
+ dm_queue_if_no_path(mpp, 1);
|
||||
break;
|
||||
default:
|
||||
if (count_active_paths(mpp) > 0) {
|
||||
@@ -612,7 +612,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||
*/
|
||||
if ((!check_features || !is_queueing) &&
|
||||
!mpp->in_recovery)
|
||||
- dm_queue_if_no_path(mpp->alias, 1);
|
||||
+ dm_queue_if_no_path(mpp, 1);
|
||||
leave_recovery_mode(mpp);
|
||||
} else {
|
||||
/*
|
||||
@@ -623,7 +623,7 @@ void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||
*/
|
||||
if ((!check_features || is_queueing) &&
|
||||
mpp->in_recovery && mpp->retry_tick == 0)
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
if (pathcount(mpp, PATH_PENDING) == 0)
|
||||
enter_recovery_mode(mpp);
|
||||
}
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 26be6dc3..74f8114c 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -502,7 +502,7 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||
mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||
mpp->disable_queueing = 1;
|
||||
mpp->stat_map_failures++;
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
}
|
||||
r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||
if (r) {
|
||||
@@ -833,7 +833,7 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- dm_queue_if_no_path(alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
remove_map_and_stop_waiter(mpp, vecs);
|
||||
out:
|
||||
lock_cleanup_pop(vecs->lock);
|
||||
@@ -2015,7 +2015,7 @@ retry_count_tick(vector mpvec)
|
||||
condlog(4, "%s: Retrying.. No active path", mpp->alias);
|
||||
if(--mpp->retry_tick == 0) {
|
||||
mpp->stat_map_failures++;
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
condlog(2, "%s: Disable queueing", mpp->alias);
|
||||
}
|
||||
}
|
||||
@@ -3110,7 +3110,7 @@ static void cleanup_maps(struct vectors *vecs)
|
||||
put_multipath_config(conf);
|
||||
if (queue_without_daemon == QUE_NO_DAEMON_OFF)
|
||||
vector_foreach_slot(vecs->mpvec, mpp, i)
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ dm_queue_if_no_path(mpp, 0);
|
||||
remove_maps_and_stop_waiters(vecs);
|
||||
vecs->mpvec = NULL;
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 25 Apr 2024 19:35:13 -0400
|
||||
Subject: [PATCH] libmultipath: export partmap_in_use
|
||||
|
||||
A future commit will make use of this function
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 2 +-
|
||||
libmultipath/devmapper.h | 1 +
|
||||
libmultipath/libmultipath.version | 5 +++++
|
||||
3 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 5711f0ee..4a66e2c4 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -1028,7 +1028,7 @@ has_partmap(const char *name __attribute__((unused)),
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int
|
||||
+int
|
||||
partmap_in_use(const char *name, void *data)
|
||||
{
|
||||
int part_count, *ret_count = (int *)data;
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 41b8c31d..88e0b114 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -48,6 +48,7 @@ int dm_get_map(const char *, unsigned long long *, char **);
|
||||
int dm_get_status(const char *, char **);
|
||||
int dm_type(const char *, char *);
|
||||
int dm_is_mpath(const char *);
|
||||
+int partmap_in_use(const char *name, void *data);
|
||||
int _dm_flush_map (const char *, int, int, int, int);
|
||||
int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||
#define dm_flush_map(mapname) _dm_flush_map(mapname, 1, 0, 0, 0)
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 1d018eab..40d9246d 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -302,3 +302,8 @@ LIBMULTIPATH_9.1.2 {
|
||||
global:
|
||||
cleanup_mutex;
|
||||
} LIBMULTIPATH_9.1.1;
|
||||
+
|
||||
+LIBMULTIPATH_9.1.3 {
|
||||
+global:
|
||||
+ partmap_in_use;
|
||||
+} LIBMULTIPATH_9.1.2;
|
|
@ -1,346 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 25 Apr 2024 19:35:14 -0400
|
||||
Subject: [PATCH] libmultipath: change flush_on_last_del to fix a multipathd
|
||||
hang
|
||||
|
||||
Commit 9bd3482e ("multipathd: make flush_map() delete maps like the
|
||||
multipath command") fixed an issue where deleting a queueing multipath
|
||||
device through multipathd could hang because the multipath device had
|
||||
outstanding IO, even though the only openers of it at the time of
|
||||
deletion were the kpartx partition devices. However it is still possible
|
||||
to hang multipathd, because autoremoving the device when all paths have
|
||||
been deleted doesn't disable queueing. To reproduce this hang:
|
||||
|
||||
1. create a multipath device with a kpartx partition on top of it and
|
||||
no_path_retry set to either "queue" or something long enough to run all
|
||||
the commands in the reproducer before it disables queueing.
|
||||
2. disable all the paths to the device with something like:
|
||||
# echo offline > /sys/block/<path_dev>/device/state
|
||||
3. Write directly to the multipath device with something like:
|
||||
# dd if=/dev/zero of=/dev/mapper/<mpath_dev> bs=4K count=1
|
||||
4. delete all the paths to the device with something like:
|
||||
# echo 1 > /sys/block/<path_dev>/device/delete
|
||||
|
||||
Multipathd will hang trying to delete the kpartx device because, as the
|
||||
last opener, it must flush the multipath device before closing it.
|
||||
Because it hangs holding the vecs_lock, multipathd will never disable
|
||||
queueing on the device, so it will hang forever, even if no_path_retry
|
||||
is set to a number.
|
||||
|
||||
This hang can occur, even if deferred_remove is set. Since nothing has
|
||||
the kpartx device opened, device-mapper does an immediate remove, which
|
||||
will still hang. This means that even if deferred_remove is set,
|
||||
multipathd still cannot delete a map while queueing is enabled. It must
|
||||
either disable queueing or skip the autoremove.
|
||||
|
||||
Mulitpath can currently be configured to avoid this hang by setting
|
||||
|
||||
flush_on_last_del yes
|
||||
|
||||
However there are good reasons why users wouldn't want to set that. They
|
||||
may need to be able to survive having all paths getting temporarily
|
||||
deleted. I should note that this is a pretty rare corner case, since
|
||||
multipath automatically sets dev_loss_tmo so that it should not trigger
|
||||
before queueing is disabled.
|
||||
|
||||
This commit avoids the hang by changing the possible values for
|
||||
flush_on_last_del to "never", "unused", and "always", and sets the
|
||||
default to "unused". "always" works like "yes" did, "never" will not
|
||||
disable queueing, and "unused" will only disable queueing if nothing has
|
||||
the kpartx devices or the multipath device open. In order to be safe, if
|
||||
the device has queue_if_no_paths set (and in case of "unused", the
|
||||
device is in-use) the autoremove will be skipped. Also, instead of just
|
||||
trusting the lack of "queue_if_no_paths" in the current mpp->features,
|
||||
multipathd will tell the kernel to disable queueing, just to be sure it
|
||||
actually is.
|
||||
|
||||
I chose "unused" as the default because this should generally only cause
|
||||
multipathd to work differently from the users perspective when nothing
|
||||
has the multipath device open but it is queueing and there is
|
||||
outstanding IO. Without this change, it would have hung instead of
|
||||
failing the outstanding IO. However, I do understand that an argument
|
||||
could be made that "never" makes more sense as default, even though it
|
||||
will cause multipathd to skip autoremoves in cases where it wouldn't
|
||||
before. The change to the behavior of deffered_remove will be
|
||||
noticeable, but skipping an autoremove is much better than hanging.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/defaults.h | 2 +-
|
||||
libmultipath/dict.c | 72 +++++++++++++++++++++++++++++++++-----
|
||||
libmultipath/dict.h | 1 +
|
||||
libmultipath/hwtable.c | 6 ++--
|
||||
libmultipath/propsel.c | 4 ++-
|
||||
libmultipath/structs.h | 7 ++--
|
||||
multipath/multipath.conf.5 | 20 ++++++++---
|
||||
multipathd/main.c | 39 ++++++++++++++++-----
|
||||
8 files changed, 122 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index c3788bbc..5e77387e 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -41,7 +41,7 @@
|
||||
#define DEFAULT_PRIO PRIO_CONST
|
||||
#define DEFAULT_PRIO_ARGS ""
|
||||
#define DEFAULT_CHECKER TUR
|
||||
-#define DEFAULT_FLUSH FLUSH_DISABLED
|
||||
+#define DEFAULT_FLUSH FLUSH_UNUSED
|
||||
#define DEFAULT_USER_FRIENDLY_NAMES USER_FRIENDLY_NAMES_OFF
|
||||
#define DEFAULT_FORCE_SYNC 0
|
||||
#define UNSET_PARTITION_DELIM "/UNSET/"
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index ce1b6c99..3c011ece 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -825,14 +825,70 @@ declare_def_snprint(checker_timeout, print_nonzero)
|
||||
declare_def_handler(allow_usb_devices, set_yes_no)
|
||||
declare_def_snprint(allow_usb_devices, print_yes_no)
|
||||
|
||||
-declare_def_handler(flush_on_last_del, set_yes_no_undef)
|
||||
-declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH)
|
||||
-declare_ovr_handler(flush_on_last_del, set_yes_no_undef)
|
||||
-declare_ovr_snprint(flush_on_last_del, print_yes_no_undef)
|
||||
-declare_hw_handler(flush_on_last_del, set_yes_no_undef)
|
||||
-declare_hw_snprint(flush_on_last_del, print_yes_no_undef)
|
||||
-declare_mp_handler(flush_on_last_del, set_yes_no_undef)
|
||||
-declare_mp_snprint(flush_on_last_del, print_yes_no_undef)
|
||||
+
|
||||
+static const char * const flush_on_last_del_optvals[] = {
|
||||
+ [FLUSH_NEVER] = "never",
|
||||
+ [FLUSH_ALWAYS] = "always",
|
||||
+ [FLUSH_UNUSED] = "unused",
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+set_flush_on_last_del(vector strvec, void *ptr, const char *file, int line_nr)
|
||||
+{
|
||||
+ int i;
|
||||
+ int *flush_val_ptr = (int *)ptr;
|
||||
+ char *buff;
|
||||
+
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
+ return 1;
|
||||
+
|
||||
+ for (i = FLUSH_NEVER; i <= FLUSH_UNUSED; i++) {
|
||||
+ if (flush_on_last_del_optvals[i] != NULL &&
|
||||
+ !strcmp(buff, flush_on_last_del_optvals[i])) {
|
||||
+ *flush_val_ptr = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i > FLUSH_UNUSED) {
|
||||
+ bool deprecated = true;
|
||||
+ if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
|
||||
+ *flush_val_ptr = FLUSH_UNUSED;
|
||||
+ else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
|
||||
+ *flush_val_ptr = FLUSH_ALWAYS;
|
||||
+ else {
|
||||
+ deprecated = false;
|
||||
+ condlog(1, "%s line %d, invalid value for flush_on_last_del: \"%s\"",
|
||||
+ file, line_nr, buff);
|
||||
+ }
|
||||
+ if (deprecated)
|
||||
+ condlog(3, "%s line %d, \"%s\" is a deprecated value for flush_on_last_del and is treated as \"%s\"",
|
||||
+ file, line_nr, buff,
|
||||
+ flush_on_last_del_optvals[*flush_val_ptr]);
|
||||
+ }
|
||||
+
|
||||
+ free(buff);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+print_flush_on_last_del(struct strbuf *buff, long v)
|
||||
+{
|
||||
+ if (v == FLUSH_UNDEF)
|
||||
+ return 0;
|
||||
+ return append_strbuf_quoted(buff, flush_on_last_del_optvals[(int)v]);
|
||||
+}
|
||||
+
|
||||
+declare_def_handler(flush_on_last_del, set_flush_on_last_del)
|
||||
+declare_def_snprint_defint(flush_on_last_del, print_flush_on_last_del,
|
||||
+ DEFAULT_FLUSH)
|
||||
+declare_ovr_handler(flush_on_last_del, set_flush_on_last_del)
|
||||
+declare_ovr_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||
+declare_hw_handler(flush_on_last_del, set_flush_on_last_del)
|
||||
+declare_hw_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||
+declare_mp_handler(flush_on_last_del, set_flush_on_last_del)
|
||||
+declare_mp_snprint(flush_on_last_del, print_flush_on_last_del)
|
||||
|
||||
declare_def_handler(user_friendly_names, set_yes_no_undef)
|
||||
declare_def_snprint_defint(user_friendly_names, print_yes_no_undef,
|
||||
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
|
||||
index d963b4ad..6b1aae5c 100644
|
||||
--- a/libmultipath/dict.h
|
||||
+++ b/libmultipath/dict.h
|
||||
@@ -20,4 +20,5 @@ int print_reservation_key(struct strbuf *buff,
|
||||
struct be64 key, uint8_t flags, int source);
|
||||
int print_off_int_undef(struct strbuf *buff, long v);
|
||||
int print_auto_resize(struct strbuf *buff, long v);
|
||||
+int print_flush_on_last_del(struct strbuf *buff, long v);
|
||||
#endif /* _DICT_H */
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index 78ac7988..94012d50 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -60,7 +60,7 @@
|
||||
.no_path_retry = NO_PATH_RETRY_UNDEF,
|
||||
.minio = 1000,
|
||||
.minio_rq = 1,
|
||||
- .flush_on_last_del = FLUSH_DISABLED,
|
||||
+ .flush_on_last_del = FLUSH_UNUSED,
|
||||
.user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||
.fast_io_fail = 5,
|
||||
.dev_loss = 600,
|
||||
@@ -800,7 +800,7 @@ static struct hwentry default_hw[] = {
|
||||
.no_path_retry = NO_PATH_RETRY_QUEUE,
|
||||
.pgpolicy = GROUP_BY_PRIO,
|
||||
.pgfailback = -FAILBACK_IMMEDIATE,
|
||||
- .flush_on_last_del = FLUSH_ENABLED,
|
||||
+ .flush_on_last_del = FLUSH_ALWAYS,
|
||||
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||
.prio_name = PRIO_ONTAP,
|
||||
.user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||
@@ -1122,7 +1122,7 @@ static struct hwentry default_hw[] = {
|
||||
.no_path_retry = NO_PATH_RETRY_FAIL,
|
||||
.minio = 1,
|
||||
.minio_rq = 1,
|
||||
- .flush_on_last_del = FLUSH_ENABLED,
|
||||
+ .flush_on_last_del = FLUSH_ALWAYS,
|
||||
.fast_io_fail = 15,
|
||||
.dev_loss = 15,
|
||||
},
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 9dea6f92..be781ff7 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -902,6 +902,7 @@ out:
|
||||
int select_flush_on_last_del(struct config *conf, struct multipath *mp)
|
||||
{
|
||||
const char *origin;
|
||||
+ STRBUF_ON_STACK(buff);
|
||||
|
||||
mp_set_mpe(flush_on_last_del);
|
||||
mp_set_ovr(flush_on_last_del);
|
||||
@@ -909,8 +910,9 @@ int select_flush_on_last_del(struct config *conf, struct multipath *mp)
|
||||
mp_set_conf(flush_on_last_del);
|
||||
mp_set_default(flush_on_last_del, DEFAULT_FLUSH);
|
||||
out:
|
||||
+ print_flush_on_last_del(&buff, mp->flush_on_last_del);
|
||||
condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
|
||||
- (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
|
||||
+ get_strbuf_str(&buff), origin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index d2ad4867..4bf8c93a 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -109,9 +109,10 @@ enum marginal_pathgroups_mode {
|
||||
};
|
||||
|
||||
enum flush_states {
|
||||
- FLUSH_UNDEF = YNU_UNDEF,
|
||||
- FLUSH_DISABLED = YNU_NO,
|
||||
- FLUSH_ENABLED = YNU_YES,
|
||||
+ FLUSH_UNDEF,
|
||||
+ FLUSH_NEVER,
|
||||
+ FLUSH_ALWAYS,
|
||||
+ FLUSH_UNUSED,
|
||||
};
|
||||
|
||||
enum log_checker_err_states {
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 38eb5c90..10eddc0c 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -672,12 +672,22 @@ The default is: \fBno\fR
|
||||
.TP
|
||||
.B flush_on_last_del
|
||||
If set to
|
||||
-.I yes
|
||||
+.I always
|
||||
, multipathd will disable queueing when the last path to a device has been
|
||||
-deleted.
|
||||
-.RS
|
||||
-.TP
|
||||
-The default is: \fBno\fR
|
||||
+deleted. If set to
|
||||
+.I never
|
||||
+, multipathd will not disable queueing when the last path to a device has
|
||||
+been deleted. Since multipath cannot safely remove a device while queueing
|
||||
+is enabled, setting this to \fInever\fR means that multipathd will not
|
||||
+automatically remove an unused multipath device whose paths are all deleted if
|
||||
+it is currently set to queue_if_no_path. If set to
|
||||
+.I unused
|
||||
+, multipathd will only disable queueing when the last path is removed if
|
||||
+nothing currently has the multipath device or any of the kpartx partition
|
||||
+devices on top of it open.
|
||||
+.RS
|
||||
+.TP
|
||||
+The default is: \fBunused\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 74f8114c..8ec58f5d 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -491,19 +491,42 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset)
|
||||
static bool
|
||||
flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
|
||||
int r;
|
||||
+ bool is_queueing = true;
|
||||
|
||||
+ if (mpp->features)
|
||||
+ is_queueing = strstr(mpp->features, "queue_if_no_path");
|
||||
+
|
||||
+ /* It's not safe to do a remove of a map that has "queue_if_no_path"
|
||||
+ * set, since there could be outstanding IO which will cause
|
||||
+ * multipathd to hang while attempting the remove */
|
||||
+ if (mpp->flush_on_last_del == FLUSH_NEVER && is_queueing) {
|
||||
+ condlog(2, "%s: map is queueing, can't remove", mpp->alias);
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (mpp->flush_on_last_del == FLUSH_UNUSED &&
|
||||
+ partmap_in_use(mpp->alias, NULL) && is_queueing) {
|
||||
+ condlog(2, "%s: map in use and queueing, can't remove",
|
||||
+ mpp->alias);
|
||||
+ return false;
|
||||
+ }
|
||||
/*
|
||||
- * flush_map will fail if the device is open
|
||||
+ * This will flush FLUSH_NEVER devices and FLUSH_UNUSED devices
|
||||
+ * that are in use, but only if they are already marked as not
|
||||
+ * queueing. That is just to make absolutely certain that they
|
||||
+ * really are not queueing, like they claim.
|
||||
*/
|
||||
- if (mpp->flush_on_last_del == FLUSH_ENABLED) {
|
||||
- condlog(2, "%s Last path deleted, disabling queueing",
|
||||
+ condlog(is_queueing ? 2 : 3, "%s Last path deleted, disabling queueing",
|
||||
+ mpp->alias);
|
||||
+ mpp->retry_tick = 0;
|
||||
+ mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||
+ mpp->disable_queueing = 1;
|
||||
+ mpp->stat_map_failures++;
|
||||
+ if (dm_queue_if_no_path(mpp, 0) != 0) {
|
||||
+ condlog(0, "%s: failed to disable queueing. Not removing",
|
||||
mpp->alias);
|
||||
- mpp->retry_tick = 0;
|
||||
- mpp->no_path_retry = NO_PATH_RETRY_FAIL;
|
||||
- mpp->disable_queueing = 1;
|
||||
- mpp->stat_map_failures++;
|
||||
- dm_queue_if_no_path(mpp, 0);
|
||||
+ return false;
|
||||
}
|
||||
+
|
||||
r = dm_flush_map_nopaths(mpp->alias, mpp->deferred_remove);
|
||||
if (r) {
|
||||
if (r == 1)
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 25 Apr 2024 19:35:16 -0400
|
||||
Subject: [PATCH] libmultipath: pad dev_loss_tmo to avoid race with
|
||||
no_path_retry
|
||||
|
||||
Currently multipath makes sure that dev_loss_tmo is at least as long as
|
||||
the configured no path queueing time. The goal is to make sure that path
|
||||
devices aren't removed while the multipath device is still queueing in
|
||||
hopes that they will become usable again.
|
||||
|
||||
This is racy. Multipathd may take longer to check the paths than
|
||||
configured. If strict_timing isn't set, it will definitely take longer.
|
||||
To account for this, pad the minimum dev_loss_tmo value by five seconds
|
||||
(one default checker interval) plus one second per minute of no path
|
||||
queueing time.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index ae7eb7e6..b24594cd 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -884,6 +884,11 @@ sysfs_set_scsi_tmo (struct config *conf, struct multipath *mpp)
|
||||
uint64_t no_path_retry_tmo =
|
||||
(uint64_t)mpp->no_path_retry * conf->checkint;
|
||||
|
||||
+ /* pad no_path_retry_tmo by one standard check interval
|
||||
+ * plus one second per minute to account for timing
|
||||
+ * issues with the rechecks */
|
||||
+ no_path_retry_tmo += no_path_retry_tmo / 60 + DEFAULT_CHECKINT;
|
||||
+
|
||||
if (no_path_retry_tmo > MAX_DEV_LOSS_TMO)
|
||||
min_dev_loss = MAX_DEV_LOSS_TMO;
|
||||
else
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nitin Yewale <nyewale@redhat.com>
|
||||
Date: Thu, 12 Jan 2023 14:28:49 -0600
|
||||
Subject: [PATCH] libmultipath: remove pathgroup wildcard options
|
||||
|
||||
The multipathd command "multipathd show wildcards" shows the pathgroup
|
||||
format wildcards, but there is no way to use them in a multipathd
|
||||
command.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/print.c | 7 -------
|
||||
1 file changed, 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 082e4e30..a6e4c774 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -803,13 +803,6 @@ int snprint_wildcards(struct strbuf *buff)
|
||||
pd[i].wildcard, pd[i].header)) < 0)
|
||||
return rc;
|
||||
|
||||
- if ((rc = append_strbuf_str(buff, "\npathgroup format wildcards:\n")) < 0)
|
||||
- return rc;
|
||||
- for (i = 0; pgd[i].header; i++)
|
||||
- if ((rc = print_strbuf(buff, "%%%c %s\n",
|
||||
- pgd[i].wildcard, pgd[i].header)) < 0)
|
||||
- return rc;
|
||||
-
|
||||
return get_strbuf_len(buff) - initial_len;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 8 May 2024 19:02:30 -0400
|
||||
Subject: [PATCH] libmultipath: print all values in snprint_failback
|
||||
|
||||
Add the missing output for manual failback and print the defferral time
|
||||
for deferred failbacks, if one isn't currently in progress.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/print.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index a6e4c774..535e0271 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -199,9 +199,13 @@ snprint_failback (struct strbuf *buff, const struct multipath * mpp)
|
||||
return append_strbuf_str(buff, "immediate");
|
||||
if (mpp->pgfailback == -FAILBACK_FOLLOWOVER)
|
||||
return append_strbuf_str(buff, "followover");
|
||||
+ if (mpp->pgfailback == -FAILBACK_MANUAL)
|
||||
+ return append_strbuf_str(buff, "manual");
|
||||
+ if (mpp->pgfailback == FAILBACK_UNDEF)
|
||||
+ return append_strbuf_str(buff, "undef");
|
||||
|
||||
if (!mpp->failback_tick)
|
||||
- return append_strbuf_str(buff, "-");
|
||||
+ return print_strbuf(buff, "%i", mpp->pgfailback);
|
||||
else
|
||||
return snprint_progress(buff, mpp->failback_tick,
|
||||
mpp->pgfailback);
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 May 2024 12:58:11 -0400
|
||||
Subject: [PATCH] multipathd: Stop double counting map failures for
|
||||
no_path_retry > 0
|
||||
|
||||
If no_path_retry was greater than 0, multipathd was counting a map
|
||||
failure when recovery mode was entered, and again when queueing was
|
||||
disabled. The first one is incorrect, since the map is still queueing.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 56915e96..b8e304e0 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -781,10 +781,13 @@ int verify_paths(struct multipath *mpp)
|
||||
void update_queue_mode_del_path(struct multipath *mpp)
|
||||
{
|
||||
int active = count_active_paths(mpp);
|
||||
+ bool is_queueing = mpp->features &&
|
||||
+ strstr(mpp->features, "queue_if_no_path");
|
||||
|
||||
if (active == 0) {
|
||||
enter_recovery_mode(mpp);
|
||||
- if (mpp->no_path_retry != NO_PATH_RETRY_QUEUE)
|
||||
+ if (mpp->no_path_retry == NO_PATH_RETRY_FAIL ||
|
||||
+ (mpp->no_path_retry == NO_PATH_RETRY_UNDEF && !is_queueing))
|
||||
mpp->stat_map_failures++;
|
||||
}
|
||||
condlog(2, "%s: remaining active paths: %d", mpp->alias, active);
|
|
@ -1,102 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 May 2024 17:15:34 -0400
|
||||
Subject: [PATCH] multipath-tools man pages: add missing multipathd commands
|
||||
|
||||
Also, the description for "del map $map" was incorrect.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/multipathd.8 | 42 ++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 37 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||
index 8bd47a80..40a8dc6d 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8
|
||||
@@ -100,18 +100,24 @@ The following commands can be used in interactive mode:
|
||||
Show the paths that multipathd is monitoring, and their state.
|
||||
.
|
||||
.TP
|
||||
-.B list|show paths format $format
|
||||
+.B list|show paths [raw] format $format
|
||||
Show the paths that multipathd is monitoring, using a format string with path
|
||||
-format wildcards.
|
||||
+format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||
+padding from the ouput.
|
||||
+.
|
||||
+.TP
|
||||
+.B list|show path $path
|
||||
+Show whether path $path is offline or running.
|
||||
.
|
||||
.TP
|
||||
.B list|show maps|multipaths
|
||||
Show the multipath devices that the multipathd is monitoring.
|
||||
.
|
||||
.TP
|
||||
-.B list|show maps|multipaths format $format
|
||||
+.B list|show maps|multipaths [raw] format $format
|
||||
Show the status of all multipath devices that the multipathd is monitoring,
|
||||
-using a format string with multipath format wildcards.
|
||||
+using a format string with multipath format wildcards. Adding \fIraw\fR will
|
||||
+remove the headers and alignment padding from the output.
|
||||
.
|
||||
.TP
|
||||
.B list|show maps|multipaths status
|
||||
@@ -124,6 +130,10 @@ Show some statistics of all multipath devices that the multipathd is monitoring.
|
||||
.TP
|
||||
.B list|show maps|multipaths topology
|
||||
Show the current multipath topology. Same as '\fImultipath \-ll\fR'.
|
||||
+.TP
|
||||
+.
|
||||
+.B list|show maps|multipaths json
|
||||
+Show information about all multipath devices in JSON format.
|
||||
.
|
||||
.TP
|
||||
.B list|show topology
|
||||
@@ -135,6 +145,16 @@ Show topology of a single multipath device specified by $map, for example
|
||||
36005076303ffc56200000000000010aa. This map could be obtained from '\fIlist maps\fR'.
|
||||
.
|
||||
.TP
|
||||
+.B list|show map|multipath $map [raw] format $format.
|
||||
+Show the status of multipath device $map, using a format string with multipath
|
||||
+format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||
+padding from the output.
|
||||
+.
|
||||
+.TP
|
||||
+.B list|show map|multipath $map json
|
||||
+Show information about multipath device $map in JSON format.
|
||||
+.
|
||||
+.TP
|
||||
.B list|show wildcards
|
||||
Show the format wildcards used in interactive commands taking $format.
|
||||
.
|
||||
@@ -168,6 +188,14 @@ paths, and whether multipathd is currently handling a uevent.
|
||||
Show the current state of the multipathd daemon.
|
||||
.
|
||||
.TP
|
||||
+.B reset maps|multipaths stats
|
||||
+Reset the statistics of all multipath devices.
|
||||
+.
|
||||
+.TP
|
||||
+.B reset map|multipath $map stats
|
||||
+Reset the statistics of multipath device $map.
|
||||
+.
|
||||
+.TP
|
||||
.B add path $path
|
||||
Add a path to the list of monitored paths. $path is as listed in /sys/block (e.g. sda).
|
||||
.
|
||||
@@ -183,8 +211,12 @@ for the multipath device (e.g. mpath1) or the uid of the multipath device
|
||||
(e.g. 36005076303ffc56200000000000010aa).
|
||||
.
|
||||
.TP
|
||||
+.B remove|del maps|multipaths
|
||||
+Remove all multipath devices.
|
||||
+.
|
||||
+.TP
|
||||
.B remove|del map|multipath $map
|
||||
-Stop monitoring a multipath device.
|
||||
+Remove the multipath device $map.
|
||||
.
|
||||
.TP
|
||||
.B resize map|multipath $map
|
|
@ -1,54 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 10 May 2024 15:36:10 -0400
|
||||
Subject: [PATCH] libmultipath: change the vend/prod/rev printing
|
||||
|
||||
The %s multipath and path wildcards both say they print the device
|
||||
vend/prod/rev string, but neither of them do. The multipath wildcards
|
||||
already provide a way to print the revision string and the %s wildcard
|
||||
is used in the multipath -l output, so leave the wildcard output alone,
|
||||
and change the description to only mention the vendor and product. There
|
||||
is no other way to print the revision by path, and the path %s wildcard
|
||||
is only used in the verbose multipath output, so make it actually print
|
||||
the revision. Also check for unset strings, and print "##" instead of
|
||||
nothing.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/print.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 535e0271..4552fd43 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -309,7 +309,7 @@ snprint_multipath_uuid (struct strbuf *buff, const struct multipath * mpp)
|
||||
}
|
||||
|
||||
static int
|
||||
-snprint_multipath_vpr (struct strbuf *buff, const struct multipath * mpp)
|
||||
+snprint_multipath_vp (struct strbuf *buff, const struct multipath * mpp)
|
||||
{
|
||||
struct pathgroup * pgp;
|
||||
struct path * pp;
|
||||
@@ -511,7 +511,10 @@ snprint_dm_path_state (struct strbuf *buff, const struct path * pp)
|
||||
static int
|
||||
snprint_vpr (struct strbuf *buff, const struct path * pp)
|
||||
{
|
||||
- return print_strbuf(buff, "%s,%s", pp->vendor_id, pp->product_id);
|
||||
+ return print_strbuf(buff, "%s,%s,%s",
|
||||
+ strlen(pp->vendor_id) ? pp->vendor_id : "##",
|
||||
+ strlen(pp->product_id) ? pp->product_id : "##",
|
||||
+ strlen(pp->rev) ? pp->rev : "##");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -743,7 +746,7 @@ struct multipath_data mpd[] = {
|
||||
{'2', "map_loads", 0, snprint_map_loads},
|
||||
{'3', "total_q_time", 0, snprint_total_q_time},
|
||||
{'4', "q_timeouts", 0, snprint_q_timeouts},
|
||||
- {'s', "vend/prod/rev", 0, snprint_multipath_vpr},
|
||||
+ {'s', "vend/prod", 0, snprint_multipath_vp},
|
||||
{'v', "vend", 0, snprint_multipath_vend},
|
||||
{'p', "prod", 0, snprint_multipath_prod},
|
||||
{'e', "rev", 0, snprint_multipath_rev},
|
|
@ -1,243 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 10 May 2024 20:53:33 -0400
|
||||
Subject: [PATCH] multipath-tools man pages: Add format wildcard descriptions
|
||||
|
||||
Suggested-by: Nitin Yewale <nyewale@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/multipathd.8 | 193 +++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 189 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||
index 40a8dc6d..d834f89e 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8
|
||||
@@ -103,7 +103,7 @@ Show the paths that multipathd is monitoring, and their state.
|
||||
.B list|show paths [raw] format $format
|
||||
Show the paths that multipathd is monitoring, using a format string with path
|
||||
format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||
-padding from the ouput.
|
||||
+padding from the output. See "Path format wildcards" below.
|
||||
.
|
||||
.TP
|
||||
.B list|show path $path
|
||||
@@ -117,7 +117,8 @@ Show the multipath devices that the multipathd is monitoring.
|
||||
.B list|show maps|multipaths [raw] format $format
|
||||
Show the status of all multipath devices that the multipathd is monitoring,
|
||||
using a format string with multipath format wildcards. Adding \fIraw\fR will
|
||||
-remove the headers and alignment padding from the output.
|
||||
+remove the headers and alignment padding from the output. See "Multipath
|
||||
+format wildcards" below.
|
||||
.
|
||||
.TP
|
||||
.B list|show maps|multipaths status
|
||||
@@ -148,7 +149,7 @@ Show topology of a single multipath device specified by $map, for example
|
||||
.B list|show map|multipath $map [raw] format $format.
|
||||
Show the status of multipath device $map, using a format string with multipath
|
||||
format wildcards. Adding \fIraw\fR will remove the headers and alignment
|
||||
-padding from the output.
|
||||
+padding from the output. See "Multipath format wildcards" below.
|
||||
.
|
||||
.TP
|
||||
.B list|show map|multipath $map json
|
||||
@@ -156,7 +157,8 @@ Show information about multipath device $map in JSON format.
|
||||
.
|
||||
.TP
|
||||
.B list|show wildcards
|
||||
-Show the format wildcards used in interactive commands taking $format.
|
||||
+Show the format wildcards used in interactive commands taking $format. See
|
||||
+"Format Wildcards" below.
|
||||
.
|
||||
.TP
|
||||
.B list|show config
|
||||
@@ -339,6 +341,189 @@ Stop multipathd.
|
||||
.
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
+.SH "Format Wildcards"
|
||||
+.\" ----------------------------------------------------------------------------
|
||||
+.
|
||||
+Multipathd commands that take a $format option require a format string. This
|
||||
+string controls how a device is printed and should include format wildcards.
|
||||
+When the devices are printed, these wildcards will be replaced by the
|
||||
+appropriate device information. The following wildcards are supported.
|
||||
+.TP
|
||||
+.B Multipath format wildcards
|
||||
+.RS
|
||||
+.TP 12
|
||||
+.B %n
|
||||
+The device name.
|
||||
+.TP
|
||||
+.B %w
|
||||
+The device WWID (uuid).
|
||||
+.TP
|
||||
+.B %d
|
||||
+The device sysfs name (dm-<minor_nr>).
|
||||
+.TP
|
||||
+.B %F
|
||||
+The device \fBfailback\fR setting. For deferred failbacks, it will either
|
||||
+print the configured time if a deferred failback is not in progress, or
|
||||
+it will show the current progress of a deferred failback.
|
||||
+.TP
|
||||
+.B %Q
|
||||
+The device \fBno_path_retry\fR setting. If no_path_retry is set to a
|
||||
+number of retires, it will either print the configured number of checker
|
||||
+retries if the device is not in recovery mode, the number of seconds until
|
||||
+queueing is disabled if the device is queueing in recovery mode, or \fIoff\fR
|
||||
+if the device has disabled queueing.
|
||||
+.TP
|
||||
+.B %N
|
||||
+The number of active paths for the device.
|
||||
+.TP
|
||||
+.B %r
|
||||
+The device write-protect setting, either \fIro\fR or \fIrw\fR.
|
||||
+.TP
|
||||
+.B %t
|
||||
+The device-mapper state of the device, either \fIsuspend\fR or \fIactive\fR.
|
||||
+.TP
|
||||
+.B %S
|
||||
+The device size.
|
||||
+.TP
|
||||
+.B %f
|
||||
+The device table features string.
|
||||
+.TP
|
||||
+.B %x
|
||||
+The number of times the device has entered a state where it will fail IO.
|
||||
+This is an alias for the \fB%4\fR wildcard.
|
||||
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||
+.TP
|
||||
+.B %h
|
||||
+The device table hardware handler string.
|
||||
+.TP
|
||||
+.B %A
|
||||
+The last action multipathd took on the device. This wildcard is for debugging
|
||||
+use, as understanding its meaning requires looking at the code.
|
||||
+.TP
|
||||
+.B %0
|
||||
+The number of times a path in the device has failed.
|
||||
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||
+.TP
|
||||
+.B %1
|
||||
+The number of times multipathd has initiated a pathgroup switch for the device.
|
||||
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||
+.TP
|
||||
+.B %2
|
||||
+The number of times multipathd has loaded a new table for the device.
|
||||
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||
+.TP
|
||||
+.B %3
|
||||
+The approximate number of seconds that multipathd has spent queueing with
|
||||
+no usable paths. This value can be reset with the '\fIreset map $map stats\fR'
|
||||
+command.
|
||||
+.TP
|
||||
+.B %4
|
||||
+The number of times the device has entered a state where it will fail IO.
|
||||
+This is an alias for the \fB%x\fR wildcard.
|
||||
+This value can be reset with the '\fIreset map $map stats\fR' command.
|
||||
+.TP
|
||||
+.B %s
|
||||
+The vendor/product string for the device.
|
||||
+.TP
|
||||
+.B %v
|
||||
+The array vendor string for the device.
|
||||
+.TP
|
||||
+.B %p
|
||||
+The array product string for the device.
|
||||
+.TP
|
||||
+.B %e
|
||||
+The array firmware revision string for the device.
|
||||
+.TP
|
||||
+.B %G
|
||||
+The foreign library used for the device, or \fB--\fR for native device-mapper
|
||||
+multipath devices.
|
||||
+.TP
|
||||
+.B %g
|
||||
+Data from vendor specific vpd pages for the device, if any.
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
+.TP
|
||||
+.B Path format wildcards
|
||||
+.RS
|
||||
+.TP 12
|
||||
+.B %w
|
||||
+The device WWID (uuid).
|
||||
+.TP
|
||||
+.B %i
|
||||
+The device Host:Channel:Id:Lun
|
||||
+.TP
|
||||
+.B %d
|
||||
+The device sysfs name.
|
||||
+.TP
|
||||
+.B %D
|
||||
+The device major:minor
|
||||
+.TP
|
||||
+.B %t
|
||||
+The device-mapper state of the device, either \fIactive\fR or \fIfailed\fR.
|
||||
+.TP
|
||||
+.B %o
|
||||
+Whether the device is \fIoffline\fR or \fIrunning\fR.
|
||||
+.TP
|
||||
+.B %T
|
||||
+The multipathd path checker state of the device.
|
||||
+.TP
|
||||
+.B %s
|
||||
+The vendor/product/revision string for the device.
|
||||
+.TP
|
||||
+.B %c
|
||||
+The device's path checker name.
|
||||
+.TP
|
||||
+.B %C
|
||||
+The progress towards the next path checker run on the device.
|
||||
+.TP
|
||||
+.B %p
|
||||
+The device priority.
|
||||
+.TP
|
||||
+.B %S
|
||||
+The device size.
|
||||
+.TP
|
||||
+.B %z
|
||||
+The device serial number.
|
||||
+.TP
|
||||
+.B %M
|
||||
+The device marginal state, either \fImarginal\fR or \fInormal\fR.
|
||||
+.TP
|
||||
+.B %m
|
||||
+The multipath device that this device is a path of.
|
||||
+.TP
|
||||
+.B %N
|
||||
+The host World Wide Node Name (WWNN) of the device.
|
||||
+.TP
|
||||
+.B %n
|
||||
+The target World Wide Node Name (WWNN) of the device.
|
||||
+.TP
|
||||
+.B %R
|
||||
+The host World Wide Port Name (WWPN) of the device.
|
||||
+.TP
|
||||
+.B %r
|
||||
+The target World Wide Port Name (WWPN) of the device.
|
||||
+.TP
|
||||
+.B %a
|
||||
+The host adapter name for the device (only SCSI devices).
|
||||
+.TP
|
||||
+.B %G
|
||||
+The foreign library used for the device, or \fB--\fR for paths of native
|
||||
+device-mapper multipath devices.
|
||||
+.TP
|
||||
+.B %g
|
||||
+Data from vendor specific vpd pages for the device, if any.
|
||||
+.TP
|
||||
+.B %0
|
||||
+The number of times this device has failed.
|
||||
+.TP
|
||||
+.B %P
|
||||
+The device protocol. This output can be used for \fIprotocol\fR blacklist
|
||||
+entries.
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
+.\" ----------------------------------------------------------------------------
|
||||
.SH "SYSTEMD INTEGRATION"
|
||||
.\" ----------------------------------------------------------------------------
|
||||
.
|
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 17 Mar 2020 17:28:24 -0500
|
||||
Subject: [PATCH] libmultipath: assign variable to make gcc happy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There is nothing wrong with is_queueing not being set at the start
|
||||
of __set_no_path_retry(), it will always get set before it is accessed,
|
||||
but gcc 8.2.1 is failing with
|
||||
|
||||
structs_vec.c: In function ‘__set_no_path_retry’:
|
||||
structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in
|
||||
this function [-Werror=maybe-uninitialized]
|
||||
bool is_queueing;
|
||||
^~~~~~~~~~~
|
||||
|
||||
so, assign a value to make it happy.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 3dbbaa0f..077f2e42 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp)
|
||||
|
||||
void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||
{
|
||||
- bool is_queueing;
|
||||
+ bool is_queueing = false; /* assign a value to make gcc happy */
|
||||
|
||||
check_features = check_features && mpp->features != NULL;
|
||||
if (check_features)
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Sat, 21 Mar 2020 23:49:59 -0500
|
||||
Subject: [PATCH] libmutipath: don't close fd on dm_lib_release
|
||||
|
||||
If dm_hold_control_open() isn't set, when dm_lib_release() is called, it
|
||||
will close the control fd. The control fd will get re-opened on the next
|
||||
dm_task_run() call, but if there is a dm_task_run() call already
|
||||
in progress in another thread, it can fail. Since many of the
|
||||
device-mapper callouts happen with the vecs lock held, this wasn't too
|
||||
noticeable, but there is code that calls dm_task_run() without the
|
||||
vecs lock held, notably the dmevent waiter code.
|
||||
|
||||
Since, as Martin pointed out, dm_hold_control_open() hasn't always
|
||||
existed in libdevmapper, check if it's supported on compilation,
|
||||
and update the version requirements if so.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 4 ++++
|
||||
libmultipath/devmapper.c | 7 ++++++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index e5651e49..ad690a49 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0)
|
||||
CFLAGS += -DLIBDM_API_DEFERRED
|
||||
endif
|
||||
|
||||
+ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0)
|
||||
+ CFLAGS += -DLIBDM_API_HOLD_CONTROL
|
||||
+endif
|
||||
+
|
||||
OBJS = memory.o parser.o vector.o devmapper.o callout.o \
|
||||
hwtable.o blacklist.o util.o dmparser.o config.o \
|
||||
structs.o discovery.o propsel.o dict.o \
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index bed8ddc6..13a1cf53 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -108,7 +108,9 @@ dm_lib_prereq (void)
|
||||
{
|
||||
char version[64];
|
||||
int v[3];
|
||||
-#if defined(LIBDM_API_DEFERRED)
|
||||
+#if defined(LIBDM_API_HOLD_CONTROL)
|
||||
+ int minv[3] = {1, 2, 111};
|
||||
+#elif defined(LIBDM_API_DEFERRED)
|
||||
int minv[3] = {1, 2, 89};
|
||||
#elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
|
||||
int minv[3] = {1, 2, 82};
|
||||
@@ -254,6 +256,9 @@ void libmp_dm_init(void)
|
||||
memcpy(conf->version, version, sizeof(version));
|
||||
put_multipath_config(conf);
|
||||
dm_init(verbosity);
|
||||
+#ifdef LIBDM_API_HOLD_CONTROL
|
||||
+ dm_hold_control_dev(1);
|
||||
+#endif
|
||||
dm_udev_set_sync_support(libmp_dm_udev_sync);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 19 Mar 2020 22:17:51 -0500
|
||||
Subject: [PATCH] libmultipath: allow force reload with no active paths
|
||||
|
||||
If the partition information has changed on multipath devices (say,
|
||||
because it was updated on another node that has access to the same
|
||||
storage), users expect that running "multipathd reconfigure" will update
|
||||
that. However, if the checkers for the multipath device are pending for
|
||||
too long when the the device is reconfigured, multipathd will give up
|
||||
waiting for them, and refuse to reload the device, since there are no
|
||||
active paths. This means that no kpartx update will be triggered.
|
||||
|
||||
Multipath is fully capable of reloading a multipath device that has no
|
||||
active paths. This has been possible for years. If multipath is supposed
|
||||
to reload the device, it should do so, even if there are no active paths.
|
||||
|
||||
Generally, when multipath is force reloaded, kpartx will be updated.
|
||||
However when a device is reloaded with no paths, the udev rules won't
|
||||
run kpartx. But they also weren't running kpartx when the first valid
|
||||
path appeared, even though the dm activation rules get run in this case.
|
||||
This changes 11-dm-mpath.rules to run kpartx when a device goes from no
|
||||
usable paths to having usable paths.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 6 ------
|
||||
multipath/11-dm-mpath.rules | 2 +-
|
||||
2 files changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index c95848a0..96c79610 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (pathcount(mpp, PATH_UP) == 0) {
|
||||
- mpp->action = ACT_IMPOSSIBLE;
|
||||
- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)",
|
||||
- mpp->alias);
|
||||
- return;
|
||||
- }
|
||||
if (force_reload) {
|
||||
mpp->force_udev_reload = 1;
|
||||
mpp->action = ACT_RELOAD;
|
||||
diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules
|
||||
index 07320a14..cd522e8c 100644
|
||||
--- a/multipath/11-dm-mpath.rules
|
||||
+++ b/multipath/11-dm-mpath.rules
|
||||
@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
||||
ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\
|
||||
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\
|
||||
ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\
|
||||
- ENV{DM_ACTIVATION}="1"
|
||||
+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0"
|
||||
|
||||
# The code to check multipath state ends here. We need to set
|
||||
# properties and symlinks regardless whether the map is usable or
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hesse <mail@eworm.de>
|
||||
Date: Wed, 6 May 2020 09:35:47 +0200
|
||||
Subject: [PATCH] libmpathpersist: depend on libmultipath
|
||||
|
||||
Without this the build fails with:
|
||||
|
||||
/usr/bin/ld: cannot find -lmultipath
|
||||
|
||||
Signed-off-by: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1dee3680..ba1d73ba 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -28,7 +28,7 @@ all: $(BUILDDIRS)
|
||||
$(BUILDDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
-multipath multipathd mpathpersist: libmultipath
|
||||
+libmpathpersist multipath multipathd mpathpersist: libmultipath
|
||||
mpathpersist: libmpathpersist
|
||||
|
||||
$(BUILDDIRS.clean):
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:21 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel
|
||||
build
|
||||
|
||||
Extend the late fixes from Christian.
|
||||
|
||||
Cc: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index ba1d73ba..fec3b73b 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -28,8 +28,9 @@ all: $(BUILDDIRS)
|
||||
$(BUILDDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
-libmpathpersist multipath multipathd mpathpersist: libmultipath
|
||||
-mpathpersist: libmpathpersist
|
||||
+libmultipath libdmmp: libmpathcmd
|
||||
+libmpathpersist multipath multipathd: libmultipath
|
||||
+mpathpersist multipathd: libmpathpersist
|
||||
|
||||
$(BUILDDIRS.clean):
|
||||
$(MAKE) -C ${@:.clean=} clean
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:24 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered
|
||||
|
||||
We need to ignore -Wclobbered because gcc has trouble dealing with glibc's
|
||||
implementation of pthread_cleanup_push().
|
||||
|
||||
For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also
|
||||
set. Compilation with -Wno-error=clobbered works, though.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index d4d1e0dd..9060ac9b 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \
|
||||
|
||||
STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,)
|
||||
+WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
|
||||
|
||||
OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:25 +0200
|
||||
Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t
|
||||
|
||||
Otherwise compilation for 32bit targets spits out warnings.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index ee3290cd..ffec5162 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len)
|
||||
}
|
||||
|
||||
if (len >= out_len) {
|
||||
- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required",
|
||||
+ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required",
|
||||
len + 1, out_len);
|
||||
len = out_len - 1;
|
||||
}
|
||||
@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
|
||||
len = sprintf(out, "%d", vpd_type);
|
||||
if (2 * vpd_len >= out_len - len) {
|
||||
- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required",
|
||||
__func__, vpd_type,
|
||||
2 * vpd_len + len + 1, out_len);
|
||||
vpd_len = (out_len - len - 1) / 2;
|
||||
@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
len += sprintf(out + len,
|
||||
"%02x", vpd[i]);
|
||||
} else if (vpd_type == 0x8 && vpd_len < 4) {
|
||||
- condlog(1, "%s: VPD length %lu too small for designator type 8",
|
||||
+ condlog(1, "%s: VPD length %zu too small for designator type 8",
|
||||
__func__, vpd_len);
|
||||
return -EINVAL;
|
||||
} else if (vpd_type == 0x8) {
|
||||
@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
while (len > 2 && vpd[len - 2] == '\0')
|
||||
--len;
|
||||
if (len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required",
|
||||
__func__, out[0], len + 1, out_len);
|
||||
len = out_len - 1;
|
||||
}
|
||||
@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
while ((p = memchr(vpd, ' ', vpd_len))) {
|
||||
p_len = p - vpd;
|
||||
if (len + p_len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required",
|
||||
__func__, len + p_len, out_len);
|
||||
p_len = out_len - len - 1;
|
||||
}
|
||||
@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
p_len = vpd_len;
|
||||
if (p_len > 0 && len < out_len - 1) {
|
||||
if (len + p_len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required",
|
||||
__func__, len + p_len + 1, out_len);
|
||||
p_len = out_len - len - 1;
|
||||
}
|
||||
@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len,
|
||||
|
||||
memset(out, 0x0, out_len);
|
||||
if (in_len <= 4 || (in[4] > 3 && in_len < 44)) {
|
||||
- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len);
|
||||
+ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */
|
||||
return -ENODATA;
|
||||
len = get_unaligned_be32(&in[40]);
|
||||
if (len > out_len || len + 44 > in_len) {
|
||||
- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu",
|
||||
+ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu",
|
||||
len);
|
||||
return -EINVAL;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:26 +0200
|
||||
Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons
|
||||
|
||||
Fix some more compiler warnings about signed/unsigned comparison.
|
||||
I've observed these only on 32bit builds, therefore they went unnoticed
|
||||
before.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/print.c | 12 ++++++------
|
||||
libmultipath/prioritizers/alua_spc3.h | 2 +-
|
||||
multipathd/cli_handlers.c | 20 ++++++++++----------
|
||||
multipathd/main.c | 2 +-
|
||||
4 files changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index b944ef32..298b3764 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len,
|
||||
}
|
||||
|
||||
c = reply + snprint_defaults(conf, reply, maxlen);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_blacklist(conf, c, reply + maxlen - c);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_blacklist_except(conf, c, reply + maxlen - c);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_hwtable(conf, c, reply + maxlen - c,
|
||||
hwtable ? hwtable : conf->hwtable);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_overrides(conf, c, reply + maxlen - c,
|
||||
conf->overrides);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
if (VECTOR_SIZE(conf->mptable) > 0 ||
|
||||
@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len,
|
||||
c += snprint_mptable(conf, c, reply + maxlen - c,
|
||||
mpvec);
|
||||
|
||||
- if ((c - reply) < maxlen) {
|
||||
+ if (c < reply + maxlen) {
|
||||
if (len)
|
||||
*len = c - reply;
|
||||
return reply;
|
||||
diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h
|
||||
index 18b495ef..7ba2cf4c 100644
|
||||
--- a/libmultipath/prioritizers/alua_spc3.h
|
||||
+++ b/libmultipath/prioritizers/alua_spc3.h
|
||||
@@ -284,7 +284,7 @@ struct rtpg_data {
|
||||
#define RTPG_FOR_EACH_PORT_GROUP(p, g) \
|
||||
for( \
|
||||
g = &(p->data[0]); \
|
||||
- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \
|
||||
+ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \
|
||||
g = (struct rtpg_tpg_dscr *) ( \
|
||||
((char *) g) + \
|
||||
sizeof(struct rtpg_tpg_dscr) + \
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 7d878c88..31c3d9fd 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style,
|
||||
c += snprint_foreign_paths(c, reply + maxlen - c,
|
||||
style, pretty);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp,
|
||||
|
||||
c += snprint_path(c, reply + maxlen - c, style, pp, 0);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp,
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2);
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
|
||||
}
|
||||
c += snprint_foreign_topology(c, reply + maxlen - c, 2);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs)
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_topology_json(c, maxlen, vecs);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp,
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_map_json(c, maxlen, mpp);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style,
|
||||
c += snprint_multipath(c, reply + maxlen - c, style,
|
||||
mpp, pretty);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
|
||||
}
|
||||
c += snprint_foreign_multipaths(c, reply + maxlen - c,
|
||||
style, pretty);
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len)
|
||||
|
||||
c = reply;
|
||||
c += snprint_blacklist_report(conf, c, maxlen);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs)
|
||||
|
||||
c = reply;
|
||||
c += snprint_devices(conf, c, maxlen, vecs);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 8baf9abe..6b7db2c0 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2374,7 +2374,7 @@ checkerloop (void *ap)
|
||||
conf = get_multipath_config();
|
||||
max_checkint = conf->max_checkint;
|
||||
put_multipath_config(conf);
|
||||
- if (diff_time.tv_sec > max_checkint)
|
||||
+ if (diff_time.tv_sec > (time_t)max_checkint)
|
||||
condlog(1, "path checkers took longer "
|
||||
"than %lu seconds, consider "
|
||||
"increasing max_polling_interval",
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:27 +0200
|
||||
Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit
|
||||
|
||||
On architectures where sizeof(long) == sizeof(int), the code wouldn't
|
||||
work as intended. Use strtoul instead. As strtoul happily parses
|
||||
negative numbers as input, require the number to begin with a digit.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 3e25e74f..0e9ea387 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -60,19 +60,22 @@ static int
|
||||
set_uint(vector strvec, void *ptr)
|
||||
{
|
||||
unsigned int *uint_ptr = (unsigned int *)ptr;
|
||||
- char *buff, *eptr;
|
||||
- long res;
|
||||
+ char *buff, *eptr, *p;
|
||||
+ unsigned long res;
|
||||
int rc;
|
||||
|
||||
buff = set_value(strvec);
|
||||
if (!buff)
|
||||
return 1;
|
||||
|
||||
- res = strtol(buff, &eptr, 10);
|
||||
+ p = buff;
|
||||
+ while (isspace(*p))
|
||||
+ p++;
|
||||
+ res = strtoul(p, &eptr, 10);
|
||||
if (eptr > buff)
|
||||
while (isspace(*eptr))
|
||||
eptr++;
|
||||
- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) {
|
||||
+ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) {
|
||||
condlog(1, "%s: invalid value for %s: \"%s\"",
|
||||
__func__, (char*)VECTOR_SLOT(strvec, 0), buff);
|
||||
rc = 1;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 22:38:22 +0200
|
||||
Subject: [PATCH] multipath-tools Makefile: add install dependency
|
||||
|
||||
$(libdir) must exist before running "make install" on prioritizer, checker,
|
||||
and foreign libraries.
|
||||
|
||||
Cc: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index fec3b73b..8bcaba66 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd
|
||||
libmpathpersist multipath multipathd: libmultipath
|
||||
mpathpersist multipathd: libmpathpersist
|
||||
|
||||
+libmultipath/checkers.install \
|
||||
+ libmultipath/prioritizers.install \
|
||||
+ libmultipath/foreign.install: libmultipath.install
|
||||
+
|
||||
$(BUILDDIRS.clean):
|
||||
$(MAKE) -C ${@:.clean=} clean
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index d0ec9b44..2a75dc9c 100644
|
||||
index 9060ac9b..034752d9 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -55,7 +55,7 @@ endif
|
||||
@@ -53,7 +53,7 @@ endif
|
||||
prefix =
|
||||
exec_prefix = $(prefix)
|
||||
usr_prefix = $(prefix)
|
||||
|
@ -28,10 +28,10 @@ index d0ec9b44..2a75dc9c 100644
|
|||
udevrulesdir = $(libudevdir)/rules.d
|
||||
multipathdir = $(TOPDIR)/libmultipath
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index d7527d7d..0e0d70d5 100644
|
||||
index 8f990494..8a3a1718 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end"
|
||||
@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end"
|
||||
GOTO="kpartx_end"
|
||||
|
||||
LABEL="run_kpartx"
|
||||
|
@ -61,3 +61,6 @@ index 0828a8f7..b9bbb3cf 100644
|
|||
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -13,26 +13,29 @@ it.
|
|||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 6 ++----
|
||||
libmultipath/blacklist.c | 9 ++-------
|
||||
multipath/multipath.conf.5 | 11 ++++++-----
|
||||
tests/blacklist.c | 7 ++-----
|
||||
3 files changed, 10 insertions(+), 14 deletions(-)
|
||||
tests/blacklist.c | 6 ++----
|
||||
3 files changed, 10 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index 4e315c97..1e463ef6 100644
|
||||
index 00e8dbdb..d9691b17 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))
|
||||
@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf)
|
||||
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
|
||||
- if (store_ble(conf->elist_property, "(SCSI_IDENT_|ID_WWN)", ORIGIN_DEFAULT))
|
||||
- str = STRDUP("(SCSI_IDENT_|ID_WWN)");
|
||||
- if (!str)
|
||||
- return 1;
|
||||
- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -410,7 +407,8 @@ filter_property(const struct config *conf, struct udev_device *udev,
|
||||
@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
*uid_attribute != '\0';
|
||||
bool uid_attr_seen = false;
|
||||
|
||||
|
@ -43,10 +46,10 @@ index 4e315c97..1e463ef6 100644
|
|||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index c74129bd..dd9f4dc7 100644
|
||||
index 05a5e8ff..3455b1cc 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
|
||||
@@ -1286,9 +1286,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,
|
||||
|
@ -62,7 +65,7 @@ index c74129bd..dd9f4dc7 100644
|
|||
.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1364,10 +1369,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
@@ -1299,10 +1304,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.
|
||||
|
@ -74,21 +77,19 @@ index c74129bd..dd9f4dc7 100644
|
|||
.TP
|
||||
.B protocol
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 882aa3a1..6a22b660 100644
|
||||
index 6e7c1864..cc8a9a4a 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 } };
|
||||
@@ -271,7 +271,7 @@ static void test_property_missing(void **state)
|
||||
conf.blist_property = blist_property_wwn;
|
||||
- expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
- MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"),
|
||||
MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, ""),
|
||||
@@ -469,9 +468,7 @@ static void test_filter_path_missing1(void **state)
|
||||
@@ -363,9 +363,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;
|
||||
|
@ -99,3 +100,6 @@ index 882aa3a1..6a22b660 100644
|
|||
}
|
||||
|
||||
/* This one matches the property whitelist, to test the other missing
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -12,19 +12,26 @@ simple way to disable multipath. Simply removing or renaming
|
|||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 13 +++++++++++++
|
||||
libmultipath/config.c | 15 +++++++++++++++
|
||||
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(+)
|
||||
5 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 30046a17..5f35c3d3 100644
|
||||
index b4d87689..b36778b0 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -895,6 +895,19 @@ int _init_config (const char *file, struct config *conf)
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "devmapper.h"
|
||||
#include "mpath_cmd.h"
|
||||
#include "propsel.h"
|
||||
+#include "version.h"
|
||||
|
||||
static int
|
||||
hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2)
|
||||
@@ -778,6 +779,20 @@ load_config (char * file)
|
||||
goto out;
|
||||
}
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
|
@ -37,7 +44,8 @@ index 30046a17..5f35c3d3 100644
|
|||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ if (store_ble(conf->blist_devnode, ".*", ORIGIN_NO_CONFIG)) {
|
||||
+ if (store_ble(conf->blist_devnode, strdup(".*"),
|
||||
+ ORIGIN_NO_CONFIG)) {
|
||||
+ condlog(0, "cannot store default no-config blacklist\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
@ -45,7 +53,7 @@ index 30046a17..5f35c3d3 100644
|
|||
|
||||
conf->processed_main_config = 1;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 933fe0d1..5f01c1fc 100644
|
||||
index ceecff2d..3368d8c9 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -9,6 +9,7 @@
|
||||
|
@ -54,8 +62,8 @@ index 933fe0d1..5f01c1fc 100644
|
|||
#define ORIGIN_CONFIG 1
|
||||
+#define ORIGIN_NO_CONFIG 2
|
||||
|
||||
enum devtypes {
|
||||
DEV_NONE,
|
||||
/*
|
||||
* In kernel, fast_io_fail == 0 means immediate failure on rport delete.
|
||||
diff --git a/multipath/multipath.rules b/multipath/multipath.rules
|
||||
index 9df11a95..0486bf70 100644
|
||||
--- a/multipath/multipath.rules
|
||||
|
@ -82,26 +90,17 @@ index 048a838d..8bd47a80 100644
|
|||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index 0b2ac814..6d57c7e8 100644
|
||||
index ba24983e..17434cef 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service
|
||||
Before=iscsi.service iscsid.service lvm2-activation-early.service
|
||||
Before=local-fs-pre.target blk-availability.service shutdown.target
|
||||
Before=local-fs-pre.target blk-availability.service
|
||||
After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service
|
||||
+ConditionPathExists=/etc/multipath.conf
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
ConditionKernelCommandLine=!nompath
|
||||
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
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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 <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 29 +++++++++++++++++++++--------
|
||||
1 file changed, 21 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 034752d9..c2abd301 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -89,16 +89,29 @@ TEST_CC_OPTION = $(shell \
|
||||
echo "$(2)"; \
|
||||
fi)
|
||||
|
||||
-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
|
||||
+ifndef RPM_OPT_FLAGS
|
||||
+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \
|
||||
+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
|
||||
+ $(STACKPROT) -grecord-gcc-switches \
|
||||
+ -fasynchronous-unwind-tables
|
||||
+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1)
|
||||
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
|
||||
+ endif
|
||||
+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-annobin-cc1 && echo 1),1)
|
||||
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1
|
||||
+ endif
|
||||
+else
|
||||
+ OPTFLAGS = $(RPM_OPT_FLAGS)
|
||||
+endif
|
||||
+OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \
|
||||
+ -Werror=implicit-int -Werror=implicit-function-declaration \
|
||||
+ $(WNOCLOBBERED) \
|
||||
+ -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
+ --param=ssp-buffer-size=4
|
||||
|
||||
-OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
- -Werror=implicit-function-declaration -Werror=format-security \
|
||||
- $(WNOCLOBBERED) \
|
||||
- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
- $(STACKPROT) --param=ssp-buffer-size=4
|
||||
-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2
|
||||
CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
-MMD -MP $(CFLAGS)
|
||||
BIN_CFLAGS = -fPIE -DPIE
|
||||
@@ -135,4 +148,4 @@ check_file = $(shell \
|
||||
|
||||
%.o: %.c
|
||||
@echo building $@ because of $?
|
||||
- $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
+ $(CC) $(CFLAGS) -c -o $@ $<
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|||
---
|
||||
libmultipath/config.c | 2 +
|
||||
multipath/Makefile | 5 +
|
||||
multipath/mpathconf | 556 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 135 ++++++++++
|
||||
4 files changed, 698 insertions(+)
|
||||
4 files changed, 697 insertions(+)
|
||||
create mode 100644 multipath/mpathconf
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 5f35c3d3..cee3bbb7 100644
|
||||
index b36778b0..26f8e050 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -897,6 +897,8 @@ int _init_config (const char *file, struct config *conf)
|
||||
@@ -781,6 +781,8 @@ load_config (char * file)
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
} else {
|
||||
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
|
@ -69,10 +69,10 @@ index b9bbb3cf..e720c7f6 100644
|
|||
$(RM) core *.o $(EXEC) *.gz
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
new file mode 100644
|
||||
index 00000000..c00d2555
|
||||
index 00000000..f34003c9
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -0,0 +1,556 @@
|
||||
@@ -0,0 +1,555 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
||||
|
@ -107,6 +107,11 @@ index 00000000..c00d2555
|
|||
+defaults {
|
||||
+ user_friendly_names yes
|
||||
+ find_multipaths yes
|
||||
+ enable_foreign \"^$\"
|
||||
+}
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+ property \"(SCSI_IDENT_|ID_WWN)\"
|
||||
+}"
|
||||
+
|
||||
+CONFIGFILE="/etc/multipath.conf"
|
||||
|
@ -124,8 +129,8 @@ index 00000000..c00d2555
|
|||
+ echo "Disable: --disable"
|
||||
+ echo "Only allow certain wwids (instead of enable): --allow <WWID>"
|
||||
+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
|
||||
+ echo "Set find_multipaths (Default y): --find_multipaths <yes|no|strict|greedy|smart>"
|
||||
+ echo "Set default property blacklist (Default n): --property_blacklist <y|n>"
|
||||
+ echo "Set find_multipaths (Default y): --find_multipaths <y|n>"
|
||||
+ echo "Set default property blacklist (Default y): --property_blacklist <y|n>"
|
||||
+ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>"
|
||||
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
|
@ -294,12 +299,8 @@ index 00000000..c00d2555
|
|||
+ 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'"
|
||||
+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
|
||||
+ echo "--find_multipaths must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then
|
||||
|
@ -310,7 +311,7 @@ index 00000000..c00d2555
|
|||
+ 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 [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
|
||||
+ SHOW_STATUS=1
|
||||
+ fi
|
||||
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
|
@ -385,50 +386,45 @@ index 00000000..c00d2555
|
|||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||
+ HAVE_DISABLE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=1
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"" ; then
|
||||
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||
+ HAVE_WWID_DISABLE=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_DEFAULTS" = "1" ]; then
|
||||
+ HAVE_FIND=`sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | sed -n 's/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*\([^[:blank:]]*\).*$/\1/p' | sed -n 1p`
|
||||
+ if [ "$HAVE_FIND" = "1" ]; then
|
||||
+ HAVE_FIND="yes"
|
||||
+ elif [ "$HAVE_FIND" = "0" ]; then
|
||||
+ HAVE_FIND="no"
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
|
||||
+ HAVE_FIND=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
|
||||
+ HAVE_FIND=0
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)" ; then
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
|
||||
+ HAVE_FRIENDLY=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(no\|0\)" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
|
||||
+ HAVE_FRIENDLY=0
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=0
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]][[:space:]]*\"\.\*\"" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
|
||||
+ HAVE_FOREIGN=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[: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
|
||||
+ HAVE_FOREIGN=2
|
||||
+ 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
|
||||
+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=1
|
||||
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=0
|
||||
+ fi
|
||||
+fi
|
||||
|
@ -439,10 +435,10 @@ index 00000000..c00d2555
|
|||
+ else
|
||||
+ echo "multipath is disabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FIND" ]; then
|
||||
+ echo "find_multipaths is no"
|
||||
+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
|
||||
+ echo "find_multipaths is disabled"
|
||||
+ else
|
||||
+ echo "find_multipaths is $HAVE_FIND"
|
||||
+ echo "find_multipaths is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
|
||||
+ echo "user_friendly_names is disabled"
|
||||
|
@ -455,10 +451,8 @@ index 00000000..c00d2555
|
|||
+ 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)"
|
||||
+ echo "enable_foreign is not set (all 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)"
|
||||
|
@ -503,14 +497,14 @@ index 00000000..c00d2555
|
|||
+
|
||||
+if [ "$ENABLE" = 2 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_WWID_DISABLE" ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||
+ wwid ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid[[:space:]][[:space:]]*\"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
|
||||
|
@ -524,7 +518,7 @@ index 00000000..c00d2555
|
|||
+ add_blacklist_exceptions
|
||||
+elif [ "$ENABLE" = 1 ]; then
|
||||
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+elif [ "$ENABLE" = 0 ]; then
|
||||
+ if [ -z "$HAVE_DISABLE" ]; then
|
||||
|
@ -532,25 +526,30 @@ index 00000000..c00d2555
|
|||
+ devnode ".*"
|
||||
+' $TMPFILE
|
||||
+ elif [ "$HAVE_DISABLE" = 0 ]; then
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode[[:space:]][[:space:]]*\"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -n "$FIND" ]; then
|
||||
+if [ "$FIND" = "n" ]; then
|
||||
+ if [ "$HAVE_FIND" = 1 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FIND" = "y" ]; then
|
||||
+ if [ -z "$HAVE_FIND" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ find_multipaths '"$FIND"'
|
||||
+ find_multipaths yes
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$FIND" != "$HAVE_FIND" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:blank:]]*find_multipaths[[:blank:]][[:blank:]]*[^[:blank:]]*/ find_multipaths '"$FIND"'/' $TMPFILE
|
||||
+ elif [ "$HAVE_FIND" = 0 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FRIENDLY" = "n" ]; then
|
||||
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]][[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FRIENDLY" = "y" ]; then
|
||||
|
@ -560,14 +559,14 @@ index 00000000..c00d2555
|
|||
+' $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
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$PROPERTY" = "n" ]; then
|
||||
+ if [ "$HAVE_PROPERTY" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]][[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$PROPERTY" = "y" ]; then
|
||||
|
@ -577,24 +576,24 @@ index 00000000..c00d2555
|
|||
+' $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
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
+if [ "$FOREIGN" = "y" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FOREIGN" = "y" ]; then
|
||||
+elif [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ -z "$HAVE_FOREIGN" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ enable_foreign ".*"
|
||||
+ enable_foreign "^$"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
|
@ -631,7 +630,7 @@ index 00000000..c00d2555
|
|||
+fi
|
||||
diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8
|
||||
new file mode 100644
|
||||
index 00000000..a14d831e
|
||||
index 00000000..b82961d6
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf.8
|
||||
@@ -0,0 +1,135 @@
|
||||
|
@ -675,9 +674,9 @@ index 00000000..a14d831e
|
|||
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
|
||||
+create a default file with
|
||||
+.B user_friendly_names
|
||||
+set and
|
||||
+and
|
||||
+.B find_multipaths
|
||||
+set to \fByes\fP. To disable these, use the
|
||||
+set. To disable these, use the
|
||||
+.B --user_friendly_names n
|
||||
+and
|
||||
+.B --find_multipaths n
|
||||
|
@ -714,13 +713,13 @@ index 00000000..a14d831e
|
|||
+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<value>\fP, this adds the line
|
||||
+.B find_multipaths <value>
|
||||
+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B find_multipaths yes
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. 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.
|
||||
+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 --property_blacklist \fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
|
@ -731,11 +730,11 @@ index 00000000..a14d831e
|
|||
+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 ".*"
|
||||
+If set to \fBn\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
|
||||
+defaults section. if set to \fBy\fP, this removes the line, if present. This
|
||||
+command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --outfile \fB<filename>\fP
|
||||
|
@ -770,3 +769,6 @@ index 00000000..a14d831e
|
|||
+.BR service (8),
|
||||
+.SH AUTHOR
|
||||
+Benjamin Marzinski <bmarzins@redhat.com>
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -14,38 +14,23 @@ multipathd.service
|
|||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 54 +++++++++++++++++++++++++++++++++--
|
||||
multipath/multipath.8 | 7 ++++-
|
||||
libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++
|
||||
libmultipath/wwids.h | 1 +
|
||||
multipath/main.c | 10 ++++++--
|
||||
multipath/multipath.8 | 7 +++++-
|
||||
multipathd/multipathd.service | 1 +
|
||||
3 files changed, 59 insertions(+), 3 deletions(-)
|
||||
5 files changed, 60 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)
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 28a2150d..fab6fc8f 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -454,3 +454,47 @@ int op ## _wwid(const char *wwid) \
|
||||
declare_failed_wwid_op(is_failed, false)
|
||||
declare_failed_wwid_op(mark_failed, true)
|
||||
declare_failed_wwid_op(unmark_failed, true)
|
||||
+
|
||||
+int remember_cmdline_wwid(void)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ char buf[LINE_MAX], *next, *ptr;
|
||||
|
@ -88,20 +73,50 @@ index 65ece830..748e7902 100644
|
|||
+ }
|
||||
+ 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[])
|
||||
diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
|
||||
index 0c6ee54d..e32a0b0e 100644
|
||||
--- a/libmultipath/wwids.h
|
||||
+++ b/libmultipath/wwids.h
|
||||
@@ -17,6 +17,7 @@ int remember_wwid(char *wwid);
|
||||
int check_wwids_file(char *wwid, int write_wwid);
|
||||
int remove_wwid(char *wwid);
|
||||
int replace_wwids(vector mp);
|
||||
+int remember_cmdline_wwid(void);
|
||||
|
||||
enum {
|
||||
WWID_IS_NOT_FAILED = 0,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index cf9d2a28..78822ee1 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -138,7 +138,7 @@ usage (char * progname)
|
||||
fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname);
|
||||
- fprintf (stderr, " %s [-v level] -W\n", progname);
|
||||
+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname);
|
||||
fprintf (stderr, " %s [-h|-t|-T]\n", progname);
|
||||
@@ -151,6 +151,8 @@ usage (char * progname)
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
+ " -A add devices from kernel command line mpath.wwids\n"
|
||||
+ " parameters to wwids file\n"
|
||||
" -c check if a device should be a path in a multipath device\n"
|
||||
" -C check if a multipath device has usable paths\n"
|
||||
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||
@@ -907,7 +909,7 @@ main (int argc, char *argv[])
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
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 ) {
|
||||
- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -915,6 +961,10 @@ main (int argc, char *argv[])
|
||||
@@ -977,6 +979,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
|
@ -113,7 +128,7 @@ index 65ece830..748e7902 100644
|
|||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 17df59f5..5ca75359 100644
|
||||
index 9cdd05a3..8befc45a 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
||||
|
@ -138,10 +153,10 @@ index 17df59f5..5ca75359 100644
|
|||
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
|
||||
index 17434cef..0fbcc46b 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -16,6 +16,7 @@ Type=notify
|
||||
@@ -15,6 +15,7 @@ Type=notify
|
||||
NotifyAccess=main
|
||||
LimitCORE=infinity
|
||||
ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
|
||||
|
@ -149,3 +164,6 @@ index 6d57c7e8..dfc1e962 100644
|
|||
ExecStart=/sbin/multipathd -d -s
|
||||
ExecReload=/sbin/multipathd reconfigure
|
||||
TasksMax=infinity
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 6 Nov 2017 21:39:28 -0600
|
||||
Subject: [PATCH] RH: warn on invalid regex instead of failing
|
||||
|
||||
multipath.conf used to allow "*" as a match everything regular expression,
|
||||
instead of requiring ".*". Instead of erroring when the old style
|
||||
regular expressions are used, it should print a warning and convert
|
||||
them.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 27 +++++++++++++++++++++------
|
||||
libmultipath/parser.c | 13 +++++++++++++
|
||||
libmultipath/parser.h | 1 +
|
||||
3 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 0e9ea387..184d4b22 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -103,6 +103,21 @@ set_str(vector strvec, void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+set_regex(vector strvec, void *ptr)
|
||||
+{
|
||||
+ char **str_ptr = (char **)ptr;
|
||||
+
|
||||
+ if (*str_ptr)
|
||||
+ FREE(*str_ptr);
|
||||
+ *str_ptr = set_regex_value(strvec);
|
||||
+
|
||||
+ if (!*str_ptr)
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
set_yes_no(vector strvec, void *ptr)
|
||||
{
|
||||
@@ -1504,7 +1519,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
- buff = set_value(strvec); \
|
||||
+ buff = set_regex_value(strvec); \
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1520,7 +1535,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
- buff = set_value(strvec); \
|
||||
+ buff = set_regex_value(strvec); \
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1623,16 +1638,16 @@ device_handler(struct config *conf, vector strvec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-declare_hw_handler(vendor, set_str)
|
||||
+declare_hw_handler(vendor, set_regex)
|
||||
declare_hw_snprint(vendor, print_str)
|
||||
|
||||
-declare_hw_handler(product, set_str)
|
||||
+declare_hw_handler(product, set_regex)
|
||||
declare_hw_snprint(product, print_str)
|
||||
|
||||
-declare_hw_handler(revision, set_str)
|
||||
+declare_hw_handler(revision, set_regex)
|
||||
declare_hw_snprint(revision, print_str)
|
||||
|
||||
-declare_hw_handler(bl_product, set_str)
|
||||
+declare_hw_handler(bl_product, set_regex)
|
||||
declare_hw_snprint(bl_product, print_str)
|
||||
|
||||
declare_hw_handler(hwhandler, set_str)
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index d478b177..a184511b 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -382,6 +382,19 @@ oom:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+void *
|
||||
+set_regex_value(vector strvec)
|
||||
+{
|
||||
+ char *buff = set_value(strvec);
|
||||
+
|
||||
+ if (buff && strcmp("*", buff) == 0) {
|
||||
+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\"");
|
||||
+ FREE(buff);
|
||||
+ return strdup(".*");
|
||||
+ }
|
||||
+ return buff;
|
||||
+}
|
||||
+
|
||||
/* non-recursive configuration stream handler */
|
||||
static int kw_level = 0;
|
||||
|
||||
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
|
||||
index 62906e98..b7917052 100644
|
||||
--- a/libmultipath/parser.h
|
||||
+++ b/libmultipath/parser.h
|
||||
@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level);
|
||||
extern void free_keywords(vector keywords);
|
||||
extern vector alloc_strvec(char *string);
|
||||
extern void *set_value(vector strvec);
|
||||
+extern void *set_regex_value(vector strvec);
|
||||
extern int process_file(struct config *conf, char *conf_file);
|
||||
extern struct keyword * find_keyword(vector keywords, vector v, char * name);
|
||||
int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index c27946c7..e0dd32ad 100644
|
||||
index e5ee6afe..52fe05b9 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -23,7 +23,7 @@
|
||||
@@ -22,7 +22,7 @@
|
||||
#define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF
|
||||
#define DEFAULT_VERBOSITY 2
|
||||
#define DEFAULT_REASSIGN_MAPS 0
|
||||
|
@ -24,3 +24,6 @@ index c27946c7..e0dd32ad 100644
|
|||
#define DEFAULT_FAST_IO_FAIL 5
|
||||
#define DEFAULT_DEV_LOSS_TMO 600
|
||||
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
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.
|
||||
Subject: [PATCH] RH: Fix nvme compilation warning
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
|
@ -24,3 +21,6 @@ index adb192b6..bfd10ef8 100644
|
|||
void argconfig_append_usage(const char *str);
|
||||
void argconfig_print_help(const char *program_desc,
|
||||
const struct argconfig_commandline_options *options);
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -82,3 +82,6 @@ index b5c7873d..e139360c 100644
|
|||
|
||||
switch (rc) {
|
||||
case NVME_ANA_OPTIMIZED:
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 8 Jun 2020 14:27:51 -0500
|
||||
Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions
|
||||
|
||||
_blacklist_exceptions() and _blacklist_exceptions_device() are exactly
|
||||
the same as _blacklist() and _blacklist_device(), so remove them, and
|
||||
give the remaining functions to a more general name.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 62 ++++++++++------------------------------
|
||||
1 file changed, 15 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index d9691b17..04d3adb9 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
-_blacklist_exceptions (vector elist, const char * str)
|
||||
-{
|
||||
- int i;
|
||||
- struct blentry * ele;
|
||||
-
|
||||
- vector_foreach_slot (elist, ele, i) {
|
||||
- if (!regexec(&ele->regex, str, 0, NULL, 0))
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-_blacklist (vector blist, const char * str)
|
||||
+static int
|
||||
+match_reglist (vector blist, const char * str)
|
||||
{
|
||||
int i;
|
||||
struct blentry * ble;
|
||||
@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
-_blacklist_exceptions_device(const struct _vector *elist, const char * vendor,
|
||||
- const char * product)
|
||||
-{
|
||||
- int i;
|
||||
- struct blentry_device * ble;
|
||||
-
|
||||
- vector_foreach_slot (elist, ble, i) {
|
||||
- if (!ble->vendor && !ble->product)
|
||||
- continue;
|
||||
- if ((!ble->vendor ||
|
||||
- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) &&
|
||||
- (!ble->product ||
|
||||
- !regexec(&ble->product_reg, product, 0, NULL, 0)))
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-_blacklist_device (const struct _vector *blist, const char * vendor,
|
||||
- const char * product)
|
||||
+static int
|
||||
+match_reglist_device (const struct _vector *blist, const char * vendor,
|
||||
+ const char * product)
|
||||
{
|
||||
int i;
|
||||
struct blentry_device * ble;
|
||||
@@ -294,9 +262,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product,
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (vendor && product) {
|
||||
- if (_blacklist_exceptions_device(elist, vendor, product))
|
||||
+ if (match_reglist_device(elist, vendor, product))
|
||||
r = MATCH_DEVICE_BLIST_EXCEPT;
|
||||
- else if (_blacklist_device(blist, vendor, product))
|
||||
+ else if (match_reglist_device(blist, vendor, product))
|
||||
r = MATCH_DEVICE_BLIST;
|
||||
}
|
||||
|
||||
@@ -310,9 +278,9 @@ filter_devnode (vector blist, vector elist, char * dev)
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (dev) {
|
||||
- if (_blacklist_exceptions(elist, dev))
|
||||
+ if (match_reglist(elist, dev))
|
||||
r = MATCH_DEVNODE_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, dev))
|
||||
+ else if (match_reglist(blist, dev))
|
||||
r = MATCH_DEVNODE_BLIST;
|
||||
}
|
||||
|
||||
@@ -326,9 +294,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev)
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (wwid) {
|
||||
- if (_blacklist_exceptions(elist, wwid))
|
||||
+ if (match_reglist(elist, wwid))
|
||||
r = MATCH_WWID_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, wwid))
|
||||
+ else if (match_reglist(blist, wwid))
|
||||
r = MATCH_WWID_BLIST;
|
||||
}
|
||||
|
||||
@@ -345,9 +313,9 @@ filter_protocol(vector blist, vector elist, struct path * pp)
|
||||
if (pp) {
|
||||
snprint_path_protocol(buf, sizeof(buf), pp);
|
||||
|
||||
- if (_blacklist_exceptions(elist, buf))
|
||||
+ if (match_reglist(elist, buf))
|
||||
r = MATCH_PROTOCOL_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, buf))
|
||||
+ else if (match_reglist(blist, buf))
|
||||
r = MATCH_PROTOCOL_BLIST;
|
||||
}
|
||||
|
||||
@@ -417,11 +385,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
if (check_missing_prop && !strcmp(env, uid_attribute))
|
||||
uid_attr_seen = true;
|
||||
|
||||
- if (_blacklist_exceptions(conf->elist_property, env)) {
|
||||
+ if (match_reglist(conf->elist_property, env)) {
|
||||
r = MATCH_PROPERTY_BLIST_EXCEPT;
|
||||
break;
|
||||
}
|
||||
- if (_blacklist(conf->blist_property, env)) {
|
||||
+ if (match_reglist(conf->blist_property, env)) {
|
||||
r = MATCH_PROPERTY_BLIST;
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 8 Jun 2020 20:23:56 -0500
|
||||
Subject: [PATCH] libmultipath: fix parser issue with comments in strings
|
||||
|
||||
If a quoted string starts with '#' or '!', the parser will stop
|
||||
parsing the line, thinking that it's a comment. It should only
|
||||
be checking for comments outside of quoted strings. Fixed this and
|
||||
added unit tests to verify it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/parser.c | 4 +++-
|
||||
tests/parser.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 45 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index a184511b..a7285a35 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -300,8 +300,10 @@ alloc_strvec(char *string)
|
||||
(isspace((int) *cp) || !isascii((int) *cp)))
|
||||
&& *cp != '\0')
|
||||
cp++;
|
||||
- if (*cp == '\0' || *cp == '!' || *cp == '#')
|
||||
+ if (*cp == '\0' ||
|
||||
+ (!in_string && (*cp == '!' || *cp == '#'))) {
|
||||
return strvec;
|
||||
+ }
|
||||
}
|
||||
out:
|
||||
vector_free(strvec);
|
||||
diff --git a/tests/parser.c b/tests/parser.c
|
||||
index 29859dac..5772391e 100644
|
||||
--- a/tests/parser.c
|
||||
+++ b/tests/parser.c
|
||||
@@ -440,6 +440,46 @@ static void test18(void **state)
|
||||
free_strvec(v);
|
||||
}
|
||||
|
||||
+static void test19(void **state)
|
||||
+{
|
||||
+#define QUOTED19 "!value"
|
||||
+ vector v = alloc_strvec("key \"" QUOTED19 "\"");
|
||||
+ char *val;
|
||||
+
|
||||
+ assert_int_equal(VECTOR_SIZE(v), 4);
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 0), "key");
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 1)));
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19);
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 3)));
|
||||
+ assert_int_equal(validate_config_strvec(v, test_file), 0);
|
||||
+
|
||||
+ val = set_value(v);
|
||||
+ assert_string_equal(val, QUOTED19);
|
||||
+
|
||||
+ free(val);
|
||||
+ free_strvec(v);
|
||||
+}
|
||||
+
|
||||
+static void test20(void **state)
|
||||
+{
|
||||
+#define QUOTED20 "#value"
|
||||
+ vector v = alloc_strvec("key \"" QUOTED20 "\"");
|
||||
+ char *val;
|
||||
+
|
||||
+ assert_int_equal(VECTOR_SIZE(v), 4);
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 0), "key");
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 1)));
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20);
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 3)));
|
||||
+ assert_int_equal(validate_config_strvec(v, test_file), 0);
|
||||
+
|
||||
+ val = set_value(v);
|
||||
+ assert_string_equal(val, QUOTED20);
|
||||
+
|
||||
+ free(val);
|
||||
+ free_strvec(v);
|
||||
+}
|
||||
+
|
||||
int test_config_parser(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
@@ -461,6 +501,8 @@ int test_config_parser(void)
|
||||
cmocka_unit_test(test16),
|
||||
cmocka_unit_test(test17),
|
||||
cmocka_unit_test(test18),
|
||||
+ cmocka_unit_test(test19),
|
||||
+ cmocka_unit_test(test20),
|
||||
};
|
||||
return cmocka_run_group_tests(tests, setup, teardown);
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,435 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 8 Jun 2020 13:40:16 -0500
|
||||
Subject: [PATCH] libmultipath: invert regexes that start with exclamation
|
||||
point
|
||||
|
||||
The number of devices that multipath needs to blacklist keeps growing,
|
||||
and the udev rules already have
|
||||
|
||||
KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath"
|
||||
|
||||
so they only work correctly with these device types. Instead of
|
||||
individually blacklisting every type of device that can't be
|
||||
multipathed, multipath's default blacklist should work like the udev
|
||||
rule, and blacklist all devices that aren't scsi, dasd, or nvme.
|
||||
Unfortunately, the c regex library doesn't support negative lookahead.
|
||||
Instead, multipath should treat "!" at the beginning of
|
||||
blacklist/exceptions regexes as inverse matching the rest of the regex.
|
||||
If users need to match a literal '!' as the first character of their
|
||||
regex, they can use "\!" instead. This allows multipath to change the
|
||||
default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])".
|
||||
|
||||
Extra tests have been added to the blacklist unit tests to verify the
|
||||
inverse matching code and the new default blacklist.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 41 +++++++++-----
|
||||
libmultipath/blacklist.h | 3 +
|
||||
multipath/multipath.conf.5 | 17 ++++--
|
||||
tests/blacklist.c | 110 +++++++++++++++++++++++++++++++++++++
|
||||
tests/test-lib.c | 2 +-
|
||||
5 files changed, 155 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index 04d3adb9..0c58aa32 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -15,9 +15,24 @@
|
||||
#include "structs_vec.h"
|
||||
#include "print.h"
|
||||
|
||||
+char *check_invert(char *str, bool *invert)
|
||||
+{
|
||||
+ if (str[0] == '!') {
|
||||
+ *invert = true;
|
||||
+ return str + 1;
|
||||
+ }
|
||||
+ if (str[0] == '\\' && str[1] == '!') {
|
||||
+ *invert = false;
|
||||
+ return str + 1;
|
||||
+ }
|
||||
+ *invert = false;
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
int store_ble(vector blist, char * str, int origin)
|
||||
{
|
||||
struct blentry * ble;
|
||||
+ char *regex_str;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin)
|
||||
if (!ble)
|
||||
goto out;
|
||||
|
||||
- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB))
|
||||
+ regex_str = check_invert(str, &ble->invert);
|
||||
+ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB))
|
||||
goto out1;
|
||||
|
||||
if (!vector_alloc_slot(blist))
|
||||
@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist)
|
||||
int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
{
|
||||
struct blentry_device * ble;
|
||||
+ char *regex_str;
|
||||
|
||||
if (!blist)
|
||||
return 1;
|
||||
@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
return 1;
|
||||
|
||||
if (vendor) {
|
||||
- if (regcomp(&ble->vendor_reg, vendor,
|
||||
+ regex_str = check_invert(vendor, &ble->vendor_invert);
|
||||
+ if (regcomp(&ble->vendor_reg, regex_str,
|
||||
REG_EXTENDED|REG_NOSUB)) {
|
||||
FREE(vendor);
|
||||
if (product)
|
||||
@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
ble->vendor = vendor;
|
||||
}
|
||||
if (product) {
|
||||
- if (regcomp(&ble->product_reg, product,
|
||||
+ regex_str = check_invert(product, &ble->product_invert);
|
||||
+ if (regcomp(&ble->product_reg, regex_str,
|
||||
REG_EXTENDED|REG_NOSUB)) {
|
||||
FREE(product);
|
||||
if (vendor) {
|
||||
@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str)
|
||||
struct blentry * ble;
|
||||
|
||||
vector_foreach_slot (blist, ble, i) {
|
||||
- if (!regexec(&ble->regex, str, 0, NULL, 0))
|
||||
+ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor,
|
||||
if (!ble->vendor && !ble->product)
|
||||
continue;
|
||||
if ((!ble->vendor ||
|
||||
- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) &&
|
||||
+ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) ==
|
||||
+ ble->vendor_invert) &&
|
||||
(!ble->product ||
|
||||
- !regexec(&ble->product_reg, product, 0, NULL, 0)))
|
||||
+ !!regexec(&ble->product_reg, product, 0, NULL, 0) ==
|
||||
+ ble->product_invert))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf)
|
||||
char * str;
|
||||
int i;
|
||||
|
||||
- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]");
|
||||
- if (!str)
|
||||
- return 1;
|
||||
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
- str = STRDUP("^(td|hd|vd)[a-z]");
|
||||
+ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])");
|
||||
if (!str)
|
||||
return 1;
|
||||
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h
|
||||
index 2d721f60..4305857d 100644
|
||||
--- a/libmultipath/blacklist.h
|
||||
+++ b/libmultipath/blacklist.h
|
||||
@@ -20,6 +20,7 @@
|
||||
struct blentry {
|
||||
char * str;
|
||||
regex_t regex;
|
||||
+ bool invert;
|
||||
int origin;
|
||||
};
|
||||
|
||||
@@ -28,6 +29,8 @@ struct blentry_device {
|
||||
char * product;
|
||||
regex_t vendor_reg;
|
||||
regex_t product_reg;
|
||||
+ bool vendor_invert;
|
||||
+ bool product_invert;
|
||||
int origin;
|
||||
};
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 3455b1cc..6dc26f10 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1248,6 +1248,16 @@ being handled by multipath-tools.
|
||||
.LP
|
||||
.
|
||||
.
|
||||
+In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a
|
||||
+quoted value with an exclamation mark \fB"!"\fR will invert the matching
|
||||
+of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will
|
||||
+match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark
|
||||
+can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a
|
||||
+regular expression. \fBNote:\fR The exclamation mark must be inside quotes,
|
||||
+otherwise it will be treated as starting a comment.
|
||||
+.LP
|
||||
+.
|
||||
+.
|
||||
The \fIblacklist_exceptions\fR section is used to revert the actions of the
|
||||
\fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which
|
||||
would normally be excluded via the \fIblacklist\fR section. A common usage is
|
||||
@@ -1264,10 +1274,9 @@ unless explicitly stated.
|
||||
Regular expression matching the device nodes to be excluded/included.
|
||||
.RS
|
||||
.PP
|
||||
-The default \fIblacklist\fR consists of the regular expressions
|
||||
-"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and
|
||||
-"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other
|
||||
-device types to be excluded from multipath handling by default.
|
||||
+The default \fIblacklist\fR consists of the regular expression
|
||||
+\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other
|
||||
+than scsi, dasd, and nvme to be excluded from multipath handling by default.
|
||||
.RE
|
||||
.TP
|
||||
.B wwid
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index cc8a9a4a..d20e97af 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry)
|
||||
return *(const char **)list_entry;
|
||||
}
|
||||
|
||||
+vector elist_property_default;
|
||||
+vector blist_devnode_default;
|
||||
vector blist_devnode_sdb;
|
||||
+vector blist_devnode_sdb_inv;
|
||||
vector blist_all;
|
||||
vector blist_device_foo_bar;
|
||||
+vector blist_device_foo_inv_bar;
|
||||
+vector blist_device_foo_bar_inv;
|
||||
vector blist_device_all;
|
||||
vector blist_wwid_xyzzy;
|
||||
+vector blist_wwid_xyzzy_inv;
|
||||
vector blist_protocol_fcp;
|
||||
+vector blist_protocol_fcp_inv;
|
||||
vector blist_property_wwn;
|
||||
+vector blist_property_wwn_inv;
|
||||
|
||||
static int setup(void **state)
|
||||
{
|
||||
+ struct config conf;
|
||||
+
|
||||
+ memset(&conf, 0, sizeof(conf));
|
||||
+ conf.blist_devnode = vector_alloc();
|
||||
+ if (!conf.blist_devnode)
|
||||
+ return -1;
|
||||
+ conf.elist_property = vector_alloc();
|
||||
+ if (!conf.elist_property)
|
||||
+ return -1;
|
||||
+ if (setup_default_blist(&conf) != 0)
|
||||
+ return -1;
|
||||
+ elist_property_default = conf.elist_property;
|
||||
+ blist_devnode_default = conf.blist_devnode;
|
||||
+
|
||||
blist_devnode_sdb = vector_alloc();
|
||||
if (!blist_devnode_sdb ||
|
||||
store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_devnode_sdb_inv = vector_alloc();
|
||||
+ if (!blist_devnode_sdb_inv ||
|
||||
+ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_all = vector_alloc();
|
||||
if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG))
|
||||
@@ -84,6 +110,18 @@ static int setup(void **state)
|
||||
set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"),
|
||||
ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_device_foo_inv_bar = vector_alloc();
|
||||
+ if (!blist_device_foo_inv_bar ||
|
||||
+ alloc_ble_device(blist_device_foo_inv_bar) ||
|
||||
+ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"),
|
||||
+ strdup("bar"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
+ blist_device_foo_bar_inv = vector_alloc();
|
||||
+ if (!blist_device_foo_bar_inv ||
|
||||
+ alloc_ble_device(blist_device_foo_bar_inv) ||
|
||||
+ set_ble_device(blist_device_foo_bar_inv, strdup("foo"),
|
||||
+ strdup("!bar"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_device_all = vector_alloc();
|
||||
if (!blist_device_all || alloc_ble_device(blist_device_all) ||
|
||||
@@ -95,29 +133,50 @@ static int setup(void **state)
|
||||
if (!blist_wwid_xyzzy ||
|
||||
store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_wwid_xyzzy_inv = vector_alloc();
|
||||
+ if (!blist_wwid_xyzzy_inv ||
|
||||
+ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_protocol_fcp = vector_alloc();
|
||||
if (!blist_protocol_fcp ||
|
||||
store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_protocol_fcp_inv = vector_alloc();
|
||||
+ if (!blist_protocol_fcp_inv ||
|
||||
+ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"),
|
||||
+ ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_property_wwn = vector_alloc();
|
||||
if (!blist_property_wwn ||
|
||||
store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_property_wwn_inv = vector_alloc();
|
||||
+ if (!blist_property_wwn_inv ||
|
||||
+ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void **state)
|
||||
{
|
||||
+ free_blacklist(elist_property_default);
|
||||
+ free_blacklist(blist_devnode_default);
|
||||
free_blacklist(blist_devnode_sdb);
|
||||
+ free_blacklist(blist_devnode_sdb_inv);
|
||||
free_blacklist(blist_all);
|
||||
free_blacklist_device(blist_device_foo_bar);
|
||||
+ free_blacklist_device(blist_device_foo_inv_bar);
|
||||
+ free_blacklist_device(blist_device_foo_bar_inv);
|
||||
free_blacklist_device(blist_device_all);
|
||||
free_blacklist(blist_wwid_xyzzy);
|
||||
+ free_blacklist(blist_wwid_xyzzy_inv);
|
||||
free_blacklist(blist_protocol_fcp);
|
||||
+ free_blacklist(blist_protocol_fcp_inv);
|
||||
free_blacklist(blist_property_wwn);
|
||||
+ free_blacklist(blist_property_wwn_inv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: device node name blacklisted\n");
|
||||
assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"),
|
||||
MATCH_DEVNODE_BLIST);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdc: device node name blacklisted\n");
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"),
|
||||
+ MATCH_DEVNODE_BLIST);
|
||||
}
|
||||
|
||||
static void test_devnode_whitelist(void **state)
|
||||
@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state)
|
||||
MATCH_NOTHING);
|
||||
}
|
||||
|
||||
+static void test_devnode_default(void **state)
|
||||
+{
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "hda: device node name blacklisted\n");
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"),
|
||||
+ MATCH_DEVNODE_BLIST);
|
||||
+}
|
||||
+
|
||||
static void test_device_blacklist(void **state)
|
||||
{
|
||||
expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n");
|
||||
assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo",
|
||||
"bar", "sdb"),
|
||||
MATCH_DEVICE_BLIST);
|
||||
+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n");
|
||||
+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_DEVICE_BLIST);
|
||||
+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n");
|
||||
+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo",
|
||||
+ "baz", "sdb"),
|
||||
+ MATCH_DEVICE_BLIST);
|
||||
}
|
||||
|
||||
static void test_device_whitelist(void **state)
|
||||
@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: wwid xyzzy blacklisted\n");
|
||||
assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"),
|
||||
MATCH_WWID_BLIST);
|
||||
+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy",
|
||||
+ "sdb"), MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdb: wwid plugh blacklisted\n");
|
||||
+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh",
|
||||
+ "sdb"), MATCH_WWID_BLIST);
|
||||
}
|
||||
|
||||
static void test_wwid_whitelist(void **state)
|
||||
@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n");
|
||||
assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp),
|
||||
MATCH_PROTOCOL_BLIST);
|
||||
+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp),
|
||||
+ MATCH_NOTHING);
|
||||
+ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA;
|
||||
+ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n");
|
||||
+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp),
|
||||
+ MATCH_PROTOCOL_BLIST);
|
||||
}
|
||||
|
||||
static void test_protocol_whitelist(void **state)
|
||||
@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state)
|
||||
static void test_property_blacklist(void **state)
|
||||
{
|
||||
static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } };
|
||||
+ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } };
|
||||
conf.blist_property = blist_property_wwn;
|
||||
expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
MATCH_PROPERTY_BLIST);
|
||||
+ conf.blist_property = blist_property_wwn_inv;
|
||||
+ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n");
|
||||
+ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
+ MATCH_PROPERTY_BLIST);
|
||||
+ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"),
|
||||
+ MATCH_NOTHING);
|
||||
}
|
||||
|
||||
/* the property check works different in that you check all the property
|
||||
@@ -482,6 +591,7 @@ int test_blacklist(void)
|
||||
cmocka_unit_test(test_devnode_blacklist),
|
||||
cmocka_unit_test(test_devnode_whitelist),
|
||||
cmocka_unit_test(test_devnode_missing),
|
||||
+ cmocka_unit_test(test_devnode_default),
|
||||
cmocka_unit_test(test_device_blacklist),
|
||||
cmocka_unit_test(test_device_whitelist),
|
||||
cmocka_unit_test(test_device_missing),
|
||||
diff --git a/tests/test-lib.c b/tests/test-lib.c
|
||||
index 59275163..08ff2d8d 100644
|
||||
--- a/tests/test-lib.c
|
||||
+++ b/tests/test-lib.c
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "test-lib.h"
|
||||
|
||||
const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO);
|
||||
-const char default_devnode[] = "sdTEST";
|
||||
+const char default_devnode[] = "sdxTEST";
|
||||
const char default_wwid[] = "TEST-WWID";
|
||||
/* default_wwid should be a substring of default_wwid_1! */
|
||||
const char default_wwid_1[] = "TEST-WWID-1";
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 23 Jun 2020 22:17:31 -0500
|
||||
Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic
|
||||
|
||||
dm_get_map() and dm_get_status() now use symbolic return codes. They
|
||||
also differentiate between failing to get information from device-mapper
|
||||
and not finding the requested device. These symboilc return codes are
|
||||
also used by update_multipath_* functions.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 51 +++++++++++++++++++++++++-------------
|
||||
libmultipath/devmapper.h | 6 +++++
|
||||
libmultipath/structs_vec.c | 45 +++++++++++++++++++--------------
|
||||
multipathd/main.c | 12 ++++-----
|
||||
4 files changed, 72 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 13a1cf53..f6204e5f 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -525,36 +525,43 @@ int dm_map_present(const char * str)
|
||||
|
||||
int dm_get_map(const char *name, unsigned long long *size, char *outparams)
|
||||
{
|
||||
- int r = 1;
|
||||
+ int r = DMP_ERR;
|
||||
struct dm_task *dmt;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params = NULL;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt))
|
||||
+ errno = 0;
|
||||
+ if (!dm_task_run(dmt)) {
|
||||
+ if (dm_task_get_errno(dmt) == ENXIO)
|
||||
+ r = DMP_NOT_FOUND;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
+ r = DMP_NOT_FOUND;
|
||||
/* Fetch 1st target */
|
||||
- dm_get_next_target(dmt, NULL, &start, &length,
|
||||
- &target_type, ¶ms);
|
||||
+ if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
+ &target_type, ¶ms) != NULL)
|
||||
+ /* more than one target */
|
||||
+ goto out;
|
||||
|
||||
if (size)
|
||||
*size = length;
|
||||
|
||||
if (!outparams) {
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
goto out;
|
||||
}
|
||||
if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
@@ -628,35 +635,45 @@ is_mpath_part(const char *part_name, const char *map_name)
|
||||
|
||||
int dm_get_status(const char *name, char *outstatus)
|
||||
{
|
||||
- int r = 1;
|
||||
+ int r = DMP_ERR;
|
||||
struct dm_task *dmt;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *status = NULL;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt))
|
||||
+ errno = 0;
|
||||
+ if (!dm_task_run(dmt)) {
|
||||
+ if (dm_task_get_errno(dmt) == ENXIO)
|
||||
+ r = DMP_NOT_FOUND;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
+ r = DMP_NOT_FOUND;
|
||||
/* Fetch 1st target */
|
||||
- dm_get_next_target(dmt, NULL, &start, &length,
|
||||
- &target_type, &status);
|
||||
+ if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
+ &target_type, &status) != NULL)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!target_type || strcmp(target_type, TGT_MPATH) != 0)
|
||||
+ goto out;
|
||||
+
|
||||
if (!status) {
|
||||
condlog(2, "get null status.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE)
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
out:
|
||||
- if (r)
|
||||
+ if (r != DMP_OK)
|
||||
condlog(0, "%s: error getting map status string", name);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
@@ -866,7 +883,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||
return 1;
|
||||
|
||||
if (need_suspend &&
|
||||
- !dm_get_map(mapname, &mapsize, params) &&
|
||||
+ dm_get_map(mapname, &mapsize, params) == DMP_OK &&
|
||||
strstr(params, "queue_if_no_path")) {
|
||||
if (!dm_queue_if_no_path(mapname, 0))
|
||||
queue_if_no_path = 1;
|
||||
@@ -1075,7 +1092,7 @@ struct multipath *dm_get_multipath(const char *name)
|
||||
if (!mpp->alias)
|
||||
goto out;
|
||||
|
||||
- if (dm_get_map(name, &mpp->size, NULL))
|
||||
+ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK)
|
||||
goto out;
|
||||
|
||||
dm_get_uuid(name, mpp->wwid, WWID_SIZE);
|
||||
@@ -1259,7 +1276,7 @@ do_foreach_partmaps (const char * mapname,
|
||||
/*
|
||||
* and we can fetch the map table from the kernel
|
||||
*/
|
||||
- !dm_get_map(names->name, &size, ¶ms[0]) &&
|
||||
+ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK &&
|
||||
|
||||
/*
|
||||
* and the table maps over the multipath map
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 7557a86b..adb55000 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -27,6 +27,12 @@
|
||||
#define UUID_PREFIX "mpath-"
|
||||
#define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1)
|
||||
|
||||
+enum {
|
||||
+ DMP_ERR,
|
||||
+ DMP_OK,
|
||||
+ DMP_NOT_FOUND,
|
||||
+};
|
||||
+
|
||||
void dm_init(int verbosity);
|
||||
void libmp_dm_init(void);
|
||||
void libmp_udev_set_sync_support(int on);
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 077f2e42..8137ea21 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp)
|
||||
int
|
||||
update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
{
|
||||
+ int r = DMP_ERR;
|
||||
char params[PARAMS_SIZE] = {0};
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
- if (dm_get_map(mpp->alias, &mpp->size, params)) {
|
||||
- condlog(3, "%s: cannot get map", mpp->alias);
|
||||
- return 1;
|
||||
+ r = dm_get_map(mpp->alias, &mpp->size, params);
|
||||
+ if (r != DMP_OK) {
|
||||
+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present");
|
||||
+ return r;
|
||||
}
|
||||
|
||||
if (disassemble_map(pathvec, params, mpp, is_daemon)) {
|
||||
condlog(3, "%s: cannot disassemble map", mpp->alias);
|
||||
- return 1;
|
||||
+ return DMP_ERR;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
int
|
||||
update_multipath_status (struct multipath *mpp)
|
||||
{
|
||||
+ int r = DMP_ERR;
|
||||
char status[PARAMS_SIZE] = {0};
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
- if (dm_get_status(mpp->alias, status)) {
|
||||
- condlog(3, "%s: cannot get status", mpp->alias);
|
||||
- return 1;
|
||||
+ r = dm_get_status(mpp->alias, status);
|
||||
+ if (r != DMP_OK) {
|
||||
+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present");
|
||||
+ return r;
|
||||
}
|
||||
|
||||
if (disassemble_status(status, mpp)) {
|
||||
condlog(3, "%s: cannot disassemble status", mpp->alias);
|
||||
- return 1;
|
||||
+ return DMP_ERR;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
void sync_paths(struct multipath *mpp, vector pathvec)
|
||||
@@ -264,10 +268,10 @@ int
|
||||
update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
{
|
||||
struct pathgroup *pgp;
|
||||
- int i;
|
||||
+ int i, r = DMP_ERR;
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
update_mpp_paths(mpp, pathvec);
|
||||
condlog(4, "%s: %s", mpp->alias, __FUNCTION__);
|
||||
@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
free_pgvec(mpp->pg, KEEP_PATHS);
|
||||
mpp->pg = NULL;
|
||||
|
||||
- if (update_multipath_table(mpp, pathvec, is_daemon))
|
||||
- return 1;
|
||||
+ r = update_multipath_table(mpp, pathvec, is_daemon);
|
||||
+ if (r != DMP_OK)
|
||||
+ return r;
|
||||
+
|
||||
sync_paths(mpp, pathvec);
|
||||
|
||||
- if (update_multipath_status(mpp))
|
||||
- return 1;
|
||||
+ r = update_multipath_status(mpp);
|
||||
+ if (r != DMP_OK)
|
||||
+ return r;
|
||||
|
||||
vector_foreach_slot(mpp->pg, pgp, i)
|
||||
if (pgp->paths)
|
||||
path_group_prio_update(pgp);
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
static void enter_recovery_mode(struct multipath *mpp)
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 6b7db2c0..e3427d3d 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -414,7 +414,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (update_multipath_strings(mpp, vecs->pathvec, 1)) {
|
||||
+ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
condlog(0, "%s: failed to setup multipath", mpp->alias);
|
||||
goto out;
|
||||
}
|
||||
@@ -553,9 +553,9 @@ add_map_without_path (struct vectors *vecs, const char *alias)
|
||||
mpp->mpe = find_mpe(conf->mptable, mpp->wwid);
|
||||
put_multipath_config(conf);
|
||||
|
||||
- if (update_multipath_table(mpp, vecs->pathvec, 1))
|
||||
+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK)
|
||||
goto out;
|
||||
- if (update_multipath_status(mpp))
|
||||
+ if (update_multipath_status(mpp) != DMP_OK)
|
||||
goto out;
|
||||
|
||||
if (!vector_alloc_slot(vecs->mpvec))
|
||||
@@ -1346,8 +1346,8 @@ map_discovery (struct vectors * vecs)
|
||||
return 1;
|
||||
|
||||
vector_foreach_slot (vecs->mpvec, mpp, i)
|
||||
- if (update_multipath_table(mpp, vecs->pathvec, 1) ||
|
||||
- update_multipath_status(mpp)) {
|
||||
+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK ||
|
||||
+ update_multipath_status(mpp) != DMP_OK) {
|
||||
remove_map(mpp, vecs, 1);
|
||||
i--;
|
||||
}
|
||||
@@ -2087,7 +2087,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* Synchronize with kernel state
|
||||
*/
|
||||
- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) {
|
||||
+ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
condlog(1, "%s: Could not synchronize with kernel state",
|
||||
pp->dev);
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 11 Jun 2020 15:41:18 -0500
|
||||
Subject: [PATCH] multipathd: fix check_path errors with removed map
|
||||
|
||||
If a multipath device is removed during, or immediately before the call
|
||||
to check_path(), multipathd can behave incorrectly. A missing multpath
|
||||
device will cause update_multipath_strings() to fail, setting
|
||||
pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause
|
||||
reinstate_path() to be called, which will also fail. This will trigger
|
||||
a reload, restoring the recently removed device.
|
||||
|
||||
If update_multipath_strings() fails because there is no multipath
|
||||
device, check_path should just quit, since the remove dmevent and uevent
|
||||
are likely already queued up. Also, I don't see any reason to reload the
|
||||
multipath device if reinstate fails. This code was added by
|
||||
fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate
|
||||
could fail if the path was disabled. Looking through the current kernel
|
||||
code, I can't see any reason why a reinstate would fail, where a reload
|
||||
would help. If the path was missing from the multipath device,
|
||||
update_multipath_strings() would already catch that, and quit
|
||||
check_path() early, which make more sense to me than reloading does.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 44 +++++++++++++++++++-------------------------
|
||||
1 file changed, 19 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index e3427d3d..1d9ce7f7 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1611,22 +1611,18 @@ fail_path (struct path * pp, int del_active)
|
||||
/*
|
||||
* caller must have locked the path list before calling that function
|
||||
*/
|
||||
-static int
|
||||
+static void
|
||||
reinstate_path (struct path * pp)
|
||||
{
|
||||
- int ret = 0;
|
||||
-
|
||||
if (!pp->mpp)
|
||||
- return 0;
|
||||
+ return;
|
||||
|
||||
- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) {
|
||||
+ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t))
|
||||
condlog(0, "%s: reinstate failed", pp->dev_t);
|
||||
- ret = 1;
|
||||
- } else {
|
||||
+ else {
|
||||
condlog(2, "%s: reinstated", pp->dev_t);
|
||||
update_queue_mode_add_path(pp->mpp);
|
||||
}
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2087,9 +2083,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* Synchronize with kernel state
|
||||
*/
|
||||
- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
- condlog(1, "%s: Could not synchronize with kernel state",
|
||||
- pp->dev);
|
||||
+ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1);
|
||||
+ if (ret != DMP_OK) {
|
||||
+ if (ret == DMP_NOT_FOUND) {
|
||||
+ /* multipath device missing. Likely removed */
|
||||
+ condlog(1, "%s: multipath device '%s' not found",
|
||||
+ pp->dev, pp->mpp->alias);
|
||||
+ return 0;
|
||||
+ } else
|
||||
+ condlog(1, "%s: Couldn't synchronize with kernel state",
|
||||
+ pp->dev);
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
}
|
||||
/* if update_multipath_strings orphaned the path, quit early */
|
||||
@@ -2179,12 +2182,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* reinstate this path
|
||||
*/
|
||||
- if (!disable_reinstate && reinstate_path(pp)) {
|
||||
- condlog(3, "%s: reload map", pp->dev);
|
||||
- ev_add_path(pp, vecs, 1);
|
||||
- pp->tick = 1;
|
||||
- return 0;
|
||||
- }
|
||||
+ if (!disable_reinstate)
|
||||
+ reinstate_path(pp);
|
||||
new_path_up = 1;
|
||||
|
||||
if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
|
||||
@@ -2200,15 +2199,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
else if (newstate == PATH_UP || newstate == PATH_GHOST) {
|
||||
if ((pp->dmstate == PSTATE_FAILED ||
|
||||
pp->dmstate == PSTATE_UNDEF) &&
|
||||
- !disable_reinstate) {
|
||||
+ !disable_reinstate)
|
||||
/* Clear IO errors */
|
||||
- if (reinstate_path(pp)) {
|
||||
- condlog(3, "%s: reload map", pp->dev);
|
||||
- ev_add_path(pp, vecs, 1);
|
||||
- pp->tick = 1;
|
||||
- return 0;
|
||||
- }
|
||||
- } else {
|
||||
+ reinstate_path(pp);
|
||||
+ else {
|
||||
LOG_MSG(4, verbosity, pp);
|
||||
if (pp->checkint != max_checkint) {
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 17 Jun 2020 13:31:37 -0500
|
||||
Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success
|
||||
|
||||
dm_flush_maps() returned both 0 and 1 on error, depending on which part
|
||||
of the function it was in, but the caller was always treating 0 as a
|
||||
success. Make dm_flush_maps() always return 1 on error and 0 on success.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index f6204e5f..cda83ce4 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -953,13 +953,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove)
|
||||
|
||||
int dm_flush_maps (int retries)
|
||||
{
|
||||
- int r = 0;
|
||||
+ int r = 1;
|
||||
struct dm_task *dmt;
|
||||
struct dm_names *names;
|
||||
unsigned next = 0;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST)))
|
||||
- return 0;
|
||||
+ return r;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
@@ -972,6 +972,7 @@ int dm_flush_maps (int retries)
|
||||
if (!names->dev)
|
||||
goto out;
|
||||
|
||||
+ r = 0;
|
||||
do {
|
||||
r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
next = names->next;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 15 Jun 2020 17:00:54 -0500
|
||||
Subject: [PATCH] multipathd: add "del maps" multipathd command
|
||||
|
||||
This will flush all multipath devices.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 7 +++++--
|
||||
libmultipath/devmapper.h | 2 +-
|
||||
multipath/main.c | 2 +-
|
||||
multipathd/cli.c | 1 +
|
||||
multipathd/cli_handlers.c | 19 +++++++++++++++++++
|
||||
multipathd/cli_handlers.h | 1 +
|
||||
multipathd/main.c | 3 ++-
|
||||
multipathd/main.h | 1 +
|
||||
8 files changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index cda83ce4..7f98bf9d 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -951,7 +951,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove)
|
||||
|
||||
#endif
|
||||
|
||||
-int dm_flush_maps (int retries)
|
||||
+int dm_flush_maps (int need_suspend, int retries)
|
||||
{
|
||||
int r = 1;
|
||||
struct dm_task *dmt;
|
||||
@@ -974,7 +974,10 @@ int dm_flush_maps (int retries)
|
||||
|
||||
r = 0;
|
||||
do {
|
||||
- r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
+ if (need_suspend)
|
||||
+ r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
+ else
|
||||
+ r |= dm_flush_map(names->name);
|
||||
next = names->next;
|
||||
names = (void *) names + next;
|
||||
} while (next);
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index adb55000..7e8812ad 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -55,7 +55,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||
#define dm_suspend_and_flush_map(mapname, retries) \
|
||||
_dm_flush_map(mapname, 1, 0, 1, retries)
|
||||
int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||
-int dm_flush_maps (int retries);
|
||||
+int dm_flush_maps (int need_suspend, int retries);
|
||||
int dm_fail_path(const char * mapname, char * path);
|
||||
int dm_reinstate_path(const char * mapname, char * path);
|
||||
int dm_queue_if_no_path(const char *mapname, int enable);
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 78822ee1..7ab3102f 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -1127,7 +1127,7 @@ main (int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
else if (conf->remove == FLUSH_ALL) {
|
||||
- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK;
|
||||
+ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||||
index 800c0fbe..bdc9fb10 100644
|
||||
--- a/multipathd/cli.c
|
||||
+++ b/multipathd/cli.c
|
||||
@@ -568,6 +568,7 @@ cli_init (void) {
|
||||
add_handler(DEL+PATH, NULL);
|
||||
add_handler(ADD+MAP, NULL);
|
||||
add_handler(DEL+MAP, NULL);
|
||||
+ add_handler(DEL+MAPS, NULL);
|
||||
add_handler(SWITCH+MAP+GROUP, NULL);
|
||||
add_handler(RECONFIGURE, NULL);
|
||||
add_handler(SUSPEND+MAP, NULL);
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 31c3d9fd..782bb003 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+int
|
||||
+cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||
+{
|
||||
+ struct vectors * vecs = (struct vectors *)data;
|
||||
+ struct multipath *mpp;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ condlog(2, "remove maps (operator)");
|
||||
+ vector_foreach_slot(vecs->mpvec, mpp, i) {
|
||||
+ if (flush_map(mpp, vecs, 0))
|
||||
+ ret++;
|
||||
+ else
|
||||
+ i--;
|
||||
+ }
|
||||
+ /* flush any multipath maps that aren't currently known by multipathd */
|
||||
+ ret |= dm_flush_maps(0, 0);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int
|
||||
cli_reload(void *v, char **reply, int *len, void *data)
|
||||
{
|
||||
diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
|
||||
index 0f451064..6f57b429 100644
|
||||
--- a/multipathd/cli_handlers.h
|
||||
+++ b/multipathd/cli_handlers.h
|
||||
@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data);
|
||||
int cli_del_path (void * v, char ** reply, int * len, void * data);
|
||||
int cli_add_map (void * v, char ** reply, int * len, void * data);
|
||||
int cli_del_map (void * v, char ** reply, int * len, void * data);
|
||||
+int cli_del_maps (void * v, char ** reply, int * len, void * data);
|
||||
int cli_switch_group(void * v, char ** reply, int * len, void * data);
|
||||
int cli_reconfigure(void * v, char ** reply, int * len, void * data);
|
||||
int cli_resize(void * v, char ** reply, int * len, void * data);
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 1d9ce7f7..1d0579e9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -631,7 +631,7 @@ sync_maps_state(vector mpvec)
|
||||
sync_map_state(mpp);
|
||||
}
|
||||
|
||||
-static int
|
||||
+int
|
||||
flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||
{
|
||||
int r;
|
||||
@@ -1551,6 +1551,7 @@ uxlsnrloop (void * ap)
|
||||
set_handler_callback(DEL+PATH, cli_del_path);
|
||||
set_handler_callback(ADD+MAP, cli_add_map);
|
||||
set_handler_callback(DEL+MAP, cli_del_map);
|
||||
+ set_handler_callback(DEL+MAPS, cli_del_maps);
|
||||
set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
|
||||
set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
|
||||
set_handler_callback(SUSPEND+MAP, cli_suspend);
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index 7bb8463f..5dff17e5 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int);
|
||||
int ev_remove_path (struct path *, struct vectors *, int);
|
||||
int ev_add_map (char *, const char *, struct vectors *);
|
||||
int ev_remove_map (char *, char *, int, struct vectors *);
|
||||
+int flush_map(struct multipath *, struct vectors *, int);
|
||||
int set_config_state(enum daemon_status);
|
||||
void * mpath_alloc_prin_response(int prin_sa);
|
||||
int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp,
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 15 Jun 2020 23:54:29 -0500
|
||||
Subject: [PATCH] multipath: make flushing maps work like other commands
|
||||
|
||||
The config structure doesn't need a special variable just for removes.
|
||||
Multipath can just use the cmd variable, like it does for the other
|
||||
commands.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.h | 3 ++-
|
||||
libmultipath/configure.h | 3 ---
|
||||
multipath/main.c | 20 ++++++++++----------
|
||||
3 files changed, 12 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 3368d8c9..4042eba6 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -39,6 +39,8 @@ enum mpath_cmds {
|
||||
CMD_ADD_WWID,
|
||||
CMD_USABLE_PATHS,
|
||||
CMD_DUMP_CONFIG,
|
||||
+ CMD_FLUSH_ONE,
|
||||
+ CMD_FLUSH_ALL,
|
||||
};
|
||||
|
||||
enum force_reload_types {
|
||||
@@ -143,7 +145,6 @@ struct config {
|
||||
unsigned int max_checkint;
|
||||
bool use_watchdog;
|
||||
int pgfailback;
|
||||
- int remove;
|
||||
int rr_weight;
|
||||
int no_path_retry;
|
||||
int user_friendly_names;
|
||||
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
|
||||
index d7509000..0e33bf40 100644
|
||||
--- a/libmultipath/configure.h
|
||||
+++ b/libmultipath/configure.h
|
||||
@@ -45,9 +45,6 @@ enum {
|
||||
CP_RETRY,
|
||||
};
|
||||
|
||||
-#define FLUSH_ONE 1
|
||||
-#define FLUSH_ALL 2
|
||||
-
|
||||
struct vectors;
|
||||
|
||||
int setup_map (struct multipath * mpp, char * params, int params_size,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 7ab3102f..a2080029 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -942,10 +942,10 @@ main (int argc, char *argv[])
|
||||
cmd = CMD_DRY_RUN;
|
||||
break;
|
||||
case 'f':
|
||||
- conf->remove = FLUSH_ONE;
|
||||
+ cmd = CMD_FLUSH_ONE;
|
||||
break;
|
||||
case 'F':
|
||||
- conf->remove = FLUSH_ALL;
|
||||
+ cmd = CMD_FLUSH_ALL;
|
||||
break;
|
||||
case 'l':
|
||||
if (optarg && !strncmp(optarg, "l", 1))
|
||||
@@ -1084,6 +1084,10 @@ main (int argc, char *argv[])
|
||||
condlog(0, "the -w option requires a device");
|
||||
goto out;
|
||||
}
|
||||
+ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) {
|
||||
+ condlog(0, "the -f option requires a map name to remove");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) {
|
||||
case DELEGATE_OK:
|
||||
@@ -1117,16 +1121,12 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (retries < 0)
|
||||
retries = conf->remove_retries;
|
||||
- if (conf->remove == FLUSH_ONE) {
|
||||
- if (dev_type == DEV_DEVMAP) {
|
||||
- r = dm_suspend_and_flush_map(dev, retries) ?
|
||||
- RTVL_FAIL : RTVL_OK;
|
||||
- } else
|
||||
- condlog(0, "must provide a map name to remove");
|
||||
-
|
||||
+ if (cmd == CMD_FLUSH_ONE) {
|
||||
+ r = dm_suspend_and_flush_map(dev, retries) ?
|
||||
+ RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
- else if (conf->remove == FLUSH_ALL) {
|
||||
+ else if (cmd == CMD_FLUSH_ALL) {
|
||||
r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 16 Jun 2020 16:25:34 -0500
|
||||
Subject: [PATCH] multipath: delegate flushing maps to multipathd
|
||||
|
||||
Since there can be problems with removing maps outside of multipathd,
|
||||
multipath should attempt to delegate this command to multipathd.
|
||||
However, multipathd doesn't attempt to suspend the device, in order
|
||||
to avoid potential hangs. If delegating to multipathd fails, multipath
|
||||
should try the remove itself.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 14 ++++++++++++++
|
||||
multipath/multipath.8 | 4 ++--
|
||||
2 files changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index a2080029..612c6815 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -828,6 +828,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd,
|
||||
if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) {
|
||||
p += snprintf(p, n, "reconfigure");
|
||||
}
|
||||
+ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) {
|
||||
+ p += snprintf(p, n, "del map %s", dev);
|
||||
+ /* multipathd doesn't try as hard, to avoid potentially
|
||||
+ * hanging. If it fails, retry with the regular multipath
|
||||
+ * command */
|
||||
+ r = NOT_DELEGATED;
|
||||
+ }
|
||||
+ else if (cmd == CMD_FLUSH_ALL) {
|
||||
+ p += snprintf(p, n, "del maps");
|
||||
+ /* multipathd doesn't try as hard, to avoid potentially
|
||||
+ * hanging. If it fails, retry with the regular multipath
|
||||
+ * command */
|
||||
+ r = NOT_DELEGATED;
|
||||
+ }
|
||||
/* Add other translations here */
|
||||
|
||||
if (strlen(command) == 0)
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 8befc45a..47a33f9b 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -125,11 +125,11 @@ the system.
|
||||
Other operation modes are chosen by using one of the following command line switches:
|
||||
.TP
|
||||
.B \-f
|
||||
-Flush (remove) a multipath device map specified as parameter, if unused.
|
||||
+Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running.
|
||||
.
|
||||
.TP
|
||||
.B \-F
|
||||
-Flush (remove) all unused multipath device maps.
|
||||
+Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running.
|
||||
.
|
||||
.TP
|
||||
.B \-l
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 16 Jun 2020 17:36:33 -0500
|
||||
Subject: [PATCH] multipath: add option to skip multipathd delegation
|
||||
|
||||
Add the -D option to allow users to skip delegating commands to
|
||||
multipathd.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.h | 1 +
|
||||
multipath/main.c | 8 +++++++-
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 4042eba6..160867cd 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -191,6 +191,7 @@ struct config {
|
||||
int ghost_delay;
|
||||
int find_multipaths_timeout;
|
||||
int marginal_pathgroups;
|
||||
+ int skip_delegate;
|
||||
unsigned int version[3];
|
||||
unsigned int sequence_nr;
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 612c6815..3c3d2398 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -825,6 +825,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd,
|
||||
*p = '\0';
|
||||
n = sizeof(command);
|
||||
|
||||
+ if (conf->skip_delegate)
|
||||
+ return NOT_DELEGATED;
|
||||
+
|
||||
if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) {
|
||||
p += snprintf(p, n, "reconfigure");
|
||||
}
|
||||
@@ -923,7 +926,7 @@ main (int argc, char *argv[])
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
- while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdDcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -955,6 +958,9 @@ main (int argc, char *argv[])
|
||||
if (cmd == CMD_CREATE)
|
||||
cmd = CMD_DRY_RUN;
|
||||
break;
|
||||
+ case 'D':
|
||||
+ conf->skip_delegate = 1;
|
||||
+ break;
|
||||
case 'f':
|
||||
cmd = CMD_FLUSH_ONE;
|
||||
break;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 25 Jun 2020 20:46:08 -0500
|
||||
Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing
|
||||
|
||||
dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as
|
||||
a signed integer. This means that if dev_loss_tmo is above INT_MAX, the
|
||||
sysfs value will be a negative number. Parsing this was causing
|
||||
sysfs_set_rport_tmo() to fail.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index ffec5162..83a41a4a 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -583,7 +583,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
|
||||
struct udev_device *rport_dev = NULL;
|
||||
char value[16], *eptr;
|
||||
char rport_id[32];
|
||||
- unsigned long long tmo = 0;
|
||||
+ unsigned int tmo;
|
||||
int ret;
|
||||
|
||||
sprintf(rport_id, "rport-%d:%d-%d",
|
||||
@@ -607,8 +607,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
|
||||
"error %d", rport_id, -ret);
|
||||
goto out;
|
||||
}
|
||||
- tmo = strtoull(value, &eptr, 0);
|
||||
- if (value == eptr || tmo == ULLONG_MAX) {
|
||||
+ tmo = strtoul(value, &eptr, 0);
|
||||
+ if (value == eptr) {
|
||||
condlog(0, "%s: Cannot parse dev_loss_tmo "
|
||||
"attribute '%s'", rport_id, value);
|
||||
goto out;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 26 Jun 2020 20:06:24 -0500
|
||||
Subject: [PATCH] kpartx: read devices with direct IO
|
||||
|
||||
If kpartx is used on top of shared storage, and a device has its
|
||||
partition table changed on one machine, and then kpartx is run on
|
||||
another, it may not see the new data, because the cache still contains
|
||||
the old data, and there is nothing to tell the machine running kpartx to
|
||||
invalidate it. To solve this, kpartx should read the devices using
|
||||
direct io.
|
||||
|
||||
One issue with how this code has been updated is that the original code
|
||||
for getblock() always read 1024 bytes. The new code reads a logical
|
||||
sector size chunk of the device, and returns a pointer to the 512 byte
|
||||
sector that the caller asked for, within that (possibly larger) chunk.
|
||||
This means that if the logical sector size is 512, then the code is now
|
||||
only reading 512 bytes. Looking through the code for the various
|
||||
partition types, I can't see a case where more than 512 bytes is needed
|
||||
and getblock() is used. If anyone has a reason why this code should be
|
||||
reading 1024 bytes at minmum, I can certainly change this. But when I
|
||||
looked, I couldn't find a case where reading 512 bytes would cause a
|
||||
problem.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/dasd.c | 7 ++++---
|
||||
kpartx/gpt.c | 22 +++++++++----------
|
||||
kpartx/kpartx.c | 56 +++++++++++++++++++++++++++++++++++++++----------
|
||||
kpartx/kpartx.h | 2 ++
|
||||
4 files changed, 61 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/kpartx/dasd.c b/kpartx/dasd.c
|
||||
index 14b9d3aa..f0398645 100644
|
||||
--- a/kpartx/dasd.c
|
||||
+++ b/kpartx/dasd.c
|
||||
@@ -22,6 +22,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
+#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -117,13 +118,13 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all,
|
||||
|
||||
sprintf(pathname, "/dev/.kpartx-node-%u-%u",
|
||||
(unsigned int)major(dev), (unsigned int)minor(dev));
|
||||
- if ((fd_dasd = open(pathname, O_RDONLY)) == -1) {
|
||||
+ if ((fd_dasd = open(pathname, O_RDONLY | O_DIRECT)) == -1) {
|
||||
/* Devicenode does not exist. Try to create one */
|
||||
if (mknod(pathname, 0600 | S_IFBLK, dev) == -1) {
|
||||
/* Couldn't create a device node */
|
||||
return -1;
|
||||
}
|
||||
- fd_dasd = open(pathname, O_RDONLY);
|
||||
+ fd_dasd = open(pathname, O_RDONLY | O_DIRECT);
|
||||
/*
|
||||
* The file will vanish when the last process (we)
|
||||
* has ceased to access it.
|
||||
@@ -175,7 +176,7 @@ read_dasd_pt(int fd, __attribute__((unused)) struct slice all,
|
||||
* Get volume label, extract name and type.
|
||||
*/
|
||||
|
||||
- if (!(data = (unsigned char *)malloc(blocksize)))
|
||||
+ if (aligned_malloc((void **)&data, blocksize, NULL))
|
||||
goto out;
|
||||
|
||||
|
||||
diff --git a/kpartx/gpt.c b/kpartx/gpt.c
|
||||
index 785b34ea..f7fefb70 100644
|
||||
--- a/kpartx/gpt.c
|
||||
+++ b/kpartx/gpt.c
|
||||
@@ -243,8 +243,7 @@ alloc_read_gpt_entries(int fd, gpt_header * gpt)
|
||||
|
||||
if (!count) return NULL;
|
||||
|
||||
- pte = (gpt_entry *)malloc(count);
|
||||
- if (!pte)
|
||||
+ if (aligned_malloc((void **)&pte, get_sector_size(fd), &count))
|
||||
return NULL;
|
||||
memset(pte, 0, count);
|
||||
|
||||
@@ -269,12 +268,11 @@ static gpt_header *
|
||||
alloc_read_gpt_header(int fd, uint64_t lba)
|
||||
{
|
||||
gpt_header *gpt;
|
||||
- gpt = (gpt_header *)
|
||||
- malloc(sizeof (gpt_header));
|
||||
- if (!gpt)
|
||||
+ size_t size = sizeof (gpt_header);
|
||||
+ if (aligned_malloc((void **)&gpt, get_sector_size(fd), &size))
|
||||
return NULL;
|
||||
- memset(gpt, 0, sizeof (*gpt));
|
||||
- if (!read_lba(fd, lba, gpt, sizeof (gpt_header))) {
|
||||
+ memset(gpt, 0, size);
|
||||
+ if (!read_lba(fd, lba, gpt, size)) {
|
||||
free(gpt);
|
||||
return NULL;
|
||||
}
|
||||
@@ -498,6 +496,7 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
|
||||
gpt_header *pgpt = NULL, *agpt = NULL;
|
||||
gpt_entry *pptes = NULL, *aptes = NULL;
|
||||
legacy_mbr *legacymbr = NULL;
|
||||
+ size_t size = sizeof(legacy_mbr);
|
||||
uint64_t lastlba;
|
||||
if (!gpt || !ptes)
|
||||
return 0;
|
||||
@@ -526,11 +525,10 @@ find_valid_gpt(int fd, gpt_header ** gpt, gpt_entry ** ptes)
|
||||
}
|
||||
|
||||
/* This will be added to the EFI Spec. per Intel after v1.02. */
|
||||
- legacymbr = malloc(sizeof (*legacymbr));
|
||||
- if (legacymbr) {
|
||||
- memset(legacymbr, 0, sizeof (*legacymbr));
|
||||
- read_lba(fd, 0, (uint8_t *) legacymbr,
|
||||
- sizeof (*legacymbr));
|
||||
+ if (aligned_malloc((void **)&legacymbr, get_sector_size(fd),
|
||||
+ &size) == 0) {
|
||||
+ memset(legacymbr, 0, size);
|
||||
+ read_lba(fd, 0, (uint8_t *) legacymbr, size);
|
||||
good_pmbr = is_pmbr_valid(legacymbr);
|
||||
free(legacymbr);
|
||||
legacymbr=NULL;
|
||||
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
|
||||
index d3620c5c..c24ad6d9 100644
|
||||
--- a/kpartx/kpartx.c
|
||||
+++ b/kpartx/kpartx.c
|
||||
@@ -19,6 +19,7 @@
|
||||
* cva, 2002-10-26
|
||||
*/
|
||||
|
||||
+#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
@@ -41,7 +42,6 @@
|
||||
|
||||
#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
-#define READ_SIZE 1024
|
||||
#define MAXTYPES 64
|
||||
#define MAXSLICES 256
|
||||
#define DM_TARGET "linear"
|
||||
@@ -388,7 +388,7 @@ main(int argc, char **argv){
|
||||
set_delimiter(mapname, delim);
|
||||
}
|
||||
|
||||
- fd = open(device, O_RDONLY);
|
||||
+ fd = open(device, O_RDONLY | O_DIRECT);
|
||||
|
||||
if (fd == -1) {
|
||||
perror(device);
|
||||
@@ -690,9 +690,9 @@ xmalloc (size_t size) {
|
||||
*/
|
||||
|
||||
static int
|
||||
-sseek(int fd, unsigned int secnr) {
|
||||
+sseek(int fd, unsigned int secnr, int secsz) {
|
||||
off64_t in, out;
|
||||
- in = ((off64_t) secnr << 9);
|
||||
+ in = ((off64_t) secnr * secsz);
|
||||
out = 1;
|
||||
|
||||
if ((out = lseek64(fd, in, SEEK_SET)) != in)
|
||||
@@ -703,6 +703,31 @@ sseek(int fd, unsigned int secnr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int
|
||||
+aligned_malloc(void **mem_p, size_t align, size_t *size_p)
|
||||
+{
|
||||
+ static size_t pgsize = 0;
|
||||
+ size_t size;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!mem_p || !align || (size_p && !*size_p))
|
||||
+ return EINVAL;
|
||||
+
|
||||
+ if (!pgsize)
|
||||
+ pgsize = getpagesize();
|
||||
+
|
||||
+ if (size_p)
|
||||
+ size = ((*size_p + align - 1) / align) * align;
|
||||
+ else
|
||||
+ size = pgsize;
|
||||
+
|
||||
+ err = posix_memalign(mem_p, pgsize, size);
|
||||
+ if (!err && size_p)
|
||||
+ *size_p = size;
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* always in sector size blocks */
|
||||
static
|
||||
struct block {
|
||||
unsigned int secnr;
|
||||
@@ -710,30 +735,39 @@ struct block {
|
||||
struct block *next;
|
||||
} *blockhead;
|
||||
|
||||
+/* blknr is always in 512 byte blocks */
|
||||
char *
|
||||
-getblock (int fd, unsigned int secnr) {
|
||||
+getblock (int fd, unsigned int blknr) {
|
||||
+ unsigned int secsz = get_sector_size(fd);
|
||||
+ unsigned int blks_per_sec = secsz / 512;
|
||||
+ unsigned int secnr = blknr / blks_per_sec;
|
||||
+ unsigned int blk_off = (blknr % blks_per_sec) * 512;
|
||||
struct block *bp;
|
||||
|
||||
for (bp = blockhead; bp; bp = bp->next)
|
||||
|
||||
if (bp->secnr == secnr)
|
||||
- return bp->block;
|
||||
+ return bp->block + blk_off;
|
||||
|
||||
- if (sseek(fd, secnr))
|
||||
+ if (sseek(fd, secnr, secsz))
|
||||
return NULL;
|
||||
|
||||
bp = xmalloc(sizeof(struct block));
|
||||
bp->secnr = secnr;
|
||||
bp->next = blockhead;
|
||||
blockhead = bp;
|
||||
- bp->block = (char *) xmalloc(READ_SIZE);
|
||||
+ if (aligned_malloc((void **)&bp->block, secsz, NULL)) {
|
||||
+ fprintf(stderr, "aligned_malloc failed\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
|
||||
- if (read(fd, bp->block, READ_SIZE) != READ_SIZE) {
|
||||
+ if (read(fd, bp->block, secsz) != secsz) {
|
||||
fprintf(stderr, "read error, sector %d\n", secnr);
|
||||
- bp->block = NULL;
|
||||
+ blockhead = bp->next;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
- return bp->block;
|
||||
+ return bp->block + blk_off;
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/kpartx/kpartx.h b/kpartx/kpartx.h
|
||||
index 67edeb82..727632c1 100644
|
||||
--- a/kpartx/kpartx.h
|
||||
+++ b/kpartx/kpartx.h
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _KPARTX_H
|
||||
#define _KPARTX_H
|
||||
|
||||
+#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
@@ -61,6 +62,7 @@ extern ptreader read_mac_pt;
|
||||
extern ptreader read_sun_pt;
|
||||
extern ptreader read_ps3_pt;
|
||||
|
||||
+int aligned_malloc(void **mem_p, size_t align, size_t *size_p);
|
||||
char *getblock(int fd, unsigned int secnr);
|
||||
|
||||
static inline unsigned int
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 10:49:59 -0500
|
||||
Subject: [PATCH] kpartx: handle alternate bsd disklabel location
|
||||
|
||||
bsd disk labels can either be at the start of the second sector, or 64
|
||||
bytes into the first sector, but kpartx only handled the first case.
|
||||
However the second case is what parted creates, and what the linux
|
||||
kernel partition code expects. kpartx should handle both cases.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/bsd.c | 16 ++++++++++++++--
|
||||
1 file changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kpartx/bsd.c b/kpartx/bsd.c
|
||||
index 0e661fbc..950b0f92 100644
|
||||
--- a/kpartx/bsd.c
|
||||
+++ b/kpartx/bsd.c
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "kpartx.h"
|
||||
#include <stdio.h>
|
||||
|
||||
+#define BSD_LABEL_OFFSET 64
|
||||
#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
|
||||
#define XBSD_MAXPARTITIONS 16
|
||||
#define BSD_FS_UNUSED 0
|
||||
@@ -60,8 +61,19 @@ read_bsd_pt(int fd, struct slice all, struct slice *sp, unsigned int ns) {
|
||||
return -1;
|
||||
|
||||
l = (struct bsd_disklabel *) bp;
|
||||
- if (l->d_magic != BSD_DISKMAGIC)
|
||||
- return -1;
|
||||
+ if (l->d_magic != BSD_DISKMAGIC) {
|
||||
+ /*
|
||||
+ * BSD disklabels can also start 64 bytes offset from the
|
||||
+ * start of the first sector
|
||||
+ */
|
||||
+ bp = getblock(fd, offset);
|
||||
+ if (bp == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ l = (struct bsd_disklabel *)(bp + 64);
|
||||
+ if (l->d_magic != BSD_DISKMAGIC)
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
max_partitions = 16;
|
||||
if (l->d_npartitions < max_partitions)
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 13:59:13 -0500
|
||||
Subject: [PATCH] libmultipath: fix checker detection for nvme devices
|
||||
|
||||
In order to fix hwhandler autodetection, commit 8794a776 made
|
||||
detect_alua() differentiate between failures to detect whether alua was
|
||||
supported, and successfully detecting that it was not supported.
|
||||
However, this causes nvme devices to get the TUR checker assigned to
|
||||
them. This is because there is nothing in detect_alua() to make it only
|
||||
work on scsi devices, and select_checker wasn't updated to handle
|
||||
detect_alua() failing without setting pp->tpgs to TPGS_NONE.
|
||||
|
||||
detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on
|
||||
non-scsi devices. Also, select_checker() should not assume that a
|
||||
devices is ALUA, simply because if failed to detect if alua was
|
||||
supported.
|
||||
|
||||
Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are
|
||||
down"
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 6 ++++++
|
||||
libmultipath/propsel.c | 4 +++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 83a41a4a..aa5942c3 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -887,6 +887,12 @@ detect_alua(struct path * pp)
|
||||
int tpgs;
|
||||
unsigned int timeout;
|
||||
|
||||
+
|
||||
+ if (pp->bus != SYSFS_BUS_SCSI) {
|
||||
+ pp->tpgs = TPGS_NONE;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (sysfs_get_timeout(pp, &timeout) <= 0)
|
||||
timeout = DEF_TIMEOUT;
|
||||
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 897e48ca..d362beb4 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -521,7 +521,9 @@ int select_checker(struct config *conf, struct path *pp)
|
||||
if (check_rdac(pp)) {
|
||||
ckr_name = RDAC;
|
||||
goto out;
|
||||
- } else if (path_get_tpgs(pp) != TPGS_NONE) {
|
||||
+ }
|
||||
+ path_get_tpgs(pp);
|
||||
+ if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) {
|
||||
ckr_name = TUR;
|
||||
goto out;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 6 Jul 2020 13:21:12 -0500
|
||||
Subject: [PATCH] Makefile.inc: trim extra information from systemd version
|
||||
|
||||
Some systemd versions print extra information in the
|
||||
"pkg-config --modversion" output, which confuses make. Trim this
|
||||
off.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index c2abd301..220009e0 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -37,7 +37,7 @@ endif
|
||||
|
||||
ifndef SYSTEMD
|
||||
ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1)
|
||||
- SYSTEMD = $(shell pkg-config --modversion libsystemd)
|
||||
+ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}')
|
||||
else
|
||||
ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1)
|
||||
SYSTEMD = $(shell systemctl --version 2> /dev/null | \
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 6 Jul 2020 17:28:46 -0500
|
||||
Subject: [PATCH] kpartx: fix -Wsign-compare error
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/kpartx.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
|
||||
index c24ad6d9..653ce0c8 100644
|
||||
--- a/kpartx/kpartx.c
|
||||
+++ b/kpartx/kpartx.c
|
||||
@@ -738,7 +738,7 @@ struct block {
|
||||
/* blknr is always in 512 byte blocks */
|
||||
char *
|
||||
getblock (int fd, unsigned int blknr) {
|
||||
- unsigned int secsz = get_sector_size(fd);
|
||||
+ int secsz = get_sector_size(fd);
|
||||
unsigned int blks_per_sec = secsz / 512;
|
||||
unsigned int secnr = blknr / blks_per_sec;
|
||||
unsigned int blk_off = (blknr % blks_per_sec) * 512;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
From 7159242be31dbb3f25aa67920462107bc2bc5fe0 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 9 Jul 2020 18:20:18 -0500
|
||||
Subject: [PATCH] libmultipath: count pending paths as active on loads
|
||||
|
||||
When multipath loads a table, it signals to udev if there are no active
|
||||
paths. Multipath wasn't counting pending paths as active. This meant
|
||||
that if all the paths were pending, udev would treat the device as not
|
||||
ready, and not run kpartx on it. Even if the pending paths later
|
||||
because active and were reinstated, the kernel would not send a new
|
||||
uevent, because from its point of view, they were always up.
|
||||
|
||||
The alternative would be to continue to treat them as failed in the udev
|
||||
rules, but then also tell the kernel that they were down, so that it
|
||||
would trigger a uevent when they were reinstated. However, this could
|
||||
lead to newly created multipath devices failing IO, simply because the
|
||||
path checkers hadn't returned yet. Having udev assume that the the
|
||||
device is up, like the kernel does, seems like the safer option.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 3 ++-
|
||||
libmultipath/structs.c | 20 ++++++++++++++++++++
|
||||
libmultipath/structs.h | 1 +
|
||||
3 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 7f98bf9d..91ff0b3d 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -408,7 +408,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload)
|
||||
/* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */
|
||||
return (mpp->skip_kpartx == SKIP_KPARTX_ON ?
|
||||
MPATH_UDEV_NO_KPARTX_FLAG : 0) |
|
||||
- ((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ?
|
||||
+ ((count_active_pending_paths(mpp) == 0 ||
|
||||
+ mpp->ghost_delay_tick > 0) ?
|
||||
MPATH_UDEV_NO_PATHS_FLAG : 0) |
|
||||
(reload && !mpp->force_udev_reload ?
|
||||
MPATH_UDEV_RELOAD_FLAG : 0);
|
||||
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
|
||||
index 2dd378c4..dda9884c 100644
|
||||
--- a/libmultipath/structs.c
|
||||
+++ b/libmultipath/structs.c
|
||||
@@ -500,6 +500,26 @@ int count_active_paths(const struct multipath *mpp)
|
||||
return count;
|
||||
}
|
||||
|
||||
+int count_active_pending_paths(const struct multipath *mpp)
|
||||
+{
|
||||
+ struct pathgroup *pgp;
|
||||
+ struct path *pp;
|
||||
+ int count = 0;
|
||||
+ int i, j;
|
||||
+
|
||||
+ if (!mpp->pg)
|
||||
+ return 0;
|
||||
+
|
||||
+ vector_foreach_slot (mpp->pg, pgp, i) {
|
||||
+ vector_foreach_slot (pgp->paths, pp, j) {
|
||||
+ if (pp->state == PATH_UP || pp->state == PATH_GHOST ||
|
||||
+ pp->state == PATH_PENDING)
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp)
|
||||
{
|
||||
int i, j;
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 9bd39eb1..8e78b8c0 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -465,6 +465,7 @@ struct path * first_path (const struct multipath *mpp);
|
||||
int pathcountgr (const struct pathgroup *, int);
|
||||
int pathcount (const struct multipath *, int);
|
||||
int count_active_paths(const struct multipath *);
|
||||
+int count_active_pending_paths(const struct multipath *);
|
||||
int pathcmp (const struct pathgroup *, const struct pathgroup *);
|
||||
int add_feature (char **, const char *);
|
||||
int remove_feature (char **, const char *);
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 13 Jul 2020 15:41:15 -0500
|
||||
Subject: [PATCH] multipath: deal with failures flushing maps
|
||||
|
||||
dm_flush_maps() was failing if there were no device-mapper devices at
|
||||
all, instead of returning success, since there is nothing to do.
|
||||
|
||||
delegate_to_multipathd() was returning success, even if the multipathd
|
||||
command failed. Also, if the command was set to fail with NOT_DELEGATED,
|
||||
it shouldn't print any errors, since multipath will try to issue to
|
||||
command itself.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 2 +-
|
||||
multipath/main.c | 9 ++++++---
|
||||
2 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 91ff0b3d..3f70e576 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -970,10 +970,10 @@ int dm_flush_maps (int need_suspend, int retries)
|
||||
if (!(names = dm_task_get_names (dmt)))
|
||||
goto out;
|
||||
|
||||
+ r = 0;
|
||||
if (!names->dev)
|
||||
goto out;
|
||||
|
||||
- r = 0;
|
||||
do {
|
||||
if (need_suspend)
|
||||
r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 3c3d2398..607cada2 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -869,9 +869,12 @@ int delegate_to_multipathd(enum mpath_cmds cmd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (reply != NULL && *reply != '\0' && strcmp(reply, "ok\n"))
|
||||
- printf("%s", reply);
|
||||
- r = DELEGATE_OK;
|
||||
+ if (reply != NULL && *reply != '\0') {
|
||||
+ if (strcmp(reply, "fail\n"))
|
||||
+ r = DELEGATE_OK;
|
||||
+ if (r != NOT_DELEGATED && strcmp(reply, "ok\n"))
|
||||
+ printf("%s", reply);
|
||||
+ }
|
||||
|
||||
out:
|
||||
FREE(reply);
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 3 Nov 2020 14:27:58 -0600
|
||||
Subject: [PATCH] libmultipath: factor out code to get vpd page data
|
||||
|
||||
A future patch will reuse the code to get the vpd page data, so factor
|
||||
it out from get_vpd_sgio().
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index aa5942c3..eb1e735d 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1239,11 +1239,10 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
|
||||
return len;
|
||||
}
|
||||
|
||||
-int
|
||||
-get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
+static int
|
||||
+fetch_vpd_page(int fd, int pg, unsigned char *buff)
|
||||
{
|
||||
- int len, buff_len;
|
||||
- unsigned char buff[4096];
|
||||
+ int buff_len;
|
||||
|
||||
memset(buff, 0x0, 4096);
|
||||
if (sgio_get_vpd(buff, 4096, fd, pg) < 0) {
|
||||
@@ -1264,6 +1263,18 @@ get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
condlog(3, "vpd pg%02x page truncated", pg);
|
||||
buff_len = 4096;
|
||||
}
|
||||
+ return buff_len;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
+{
|
||||
+ int len, buff_len;
|
||||
+ unsigned char buff[4096];
|
||||
+
|
||||
+ buff_len = fetch_vpd_page(fd, pg, buff);
|
||||
+ if (buff_len < 0)
|
||||
+ return buff_len;
|
||||
if (pg == 0x80)
|
||||
len = parse_vpd_pg80(buff, str, maxlen);
|
||||
else if (pg == 0x83)
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 7 Oct 2020 21:43:02 -0500
|
||||
Subject: [PATCH] libmultipath: limit reading 0xc9 vpd page
|
||||
|
||||
Only rdac arrays support 0xC9 vpd page inquiries. All other arrays will
|
||||
return a failure. Only do the rdac inquiry when detecting array
|
||||
capabilities if the array's path checker is explicitly set to rdac, or
|
||||
the path checker is not set, and the array reports that it supports vpd
|
||||
page 0xC9 in the Supported VPD Pages (0x00) vpd page.
|
||||
|
||||
Multipath was doing the check if either the path checker was set to
|
||||
rdac, or no path checker was set. This means that for almost all
|
||||
non-rdac arrays, multipath was issuing a bad inquiry. This was annoying
|
||||
users.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 25 +++++++++++++++++++++++++
|
||||
libmultipath/discovery.h | 1 +
|
||||
libmultipath/propsel.c | 10 ++++++----
|
||||
3 files changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index eb1e735d..01aadba9 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1266,6 +1266,31 @@ fetch_vpd_page(int fd, int pg, unsigned char *buff)
|
||||
return buff_len;
|
||||
}
|
||||
|
||||
+/* heavily based on sg_inq.c from sg3_utils */
|
||||
+bool
|
||||
+is_vpd_page_supported(int fd, int pg)
|
||||
+{
|
||||
+ int i, len, buff_len;
|
||||
+ unsigned char buff[4096];
|
||||
+
|
||||
+ buff_len = fetch_vpd_page(fd, 0x00, buff);
|
||||
+ if (buff_len < 0)
|
||||
+ return false;
|
||||
+ if (buff_len < 4) {
|
||||
+ condlog(3, "VPD page 00h too short");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ len = buff[3] + 4;
|
||||
+ if (len > buff_len)
|
||||
+ condlog(3, "vpd page 00h trucated, expected %d, have %d",
|
||||
+ len, buff_len);
|
||||
+ for (i = 4; i < len; ++i)
|
||||
+ if (buff[i] == pg)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
{
|
||||
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
||||
index 6444887d..d3193daf 100644
|
||||
--- a/libmultipath/discovery.h
|
||||
+++ b/libmultipath/discovery.h
|
||||
@@ -56,6 +56,7 @@ int sysfs_get_asymmetric_access_state(struct path *pp,
|
||||
char *buff, int buflen);
|
||||
int get_uid(struct path * pp, int path_state, struct udev_device *udev,
|
||||
int allow_fallback);
|
||||
+bool is_vpd_page_supported(int fd, int pg);
|
||||
|
||||
/*
|
||||
* discovery bitmask
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index d362beb4..d7febec6 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -496,13 +496,15 @@ check_rdac(struct path * pp)
|
||||
{
|
||||
int len;
|
||||
char buff[44];
|
||||
- const char *checker_name;
|
||||
+ const char *checker_name = NULL;
|
||||
|
||||
if (pp->bus != SYSFS_BUS_SCSI)
|
||||
return 0;
|
||||
- /* Avoid ioctl if this is likely not an RDAC array */
|
||||
- if (__do_set_from_hwe(checker_name, pp, checker_name) &&
|
||||
- strcmp(checker_name, RDAC))
|
||||
+ /* Avoid checking 0xc9 if this is likely not an RDAC array */
|
||||
+ if (!__do_set_from_hwe(checker_name, pp, checker_name) &&
|
||||
+ !is_vpd_page_supported(pp->fd, 0xC9))
|
||||
+ return 0;
|
||||
+ if (checker_name && strcmp(checker_name, RDAC))
|
||||
return 0;
|
||||
len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44);
|
||||
if (len <= 0)
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Schremmer <steve.schremmer@netapp.com>
|
||||
Date: Mon, 6 Jul 2020 20:22:35 +0000
|
||||
Subject: [PATCH] libmultipath: add device to hwtable.c
|
||||
|
||||
Add FUJITSU ETERNUS_AHB defaults.
|
||||
|
||||
Signed-off-by: Steve Schremmer <steve.schremmer@netapp.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index d1fcfdb3..d680bdfc 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -428,6 +428,22 @@ static struct hwentry default_hw[] = {
|
||||
.pgpolicy = MULTIBUS,
|
||||
.no_path_retry = 10,
|
||||
},
|
||||
+ {
|
||||
+ /*
|
||||
+ * ETERNUS AB/HB
|
||||
+ * Maintainer: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
|
||||
+ */
|
||||
+ .vendor = "FUJITSU",
|
||||
+ .product = "ETERNUS_AHB",
|
||||
+ .bl_product = "Universal Xport",
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .checker_name = RDAC,
|
||||
+ .features = "2 pg_init_retries 50",
|
||||
+ .hwhandler = "1 rdac",
|
||||
+ .prio_name = PRIO_RDAC,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .no_path_retry = 30,
|
||||
+ },
|
||||
/*
|
||||
* Hitachi Vantara
|
||||
*
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 12 Oct 2020 16:06:11 -0500
|
||||
Subject: [PATCH] libmultipath: move fast_io_fail defines to structs.h
|
||||
|
||||
Since fast_io_fail is part of the multipath struct, its symbolic values
|
||||
belong in structs.h. Also, make it an instance of a general enum, which
|
||||
will be used again in future patches, and change the set/print functions
|
||||
which use it to use the general enum instead.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.h | 8 --------
|
||||
libmultipath/dict.c | 30 +++++++++++++++---------------
|
||||
libmultipath/dict.h | 2 +-
|
||||
libmultipath/propsel.c | 2 +-
|
||||
libmultipath/structs.h | 17 +++++++++++++++++
|
||||
5 files changed, 34 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 160867cd..f38c7639 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -11,14 +11,6 @@
|
||||
#define ORIGIN_CONFIG 1
|
||||
#define ORIGIN_NO_CONFIG 2
|
||||
|
||||
-/*
|
||||
- * In kernel, fast_io_fail == 0 means immediate failure on rport delete.
|
||||
- * OTOH '0' means not-configured in various places in multipath-tools.
|
||||
- */
|
||||
-#define MP_FAST_IO_FAIL_UNSET (0)
|
||||
-#define MP_FAST_IO_FAIL_OFF (-1)
|
||||
-#define MP_FAST_IO_FAIL_ZERO (-2)
|
||||
-
|
||||
enum devtypes {
|
||||
DEV_NONE,
|
||||
DEV_DEVT,
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 184d4b22..ce8e1cda 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -834,7 +834,7 @@ declare_mp_attr_handler(gid, set_gid)
|
||||
declare_mp_attr_snprint(gid, print_gid)
|
||||
|
||||
static int
|
||||
-set_fast_io_fail(vector strvec, void *ptr)
|
||||
+set_undef_off_zero(vector strvec, void *ptr)
|
||||
{
|
||||
char * buff;
|
||||
int *int_ptr = (int *)ptr;
|
||||
@@ -844,36 +844,36 @@ set_fast_io_fail(vector strvec, void *ptr)
|
||||
return 1;
|
||||
|
||||
if (strcmp(buff, "off") == 0)
|
||||
- *int_ptr = MP_FAST_IO_FAIL_OFF;
|
||||
+ *int_ptr = UOZ_OFF;
|
||||
else if (sscanf(buff, "%d", int_ptr) != 1 ||
|
||||
- *int_ptr < MP_FAST_IO_FAIL_ZERO)
|
||||
- *int_ptr = MP_FAST_IO_FAIL_UNSET;
|
||||
+ *int_ptr < UOZ_ZERO)
|
||||
+ *int_ptr = UOZ_UNDEF;
|
||||
else if (*int_ptr == 0)
|
||||
- *int_ptr = MP_FAST_IO_FAIL_ZERO;
|
||||
+ *int_ptr = UOZ_ZERO;
|
||||
|
||||
FREE(buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
-print_fast_io_fail(char * buff, int len, long v)
|
||||
+print_undef_off_zero(char * buff, int len, long v)
|
||||
{
|
||||
- if (v == MP_FAST_IO_FAIL_UNSET)
|
||||
+ if (v == UOZ_UNDEF)
|
||||
return 0;
|
||||
- if (v == MP_FAST_IO_FAIL_OFF)
|
||||
+ if (v == UOZ_OFF)
|
||||
return snprintf(buff, len, "\"off\"");
|
||||
- if (v == MP_FAST_IO_FAIL_ZERO)
|
||||
+ if (v == UOZ_ZERO)
|
||||
return snprintf(buff, len, "0");
|
||||
return snprintf(buff, len, "%ld", v);
|
||||
}
|
||||
|
||||
-declare_def_handler(fast_io_fail, set_fast_io_fail)
|
||||
-declare_def_snprint_defint(fast_io_fail, print_fast_io_fail,
|
||||
+declare_def_handler(fast_io_fail, set_undef_off_zero)
|
||||
+declare_def_snprint_defint(fast_io_fail, print_undef_off_zero,
|
||||
DEFAULT_FAST_IO_FAIL)
|
||||
-declare_ovr_handler(fast_io_fail, set_fast_io_fail)
|
||||
-declare_ovr_snprint(fast_io_fail, print_fast_io_fail)
|
||||
-declare_hw_handler(fast_io_fail, set_fast_io_fail)
|
||||
-declare_hw_snprint(fast_io_fail, print_fast_io_fail)
|
||||
+declare_ovr_handler(fast_io_fail, set_undef_off_zero)
|
||||
+declare_ovr_snprint(fast_io_fail, print_undef_off_zero)
|
||||
+declare_hw_handler(fast_io_fail, set_undef_off_zero)
|
||||
+declare_hw_snprint(fast_io_fail, print_undef_off_zero)
|
||||
|
||||
static int
|
||||
set_dev_loss(vector strvec, void *ptr)
|
||||
diff --git a/libmultipath/dict.h b/libmultipath/dict.h
|
||||
index a40ac66f..a917e1ca 100644
|
||||
--- a/libmultipath/dict.h
|
||||
+++ b/libmultipath/dict.h
|
||||
@@ -13,7 +13,7 @@ int print_rr_weight(char *buff, int len, long v);
|
||||
int print_pgfailback(char *buff, int len, long v);
|
||||
int print_pgpolicy(char *buff, int len, long v);
|
||||
int print_no_path_retry(char *buff, int len, long v);
|
||||
-int print_fast_io_fail(char *buff, int len, long v);
|
||||
+int print_undef_off_zero(char *buff, int len, long v);
|
||||
int print_dev_loss(char *buff, int len, unsigned long v);
|
||||
int print_reservation_key(char * buff, int len, struct be64 key, uint8_t
|
||||
flags, int source);
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index d7febec6..725db2b1 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -755,7 +755,7 @@ int select_fast_io_fail(struct config *conf, struct multipath *mp)
|
||||
mp_set_conf(fast_io_fail);
|
||||
mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL);
|
||||
out:
|
||||
- print_fast_io_fail(buff, 12, mp->fast_io_fail);
|
||||
+ print_undef_off_zero(buff, 12, mp->fast_io_fail);
|
||||
condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 8e78b8c0..29209984 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -229,6 +229,23 @@ enum vpd_vendor_ids {
|
||||
VPD_VP_ARRAY_SIZE, /* This must remain the last entry */
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Multipath treats 0 as undefined for optional config parameters.
|
||||
+ * Use this for cases where 0 is a valid option for systems multipath
|
||||
+ * is communicating with
|
||||
+ */
|
||||
+enum undefined_off_zero {
|
||||
+ UOZ_UNDEF = 0,
|
||||
+ UOZ_OFF = -1,
|
||||
+ UOZ_ZERO = -2,
|
||||
+};
|
||||
+
|
||||
+enum fast_io_fail_states {
|
||||
+ MP_FAST_IO_FAIL_UNSET = UOZ_UNDEF,
|
||||
+ MP_FAST_IO_FAIL_OFF = UOZ_OFF,
|
||||
+ MP_FAST_IO_FAIL_ZERO = UOZ_ZERO,
|
||||
+};
|
||||
+
|
||||
struct vpd_vendor_page {
|
||||
int pg;
|
||||
const char *name;
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 14 Oct 2020 18:38:20 -0500
|
||||
Subject: [PATCH] libmultipath: add eh_deadline multipath.conf parameter
|
||||
|
||||
There are times a fc rport is never lost, meaning that fast_io_fail_tmo
|
||||
and dev_loss_tmo never trigger, but scsi commands still hang. This can
|
||||
cause problems in cases where users have string timing requirements, and
|
||||
the easiest way to solve these issues is to set eh_deadline. Since it's
|
||||
already possible to set fast_io_fail_tmo and dev_loss_tmo from
|
||||
multipath.conf, and have multipath take care of setting it correctly for
|
||||
the scsi devices in sysfs, it makes sense to allow users to set
|
||||
eh_deadline here as well.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 ++
|
||||
libmultipath/config.h | 2 ++
|
||||
libmultipath/configure.c | 1 +
|
||||
libmultipath/dict.c | 10 +++++++
|
||||
libmultipath/discovery.c | 58 +++++++++++++++++++++++++++++++++-----
|
||||
libmultipath/propsel.c | 17 +++++++++++
|
||||
libmultipath/propsel.h | 1 +
|
||||
libmultipath/structs.h | 7 +++++
|
||||
multipath/multipath.conf.5 | 16 +++++++++++
|
||||
9 files changed, 107 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 26f8e050..a71db2d0 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -359,6 +359,7 @@ merge_hwe (struct hwentry * dst, struct hwentry * src)
|
||||
merge_num(flush_on_last_del);
|
||||
merge_num(fast_io_fail);
|
||||
merge_num(dev_loss);
|
||||
+ merge_num(eh_deadline);
|
||||
merge_num(user_friendly_names);
|
||||
merge_num(retain_hwhandler);
|
||||
merge_num(detect_prio);
|
||||
@@ -514,6 +515,7 @@ store_hwe (vector hwtable, struct hwentry * dhwe)
|
||||
hwe->flush_on_last_del = dhwe->flush_on_last_del;
|
||||
hwe->fast_io_fail = dhwe->fast_io_fail;
|
||||
hwe->dev_loss = dhwe->dev_loss;
|
||||
+ hwe->eh_deadline = dhwe->eh_deadline;
|
||||
hwe->user_friendly_names = dhwe->user_friendly_names;
|
||||
hwe->retain_hwhandler = dhwe->retain_hwhandler;
|
||||
hwe->detect_prio = dhwe->detect_prio;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index f38c7639..a22c1b4e 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -64,6 +64,7 @@ struct hwentry {
|
||||
int flush_on_last_del;
|
||||
int fast_io_fail;
|
||||
unsigned int dev_loss;
|
||||
+ int eh_deadline;
|
||||
int user_friendly_names;
|
||||
int retain_hwhandler;
|
||||
int detect_prio;
|
||||
@@ -149,6 +150,7 @@ struct config {
|
||||
int attribute_flags;
|
||||
int fast_io_fail;
|
||||
unsigned int dev_loss;
|
||||
+ int eh_deadline;
|
||||
int log_checker_err;
|
||||
int allow_queueing;
|
||||
int find_multipaths;
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 96c79610..b7113291 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -340,6 +340,7 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
|
||||
select_gid(conf, mpp);
|
||||
select_fast_io_fail(conf, mpp);
|
||||
select_dev_loss(conf, mpp);
|
||||
+ select_eh_deadline(conf, mpp);
|
||||
select_reservation_key(conf, mpp);
|
||||
select_deferred_remove(conf, mpp);
|
||||
select_marginal_path_err_sample_time(conf, mpp);
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index ce8e1cda..8fd91d8c 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -911,6 +911,13 @@ declare_ovr_snprint(dev_loss, print_dev_loss)
|
||||
declare_hw_handler(dev_loss, set_dev_loss)
|
||||
declare_hw_snprint(dev_loss, print_dev_loss)
|
||||
|
||||
+declare_def_handler(eh_deadline, set_undef_off_zero)
|
||||
+declare_def_snprint(eh_deadline, print_undef_off_zero)
|
||||
+declare_ovr_handler(eh_deadline, set_undef_off_zero)
|
||||
+declare_ovr_snprint(eh_deadline, print_undef_off_zero)
|
||||
+declare_hw_handler(eh_deadline, set_undef_off_zero)
|
||||
+declare_hw_snprint(eh_deadline, print_undef_off_zero)
|
||||
+
|
||||
static int
|
||||
set_pgpolicy(vector strvec, void *ptr)
|
||||
{
|
||||
@@ -1776,6 +1783,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("gid", &def_gid_handler, &snprint_def_gid);
|
||||
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
|
||||
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
|
||||
+ install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline);
|
||||
install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file);
|
||||
install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file);
|
||||
install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
|
||||
@@ -1885,6 +1893,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
|
||||
install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
|
||||
install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
|
||||
+ install_keyword("eh_deadline", &hw_eh_deadline_handler, &snprint_hw_eh_deadline);
|
||||
install_keyword("user_friendly_names", &hw_user_friendly_names_handler, &snprint_hw_user_friendly_names);
|
||||
install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler);
|
||||
install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_hw_detect_prio);
|
||||
@@ -1925,6 +1934,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("flush_on_last_del", &ovr_flush_on_last_del_handler, &snprint_ovr_flush_on_last_del);
|
||||
install_keyword("fast_io_fail_tmo", &ovr_fast_io_fail_handler, &snprint_ovr_fast_io_fail);
|
||||
install_keyword("dev_loss_tmo", &ovr_dev_loss_handler, &snprint_ovr_dev_loss);
|
||||
+ install_keyword("eh_deadline", &ovr_eh_deadline_handler, &snprint_ovr_eh_deadline);
|
||||
install_keyword("user_friendly_names", &ovr_user_friendly_names_handler, &snprint_ovr_user_friendly_names);
|
||||
install_keyword("retain_attached_hw_handler", &ovr_retain_hwhandler_handler, &snprint_ovr_retain_hwhandler);
|
||||
install_keyword("detect_prio", &ovr_detect_prio_handler, &snprint_ovr_detect_prio);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 01aadba9..a328aafa 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -577,6 +577,42 @@ sysfs_get_asymmetric_access_state(struct path *pp, char *buff, int buflen)
|
||||
return !!preferred;
|
||||
}
|
||||
|
||||
+static int
|
||||
+sysfs_set_eh_deadline(struct multipath *mpp, struct path *pp)
|
||||
+{
|
||||
+ struct udev_device *hostdev;
|
||||
+ char host_name[HOST_NAME_LEN], value[16];
|
||||
+ int ret;
|
||||
+
|
||||
+ if (mpp->eh_deadline == EH_DEADLINE_UNSET)
|
||||
+ return 0;
|
||||
+
|
||||
+ sprintf(host_name, "host%d", pp->sg_id.host_no);
|
||||
+ hostdev = udev_device_new_from_subsystem_sysname(udev,
|
||||
+ "scsi_host", host_name);
|
||||
+ if (!hostdev)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (mpp->eh_deadline == EH_DEADLINE_OFF)
|
||||
+ sprintf(value, "off");
|
||||
+ else if (mpp->eh_deadline == EH_DEADLINE_ZERO)
|
||||
+ sprintf(value, "0");
|
||||
+ else
|
||||
+ snprintf(value, 16, "%u", mpp->eh_deadline);
|
||||
+
|
||||
+ ret = sysfs_attr_set_value(hostdev, "eh_deadline",
|
||||
+ value, strlen(value));
|
||||
+ /*
|
||||
+ * not all scsi drivers support setting eh_deadline, so failing
|
||||
+ * is totally reasonable
|
||||
+ */
|
||||
+ if (ret <= 0)
|
||||
+ condlog(4, "%s: failed to set eh_deadline to %s, error %d", udev_device_get_sysname(hostdev), value, -ret);
|
||||
+
|
||||
+ udev_device_unref(hostdev);
|
||||
+ return (ret <= 0);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
|
||||
{
|
||||
@@ -787,16 +823,24 @@ sysfs_set_scsi_tmo (struct multipath *mpp, unsigned int checkint)
|
||||
mpp->alias, mpp->fast_io_fail);
|
||||
mpp->fast_io_fail = MP_FAST_IO_FAIL_OFF;
|
||||
}
|
||||
- if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
|
||||
+ if (!mpp->dev_loss && mpp->fast_io_fail == MP_FAST_IO_FAIL_UNSET &&
|
||||
+ mpp->eh_deadline == EH_DEADLINE_UNSET)
|
||||
return 0;
|
||||
|
||||
vector_foreach_slot(mpp->paths, pp, i) {
|
||||
- if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
|
||||
- sysfs_set_rport_tmo(mpp, pp);
|
||||
- if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
|
||||
- sysfs_set_session_tmo(mpp, pp);
|
||||
- if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
|
||||
- sysfs_set_nexus_loss_tmo(mpp, pp);
|
||||
+ if (pp->bus != SYSFS_BUS_SCSI)
|
||||
+ continue;
|
||||
+
|
||||
+ if (mpp->dev_loss ||
|
||||
+ mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
|
||||
+ if (pp->sg_id.proto_id == SCSI_PROTOCOL_FCP)
|
||||
+ sysfs_set_rport_tmo(mpp, pp);
|
||||
+ else if (pp->sg_id.proto_id == SCSI_PROTOCOL_ISCSI)
|
||||
+ sysfs_set_session_tmo(mpp, pp);
|
||||
+ else if (pp->sg_id.proto_id == SCSI_PROTOCOL_SAS)
|
||||
+ sysfs_set_nexus_loss_tmo(mpp, pp);
|
||||
+ }
|
||||
+ sysfs_set_eh_deadline(mpp, pp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 725db2b1..1150cfe8 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -776,6 +776,23 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int select_eh_deadline(struct config *conf, struct multipath *mp)
|
||||
+{
|
||||
+ const char *origin;
|
||||
+ char buff[12];
|
||||
+
|
||||
+ mp_set_ovr(eh_deadline);
|
||||
+ mp_set_hwe(eh_deadline);
|
||||
+ mp_set_conf(eh_deadline);
|
||||
+ mp->eh_deadline = EH_DEADLINE_UNSET;
|
||||
+ /* not changing sysfs in default cause, so don't print anything */
|
||||
+ return 0;
|
||||
+out:
|
||||
+ print_undef_off_zero(buff, 12, mp->eh_deadline);
|
||||
+ condlog(3, "%s: eh_deadline = %s %s", mp->alias, buff, origin);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int select_flush_on_last_del(struct config *conf, struct multipath *mp)
|
||||
{
|
||||
const char *origin;
|
||||
diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h
|
||||
index 3d6edd8a..a68bacf0 100644
|
||||
--- a/libmultipath/propsel.h
|
||||
+++ b/libmultipath/propsel.h
|
||||
@@ -17,6 +17,7 @@ int select_uid(struct config *conf, struct multipath *mp);
|
||||
int select_gid(struct config *conf, struct multipath *mp);
|
||||
int select_fast_io_fail(struct config *conf, struct multipath *mp);
|
||||
int select_dev_loss(struct config *conf, struct multipath *mp);
|
||||
+int select_eh_deadline(struct config *conf, struct multipath *mp);
|
||||
int select_reservation_key(struct config *conf, struct multipath *mp);
|
||||
int select_retain_hwhandler (struct config *conf, struct multipath * mp);
|
||||
int select_detect_prio(struct config *conf, struct path * pp);
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 29209984..65542dea 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -246,6 +246,12 @@ enum fast_io_fail_states {
|
||||
MP_FAST_IO_FAIL_ZERO = UOZ_ZERO,
|
||||
};
|
||||
|
||||
+enum eh_deadline_states {
|
||||
+ EH_DEADLINE_UNSET = UOZ_UNDEF,
|
||||
+ EH_DEADLINE_OFF = UOZ_OFF,
|
||||
+ EH_DEADLINE_ZERO = UOZ_ZERO,
|
||||
+};
|
||||
+
|
||||
struct vpd_vendor_page {
|
||||
int pg;
|
||||
const char *name;
|
||||
@@ -366,6 +372,7 @@ struct multipath {
|
||||
int ghost_delay;
|
||||
int ghost_delay_tick;
|
||||
unsigned int dev_loss;
|
||||
+ int eh_deadline;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 6dc26f10..60954574 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -700,6 +700,22 @@ The default is: \fB600\fR
|
||||
.
|
||||
.
|
||||
.TP
|
||||
+.B eh_deadline
|
||||
+Specify the maximum number of seconds the SCSI layer will spend doing error
|
||||
+handling when scsi devices fail. After this timeout the scsi layer will perform
|
||||
+a full HBA reset. Setting this may be necessary in cases where the rport is
|
||||
+never lost, so \fIfast_io_fail_tmo\fR and \fIdev_loss_tmo\fR will never
|
||||
+trigger, but (frequently do to load) scsi commands still hang. \fBNote:\fR when
|
||||
+the scsi error handler performs the HBA reset, all target paths on that HBA
|
||||
+will be affected. eh_deadline should only be set in cases where all targets on
|
||||
+the affected HBAs are multipathed.
|
||||
+.RS
|
||||
+.TP
|
||||
+The default is: \fB<unset>\fR
|
||||
+.RE
|
||||
+.
|
||||
+.
|
||||
+.TP
|
||||
.B bindings_file
|
||||
The full pathname of the binding file to be used when the user_friendly_names
|
||||
option is set.
|
||||
--
|
||||
2.17.2
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 23 Oct 2020 11:38:24 -0500
|
||||
Subject: [PATCH] libmultipath: don't dlclose tur checker DSO
|
||||
|
||||
The multipathd tur checker thread is designed to be able to finish at
|
||||
any time, even after the tur checker itself has been freed. The
|
||||
multipathd shutdown code makes sure all the checkers have been freed
|
||||
before freeing the checker_class and calling dlclose() to unload the
|
||||
DSO, but this doesn't guarantee that the checker threads have finished.
|
||||
If one hasn't, the DSO will get unloaded while the thread still running
|
||||
code from it, causing a segfault. Unfortunately, it's not possible to be
|
||||
sure that all tur checker threads have ended during shutdown, without
|
||||
making them joinable.
|
||||
|
||||
However, since libmultipath will never be reinitialized after it has
|
||||
been uninitialzed, not dlclosing the tur checker DSO once a thread is
|
||||
started has minimal cost (keeping the DSO code around until the program
|
||||
exits, which usually happens right after freeing the checkers).
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/checkers.c | 10 +++++++++-
|
||||
libmultipath/checkers.h | 1 +
|
||||
libmultipath/checkers/tur.c | 1 +
|
||||
3 files changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
|
||||
index 8d2be8a9..6359e5d8 100644
|
||||
--- a/libmultipath/checkers.c
|
||||
+++ b/libmultipath/checkers.c
|
||||
@@ -21,6 +21,7 @@ struct checker_class {
|
||||
void (*reset)(void); /* to reset the global variables */
|
||||
const char **msgtable;
|
||||
short msgtable_size;
|
||||
+ int keep_dso;
|
||||
};
|
||||
|
||||
char *checker_state_names[] = {
|
||||
@@ -69,7 +70,7 @@ void free_checker_class(struct checker_class *c)
|
||||
list_del(&c->node);
|
||||
if (c->reset)
|
||||
c->reset();
|
||||
- if (c->handle) {
|
||||
+ if (c->handle && !c->keep_dso) {
|
||||
if (dlclose(c->handle) != 0) {
|
||||
condlog(0, "Cannot unload checker %s: %s",
|
||||
c->name, dlerror());
|
||||
@@ -192,6 +193,13 @@ out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+void checker_keep_dso(struct checker * c)
|
||||
+{
|
||||
+ if (!c || !c->cls)
|
||||
+ return;
|
||||
+ c->cls->keep_dso = 1;
|
||||
+}
|
||||
+
|
||||
void checker_set_fd (struct checker * c, int fd)
|
||||
{
|
||||
if (!c)
|
||||
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
|
||||
index b458118d..f183cff9 100644
|
||||
--- a/libmultipath/checkers.h
|
||||
+++ b/libmultipath/checkers.h
|
||||
@@ -145,6 +145,7 @@ void checker_reset (struct checker *);
|
||||
void checker_set_sync (struct checker *);
|
||||
void checker_set_async (struct checker *);
|
||||
void checker_set_fd (struct checker *, int);
|
||||
+void checker_keep_dso(struct checker *c);
|
||||
void checker_enable (struct checker *);
|
||||
void checker_disable (struct checker *);
|
||||
int checker_check (struct checker *, int);
|
||||
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
||||
index e886fcf8..fd58d62a 100644
|
||||
--- a/libmultipath/checkers/tur.c
|
||||
+++ b/libmultipath/checkers/tur.c
|
||||
@@ -394,6 +394,7 @@ int libcheck_check(struct checker * c)
|
||||
uatomic_set(&ct->running, 1);
|
||||
tur_set_async_timeout(c);
|
||||
setup_thread_attr(&attr, 32 * 1024, 1);
|
||||
+ checker_keep_dso(c);
|
||||
r = pthread_create(&ct->thread, &attr, tur_thread, ct);
|
||||
pthread_attr_destroy(&attr);
|
||||
if (r) {
|
||||
--
|
||||
2.17.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue