device-mapper-multipath-0.8.4-2
Rebased on top of Martin Wilck's queue of ACKed upstream commits * https://github.com/openSUSE/multipath-tools/tree/upstream-queue * All previous patches have been reordered, with the exception of 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch which has been replaced with 0029-fix-boolean-value-with-json-c-0.14.patch Modify 0054-RH-add-mpathconf.patch * remove default enable_foreign and property blacklist_exceptions settings, and deal with the builtin default change from 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch. Fixes bz #1853668 Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch Add 0049-kpartx-fix-Wsign-compare-error.patch * The above two patches have been submitted upstream
This commit is contained in:
parent
c80b4a3ee2
commit
2b0cd7cceb
@ -0,0 +1,35 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 6 Mar 2020 21:50:30 +0100
|
||||
Subject: [PATCH] libmpathpersist: limit PRIN allocation length to 8192 bytes
|
||||
|
||||
Some targets (notably the qemu-pr-helper) don't support PERSISTENT
|
||||
RESERVE IN commands with more than 8192 bytes allocation length.
|
||||
While I have found no explicit requirement in the SCSI specs that
|
||||
the allocation lengh may not exceed 8k, an 8k limit is also enforced
|
||||
by sg_persist(8), and actually by mpathpersist itself for the
|
||||
--allocation-length option, but not for the auto-determined length.
|
||||
|
||||
Fix that.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_pr_ioctl.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
|
||||
index 74b26b0c..1a28cba7 100644
|
||||
--- a/libmpathpersist/mpath_pr_ioctl.c
|
||||
+++ b/libmpathpersist/mpath_pr_ioctl.c
|
||||
@@ -543,5 +543,7 @@ int get_prin_length(int rq_servact)
|
||||
mx_resp_len = 0;
|
||||
break;
|
||||
}
|
||||
+ if (mx_resp_len > MPATH_MAX_PARAM_LEN)
|
||||
+ mx_resp_len = MPATH_MAX_PARAM_LEN;
|
||||
return mx_resp_len;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 6 Mar 2020 23:33:04 +0100
|
||||
Subject: [PATCH] libmpathpersist: format_transportids(): avoid PROUT overflow
|
||||
|
||||
This limits the PERSISTENT RESERVE OUT data size to max. 8192 bytes.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_pr_ioctl.c | 31 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
|
||||
index 1a28cba7..c78e8000 100644
|
||||
--- a/libmpathpersist/mpath_pr_ioctl.c
|
||||
+++ b/libmpathpersist/mpath_pr_ioctl.c
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <stddef.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -138,38 +139,64 @@ retry :
|
||||
return status;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Helper macro to avoid overflow of prout_param_descriptor in
|
||||
+ * format_transportids(). Data must not be written past
|
||||
+ * MPATH_MAX_PARAM_LEN bytes from struct prout_param_descriptor.
|
||||
+ */
|
||||
+#define check_overflow(ofs, n, start, label) \
|
||||
+ do { \
|
||||
+ if ((ofs) + (n) + \
|
||||
+ offsetof(struct prout_param_descriptor, private_buffer) \
|
||||
+ > MPATH_MAX_PARAM_LEN) \
|
||||
+ { \
|
||||
+ (ofs) = (start); \
|
||||
+ goto label; \
|
||||
+ } \
|
||||
+ } while(0)
|
||||
+
|
||||
uint32_t format_transportids(struct prout_param_descriptor *paramp)
|
||||
{
|
||||
unsigned int i = 0, len;
|
||||
uint32_t buff_offset = 4;
|
||||
- memset(paramp->private_buffer, 0, MPATH_MAX_PARAM_LEN);
|
||||
+ memset(paramp->private_buffer, 0, sizeof(paramp->private_buffer));
|
||||
for (i=0; i < paramp->num_transportid; i++ )
|
||||
{
|
||||
+ uint32_t start_offset = buff_offset;
|
||||
+
|
||||
+ check_overflow(buff_offset, 1, start_offset, end_loop);
|
||||
paramp->private_buffer[buff_offset] = (uint8_t)((paramp->trnptid_list[i]->format_code & 0xff)|
|
||||
(paramp->trnptid_list[i]->protocol_id & 0xff));
|
||||
buff_offset += 1;
|
||||
switch(paramp->trnptid_list[i]->protocol_id)
|
||||
{
|
||||
case MPATH_PROTOCOL_ID_FC:
|
||||
+ check_overflow(buff_offset, 7 + 8 + 8,
|
||||
+ start_offset, end_loop);
|
||||
buff_offset += 7;
|
||||
memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->n_port_name, 8);
|
||||
buff_offset +=8 ;
|
||||
buff_offset +=8 ;
|
||||
break;
|
||||
case MPATH_PROTOCOL_ID_SAS:
|
||||
+ check_overflow(buff_offset, 3 + 12,
|
||||
+ start_offset, end_loop);
|
||||
buff_offset += 3;
|
||||
memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->sas_address, 8);
|
||||
buff_offset += 12;
|
||||
break;
|
||||
case MPATH_PROTOCOL_ID_ISCSI:
|
||||
- buff_offset += 1;
|
||||
len = (paramp->trnptid_list[i]->iscsi_name[1] & 0xff)+2;
|
||||
+ check_overflow(buff_offset, 1 + len,
|
||||
+ start_offset, end_loop);
|
||||
+ buff_offset += 1;
|
||||
memcpy(¶mp->private_buffer[buff_offset], ¶mp->trnptid_list[i]->iscsi_name,len);
|
||||
buff_offset += len ;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
+end_loop:
|
||||
buff_offset -= 4;
|
||||
paramp->private_buffer[0] = (unsigned char)((buff_offset >> 24) & 0xff);
|
||||
paramp->private_buffer[1] = (unsigned char)((buff_offset >> 16) & 0xff);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 6 Mar 2020 23:46:47 +0100
|
||||
Subject: [PATCH] libmpathpersist: mpath_format_readfullstatus(): use real
|
||||
buffer size
|
||||
|
||||
This changes no semantics, but it will allow changing the size of
|
||||
prin_readfd.private_buffer in a follow-up patch.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_pr_ioctl.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
|
||||
index c78e8000..fadc9e10 100644
|
||||
--- a/libmpathpersist/mpath_pr_ioctl.c
|
||||
+++ b/libmpathpersist/mpath_pr_ioctl.c
|
||||
@@ -238,6 +238,8 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff)
|
||||
uint32_t additional_length, k, tid_len_len = 0;
|
||||
char tempbuff[MPATH_MAX_PARAM_LEN];
|
||||
struct prin_fulldescr fdesc;
|
||||
+ static const int pbuf_size =
|
||||
+ sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer);
|
||||
|
||||
convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration);
|
||||
convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.number_of_descriptor);
|
||||
@@ -249,16 +251,18 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff)
|
||||
}
|
||||
|
||||
additional_length = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor;
|
||||
- if (additional_length > MPATH_MAX_PARAM_LEN) {
|
||||
+ if (additional_length > pbuf_size) {
|
||||
condlog(3, "PRIN length %u exceeds max length %d", additional_length,
|
||||
- MPATH_MAX_PARAM_LEN);
|
||||
+ pbuf_size);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&fdesc, 0, sizeof(struct prin_fulldescr));
|
||||
|
||||
- memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,MPATH_MAX_PARAM_LEN );
|
||||
- memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0, MPATH_MAX_PARAM_LEN);
|
||||
+ memcpy( tempbuff, pr_buff->prin_descriptor.prin_readfd.private_buffer,
|
||||
+ pbuf_size);
|
||||
+ memset(&pr_buff->prin_descriptor.prin_readfd.private_buffer, 0,
|
||||
+ pbuf_size);
|
||||
|
||||
p =(unsigned char *)tempbuff;
|
||||
ppbuff = (char *)pr_buff->prin_descriptor.prin_readfd.private_buffer;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 17 Mar 2020 17:28:24 -0500
|
||||
Date: Wed, 25 Mar 2020 23:22:46 -0500
|
||||
Subject: [PATCH] libmultipath: assign variable to make gcc happy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Sat, 21 Mar 2020 23:49:59 -0500
|
||||
Date: Wed, 25 Mar 2020 23:22:47 -0500
|
||||
Subject: [PATCH] libmutipath: don't close fd on dm_lib_release
|
||||
|
||||
If dm_hold_control_open() isn't set, when dm_lib_release() is called, it
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 19 Mar 2020 22:17:51 -0500
|
||||
Date: Wed, 25 Mar 2020 23:22:48 -0500
|
||||
Subject: [PATCH] libmultipath: allow force reload with no active paths
|
||||
|
||||
If the partition information has changed on multipath devices (say,
|
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 3 Apr 2020 13:03:01 +0200
|
||||
Subject: [PATCH] kpartx.rules: honor DM_UDEV_DISABLE_OTHER_RULES_FLAG
|
||||
|
||||
10-dm.rules sets DM_UDEV_DISABLE_OTHER_RULES_FLAG for spurious
|
||||
events that should be ignored by other layers. This means devices
|
||||
with DISK_RO set, and devices that have never been set up properly
|
||||
by device-mapper before. This flag should be respected by kpartx.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/kpartx.rules | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index 8f990494..f1bf31ca 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -7,6 +7,7 @@
|
||||
KERNEL!="dm-*", GOTO="kpartx_end"
|
||||
ACTION!="add|change", GOTO="kpartx_end"
|
||||
ENV{DM_UUID}!="?*", GOTO="kpartx_end"
|
||||
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end"
|
||||
|
||||
# Create dm tables for partitions on multipath devices.
|
||||
ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end"
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 2 Apr 2020 18:12:48 +0200
|
||||
Subject: [PATCH] kpartx.rules: check for skip_kpartx on synthetic uevents
|
||||
|
||||
The current test to detect "spurious" uevents, and thus whether to
|
||||
import DM_SUBSYSTEM_UDEV_FLAG1 (the flag for the "skip_kpartx" option)
|
||||
from the udev db is wrong. In 10-dm.rules, DM_UDEV_PRIMARY_SOURCE_FLAG
|
||||
is imported from the db if it isn't set, meaning that it's always 1
|
||||
for active maps. The only events for which DM_SUBSYSTEM_UDEV_FLAG1
|
||||
must not be loaded from the db are the real "primary" events, which
|
||||
are "change" events with DM_ACTIVATION=="1".
|
||||
|
||||
11-dm-mpath.rules resets DM_ACTIVATION to 0 if nothing should change in upper
|
||||
layers. In this case importing DM_SUBSYSTEM_UDEV_FLAG1 is correct, too. kpartx
|
||||
will not be called anyway, because 11-dm-mpath.rules also sets MPATH_UNCHANGED=1.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/kpartx.rules | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index f1bf31ca..d7527d7d 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -13,8 +13,11 @@ ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="kpartx_end"
|
||||
ENV{DM_UUID}!="mpath-?*", GOTO="mpath_kpartx_end"
|
||||
|
||||
# DM_SUBSYSTEM_UDEV_FLAG1 is the "skip_kpartx" flag.
|
||||
-# For events not generated by libdevmapper, we need to fetch it from db.
|
||||
-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1"
|
||||
+# For events not generated by libdevmapper, we need to fetch it from db:
|
||||
+# - "change" events with DM_ACTIVATION!="1" (e.g. partition table changes)
|
||||
+# - "add" events for which rules are not disabled ("coldplug" case)
|
||||
+ENV{DM_ACTIVATION}!="1", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1"
|
||||
+ACTION=="add", IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1"
|
||||
ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="mpath_kpartx_end"
|
||||
|
||||
# 11-dm-mpath.rules sets MPATH_UNCHANGED for events that can be ignored.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,13 +1,12 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:21 +0200
|
||||
Date: Mon, 11 May 2020 14:24:37 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile: more dependency fixes for parallel
|
||||
build
|
||||
|
||||
Extend the late fixes from Christian.
|
||||
|
||||
Cc: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 5 +++--
|
@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
|
||||
Date: Mon, 13 Apr 2020 19:22:02 +0200
|
||||
Subject: [PATCH] libdmmp: Add support for upcoming json-c 0.14.0.
|
||||
|
||||
TRUE/FALSE are not defined anymore. 1 and 0 are used instead.
|
||||
This is backwards compatible, as earlier versions of json-c are
|
||||
using the same integer values in their present definitions.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libdmmp/libdmmp_private.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h
|
||||
index ac85b63f..4378962b 100644
|
||||
--- a/libdmmp/libdmmp_private.h
|
||||
+++ b/libdmmp/libdmmp_private.h
|
||||
@@ -82,7 +82,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \
|
||||
do { \
|
||||
json_type j_type = json_type_null; \
|
||||
json_object *j_obj_tmp = NULL; \
|
||||
- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \
|
||||
+ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != 1) { \
|
||||
_error(ctx, "Invalid JSON output from multipathd IPC: " \
|
||||
"key '%s' not found", key); \
|
||||
rc = DMMP_ERR_IPC_ERROR; \
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 15:27:34 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile.inc: separate out OPTFLAGS
|
||||
|
||||
OPTFLAGS is what distribution builds would typically override. That
|
||||
should not include the warning flags we use.
|
||||
|
||||
Moreover, in the definition of CFLAGS, put $(CFLAGS) first to make it
|
||||
easier for the user to spot her input in the build logs.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index d4d1e0dd..7a59db85 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -93,14 +93,14 @@ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,)
|
||||
|
||||
-OPTFLAGS = -O2 -g -pipe -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
+OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
+WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
- $(WNOCLOBBERED) \
|
||||
- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
- $(STACKPROT) --param=ssp-buffer-size=4
|
||||
+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS)
|
||||
CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2
|
||||
-CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
- -MMD -MP $(CFLAGS)
|
||||
+CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
|
||||
+ -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
+ -MMD -MP
|
||||
BIN_CFLAGS = -fPIE -DPIE
|
||||
LIB_CFLAGS = -fPIC
|
||||
SHARED_FLAGS = -shared
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 16:00:04 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile.inc: allow user settings for
|
||||
LDFLAGS
|
||||
|
||||
This allows e.g. setting LDFLAGS="-m32 -Wl,-b,elf32-i386" to compile
|
||||
for a 32bit target on a 64bit system.
|
||||
|
||||
Note that, like CFLAGS, the variable needs to be set in the environment,
|
||||
not on the "make" command line.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 7a59db85..671dd1ca 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -104,7 +104,7 @@ CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
|
||||
BIN_CFLAGS = -fPIE -DPIE
|
||||
LIB_CFLAGS = -fPIC
|
||||
SHARED_FLAGS = -shared
|
||||
-LDFLAGS = -Wl,-z,relro -Wl,-z,now
|
||||
+LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,now
|
||||
BIN_LDFLAGS = -pie
|
||||
|
||||
# Check whether a function with name $1 has been declared in header file $2.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:24 +0200
|
||||
Date: Mon, 11 May 2020 17:19:37 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered
|
||||
|
||||
We need to ignore -Wclobbered because gcc has trouble dealing with glibc's
|
||||
@ -9,14 +9,13 @@ 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
|
||||
index 671dd1ca..e7256e3a 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \
|
||||
@ -26,8 +25,8 @@ index d4d1e0dd..9060ac9b 100644
|
||||
-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 \
|
||||
OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,11 +1,10 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:25 +0200
|
||||
Date: Mon, 11 May 2020 16:02:25 +0200
|
||||
Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t
|
||||
|
||||
Otherwise compilation for 32bit targets spits out warnings.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 16 ++++++++--------
|
@ -1,21 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:26 +0200
|
||||
Date: Mon, 11 May 2020 16:03:58 +0200
|
||||
Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons
|
||||
|
||||
Fix some more compiler warnings about signed/unsigned comparison.
|
||||
I've observed these only on 32bit builds, therefore they went unnoticed
|
||||
before.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_pr_ioctl.c | 2 +-
|
||||
libmultipath/print.c | 12 ++++++------
|
||||
libmultipath/prioritizers/alua_spc3.h | 2 +-
|
||||
multipathd/cli_handlers.c | 20 ++++++++++----------
|
||||
multipathd/main.c | 2 +-
|
||||
4 files changed, 18 insertions(+), 18 deletions(-)
|
||||
5 files changed, 19 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
|
||||
index fadc9e10..126601c3 100644
|
||||
--- a/libmpathpersist/mpath_pr_ioctl.c
|
||||
+++ b/libmpathpersist/mpath_pr_ioctl.c
|
||||
@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff)
|
||||
uint32_t additional_length, k, tid_len_len = 0;
|
||||
char tempbuff[MPATH_MAX_PARAM_LEN];
|
||||
struct prin_fulldescr fdesc;
|
||||
- static const int pbuf_size =
|
||||
+ static const unsigned int pbuf_size =
|
||||
sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer);
|
||||
|
||||
convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration);
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index b944ef32..298b3764 100644
|
||||
--- a/libmultipath/print.c
|
@ -1,13 +1,12 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:39:27 +0200
|
||||
Date: Mon, 11 May 2020 22:22:25 +0200
|
||||
Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit
|
||||
|
||||
On architectures where sizeof(long) == sizeof(int), the code wouldn't
|
||||
work as intended. Use strtoul instead. As strtoul happily parses
|
||||
negative numbers as input, require the number to begin with a digit.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 11 +++++++----
|
@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 18:24:19 +0200
|
||||
Subject: [PATCH] multipath-tools tests/Makefile: add -lmpathcmd to LIBDEPS
|
||||
|
||||
Make sure the linker finds libmpathcmd.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index 77ff3249..028c9ea7 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -10,7 +10,7 @@ W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)
|
||||
|
||||
CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \
|
||||
-Wno-unused-parameter $(W_MISSING_INITIALIZERS)
|
||||
-LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka
|
||||
+LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka
|
||||
|
||||
TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \
|
||||
alias directio
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 23:44:19 +0200
|
||||
Subject: [PATCH] multipath tools tests/Makefile: Fix OBJDEPS for hwtable-test
|
||||
|
||||
OBJDEPS needs to list object files that _call_ functions we want
|
||||
to wrap, but it should _not_ list the object files where these
|
||||
functions are defined; otherwise the linker might resolve these
|
||||
symbols before they can be wrapped.
|
||||
|
||||
(Observed on i586 with gcc 9.3.1, ld 2.34.0, where wrapping
|
||||
prio_getprio() doesn't work with prio.o in OBJDEPS).
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index 028c9ea7..1b8706a7 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -41,7 +41,7 @@ endif
|
||||
dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu
|
||||
hwtable-test_TESTDEPS := test-lib.o
|
||||
hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \
|
||||
- ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o
|
||||
+ ../libmultipath/structs.o
|
||||
hwtable-test_LIBDEPS := -ludev -lpthread -ldl
|
||||
blacklist-test_TESTDEPS := test-log.o
|
||||
blacklist-test_OBJDEPS := ../libmultipath/blacklist.o
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 23:43:02 +0200
|
||||
Subject: [PATCH] multipath-tools tests/test-lib.c: drop
|
||||
__wrap_is_claimed_by_foreign
|
||||
|
||||
is_claimed_by_foreign() is an inline function and can't be wrapped.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/test-lib.c | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
diff --git a/tests/test-lib.c b/tests/test-lib.c
|
||||
index 59275163..00bae58e 100644
|
||||
--- a/tests/test-lib.c
|
||||
+++ b/tests/test-lib.c
|
||||
@@ -56,12 +56,6 @@ int __wrap_execute_program(char *path, char *value, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-bool __wrap_is_claimed_by_foreign(struct udev_device *ud)
|
||||
-{
|
||||
- condlog(5, "%s: %p", __func__, ud);
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
struct udev_list_entry
|
||||
*__wrap_udev_device_get_properties_list_entry(struct udev_device *ud)
|
||||
{
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 00:11:39 +0200
|
||||
Subject: [PATCH] multipath-tools tests/directio: fix -Wmaybe-uninitalized
|
||||
warning
|
||||
|
||||
Initialize aio_grp to satisfy gcc.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/directio.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/directio.c b/tests/directio.c
|
||||
index 3cd7a520..66aaf0eb 100644
|
||||
--- a/tests/directio.c
|
||||
+++ b/tests/directio.c
|
||||
@@ -316,7 +316,7 @@ static void test_init_free(void **state)
|
||||
{
|
||||
int i, count = 0;
|
||||
struct checker c[4096] = {0};
|
||||
- struct aio_group *aio_grp;
|
||||
+ struct aio_group *aio_grp = NULL;
|
||||
|
||||
assert_true(list_empty(&aio_grp_list));
|
||||
will_return(__wrap_io_setup, 0);
|
||||
--
|
||||
2.17.2
|
||||
|
83
0021-libmultipath-move-libsg-into-libmultipath.patch
Normal file
83
0021-libmultipath-move-libsg-into-libmultipath.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 16:46:15 +0200
|
||||
Subject: [PATCH] libmultipath: move libsg into libmultipath
|
||||
|
||||
sg_read() is called from readsector0 and emc_clariion. Move it
|
||||
to libmultipath/, where all common code resides.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 3 ++-
|
||||
libmultipath/checkers/Makefile | 6 +++---
|
||||
libmultipath/{checkers => }/libsg.c | 0
|
||||
libmultipath/{checkers => }/libsg.h | 0
|
||||
libmultipath/prioritizers/Makefile | 2 +-
|
||||
5 files changed, 6 insertions(+), 5 deletions(-)
|
||||
rename libmultipath/{checkers => }/libsg.c (100%)
|
||||
rename libmultipath/{checkers => }/libsg.h (100%)
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index ad690a49..f19b7ad2 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -47,7 +47,8 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
|
||||
switchgroup.o uxsock.o print.o alias.o log_pthread.o \
|
||||
log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
|
||||
lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \
|
||||
- io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o
|
||||
+ io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \
|
||||
+ libsg.o
|
||||
|
||||
all: $(LIBS)
|
||||
|
||||
diff --git a/libmultipath/checkers/Makefile b/libmultipath/checkers/Makefile
|
||||
index 02caea64..01c04510 100644
|
||||
--- a/libmultipath/checkers/Makefile
|
||||
+++ b/libmultipath/checkers/Makefile
|
||||
@@ -17,10 +17,10 @@ LIBS= \
|
||||
|
||||
all: $(LIBS)
|
||||
|
||||
-libcheckdirectio.so: libsg.o directio.o
|
||||
+libcheckdirectio.so: directio.o
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -laio
|
||||
|
||||
-libcheck%.so: libsg.o %.o
|
||||
+libcheck%.so: %.o
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^
|
||||
|
||||
install:
|
||||
@@ -32,7 +32,7 @@ uninstall:
|
||||
clean: dep_clean
|
||||
$(RM) core *.a *.o *.gz *.so
|
||||
|
||||
-OBJS := $(LIBS:libcheck%.so=%.o) libsg.o directio.o
|
||||
+OBJS := $(LIBS:libcheck%.so=%.o)
|
||||
.SECONDARY: $(OBJS)
|
||||
|
||||
include $(wildcard $(OBJS:.o=.d))
|
||||
diff --git a/libmultipath/checkers/libsg.c b/libmultipath/libsg.c
|
||||
similarity index 100%
|
||||
rename from libmultipath/checkers/libsg.c
|
||||
rename to libmultipath/libsg.c
|
||||
diff --git a/libmultipath/checkers/libsg.h b/libmultipath/libsg.h
|
||||
similarity index 100%
|
||||
rename from libmultipath/checkers/libsg.h
|
||||
rename to libmultipath/libsg.h
|
||||
diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile
|
||||
index 9d0fe03c..fc6e0e0c 100644
|
||||
--- a/libmultipath/prioritizers/Makefile
|
||||
+++ b/libmultipath/prioritizers/Makefile
|
||||
@@ -28,7 +28,7 @@ endif
|
||||
|
||||
all: $(LIBS)
|
||||
|
||||
-libpriopath_latency.so: path_latency.o ../checkers/libsg.o
|
||||
+libpriopath_latency.so: path_latency.o
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^ -lm
|
||||
|
||||
libprio%.so: %.o
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,13 +1,12 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 12 May 2020 22:38:22 +0200
|
||||
Date: Tue, 12 May 2020 22:13:51 +0200
|
||||
Subject: [PATCH] multipath-tools Makefile: add install dependency
|
||||
|
||||
$(libdir) must exist before running "make install" on prioritizer, checker,
|
||||
and foreign libraries.
|
||||
|
||||
Cc: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 4 ++++
|
89
0023-libmultipath-make-libmp_dm_init-optional.patch
Normal file
89
0023-libmultipath-make-libmp_dm_init-optional.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:08:40 -0500
|
||||
Subject: [PATCH] libmultipath: make libmp_dm_init optional
|
||||
|
||||
Move dm_initialized out of libmp_dm_task_create(), and add
|
||||
a function skip_libmp_dm_init() so that users of libmultipath can skip
|
||||
initializing device-mapper. This is needed for other programs that
|
||||
use libmultipath (or a library that depends on it) but want to control
|
||||
how device-mapper is set up.
|
||||
|
||||
Also make dm_prereq a global function.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 17 +++++++++++++----
|
||||
libmultipath/devmapper.h | 3 ++-
|
||||
2 files changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 13a1cf53..7ed494a1 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -33,6 +33,8 @@
|
||||
#define MAX_WAIT 5
|
||||
#define LOOPS_PER_SEC 5
|
||||
|
||||
+static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
|
||||
+
|
||||
static int dm_conf_verbosity;
|
||||
|
||||
#ifdef LIBDM_API_DEFERRED
|
||||
@@ -229,7 +231,7 @@ dm_tgt_prereq (unsigned int *ver)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int dm_prereq(unsigned int *v)
|
||||
+int dm_prereq(unsigned int *v)
|
||||
{
|
||||
if (dm_lib_prereq())
|
||||
return 1;
|
||||
@@ -243,7 +245,7 @@ void libmp_udev_set_sync_support(int on)
|
||||
libmp_dm_udev_sync = !!on;
|
||||
}
|
||||
|
||||
-void libmp_dm_init(void)
|
||||
+static void libmp_dm_init(void)
|
||||
{
|
||||
struct config *conf;
|
||||
int verbosity;
|
||||
@@ -262,11 +264,18 @@ void libmp_dm_init(void)
|
||||
dm_udev_set_sync_support(libmp_dm_udev_sync);
|
||||
}
|
||||
|
||||
+static void _do_skip_libmp_dm_init(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+void skip_libmp_dm_init(void)
|
||||
+{
|
||||
+ pthread_once(&dm_initialized, _do_skip_libmp_dm_init);
|
||||
+}
|
||||
+
|
||||
struct dm_task*
|
||||
libmp_dm_task_create(int task)
|
||||
{
|
||||
- static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
|
||||
-
|
||||
pthread_once(&dm_initialized, libmp_dm_init);
|
||||
return dm_task_create(task);
|
||||
}
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 7557a86b..17fc9faf 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -28,7 +28,8 @@
|
||||
#define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1)
|
||||
|
||||
void dm_init(int verbosity);
|
||||
-void libmp_dm_init(void);
|
||||
+int dm_prereq(unsigned int *v);
|
||||
+void skip_libmp_dm_init(void);
|
||||
void libmp_udev_set_sync_support(int on);
|
||||
struct dm_task *libmp_dm_task_create(int task);
|
||||
int dm_drv_version (unsigned int * version);
|
||||
--
|
||||
2.17.2
|
||||
|
108
0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch
Normal file
108
0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:08:41 -0500
|
||||
Subject: [PATCH] libmultipath: make sysfs_is_multipathed able to return wwid
|
||||
|
||||
sysfs_is_multipathed reads the wwid of the dm device holding a path to
|
||||
check if its a multipath device. Add code to optinally set pp->wwid to
|
||||
that wwid. This will be used by a future patch.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/sysfs.c | 24 +++++++++++++++++++-----
|
||||
libmultipath/sysfs.h | 2 +-
|
||||
multipath/main.c | 7 ++++---
|
||||
3 files changed, 24 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
|
||||
index 62ec2ed7..12a82d95 100644
|
||||
--- a/libmultipath/sysfs.c
|
||||
+++ b/libmultipath/sysfs.c
|
||||
@@ -295,7 +295,7 @@ static int select_dm_devs(const struct dirent *di)
|
||||
return fnmatch("dm-*", di->d_name, FNM_FILE_NAME) == 0;
|
||||
}
|
||||
|
||||
-bool sysfs_is_multipathed(const struct path *pp)
|
||||
+bool sysfs_is_multipathed(struct path *pp, bool set_wwid)
|
||||
{
|
||||
char pathbuf[PATH_MAX];
|
||||
struct scandir_result sr;
|
||||
@@ -325,7 +325,7 @@ bool sysfs_is_multipathed(const struct path *pp)
|
||||
for (i = 0; i < r && !found; i++) {
|
||||
long fd;
|
||||
int nr;
|
||||
- char uuid[6];
|
||||
+ char uuid[WWID_SIZE + UUID_PREFIX_LEN];
|
||||
|
||||
if (safe_snprintf(pathbuf + n, sizeof(pathbuf) - n,
|
||||
"/%s/dm/uuid", di[i]->d_name))
|
||||
@@ -339,12 +339,26 @@ bool sysfs_is_multipathed(const struct path *pp)
|
||||
|
||||
pthread_cleanup_push(close_fd, (void *)fd);
|
||||
nr = read(fd, uuid, sizeof(uuid));
|
||||
- if (nr == sizeof(uuid) && !memcmp(uuid, "mpath-", sizeof(uuid)))
|
||||
+ if (nr > (int)UUID_PREFIX_LEN &&
|
||||
+ !memcmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN))
|
||||
found = true;
|
||||
else if (nr < 0) {
|
||||
- condlog(1, "%s: error reading from %s: %s",
|
||||
- __func__, pathbuf, strerror(errno));
|
||||
+ condlog(1, "%s: error reading from %s: %m",
|
||||
+ __func__, pathbuf);
|
||||
}
|
||||
+ if (found && set_wwid) {
|
||||
+ nr -= UUID_PREFIX_LEN;
|
||||
+ memcpy(pp->wwid, uuid + UUID_PREFIX_LEN, nr);
|
||||
+ if (nr == WWID_SIZE) {
|
||||
+ condlog(4, "%s: overflow while reading from %s",
|
||||
+ __func__, pathbuf);
|
||||
+ pp->wwid[0] = '\0';
|
||||
+ } else {
|
||||
+ pp->wwid[nr] = '\0';
|
||||
+ strchop(pp->wwid);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h
|
||||
index 9ae30b39..72b39ab2 100644
|
||||
--- a/libmultipath/sysfs.h
|
||||
+++ b/libmultipath/sysfs.h
|
||||
@@ -14,5 +14,5 @@ ssize_t sysfs_bin_attr_get_value(struct udev_device *dev, const char *attr_name,
|
||||
unsigned char * value, size_t value_len);
|
||||
int sysfs_get_size (struct path *pp, unsigned long long * size);
|
||||
int sysfs_check_holders(char * check_devt, char * new_devt);
|
||||
-bool sysfs_is_multipathed(const struct path *pp);
|
||||
+bool sysfs_is_multipathed(struct path *pp, bool set_wwid);
|
||||
#endif
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index cf9d2a28..545ead87 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -638,7 +638,8 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
* Shortcut for find_multipaths smart:
|
||||
* Quick check if path is already multipathed.
|
||||
*/
|
||||
- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0))) {
|
||||
+ if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0),
|
||||
+ false)) {
|
||||
r = RTVL_YES;
|
||||
goto print_valid;
|
||||
}
|
||||
@@ -747,8 +748,8 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
/*
|
||||
* Check if we raced with multipathd
|
||||
*/
|
||||
- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0)) ?
|
||||
- RTVL_YES : RTVL_NO;
|
||||
+ r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0),
|
||||
+ false) ? RTVL_YES : RTVL_NO;
|
||||
}
|
||||
goto print_valid;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
777
0025-multipath-centralize-validation-code.patch
Normal file
777
0025-multipath-centralize-validation-code.patch
Normal file
@ -0,0 +1,777 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:08:42 -0500
|
||||
Subject: [PATCH] multipath: centralize validation code
|
||||
|
||||
This code pulls the multipath path validation code out of configure(),
|
||||
and puts it into its own function, check_path_valid(). This function
|
||||
calls a new libmultipath function, is_path_valid() to check just path
|
||||
requested. This seperation exists so that is_path_valid() can be reused
|
||||
by future code. This code will give almost the same answer as the
|
||||
existing code, with the exception that now, if a device is currently
|
||||
multipathed, it will always be a valid multipath path.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 2 +-
|
||||
libmultipath/devmapper.c | 45 ++++++
|
||||
libmultipath/devmapper.h | 1 +
|
||||
libmultipath/structs.h | 24 +---
|
||||
libmultipath/valid.c | 118 ++++++++++++++++
|
||||
libmultipath/valid.h | 42 ++++++
|
||||
libmultipath/wwids.c | 10 +-
|
||||
multipath/main.c | 296 +++++++++++++++++----------------------
|
||||
8 files changed, 343 insertions(+), 195 deletions(-)
|
||||
create mode 100644 libmultipath/valid.c
|
||||
create mode 100644 libmultipath/valid.h
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index f19b7ad2..e5dac5ea 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -48,7 +48,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
|
||||
log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
|
||||
lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \
|
||||
io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \
|
||||
- libsg.o
|
||||
+ libsg.o valid.o
|
||||
|
||||
all: $(LIBS)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 7ed494a1..27d52398 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -770,6 +770,51 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Return
|
||||
+ * 1 : map with uuid exists
|
||||
+ * 0 : map with uuid doesn't exist
|
||||
+ * -1 : error
|
||||
+ */
|
||||
+int
|
||||
+dm_map_present_by_uuid(const char *uuid)
|
||||
+{
|
||||
+ struct dm_task *dmt;
|
||||
+ struct dm_info info;
|
||||
+ char prefixed_uuid[WWID_SIZE + UUID_PREFIX_LEN];
|
||||
+ int r = -1;
|
||||
+
|
||||
+ if (!uuid || uuid[0] == '\0')
|
||||
+ return 0;
|
||||
+
|
||||
+ if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
|
||||
+ goto out;
|
||||
+
|
||||
+ dm_task_no_open_count(dmt);
|
||||
+
|
||||
+ if (!dm_task_set_uuid(dmt, prefixed_uuid))
|
||||
+ goto out_task;
|
||||
+
|
||||
+ if (!dm_task_run(dmt))
|
||||
+ goto out_task;
|
||||
+
|
||||
+ if (!dm_task_get_info(dmt, &info))
|
||||
+ goto out_task;
|
||||
+
|
||||
+ r = !!info.exists;
|
||||
+
|
||||
+out_task:
|
||||
+ dm_task_destroy(dmt);
|
||||
+out:
|
||||
+ if (r < 0)
|
||||
+ condlog(3, "%s: dm command failed in %s: %s", uuid,
|
||||
+ __FUNCTION__, strerror(errno));
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
dm_dev_t (const char * mapname, char * dev_t, int len)
|
||||
{
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 17fc9faf..5ed7edc5 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -39,6 +39,7 @@ int dm_simplecmd_noflush (int, const char *, uint16_t);
|
||||
int dm_addmap_create (struct multipath *mpp, char *params);
|
||||
int dm_addmap_reload (struct multipath *mpp, char *params, int flush);
|
||||
int dm_map_present (const char *);
|
||||
+int dm_map_present_by_uuid(const char *uuid);
|
||||
int dm_get_map(const char *, unsigned long long *, char *);
|
||||
int dm_get_status(const char *, char *);
|
||||
int dm_type(const char *, char *);
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 9bd39eb1..d69bc2e9 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -101,29 +101,13 @@ enum yes_no_undef_states {
|
||||
YNU_YES,
|
||||
};
|
||||
|
||||
-#define _FIND_MULTIPATHS_F (1 << 1)
|
||||
-#define _FIND_MULTIPATHS_I (1 << 2)
|
||||
-#define _FIND_MULTIPATHS_N (1 << 3)
|
||||
-/*
|
||||
- * _FIND_MULTIPATHS_F must have the same value as YNU_YES.
|
||||
- * Generate a compile time error if that isn't the case.
|
||||
- */
|
||||
-extern char ___error1___[-(_FIND_MULTIPATHS_F != YNU_YES)];
|
||||
-
|
||||
-#define find_multipaths_on(conf) \
|
||||
- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_F))
|
||||
-#define ignore_wwids_on(conf) \
|
||||
- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_I))
|
||||
-#define ignore_new_devs_on(conf) \
|
||||
- (!!((conf)->find_multipaths & _FIND_MULTIPATHS_N))
|
||||
-
|
||||
enum find_multipaths_states {
|
||||
FIND_MULTIPATHS_UNDEF = YNU_UNDEF,
|
||||
FIND_MULTIPATHS_OFF = YNU_NO,
|
||||
- FIND_MULTIPATHS_ON = _FIND_MULTIPATHS_F,
|
||||
- FIND_MULTIPATHS_GREEDY = _FIND_MULTIPATHS_I,
|
||||
- FIND_MULTIPATHS_SMART = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_I,
|
||||
- FIND_MULTIPATHS_STRICT = _FIND_MULTIPATHS_F|_FIND_MULTIPATHS_N,
|
||||
+ FIND_MULTIPATHS_ON = YNU_YES,
|
||||
+ FIND_MULTIPATHS_GREEDY,
|
||||
+ FIND_MULTIPATHS_SMART,
|
||||
+ FIND_MULTIPATHS_STRICT,
|
||||
__FIND_MULTIPATHS_LAST,
|
||||
};
|
||||
|
||||
diff --git a/libmultipath/valid.c b/libmultipath/valid.c
|
||||
new file mode 100644
|
||||
index 00000000..456b1f6e
|
||||
--- /dev/null
|
||||
+++ b/libmultipath/valid.c
|
||||
@@ -0,0 +1,118 @@
|
||||
+/*
|
||||
+ Copyright (c) 2020 Benjamin Marzinski, IBM
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU General Public License
|
||||
+ as published by the Free Software Foundation; either version 2
|
||||
+ of the License, or (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+#include <stddef.h>
|
||||
+#include <errno.h>
|
||||
+#include <libudev.h>
|
||||
+
|
||||
+#include "vector.h"
|
||||
+#include "config.h"
|
||||
+#include "debug.h"
|
||||
+#include "util.h"
|
||||
+#include "devmapper.h"
|
||||
+#include "discovery.h"
|
||||
+#include "wwids.h"
|
||||
+#include "sysfs.h"
|
||||
+#include "blacklist.h"
|
||||
+#include "mpath_cmd.h"
|
||||
+#include "valid.h"
|
||||
+
|
||||
+int
|
||||
+is_path_valid(const char *name, struct config *conf, struct path *pp,
|
||||
+ bool check_multipathd)
|
||||
+{
|
||||
+ int r;
|
||||
+ int fd;
|
||||
+
|
||||
+ if (!pp || !name || !conf)
|
||||
+ return PATH_IS_ERROR;
|
||||
+
|
||||
+ if (conf->find_multipaths <= FIND_MULTIPATHS_UNDEF ||
|
||||
+ conf->find_multipaths >= __FIND_MULTIPATHS_LAST)
|
||||
+ return PATH_IS_ERROR;
|
||||
+
|
||||
+ if (safe_sprintf(pp->dev, "%s", name))
|
||||
+ return PATH_IS_ERROR;
|
||||
+
|
||||
+ if (sysfs_is_multipathed(pp, true)) {
|
||||
+ if (pp->wwid[0] == '\0')
|
||||
+ return PATH_IS_ERROR;
|
||||
+ return PATH_IS_VALID_NO_CHECK;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * "multipath -u" may be run before the daemon is started. In this
|
||||
+ * case, systemd might own the socket but might delay multipathd
|
||||
+ * startup until some other unit (udev settle!) has finished
|
||||
+ * starting. With many LUNs, the listen backlog may be exceeded, which
|
||||
+ * would cause connect() to block. This causes udev workers calling
|
||||
+ * "multipath -u" to hang, and thus creates a deadlock, until "udev
|
||||
+ * settle" times out. To avoid this, call connect() in non-blocking
|
||||
+ * mode here, and take EAGAIN as indication for a filled-up systemd
|
||||
+ * backlog.
|
||||
+ */
|
||||
+
|
||||
+ if (check_multipathd) {
|
||||
+ fd = __mpath_connect(1);
|
||||
+ if (fd < 0) {
|
||||
+ if (errno != EAGAIN && !systemd_service_enabled(name)) {
|
||||
+ condlog(3, "multipathd not running or enabled");
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+ }
|
||||
+ } else
|
||||
+ mpath_disconnect(fd);
|
||||
+ }
|
||||
+
|
||||
+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block", name);
|
||||
+ if (!pp->udev)
|
||||
+ return PATH_IS_ERROR;
|
||||
+
|
||||
+ r = pathinfo(pp, conf, DI_SYSFS | DI_WWID | DI_BLACKLIST);
|
||||
+ if (r == PATHINFO_SKIPPED)
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+ else if (r)
|
||||
+ return PATH_IS_ERROR;
|
||||
+
|
||||
+ if (pp->wwid[0] == '\0')
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+
|
||||
+ if (pp->udev && pp->uid_attribute &&
|
||||
+ filter_property(conf, pp->udev, 3, pp->uid_attribute) > 0)
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+
|
||||
+ r = is_failed_wwid(pp->wwid);
|
||||
+ if (r != WWID_IS_NOT_FAILED) {
|
||||
+ if (r == WWID_IS_FAILED)
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+ return PATH_IS_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (conf->find_multipaths == FIND_MULTIPATHS_GREEDY)
|
||||
+ return PATH_IS_VALID;
|
||||
+
|
||||
+ if (check_wwids_file(pp->wwid, 0) == 0)
|
||||
+ return PATH_IS_VALID_NO_CHECK;
|
||||
+
|
||||
+ if (dm_map_present_by_uuid(pp->wwid) == 1)
|
||||
+ return PATH_IS_VALID;
|
||||
+
|
||||
+ /* all these act like FIND_MULTIPATHS_STRICT for finding if a
|
||||
+ * path is valid */
|
||||
+ if (conf->find_multipaths != FIND_MULTIPATHS_SMART)
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
+
|
||||
+ return PATH_IS_MAYBE_VALID;
|
||||
+}
|
||||
diff --git a/libmultipath/valid.h b/libmultipath/valid.h
|
||||
new file mode 100644
|
||||
index 00000000..ce1c7cbf
|
||||
--- /dev/null
|
||||
+++ b/libmultipath/valid.h
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ Copyright (c) 2020 Benjamin Marzinski, IBM
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU General Public License
|
||||
+ as published by the Free Software Foundation; either version 2
|
||||
+ of the License, or (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+#ifndef _VALID_H
|
||||
+#define _VALID_H
|
||||
+
|
||||
+/*
|
||||
+ * PATH_IS_VALID_NO_CHECK is returned when multipath should claim
|
||||
+ * the path, regardless of whether is has been released to systemd
|
||||
+ * already.
|
||||
+ * PATH_IS_VALID is returned by is_path_valid, when the path is
|
||||
+ * valid only if it hasn't been released to systemd already.
|
||||
+ * PATH_IS_MAYBE_VALID is returned when the the path would be valid
|
||||
+ * if other paths with the same wwid existed. It is up to the caller
|
||||
+ * to check for these other paths.
|
||||
+ */
|
||||
+enum is_path_valid_result {
|
||||
+ PATH_IS_ERROR = -1,
|
||||
+ PATH_IS_NOT_VALID,
|
||||
+ PATH_IS_VALID,
|
||||
+ PATH_IS_VALID_NO_CHECK,
|
||||
+ PATH_IS_MAYBE_VALID,
|
||||
+ PATH_MAX_VALID_RESULT, /* only for bounds checking */
|
||||
+};
|
||||
+
|
||||
+int is_path_valid(const char *name, struct config *conf, struct path *pp,
|
||||
+ bool check_multipathd);
|
||||
+
|
||||
+#endif /* _VALID_D */
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 28a2150d..637cb0ab 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -289,19 +289,19 @@ out:
|
||||
int
|
||||
should_multipath(struct path *pp1, vector pathvec, vector mpvec)
|
||||
{
|
||||
- int i, ignore_new_devs, find_multipaths;
|
||||
+ int i, find_multipaths;
|
||||
struct path *pp2;
|
||||
struct config *conf;
|
||||
|
||||
conf = get_multipath_config();
|
||||
- ignore_new_devs = ignore_new_devs_on(conf);
|
||||
- find_multipaths = find_multipaths_on(conf);
|
||||
+ find_multipaths = conf->find_multipaths;
|
||||
put_multipath_config(conf);
|
||||
- if (!find_multipaths && !ignore_new_devs)
|
||||
+ if (find_multipaths == FIND_MULTIPATHS_OFF ||
|
||||
+ find_multipaths == FIND_MULTIPATHS_GREEDY)
|
||||
return 1;
|
||||
|
||||
condlog(4, "checking if %s should be multipathed", pp1->dev);
|
||||
- if (!ignore_new_devs) {
|
||||
+ if (find_multipaths != FIND_MULTIPATHS_STRICT) {
|
||||
char tmp_wwid[WWID_SIZE];
|
||||
struct multipath *mp = find_mp_by_wwid(mpvec, pp1->wwid);
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 545ead87..953fab27 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -63,21 +63,18 @@
|
||||
#include "propsel.h"
|
||||
#include "time-util.h"
|
||||
#include "file.h"
|
||||
+#include "valid.h"
|
||||
|
||||
int logsink;
|
||||
struct udev *udev;
|
||||
struct config *multipath_conf;
|
||||
|
||||
/*
|
||||
- * Return values of configure(), print_cmd_valid(), and main().
|
||||
- * RTVL_{YES,NO} are synonyms for RTVL_{OK,FAIL} for the CMD_VALID_PATH case.
|
||||
+ * Return values of configure(), check_path_valid(), and main().
|
||||
*/
|
||||
enum {
|
||||
RTVL_OK = 0,
|
||||
- RTVL_YES = RTVL_OK,
|
||||
RTVL_FAIL = 1,
|
||||
- RTVL_NO = RTVL_FAIL,
|
||||
- RTVL_MAYBE, /* only used internally, never returned */
|
||||
RTVL_RETRY, /* returned by configure(), not by main() */
|
||||
};
|
||||
|
||||
@@ -269,9 +266,6 @@ get_dm_mpvec (enum mpath_cmds cmd, vector curmp, vector pathvec, char * refwwid)
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (cmd == CMD_VALID_PATH)
|
||||
- continue;
|
||||
-
|
||||
dm_get_map(mpp->alias, &mpp->size, params);
|
||||
condlog(3, "params = %s", params);
|
||||
dm_get_status(mpp->alias, status);
|
||||
@@ -491,10 +485,11 @@ static int print_cmd_valid(int k, const vector pathvec,
|
||||
struct timespec until;
|
||||
struct path *pp;
|
||||
|
||||
- if (k != RTVL_YES && k != RTVL_NO && k != RTVL_MAYBE)
|
||||
- return RTVL_NO;
|
||||
+ if (k != PATH_IS_VALID && k != PATH_IS_NOT_VALID &&
|
||||
+ k != PATH_IS_MAYBE_VALID)
|
||||
+ return PATH_IS_NOT_VALID;
|
||||
|
||||
- if (k == RTVL_MAYBE) {
|
||||
+ if (k == PATH_IS_MAYBE_VALID) {
|
||||
/*
|
||||
* Caller ensures that pathvec[0] is the path to
|
||||
* examine.
|
||||
@@ -504,7 +499,7 @@ static int print_cmd_valid(int k, const vector pathvec,
|
||||
wait = find_multipaths_check_timeout(
|
||||
pp, pp->find_multipaths_timeout, &until);
|
||||
if (wait != FIND_MULTIPATHS_WAITING)
|
||||
- k = RTVL_NO;
|
||||
+ k = PATH_IS_NOT_VALID;
|
||||
} else if (pathvec != NULL && (pp = VECTOR_SLOT(pathvec, 0)))
|
||||
wait = find_multipaths_check_timeout(pp, 0, &until);
|
||||
if (wait == FIND_MULTIPATHS_WAITING)
|
||||
@@ -513,9 +508,9 @@ static int print_cmd_valid(int k, const vector pathvec,
|
||||
else if (wait == FIND_MULTIPATHS_WAIT_DONE)
|
||||
printf("FIND_MULTIPATHS_WAIT_UNTIL=\"0\"\n");
|
||||
printf("DM_MULTIPATH_DEVICE_PATH=\"%d\"\n",
|
||||
- k == RTVL_MAYBE ? 2 : k == RTVL_YES ? 1 : 0);
|
||||
+ k == PATH_IS_MAYBE_VALID ? 2 : k == PATH_IS_VALID ? 1 : 0);
|
||||
/* Never return RTVL_MAYBE */
|
||||
- return k == RTVL_NO ? RTVL_NO : RTVL_YES;
|
||||
+ return k == PATH_IS_NOT_VALID ? PATH_IS_NOT_VALID : PATH_IS_VALID;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -548,7 +543,6 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
int di_flag = 0;
|
||||
char * refwwid = NULL;
|
||||
char * dev = NULL;
|
||||
- bool released = released_to_systemd();
|
||||
|
||||
/*
|
||||
* allocate core vectors to store paths and multipaths
|
||||
@@ -573,7 +567,7 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
cmd != CMD_REMOVE_WWID &&
|
||||
(filter_devnode(conf->blist_devnode,
|
||||
conf->elist_devnode, dev) > 0)) {
|
||||
- goto print_valid;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -581,14 +575,10 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
* failing the translation is fatal (by policy)
|
||||
*/
|
||||
if (devpath) {
|
||||
- int failed = get_refwwid(cmd, devpath, dev_type,
|
||||
- pathvec, &refwwid);
|
||||
+ get_refwwid(cmd, devpath, dev_type, pathvec, &refwwid);
|
||||
if (!refwwid) {
|
||||
condlog(4, "%s: failed to get wwid", devpath);
|
||||
- if (failed == 2 && cmd == CMD_VALID_PATH)
|
||||
- goto print_valid;
|
||||
- else
|
||||
- condlog(3, "scope is null");
|
||||
+ condlog(3, "scope is null");
|
||||
goto out;
|
||||
}
|
||||
if (cmd == CMD_REMOVE_WWID) {
|
||||
@@ -614,53 +604,6 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
goto out;
|
||||
}
|
||||
condlog(3, "scope limited to %s", refwwid);
|
||||
- /* If you are ignoring the wwids file and find_multipaths is
|
||||
- * set, you need to actually check if there are two available
|
||||
- * paths to determine if this path should be multipathed. To
|
||||
- * do this, we put off the check until after discovering all
|
||||
- * the paths.
|
||||
- * Paths listed in the wwids file are always considered valid.
|
||||
- */
|
||||
- if (cmd == CMD_VALID_PATH) {
|
||||
- if (is_failed_wwid(refwwid) == WWID_IS_FAILED) {
|
||||
- r = RTVL_NO;
|
||||
- goto print_valid;
|
||||
- }
|
||||
- if ((!find_multipaths_on(conf) &&
|
||||
- ignore_wwids_on(conf)) ||
|
||||
- check_wwids_file(refwwid, 0) == 0)
|
||||
- r = RTVL_YES;
|
||||
- if (!ignore_wwids_on(conf))
|
||||
- goto print_valid;
|
||||
- /* At this point, either r==0 or find_multipaths_on. */
|
||||
-
|
||||
- /*
|
||||
- * Shortcut for find_multipaths smart:
|
||||
- * Quick check if path is already multipathed.
|
||||
- */
|
||||
- if (sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0),
|
||||
- false)) {
|
||||
- r = RTVL_YES;
|
||||
- goto print_valid;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * DM_MULTIPATH_DEVICE_PATH=="0" means that we have
|
||||
- * been called for this device already, and have
|
||||
- * released it to systemd. Unless the device is now
|
||||
- * already multipathed (see above), we can't try to
|
||||
- * grab it, because setting SYSTEMD_READY=0 would
|
||||
- * cause file systems to be unmounted.
|
||||
- * Leave DM_MULTIPATH_DEVICE_PATH="0".
|
||||
- */
|
||||
- if (released) {
|
||||
- r = RTVL_NO;
|
||||
- goto print_valid;
|
||||
- }
|
||||
- if (r == RTVL_YES)
|
||||
- goto print_valid;
|
||||
- /* find_multipaths_on: Fall through to path detection */
|
||||
- }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -701,59 +644,6 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (cmd == CMD_VALID_PATH) {
|
||||
- struct path *pp;
|
||||
- int fd;
|
||||
-
|
||||
- /* This only happens if find_multipaths and
|
||||
- * ignore_wwids is set, and the path is not in WWIDs
|
||||
- * file, not currently multipathed, and has
|
||||
- * never been released to systemd.
|
||||
- * If there is currently a multipath device matching
|
||||
- * the refwwid, or there is more than one path matching
|
||||
- * the refwwid, then the path is valid */
|
||||
- if (VECTOR_SIZE(curmp) != 0) {
|
||||
- r = RTVL_YES;
|
||||
- goto print_valid;
|
||||
- } else if (VECTOR_SIZE(pathvec) > 1)
|
||||
- r = RTVL_YES;
|
||||
- else
|
||||
- r = RTVL_MAYBE;
|
||||
-
|
||||
- /*
|
||||
- * If opening the path with O_EXCL fails, the path
|
||||
- * is in use (e.g. mounted during initramfs processing).
|
||||
- * We know that it's not used by dm-multipath.
|
||||
- * We may not set SYSTEMD_READY=0 on such devices, it
|
||||
- * might cause systemd to umount the device.
|
||||
- * Use O_RDONLY, because udevd would trigger another
|
||||
- * uevent for close-after-write.
|
||||
- *
|
||||
- * The O_EXCL check is potentially dangerous, because it may
|
||||
- * race with other tasks trying to access the device. Therefore
|
||||
- * this code is only executed if the path hasn't been released
|
||||
- * to systemd earlier (see above).
|
||||
- *
|
||||
- * get_refwwid() above stores the path we examine in slot 0.
|
||||
- */
|
||||
- pp = VECTOR_SLOT(pathvec, 0);
|
||||
- fd = open(udev_device_get_devnode(pp->udev),
|
||||
- O_RDONLY|O_EXCL);
|
||||
- if (fd >= 0)
|
||||
- close(fd);
|
||||
- else {
|
||||
- condlog(3, "%s: path %s is in use: %s",
|
||||
- __func__, pp->dev,
|
||||
- strerror(errno));
|
||||
- /*
|
||||
- * Check if we raced with multipathd
|
||||
- */
|
||||
- r = sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0),
|
||||
- false) ? RTVL_YES : RTVL_NO;
|
||||
- }
|
||||
- goto print_valid;
|
||||
- }
|
||||
-
|
||||
if (cmd != CMD_CREATE && cmd != CMD_DRY_RUN) {
|
||||
r = RTVL_OK;
|
||||
goto out;
|
||||
@@ -766,10 +656,6 @@ configure (struct config *conf, enum mpath_cmds cmd,
|
||||
conf->force_reload, cmd);
|
||||
r = rc == CP_RETRY ? RTVL_RETRY : rc == CP_OK ? RTVL_OK : RTVL_FAIL;
|
||||
|
||||
-print_valid:
|
||||
- if (cmd == CMD_VALID_PATH)
|
||||
- r = print_cmd_valid(r, pathvec, conf);
|
||||
-
|
||||
out:
|
||||
if (refwwid)
|
||||
FREE(refwwid);
|
||||
@@ -780,6 +666,112 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
+static int
|
||||
+check_path_valid(const char *name, struct config *conf, bool is_uevent)
|
||||
+{
|
||||
+ int fd, r = PATH_IS_ERROR;
|
||||
+ struct path *pp = NULL;
|
||||
+ vector pathvec = NULL;
|
||||
+
|
||||
+ pp = alloc_path();
|
||||
+ if (!pp)
|
||||
+ return RTVL_FAIL;
|
||||
+
|
||||
+ r = is_path_valid(name, conf, pp, is_uevent);
|
||||
+ if (r <= PATH_IS_ERROR || r >= PATH_MAX_VALID_RESULT)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* set path values if is_path_valid() didn't */
|
||||
+ if (!pp->udev)
|
||||
+ pp->udev = udev_device_new_from_subsystem_sysname(udev, "block",
|
||||
+ name);
|
||||
+ if (!pp->udev)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (!strlen(pp->dev_t)) {
|
||||
+ dev_t devt = udev_device_get_devnum(pp->udev);
|
||||
+ if (major(devt) == 0 && minor(devt) == 0)
|
||||
+ goto fail;
|
||||
+ snprintf(pp->dev_t, BLK_DEV_SIZE, "%d:%d", major(devt),
|
||||
+ minor(devt));
|
||||
+ }
|
||||
+
|
||||
+ pathvec = vector_alloc();
|
||||
+ if (!pathvec)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (store_path(pathvec, pp) != 0) {
|
||||
+ free_path(pp);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if ((r == PATH_IS_VALID || r == PATH_IS_MAYBE_VALID) &&
|
||||
+ released_to_systemd())
|
||||
+ r = PATH_IS_NOT_VALID;
|
||||
+
|
||||
+ /* This state is only used to skip the released_to_systemd() check */
|
||||
+ if (r == PATH_IS_VALID_NO_CHECK)
|
||||
+ r = PATH_IS_VALID;
|
||||
+
|
||||
+ if (r != PATH_IS_MAYBE_VALID)
|
||||
+ goto out;
|
||||
+
|
||||
+ /*
|
||||
+ * If opening the path with O_EXCL fails, the path
|
||||
+ * is in use (e.g. mounted during initramfs processing).
|
||||
+ * We know that it's not used by dm-multipath.
|
||||
+ * We may not set SYSTEMD_READY=0 on such devices, it
|
||||
+ * might cause systemd to umount the device.
|
||||
+ * Use O_RDONLY, because udevd would trigger another
|
||||
+ * uevent for close-after-write.
|
||||
+ *
|
||||
+ * The O_EXCL check is potentially dangerous, because it may
|
||||
+ * race with other tasks trying to access the device. Therefore
|
||||
+ * this code is only executed if the path hasn't been released
|
||||
+ * to systemd earlier (see above).
|
||||
+ */
|
||||
+ fd = open(udev_device_get_devnode(pp->udev), O_RDONLY|O_EXCL);
|
||||
+ if (fd >= 0)
|
||||
+ close(fd);
|
||||
+ else {
|
||||
+ condlog(3, "%s: path %s is in use: %m", __func__, pp->dev);
|
||||
+ /* Check if we raced with multipathd */
|
||||
+ if (sysfs_is_multipathed(pp, false))
|
||||
+ r = PATH_IS_VALID;
|
||||
+ else
|
||||
+ r = PATH_IS_NOT_VALID;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* For find_multipaths = SMART, if there is more than one path
|
||||
+ * matching the refwwid, then the path is valid */
|
||||
+ if (path_discovery(pathvec, DI_SYSFS | DI_WWID) < 0)
|
||||
+ goto fail;
|
||||
+ filter_pathvec(pathvec, pp->wwid);
|
||||
+ if (VECTOR_SIZE(pathvec) > 1)
|
||||
+ r = PATH_IS_VALID;
|
||||
+ else
|
||||
+ r = PATH_IS_MAYBE_VALID;
|
||||
+
|
||||
+out:
|
||||
+ r = print_cmd_valid(r, pathvec, conf);
|
||||
+ free_pathvec(pathvec, FREE_PATHS);
|
||||
+ /*
|
||||
+ * multipath -u must exit with status 0, otherwise udev won't
|
||||
+ * import its output.
|
||||
+ */
|
||||
+ if (!is_uevent && r == PATH_IS_NOT_VALID)
|
||||
+ return RTVL_FAIL;
|
||||
+ return RTVL_OK;
|
||||
+
|
||||
+fail:
|
||||
+ if (pathvec)
|
||||
+ free_pathvec(pathvec, FREE_PATHS);
|
||||
+ else
|
||||
+ free_path(pp);
|
||||
+ return RTVL_FAIL;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
get_dev_type(char *dev) {
|
||||
struct stat buf;
|
||||
@@ -861,32 +853,6 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
-static int test_multipathd_socket(void)
|
||||
-{
|
||||
- int fd;
|
||||
- /*
|
||||
- * "multipath -u" may be run before the daemon is started. In this
|
||||
- * case, systemd might own the socket but might delay multipathd
|
||||
- * startup until some other unit (udev settle!) has finished
|
||||
- * starting. With many LUNs, the listen backlog may be exceeded, which
|
||||
- * would cause connect() to block. This causes udev workers calling
|
||||
- * "multipath -u" to hang, and thus creates a deadlock, until "udev
|
||||
- * settle" times out. To avoid this, call connect() in non-blocking
|
||||
- * mode here, and take EAGAIN as indication for a filled-up systemd
|
||||
- * backlog.
|
||||
- */
|
||||
-
|
||||
- fd = __mpath_connect(1);
|
||||
- if (fd == -1) {
|
||||
- if (errno == EAGAIN)
|
||||
- condlog(3, "daemon backlog exceeded");
|
||||
- else
|
||||
- return 0;
|
||||
- } else
|
||||
- close(fd);
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -970,7 +936,11 @@ main (int argc, char *argv[])
|
||||
conf->force_reload = FORCE_RELOAD_YES;
|
||||
break;
|
||||
case 'i':
|
||||
- conf->find_multipaths |= _FIND_MULTIPATHS_I;
|
||||
+ if (conf->find_multipaths == FIND_MULTIPATHS_ON ||
|
||||
+ conf->find_multipaths == FIND_MULTIPATHS_STRICT)
|
||||
+ conf->find_multipaths = FIND_MULTIPATHS_SMART;
|
||||
+ else if (conf->find_multipaths == FIND_MULTIPATHS_OFF)
|
||||
+ conf->find_multipaths = FIND_MULTIPATHS_GREEDY;
|
||||
break;
|
||||
case 't':
|
||||
r = dump_config(conf, NULL, NULL) ? RTVL_FAIL : RTVL_OK;
|
||||
@@ -1064,15 +1034,10 @@ main (int argc, char *argv[])
|
||||
condlog(0, "the -c option requires a path to check");
|
||||
goto out;
|
||||
}
|
||||
- if (cmd == CMD_VALID_PATH &&
|
||||
- dev_type == DEV_UEVENT) {
|
||||
- if (!test_multipathd_socket()) {
|
||||
- condlog(3, "%s: daemon is not running", dev);
|
||||
- if (!systemd_service_enabled(dev)) {
|
||||
- r = print_cmd_valid(RTVL_NO, NULL, conf);
|
||||
- goto out;
|
||||
- }
|
||||
- }
|
||||
+ if (cmd == CMD_VALID_PATH) {
|
||||
+ char * name = convert_dev(dev, (dev_type == DEV_DEVNODE));
|
||||
+ r = check_path_valid(name, conf, dev_type == DEV_UEVENT);
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (cmd == CMD_REMOVE_WWID && !dev) {
|
||||
@@ -1136,13 +1101,6 @@ out:
|
||||
cleanup_prio();
|
||||
cleanup_checkers();
|
||||
|
||||
- /*
|
||||
- * multipath -u must exit with status 0, otherwise udev won't
|
||||
- * import its output.
|
||||
- */
|
||||
- if (cmd == CMD_VALID_PATH && dev_type == DEV_UEVENT && r == RTVL_NO)
|
||||
- r = RTVL_OK;
|
||||
-
|
||||
if (dev_type == DEV_UEVENT)
|
||||
closelog();
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
530
0026-Unit-tests-for-is_path_valid.patch
Normal file
530
0026-Unit-tests-for-is_path_valid.patch
Normal file
@ -0,0 +1,530 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:08:43 -0500
|
||||
Subject: [PATCH] Unit tests for is_path_valid()
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
tests/Makefile | 4 +-
|
||||
tests/valid.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 489 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tests/valid.c
|
||||
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index 1b8706a7..125553b8 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -13,7 +13,7 @@ CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) \
|
||||
LIBDEPS += -L$(multipathdir) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka
|
||||
|
||||
TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \
|
||||
- alias directio
|
||||
+ alias directio valid
|
||||
|
||||
.SILENT: $(TESTS:%=%.o)
|
||||
.PRECIOUS: $(TESTS:%=%-test)
|
||||
@@ -50,6 +50,8 @@ vpd-test_OBJDEPS := ../libmultipath/discovery.o
|
||||
vpd-test_LIBDEPS := -ludev -lpthread -ldl
|
||||
alias-test_TESTDEPS := test-log.o
|
||||
alias-test_LIBDEPS := -lpthread -ldl
|
||||
+valid-test_OBJDEPS := ../libmultipath/valid.o
|
||||
+valid-test_LIBDEPS := -ludev -lpthread -ldl
|
||||
ifneq ($(DIO_TEST_DEV),)
|
||||
directio-test_LIBDEPS := -laio
|
||||
endif
|
||||
diff --git a/tests/valid.c b/tests/valid.c
|
||||
new file mode 100644
|
||||
index 00000000..693c72c5
|
||||
--- /dev/null
|
||||
+++ b/tests/valid.c
|
||||
@@ -0,0 +1,486 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 Benjamin Marzinski, Redhat
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License
|
||||
+ * as published by the Free Software Foundation; either version 2
|
||||
+ * of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#define _GNU_SOURCE
|
||||
+#include <stdint.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <errno.h>
|
||||
+#include <cmocka.h>
|
||||
+#include "globals.c"
|
||||
+#include "util.h"
|
||||
+#include "discovery.h"
|
||||
+#include "wwids.h"
|
||||
+#include "blacklist.h"
|
||||
+#include "valid.h"
|
||||
+
|
||||
+int test_fd;
|
||||
+struct udev_device {
|
||||
+ int unused;
|
||||
+} test_udev;
|
||||
+
|
||||
+bool __wrap_sysfs_is_multipathed(struct path *pp, bool set_wwid)
|
||||
+{
|
||||
+ bool is_multipathed = mock_type(bool);
|
||||
+ assert_non_null(pp);
|
||||
+ assert_int_not_equal(strlen(pp->dev), 0);
|
||||
+ if (is_multipathed && set_wwid)
|
||||
+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE);
|
||||
+ return is_multipathed;
|
||||
+}
|
||||
+
|
||||
+int __wrap___mpath_connect(int nonblocking)
|
||||
+{
|
||||
+ bool connected = mock_type(bool);
|
||||
+ assert_int_equal(nonblocking, 1);
|
||||
+ if (connected)
|
||||
+ return test_fd;
|
||||
+ errno = mock_type(int);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int __wrap_systemd_service_enabled(const char *dev)
|
||||
+{
|
||||
+ return (int)mock_type(bool);
|
||||
+}
|
||||
+
|
||||
+/* There's no point in checking the return value here */
|
||||
+int __wrap_mpath_disconnect(int fd)
|
||||
+{
|
||||
+ assert_int_equal(fd, test_fd);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct udev_device *__wrap_udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
|
||||
+{
|
||||
+ bool passed = mock_type(bool);
|
||||
+ assert_string_equal(sysname, mock_ptr_type(char *));
|
||||
+ if (passed)
|
||||
+ return &test_udev;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+int __wrap_pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
+{
|
||||
+ int ret = mock_type(int);
|
||||
+ assert_string_equal(pp->dev, mock_ptr_type(char *));
|
||||
+ assert_int_equal(mask, DI_SYSFS | DI_WWID | DI_BLACKLIST);
|
||||
+ if (ret == PATHINFO_OK) {
|
||||
+ pp->uid_attribute = "ID_TEST";
|
||||
+ strlcpy(pp->wwid, mock_ptr_type(char *), WWID_SIZE);
|
||||
+ } else
|
||||
+ memset(pp->wwid, 0, WWID_SIZE);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int __wrap_filter_property(struct config *conf, struct udev_device *udev,
|
||||
+ int lvl, const char *uid_attribute)
|
||||
+{
|
||||
+ int ret = mock_type(int);
|
||||
+ assert_string_equal(uid_attribute, "ID_TEST");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int __wrap_is_failed_wwid(const char *wwid)
|
||||
+{
|
||||
+ int ret = mock_type(int);
|
||||
+ assert_string_equal(wwid, mock_ptr_type(char *));
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int __wrap_check_wwids_file(char *wwid, int write_wwid)
|
||||
+{
|
||||
+ bool passed = mock_type(bool);
|
||||
+ assert_int_equal(write_wwid, 0);
|
||||
+ assert_string_equal(wwid, mock_ptr_type(char *));
|
||||
+ if (passed)
|
||||
+ return 0;
|
||||
+ else
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int __wrap_dm_map_present_by_uuid(const char *uuid)
|
||||
+{
|
||||
+ int ret = mock_type(int);
|
||||
+ assert_string_equal(uuid, mock_ptr_type(char *));
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+enum {
|
||||
+ STAGE_IS_MULTIPATHED,
|
||||
+ STAGE_CHECK_MULTIPATHD,
|
||||
+ STAGE_GET_UDEV_DEVICE,
|
||||
+ STAGE_PATHINFO,
|
||||
+ STAGE_FILTER_PROPERTY,
|
||||
+ STAGE_IS_FAILED,
|
||||
+ STAGE_CHECK_WWIDS,
|
||||
+ STAGE_UUID_PRESENT,
|
||||
+};
|
||||
+
|
||||
+enum {
|
||||
+ CHECK_MPATHD_RUNNING,
|
||||
+ CHECK_MPATHD_EAGAIN,
|
||||
+ CHECK_MPATHD_ENABLED,
|
||||
+ CHECK_MPATHD_SKIP,
|
||||
+};
|
||||
+
|
||||
+/* setup the test to continue past the given stage in is_path_valid() */
|
||||
+static void setup_passing(char *name, char *wwid, unsigned int check_multipathd,
|
||||
+ unsigned int stage)
|
||||
+{
|
||||
+ will_return(__wrap_sysfs_is_multipathed, false);
|
||||
+ if (stage == STAGE_IS_MULTIPATHED)
|
||||
+ return;
|
||||
+ if (check_multipathd == CHECK_MPATHD_RUNNING)
|
||||
+ will_return(__wrap___mpath_connect, true);
|
||||
+ else if (check_multipathd == CHECK_MPATHD_EAGAIN) {
|
||||
+ will_return(__wrap___mpath_connect, false);
|
||||
+ will_return(__wrap___mpath_connect, EAGAIN);
|
||||
+ } else if (check_multipathd == CHECK_MPATHD_ENABLED) {
|
||||
+ will_return(__wrap___mpath_connect, false);
|
||||
+ will_return(__wrap___mpath_connect, ECONNREFUSED);
|
||||
+ will_return(__wrap_systemd_service_enabled, true);
|
||||
+ }
|
||||
+ /* nothing for CHECK_MPATHD_SKIP */
|
||||
+ if (stage == STAGE_CHECK_MULTIPATHD)
|
||||
+ return;
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname, true);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname,
|
||||
+ name);
|
||||
+ if (stage == STAGE_GET_UDEV_DEVICE)
|
||||
+ return;
|
||||
+ will_return(__wrap_pathinfo, PATHINFO_OK);
|
||||
+ will_return(__wrap_pathinfo, name);
|
||||
+ will_return(__wrap_pathinfo, wwid);
|
||||
+ if (stage == STAGE_PATHINFO)
|
||||
+ return;
|
||||
+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_EXCEPT);
|
||||
+ if (stage == STAGE_FILTER_PROPERTY)
|
||||
+ return;
|
||||
+ will_return(__wrap_is_failed_wwid, WWID_IS_NOT_FAILED);
|
||||
+ will_return(__wrap_is_failed_wwid, wwid);
|
||||
+ if (stage == STAGE_IS_FAILED)
|
||||
+ return;
|
||||
+ will_return(__wrap_check_wwids_file, false);
|
||||
+ will_return(__wrap_check_wwids_file, wwid);
|
||||
+ if (stage == STAGE_CHECK_WWIDS)
|
||||
+ return;
|
||||
+ will_return(__wrap_dm_map_present_by_uuid, 0);
|
||||
+ will_return(__wrap_dm_map_present_by_uuid, wwid);
|
||||
+}
|
||||
+
|
||||
+static void test_bad_arguments(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char too_long[FILE_NAME_SIZE + 1];
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ /* test NULL pointers */
|
||||
+ assert_int_equal(is_path_valid("test", &conf, NULL, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ assert_int_equal(is_path_valid("test", NULL, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ assert_int_equal(is_path_valid(NULL, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ /* test undefined find_multipaths */
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_UNDEF;
|
||||
+ assert_int_equal(is_path_valid("test", &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ /* test name too long */
|
||||
+ memset(too_long, 'x', sizeof(too_long));
|
||||
+ too_long[sizeof(too_long) - 1] = '\0';
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ assert_int_equal(is_path_valid(too_long, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+}
|
||||
+
|
||||
+static void test_sysfs_is_multipathed(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test_wwid";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ /* test for already existing multiapthed device */
|
||||
+ will_return(__wrap_sysfs_is_multipathed, true);
|
||||
+ will_return(__wrap_sysfs_is_multipathed, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_VALID_NO_CHECK);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+ /* test for wwid device with empty wwid */
|
||||
+ will_return(__wrap_sysfs_is_multipathed, true);
|
||||
+ will_return(__wrap_sysfs_is_multipathed, "");
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+}
|
||||
+
|
||||
+static void test_check_multipathd(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ /* test failed check to see if multipathd is active */
|
||||
+ will_return(__wrap_sysfs_is_multipathed, false);
|
||||
+ will_return(__wrap___mpath_connect, false);
|
||||
+ will_return(__wrap___mpath_connect, ECONNREFUSED);
|
||||
+ will_return(__wrap_systemd_service_enabled, false);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ /* test pass because service is enabled. fail getting udev */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_ENABLED, STAGE_CHECK_MULTIPATHD);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname,
|
||||
+ name);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ /* test pass because connect returned EAGAIN. fail getting udev */
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_EAGAIN, STAGE_CHECK_MULTIPATHD);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname,
|
||||
+ name);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ /* test pass because connect succeeded. fail getting udev */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_RUNNING, STAGE_CHECK_MULTIPATHD);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname, false);
|
||||
+ will_return(__wrap_udev_device_new_from_subsystem_sysname,
|
||||
+ name);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_ERROR);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+}
|
||||
+
|
||||
+static void test_pathinfo(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ /* Test pathinfo blacklisting device */
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE);
|
||||
+ will_return(__wrap_pathinfo, PATHINFO_SKIPPED);
|
||||
+ will_return(__wrap_pathinfo, name);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ /* Test pathinfo failing */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE);
|
||||
+ will_return(__wrap_pathinfo, PATHINFO_FAILED);
|
||||
+ will_return(__wrap_pathinfo, name);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_ERROR);
|
||||
+ /* Test blank wwid */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, NULL, CHECK_MPATHD_SKIP, STAGE_GET_UDEV_DEVICE);
|
||||
+ will_return(__wrap_pathinfo, PATHINFO_OK);
|
||||
+ will_return(__wrap_pathinfo, name);
|
||||
+ will_return(__wrap_pathinfo, "");
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+}
|
||||
+
|
||||
+static void test_filter_property(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ /* test blacklist property */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO);
|
||||
+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+ /* test missing property */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO);
|
||||
+ will_return(__wrap_filter_property, MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ /* test MATCH_NOTHING fail on is_failed_wwid */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_PATHINFO);
|
||||
+ will_return(__wrap_filter_property, MATCH_NOTHING);
|
||||
+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED);
|
||||
+ will_return(__wrap_is_failed_wwid, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+}
|
||||
+
|
||||
+static void test_is_failed_wwid(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ /* Test wwid failed */
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY);
|
||||
+ will_return(__wrap_is_failed_wwid, WWID_IS_FAILED);
|
||||
+ will_return(__wrap_is_failed_wwid, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+ /* test is_failed_wwid error */
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_FILTER_PROPERTY);
|
||||
+ will_return(__wrap_is_failed_wwid, WWID_FAILED_ERROR);
|
||||
+ will_return(__wrap_is_failed_wwid, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_ERROR);
|
||||
+}
|
||||
+
|
||||
+static void test_greedy(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ /* test greedy success with checking multipathd */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_GREEDY;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_RUNNING, STAGE_IS_FAILED);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+ /* test greedy success without checking multiapthd */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_IS_FAILED);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_VALID);
|
||||
+}
|
||||
+
|
||||
+static void test_check_wwids(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_EAGAIN, STAGE_IS_FAILED);
|
||||
+ will_return(__wrap_check_wwids_file, true);
|
||||
+ will_return(__wrap_check_wwids_file, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_VALID_NO_CHECK);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+}
|
||||
+
|
||||
+static void test_check_uuid_present(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_ENABLED, STAGE_CHECK_WWIDS);
|
||||
+ will_return(__wrap_dm_map_present_by_uuid, 1);
|
||||
+ will_return(__wrap_dm_map_present_by_uuid, wwid);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, true),
|
||||
+ PATH_IS_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void test_find_multipaths(void **state)
|
||||
+{
|
||||
+ struct path pp;
|
||||
+ char *name = "test";
|
||||
+ char *wwid = "test-wwid";
|
||||
+
|
||||
+ /* test find_multipaths = FIND_MULTIPATHS_STRICT */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_STRICT;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+ /* test find_multipaths = FIND_MULTIPATHS_OFF */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_OFF;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ /* test find_multipaths = FIND_MULTIPATHS_ON */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_ON;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_NOT_VALID);
|
||||
+ /* test find_multipaths = FIND_MULTIPATHS_SMART */
|
||||
+ memset(&pp, 0, sizeof(pp));
|
||||
+ conf.find_multipaths = FIND_MULTIPATHS_SMART;
|
||||
+ setup_passing(name, wwid, CHECK_MPATHD_SKIP, STAGE_UUID_PRESENT);
|
||||
+ assert_int_equal(is_path_valid(name, &conf, &pp, false),
|
||||
+ PATH_IS_MAYBE_VALID);
|
||||
+ assert_string_equal(pp.dev, name);
|
||||
+ assert_ptr_equal(pp.udev, &test_udev);
|
||||
+ assert_string_equal(pp.wwid, wwid);
|
||||
+}
|
||||
+
|
||||
+int test_valid(void)
|
||||
+{
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test(test_bad_arguments),
|
||||
+ cmocka_unit_test(test_sysfs_is_multipathed),
|
||||
+ cmocka_unit_test(test_check_multipathd),
|
||||
+ cmocka_unit_test(test_pathinfo),
|
||||
+ cmocka_unit_test(test_filter_property),
|
||||
+ cmocka_unit_test(test_is_failed_wwid),
|
||||
+ cmocka_unit_test(test_greedy),
|
||||
+ cmocka_unit_test(test_check_wwids),
|
||||
+ cmocka_unit_test(test_check_uuid_present),
|
||||
+ cmocka_unit_test(test_find_multipaths),
|
||||
+ };
|
||||
+ return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
+int main(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ ret += test_valid();
|
||||
+ return ret;
|
||||
+}
|
||||
--
|
||||
2.17.2
|
||||
|
205
0027-libmultipath-simplify-failed-wwid-code.patch
Normal file
205
0027-libmultipath-simplify-failed-wwid-code.patch
Normal file
@ -0,0 +1,205 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:08:44 -0500
|
||||
Subject: [PATCH] libmultipath: simplify failed wwid code
|
||||
|
||||
The (is|mark|unmark)_failed_wwid code is needlessly complicated.
|
||||
Locking a file is necssary if multiple processes could otherwise be
|
||||
writing to it at the same time. That is not the case with the
|
||||
failed_wwids files. They can simply be empty files in a directory. Even
|
||||
with all the locking in place, two processes accessing or modifying a
|
||||
file at the same time will still race. And even without the locking, if
|
||||
two processes try to access or modify a file at the same time, they will
|
||||
both see a reasonable result, and will leave the files in a valid state
|
||||
afterwards.
|
||||
|
||||
Instead of doing all the locking work (which made it necessary to write
|
||||
a file, even just to check if a file existed), simply check for files
|
||||
with lstat(), create them with open(), and remove them with unlink().
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/wwids.c | 131 ++++++++++++++++++-------------------------
|
||||
1 file changed, 56 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 637cb0ab..aab5da8a 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "checkers.h"
|
||||
@@ -348,109 +349,89 @@ remember_wwid(char *wwid)
|
||||
}
|
||||
|
||||
static const char shm_dir[] = MULTIPATH_SHM_BASE "failed_wwids";
|
||||
-static const char shm_lock[] = ".lock";
|
||||
-static const char shm_header[] = "multipath shm lock file, don't edit";
|
||||
-static char _shm_lock_path[sizeof(shm_dir)+sizeof(shm_lock)];
|
||||
-static const char *shm_lock_path = &_shm_lock_path[0];
|
||||
|
||||
-static void init_shm_paths(void)
|
||||
+static void print_failed_wwid_result(const char * msg, const char *wwid, int r)
|
||||
{
|
||||
- snprintf(_shm_lock_path, sizeof(_shm_lock_path),
|
||||
- "%s/%s", shm_dir, shm_lock);
|
||||
+ switch(r) {
|
||||
+ case WWID_FAILED_ERROR:
|
||||
+ condlog(1, "%s: %s: %m", msg, wwid);
|
||||
+ return;
|
||||
+ case WWID_IS_FAILED:
|
||||
+ case WWID_IS_NOT_FAILED:
|
||||
+ condlog(4, "%s: %s is %s", msg, wwid,
|
||||
+ r == WWID_IS_FAILED ? "failed" : "good");
|
||||
+ return;
|
||||
+ case WWID_FAILED_CHANGED:
|
||||
+ condlog(3, "%s: %s", msg, wwid);
|
||||
+ }
|
||||
}
|
||||
|
||||
-static pthread_once_t shm_path_once = PTHREAD_ONCE_INIT;
|
||||
-
|
||||
-static int multipath_shm_open(bool rw)
|
||||
+int is_failed_wwid(const char *wwid)
|
||||
{
|
||||
- int fd;
|
||||
- int can_write;
|
||||
-
|
||||
- pthread_once(&shm_path_once, init_shm_paths);
|
||||
- fd = open_file(shm_lock_path, &can_write, shm_header);
|
||||
+ struct stat st;
|
||||
+ char path[PATH_MAX];
|
||||
+ int r;
|
||||
|
||||
- if (fd >= 0 && rw && !can_write) {
|
||||
- close(fd);
|
||||
- condlog(1, "failed to open %s for writing", shm_dir);
|
||||
+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
+ condlog(1, "%s: path name overflow", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- return fd;
|
||||
-}
|
||||
-
|
||||
-static void multipath_shm_close(void *arg)
|
||||
-{
|
||||
- long fd = (long)arg;
|
||||
+ if (lstat(path, &st) == 0)
|
||||
+ r = WWID_IS_FAILED;
|
||||
+ else if (errno == ENOENT)
|
||||
+ r = WWID_IS_NOT_FAILED;
|
||||
+ else
|
||||
+ r = WWID_FAILED_ERROR;
|
||||
|
||||
- close(fd);
|
||||
- unlink(shm_lock_path);
|
||||
+ print_failed_wwid_result("is_failed", wwid, r);
|
||||
+ return r;
|
||||
}
|
||||
|
||||
-static int _failed_wwid_op(const char *wwid, bool rw,
|
||||
- int (*func)(const char *), const char *msg)
|
||||
+int mark_failed_wwid(const char *wwid)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
- long lockfd;
|
||||
- int r = -1;
|
||||
+ int r, fd;
|
||||
|
||||
if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
condlog(1, "%s: path name overflow", __func__);
|
||||
return -1;
|
||||
}
|
||||
-
|
||||
- lockfd = multipath_shm_open(rw);
|
||||
- if (lockfd == -1)
|
||||
+ if (ensure_directories_exist(path, 0700) < 0) {
|
||||
+ condlog(1, "%s: can't setup directories", __func__);
|
||||
return -1;
|
||||
+ }
|
||||
|
||||
- pthread_cleanup_push(multipath_shm_close, (void *)lockfd);
|
||||
- r = func(path);
|
||||
- pthread_cleanup_pop(1);
|
||||
-
|
||||
- if (r == WWID_FAILED_ERROR)
|
||||
- condlog(1, "%s: %s: %s", msg, wwid, strerror(errno));
|
||||
- else if (r == WWID_FAILED_CHANGED)
|
||||
- condlog(3, "%s: %s", msg, wwid);
|
||||
- else if (!rw)
|
||||
- condlog(4, "%s: %s is %s", msg, wwid,
|
||||
- r == WWID_IS_FAILED ? "failed" : "good");
|
||||
+ fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR);
|
||||
+ if (fd >= 0) {
|
||||
+ close(fd);
|
||||
+ r = WWID_FAILED_CHANGED;
|
||||
+ } else if (errno == EEXIST)
|
||||
+ r = WWID_FAILED_UNCHANGED;
|
||||
+ else
|
||||
+ r = WWID_FAILED_ERROR;
|
||||
|
||||
+ print_failed_wwid_result("mark_failed", wwid, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
-static int _is_failed(const char *path)
|
||||
+int unmark_failed_wwid(const char *wwid)
|
||||
{
|
||||
- struct stat st;
|
||||
+ char path[PATH_MAX];
|
||||
+ int r;
|
||||
|
||||
- if (lstat(path, &st) == 0)
|
||||
- return WWID_IS_FAILED;
|
||||
+ if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
+ condlog(1, "%s: path name overflow", __func__);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (unlink(path) == 0)
|
||||
+ r = WWID_FAILED_CHANGED;
|
||||
else if (errno == ENOENT)
|
||||
- return WWID_IS_NOT_FAILED;
|
||||
+ r = WWID_FAILED_UNCHANGED;
|
||||
else
|
||||
- return WWID_FAILED_ERROR;
|
||||
-}
|
||||
-
|
||||
-static int _mark_failed(const char *path)
|
||||
-{
|
||||
- /* Called from _failed_wwid_op: we know that shm_lock_path exists */
|
||||
- if (_is_failed(path) == WWID_IS_FAILED)
|
||||
- return WWID_FAILED_UNCHANGED;
|
||||
- return (link(shm_lock_path, path) == 0 ? WWID_FAILED_CHANGED :
|
||||
- WWID_FAILED_ERROR);
|
||||
-}
|
||||
+ r = WWID_FAILED_ERROR;
|
||||
|
||||
-static int _unmark_failed(const char *path)
|
||||
-{
|
||||
- if (_is_failed(path) == WWID_IS_NOT_FAILED)
|
||||
- return WWID_FAILED_UNCHANGED;
|
||||
- return (unlink(path) == 0 ? WWID_FAILED_CHANGED : WWID_FAILED_ERROR);
|
||||
-}
|
||||
-
|
||||
-#define declare_failed_wwid_op(op, rw) \
|
||||
-int op ## _wwid(const char *wwid) \
|
||||
-{ \
|
||||
- return _failed_wwid_op(wwid, (rw), _ ## op, #op); \
|
||||
+ print_failed_wwid_result("unmark_failed", wwid, r);
|
||||
+ return r;
|
||||
}
|
||||
-
|
||||
-declare_failed_wwid_op(is_failed, false)
|
||||
-declare_failed_wwid_op(mark_failed, true)
|
||||
-declare_failed_wwid_op(unmark_failed, true)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 19 May 2020 12:08:45 -0500
|
||||
Subject: [PATCH] libmultipath: use atomic linkat() in mark_failed_wwid()
|
||||
|
||||
This keeps (almost) the simplicity of the previous patch, while
|
||||
making sure that the return value of mark_failed_wwid()
|
||||
(WWID_FAILED_CHANGED vs. WWID_FAILED_UNCHANGED) is correct, even
|
||||
if several processes access this WWID at the same time.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/wwids.c | 42 +++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 29 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index aab5da8a..61d9c39e 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -374,7 +374,7 @@ int is_failed_wwid(const char *wwid)
|
||||
|
||||
if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
condlog(1, "%s: path name overflow", __func__);
|
||||
- return -1;
|
||||
+ return WWID_FAILED_ERROR;
|
||||
}
|
||||
|
||||
if (lstat(path, &st) == 0)
|
||||
@@ -390,27 +390,43 @@ int is_failed_wwid(const char *wwid)
|
||||
|
||||
int mark_failed_wwid(const char *wwid)
|
||||
{
|
||||
- char path[PATH_MAX];
|
||||
- int r, fd;
|
||||
+ char tmpfile[WWID_SIZE + 2 * sizeof(long) + 1];
|
||||
+ int r = WWID_FAILED_ERROR, fd, dfd;
|
||||
|
||||
- if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
- condlog(1, "%s: path name overflow", __func__);
|
||||
- return -1;
|
||||
+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY);
|
||||
+ if (dfd == -1 && errno == ENOENT) {
|
||||
+ char path[sizeof(shm_dir) + 2];
|
||||
+
|
||||
+ /* arg for ensure_directories_exist() must not end with "/" */
|
||||
+ safe_sprintf(path, "%s/_", shm_dir);
|
||||
+ ensure_directories_exist(path, 0700);
|
||||
+ dfd = open(shm_dir, O_RDONLY|O_DIRECTORY);
|
||||
}
|
||||
- if (ensure_directories_exist(path, 0700) < 0) {
|
||||
- condlog(1, "%s: can't setup directories", __func__);
|
||||
- return -1;
|
||||
+ if (dfd == -1) {
|
||||
+ condlog(1, "%s: can't setup %s: %m", __func__, shm_dir);
|
||||
+ return WWID_FAILED_ERROR;
|
||||
}
|
||||
|
||||
- fd = open(path, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR);
|
||||
- if (fd >= 0) {
|
||||
+ safe_sprintf(tmpfile, "%s.%lx", wwid, (long)getpid());
|
||||
+ fd = openat(dfd, tmpfile, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR);
|
||||
+ if (fd >= 0)
|
||||
close(fd);
|
||||
+ else
|
||||
+ goto out_closedir;
|
||||
+
|
||||
+ if (linkat(dfd, tmpfile, dfd, wwid, 0) == 0)
|
||||
r = WWID_FAILED_CHANGED;
|
||||
- } else if (errno == EEXIST)
|
||||
+ else if (errno == EEXIST)
|
||||
r = WWID_FAILED_UNCHANGED;
|
||||
else
|
||||
r = WWID_FAILED_ERROR;
|
||||
|
||||
+ if (unlinkat(dfd, tmpfile, 0) == -1)
|
||||
+ condlog(2, "%s: failed to unlink %s/%s: %m",
|
||||
+ __func__, shm_dir, tmpfile);
|
||||
+
|
||||
+out_closedir:
|
||||
+ close(dfd);
|
||||
print_failed_wwid_result("mark_failed", wwid, r);
|
||||
return r;
|
||||
}
|
||||
@@ -422,7 +438,7 @@ int unmark_failed_wwid(const char *wwid)
|
||||
|
||||
if (safe_sprintf(path, "%s/%s", shm_dir, wwid)) {
|
||||
condlog(1, "%s: path name overflow", __func__);
|
||||
- return -1;
|
||||
+ return WWID_FAILED_ERROR;
|
||||
}
|
||||
|
||||
if (unlink(path) == 0)
|
||||
--
|
||||
2.17.2
|
||||
|
41
0029-fix-boolean-value-with-json-c-0.14.patch
Normal file
41
0029-fix-boolean-value-with-json-c-0.14.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "mail@eworm.de" <mail@eworm.de>
|
||||
Date: Sat, 25 Apr 2020 21:11:13 +0200
|
||||
Subject: [PATCH] fix boolean value with json-c 0.14
|
||||
|
||||
Upstream json-c removed the TRUE and FALSE defines in commit
|
||||
0992aac61f8b087efd7094e9ac2b84fa9c040fcd.
|
||||
|
||||
[mwilck]: Use stdbool.h, and keep the log message unchanged.
|
||||
|
||||
Signed-off-by: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libdmmp/libdmmp_private.h | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libdmmp/libdmmp_private.h b/libdmmp/libdmmp_private.h
|
||||
index ac85b63f..b1a6ddea 100644
|
||||
--- a/libdmmp/libdmmp_private.h
|
||||
+++ b/libdmmp/libdmmp_private.h
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
+#include <stdbool.h>
|
||||
#include <json.h>
|
||||
|
||||
#include "libdmmp/libdmmp.h"
|
||||
@@ -82,7 +83,7 @@ static out_type func_name(struct dmmp_context *ctx, const char *var_name) { \
|
||||
do { \
|
||||
json_type j_type = json_type_null; \
|
||||
json_object *j_obj_tmp = NULL; \
|
||||
- if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != TRUE) { \
|
||||
+ if (json_object_object_get_ex(j_obj, key, &j_obj_tmp) != true) { \
|
||||
_error(ctx, "Invalid JSON output from multipathd IPC: " \
|
||||
"key '%s' not found", key); \
|
||||
rc = DMMP_ERR_IPC_ERROR; \
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 29 May 2020 15:13:59 -0500
|
||||
Date: Thu, 4 Jun 2020 18:20:06 -0500
|
||||
Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var
|
||||
|
||||
uevent_get_env_var() could call condlog with p == NULL. On gcc 10,
|
@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 21 Aug 2019 16:07:12 +0200
|
||||
Subject: [PATCH] libmultipath: set "enable_foreign" to NONE by default
|
||||
|
||||
This has been requested by NetApp.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/defaults.h | 4 ++--
|
||||
multipath/multipath.conf.5 | 5 +++--
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index e5ee6afe..01a501bd 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -50,8 +50,8 @@
|
||||
#define DEFAULT_FIND_MULTIPATHS_TIMEOUT -10
|
||||
#define DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT 1
|
||||
#define DEFAULT_ALL_TG_PT ALL_TG_PT_OFF
|
||||
-/* Enable all foreign libraries by default */
|
||||
-#define DEFAULT_ENABLE_FOREIGN ""
|
||||
+/* Enable no foreign libraries by default */
|
||||
+#define DEFAULT_ENABLE_FOREIGN "NONE"
|
||||
|
||||
#define CHECKINT_UNDEF UINT_MAX
|
||||
#define DEFAULT_CHECKINT 5
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 05a5e8ff..28cea88c 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1228,10 +1228,11 @@ Enables or disables foreign libraries (see section
|
||||
.I FOREIGN MULTIPATH SUPPORT
|
||||
below). The value is a regular expression; foreign libraries are loaded
|
||||
if their name (e.g. \(dqnvme\(dq) matches the expression. By default,
|
||||
-all foreign libraries are enabled.
|
||||
+no foreign libraries are enabled. Set this to \(dqnvme\(dq to enable NVMe native
|
||||
+multipath support, or \(dq.*\(dq to enable all foreign libraries.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB\(dq\(dq\fR (the empty regular expression)
|
||||
+The default is: \fB\(dqNONE\(dq\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 2 Mar 2020 22:43:27 +0100
|
||||
Subject: [PATCH] multipath: add "-e" option to enable foreign libraries
|
||||
|
||||
As we have set "enable_foreign" to "NONE" now by default, users
|
||||
may find it useful to be able to switch on foreign multipath display
|
||||
with an extra command line option even if foreign libraries are
|
||||
not enabled in multipath.conf. Currently this makes only sense
|
||||
with "multipath -ll", as the nvme library (and foreign libraries
|
||||
in general) support only the display of status information.
|
||||
|
||||
Suggested-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 11 ++++++++++-
|
||||
multipath/multipath.8 | 6 ++++++
|
||||
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 953fab27..c4740fab 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -145,6 +145,7 @@ usage (char * progname)
|
||||
" -h print this usage text\n"
|
||||
" -l show multipath topology (sysfs and DM info)\n"
|
||||
" -ll show multipath topology (maximum info)\n"
|
||||
+ " -e enable foreign libraries with -l/-ll\n"
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
@@ -865,6 +866,7 @@ main (int argc, char *argv[])
|
||||
char *dev = NULL;
|
||||
struct config *conf;
|
||||
int retries = -1;
|
||||
+ bool enable_foreign = false;
|
||||
|
||||
udev = udev_new();
|
||||
logsink = 0;
|
||||
@@ -874,7 +876,7 @@ main (int argc, char *argv[])
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -971,6 +973,9 @@ main (int argc, char *argv[])
|
||||
case 'R':
|
||||
retries = atoi(optarg);
|
||||
break;
|
||||
+ case 'e':
|
||||
+ enable_foreign = true;
|
||||
+ break;
|
||||
case ':':
|
||||
fprintf(stderr, "Missing option argument\n");
|
||||
usage(argv[0]);
|
||||
@@ -1022,6 +1027,10 @@ main (int argc, char *argv[])
|
||||
condlog(0, "failed to initialize prioritizers");
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
+ if ((cmd == CMD_LIST_SHORT || cmd == CMD_LIST_LONG) && enable_foreign)
|
||||
+ conf->enable_foreign = "";
|
||||
+
|
||||
/* Failing here is non-fatal */
|
||||
init_foreign(conf->multipath_dir, conf->enable_foreign);
|
||||
if (cmd == CMD_USABLE_PATHS) {
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 9cdd05a3..6fb8645a 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -223,6 +223,12 @@ The verbosity level also controls the level of log and debug messages printed to
|
||||
Dry run, do not create or update devmaps.
|
||||
.
|
||||
.TP
|
||||
+.B \-e
|
||||
+Enable all foreign libraries. This overrides the
|
||||
+.I enable_foreign
|
||||
+option from \fBmultipath.conf(5)\fR.
|
||||
+.
|
||||
+.TP
|
||||
.B \-i
|
||||
Ignore WWIDs file when processing devices. If
|
||||
\fIfind_multipaths strict\fR or \fIfind_multipaths no\fR is set in
|
||||
--
|
||||
2.17.2
|
||||
|
139
0033-libmultipath-remove-_blacklist_exceptions-functions.patch
Normal file
139
0033-libmultipath-remove-_blacklist_exceptions-functions.patch
Normal file
@ -0,0 +1,139 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 9 Jun 2020 16:35:27 -0500
|
||||
Subject: [PATCH] libmultipath: remove _blacklist_exceptions functions
|
||||
|
||||
_blacklist_exceptions() and _blacklist_exceptions_device() are exactly
|
||||
the same as _blacklist() and _blacklist_device(), so remove them, and
|
||||
give the remaining functions to a more general name.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 00e8dbdb..c21a0e27 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -101,21 +101,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
-_blacklist_exceptions (vector elist, const char * str)
|
||||
-{
|
||||
- int i;
|
||||
- struct blentry * ele;
|
||||
-
|
||||
- vector_foreach_slot (elist, ele, i) {
|
||||
- if (!regexec(&ele->regex, str, 0, NULL, 0))
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-_blacklist (vector blist, const char * str)
|
||||
+static int
|
||||
+match_reglist (vector blist, const char * str)
|
||||
{
|
||||
int i;
|
||||
struct blentry * ble;
|
||||
@@ -127,28 +114,9 @@ _blacklist (vector blist, const char * str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
-_blacklist_exceptions_device(const struct _vector *elist, const char * vendor,
|
||||
- const char * product)
|
||||
-{
|
||||
- int i;
|
||||
- struct blentry_device * ble;
|
||||
-
|
||||
- vector_foreach_slot (elist, ble, i) {
|
||||
- if (!ble->vendor && !ble->product)
|
||||
- continue;
|
||||
- if ((!ble->vendor ||
|
||||
- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) &&
|
||||
- (!ble->product ||
|
||||
- !regexec(&ble->product_reg, product, 0, NULL, 0)))
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
-_blacklist_device (const struct _vector *blist, const char * vendor,
|
||||
- const char * product)
|
||||
+static int
|
||||
+match_reglist_device (const struct _vector *blist, const char * vendor,
|
||||
+ const char * product)
|
||||
{
|
||||
int i;
|
||||
struct blentry_device * ble;
|
||||
@@ -300,9 +268,9 @@ filter_device (vector blist, vector elist, char * vendor, char * product,
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (vendor && product) {
|
||||
- if (_blacklist_exceptions_device(elist, vendor, product))
|
||||
+ if (match_reglist_device(elist, vendor, product))
|
||||
r = MATCH_DEVICE_BLIST_EXCEPT;
|
||||
- else if (_blacklist_device(blist, vendor, product))
|
||||
+ else if (match_reglist_device(blist, vendor, product))
|
||||
r = MATCH_DEVICE_BLIST;
|
||||
}
|
||||
|
||||
@@ -316,9 +284,9 @@ filter_devnode (vector blist, vector elist, char * dev)
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (dev) {
|
||||
- if (_blacklist_exceptions(elist, dev))
|
||||
+ if (match_reglist(elist, dev))
|
||||
r = MATCH_DEVNODE_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, dev))
|
||||
+ else if (match_reglist(blist, dev))
|
||||
r = MATCH_DEVNODE_BLIST;
|
||||
}
|
||||
|
||||
@@ -332,9 +300,9 @@ filter_wwid (vector blist, vector elist, char * wwid, char * dev)
|
||||
int r = MATCH_NOTHING;
|
||||
|
||||
if (wwid) {
|
||||
- if (_blacklist_exceptions(elist, wwid))
|
||||
+ if (match_reglist(elist, wwid))
|
||||
r = MATCH_WWID_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, wwid))
|
||||
+ else if (match_reglist(blist, wwid))
|
||||
r = MATCH_WWID_BLIST;
|
||||
}
|
||||
|
||||
@@ -351,9 +319,9 @@ filter_protocol(vector blist, vector elist, struct path * pp)
|
||||
if (pp) {
|
||||
snprint_path_protocol(buf, sizeof(buf), pp);
|
||||
|
||||
- if (_blacklist_exceptions(elist, buf))
|
||||
+ if (match_reglist(elist, buf))
|
||||
r = MATCH_PROTOCOL_BLIST_EXCEPT;
|
||||
- else if (_blacklist(blist, buf))
|
||||
+ else if (match_reglist(blist, buf))
|
||||
r = MATCH_PROTOCOL_BLIST;
|
||||
}
|
||||
|
||||
@@ -422,11 +390,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
if (check_missing_prop && !strcmp(env, uid_attribute))
|
||||
uid_attr_seen = true;
|
||||
|
||||
- if (_blacklist_exceptions(conf->elist_property, env)) {
|
||||
+ if (match_reglist(conf->elist_property, env)) {
|
||||
r = MATCH_PROPERTY_BLIST_EXCEPT;
|
||||
break;
|
||||
}
|
||||
- if (_blacklist(conf->blist_property, env)) {
|
||||
+ if (match_reglist(conf->blist_property, env)) {
|
||||
r = MATCH_PROPERTY_BLIST;
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,95 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 9 Jun 2020 16:35:28 -0500
|
||||
Subject: [PATCH] libmultipath: fix parser issue with comments in strings
|
||||
|
||||
If a quoted string starts with '#' or '!', the parser will stop
|
||||
parsing the line, thinking that it's a comment. It should only
|
||||
be checking for comments outside of quoted strings. Fixed this and
|
||||
added unit tests to verify it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 d478b177..11a6168c 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -300,8 +300,10 @@ alloc_strvec(char *string)
|
||||
(isspace((int) *cp) || !isascii((int) *cp)))
|
||||
&& *cp != '\0')
|
||||
cp++;
|
||||
- if (*cp == '\0' || *cp == '!' || *cp == '#')
|
||||
+ if (*cp == '\0' ||
|
||||
+ (!in_string && (*cp == '!' || *cp == '#'))) {
|
||||
return strvec;
|
||||
+ }
|
||||
}
|
||||
out:
|
||||
vector_free(strvec);
|
||||
diff --git a/tests/parser.c b/tests/parser.c
|
||||
index 29859dac..5772391e 100644
|
||||
--- a/tests/parser.c
|
||||
+++ b/tests/parser.c
|
||||
@@ -440,6 +440,46 @@ static void test18(void **state)
|
||||
free_strvec(v);
|
||||
}
|
||||
|
||||
+static void test19(void **state)
|
||||
+{
|
||||
+#define QUOTED19 "!value"
|
||||
+ vector v = alloc_strvec("key \"" QUOTED19 "\"");
|
||||
+ char *val;
|
||||
+
|
||||
+ assert_int_equal(VECTOR_SIZE(v), 4);
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 0), "key");
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 1)));
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED19);
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 3)));
|
||||
+ assert_int_equal(validate_config_strvec(v, test_file), 0);
|
||||
+
|
||||
+ val = set_value(v);
|
||||
+ assert_string_equal(val, QUOTED19);
|
||||
+
|
||||
+ free(val);
|
||||
+ free_strvec(v);
|
||||
+}
|
||||
+
|
||||
+static void test20(void **state)
|
||||
+{
|
||||
+#define QUOTED20 "#value"
|
||||
+ vector v = alloc_strvec("key \"" QUOTED20 "\"");
|
||||
+ char *val;
|
||||
+
|
||||
+ assert_int_equal(VECTOR_SIZE(v), 4);
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 0), "key");
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 1)));
|
||||
+ assert_string_equal(VECTOR_SLOT(v, 2), QUOTED20);
|
||||
+ assert_true(is_quote(VECTOR_SLOT(v, 3)));
|
||||
+ assert_int_equal(validate_config_strvec(v, test_file), 0);
|
||||
+
|
||||
+ val = set_value(v);
|
||||
+ assert_string_equal(val, QUOTED20);
|
||||
+
|
||||
+ free(val);
|
||||
+ free_strvec(v);
|
||||
+}
|
||||
+
|
||||
int test_config_parser(void)
|
||||
{
|
||||
const struct CMUnitTest tests[] = {
|
||||
@@ -461,6 +501,8 @@ int test_config_parser(void)
|
||||
cmocka_unit_test(test16),
|
||||
cmocka_unit_test(test17),
|
||||
cmocka_unit_test(test18),
|
||||
+ cmocka_unit_test(test19),
|
||||
+ cmocka_unit_test(test20),
|
||||
};
|
||||
return cmocka_run_group_tests(tests, setup, teardown);
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
435
0035-libmultipath-invert-regexes-that-start-with-exclamat.patch
Normal file
435
0035-libmultipath-invert-regexes-that-start-with-exclamat.patch
Normal file
@ -0,0 +1,435 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 9 Jun 2020 16:35:29 -0500
|
||||
Subject: [PATCH] libmultipath: invert regexes that start with exclamation
|
||||
point
|
||||
|
||||
The number of devices that multipath needs to blacklist keeps growing,
|
||||
and the udev rules already have
|
||||
|
||||
KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath"
|
||||
|
||||
so they only work correctly with these device types. Instead of
|
||||
individually blacklisting every type of device that can't be
|
||||
multipathed, multipath's default blacklist should work like the udev
|
||||
rule, and blacklist all devices that aren't scsi, dasd, or nvme.
|
||||
Unfortunately, the c regex library doesn't support negative lookahead.
|
||||
Instead, multipath should treat "!" at the beginning of
|
||||
blacklist/exceptions regexes as inverse matching the rest of the regex.
|
||||
If users need to match a literal '!' as the first character of their
|
||||
regex, they can use "\!" instead. This allows multipath to change the
|
||||
default devnode blacklist regex to "!^(sd[a-z]|dasd[a-z]|nvme[0-9])".
|
||||
|
||||
Extra tests have been added to the blacklist unit tests to verify the
|
||||
inverse matching code and the new default blacklist.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 c21a0e27..db58ccca 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -15,9 +15,24 @@
|
||||
#include "structs_vec.h"
|
||||
#include "print.h"
|
||||
|
||||
+char *check_invert(char *str, bool *invert)
|
||||
+{
|
||||
+ if (str[0] == '!') {
|
||||
+ *invert = true;
|
||||
+ return str + 1;
|
||||
+ }
|
||||
+ if (str[0] == '\\' && str[1] == '!') {
|
||||
+ *invert = false;
|
||||
+ return str + 1;
|
||||
+ }
|
||||
+ *invert = false;
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
int store_ble(vector blist, char * str, int origin)
|
||||
{
|
||||
struct blentry * ble;
|
||||
+ char *regex_str;
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
@@ -30,7 +45,8 @@ int store_ble(vector blist, char * str, int origin)
|
||||
if (!ble)
|
||||
goto out;
|
||||
|
||||
- if (regcomp(&ble->regex, str, REG_EXTENDED|REG_NOSUB))
|
||||
+ regex_str = check_invert(str, &ble->invert);
|
||||
+ if (regcomp(&ble->regex, regex_str, REG_EXTENDED|REG_NOSUB))
|
||||
goto out1;
|
||||
|
||||
if (!vector_alloc_slot(blist))
|
||||
@@ -66,6 +82,7 @@ int alloc_ble_device(vector blist)
|
||||
int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
{
|
||||
struct blentry_device * ble;
|
||||
+ char *regex_str;
|
||||
|
||||
if (!blist)
|
||||
return 1;
|
||||
@@ -76,7 +93,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
return 1;
|
||||
|
||||
if (vendor) {
|
||||
- if (regcomp(&ble->vendor_reg, vendor,
|
||||
+ regex_str = check_invert(vendor, &ble->vendor_invert);
|
||||
+ if (regcomp(&ble->vendor_reg, regex_str,
|
||||
REG_EXTENDED|REG_NOSUB)) {
|
||||
FREE(vendor);
|
||||
if (product)
|
||||
@@ -86,7 +104,8 @@ int set_ble_device(vector blist, char * vendor, char * product, int origin)
|
||||
ble->vendor = vendor;
|
||||
}
|
||||
if (product) {
|
||||
- if (regcomp(&ble->product_reg, product,
|
||||
+ regex_str = check_invert(product, &ble->product_invert);
|
||||
+ if (regcomp(&ble->product_reg, regex_str,
|
||||
REG_EXTENDED|REG_NOSUB)) {
|
||||
FREE(product);
|
||||
if (vendor) {
|
||||
@@ -108,7 +127,7 @@ match_reglist (vector blist, const char * str)
|
||||
struct blentry * ble;
|
||||
|
||||
vector_foreach_slot (blist, ble, i) {
|
||||
- if (!regexec(&ble->regex, str, 0, NULL, 0))
|
||||
+ if (!!regexec(&ble->regex, str, 0, NULL, 0) == ble->invert)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -125,9 +144,11 @@ match_reglist_device (const struct _vector *blist, const char * vendor,
|
||||
if (!ble->vendor && !ble->product)
|
||||
continue;
|
||||
if ((!ble->vendor ||
|
||||
- !regexec(&ble->vendor_reg, vendor, 0, NULL, 0)) &&
|
||||
+ !!regexec(&ble->vendor_reg, vendor, 0, NULL, 0) ==
|
||||
+ ble->vendor_invert) &&
|
||||
(!ble->product ||
|
||||
- !regexec(&ble->product_reg, product, 0, NULL, 0)))
|
||||
+ !!regexec(&ble->product_reg, product, 0, NULL, 0) ==
|
||||
+ ble->product_invert))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -160,13 +181,7 @@ setup_default_blist (struct config * conf)
|
||||
char * str;
|
||||
int i;
|
||||
|
||||
- str = STRDUP("^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]");
|
||||
- if (!str)
|
||||
- return 1;
|
||||
- if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
- return 1;
|
||||
-
|
||||
- str = STRDUP("^(td|hd|vd)[a-z]");
|
||||
+ str = STRDUP("!^(sd[a-z]|dasd[a-z]|nvme[0-9])");
|
||||
if (!str)
|
||||
return 1;
|
||||
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h
|
||||
index 2d721f60..4305857d 100644
|
||||
--- a/libmultipath/blacklist.h
|
||||
+++ b/libmultipath/blacklist.h
|
||||
@@ -20,6 +20,7 @@
|
||||
struct blentry {
|
||||
char * str;
|
||||
regex_t regex;
|
||||
+ bool invert;
|
||||
int origin;
|
||||
};
|
||||
|
||||
@@ -28,6 +29,8 @@ struct blentry_device {
|
||||
char * product;
|
||||
regex_t vendor_reg;
|
||||
regex_t product_reg;
|
||||
+ bool vendor_invert;
|
||||
+ bool product_invert;
|
||||
int origin;
|
||||
};
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 28cea88c..5adaced6 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1249,6 +1249,16 @@ being handled by multipath-tools.
|
||||
.LP
|
||||
.
|
||||
.
|
||||
+In the \fIblacklist\fR and \fIblacklist_exceptions\fR sections, starting a
|
||||
+quoted value with an exclamation mark \fB"!"\fR will invert the matching
|
||||
+of the rest of the regular expression. For instance, \fB"!^sd[a-z]"\fR will
|
||||
+match all values that do not start with \fB"sd[a-z]"\fR. The exclamation mark
|
||||
+can be escaped \fB"\\!"\fR to match a literal \fB!\fR at the start of a
|
||||
+regular expression. \fBNote:\fR The exclamation mark must be inside quotes,
|
||||
+otherwise it will be treated as starting a comment.
|
||||
+.LP
|
||||
+.
|
||||
+.
|
||||
The \fIblacklist_exceptions\fR section is used to revert the actions of the
|
||||
\fIblacklist\fR section. This allows one to selectively include ("whitelist") devices which
|
||||
would normally be excluded via the \fIblacklist\fR section. A common usage is
|
||||
@@ -1265,10 +1275,9 @@ unless explicitly stated.
|
||||
Regular expression matching the device nodes to be excluded/included.
|
||||
.RS
|
||||
.PP
|
||||
-The default \fIblacklist\fR consists of the regular expressions
|
||||
-"^(ram|zram|raw|loop|fd|md|dm-|sr|scd|st|dcssblk)[0-9]" and
|
||||
-"^(td|hd|vd)[a-z]". This causes virtual devices, non-disk devices, and some other
|
||||
-device types to be excluded from multipath handling by default.
|
||||
+The default \fIblacklist\fR consists of the regular expression
|
||||
+\fB"!^(sd[a-z]|dasd[a-z]|nvme[0-9])"\fR. This causes all device types other
|
||||
+than scsi, dasd, and nvme to be excluded from multipath handling by default.
|
||||
.RE
|
||||
.TP
|
||||
.B wwid
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 6e7c1864..d5c40898 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -60,20 +60,46 @@ __wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry)
|
||||
return *(const char **)list_entry;
|
||||
}
|
||||
|
||||
+vector elist_property_default;
|
||||
+vector blist_devnode_default;
|
||||
vector blist_devnode_sdb;
|
||||
+vector blist_devnode_sdb_inv;
|
||||
vector blist_all;
|
||||
vector blist_device_foo_bar;
|
||||
+vector blist_device_foo_inv_bar;
|
||||
+vector blist_device_foo_bar_inv;
|
||||
vector blist_device_all;
|
||||
vector blist_wwid_xyzzy;
|
||||
+vector blist_wwid_xyzzy_inv;
|
||||
vector blist_protocol_fcp;
|
||||
+vector blist_protocol_fcp_inv;
|
||||
vector blist_property_wwn;
|
||||
+vector blist_property_wwn_inv;
|
||||
|
||||
static int setup(void **state)
|
||||
{
|
||||
+ struct config conf;
|
||||
+
|
||||
+ memset(&conf, 0, sizeof(conf));
|
||||
+ conf.blist_devnode = vector_alloc();
|
||||
+ if (!conf.blist_devnode)
|
||||
+ return -1;
|
||||
+ conf.elist_property = vector_alloc();
|
||||
+ if (!conf.elist_property)
|
||||
+ return -1;
|
||||
+ if (setup_default_blist(&conf) != 0)
|
||||
+ return -1;
|
||||
+ elist_property_default = conf.elist_property;
|
||||
+ blist_devnode_default = conf.blist_devnode;
|
||||
+
|
||||
blist_devnode_sdb = vector_alloc();
|
||||
if (!blist_devnode_sdb ||
|
||||
store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_devnode_sdb_inv = vector_alloc();
|
||||
+ if (!blist_devnode_sdb_inv ||
|
||||
+ store_ble(blist_devnode_sdb_inv, strdup("!sdb"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_all = vector_alloc();
|
||||
if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG))
|
||||
@@ -84,6 +110,18 @@ static int setup(void **state)
|
||||
set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"),
|
||||
ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_device_foo_inv_bar = vector_alloc();
|
||||
+ if (!blist_device_foo_inv_bar ||
|
||||
+ alloc_ble_device(blist_device_foo_inv_bar) ||
|
||||
+ set_ble_device(blist_device_foo_inv_bar, strdup("!foo"),
|
||||
+ strdup("bar"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
+ blist_device_foo_bar_inv = vector_alloc();
|
||||
+ if (!blist_device_foo_bar_inv ||
|
||||
+ alloc_ble_device(blist_device_foo_bar_inv) ||
|
||||
+ set_ble_device(blist_device_foo_bar_inv, strdup("foo"),
|
||||
+ strdup("!bar"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_device_all = vector_alloc();
|
||||
if (!blist_device_all || alloc_ble_device(blist_device_all) ||
|
||||
@@ -95,29 +133,50 @@ static int setup(void **state)
|
||||
if (!blist_wwid_xyzzy ||
|
||||
store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_wwid_xyzzy_inv = vector_alloc();
|
||||
+ if (!blist_wwid_xyzzy_inv ||
|
||||
+ store_ble(blist_wwid_xyzzy_inv, strdup("!xyzzy"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_protocol_fcp = vector_alloc();
|
||||
if (!blist_protocol_fcp ||
|
||||
store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_protocol_fcp_inv = vector_alloc();
|
||||
+ if (!blist_protocol_fcp_inv ||
|
||||
+ store_ble(blist_protocol_fcp_inv, strdup("!scsi:fcp"),
|
||||
+ ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
blist_property_wwn = vector_alloc();
|
||||
if (!blist_property_wwn ||
|
||||
store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG))
|
||||
return -1;
|
||||
+ blist_property_wwn_inv = vector_alloc();
|
||||
+ if (!blist_property_wwn_inv ||
|
||||
+ store_ble(blist_property_wwn_inv, strdup("!ID_WWN"), ORIGIN_CONFIG))
|
||||
+ return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int teardown(void **state)
|
||||
{
|
||||
+ free_blacklist(elist_property_default);
|
||||
+ free_blacklist(blist_devnode_default);
|
||||
free_blacklist(blist_devnode_sdb);
|
||||
+ free_blacklist(blist_devnode_sdb_inv);
|
||||
free_blacklist(blist_all);
|
||||
free_blacklist_device(blist_device_foo_bar);
|
||||
+ free_blacklist_device(blist_device_foo_inv_bar);
|
||||
+ free_blacklist_device(blist_device_foo_bar_inv);
|
||||
free_blacklist_device(blist_device_all);
|
||||
free_blacklist(blist_wwid_xyzzy);
|
||||
+ free_blacklist(blist_wwid_xyzzy_inv);
|
||||
free_blacklist(blist_protocol_fcp);
|
||||
+ free_blacklist(blist_protocol_fcp_inv);
|
||||
free_blacklist(blist_property_wwn);
|
||||
+ free_blacklist(blist_property_wwn_inv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -141,6 +200,11 @@ static void test_devnode_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: device node name blacklisted\n");
|
||||
assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"),
|
||||
MATCH_DEVNODE_BLIST);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdc: device node name blacklisted\n");
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_sdb_inv, NULL, "sdc"),
|
||||
+ MATCH_DEVNODE_BLIST);
|
||||
}
|
||||
|
||||
static void test_devnode_whitelist(void **state)
|
||||
@@ -159,12 +223,39 @@ static void test_devnode_missing(void **state)
|
||||
MATCH_NOTHING);
|
||||
}
|
||||
|
||||
+static void test_devnode_default(void **state)
|
||||
+{
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "sdaa"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "nvme0n1"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "dasda"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "hda: device node name blacklisted\n");
|
||||
+ assert_int_equal(filter_devnode(blist_devnode_default, NULL, "hda"),
|
||||
+ MATCH_DEVNODE_BLIST);
|
||||
+}
|
||||
+
|
||||
static void test_device_blacklist(void **state)
|
||||
{
|
||||
expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n");
|
||||
assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo",
|
||||
"bar", "sdb"),
|
||||
MATCH_DEVICE_BLIST);
|
||||
+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "foo",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdb: (baz:bar) vendor/product blacklisted\n");
|
||||
+ assert_int_equal(filter_device(blist_device_foo_inv_bar, NULL, "baz",
|
||||
+ "bar", "sdb"),
|
||||
+ MATCH_DEVICE_BLIST);
|
||||
+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n");
|
||||
+ assert_int_equal(filter_device(blist_device_foo_bar_inv, NULL, "foo",
|
||||
+ "baz", "sdb"),
|
||||
+ MATCH_DEVICE_BLIST);
|
||||
}
|
||||
|
||||
static void test_device_whitelist(void **state)
|
||||
@@ -191,6 +282,11 @@ static void test_wwid_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: wwid xyzzy blacklisted\n");
|
||||
assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"),
|
||||
MATCH_WWID_BLIST);
|
||||
+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "xyzzy",
|
||||
+ "sdb"), MATCH_NOTHING);
|
||||
+ expect_condlog(3, "sdb: wwid plugh blacklisted\n");
|
||||
+ assert_int_equal(filter_wwid(blist_wwid_xyzzy_inv, NULL, "plugh",
|
||||
+ "sdb"), MATCH_WWID_BLIST);
|
||||
}
|
||||
|
||||
static void test_wwid_whitelist(void **state)
|
||||
@@ -218,6 +314,12 @@ static void test_protocol_blacklist(void **state)
|
||||
expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n");
|
||||
assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp),
|
||||
MATCH_PROTOCOL_BLIST);
|
||||
+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp),
|
||||
+ MATCH_NOTHING);
|
||||
+ pp.sg_id.proto_id = SCSI_PROTOCOL_ATA;
|
||||
+ expect_condlog(3, "sdb: protocol scsi:ata blacklisted\n");
|
||||
+ assert_int_equal(filter_protocol(blist_protocol_fcp_inv, NULL, &pp),
|
||||
+ MATCH_PROTOCOL_BLIST);
|
||||
}
|
||||
|
||||
static void test_protocol_whitelist(void **state)
|
||||
@@ -245,10 +347,17 @@ static void test_protocol_missing(void **state)
|
||||
static void test_property_blacklist(void **state)
|
||||
{
|
||||
static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } };
|
||||
+ static struct udev_device udev_inv = { "sdb", { "ID_WWN", NULL } };
|
||||
conf.blist_property = blist_property_wwn;
|
||||
expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
MATCH_PROPERTY_BLIST);
|
||||
+ conf.blist_property = blist_property_wwn_inv;
|
||||
+ expect_condlog(3, "sdb: udev property ID_FOO blacklisted\n");
|
||||
+ assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
+ MATCH_PROPERTY_BLIST);
|
||||
+ assert_int_equal(filter_property(&conf, &udev_inv, 3, "ID_SERIAL"),
|
||||
+ MATCH_NOTHING);
|
||||
}
|
||||
|
||||
/* the property check works different in that you check all the property
|
||||
@@ -484,6 +593,7 @@ int test_blacklist(void)
|
||||
cmocka_unit_test(test_devnode_blacklist),
|
||||
cmocka_unit_test(test_devnode_whitelist),
|
||||
cmocka_unit_test(test_devnode_missing),
|
||||
+ cmocka_unit_test(test_devnode_default),
|
||||
cmocka_unit_test(test_device_blacklist),
|
||||
cmocka_unit_test(test_device_whitelist),
|
||||
cmocka_unit_test(test_device_missing),
|
||||
diff --git a/tests/test-lib.c b/tests/test-lib.c
|
||||
index 00bae58e..b7c09cc2 100644
|
||||
--- a/tests/test-lib.c
|
||||
+++ b/tests/test-lib.c
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "test-lib.h"
|
||||
|
||||
const int default_mask = (DI_SYSFS|DI_BLACKLIST|DI_WWID|DI_CHECKER|DI_PRIO);
|
||||
-const char default_devnode[] = "sdTEST";
|
||||
+const char default_devnode[] = "sdxTEST";
|
||||
const char default_wwid[] = "TEST-WWID";
|
||||
/* default_wwid should be a substring of default_wwid_1! */
|
||||
const char default_wwid_1[] = "TEST-WWID-1";
|
||||
--
|
||||
2.17.2
|
||||
|
111
0036-multipath-Fix-compiler-warnings-when-built-without-s.patch
Normal file
111
0036-multipath-Fix-compiler-warnings-when-built-without-s.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marius Bakke <marius@devup.no>
|
||||
Date: Wed, 17 Jun 2020 01:11:26 +0200
|
||||
Subject: [PATCH] multipath: Fix compiler warnings when built without systemd.
|
||||
|
||||
Add ifdef guards for code that is unused when systemd is not available.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 6 ++++--
|
||||
multipathd/main.c | 10 +++++++++-
|
||||
2 files changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index b4d87689..658bec8b 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -696,9 +696,9 @@ process_config_dir(struct config *conf, char *dir)
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
|
||||
+#ifdef USE_SYSTEMD
|
||||
static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
{
|
||||
-#ifdef USE_SYSTEMD
|
||||
char *envp = getenv("WATCHDOG_USEC");
|
||||
unsigned long checkint;
|
||||
|
||||
@@ -714,8 +714,8 @@ static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
condlog(3, "enabling watchdog, interval %ld", checkint);
|
||||
conf->use_watchdog = true;
|
||||
}
|
||||
-#endif
|
||||
}
|
||||
+#endif
|
||||
|
||||
struct config *
|
||||
load_config (char * file)
|
||||
@@ -789,7 +789,9 @@ load_config (char * file)
|
||||
/*
|
||||
* fill the voids left in the config file
|
||||
*/
|
||||
+#ifdef USE_SYSTEMD
|
||||
set_max_checkint_from_watchdog(conf);
|
||||
+#endif
|
||||
if (conf->max_checkint == 0) {
|
||||
if (conf->checkint == CHECKINT_UNDEF)
|
||||
conf->checkint = DEFAULT_CHECKINT;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 6b7db2c0..205ddb32 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -176,6 +176,7 @@ daemon_status(void)
|
||||
/*
|
||||
* I love you too, systemd ...
|
||||
*/
|
||||
+#ifdef USE_SYSTEMD
|
||||
static const char *
|
||||
sd_notify_status(enum daemon_status state)
|
||||
{
|
||||
@@ -195,7 +196,6 @@ sd_notify_status(enum daemon_status state)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-#ifdef USE_SYSTEMD
|
||||
static void do_sd_notify(enum daemon_status old_state,
|
||||
enum daemon_status new_state)
|
||||
{
|
||||
@@ -247,7 +247,9 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate,
|
||||
static void __post_config_state(enum daemon_status state)
|
||||
{
|
||||
if (state != running_state && running_state != DAEMON_SHUTDOWN) {
|
||||
+#ifdef USE_SYSTEMD
|
||||
enum daemon_status old_state = running_state;
|
||||
+#endif
|
||||
|
||||
running_state = state;
|
||||
pthread_cond_broadcast(&config_cond);
|
||||
@@ -272,7 +274,9 @@ int set_config_state(enum daemon_status state)
|
||||
pthread_cleanup_push(config_cleanup, NULL);
|
||||
pthread_mutex_lock(&config_lock);
|
||||
if (running_state != state) {
|
||||
+#ifdef USE_SYSTEMD
|
||||
enum daemon_status old_state = running_state;
|
||||
+#endif
|
||||
|
||||
if (running_state == DAEMON_SHUTDOWN)
|
||||
rc = EINVAL;
|
||||
@@ -2280,7 +2284,9 @@ checkerloop (void *ap)
|
||||
struct timespec last_time;
|
||||
struct config *conf;
|
||||
int foreign_tick = 0;
|
||||
+#ifdef USE_SYSTEMD
|
||||
bool use_watchdog;
|
||||
+#endif
|
||||
|
||||
pthread_cleanup_push(rcu_unregister, NULL);
|
||||
rcu_register_thread();
|
||||
@@ -2294,7 +2300,9 @@ checkerloop (void *ap)
|
||||
|
||||
/* use_watchdog is set from process environment and never changes */
|
||||
conf = get_multipath_config();
|
||||
+#ifdef USE_SYSTEMD
|
||||
use_watchdog = conf->use_watchdog;
|
||||
+#endif
|
||||
put_multipath_config(conf);
|
||||
|
||||
while (1) {
|
||||
--
|
||||
2.17.2
|
||||
|
43
0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch
Normal file
43
0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:38:24 -0500
|
||||
Subject: [PATCH] libmultipath: fix sysfs dev_loss_tmo parsing
|
||||
|
||||
dev_loss_tmo is a u32 value. However the kernel sysfs code prints it as
|
||||
a signed integer. This means that if dev_loss_tmo is above INT_MAX, the
|
||||
sysfs value will be a negative number. Parsing this was causing
|
||||
sysfs_set_rport_tmo() to fail.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.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
|
||||
|
267
0038-kpartx-read-devices-with-direct-IO.patch
Normal file
267
0038-kpartx-read-devices-with-direct-IO.patch
Normal file
@ -0,0 +1,267 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:38:25 -0500
|
||||
Subject: [PATCH] kpartx: read devices with direct IO
|
||||
|
||||
If kpartx is used on top of shared storage, and a device has its
|
||||
partition table changed on one machine, and then kpartx is run on
|
||||
another, it may not see the new data, because the cache still contains
|
||||
the old data, and there is nothing to tell the machine running kpartx to
|
||||
invalidate it. To solve this, kpartx should read the devices using
|
||||
direct io.
|
||||
|
||||
One issue with how this code has been updated is that the original code
|
||||
for getblock() always read 1024 bytes. The new code reads a logical
|
||||
sector size chunk of the device, and returns a pointer to the 512 byte
|
||||
sector that the caller asked for, within that (possibly larger) chunk.
|
||||
This means that if the logical sector size is 512, then the code is now
|
||||
only reading 512 bytes. Looking through the code for the various
|
||||
partition types, I can't see a case where more than 512 bytes is needed
|
||||
and getblock() is used. If anyone has a reason why this code should be
|
||||
reading 1024 bytes at minmum, I can certainly change this. But when I
|
||||
looked, I couldn't find a case where reading 512 bytes would cause a
|
||||
problem.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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
|
||||
|
53
0039-kpartx-handle-alternate-bsd-disklabel-location.patch
Normal file
53
0039-kpartx-handle-alternate-bsd-disklabel-location.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:38:26 -0500
|
||||
Subject: [PATCH] kpartx: handle alternate bsd disklabel location
|
||||
|
||||
bsd disk labels can either be at the start of the second sector, or 64
|
||||
bytes into the first sector, but kpartx only handled the first case.
|
||||
However the second case is what parted creates, and what the linux
|
||||
kernel partition code expects. kpartx should handle both cases.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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,62 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:38:27 -0500
|
||||
Subject: [PATCH] libmultipath: fix checker detection for nvme devices
|
||||
|
||||
In order to fix hwhandler autodetection, commit 8794a776 made
|
||||
detect_alua() differentiate between failures to detect whether alua was
|
||||
supported, and successfully detecting that it was not supported.
|
||||
However, this causes nvme devices to get the TUR checker assigned to
|
||||
them. This is because there is nothing in detect_alua() to make it only
|
||||
work on scsi devices, and select_checker wasn't updated to handle
|
||||
detect_alua() failing without setting pp->tpgs to TPGS_NONE.
|
||||
|
||||
detect_alua() should automatically set pp->tpgs to TPGS_NONE and exit on
|
||||
non-scsi devices. Also, select_checker() should not assume that a
|
||||
devices is ALUA, simply because if failed to detect if alua was
|
||||
supported.
|
||||
|
||||
Fixes: 8794a776 "libmultipath: fix ALUA autodetection when paths are
|
||||
down"
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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
|
||||
|
322
0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch
Normal file
322
0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch
Normal file
@ -0,0 +1,322 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:00 -0500
|
||||
Subject: [PATCH] libmultipath: make dm_get_map/status return codes symbolic
|
||||
|
||||
dm_get_map() and dm_get_status() now use symbolic return codes. They
|
||||
also differentiate between failing to get information from device-mapper
|
||||
and not finding the requested device. These symboilc return codes are
|
||||
also used by update_multipath_* functions.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 27d52398..24cc616a 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -534,36 +534,43 @@ int dm_map_present(const char * str)
|
||||
|
||||
int dm_get_map(const char *name, unsigned long long *size, char *outparams)
|
||||
{
|
||||
- int r = 1;
|
||||
+ int r = DMP_ERR;
|
||||
struct dm_task *dmt;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *params = NULL;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt))
|
||||
+ errno = 0;
|
||||
+ if (!dm_task_run(dmt)) {
|
||||
+ if (dm_task_get_errno(dmt) == ENXIO)
|
||||
+ r = DMP_NOT_FOUND;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
+ r = DMP_NOT_FOUND;
|
||||
/* Fetch 1st target */
|
||||
- dm_get_next_target(dmt, NULL, &start, &length,
|
||||
- &target_type, ¶ms);
|
||||
+ if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
+ &target_type, ¶ms) != NULL)
|
||||
+ /* more than one target */
|
||||
+ goto out;
|
||||
|
||||
if (size)
|
||||
*size = length;
|
||||
|
||||
if (!outparams) {
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
goto out;
|
||||
}
|
||||
if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
@@ -637,35 +644,45 @@ is_mpath_part(const char *part_name, const char *map_name)
|
||||
|
||||
int dm_get_status(const char *name, char *outstatus)
|
||||
{
|
||||
- int r = 1;
|
||||
+ int r = DMP_ERR;
|
||||
struct dm_task *dmt;
|
||||
uint64_t start, length;
|
||||
char *target_type = NULL;
|
||||
char *status = NULL;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
if (!dm_task_set_name(dmt, name))
|
||||
goto out;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt))
|
||||
+ errno = 0;
|
||||
+ if (!dm_task_run(dmt)) {
|
||||
+ if (dm_task_get_errno(dmt) == ENXIO)
|
||||
+ r = DMP_NOT_FOUND;
|
||||
goto out;
|
||||
+ }
|
||||
|
||||
+ r = DMP_NOT_FOUND;
|
||||
/* Fetch 1st target */
|
||||
- dm_get_next_target(dmt, NULL, &start, &length,
|
||||
- &target_type, &status);
|
||||
+ if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
+ &target_type, &status) != NULL)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!target_type || strcmp(target_type, TGT_MPATH) != 0)
|
||||
+ goto out;
|
||||
+
|
||||
if (!status) {
|
||||
condlog(2, "get null status.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE)
|
||||
- r = 0;
|
||||
+ r = DMP_OK;
|
||||
out:
|
||||
- if (r)
|
||||
+ if (r != DMP_OK)
|
||||
condlog(0, "%s: error getting map status string", name);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
@@ -920,7 +937,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
||||
return 1;
|
||||
|
||||
if (need_suspend &&
|
||||
- !dm_get_map(mapname, &mapsize, params) &&
|
||||
+ dm_get_map(mapname, &mapsize, params) == DMP_OK &&
|
||||
strstr(params, "queue_if_no_path")) {
|
||||
if (!dm_queue_if_no_path(mapname, 0))
|
||||
queue_if_no_path = 1;
|
||||
@@ -1129,7 +1146,7 @@ struct multipath *dm_get_multipath(const char *name)
|
||||
if (!mpp->alias)
|
||||
goto out;
|
||||
|
||||
- if (dm_get_map(name, &mpp->size, NULL))
|
||||
+ if (dm_get_map(name, &mpp->size, NULL) != DMP_OK)
|
||||
goto out;
|
||||
|
||||
dm_get_uuid(name, mpp->wwid, WWID_SIZE);
|
||||
@@ -1313,7 +1330,7 @@ do_foreach_partmaps (const char * mapname,
|
||||
/*
|
||||
* and we can fetch the map table from the kernel
|
||||
*/
|
||||
- !dm_get_map(names->name, &size, ¶ms[0]) &&
|
||||
+ dm_get_map(names->name, &size, ¶ms[0]) == DMP_OK &&
|
||||
|
||||
/*
|
||||
* and the table maps over the multipath map
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index 5ed7edc5..b2108638 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -27,6 +27,12 @@
|
||||
#define UUID_PREFIX "mpath-"
|
||||
#define UUID_PREFIX_LEN (sizeof(UUID_PREFIX) - 1)
|
||||
|
||||
+enum {
|
||||
+ DMP_ERR,
|
||||
+ DMP_OK,
|
||||
+ DMP_NOT_FOUND,
|
||||
+};
|
||||
+
|
||||
void dm_init(int verbosity);
|
||||
int dm_prereq(unsigned int *v);
|
||||
void skip_libmp_dm_init(void);
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 077f2e42..8137ea21 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -196,43 +196,47 @@ extract_hwe_from_path(struct multipath * mpp)
|
||||
int
|
||||
update_multipath_table (struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
{
|
||||
+ int r = DMP_ERR;
|
||||
char params[PARAMS_SIZE] = {0};
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
- if (dm_get_map(mpp->alias, &mpp->size, params)) {
|
||||
- condlog(3, "%s: cannot get map", mpp->alias);
|
||||
- return 1;
|
||||
+ r = dm_get_map(mpp->alias, &mpp->size, params);
|
||||
+ if (r != DMP_OK) {
|
||||
+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting table" : "map not present");
|
||||
+ return r;
|
||||
}
|
||||
|
||||
if (disassemble_map(pathvec, params, mpp, is_daemon)) {
|
||||
condlog(3, "%s: cannot disassemble map", mpp->alias);
|
||||
- return 1;
|
||||
+ return DMP_ERR;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
int
|
||||
update_multipath_status (struct multipath *mpp)
|
||||
{
|
||||
+ int r = DMP_ERR;
|
||||
char status[PARAMS_SIZE] = {0};
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
- if (dm_get_status(mpp->alias, status)) {
|
||||
- condlog(3, "%s: cannot get status", mpp->alias);
|
||||
- return 1;
|
||||
+ r = dm_get_status(mpp->alias, status);
|
||||
+ if (r != DMP_OK) {
|
||||
+ condlog(3, "%s: %s", mpp->alias, (r == DMP_ERR)? "error getting status" : "map not present");
|
||||
+ return r;
|
||||
}
|
||||
|
||||
if (disassemble_status(status, mpp)) {
|
||||
condlog(3, "%s: cannot disassemble status", mpp->alias);
|
||||
- return 1;
|
||||
+ return DMP_ERR;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
void sync_paths(struct multipath *mpp, vector pathvec)
|
||||
@@ -264,10 +268,10 @@ int
|
||||
update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
{
|
||||
struct pathgroup *pgp;
|
||||
- int i;
|
||||
+ int i, r = DMP_ERR;
|
||||
|
||||
if (!mpp)
|
||||
- return 1;
|
||||
+ return r;
|
||||
|
||||
update_mpp_paths(mpp, pathvec);
|
||||
condlog(4, "%s: %s", mpp->alias, __FUNCTION__);
|
||||
@@ -276,18 +280,21 @@ update_multipath_strings(struct multipath *mpp, vector pathvec, int is_daemon)
|
||||
free_pgvec(mpp->pg, KEEP_PATHS);
|
||||
mpp->pg = NULL;
|
||||
|
||||
- if (update_multipath_table(mpp, pathvec, is_daemon))
|
||||
- return 1;
|
||||
+ r = update_multipath_table(mpp, pathvec, is_daemon);
|
||||
+ if (r != DMP_OK)
|
||||
+ return r;
|
||||
+
|
||||
sync_paths(mpp, pathvec);
|
||||
|
||||
- if (update_multipath_status(mpp))
|
||||
- return 1;
|
||||
+ r = update_multipath_status(mpp);
|
||||
+ if (r != DMP_OK)
|
||||
+ return r;
|
||||
|
||||
vector_foreach_slot(mpp->pg, pgp, i)
|
||||
if (pgp->paths)
|
||||
path_group_prio_update(pgp);
|
||||
|
||||
- return 0;
|
||||
+ return DMP_OK;
|
||||
}
|
||||
|
||||
static void enter_recovery_mode(struct multipath *mpp)
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 205ddb32..ab141fed 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -418,7 +418,7 @@ int __setup_multipath(struct vectors *vecs, struct multipath *mpp,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (update_multipath_strings(mpp, vecs->pathvec, 1)) {
|
||||
+ if (update_multipath_strings(mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
condlog(0, "%s: failed to setup multipath", mpp->alias);
|
||||
goto out;
|
||||
}
|
||||
@@ -557,9 +557,9 @@ add_map_without_path (struct vectors *vecs, const char *alias)
|
||||
mpp->mpe = find_mpe(conf->mptable, mpp->wwid);
|
||||
put_multipath_config(conf);
|
||||
|
||||
- if (update_multipath_table(mpp, vecs->pathvec, 1))
|
||||
+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK)
|
||||
goto out;
|
||||
- if (update_multipath_status(mpp))
|
||||
+ if (update_multipath_status(mpp) != DMP_OK)
|
||||
goto out;
|
||||
|
||||
if (!vector_alloc_slot(vecs->mpvec))
|
||||
@@ -1350,8 +1350,8 @@ map_discovery (struct vectors * vecs)
|
||||
return 1;
|
||||
|
||||
vector_foreach_slot (vecs->mpvec, mpp, i)
|
||||
- if (update_multipath_table(mpp, vecs->pathvec, 1) ||
|
||||
- update_multipath_status(mpp)) {
|
||||
+ if (update_multipath_table(mpp, vecs->pathvec, 1) != DMP_OK ||
|
||||
+ update_multipath_status(mpp) != DMP_OK) {
|
||||
remove_map(mpp, vecs, 1);
|
||||
i--;
|
||||
}
|
||||
@@ -2091,7 +2091,7 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* Synchronize with kernel state
|
||||
*/
|
||||
- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1)) {
|
||||
+ if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
condlog(1, "%s: Could not synchronize with kernel state",
|
||||
pp->dev);
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
--
|
||||
2.17.2
|
||||
|
116
0042-multipathd-fix-check_path-errors-with-removed-map.patch
Normal file
116
0042-multipathd-fix-check_path-errors-with-removed-map.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:01 -0500
|
||||
Subject: [PATCH] multipathd: fix check_path errors with removed map
|
||||
|
||||
If a multipath device is removed during, or immediately before the call
|
||||
to check_path(), multipathd can behave incorrectly. A missing multpath
|
||||
device will cause update_multipath_strings() to fail, setting
|
||||
pp->dmstate to PSTATE_UNDEF. If the path is up, this state will cause
|
||||
reinstate_path() to be called, which will also fail. This will trigger
|
||||
a reload, restoring the recently removed device.
|
||||
|
||||
If update_multipath_strings() fails because there is no multipath
|
||||
device, check_path should just quit, since the remove dmevent and uevent
|
||||
are likely already queued up. Also, I don't see any reason to reload the
|
||||
multipath device if reinstate fails. This code was added by
|
||||
fac68d7a99ef17d496079538a5c6836acd7911ab, which clamined that reinstate
|
||||
could fail if the path was disabled. Looking through the current kernel
|
||||
code, I can't see any reason why a reinstate would fail, where a reload
|
||||
would help. If the path was missing from the multipath device,
|
||||
update_multipath_strings() would already catch that, and quit
|
||||
check_path() early, which make more sense to me than reloading does.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 ab141fed..daf19a4e 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1615,22 +1615,18 @@ fail_path (struct path * pp, int del_active)
|
||||
/*
|
||||
* caller must have locked the path list before calling that function
|
||||
*/
|
||||
-static int
|
||||
+static void
|
||||
reinstate_path (struct path * pp)
|
||||
{
|
||||
- int ret = 0;
|
||||
-
|
||||
if (!pp->mpp)
|
||||
- return 0;
|
||||
+ return;
|
||||
|
||||
- if (dm_reinstate_path(pp->mpp->alias, pp->dev_t)) {
|
||||
+ if (dm_reinstate_path(pp->mpp->alias, pp->dev_t))
|
||||
condlog(0, "%s: reinstate failed", pp->dev_t);
|
||||
- ret = 1;
|
||||
- } else {
|
||||
+ else {
|
||||
condlog(2, "%s: reinstated", pp->dev_t);
|
||||
update_queue_mode_add_path(pp->mpp);
|
||||
}
|
||||
- return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2091,9 +2087,16 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* Synchronize with kernel state
|
||||
*/
|
||||
- if (update_multipath_strings(pp->mpp, vecs->pathvec, 1) != DMP_OK) {
|
||||
- condlog(1, "%s: Could not synchronize with kernel state",
|
||||
- pp->dev);
|
||||
+ ret = update_multipath_strings(pp->mpp, vecs->pathvec, 1);
|
||||
+ if (ret != DMP_OK) {
|
||||
+ if (ret == DMP_NOT_FOUND) {
|
||||
+ /* multipath device missing. Likely removed */
|
||||
+ condlog(1, "%s: multipath device '%s' not found",
|
||||
+ pp->dev, pp->mpp->alias);
|
||||
+ return 0;
|
||||
+ } else
|
||||
+ condlog(1, "%s: Couldn't synchronize with kernel state",
|
||||
+ pp->dev);
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
}
|
||||
/* if update_multipath_strings orphaned the path, quit early */
|
||||
@@ -2183,12 +2186,8 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
/*
|
||||
* reinstate this path
|
||||
*/
|
||||
- if (!disable_reinstate && reinstate_path(pp)) {
|
||||
- condlog(3, "%s: reload map", pp->dev);
|
||||
- ev_add_path(pp, vecs, 1);
|
||||
- pp->tick = 1;
|
||||
- return 0;
|
||||
- }
|
||||
+ if (!disable_reinstate)
|
||||
+ reinstate_path(pp);
|
||||
new_path_up = 1;
|
||||
|
||||
if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
|
||||
@@ -2204,15 +2203,10 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
|
||||
else if (newstate == PATH_UP || newstate == PATH_GHOST) {
|
||||
if ((pp->dmstate == PSTATE_FAILED ||
|
||||
pp->dmstate == PSTATE_UNDEF) &&
|
||||
- !disable_reinstate) {
|
||||
+ !disable_reinstate)
|
||||
/* Clear IO errors */
|
||||
- if (reinstate_path(pp)) {
|
||||
- condlog(3, "%s: reload map", pp->dev);
|
||||
- ev_add_path(pp, vecs, 1);
|
||||
- pp->tick = 1;
|
||||
- return 0;
|
||||
- }
|
||||
- } else {
|
||||
+ reinstate_path(pp);
|
||||
+ else {
|
||||
LOG_MSG(4, verbosity, pp);
|
||||
if (pp->checkint != max_checkint) {
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:02 -0500
|
||||
Subject: [PATCH] libmultipath: make dm_flush_maps only return 0 on success
|
||||
|
||||
dm_flush_maps() returned both 0 and 1 on error, depending on which part
|
||||
of the function it was in, but the caller was always treating 0 as a
|
||||
success. Make dm_flush_maps() always return 1 on error and 0 on success.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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 24cc616a..4c86b6d4 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -1007,13 +1007,13 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove)
|
||||
|
||||
int dm_flush_maps (int retries)
|
||||
{
|
||||
- int r = 0;
|
||||
+ int r = 1;
|
||||
struct dm_task *dmt;
|
||||
struct dm_names *names;
|
||||
unsigned next = 0;
|
||||
|
||||
if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST)))
|
||||
- return 0;
|
||||
+ return r;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
@@ -1026,6 +1026,7 @@ int dm_flush_maps (int retries)
|
||||
if (!names->dev)
|
||||
goto out;
|
||||
|
||||
+ r = 0;
|
||||
do {
|
||||
r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
next = names->next;
|
||||
--
|
||||
2.17.2
|
||||
|
161
0044-multipathd-add-del-maps-multipathd-command.patch
Normal file
161
0044-multipathd-add-del-maps-multipathd-command.patch
Normal file
@ -0,0 +1,161 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:03 -0500
|
||||
Subject: [PATCH] multipathd: add "del maps" multipathd command
|
||||
|
||||
This will flush all multipath devices.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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 4c86b6d4..f597ff8b 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -1005,7 +1005,7 @@ dm_flush_map_nopaths(const char * mapname, int deferred_remove)
|
||||
|
||||
#endif
|
||||
|
||||
-int dm_flush_maps (int retries)
|
||||
+int dm_flush_maps (int need_suspend, int retries)
|
||||
{
|
||||
int r = 1;
|
||||
struct dm_task *dmt;
|
||||
@@ -1028,7 +1028,10 @@ int dm_flush_maps (int retries)
|
||||
|
||||
r = 0;
|
||||
do {
|
||||
- r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
+ if (need_suspend)
|
||||
+ r |= dm_suspend_and_flush_map(names->name, retries);
|
||||
+ else
|
||||
+ r |= dm_flush_map(names->name);
|
||||
next = names->next;
|
||||
names = (void *) names + next;
|
||||
} while (next);
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index b2108638..6dd178c8 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -57,7 +57,7 @@ int dm_flush_map_nopaths(const char * mapname, int deferred_remove);
|
||||
#define dm_suspend_and_flush_map(mapname, retries) \
|
||||
_dm_flush_map(mapname, 1, 0, 1, retries)
|
||||
int dm_cancel_deferred_remove(struct multipath *mpp);
|
||||
-int dm_flush_maps (int retries);
|
||||
+int dm_flush_maps (int need_suspend, int retries);
|
||||
int dm_fail_path(const char * mapname, char * path);
|
||||
int dm_reinstate_path(const char * mapname, char * path);
|
||||
int dm_queue_if_no_path(const char *mapname, int enable);
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index c4740fab..d89f0a91 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -1096,7 +1096,7 @@ main (int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
else if (conf->remove == FLUSH_ALL) {
|
||||
- r = dm_flush_maps(retries) ? RTVL_FAIL : RTVL_OK;
|
||||
+ r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
while ((r = configure(conf, cmd, dev_type, dev)) == RTVL_RETRY)
|
||||
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||||
index 800c0fbe..bdc9fb10 100644
|
||||
--- a/multipathd/cli.c
|
||||
+++ b/multipathd/cli.c
|
||||
@@ -568,6 +568,7 @@ cli_init (void) {
|
||||
add_handler(DEL+PATH, NULL);
|
||||
add_handler(ADD+MAP, NULL);
|
||||
add_handler(DEL+MAP, NULL);
|
||||
+ add_handler(DEL+MAPS, NULL);
|
||||
add_handler(SWITCH+MAP+GROUP, NULL);
|
||||
add_handler(RECONFIGURE, NULL);
|
||||
add_handler(SUSPEND+MAP, NULL);
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 31c3d9fd..782bb003 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -852,6 +852,25 @@ cli_del_map (void * v, char ** reply, int * len, void * data)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+int
|
||||
+cli_del_maps (void *v, char **reply, int *len, void *data)
|
||||
+{
|
||||
+ struct vectors * vecs = (struct vectors *)data;
|
||||
+ struct multipath *mpp;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ condlog(2, "remove maps (operator)");
|
||||
+ vector_foreach_slot(vecs->mpvec, mpp, i) {
|
||||
+ if (flush_map(mpp, vecs, 0))
|
||||
+ ret++;
|
||||
+ else
|
||||
+ i--;
|
||||
+ }
|
||||
+ /* flush any multipath maps that aren't currently known by multipathd */
|
||||
+ ret |= dm_flush_maps(0, 0);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int
|
||||
cli_reload(void *v, char **reply, int *len, void *data)
|
||||
{
|
||||
diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
|
||||
index 0f451064..6f57b429 100644
|
||||
--- a/multipathd/cli_handlers.h
|
||||
+++ b/multipathd/cli_handlers.h
|
||||
@@ -26,6 +26,7 @@ int cli_add_path (void * v, char ** reply, int * len, void * data);
|
||||
int cli_del_path (void * v, char ** reply, int * len, void * data);
|
||||
int cli_add_map (void * v, char ** reply, int * len, void * data);
|
||||
int cli_del_map (void * v, char ** reply, int * len, void * data);
|
||||
+int cli_del_maps (void * v, char ** reply, int * len, void * data);
|
||||
int cli_switch_group(void * v, char ** reply, int * len, void * data);
|
||||
int cli_reconfigure(void * v, char ** reply, int * len, void * data);
|
||||
int cli_resize(void * v, char ** reply, int * len, void * data);
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index daf19a4e..f014d2a1 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -635,7 +635,7 @@ sync_maps_state(vector mpvec)
|
||||
sync_map_state(mpp);
|
||||
}
|
||||
|
||||
-static int
|
||||
+int
|
||||
flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||
{
|
||||
int r;
|
||||
@@ -1555,6 +1555,7 @@ uxlsnrloop (void * ap)
|
||||
set_handler_callback(DEL+PATH, cli_del_path);
|
||||
set_handler_callback(ADD+MAP, cli_add_map);
|
||||
set_handler_callback(DEL+MAP, cli_del_map);
|
||||
+ set_handler_callback(DEL+MAPS, cli_del_maps);
|
||||
set_handler_callback(SWITCH+MAP+GROUP, cli_switch_group);
|
||||
set_unlocked_handler_callback(RECONFIGURE, cli_reconfigure);
|
||||
set_handler_callback(SUSPEND+MAP, cli_suspend);
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index 7bb8463f..5dff17e5 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -28,6 +28,7 @@ int ev_add_path (struct path *, struct vectors *, int);
|
||||
int ev_remove_path (struct path *, struct vectors *, int);
|
||||
int ev_add_map (char *, const char *, struct vectors *);
|
||||
int ev_remove_map (char *, char *, int, struct vectors *);
|
||||
+int flush_map(struct multipath *, struct vectors *, int);
|
||||
int set_config_state(enum daemon_status);
|
||||
void * mpath_alloc_prin_response(int prin_sa);
|
||||
int prin_do_scsi_ioctl(char *, int rq_servact, struct prin_resp * resp,
|
||||
--
|
||||
2.17.2
|
||||
|
104
0045-multipath-make-flushing-maps-work-like-other-command.patch
Normal file
104
0045-multipath-make-flushing-maps-work-like-other-command.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:04 -0500
|
||||
Subject: [PATCH] multipath: make flushing maps work like other commands
|
||||
|
||||
The config structure doesn't need a special variable just for removes.
|
||||
Multipath can just use the cmd variable, like it does for the other
|
||||
commands.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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 ceecff2d..55569360 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -38,6 +38,8 @@ enum mpath_cmds {
|
||||
CMD_ADD_WWID,
|
||||
CMD_USABLE_PATHS,
|
||||
CMD_DUMP_CONFIG,
|
||||
+ CMD_FLUSH_ONE,
|
||||
+ CMD_FLUSH_ALL,
|
||||
};
|
||||
|
||||
enum force_reload_types {
|
||||
@@ -142,7 +144,6 @@ struct config {
|
||||
unsigned int max_checkint;
|
||||
bool use_watchdog;
|
||||
int pgfailback;
|
||||
- int remove;
|
||||
int rr_weight;
|
||||
int no_path_retry;
|
||||
int user_friendly_names;
|
||||
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
|
||||
index d7509000..0e33bf40 100644
|
||||
--- a/libmultipath/configure.h
|
||||
+++ b/libmultipath/configure.h
|
||||
@@ -45,9 +45,6 @@ enum {
|
||||
CP_RETRY,
|
||||
};
|
||||
|
||||
-#define FLUSH_ONE 1
|
||||
-#define FLUSH_ALL 2
|
||||
-
|
||||
struct vectors;
|
||||
|
||||
int setup_map (struct multipath * mpp, char * params, int params_size,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index d89f0a91..101fd656 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -909,10 +909,10 @@ main (int argc, char *argv[])
|
||||
cmd = CMD_DRY_RUN;
|
||||
break;
|
||||
case 'f':
|
||||
- conf->remove = FLUSH_ONE;
|
||||
+ cmd = CMD_FLUSH_ONE;
|
||||
break;
|
||||
case 'F':
|
||||
- conf->remove = FLUSH_ALL;
|
||||
+ cmd = CMD_FLUSH_ALL;
|
||||
break;
|
||||
case 'l':
|
||||
if (optarg && !strncmp(optarg, "l", 1))
|
||||
@@ -1053,6 +1053,10 @@ main (int argc, char *argv[])
|
||||
condlog(0, "the -w option requires a device");
|
||||
goto out;
|
||||
}
|
||||
+ if (cmd == CMD_FLUSH_ONE && dev_type != DEV_DEVMAP) {
|
||||
+ condlog(0, "the -f option requires a map name to remove");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
switch(delegate_to_multipathd(cmd, dev, dev_type, conf)) {
|
||||
case DELEGATE_OK:
|
||||
@@ -1086,16 +1090,12 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (retries < 0)
|
||||
retries = conf->remove_retries;
|
||||
- if (conf->remove == FLUSH_ONE) {
|
||||
- if (dev_type == DEV_DEVMAP) {
|
||||
- r = dm_suspend_and_flush_map(dev, retries) ?
|
||||
- RTVL_FAIL : RTVL_OK;
|
||||
- } else
|
||||
- condlog(0, "must provide a map name to remove");
|
||||
-
|
||||
+ if (cmd == CMD_FLUSH_ONE) {
|
||||
+ r = dm_suspend_and_flush_map(dev, retries) ?
|
||||
+ RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
- else if (conf->remove == FLUSH_ALL) {
|
||||
+ else if (cmd == CMD_FLUSH_ALL) {
|
||||
r = dm_flush_maps(1, retries) ? RTVL_FAIL : RTVL_OK;
|
||||
goto out;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
64
0046-multipath-delegate-flushing-maps-to-multipathd.patch
Normal file
64
0046-multipath-delegate-flushing-maps-to-multipathd.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:05 -0500
|
||||
Subject: [PATCH] multipath: delegate flushing maps to multipathd
|
||||
|
||||
Since there can be problems with removing maps outside of multipathd,
|
||||
multipath should attempt to delegate this command to multipathd.
|
||||
However, multipathd doesn't attempt to suspend the device, in order
|
||||
to avoid potential hangs. If delegating to multipathd fails, multipath
|
||||
should try the remove itself.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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 101fd656..6a24e483 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -820,6 +820,20 @@ int delegate_to_multipathd(enum mpath_cmds cmd,
|
||||
if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) {
|
||||
p += snprintf(p, n, "reconfigure");
|
||||
}
|
||||
+ else if (cmd == CMD_FLUSH_ONE && dev && dev_type == DEV_DEVMAP) {
|
||||
+ p += snprintf(p, n, "del map %s", dev);
|
||||
+ /* multipathd doesn't try as hard, to avoid potentially
|
||||
+ * hanging. If it fails, retry with the regular multipath
|
||||
+ * command */
|
||||
+ r = NOT_DELEGATED;
|
||||
+ }
|
||||
+ else if (cmd == CMD_FLUSH_ALL) {
|
||||
+ p += snprintf(p, n, "del maps");
|
||||
+ /* multipathd doesn't try as hard, to avoid potentially
|
||||
+ * hanging. If it fails, retry with the regular multipath
|
||||
+ * command */
|
||||
+ r = NOT_DELEGATED;
|
||||
+ }
|
||||
/* Add other translations here */
|
||||
|
||||
if (strlen(command) == 0)
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 6fb8645a..5b29a5d9 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -125,11 +125,11 @@ the system.
|
||||
Other operation modes are chosen by using one of the following command line switches:
|
||||
.TP
|
||||
.B \-f
|
||||
-Flush (remove) a multipath device map specified as parameter, if unused.
|
||||
+Flush (remove) a multipath device map specified as parameter, if unused. This operation is delegated to the multipathd daemon if it's running.
|
||||
.
|
||||
.TP
|
||||
.B \-F
|
||||
-Flush (remove) all unused multipath device maps.
|
||||
+Flush (remove) all unused multipath device maps. This operation is delegated to the multipathd daemon if it's running.
|
||||
.
|
||||
.TP
|
||||
.B \-l
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 2 Jul 2020 19:07:06 -0500
|
||||
Subject: [PATCH] multipath: add option to skip multipathd delegation
|
||||
|
||||
Add the -D option to allow users to skip delegating commands to
|
||||
multipathd.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
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 55569360..92c61a0d 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -190,6 +190,7 @@ struct config {
|
||||
int ghost_delay;
|
||||
int find_multipaths_timeout;
|
||||
int marginal_pathgroups;
|
||||
+ int skip_delegate;
|
||||
unsigned int version[3];
|
||||
unsigned int sequence_nr;
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 6a24e483..4c43314e 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -817,6 +817,9 @@ int delegate_to_multipathd(enum mpath_cmds cmd,
|
||||
*p = '\0';
|
||||
n = sizeof(command);
|
||||
|
||||
+ if (conf->skip_delegate)
|
||||
+ return NOT_DELEGATED;
|
||||
+
|
||||
if (cmd == CMD_CREATE && conf->force_reload == FORCE_RELOAD_YES) {
|
||||
p += snprintf(p, n, "reconfigure");
|
||||
}
|
||||
@@ -890,7 +893,7 @@ main (int argc, char *argv[])
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
- while ((arg = getopt(argc, argv, ":adcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -922,6 +925,9 @@ main (int argc, char *argv[])
|
||||
if (cmd == CMD_CREATE)
|
||||
cmd = CMD_DRY_RUN;
|
||||
break;
|
||||
+ case 'D':
|
||||
+ conf->skip_delegate = 1;
|
||||
+ break;
|
||||
case 'f':
|
||||
cmd = CMD_FLUSH_ONE;
|
||||
break;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -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 e7256e3a..8ea3352d 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -37,7 +37,7 @@ endif
|
||||
|
||||
ifndef SYSTEMD
|
||||
ifeq ($(shell pkg-config --modversion libsystemd >/dev/null 2>&1 && echo 1), 1)
|
||||
- SYSTEMD = $(shell pkg-config --modversion libsystemd)
|
||||
+ SYSTEMD = $(shell pkg-config --modversion libsystemd | awk '{print $$1}')
|
||||
else
|
||||
ifeq ($(shell systemctl --version >/dev/null 2>&1 && echo 1), 1)
|
||||
SYSTEMD = $(shell systemctl --version 2> /dev/null | \
|
||||
--
|
||||
2.17.2
|
||||
|
26
0049-kpartx-fix-Wsign-compare-error.patch
Normal file
26
0049-kpartx-fix-Wsign-compare-error.patch
Normal file
@ -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
|
||||
|
@ -15,7 +15,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 9060ac9b..034752d9 100644
|
||||
index 8ea3352d..873fb62f 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -53,7 +53,7 @@ endif
|
||||
@ -28,10 +28,10 @@ index 9060ac9b..034752d9 100644
|
||||
udevrulesdir = $(libudevdir)/rules.d
|
||||
multipathdir = $(TOPDIR)/libmultipath
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index 8f990494..8a3a1718 100644
|
||||
index d7527d7d..0e0d70d5 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end"
|
||||
@@ -36,6 +36,6 @@ LABEL="mpath_kpartx_end"
|
||||
GOTO="kpartx_end"
|
||||
|
||||
LABEL="run_kpartx"
|
@ -19,10 +19,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
3 files changed, 10 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index 00e8dbdb..d9691b17 100644
|
||||
index db58ccca..0c58aa32 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf)
|
||||
@@ -187,12 +187,6 @@ setup_default_blist (struct config * conf)
|
||||
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||
return 1;
|
||||
|
||||
@ -35,7 +35,7 @@ index 00e8dbdb..d9691b17 100644
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
@@ -394,7 +388,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
*uid_attribute != '\0';
|
||||
bool uid_attr_seen = false;
|
||||
|
||||
@ -46,10 +46,10 @@ index 00e8dbdb..d9691b17 100644
|
||||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 05a5e8ff..3455b1cc 100644
|
||||
index 5adaced6..42a192f6 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1286,9 +1286,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
@@ -1296,9 +1296,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
Regular expression for an udev property. All
|
||||
devices that have matching udev properties will be excluded/included.
|
||||
The handling of the \fIproperty\fR keyword is special,
|
||||
@ -65,7 +65,7 @@ index 05a5e8ff..3455b1cc 100644
|
||||
.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1299,10 +1304,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
@@ -1309,10 +1314,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR)
|
||||
set. Previously, it was applied to every device, possibly causing devices to be
|
||||
blacklisted because of temporary I/O error conditions.
|
||||
@ -77,10 +77,10 @@ index 05a5e8ff..3455b1cc 100644
|
||||
.TP
|
||||
.B protocol
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 6e7c1864..cc8a9a4a 100644
|
||||
index d5c40898..d20e97af 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -271,7 +271,7 @@ static void test_property_missing(void **state)
|
||||
@@ -380,7 +380,7 @@ static void test_property_missing(void **state)
|
||||
conf.blist_property = blist_property_wwn;
|
||||
expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
@ -89,7 +89,7 @@ index 6e7c1864..cc8a9a4a 100644
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"),
|
||||
MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, ""),
|
||||
@@ -363,9 +363,7 @@ static void test_filter_path_missing1(void **state)
|
||||
@@ -472,9 +472,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;
|
@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
5 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index b4d87689..b36778b0 100644
|
||||
index 658bec8b..1c02e230 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -53,7 +53,7 @@ index b4d87689..b36778b0 100644
|
||||
|
||||
conf->processed_main_config = 1;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index ceecff2d..3368d8c9 100644
|
||||
index 92c61a0d..160867cd 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -9,6 +9,7 @@
|
@ -9,26 +9,28 @@ still being generic.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 29 +++++++++++++++++++++--------
|
||||
1 file changed, 21 insertions(+), 8 deletions(-)
|
||||
Makefile.inc | 24 ++++++++++++++++++------
|
||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 034752d9..c2abd301 100644
|
||||
index 873fb62f..479523bc 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -89,16 +89,29 @@ TEST_CC_OPTION = $(shell \
|
||||
@@ -89,15 +89,27 @@ TEST_CC_OPTION = $(shell \
|
||||
echo "$(2)"; \
|
||||
fi)
|
||||
|
||||
-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
|
||||
|
||||
-OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
-WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
+ifndef RPM_OPT_FLAGS
|
||||
+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \
|
||||
+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
|
||||
+ $(STACKPROT) -grecord-gcc-switches \
|
||||
+ -fasynchronous-unwind-tables
|
||||
+ 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
|
||||
@ -36,24 +38,18 @@ index 034752d9..c2abd301 100644
|
||||
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1
|
||||
+ endif
|
||||
+else
|
||||
+ OPTFLAGS = $(RPM_OPT_FLAGS)
|
||||
+ OPTFLAGS := $(RPM_OPT_FLAGS) --param=ssp-buffer-size=4
|
||||
+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
|
||||
+WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
- $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS)
|
||||
-CPPFLAGS := -Wp,-D_FORTIFY_SOURCE=2
|
||||
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 \
|
||||
+ $(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
+ -Wstrict-prototypes
|
||||
CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
|
||||
-DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
-MMD -MP
|
||||
@@ -135,4 +147,4 @@ check_file = $(shell \
|
||||
|
||||
%.o: %.c
|
||||
@echo building $@ because of $?
|
@ -14,14 +14,14 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 +
|
||||
multipath/Makefile | 5 +
|
||||
multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf | 565 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 135 ++++++++++
|
||||
4 files changed, 697 insertions(+)
|
||||
4 files changed, 707 insertions(+)
|
||||
create mode 100644 multipath/mpathconf
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index b36778b0..26f8e050 100644
|
||||
index 1c02e230..a253a936 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -781,6 +781,8 @@ load_config (char * file)
|
||||
@ -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..f34003c9
|
||||
index 00000000..f0d09cbb
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -0,0 +1,555 @@
|
||||
@@ -0,0 +1,565 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
||||
@ -107,11 +107,6 @@ index 00000000..f34003c9
|
||||
+defaults {
|
||||
+ user_friendly_names yes
|
||||
+ find_multipaths yes
|
||||
+ enable_foreign \"^$\"
|
||||
+}
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
+ property \"(SCSI_IDENT_|ID_WWN)\"
|
||||
+}"
|
||||
+
|
||||
+CONFIGFILE="/etc/multipath.conf"
|
||||
@ -130,7 +125,7 @@ index 00000000..f34003c9
|
||||
+ 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 <y|n>"
|
||||
+ echo "Set default property blacklist (Default y): --property_blacklist <y|n>"
|
||||
+ 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 "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
@ -288,12 +283,13 @@ index 00000000..f34003c9
|
||||
+
|
||||
+function validate_args
|
||||
+{
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" -o -n "$FOREIGN" ]; then
|
||||
+ echo "ignoring extra parameters on disable"
|
||||
+ FRIENDLY=""
|
||||
+ FIND=""
|
||||
+ PROPERTY=""
|
||||
+ MODULE=""
|
||||
+ FOREIGN=""
|
||||
+ fi
|
||||
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
|
||||
+ echo "--user_friendly_names must be either 'y' or 'n'"
|
||||
@ -311,7 +307,7 @@ index 00000000..f34003c9
|
||||
+ echo "--enable_foreign must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" -a -z "$FOREIGN" ]; then
|
||||
+ SHOW_STATUS=1
|
||||
+ fi
|
||||
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
@ -416,8 +412,12 @@ index 00000000..f34003c9
|
||||
+ HAVE_FOREIGN=0
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
|
||||
+ HAVE_FOREIGN=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"NONE\"" ; then
|
||||
+ HAVE_FOREIGN=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]] \"\.\?\*\"" ; then
|
||||
+ HAVE_FOREIGN=2
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=3
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
@ -451,9 +451,11 @@ index 00000000..f34003c9
|
||||
+ echo "default property blacklist is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then
|
||||
+ echo "enable_foreign is not set (all foreign multipath devices will be shown)"
|
||||
+ echo "enable_foreign is not set (no foreign multipath devices will be shown)"
|
||||
+ elif [ "$HAVE_FOREIGN" = 1 ]; then
|
||||
+ echo "enable_foreign is set (no foreign multipath devices will be shown)"
|
||||
+ elif [ "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ echo "enable_foreign is set (all foreign multipath devices will be shown)"
|
||||
+ else
|
||||
+ echo "enable_foreign is set (foreign multipath devices may not be shown)"
|
||||
+ fi
|
||||
@ -570,7 +572,15 @@ index 00000000..f34003c9
|
||||
+ 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
|
||||
@ -582,18 +592,18 @@ index 00000000..f34003c9
|
||||
+fi
|
||||
+
|
||||
+if [ "$FOREIGN" = "y" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
+ if [ -z "$HAVE_FOREIGN" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ enable_foreign ".*"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign ".*"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ -z "$HAVE_FOREIGN" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ enable_foreign "^$"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE
|
||||
+ if [ "$HAVE_FOREIGN" = 2 -o "$HAVE_FOREIGN" = 3 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
@ -22,13 +22,13 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
5 files changed, 60 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 28a2150d..fab6fc8f 100644
|
||||
index 61d9c39e..c7a16636 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)
|
||||
@@ -451,3 +451,47 @@ int unmark_failed_wwid(const char *wwid)
|
||||
print_failed_wwid_result("unmark_failed", wwid, r);
|
||||
return r;
|
||||
}
|
||||
+
|
||||
+int remember_cmdline_wwid(void)
|
||||
+{
|
||||
@ -86,10 +86,10 @@ index 0c6ee54d..e32a0b0e 100644
|
||||
enum {
|
||||
WWID_IS_NOT_FAILED = 0,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index cf9d2a28..78822ee1 100644
|
||||
index 4c43314e..c73f6963 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -138,7 +138,7 @@ usage (char * progname)
|
||||
@@ -135,7 +135,7 @@ usage (char * progname)
|
||||
fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname);
|
||||
@ -98,7 +98,7 @@ index cf9d2a28..78822ee1 100644
|
||||
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)
|
||||
@@ -149,6 +149,8 @@ usage (char * progname)
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
@ -107,16 +107,16 @@ index cf9d2a28..78822ee1 100644
|
||||
" -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[])
|
||||
@@ -893,7 +895,7 @@ main (int argc, char *argv[])
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
- while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
+ while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -977,6 +979,10 @@ main (int argc, char *argv[])
|
||||
@@ -970,6 +972,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
@ -128,7 +128,7 @@ index cf9d2a28..78822ee1 100644
|
||||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 9cdd05a3..8befc45a 100644
|
||||
index 5b29a5d9..0478f4e7 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
@ -81,10 +81,10 @@ index 0e9ea387..184d4b22 100644
|
||||
|
||||
declare_hw_handler(hwhandler, set_str)
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index d478b177..a184511b 100644
|
||||
index 11a6168c..a7285a35 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -382,6 +382,19 @@ oom:
|
||||
@@ -384,6 +384,19 @@ oom:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ 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 e5ee6afe..52fe05b9 100644
|
||||
index 01a501bd..984d8dd8 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -22,7 +22,7 @@
|
@ -14,18 +14,18 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index c2abd301..bb642931 100644
|
||||
index 479523bc..e2f5d0dc 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -108,7 +108,7 @@ else
|
||||
endif
|
||||
OPTFLAGS += -Werror -Wextra -Wstrict-prototypes -Wformat=2 \
|
||||
-Werror=implicit-int -Werror=implicit-function-declaration \
|
||||
- $(WNOCLOBBERED) \
|
||||
+ $(WNOCLOBBERED) -Wno-error=format-truncation \
|
||||
-Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
--param=ssp-buffer-size=4
|
||||
|
||||
@@ -109,7 +109,7 @@ endif
|
||||
WARNFLAGS := -Werror -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
-Werror=implicit-function-declaration -Werror=format-security \
|
||||
$(WNOCLOBBERED) -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||
- -Wstrict-prototypes
|
||||
+ -Wstrict-prototypes -Wno-error=format-truncation
|
||||
CFLAGS := $(CFLAGS) $(OPTFLAGS) $(WARNFLAGS) -pipe \
|
||||
-DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||
-MMD -MP
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
Name: device-mapper-multipath
|
||||
Version: 0.8.4
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: Tools to manage multipath devices using device-mapper
|
||||
License: GPLv2
|
||||
URL: http://christophe.varoqui.free.fr/
|
||||
@ -10,29 +10,66 @@ URL: http://christophe.varoqui.free.fr/
|
||||
# curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.4;sf=tgz" -o multipath-tools-0.8.4.tgz
|
||||
Source0: multipath-tools-0.8.4.tgz
|
||||
Source1: multipath.conf
|
||||
Patch0001:0001-libmultipath-assign-variable-to-make-gcc-happy.patch
|
||||
Patch0002: 0002-libmutipath-don-t-close-fd-on-dm_lib_release.patch
|
||||
Patch0003: 0003-libmultipath-allow-force-reload-with-no-active-paths.patch
|
||||
Patch0004: 0004-libmpathpersist-depend-on-libmultipath.patch
|
||||
Patch0005: 0005-multipath-tools-Makefile-more-dependency-fixes-for-p.patch
|
||||
Patch0006: 0006-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch
|
||||
Patch0007: 0007-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch
|
||||
Patch0008: 0008-libmultipath-eliminate-more-signed-unsigned-comparis.patch
|
||||
Patch0009: 0009-libmultipath-set_uint-fix-parsing-for-32bit.patch
|
||||
Patch0010: 0010-multipath-tools-Makefile-add-install-dependency.patch
|
||||
Patch0011: 0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch
|
||||
Patch0012: 0012-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch
|
||||
Patch0013: 0013-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch0014: 0014-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch0015: 0015-RH-don-t-start-without-a-config-file.patch
|
||||
Patch0016: 0016-RH-use-rpm-optflags-if-present.patch
|
||||
Patch0017: 0017-RH-add-mpathconf.patch
|
||||
Patch0018: 0018-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch0019: 0019-RH-warn-on-invalid-regex-instead-of-failing.patch
|
||||
Patch0020: 0020-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch0021: 0021-RH-Fix-nvme-compilation-warning.patch
|
||||
Patch0022: 0022-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
Patch0023: 0023-RH-work-around-gcc-10-format-truncation-issue.patch
|
||||
Patch0001: 0001-libmpathpersist-limit-PRIN-allocation-length-to-8192.patch
|
||||
Patch0002: 0002-libmpathpersist-format_transportids-avoid-PROUT-over.patch
|
||||
Patch0003: 0003-libmpathpersist-mpath_format_readfullstatus-use-real.patch
|
||||
Patch0004: 0004-libmultipath-assign-variable-to-make-gcc-happy.patch
|
||||
Patch0005: 0005-libmutipath-don-t-close-fd-on-dm_lib_release.patch
|
||||
Patch0006: 0006-libmultipath-allow-force-reload-with-no-active-paths.patch
|
||||
Patch0007: 0007-kpartx.rules-honor-DM_UDEV_DISABLE_OTHER_RULES_FLAG.patch
|
||||
Patch0008: 0008-kpartx.rules-check-for-skip_kpartx-on-synthetic-ueve.patch
|
||||
Patch0009: 0009-libmpathpersist-depend-on-libmultipath.patch
|
||||
Patch0010: 0010-multipath-tools-Makefile-more-dependency-fixes-for-p.patch
|
||||
Patch0011: 0011-multipath-tools-Makefile.inc-separate-out-OPTFLAGS.patch
|
||||
Patch0012: 0012-multipath-tools-Makefile.inc-allow-user-settings-for.patch
|
||||
Patch0013: 0013-multipath-tools-Makefile.inc-set-Wno-error-clobbered.patch
|
||||
Patch0014: 0014-libmultipath-discovery.c-use-z-qualifier-for-size_t.patch
|
||||
Patch0015: 0015-libmultipath-eliminate-more-signed-unsigned-comparis.patch
|
||||
Patch0016: 0016-libmultipath-set_uint-fix-parsing-for-32bit.patch
|
||||
Patch0017: 0017-multipath-tools-tests-Makefile-add-lmpathcmd-to-LIBD.patch
|
||||
Patch0018: 0018-multipath-tools-tests-Makefile-Fix-OBJDEPS-for-hwtab.patch
|
||||
Patch0019: 0019-multipath-tools-tests-test-lib.c-drop-__wrap_is_clai.patch
|
||||
Patch0020: 0020-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch
|
||||
Patch0021: 0021-libmultipath-move-libsg-into-libmultipath.patch
|
||||
Patch0022: 0022-multipath-tools-Makefile-add-install-dependency.patch
|
||||
Patch0023: 0023-libmultipath-make-libmp_dm_init-optional.patch
|
||||
Patch0024: 0024-libmultipath-make-sysfs_is_multipathed-able-to-retur.patch
|
||||
Patch0025: 0025-multipath-centralize-validation-code.patch
|
||||
Patch0026: 0026-Unit-tests-for-is_path_valid.patch
|
||||
Patch0027: 0027-libmultipath-simplify-failed-wwid-code.patch
|
||||
Patch0028: 0028-libmultipath-use-atomic-linkat-in-mark_failed_wwid.patch
|
||||
Patch0029: 0029-fix-boolean-value-with-json-c-0.14.patch
|
||||
Patch0030: 0030-libmultipath-fix-condlog-NULL-argument-in-uevent_get.patch
|
||||
Patch0031: 0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch
|
||||
Patch0032: 0032-multipath-add-e-option-to-enable-foreign-libraries.patch
|
||||
Patch0033: 0033-libmultipath-remove-_blacklist_exceptions-functions.patch
|
||||
Patch0034: 0034-libmultipath-fix-parser-issue-with-comments-in-strin.patch
|
||||
Patch0035: 0035-libmultipath-invert-regexes-that-start-with-exclamat.patch
|
||||
Patch0036: 0036-multipath-Fix-compiler-warnings-when-built-without-s.patch
|
||||
Patch0037: 0037-libmultipath-fix-sysfs-dev_loss_tmo-parsing.patch
|
||||
Patch0038: 0038-kpartx-read-devices-with-direct-IO.patch
|
||||
Patch0039: 0039-kpartx-handle-alternate-bsd-disklabel-location.patch
|
||||
Patch0040: 0040-libmultipath-fix-checker-detection-for-nvme-devices.patch
|
||||
Patch0041: 0041-libmultipath-make-dm_get_map-status-return-codes-sym.patch
|
||||
Patch0042: 0042-multipathd-fix-check_path-errors-with-removed-map.patch
|
||||
Patch0043: 0043-libmultipath-make-dm_flush_maps-only-return-0-on-suc.patch
|
||||
Patch0044: 0044-multipathd-add-del-maps-multipathd-command.patch
|
||||
Patch0045: 0045-multipath-make-flushing-maps-work-like-other-command.patch
|
||||
Patch0046: 0046-multipath-delegate-flushing-maps-to-multipathd.patch
|
||||
Patch0047: 0047-multipath-add-option-to-skip-multipathd-delegation.patch
|
||||
Patch0048: 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch
|
||||
Patch0049: 0049-kpartx-fix-Wsign-compare-error.patch
|
||||
Patch0050: 0050-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch0051: 0051-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch0052: 0052-RH-don-t-start-without-a-config-file.patch
|
||||
Patch0053: 0053-RH-use-rpm-optflags-if-present.patch
|
||||
Patch0054: 0054-RH-add-mpathconf.patch
|
||||
Patch0055: 0055-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch0056: 0056-RH-warn-on-invalid-regex-instead-of-failing.patch
|
||||
Patch0057: 0057-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch0058: 0058-RH-Fix-nvme-compilation-warning.patch
|
||||
Patch0059: 0059-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
Patch0060: 0060-RH-work-around-gcc-10-format-truncation-issue.patch
|
||||
|
||||
# runtime
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
@ -227,8 +264,24 @@ fi
|
||||
%{_pkgconfdir}/libdmmp.pc
|
||||
|
||||
%changelog
|
||||
* Wed Jul 8 2020 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.4-2
|
||||
- Rebased on top of Martin Wilck's queue of ACKed upstream commits
|
||||
* https://github.com/openSUSE/multipath-tools/tree/upstream-queue
|
||||
* All previous patches have been reordered, with the exception of
|
||||
0011-libdmmp-Add-support-for-upcoming-json-c-0.14.0.patch
|
||||
which has been replaced with
|
||||
0029-fix-boolean-value-with-json-c-0.14.patch
|
||||
- Modify 0054-RH-add-mpathconf.patch
|
||||
* remove default enable_foreign and property blacklist_exceptions
|
||||
settings, and deal with the builtin default change from
|
||||
0031-libmultipath-set-enable_foreign-to-NONE-by-default.patch.
|
||||
Fixes bz #1853668
|
||||
- Add 0048-Makefile.inc-trim-extra-information-from-systemd-ver.patch
|
||||
- Add 0049-kpartx-fix-Wsign-compare-error.patch
|
||||
* The above two patches have been submitted upstream
|
||||
|
||||
* Fri May 29 2020 Benjamin Marzinski <bmarzins@redhat.com> - 0.8.4-1
|
||||
- Update Source to upstream version 0.8.2
|
||||
- Update Source to upstream version 0.8.4
|
||||
* Previoud patches 0001-0020 & 0031 are included in this commit
|
||||
- Rename files
|
||||
* Previous patches 0021-0032 are now patches 0012-0022
|
||||
@ -509,7 +562,7 @@ fi
|
||||
- Rename files
|
||||
* Previous patches 0007-0014 are now patches 0008-0015
|
||||
|
||||
* Tue Apr 02 2018 Björn Esser <besser82@fedoraproject.org> - 0.7.6-1.git1cb704b
|
||||
* Mon Apr 02 2018 Benjamin Marzinski <bmarzins@redhat.com> 0.7.6-1.git1cb704b
|
||||
- Update Source to the latest upstream commit
|
||||
* Previous patches 0001-0014 are included in this commit
|
||||
* Previous patches 0015-0022 are now patches 0007-0014
|
||||
|
Loading…
Reference in New Issue
Block a user