device-mapper-multipath-0.8.5-1
Update Source to upstream version 0.8.5 plus post tag commits * Patches 0001-0102 are from https://github.com/openSUSE/multipath-tools/tree/queue and are already queued for upstream. Rename files * Previous patches 0059-0068 are now patches 0103-0111
This commit is contained in:
parent
d5b202726f
commit
1dad67a5af
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,3 +20,4 @@ multipath-tools-091027.tar.gz
|
||||
/multipath-tools-0.8.0.tgz
|
||||
/multipath-tools-0.8.2.tgz
|
||||
/multipath-tools-0.8.4.tgz
|
||||
/multipath-tools-0.8.5.tgz
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Date: Mon, 14 Dec 2020 11:05:24 +0100
|
||||
Subject: [PATCH] Change the multipath.conf manpage uxsock_timeout default
|
||||
value
|
||||
|
||||
Fixes: 7db0c44 ("multipathd: Set CLI timeout correctly")
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.conf.5 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index d2101ed6..7242d39b 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1153,7 +1153,7 @@ In these cases it is recommended to increase the CLI timeout to avoid
|
||||
those issues.
|
||||
.RS
|
||||
.TP
|
||||
-The default is: \fB1000\fR
|
||||
+The default is: \fB4000\fR
|
||||
.RE
|
||||
.
|
||||
.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,35 +0,0 @@
|
||||
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
|
||||
|
@ -1,93 +0,0 @@
|
||||
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
|
||||
|
27
0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch
Normal file
27
0002-libmultipath-find_mpe-don-t-match-with-empty-WWID.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 16 Sep 2020 21:59:11 +0200
|
||||
Subject: [PATCH] libmultipath: find_mpe(): don't match with empty WWID
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index b9bdbdbc..df0f8f45 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -147,7 +147,7 @@ struct mpentry *find_mpe(vector mptable, char *wwid)
|
||||
int i;
|
||||
struct mpentry * mpe;
|
||||
|
||||
- if (!wwid)
|
||||
+ if (!wwid || !*wwid)
|
||||
return NULL;
|
||||
|
||||
vector_foreach_slot (mptable, mpe, i)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,54 +0,0 @@
|
||||
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
|
||||
|
260
0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch
Normal file
260
0003-libmultipath-copy-mpp-hwe-from-pp-hwe.patch
Normal file
@ -0,0 +1,260 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 16 Sep 2020 22:22:36 +0200
|
||||
Subject: [PATCH] libmultipath: copy mpp->hwe from pp->hwe
|
||||
|
||||
Since f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe"),
|
||||
we've been trying to fix issues caused by paths getting freed and mpp->hwe
|
||||
dangling. This approach couldn't work because we need mpp->hwe to persist,
|
||||
even if all paths are removed from the map. Before f0462f0, a simple
|
||||
assignment worked, because the lifetime of the hwe wasn't bound to the
|
||||
path. But now, we need to copy the vector. It turns out that we need to set
|
||||
mpp->hwe only in two places, add_map_with_path() and setup_map(), and
|
||||
that the code is simplified overall.
|
||||
|
||||
Even now, it can happen that a map is added with add_map_without_paths(),
|
||||
and has no paths. In that case, calling do_set_from_hwe() with a NULL
|
||||
pointer is not a bug, so remove the message.
|
||||
|
||||
Fixes: f0462f0 ("libmultipath: use vector for for pp->hwe and mp->hwe")
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 7 +++++
|
||||
libmultipath/propsel.c | 4 +--
|
||||
libmultipath/structs.c | 15 +++++++++++
|
||||
libmultipath/structs.h | 1 +
|
||||
libmultipath/structs_vec.c | 54 ++++++++++++++++----------------------
|
||||
multipathd/main.c | 10 -------
|
||||
6 files changed, 46 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 6fb477fc..d7afc915 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -311,6 +311,13 @@ int setup_map(struct multipath *mpp, char *params, int params_size,
|
||||
if (mpp->disable_queueing && VECTOR_SIZE(mpp->paths) != 0)
|
||||
mpp->disable_queueing = 0;
|
||||
|
||||
+ /*
|
||||
+ * If this map was created with add_map_without_path(),
|
||||
+ * mpp->hwe might not be set yet.
|
||||
+ */
|
||||
+ if (!mpp->hwe)
|
||||
+ extract_hwe_from_path(mpp);
|
||||
+
|
||||
/*
|
||||
* properties selectors
|
||||
*
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 7e6e0d68..40201344 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -65,9 +65,7 @@ do { \
|
||||
__do_set_from_vec(struct hwentry, var, (src)->hwe, dest)
|
||||
|
||||
#define do_set_from_hwe(var, src, dest, msg) \
|
||||
- if (!src->hwe) { \
|
||||
- condlog(0, "BUG: do_set_from_hwe called with hwe == NULL"); \
|
||||
- } else if (__do_set_from_hwe(var, src, dest)) { \
|
||||
+ if (src->hwe && __do_set_from_hwe(var, src, dest)) { \
|
||||
origin = msg; \
|
||||
goto out; \
|
||||
}
|
||||
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
|
||||
index 464596fc..2efad6f0 100644
|
||||
--- a/libmultipath/structs.c
|
||||
+++ b/libmultipath/structs.c
|
||||
@@ -234,6 +234,17 @@ alloc_multipath (void)
|
||||
return mpp;
|
||||
}
|
||||
|
||||
+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp)
|
||||
+{
|
||||
+ if (!mpp || !pp || !pp->hwe)
|
||||
+ return NULL;
|
||||
+ if (mpp->hwe)
|
||||
+ return mpp->hwe;
|
||||
+ mpp->hwe = vector_convert(NULL, pp->hwe,
|
||||
+ struct hwentry, identity);
|
||||
+ return mpp->hwe;
|
||||
+}
|
||||
+
|
||||
void free_multipath_attributes(struct multipath *mpp)
|
||||
{
|
||||
if (!mpp)
|
||||
@@ -290,6 +301,10 @@ free_multipath (struct multipath * mpp, enum free_path_mode free_paths)
|
||||
|
||||
free_pathvec(mpp->paths, free_paths);
|
||||
free_pgvec(mpp->pg, free_paths);
|
||||
+ if (mpp->hwe) {
|
||||
+ vector_free(mpp->hwe);
|
||||
+ mpp->hwe = NULL;
|
||||
+ }
|
||||
FREE_PTR(mpp->mpcontext);
|
||||
FREE(mpp);
|
||||
}
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 7de93d6c..4ce30551 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -422,6 +422,7 @@ struct host_group {
|
||||
struct path * alloc_path (void);
|
||||
struct pathgroup * alloc_pathgroup (void);
|
||||
struct multipath * alloc_multipath (void);
|
||||
+void *set_mpp_hwe(struct multipath *mpp, const struct path *pp);
|
||||
void uninitialize_path(struct path *pp);
|
||||
void free_path (struct path *);
|
||||
void free_pathvec (vector vec, enum free_path_mode free_paths);
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 8895fa77..f7f45f11 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -294,11 +294,6 @@ err:
|
||||
void orphan_path(struct path *pp, const char *reason)
|
||||
{
|
||||
condlog(3, "%s: orphan path, %s", pp->dev, reason);
|
||||
- if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) {
|
||||
- condlog(0, "BUG: orphaning path %s that holds hwe of %s",
|
||||
- pp->dev, pp->mpp->alias);
|
||||
- pp->mpp->hwe = NULL;
|
||||
- }
|
||||
pp->mpp = NULL;
|
||||
uninitialize_path(pp);
|
||||
}
|
||||
@@ -308,8 +303,6 @@ void orphan_paths(vector pathvec, struct multipath *mpp, const char *reason)
|
||||
int i;
|
||||
struct path * pp;
|
||||
|
||||
- /* Avoid BUG message from orphan_path() */
|
||||
- mpp->hwe = NULL;
|
||||
vector_foreach_slot (pathvec, pp, i) {
|
||||
if (pp->mpp == mpp) {
|
||||
if (pp->initialized == INIT_REMOVED) {
|
||||
@@ -397,24 +390,26 @@ extract_hwe_from_path(struct multipath * mpp)
|
||||
if (mpp->hwe || !mpp->paths)
|
||||
return;
|
||||
|
||||
- condlog(3, "%s: searching paths for valid hwe", mpp->alias);
|
||||
+ condlog(4, "%s: searching paths for valid hwe", mpp->alias);
|
||||
/* doing this in two passes seems like paranoia to me */
|
||||
vector_foreach_slot(mpp->paths, pp, i) {
|
||||
- if (pp->state != PATH_UP)
|
||||
- continue;
|
||||
- if (pp->hwe) {
|
||||
- mpp->hwe = pp->hwe;
|
||||
- return;
|
||||
- }
|
||||
+ if (pp->state == PATH_UP &&
|
||||
+ pp->initialized != INIT_REMOVED && pp->hwe)
|
||||
+ goto done;
|
||||
}
|
||||
vector_foreach_slot(mpp->paths, pp, i) {
|
||||
- if (pp->state == PATH_UP)
|
||||
- continue;
|
||||
- if (pp->hwe) {
|
||||
- mpp->hwe = pp->hwe;
|
||||
- return;
|
||||
- }
|
||||
+ if (pp->state != PATH_UP &&
|
||||
+ pp->initialized != INIT_REMOVED && pp->hwe)
|
||||
+ goto done;
|
||||
}
|
||||
+done:
|
||||
+ if (i < VECTOR_SIZE(mpp->paths))
|
||||
+ (void)set_mpp_hwe(mpp, pp);
|
||||
+
|
||||
+ if (mpp->hwe)
|
||||
+ condlog(3, "%s: got hwe from path %s", mpp->alias, pp->dev);
|
||||
+ else
|
||||
+ condlog(2, "%s: no hwe found", mpp->alias);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -514,8 +509,6 @@ void sync_paths(struct multipath *mpp, vector pathvec)
|
||||
}
|
||||
if (!found) {
|
||||
condlog(3, "%s dropped path %s", mpp->alias, pp->dev);
|
||||
- if (mpp->hwe == pp->hwe)
|
||||
- mpp->hwe = NULL;
|
||||
vector_del_slot(mpp->paths, i--);
|
||||
orphan_path(pp, "path removed externally");
|
||||
}
|
||||
@@ -524,8 +517,6 @@ void sync_paths(struct multipath *mpp, vector pathvec)
|
||||
update_mpp_paths(mpp, pathvec);
|
||||
vector_foreach_slot (mpp->paths, pp, i)
|
||||
pp->mpp = mpp;
|
||||
- if (mpp->hwe == NULL)
|
||||
- extract_hwe_from_path(mpp);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -701,9 +692,15 @@ struct multipath *add_map_with_path(struct vectors *vecs, struct path *pp,
|
||||
|
||||
conf = get_multipath_config();
|
||||
mpp->mpe = find_mpe(conf->mptable, pp->wwid);
|
||||
- mpp->hwe = pp->hwe;
|
||||
put_multipath_config(conf);
|
||||
|
||||
+ /*
|
||||
+ * We need to call this before select_alias(),
|
||||
+ * because that accesses hwe properties.
|
||||
+ */
|
||||
+ if (pp->hwe && !set_mpp_hwe(mpp, pp))
|
||||
+ goto out;
|
||||
+
|
||||
strcpy(mpp->wwid, pp->wwid);
|
||||
find_existing_alias(mpp, vecs);
|
||||
if (select_alias(conf, mpp))
|
||||
@@ -754,12 +751,6 @@ int verify_paths(struct multipath *mpp)
|
||||
vector_del_slot(mpp->paths, i);
|
||||
i--;
|
||||
|
||||
- /* Make sure mpp->hwe doesn't point to freed memory.
|
||||
- * We call extract_hwe_from_path() below to restore
|
||||
- * mpp->hwe
|
||||
- */
|
||||
- if (mpp->hwe == pp->hwe)
|
||||
- mpp->hwe = NULL;
|
||||
/*
|
||||
* Don't delete path from pathvec yet. We'll do this
|
||||
* after the path has been removed from the map, in
|
||||
@@ -771,7 +762,6 @@ int verify_paths(struct multipath *mpp)
|
||||
mpp->alias, pp->dev, pp->dev_t);
|
||||
}
|
||||
}
|
||||
- extract_hwe_from_path(mpp);
|
||||
return count;
|
||||
}
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index a4abbb27..eedc6c10 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1153,13 +1153,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
if (i != -1)
|
||||
vector_del_slot(mpp->paths, i);
|
||||
|
||||
- /*
|
||||
- * Make sure mpp->hwe doesn't point to freed memory
|
||||
- * We call extract_hwe_from_path() below to restore mpp->hwe
|
||||
- */
|
||||
- if (mpp->hwe == pp->hwe)
|
||||
- mpp->hwe = NULL;
|
||||
-
|
||||
/*
|
||||
* remove the map IF removing the last path
|
||||
*/
|
||||
@@ -1191,9 +1184,6 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map)
|
||||
*/
|
||||
}
|
||||
|
||||
- if (mpp->hwe == NULL)
|
||||
- extract_hwe_from_path(mpp);
|
||||
-
|
||||
if (setup_map(mpp, params, PARAMS_SIZE, vecs)) {
|
||||
condlog(0, "%s: failed to setup map for"
|
||||
" removal of path %s", mpp->alias, pp->dev);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 25 Mar 2020 23:22:46 -0500
|
||||
Subject: [PATCH] libmultipath: assign variable to make gcc happy
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There is nothing wrong with is_queueing not being set at the start
|
||||
of __set_no_path_retry(), it will always get set before it is accessed,
|
||||
but gcc 8.2.1 is failing with
|
||||
|
||||
structs_vec.c: In function ‘__set_no_path_retry’:
|
||||
structs_vec.c:339:7: error: ‘is_queueing’ may be used uninitialized in
|
||||
this function [-Werror=maybe-uninitialized]
|
||||
bool is_queueing;
|
||||
^~~~~~~~~~~
|
||||
|
||||
so, assign a value to make it happy.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 3dbbaa0f..077f2e42 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -336,7 +336,7 @@ static void leave_recovery_mode(struct multipath *mpp)
|
||||
|
||||
void __set_no_path_retry(struct multipath *mpp, bool check_features)
|
||||
{
|
||||
- bool is_queueing;
|
||||
+ bool is_queueing = false; /* assign a value to make gcc happy */
|
||||
|
||||
check_features = check_features && mpp->features != NULL;
|
||||
if (check_features)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Sep 2020 14:24:41 +0200
|
||||
Subject: [PATCH] libmultipath: dm_map_present_by_uuid(): fix dm_task_create()
|
||||
call
|
||||
|
||||
libmultipath shouldn't call dm_task_create() directly any more.
|
||||
|
||||
Fixes: 90535a3 ("multipath: centralize validation code")
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 7f093617..0bc1d16e 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -836,7 +836,7 @@ dm_map_present_by_uuid(const char *uuid)
|
||||
if (safe_sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid))
|
||||
goto out;
|
||||
|
||||
- if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
|
||||
+ if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO)))
|
||||
goto out;
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
--
|
||||
2.17.2
|
||||
|
43
0005-libdmmp-tests-fix-compilation.patch
Normal file
43
0005-libdmmp-tests-fix-compilation.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Sep 2020 12:10:35 +0200
|
||||
Subject: [PATCH] libdmmp tests: fix compilation
|
||||
|
||||
These tests don't compile with -Werror=unused-parameter. Fix it.
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libdmmp/test/libdmmp_speed_test.c | 2 +-
|
||||
libdmmp/test/libdmmp_test.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libdmmp/test/libdmmp_speed_test.c b/libdmmp/test/libdmmp_speed_test.c
|
||||
index 372cd390..d91ba50a 100644
|
||||
--- a/libdmmp/test/libdmmp_speed_test.c
|
||||
+++ b/libdmmp/test/libdmmp_speed_test.c
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <libdmmp/libdmmp.h>
|
||||
|
||||
-int main(int argc, char *argv[])
|
||||
+int main(void)
|
||||
{
|
||||
struct dmmp_context *ctx = NULL;
|
||||
struct dmmp_mpath **dmmp_mps = NULL;
|
||||
diff --git a/libdmmp/test/libdmmp_test.c b/libdmmp/test/libdmmp_test.c
|
||||
index d944e1e3..a940b576 100644
|
||||
--- a/libdmmp/test/libdmmp_test.c
|
||||
+++ b/libdmmp/test/libdmmp_test.c
|
||||
@@ -102,7 +102,7 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
-int main(int argc, char *argv[])
|
||||
+int main(void)
|
||||
{
|
||||
struct dmmp_context *ctx = NULL;
|
||||
struct dmmp_mpath **dmmp_mps = NULL;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,66 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 25 Mar 2020 23:22:47 -0500
|
||||
Subject: [PATCH] libmutipath: don't close fd on dm_lib_release
|
||||
|
||||
If dm_hold_control_open() isn't set, when dm_lib_release() is called, it
|
||||
will close the control fd. The control fd will get re-opened on the next
|
||||
dm_task_run() call, but if there is a dm_task_run() call already
|
||||
in progress in another thread, it can fail. Since many of the
|
||||
device-mapper callouts happen with the vecs lock held, this wasn't too
|
||||
noticeable, but there is code that calls dm_task_run() without the
|
||||
vecs lock held, notably the dmevent waiter code.
|
||||
|
||||
Since, as Martin pointed out, dm_hold_control_open() hasn't always
|
||||
existed in libdevmapper, check if it's supported on compilation,
|
||||
and update the version requirements if so.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 4 ++++
|
||||
libmultipath/devmapper.c | 7 ++++++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index e5651e49..ad690a49 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -36,6 +36,10 @@ ifneq ($(call check_func,dm_task_deferred_remove,/usr/include/libdevmapper.h),0)
|
||||
CFLAGS += -DLIBDM_API_DEFERRED
|
||||
endif
|
||||
|
||||
+ifneq ($(call check_func,dm_hold_control_dev,/usr/include/libdevmapper.h),0)
|
||||
+ CFLAGS += -DLIBDM_API_HOLD_CONTROL
|
||||
+endif
|
||||
+
|
||||
OBJS = memory.o parser.o vector.o devmapper.o callout.o \
|
||||
hwtable.o blacklist.o util.o dmparser.o config.o \
|
||||
structs.o discovery.o propsel.o dict.o \
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index bed8ddc6..13a1cf53 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -108,7 +108,9 @@ dm_lib_prereq (void)
|
||||
{
|
||||
char version[64];
|
||||
int v[3];
|
||||
-#if defined(LIBDM_API_DEFERRED)
|
||||
+#if defined(LIBDM_API_HOLD_CONTROL)
|
||||
+ int minv[3] = {1, 2, 111};
|
||||
+#elif defined(LIBDM_API_DEFERRED)
|
||||
int minv[3] = {1, 2, 89};
|
||||
#elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
|
||||
int minv[3] = {1, 2, 82};
|
||||
@@ -254,6 +256,9 @@ void libmp_dm_init(void)
|
||||
memcpy(conf->version, version, sizeof(version));
|
||||
put_multipath_config(conf);
|
||||
dm_init(verbosity);
|
||||
+#ifdef LIBDM_API_HOLD_CONTROL
|
||||
+ dm_hold_control_dev(1);
|
||||
+#endif
|
||||
dm_udev_set_sync_support(libmp_dm_udev_sync);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,64 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 25 Mar 2020 23:22:48 -0500
|
||||
Subject: [PATCH] libmultipath: allow force reload with no active paths
|
||||
|
||||
If the partition information has changed on multipath devices (say,
|
||||
because it was updated on another node that has access to the same
|
||||
storage), users expect that running "multipathd reconfigure" will update
|
||||
that. However, if the checkers for the multipath device are pending for
|
||||
too long when the the device is reconfigured, multipathd will give up
|
||||
waiting for them, and refuse to reload the device, since there are no
|
||||
active paths. This means that no kpartx update will be triggered.
|
||||
|
||||
Multipath is fully capable of reloading a multipath device that has no
|
||||
active paths. This has been possible for years. If multipath is supposed
|
||||
to reload the device, it should do so, even if there are no active paths.
|
||||
|
||||
Generally, when multipath is force reloaded, kpartx will be updated.
|
||||
However when a device is reloaded with no paths, the udev rules won't
|
||||
run kpartx. But they also weren't running kpartx when the first valid
|
||||
path appeared, even though the dm activation rules get run in this case.
|
||||
This changes 11-dm-mpath.rules to run kpartx when a device goes from no
|
||||
usable paths to having usable paths.
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 6 ------
|
||||
multipath/11-dm-mpath.rules | 2 +-
|
||||
2 files changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index c95848a0..96c79610 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -710,12 +710,6 @@ select_action (struct multipath * mpp, vector curmp, int force_reload)
|
||||
return;
|
||||
}
|
||||
|
||||
- if (pathcount(mpp, PATH_UP) == 0) {
|
||||
- mpp->action = ACT_IMPOSSIBLE;
|
||||
- condlog(3, "%s: set ACT_IMPOSSIBLE (no usable path)",
|
||||
- mpp->alias);
|
||||
- return;
|
||||
- }
|
||||
if (force_reload) {
|
||||
mpp->force_udev_reload = 1;
|
||||
mpp->action = ACT_RELOAD;
|
||||
diff --git a/multipath/11-dm-mpath.rules b/multipath/11-dm-mpath.rules
|
||||
index 07320a14..cd522e8c 100644
|
||||
--- a/multipath/11-dm-mpath.rules
|
||||
+++ b/multipath/11-dm-mpath.rules
|
||||
@@ -75,7 +75,7 @@ ENV{MPATH_DEVICE_READY}=="0", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
|
||||
ENV{MPATH_DEVICE_READY}!="0", ENV{.MPATH_DEVICE_READY_OLD}=="0",\
|
||||
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="$env{DM_DISABLE_OTHER_RULES_FLAG_OLD}",\
|
||||
ENV{DM_DISABLE_OTHER_RULES_FLAG_OLD}="",\
|
||||
- ENV{DM_ACTIVATION}="1"
|
||||
+ ENV{DM_ACTIVATION}="1", ENV{MPATH_UNCHANGED}="0"
|
||||
|
||||
# The code to check multipath state ends here. We need to set
|
||||
# properties and symlinks regardless whether the map is usable or
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 18 Sep 2020 23:57:22 +0200
|
||||
Subject: [PATCH] libmultipath: prio: constify some function parameters
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/prio.c | 4 ++--
|
||||
libmultipath/prio.h | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/prio.c b/libmultipath/prio.c
|
||||
index 194563c4..3a718ba5 100644
|
||||
--- a/libmultipath/prio.c
|
||||
+++ b/libmultipath/prio.c
|
||||
@@ -18,7 +18,7 @@ unsigned int get_prio_timeout(unsigned int timeout_ms,
|
||||
return default_timeout;
|
||||
}
|
||||
|
||||
-int init_prio (char *multipath_dir)
|
||||
+int init_prio (const char *multipath_dir)
|
||||
{
|
||||
if (!add_prio(multipath_dir, DEFAULT_PRIO))
|
||||
return 1;
|
||||
@@ -87,7 +87,7 @@ int prio_set_args (struct prio * p, const char * args)
|
||||
return snprintf(p->args, PRIO_ARGS_LEN, "%s", args);
|
||||
}
|
||||
|
||||
-struct prio * add_prio (char *multipath_dir, char * name)
|
||||
+struct prio * add_prio (const char *multipath_dir, const char * name)
|
||||
{
|
||||
char libname[LIB_PRIO_NAMELEN];
|
||||
struct stat stbuf;
|
||||
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
|
||||
index 599d1d88..26754f78 100644
|
||||
--- a/libmultipath/prio.h
|
||||
+++ b/libmultipath/prio.h
|
||||
@@ -55,9 +55,9 @@ struct prio {
|
||||
|
||||
unsigned int get_prio_timeout(unsigned int checker_timeout,
|
||||
unsigned int default_timeout);
|
||||
-int init_prio (char *);
|
||||
+int init_prio (const char *);
|
||||
void cleanup_prio (void);
|
||||
-struct prio * add_prio (char *, char *);
|
||||
+struct prio * add_prio (const char *, const char *);
|
||||
int prio_getprio (struct prio *, struct path *, unsigned int);
|
||||
void prio_get (char *, struct prio *, char *, char *);
|
||||
void prio_put (struct prio *);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
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,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 18 Sep 2020 23:58:15 +0200
|
||||
Subject: [PATCH] libmultipath: checkers/prio: allow non-lazy .so loading
|
||||
|
||||
If compiled with -DLOAD_ALL_SHARED_LIBS, all known prioritizers
|
||||
and checkers will be loaded immediately on startup. This is useful
|
||||
for determining symbol usage (start executables with LD_BIND_NOW=1).
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/checkers.c | 17 +++++++++++++++++
|
||||
libmultipath/prio.c | 22 ++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
|
||||
index f7ddd536..18b1f5eb 100644
|
||||
--- a/libmultipath/checkers.c
|
||||
+++ b/libmultipath/checkers.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "debug.h"
|
||||
#include "checkers.h"
|
||||
#include "vector.h"
|
||||
+#include "util.h"
|
||||
|
||||
struct checker_class {
|
||||
struct list_head node;
|
||||
@@ -375,7 +376,23 @@ void checker_get(const char *multipath_dir, struct checker *dst,
|
||||
|
||||
int init_checkers(const char *multipath_dir)
|
||||
{
|
||||
+#ifdef LOAD_ALL_SHARED_LIBS
|
||||
+ static const char *const all_checkers[] = {
|
||||
+ DIRECTIO,
|
||||
+ TUR,
|
||||
+ HP_SW,
|
||||
+ RDAC,
|
||||
+ EMC_CLARIION,
|
||||
+ READSECTOR0,
|
||||
+ CCISS_TUR,
|
||||
+ };
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(all_checkers); i++)
|
||||
+ add_checker_class(multipath_dir, all_checkers[i]);
|
||||
+#else
|
||||
if (!add_checker_class(multipath_dir, DEFAULT_CHECKER))
|
||||
return 1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libmultipath/prio.c b/libmultipath/prio.c
|
||||
index 3a718ba5..c92bde7f 100644
|
||||
--- a/libmultipath/prio.c
|
||||
+++ b/libmultipath/prio.c
|
||||
@@ -20,8 +20,30 @@ unsigned int get_prio_timeout(unsigned int timeout_ms,
|
||||
|
||||
int init_prio (const char *multipath_dir)
|
||||
{
|
||||
+#ifdef LOAD_ALL_SHARED_LIBS
|
||||
+ static const char *const all_prios[] = {
|
||||
+ PRIO_ALUA,
|
||||
+ PRIO_CONST,
|
||||
+ PRIO_DATACORE,
|
||||
+ PRIO_EMC,
|
||||
+ PRIO_HDS,
|
||||
+ PRIO_HP_SW,
|
||||
+ PRIO_ONTAP,
|
||||
+ PRIO_RANDOM,
|
||||
+ PRIO_RDAC,
|
||||
+ PRIO_WEIGHTED_PATH,
|
||||
+ PRIO_SYSFS,
|
||||
+ PRIO_PATH_LATENCY,
|
||||
+ PRIO_ANA,
|
||||
+ };
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(all_prios); i++)
|
||||
+ add_prio(multipath_dir, all_prios[i]);
|
||||
+#else
|
||||
if (!add_prio(multipath_dir, DEFAULT_PRIO))
|
||||
return 1;
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,43 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,96 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Sep 2020 12:52:49 +0200
|
||||
Subject: [PATCH] multipath-tools Makefiles: separate rules for .so and man
|
||||
pages
|
||||
|
||||
Rely more on "make" functionality than on sequential command execution.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathcmd/Makefile | 8 +++++---
|
||||
libmpathpersist/Makefile | 10 +++++++---
|
||||
libmultipath/Makefile | 8 +++++---
|
||||
3 files changed, 17 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile
|
||||
index 0f6b8166..08ccb811 100644
|
||||
--- a/libmpathcmd/Makefile
|
||||
+++ b/libmpathcmd/Makefile
|
||||
@@ -8,13 +8,15 @@ CFLAGS += $(LIB_CFLAGS)
|
||||
|
||||
OBJS = mpath_cmd.o
|
||||
|
||||
-all: $(LIBS)
|
||||
+all: $(DEVLIB)
|
||||
|
||||
$(LIBS): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS)
|
||||
- $(LN) $@ $(DEVLIB)
|
||||
|
||||
-install: $(LIBS)
|
||||
+$(DEVLIB): $(LIBS)
|
||||
+ $(LN) $(LIBS) $@
|
||||
+
|
||||
+install: all
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
||||
$(LN) $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
|
||||
diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile
|
||||
index 21fdad80..9e869fdc 100644
|
||||
--- a/libmpathpersist/Makefile
|
||||
+++ b/libmpathpersist/Makefile
|
||||
@@ -11,15 +11,19 @@ LIBDEPS += -lpthread -ldevmapper -ldl -L$(multipathdir) -lmultipath \
|
||||
|
||||
OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o
|
||||
|
||||
-all: $(LIBS)
|
||||
+all: $(DEVLIB) man
|
||||
|
||||
$(LIBS): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS)
|
||||
- $(LN) $(LIBS) $(DEVLIB)
|
||||
+
|
||||
+$(DEVLIB): $(LIBS)
|
||||
+ $(LN) $(LIBS) $@
|
||||
+
|
||||
+man:
|
||||
$(GZIP) mpath_persistent_reserve_in.3 > mpath_persistent_reserve_in.3.gz
|
||||
$(GZIP) mpath_persistent_reserve_out.3 > mpath_persistent_reserve_out.3.gz
|
||||
|
||||
-install: $(LIBS)
|
||||
+install: all
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
||||
$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(syslibdir)
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index 62ba16e8..40028556 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -54,7 +54,7 @@ OBJS = memory.o parser.o vector.o devmapper.o callout.o \
|
||||
io_err_stat.o dm-generic.o generic.o foreign.o nvme-lib.o \
|
||||
libsg.o valid.o
|
||||
|
||||
-all: $(LIBS)
|
||||
+all: $(DEVLIB)
|
||||
|
||||
nvme-lib.o: nvme-lib.c nvme-ioctl.c nvme-ioctl.h
|
||||
$(CC) $(CFLAGS) -Wno-unused-function -c -o $@ $<
|
||||
@@ -74,9 +74,11 @@ nvme-ioctl.h: nvme/nvme-ioctl.h
|
||||
|
||||
$(LIBS): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS)
|
||||
- $(LN) $@ $(DEVLIB)
|
||||
|
||||
-install:
|
||||
+$(DEVLIB): $(LIBS)
|
||||
+ $(LN) $(LIBS) $@
|
||||
+
|
||||
+install: all
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
||||
$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Hesse <mail@eworm.de>
|
||||
Date: Wed, 6 May 2020 09:35:47 +0200
|
||||
Subject: [PATCH] libmpathpersist: depend on libmultipath
|
||||
|
||||
Without this the build fails with:
|
||||
|
||||
/usr/bin/ld: cannot find -lmultipath
|
||||
|
||||
Signed-off-by: Christian Hesse <mail@eworm.de>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 1dee3680..ba1d73ba 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -28,7 +28,7 @@ all: $(BUILDDIRS)
|
||||
$(BUILDDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
-multipath multipathd mpathpersist: libmultipath
|
||||
+libmpathpersist multipath multipathd mpathpersist: libmultipath
|
||||
mpathpersist: libmpathpersist
|
||||
|
||||
$(BUILDDIRS.clean):
|
||||
--
|
||||
2.17.2
|
||||
|
87
0009-libmultipath-create-separate-.so-for-unit-tests.patch
Normal file
87
0009-libmultipath-create-separate-.so-for-unit-tests.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Sat, 19 Sep 2020 00:29:45 +0200
|
||||
Subject: [PATCH] libmultipath: create separate .so for unit tests
|
||||
|
||||
The unit tests use a lot of internal symbols that we don't want
|
||||
to add to the ABI if we don't have to. As long as we don't
|
||||
have to make incompatible changes to functions, we can work around
|
||||
that by simply using a non-versioned library for the unit tests.
|
||||
Therefore we add a seperate rule here. Do this before actually
|
||||
adding a version script, to avoid breakage during bisection.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 7 +++++++
|
||||
tests/Makefile | 10 ++++++----
|
||||
2 files changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index 40028556..12bf6300 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -78,6 +78,13 @@ $(LIBS): $(OBJS)
|
||||
$(DEVLIB): $(LIBS)
|
||||
$(LN) $(LIBS) $@
|
||||
|
||||
+../tests/$(LIBS): $(OBJS) $(VERSION_SCRIPT)
|
||||
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=`basename $@` \
|
||||
+ -o $@ $(OBJS) $(LIBDEPS)
|
||||
+ $(LN) $@ ${@:.so.0=.so}
|
||||
+
|
||||
+test-lib: ../tests/$(LIBS)
|
||||
+
|
||||
install: all
|
||||
$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
|
||||
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index d26b3ce7..9658c9fd 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) -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka
|
||||
+LIBDEPS += -L. -L$(mpathcmddir) -lmultipath -lmpathcmd -lcmocka
|
||||
|
||||
TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy \
|
||||
alias directio valid devt
|
||||
@@ -68,7 +68,7 @@ lib/libchecktur.so:
|
||||
|
||||
%.out: %-test lib/libchecktur.so
|
||||
@echo == running $< ==
|
||||
- @LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) ./$< >$@
|
||||
+ @LD_LIBRARY_PATH=.:$(mpathcmddir) ./$< >$@
|
||||
|
||||
%.vgr: %-test lib/libchecktur.so
|
||||
@echo == running valgrind for $< ==
|
||||
@@ -78,7 +78,7 @@ lib/libchecktur.so:
|
||||
OBJS = $(TESTS:%=%.o) $(HELPERS)
|
||||
|
||||
test_clean:
|
||||
- $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr)
|
||||
+ $(RM) $(TESTS:%=%.out) $(TESTS:%=%.vgr) *.so*
|
||||
|
||||
valgrind_clean:
|
||||
$(RM) $(TESTS:%=%.vgr)
|
||||
@@ -98,12 +98,14 @@ dep_clean:
|
||||
@sed -n 's/^.*__wrap_\([a-zA-Z0-9_]*\).*$$/-Wl,--wrap=\1/p' $< | \
|
||||
sort -u | tr '\n' ' ' >$@
|
||||
|
||||
+libmultipath.so.0:
|
||||
+ $(MAKE) -C $(multipathdir) test-lib
|
||||
|
||||
# COLON will get expanded during second expansion below
|
||||
COLON:=:
|
||||
.SECONDEXPANSION:
|
||||
%-test: %.o %.o.wrap $$($$@_OBJDEPS) $$($$@_TESTDEPS) $$($$@_TESTDEPS$$(COLON).o=.o.wrap) \
|
||||
- $(multipathdir)/libmultipath.so Makefile
|
||||
+ libmultipath.so.0 Makefile
|
||||
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \
|
||||
$(LIBDEPS) $($@_LIBDEPS) \
|
||||
$(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap))
|
||||
--
|
||||
2.17.2
|
||||
|
303
0010-libmultipath-add-linker-version-script.patch
Normal file
303
0010-libmultipath-add-linker-version-script.patch
Normal file
@ -0,0 +1,303 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Sat, 19 Sep 2020 00:00:18 +0200
|
||||
Subject: [PATCH] libmultipath: add linker version script
|
||||
|
||||
This version script documents the current ABI of libmultipath,
|
||||
as used by multipath, multipathd, (lib)mpathpersist, and the
|
||||
dynamically loaded libraries (prioritizers, checkers, and foreign).
|
||||
The initial version string is set to "LIBMULTIPATH_1.0.0".
|
||||
|
||||
This reduces the amount of exported symbols of libmultipath.so.0
|
||||
by more than a half (199 vs. 434).
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/Makefile | 7 +-
|
||||
libmultipath/libmultipath.version | 248 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 253 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libmultipath/libmultipath.version
|
||||
|
||||
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
|
||||
index 12bf6300..e7254f39 100644
|
||||
--- a/libmultipath/Makefile
|
||||
+++ b/libmultipath/Makefile
|
||||
@@ -6,6 +6,7 @@ include ../Makefile.inc
|
||||
SONAME = 0
|
||||
DEVLIB = libmultipath.so
|
||||
LIBS = $(DEVLIB).$(SONAME)
|
||||
+VERSION_SCRIPT := libmultipath.version
|
||||
|
||||
CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir) -I$(nvmedir)
|
||||
|
||||
@@ -72,8 +73,10 @@ nvme-ioctl.c: nvme/nvme-ioctl.c
|
||||
nvme-ioctl.h: nvme/nvme-ioctl.h
|
||||
$(call make_static,$<,$@)
|
||||
|
||||
-$(LIBS): $(OBJS)
|
||||
- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS)
|
||||
+
|
||||
+$(LIBS): $(OBJS) $(VERSION_SCRIPT)
|
||||
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \
|
||||
+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS)
|
||||
|
||||
$(DEVLIB): $(LIBS)
|
||||
$(LN) $(LIBS) $@
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
new file mode 100644
|
||||
index 00000000..a6bf8218
|
||||
--- /dev/null
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -0,0 +1,248 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 SUSE LLC
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ * libmultipath ABI
|
||||
+ *
|
||||
+ * libmultipath doesn't have a stable ABI in the usual sense. In particular,
|
||||
+ * the library does not attempt to ship different versions of the same symbol
|
||||
+ * for backward compatibility.
|
||||
+ *
|
||||
+ * The ABI versioning only serves to avoid linking with a non-matching ABI, to
|
||||
+ * cut down the set of exported symbols, and to describe it.
|
||||
+ * The version string is LIBMULTIPATH_$MAJOR.$MINOR.$REL.
|
||||
+ *
|
||||
+ * Policy:
|
||||
+ *
|
||||
+ * * Bump $MAJOR for incompatible changes, like:
|
||||
+ * - symbols removed
|
||||
+ * - parameter list or return values changed for existing functions
|
||||
+ * - externally visible data structures changed in incompatible ways
|
||||
+ * (like offsets of previously existing struct members)
|
||||
+ * In this case, the new version doesn't inherit the previous versions,
|
||||
+ * because the new library doesn't provide the full previous ABI any more.
|
||||
+ * All predecessors are merged into the new version.
|
||||
+ *
|
||||
+ * * Bump $MINOR for compatible changes, like adding symbols.
|
||||
+ * The new version inherits the previous ones.
|
||||
+ *
|
||||
+ * * Bump $REL to describe deviations from upstream, e.g. in
|
||||
+ * multipath-tools packages shipped by distributions.
|
||||
+ * The new version inherits the previous ones.
|
||||
+ */
|
||||
+
|
||||
+LIBMULTIPATH_1.0.0 {
|
||||
+global:
|
||||
+ /* symbols referenced by multipath and multipathd */
|
||||
+ add_foreign;
|
||||
+ add_map_with_path;
|
||||
+ adopt_paths;
|
||||
+ alloc_multipath;
|
||||
+ alloc_path;
|
||||
+ alloc_path_with_pathinfo;
|
||||
+ alloc_strvec;
|
||||
+ change_foreign;
|
||||
+ check_alias_settings;
|
||||
+ checker_clear_message;
|
||||
+ checker_disable;
|
||||
+ checker_enable;
|
||||
+ checker_is_sync;
|
||||
+ checker_message;
|
||||
+ checker_name;
|
||||
+ checker_state_name;
|
||||
+ check_foreign;
|
||||
+ cleanup_checkers;
|
||||
+ cleanup_foreign;
|
||||
+ cleanup_lock;
|
||||
+ cleanup_prio;
|
||||
+ close_fd;
|
||||
+ coalesce_paths;
|
||||
+ convert_dev;
|
||||
+ count_active_paths;
|
||||
+ delete_all_foreign;
|
||||
+ delete_foreign;
|
||||
+ disassemble_map;
|
||||
+ disassemble_status;
|
||||
+ dlog;
|
||||
+ dm_cancel_deferred_remove;
|
||||
+ dm_drv_version;
|
||||
+ dm_enablegroup;
|
||||
+ dm_fail_path;
|
||||
+ _dm_flush_map;
|
||||
+ dm_flush_map_nopaths;
|
||||
+ dm_flush_maps;
|
||||
+ dm_geteventnr;
|
||||
+ dm_get_info;
|
||||
+ dm_get_major_minor;
|
||||
+ dm_get_map;
|
||||
+ dm_get_maps;
|
||||
+ dm_get_multipath;
|
||||
+ dm_get_status;
|
||||
+ dm_get_uuid;
|
||||
+ dm_is_mpath;
|
||||
+ dm_mapname;
|
||||
+ dm_map_present;
|
||||
+ dm_queue_if_no_path;
|
||||
+ dm_reassign;
|
||||
+ dm_reinstate_path;
|
||||
+ dm_simplecmd_noflush;
|
||||
+ dm_switchgroup;
|
||||
+ dm_tgt_version;
|
||||
+ domap;
|
||||
+ ensure_directories_exist;
|
||||
+ extract_hwe_from_path;
|
||||
+ filter_devnode;
|
||||
+ filter_path;
|
||||
+ filter_wwid;
|
||||
+ find_mp_by_alias;
|
||||
+ find_mp_by_minor;
|
||||
+ find_mp_by_str;
|
||||
+ find_mp_by_wwid;
|
||||
+ find_mpe;
|
||||
+ find_path_by_dev;
|
||||
+ find_path_by_devt;
|
||||
+ find_slot;
|
||||
+ foreign_multipath_layout;
|
||||
+ foreign_path_layout;
|
||||
+ free_config;
|
||||
+ free_multipath;
|
||||
+ free_multipathvec;
|
||||
+ free_path;
|
||||
+ free_pathvec;
|
||||
+ free_strvec;
|
||||
+ get_monotonic_time;
|
||||
+ get_multipath_layout;
|
||||
+ get_path_layout;
|
||||
+ get_pgpolicy_id;
|
||||
+ get_refwwid;
|
||||
+ get_state;
|
||||
+ get_udev_device;
|
||||
+ get_uid;
|
||||
+ get_used_hwes;
|
||||
+ group_by_prio;
|
||||
+ init_checkers;
|
||||
+ init_foreign;
|
||||
+ init_prio;
|
||||
+ io_err_stat_attr;
|
||||
+ io_err_stat_handle_pathfail;
|
||||
+ is_path_valid;
|
||||
+ is_quote;
|
||||
+ libmp_dm_task_create;
|
||||
+ libmp_udev_set_sync_support;
|
||||
+ load_config;
|
||||
+ log_thread_reset;
|
||||
+ log_thread_start;
|
||||
+ log_thread_stop;
|
||||
+ need_io_err_check;
|
||||
+ normalize_timespec;
|
||||
+ orphan_path;
|
||||
+ orphan_paths;
|
||||
+ parse_prkey_flags;
|
||||
+ pathcount;
|
||||
+ path_discovery;
|
||||
+ path_get_tpgs;
|
||||
+ pathinfo;
|
||||
+ path_offline;
|
||||
+ print_all_paths;
|
||||
+ print_foreign_topology;
|
||||
+ _print_multipath_topology;
|
||||
+ pthread_cond_init_mono;
|
||||
+ recv_packet;
|
||||
+ recv_packet_from_client;
|
||||
+ reinstate_paths;
|
||||
+ remember_wwid;
|
||||
+ remove_map;
|
||||
+ remove_map_by_alias;
|
||||
+ remove_maps;
|
||||
+ remove_wwid;
|
||||
+ replace_wwids;
|
||||
+ reset_checker_classes;
|
||||
+ select_all_tg_pt;
|
||||
+ select_action;
|
||||
+ select_find_multipaths_timeout;
|
||||
+ select_no_path_retry;
|
||||
+ select_path_group;
|
||||
+ select_reservation_key;
|
||||
+ send_packet;
|
||||
+ set_max_fds;
|
||||
+ __set_no_path_retry;
|
||||
+ set_path_removed;
|
||||
+ set_prkey;
|
||||
+ setup_map;
|
||||
+ setup_thread_attr;
|
||||
+ should_multipath;
|
||||
+ snprint_blacklist_report;
|
||||
+ snprint_config;
|
||||
+ snprint_devices;
|
||||
+ snprint_foreign_multipaths;
|
||||
+ snprint_foreign_paths;
|
||||
+ snprint_foreign_topology;
|
||||
+ _snprint_multipath;
|
||||
+ snprint_multipath_header;
|
||||
+ snprint_multipath_map_json;
|
||||
+ _snprint_multipath_topology;
|
||||
+ snprint_multipath_topology_json;
|
||||
+ _snprint_path;
|
||||
+ snprint_path_header;
|
||||
+ snprint_status;
|
||||
+ snprint_wildcards;
|
||||
+ stop_io_err_stat_thread;
|
||||
+ store_path;
|
||||
+ store_pathinfo;
|
||||
+ strchop;
|
||||
+ strlcpy;
|
||||
+ sync_map_state;
|
||||
+ sysfs_attr_set_value;
|
||||
+ sysfs_get_size;
|
||||
+ sysfs_is_multipathed;
|
||||
+ timespecsub;
|
||||
+ trigger_paths_udev_change;
|
||||
+ uevent_dispatch;
|
||||
+ uevent_get_dm_str;
|
||||
+ uevent_get_env_positive_int;
|
||||
+ uevent_is_mpath;
|
||||
+ uevent_listen;
|
||||
+ update_mpp_paths;
|
||||
+ update_multipath_status;
|
||||
+ update_multipath_strings;
|
||||
+ update_multipath_table;
|
||||
+ update_pathvec_from_dm;
|
||||
+ update_queue_mode_add_path;
|
||||
+ update_queue_mode_del_path;
|
||||
+ ux_socket_listen;
|
||||
+ valid_alias;
|
||||
+ vector_alloc;
|
||||
+ vector_alloc_slot;
|
||||
+ vector_del_slot;
|
||||
+ vector_free;
|
||||
+ vector_reset;
|
||||
+ vector_set_slot;
|
||||
+ verify_paths;
|
||||
+
|
||||
+ /* checkers */
|
||||
+ sg_read;
|
||||
+
|
||||
+ /* prioritizers */
|
||||
+ get_asymmetric_access_state;
|
||||
+ get_prio_timeout;
|
||||
+ get_target_port_group;
|
||||
+ get_target_port_group_support;
|
||||
+ libmp_nvme_ana_log;
|
||||
+ libmp_nvme_get_nsid;
|
||||
+ libmp_nvme_identify_ns;
|
||||
+ log_nvme_errcode;
|
||||
+ nvme_id_ctrl_ana;
|
||||
+ snprint_host_wwnn;
|
||||
+ snprint_host_wwpn;
|
||||
+ snprint_path_serial;
|
||||
+ snprint_tgt_wwnn;
|
||||
+ snprint_tgt_wwpn;
|
||||
+ sysfs_get_asymmetric_access_state;
|
||||
+
|
||||
+ /* foreign */
|
||||
+ free_scandir_result;
|
||||
+ sysfs_attr_get_value;
|
||||
+
|
||||
+local:
|
||||
+ *;
|
||||
+};
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
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: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index ba1d73ba..fec3b73b 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -28,8 +28,9 @@ all: $(BUILDDIRS)
|
||||
$(BUILDDIRS):
|
||||
$(MAKE) -C $@
|
||||
|
||||
-libmpathpersist multipath multipathd mpathpersist: libmultipath
|
||||
-mpathpersist: libmpathpersist
|
||||
+libmultipath libdmmp: libmpathcmd
|
||||
+libmpathpersist multipath multipathd: libmultipath
|
||||
+mpathpersist multipathd: libmpathpersist
|
||||
|
||||
$(BUILDDIRS.clean):
|
||||
$(MAKE) -C ${@:.clean=} clean
|
||||
--
|
||||
2.17.2
|
||||
|
81
0011-libmpathpersist-add-linker-version-script.patch
Normal file
81
0011-libmpathpersist-add-linker-version-script.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Sat, 19 Sep 2020 00:02:16 +0200
|
||||
Subject: [PATCH] libmpathpersist: add linker version script
|
||||
|
||||
This defines the ABI of libmpathpersist in the current state.
|
||||
The initial version is set to "LIBMPATHPERSIST_1.0.0".
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/Makefile | 6 +++--
|
||||
libmpathpersist/libmpathpersist.version | 32 +++++++++++++++++++++++++
|
||||
2 files changed, 36 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libmpathpersist/libmpathpersist.version
|
||||
|
||||
diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile
|
||||
index 9e869fdc..456ce4cf 100644
|
||||
--- a/libmpathpersist/Makefile
|
||||
+++ b/libmpathpersist/Makefile
|
||||
@@ -3,6 +3,7 @@ include ../Makefile.inc
|
||||
SONAME = 0
|
||||
DEVLIB = libmpathpersist.so
|
||||
LIBS = $(DEVLIB).$(SONAME)
|
||||
+VERSION_SCRIPT := libmpathpersist.version
|
||||
|
||||
CFLAGS += $(LIB_CFLAGS) -I$(multipathdir) -I$(mpathpersistdir) -I$(mpathcmddir)
|
||||
|
||||
@@ -13,8 +14,9 @@ OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o
|
||||
|
||||
all: $(DEVLIB) man
|
||||
|
||||
-$(LIBS): $(OBJS)
|
||||
- $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ -o $@ $(OBJS)
|
||||
+$(LIBS): $(OBJS) $(VERSION_SCRIPT)
|
||||
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) $(LIBDEPS) -Wl,-soname=$@ \
|
||||
+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS)
|
||||
|
||||
$(DEVLIB): $(LIBS)
|
||||
$(LN) $(LIBS) $@
|
||||
diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version
|
||||
new file mode 100644
|
||||
index 00000000..dc648ce6
|
||||
--- /dev/null
|
||||
+++ b/libmpathpersist/libmpathpersist.version
|
||||
@@ -0,0 +1,32 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 SUSE LLC
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ * libmpathpersist ABI
|
||||
+ *
|
||||
+ * The ABI of libmpathpersist is supposed to remain stable. Removing symbols
|
||||
+ * or altering existing symbols' semantics is not allowed. When changing a
|
||||
+ * a symbol, either use a new name, or explicit symver directives.
|
||||
+ *
|
||||
+ * See libmultipath.version for general policy about version numbers.
|
||||
+ */
|
||||
+LIBMPATHPERSIST_1.0.0 {
|
||||
+global:
|
||||
+
|
||||
+ __mpath_persistent_reserve_in;
|
||||
+ __mpath_persistent_reserve_out;
|
||||
+ dumpHex;
|
||||
+ mpath_alloc_prin_response;
|
||||
+ mpath_lib_exit;
|
||||
+ mpath_lib_init;
|
||||
+ mpath_mx_alloc_len;
|
||||
+ mpath_persistent_reserve_in;
|
||||
+ mpath_persistent_reserve_init_vecs;
|
||||
+ mpath_persistent_reserve_out;
|
||||
+ mpath_persistent_reserve_free_vecs;
|
||||
+ prin_do_scsi_ioctl;
|
||||
+ prout_do_scsi_ioctl;
|
||||
+ update_map_pr;
|
||||
+
|
||||
+local: *;
|
||||
+};
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
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
|
||||
|
74
0012-libmpathcmd-add-linker-version-script.patch
Normal file
74
0012-libmpathcmd-add-linker-version-script.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Sep 2020 12:54:20 +0200
|
||||
Subject: [PATCH] libmpathcmd: add linker version script
|
||||
|
||||
For completeness, this isn't really necessary.
|
||||
The version string is set to "LIBMPATHCMD_1.0.0".
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathcmd/Makefile | 6 ++++--
|
||||
libmpathcmd/libmpathcmd.version | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 29 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libmpathcmd/libmpathcmd.version
|
||||
|
||||
diff --git a/libmpathcmd/Makefile b/libmpathcmd/Makefile
|
||||
index 08ccb811..25910194 100644
|
||||
--- a/libmpathcmd/Makefile
|
||||
+++ b/libmpathcmd/Makefile
|
||||
@@ -3,6 +3,7 @@ include ../Makefile.inc
|
||||
SONAME = 0
|
||||
DEVLIB = libmpathcmd.so
|
||||
LIBS = $(DEVLIB).$(SONAME)
|
||||
+VERSION_SCRIPT := libmpathcmd.version
|
||||
|
||||
CFLAGS += $(LIB_CFLAGS)
|
||||
|
||||
@@ -10,8 +11,9 @@ OBJS = mpath_cmd.o
|
||||
|
||||
all: $(DEVLIB)
|
||||
|
||||
-$(LIBS): $(OBJS)
|
||||
- $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ -o $@ $(OBJS) $(LIBDEPS)
|
||||
+$(LIBS): $(OBJS) $(VERSION_SCRIPT)
|
||||
+ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -Wl,-soname=$@ \
|
||||
+ -Wl,--version-script=$(VERSION_SCRIPT) -o $@ $(OBJS) $(LIBDEPS)
|
||||
|
||||
$(DEVLIB): $(LIBS)
|
||||
$(LN) $(LIBS) $@
|
||||
diff --git a/libmpathcmd/libmpathcmd.version b/libmpathcmd/libmpathcmd.version
|
||||
new file mode 100644
|
||||
index 00000000..f1006280
|
||||
--- /dev/null
|
||||
+++ b/libmpathcmd/libmpathcmd.version
|
||||
@@ -0,0 +1,25 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2020 SUSE LLC
|
||||
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+ *
|
||||
+ * libmpathcmd ABI
|
||||
+ *
|
||||
+ * The ABI of libmpathcmd is supposed to remain stable. Removing symbols
|
||||
+ * or altering existing symbols' semantics is not allowed. When changing a
|
||||
+ * a symbol, either use a new name, or explicit symver directives.
|
||||
+ *
|
||||
+ * See libmultipath.version for general policy about version numbers.
|
||||
+ */
|
||||
+LIBMPATHCMD_1.0.0 {
|
||||
+global:
|
||||
+ __mpath_connect;
|
||||
+ mpath_connect;
|
||||
+ mpath_disconnect;
|
||||
+ mpath_process_cmd;
|
||||
+ mpath_recv_reply;
|
||||
+ mpath_recv_reply_len;
|
||||
+ mpath_recv_reply_data;
|
||||
+ mpath_send_cmd;
|
||||
+local:
|
||||
+ *;
|
||||
+};
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
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
|
||||
|
38
0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch
Normal file
38
0013-libmpathpersist-initialize-mpp-hwe-in-get_mpvec.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 25 Sep 2020 21:37:16 +0200
|
||||
Subject: [PATCH] libmpathpersist: initialize mpp->hwe in get_mpvec()
|
||||
|
||||
In __mpath_persistent_reserve_out, we call select_all_tg_pt(),
|
||||
which requires mpp->hwe to be set. Initialize it in get_mpvec().
|
||||
|
||||
Fixes: 5b54e77 ("mpathpersist: add all_tg_pt option")
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_persist.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
||||
index 1f9817ed..4b3f3e0d 100644
|
||||
--- a/libmpathpersist/mpath_persist.c
|
||||
+++ b/libmpathpersist/mpath_persist.c
|
||||
@@ -341,11 +341,13 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid)
|
||||
continue;
|
||||
|
||||
if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK ||
|
||||
- update_multipath_status(mpp) != DMP_OK) {
|
||||
+ update_multipath_status(mpp) != DMP_OK ||
|
||||
+ update_mpp_paths(mpp, pathvec)) {
|
||||
condlog(1, "error parsing map %s", mpp->wwid);
|
||||
remove_map(mpp, pathvec, curmp, PURGE_VEC);
|
||||
i--;
|
||||
- }
|
||||
+ } else
|
||||
+ extract_hwe_from_path(mpp);
|
||||
}
|
||||
return MPATH_PR_SUCCESS ;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 17:19:37 +0200
|
||||
Subject: [PATCH] multipath-tools: Makefile.inc: set -Wno-error=clobbered
|
||||
|
||||
We need to ignore -Wclobbered because gcc has trouble dealing with glibc's
|
||||
implementation of pthread_cleanup_push().
|
||||
|
||||
For some variants of gcc, -Wno-clobbered alone isn't enough if -Werror is also
|
||||
set. Compilation with -Wno-error=clobbered works, though.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 671dd1ca..e7256e3a 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -91,7 +91,7 @@ TEST_CC_OPTION = $(shell \
|
||||
|
||||
STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||
-WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered,)
|
||||
+WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
|
||||
|
||||
OPTFLAGS := -O2 -g $(STACKPROT) --param=ssp-buffer-size=4
|
||||
WARNFLAGS := -Werror -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 16:02:25 +0200
|
||||
Subject: [PATCH] libmultipath: discovery.c: use %z qualifier for size_t
|
||||
|
||||
Otherwise compilation for 32bit targets spits out warnings.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index ee3290cd..ffec5162 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -986,7 +986,7 @@ parse_vpd_pg80(const unsigned char *in, char *out, size_t out_len)
|
||||
}
|
||||
|
||||
if (len >= out_len) {
|
||||
- condlog(2, "vpd pg80 overflow, %lu/%lu bytes required",
|
||||
+ condlog(2, "vpd pg80 overflow, %zu/%zu bytes required",
|
||||
len + 1, out_len);
|
||||
len = out_len - 1;
|
||||
}
|
||||
@@ -1087,7 +1087,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
|
||||
len = sprintf(out, "%d", vpd_type);
|
||||
if (2 * vpd_len >= out_len - len) {
|
||||
- condlog(1, "%s: WWID overflow, type %d, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type %d, %zu/%zu bytes required",
|
||||
__func__, vpd_type,
|
||||
2 * vpd_len + len + 1, out_len);
|
||||
vpd_len = (out_len - len - 1) / 2;
|
||||
@@ -1096,7 +1096,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
len += sprintf(out + len,
|
||||
"%02x", vpd[i]);
|
||||
} else if (vpd_type == 0x8 && vpd_len < 4) {
|
||||
- condlog(1, "%s: VPD length %lu too small for designator type 8",
|
||||
+ condlog(1, "%s: VPD length %zu too small for designator type 8",
|
||||
__func__, vpd_len);
|
||||
return -EINVAL;
|
||||
} else if (vpd_type == 0x8) {
|
||||
@@ -1112,7 +1112,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
while (len > 2 && vpd[len - 2] == '\0')
|
||||
--len;
|
||||
if (len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 8/%c, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 8/%c, %zu/%zu bytes required",
|
||||
__func__, out[0], len + 1, out_len);
|
||||
len = out_len - 1;
|
||||
}
|
||||
@@ -1136,7 +1136,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
while ((p = memchr(vpd, ' ', vpd_len))) {
|
||||
p_len = p - vpd;
|
||||
if (len + p_len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required",
|
||||
__func__, len + p_len, out_len);
|
||||
p_len = out_len - len - 1;
|
||||
}
|
||||
@@ -1162,7 +1162,7 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
p_len = vpd_len;
|
||||
if (p_len > 0 && len < out_len - 1) {
|
||||
if (len + p_len > out_len - 1) {
|
||||
- condlog(1, "%s: WWID overflow, type 1, %lu/%lu bytes required",
|
||||
+ condlog(1, "%s: WWID overflow, type 1, %zu/%zu bytes required",
|
||||
__func__, len + p_len + 1, out_len);
|
||||
p_len = out_len - len - 1;
|
||||
}
|
||||
@@ -1186,14 +1186,14 @@ parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len,
|
||||
|
||||
memset(out, 0x0, out_len);
|
||||
if (in_len <= 4 || (in[4] > 3 && in_len < 44)) {
|
||||
- condlog(3, "HP/3PAR vendor specific VPD page length too short: %lu", in_len);
|
||||
+ condlog(3, "HP/3PAR vendor specific VPD page length too short: %zu", in_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (in[4] <= 3) /* revision must be > 3 to have Vomlume Name */
|
||||
return -ENODATA;
|
||||
len = get_unaligned_be32(&in[40]);
|
||||
if (len > out_len || len + 44 > in_len) {
|
||||
- condlog(3, "HP/3PAR vendor specific Volume name too long: %lu",
|
||||
+ condlog(3, "HP/3PAR vendor specific Volume name too long: %zu",
|
||||
len);
|
||||
return -EINVAL;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
140
0014-multipathd-allow-shutdown-during-configure.patch
Normal file
140
0014-multipathd-allow-shutdown-during-configure.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 4 Jan 2019 16:59:49 +0100
|
||||
Subject: [PATCH] multipathd: allow shutdown during configure()
|
||||
|
||||
reconfigure() can be a long-running operation; both initial path
|
||||
discovery and initial map setup can take a long time. Allow
|
||||
the main program to indicate that the process should be
|
||||
interrupted if a shutdown signal was received.
|
||||
|
||||
We take advantage of the dynamic linker's symbol lookup ordering
|
||||
here. The default implementation of should_exit never returns
|
||||
true, but callers (like multipathd) can override it.
|
||||
|
||||
Cc: Chongyun Wu <wu.chongyun@h3c.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 6 ++++++
|
||||
libmultipath/discovery.c | 3 +++
|
||||
libmultipath/util.c | 5 +++++
|
||||
libmultipath/util.h | 1 +
|
||||
multipathd/main.c | 17 +++++++++++++++++
|
||||
5 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index d7afc915..1c8aac08 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1173,6 +1173,12 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
|
||||
vector_foreach_slot (pathvec, pp1, k) {
|
||||
int invalid;
|
||||
+
|
||||
+ if (should_exit()) {
|
||||
+ ret = CP_FAIL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* skip this path for some reason */
|
||||
|
||||
/* 1. if path has no unique id or wwid blacklisted */
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index c2e1754c..e7084664 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -200,6 +200,9 @@ path_discovery (vector pathvec, int flag)
|
||||
const char *devtype;
|
||||
const char *devpath;
|
||||
|
||||
+ if (should_exit())
|
||||
+ break;
|
||||
+
|
||||
devpath = udev_list_entry_get_name(entry);
|
||||
condlog(4, "Discover device %s", devpath);
|
||||
udevice = udev_device_new_from_syspath(udev, devpath);
|
||||
diff --git a/libmultipath/util.c b/libmultipath/util.c
|
||||
index 1748eafe..1f977792 100644
|
||||
--- a/libmultipath/util.c
|
||||
+++ b/libmultipath/util.c
|
||||
@@ -445,3 +445,8 @@ void _log_bitfield_overflow(const char *f, unsigned int bit, unsigned int len)
|
||||
{
|
||||
condlog(0, "%s: bitfield overflow: %u >= %u", f, bit, len);
|
||||
}
|
||||
+
|
||||
+int should_exit(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/libmultipath/util.h b/libmultipath/util.h
|
||||
index 2b9703ac..ac19473e 100644
|
||||
--- a/libmultipath/util.h
|
||||
+++ b/libmultipath/util.h
|
||||
@@ -27,6 +27,7 @@ int parse_prkey(const char *ptr, uint64_t *prkey);
|
||||
int parse_prkey_flags(const char *ptr, uint64_t *prkey, uint8_t *flags);
|
||||
int safe_write(int fd, const void *buf, size_t count);
|
||||
void set_max_fds(rlim_t max_fds);
|
||||
+int should_exit(void);
|
||||
|
||||
#define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index eedc6c10..fa53e963 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -141,6 +141,11 @@ static inline enum daemon_status get_running_state(void)
|
||||
return st;
|
||||
}
|
||||
|
||||
+int should_exit(void)
|
||||
+{
|
||||
+ return get_running_state() == DAEMON_SHUTDOWN;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* global copy of vecs for use in sig handlers
|
||||
*/
|
||||
@@ -2570,6 +2575,9 @@ configure (struct vectors * vecs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (should_exit())
|
||||
+ goto fail;
|
||||
+
|
||||
conf = get_multipath_config();
|
||||
pthread_cleanup_push(put_multipath_config, conf);
|
||||
vector_foreach_slot (vecs->pathvec, pp, i){
|
||||
@@ -2586,6 +2594,9 @@ configure (struct vectors * vecs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (should_exit())
|
||||
+ goto fail;
|
||||
+
|
||||
/*
|
||||
* create new set of maps & push changed ones into dm
|
||||
* In the first call, use FORCE_RELOAD_WEAK to avoid making
|
||||
@@ -2600,6 +2611,9 @@ configure (struct vectors * vecs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (should_exit())
|
||||
+ goto fail;
|
||||
+
|
||||
/*
|
||||
* may need to remove some maps which are no longer relevant
|
||||
* e.g., due to blacklist changes in conf file
|
||||
@@ -2611,6 +2625,9 @@ configure (struct vectors * vecs)
|
||||
|
||||
dm_lib_release();
|
||||
|
||||
+ if (should_exit())
|
||||
+ goto fail;
|
||||
+
|
||||
sync_maps_state(mpvec);
|
||||
vector_foreach_slot(mpvec, mpp, i){
|
||||
if (remember_wwid(mpp->wwid) == 1)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,198 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 16:03:58 +0200
|
||||
Subject: [PATCH] libmultipath: eliminate more signed/unsigned comparisons
|
||||
|
||||
Fix some more compiler warnings about signed/unsigned comparison.
|
||||
I've observed these only on 32bit builds, therefore they went unnoticed
|
||||
before.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <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 +-
|
||||
5 files changed, 19 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_pr_ioctl.c b/libmpathpersist/mpath_pr_ioctl.c
|
||||
index fadc9e10..126601c3 100644
|
||||
--- a/libmpathpersist/mpath_pr_ioctl.c
|
||||
+++ b/libmpathpersist/mpath_pr_ioctl.c
|
||||
@@ -238,7 +238,7 @@ static void mpath_format_readfullstatus(struct prin_resp *pr_buff)
|
||||
uint32_t additional_length, k, tid_len_len = 0;
|
||||
char tempbuff[MPATH_MAX_PARAM_LEN];
|
||||
struct prin_fulldescr fdesc;
|
||||
- static const int pbuf_size =
|
||||
+ static const unsigned int pbuf_size =
|
||||
sizeof(pr_buff->prin_descriptor.prin_readfd.private_buffer);
|
||||
|
||||
convert_be32_to_cpu(&pr_buff->prin_descriptor.prin_readfd.prgeneration);
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index b944ef32..298b3764 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -1958,25 +1958,25 @@ char *snprint_config(const struct config *conf, int *len,
|
||||
}
|
||||
|
||||
c = reply + snprint_defaults(conf, reply, maxlen);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_blacklist(conf, c, reply + maxlen - c);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_blacklist_except(conf, c, reply + maxlen - c);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_hwtable(conf, c, reply + maxlen - c,
|
||||
hwtable ? hwtable : conf->hwtable);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
c += snprint_overrides(conf, c, reply + maxlen - c,
|
||||
conf->overrides);
|
||||
- if ((c - reply) == maxlen)
|
||||
+ if (c == reply + maxlen)
|
||||
continue;
|
||||
|
||||
if (VECTOR_SIZE(conf->mptable) > 0 ||
|
||||
@@ -1984,7 +1984,7 @@ char *snprint_config(const struct config *conf, int *len,
|
||||
c += snprint_mptable(conf, c, reply + maxlen - c,
|
||||
mpvec);
|
||||
|
||||
- if ((c - reply) < maxlen) {
|
||||
+ if (c < reply + maxlen) {
|
||||
if (len)
|
||||
*len = c - reply;
|
||||
return reply;
|
||||
diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h
|
||||
index 18b495ef..7ba2cf4c 100644
|
||||
--- a/libmultipath/prioritizers/alua_spc3.h
|
||||
+++ b/libmultipath/prioritizers/alua_spc3.h
|
||||
@@ -284,7 +284,7 @@ struct rtpg_data {
|
||||
#define RTPG_FOR_EACH_PORT_GROUP(p, g) \
|
||||
for( \
|
||||
g = &(p->data[0]); \
|
||||
- (((char *) g) - ((char *) p)) < get_unaligned_be32(p->length); \
|
||||
+ ((char *) g) < ((char *) p) + get_unaligned_be32(p->length); \
|
||||
g = (struct rtpg_tpg_dscr *) ( \
|
||||
((char *) g) + \
|
||||
sizeof(struct rtpg_tpg_dscr) + \
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 7d878c88..31c3d9fd 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -66,7 +66,7 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style,
|
||||
c += snprint_foreign_paths(c, reply + maxlen - c,
|
||||
style, pretty);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -102,7 +102,7 @@ show_path (char ** r, int * len, struct vectors * vecs, struct path *pp,
|
||||
|
||||
c += snprint_path(c, reply + maxlen - c, style, pp, 0);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ show_map_topology (char ** r, int * len, struct multipath * mpp,
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_topology(c, reply + maxlen - c, mpp, 2);
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -171,7 +171,7 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
|
||||
}
|
||||
c += snprint_foreign_topology(c, reply + maxlen - c, 2);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -209,7 +209,7 @@ show_maps_json (char ** r, int * len, struct vectors * vecs)
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_topology_json(c, maxlen, vecs);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -238,7 +238,7 @@ show_map_json (char ** r, int * len, struct multipath * mpp,
|
||||
c = reply;
|
||||
|
||||
c += snprint_multipath_map_json(c, maxlen, mpp);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -487,7 +487,7 @@ show_map (char ** r, int *len, struct multipath * mpp, char * style,
|
||||
c += snprint_multipath(c, reply + maxlen - c, style,
|
||||
mpp, pretty);
|
||||
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -533,7 +533,7 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
|
||||
}
|
||||
c += snprint_foreign_multipaths(c, reply + maxlen - c,
|
||||
style, pretty);
|
||||
- again = ((c - reply) == (maxlen - 1));
|
||||
+ again = (c == reply + maxlen - 1);
|
||||
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
@@ -1297,7 +1297,7 @@ show_blacklist (char ** r, int * len)
|
||||
|
||||
c = reply;
|
||||
c += snprint_blacklist_report(conf, c, maxlen);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
@@ -1339,7 +1339,7 @@ show_devices (char ** r, int * len, struct vectors *vecs)
|
||||
|
||||
c = reply;
|
||||
c += snprint_devices(conf, c, maxlen, vecs);
|
||||
- again = ((c - reply) == maxlen);
|
||||
+ again = (c == reply + maxlen);
|
||||
REALLOC_REPLY(reply, again, maxlen);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 8baf9abe..6b7db2c0 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2374,7 +2374,7 @@ checkerloop (void *ap)
|
||||
conf = get_multipath_config();
|
||||
max_checkint = conf->max_checkint;
|
||||
put_multipath_config(conf);
|
||||
- if (diff_time.tv_sec > max_checkint)
|
||||
+ if (diff_time.tv_sec > (time_t)max_checkint)
|
||||
condlog(1, "path checkers took longer "
|
||||
"than %lu seconds, consider "
|
||||
"increasing max_polling_interval",
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,67 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 10:23:05 +0200
|
||||
Subject: [PATCH] multipathd: avoid sending "READY=1" to systemd on early
|
||||
shutdown
|
||||
|
||||
If multipathd gets a shutdown request during initial reconfigure(),
|
||||
it shouldn't send "READY=1" to systemd. Ensure this by sending
|
||||
"READY=1" via post_config_state().
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fa53e963..53a22a43 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -189,6 +189,8 @@ static void do_sd_notify(enum daemon_status old_state,
|
||||
{
|
||||
char notify_msg[MSG_SIZE];
|
||||
const char *msg;
|
||||
+ static bool startup_done = false;
|
||||
+
|
||||
/*
|
||||
* Checkerloop switches back and forth between idle and running state.
|
||||
* No need to tell systemd each time.
|
||||
@@ -205,6 +207,11 @@ static void do_sd_notify(enum daemon_status old_state,
|
||||
|
||||
if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg))
|
||||
sd_notify(0, notify_msg);
|
||||
+
|
||||
+ if (new_state == DAEMON_IDLE && !startup_done) {
|
||||
+ sd_notify(0, "READY=1");
|
||||
+ startup_done = true;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2903,9 +2910,6 @@ child (__attribute__((unused)) void *param)
|
||||
struct vectors * vecs;
|
||||
struct multipath * mpp;
|
||||
int i;
|
||||
-#ifdef USE_SYSTEMD
|
||||
- int startup_done = 0;
|
||||
-#endif
|
||||
int rc;
|
||||
int pid_fd = -1;
|
||||
struct config *conf;
|
||||
@@ -3065,12 +3069,6 @@ child (__attribute__((unused)) void *param)
|
||||
}
|
||||
lock_cleanup_pop(vecs->lock);
|
||||
post_config_state(DAEMON_IDLE);
|
||||
-#ifdef USE_SYSTEMD
|
||||
- if (!startup_done) {
|
||||
- sd_notify(0, "READY=1");
|
||||
- startup_done = 1;
|
||||
- }
|
||||
-#endif
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 11 May 2020 22:22:25 +0200
|
||||
Subject: [PATCH] libmultipath: set_uint: fix parsing for 32bit
|
||||
|
||||
On architectures where sizeof(long) == sizeof(int), the code wouldn't
|
||||
work as intended. Use strtoul instead. As strtoul happily parses
|
||||
negative numbers as input, require the number to begin with a digit.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/dict.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 3e25e74f..0e9ea387 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -60,19 +60,22 @@ static int
|
||||
set_uint(vector strvec, void *ptr)
|
||||
{
|
||||
unsigned int *uint_ptr = (unsigned int *)ptr;
|
||||
- char *buff, *eptr;
|
||||
- long res;
|
||||
+ char *buff, *eptr, *p;
|
||||
+ unsigned long res;
|
||||
int rc;
|
||||
|
||||
buff = set_value(strvec);
|
||||
if (!buff)
|
||||
return 1;
|
||||
|
||||
- res = strtol(buff, &eptr, 10);
|
||||
+ p = buff;
|
||||
+ while (isspace(*p))
|
||||
+ p++;
|
||||
+ res = strtoul(p, &eptr, 10);
|
||||
if (eptr > buff)
|
||||
while (isspace(*eptr))
|
||||
eptr++;
|
||||
- if (*buff == '\0' || *eptr != '\0' || res < 0 || res > UINT_MAX) {
|
||||
+ if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX) {
|
||||
condlog(1, "%s: invalid value for %s: \"%s\"",
|
||||
__func__, (char*)VECTOR_SLOT(strvec, 0), buff);
|
||||
rc = 1;
|
||||
--
|
||||
2.17.2
|
||||
|
31
0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch
Normal file
31
0016-multipathd-send-STOPPING-1-to-systemd-on-shutdown.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 10:47:52 +0200
|
||||
Subject: [PATCH] multipathd: send "STOPPING=1" to systemd on shutdown
|
||||
|
||||
Inform systemd that the daemon is shutting down. See sd_notify(3).
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 53a22a43..c264351c 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -208,7 +208,9 @@ static void do_sd_notify(enum daemon_status old_state,
|
||||
if (msg && !safe_sprintf(notify_msg, "STATUS=%s", msg))
|
||||
sd_notify(0, notify_msg);
|
||||
|
||||
- if (new_state == DAEMON_IDLE && !startup_done) {
|
||||
+ if (new_state == DAEMON_SHUTDOWN)
|
||||
+ sd_notify(0, "STOPPING=1");
|
||||
+ else if (new_state == DAEMON_IDLE && !startup_done) {
|
||||
sd_notify(0, "READY=1");
|
||||
startup_done = true;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,28 +0,0 @@
|
||||
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,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 10:57:22 +0200
|
||||
Subject: [PATCH] multipathd: send "RELOADING=1" to systemd on DAEMON_CONFIGURE
|
||||
state
|
||||
|
||||
The logic is as follows: child() sets DAEMON_IDLE status after
|
||||
DAEMON_CONFIGURE when reconfigure() has finished. The only other state change
|
||||
that can race with that is DAEMON_SHUTDOWN. Other state changes will wait for
|
||||
DAEMON_IDLE first (see set_config_state()). When DAEMON_CONFIGURE is entered,
|
||||
and we are not just starting up, send a "RELOADING=1" message to
|
||||
systemd. After that, we must send "READY=1" when we're done reloading. Also
|
||||
do that on startup, when DAEMON_IDLE is set for the first time.
|
||||
See sd_notify(3).
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index c264351c..e3f2328d 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -210,10 +210,11 @@ static void do_sd_notify(enum daemon_status old_state,
|
||||
|
||||
if (new_state == DAEMON_SHUTDOWN)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
- else if (new_state == DAEMON_IDLE && !startup_done) {
|
||||
+ else if (new_state == DAEMON_IDLE && old_state == DAEMON_CONFIGURE) {
|
||||
sd_notify(0, "READY=1");
|
||||
startup_done = true;
|
||||
- }
|
||||
+ } else if (new_state == DAEMON_CONFIGURE && startup_done)
|
||||
+ sd_notify(0, "RELOADING=1");
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,34 +0,0 @@
|
||||
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,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 12:44:59 +0200
|
||||
Subject: [PATCH] multipathd: use volatile qualifier for running_state
|
||||
|
||||
While we access running_state only under the config_lock,
|
||||
we sometimes do in a loop. Use the volatile qualifier to make
|
||||
sure compilers can't optimize away the loads.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index e3f2328d..d081b3e9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -126,7 +126,7 @@ int poll_dmevents = 0;
|
||||
int poll_dmevents = 1;
|
||||
#endif
|
||||
/* Don't access this variable without holding config_lock */
|
||||
-enum daemon_status running_state = DAEMON_INIT;
|
||||
+volatile enum daemon_status running_state = DAEMON_INIT;
|
||||
pid_t daemon_pid;
|
||||
pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t config_cond;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
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,72 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 12:46:36 +0200
|
||||
Subject: [PATCH] multipathd: generalize and fix wait_for_state_change_if()
|
||||
|
||||
It's unlikely but not impossible that other threads change the state
|
||||
while we're waiting, and if we grab the lock again, it's still not
|
||||
what we wanted. We need to continue waiting until either the condition
|
||||
is met, or time timeout expired.
|
||||
|
||||
Moreover, generalize this code so that it can also be used in
|
||||
set_config_state().
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 25 ++++++++++++++++++-------
|
||||
1 file changed, 18 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index d081b3e9..1fb0ee62 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -223,6 +223,23 @@ static void config_cleanup(__attribute__((unused)) void *arg)
|
||||
pthread_mutex_unlock(&config_lock);
|
||||
}
|
||||
|
||||
+#define __wait_for_state_change(condition, ms) \
|
||||
+ ({ \
|
||||
+ struct timespec tmo; \
|
||||
+ int rc = 0; \
|
||||
+ \
|
||||
+ if (condition) { \
|
||||
+ get_monotonic_time(&tmo); \
|
||||
+ tmo.tv_nsec += (ms) * 1000 * 1000; \
|
||||
+ normalize_timespec(&tmo); \
|
||||
+ do \
|
||||
+ rc = pthread_cond_timedwait( \
|
||||
+ &config_cond, &config_lock, &tmo); \
|
||||
+ while (rc == 0 && (condition)); \
|
||||
+ } \
|
||||
+ rc; \
|
||||
+ })
|
||||
+
|
||||
/*
|
||||
* If the current status is @oldstate, wait for at most @ms milliseconds
|
||||
* for the state to change, and return the new state, which may still be
|
||||
@@ -232,20 +249,14 @@ enum daemon_status wait_for_state_change_if(enum daemon_status oldstate,
|
||||
unsigned long ms)
|
||||
{
|
||||
enum daemon_status st;
|
||||
- struct timespec tmo;
|
||||
|
||||
if (oldstate == DAEMON_SHUTDOWN)
|
||||
return DAEMON_SHUTDOWN;
|
||||
|
||||
pthread_mutex_lock(&config_lock);
|
||||
pthread_cleanup_push(config_cleanup, NULL);
|
||||
+ __wait_for_state_change(running_state == oldstate, ms);
|
||||
st = running_state;
|
||||
- if (st == oldstate && clock_gettime(CLOCK_MONOTONIC, &tmo) == 0) {
|
||||
- tmo.tv_nsec += ms * 1000 * 1000;
|
||||
- normalize_timespec(&tmo);
|
||||
- (void)pthread_cond_timedwait(&config_cond, &config_lock, &tmo);
|
||||
- st = running_state;
|
||||
- }
|
||||
pthread_cleanup_pop(1);
|
||||
return st;
|
||||
}
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,29 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 12:48:55 +0200
|
||||
Subject: [PATCH] multipathd: set_config_state(): avoid code duplication
|
||||
|
||||
Use __post_config_state() and __wait_for_state_change(). This
|
||||
way __post_config_state() is the only place where running_state
|
||||
is ever changed, and we avoid code duplication.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 23 +++++------------------
|
||||
1 file changed, 5 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 1fb0ee62..39aea4ad 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -292,27 +292,14 @@ 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;
|
||||
- else if (running_state != DAEMON_IDLE) {
|
||||
- struct timespec ts;
|
||||
-
|
||||
- get_monotonic_time(&ts);
|
||||
- ts.tv_sec += 1;
|
||||
- rc = pthread_cond_timedwait(&config_cond,
|
||||
- &config_lock, &ts);
|
||||
- }
|
||||
- if (!rc && (running_state != DAEMON_SHUTDOWN)) {
|
||||
- running_state = state;
|
||||
- pthread_cond_broadcast(&config_cond);
|
||||
-#ifdef USE_SYSTEMD
|
||||
- do_sd_notify(old_state, state);
|
||||
-#endif
|
||||
- }
|
||||
+ else
|
||||
+ rc = __wait_for_state_change(
|
||||
+ running_state != DAEMON_IDLE, 1000);
|
||||
+ if (!rc)
|
||||
+ __post_config_state(state);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
return rc;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,83 +0,0 @@
|
||||
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
|
||||
|
61
0021-multipathd-cancel-threads-early-during-shutdown.patch
Normal file
61
0021-multipathd-cancel-threads-early-during-shutdown.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Fri, 4 Jan 2019 17:10:25 +0100
|
||||
Subject: [PATCH] multipathd: cancel threads early during shutdown
|
||||
|
||||
Cancel the other threads before taking vecs->lock. This avoids
|
||||
delays during shutdown caused e.g. by the checker thread holding
|
||||
the vecs lock.
|
||||
|
||||
Note: this makes it possible that cancelled threads leak memory,
|
||||
because they can now be cancelled before having released the vecs
|
||||
lock. I believe this is acceptable, as only threads are affected
|
||||
that are cancelled during multipathd shutdown.
|
||||
|
||||
Cc: Chongyun Wu <wu.chongyun@h3c.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 39aea4ad..d1f8cc1b 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -3073,23 +3073,24 @@ child (__attribute__((unused)) void *param)
|
||||
}
|
||||
}
|
||||
|
||||
- lock(&vecs->lock);
|
||||
+ pthread_cancel(check_thr);
|
||||
+ pthread_cancel(uevent_thr);
|
||||
+ pthread_cancel(uxlsnr_thr);
|
||||
+ pthread_cancel(uevq_thr);
|
||||
+ if (poll_dmevents)
|
||||
+ pthread_cancel(dmevent_thr);
|
||||
+
|
||||
conf = get_multipath_config();
|
||||
queue_without_daemon = conf->queue_without_daemon;
|
||||
put_multipath_config(conf);
|
||||
+
|
||||
+ lock(&vecs->lock);
|
||||
if (queue_without_daemon == QUE_NO_DAEMON_OFF)
|
||||
vector_foreach_slot(vecs->mpvec, mpp, i)
|
||||
dm_queue_if_no_path(mpp->alias, 0);
|
||||
remove_maps_and_stop_waiters(vecs);
|
||||
unlock(&vecs->lock);
|
||||
|
||||
- pthread_cancel(check_thr);
|
||||
- pthread_cancel(uevent_thr);
|
||||
- pthread_cancel(uxlsnr_thr);
|
||||
- pthread_cancel(uevq_thr);
|
||||
- if (poll_dmevents)
|
||||
- pthread_cancel(dmevent_thr);
|
||||
-
|
||||
pthread_join(check_thr, NULL);
|
||||
pthread_join(uevent_thr, NULL);
|
||||
pthread_join(uxlsnr_thr, NULL);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
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: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
Makefile | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index fec3b73b..8bcaba66 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -32,6 +32,10 @@ libmultipath libdmmp: libmpathcmd
|
||||
libmpathpersist multipath multipathd: libmultipath
|
||||
mpathpersist multipathd: libmpathpersist
|
||||
|
||||
+libmultipath/checkers.install \
|
||||
+ libmultipath/prioritizers.install \
|
||||
+ libmultipath/foreign.install: libmultipath.install
|
||||
+
|
||||
$(BUILDDIRS.clean):
|
||||
$(MAKE) -C ${@:.clean=} clean
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
165
0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch
Normal file
165
0022-multipath-tools-don-t-call-dm_lib_release-any-more.patch
Normal file
@ -0,0 +1,165 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 17:57:16 +0200
|
||||
Subject: [PATCH] multipath-tools: don't call dm_lib_release() any more
|
||||
|
||||
The purpose of dm_lib_release() is to release stacked device node
|
||||
operations in libdevmapper. This is functionality we don't need and
|
||||
use any more, as we rely on udev to set up device nodes and symlinks.
|
||||
|
||||
We always set DM_UDEV_DISABLE_LIBRARY_FALLBACK when we run dm tasks.
|
||||
In the standard CREATE and REMOVE cases, libdevmapper doesn't
|
||||
stack any operations if this flag is set. The only exceptions are
|
||||
|
||||
a) RESUME operations with DM_ADD_NODE_ON_RESUME set. This happens
|
||||
implicity when we create new maps
|
||||
b) RENAME operations
|
||||
|
||||
In both cases, we call dm_udev_wait() after the libdm operation, which
|
||||
calls update_devs() and thus has the same effect as dm_lib_release(),
|
||||
cleaning out stacked operations.
|
||||
|
||||
OTOH, dm_lib_releases() accesses static variables in libdevmapper, so
|
||||
calling it might be racy.
|
||||
|
||||
Drop the calls to dm_lib_release().
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/kpartx.c | 1 -
|
||||
libmpathpersist/mpath_persist.c | 1 -
|
||||
multipath/main.c | 1 -
|
||||
multipathd/cli_handlers.c | 2 --
|
||||
multipathd/main.c | 15 ++-------------
|
||||
5 files changed, 2 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
|
||||
index 4a0aae93..6a7933fa 100644
|
||||
--- a/kpartx/kpartx.c
|
||||
+++ b/kpartx/kpartx.c
|
||||
@@ -681,7 +681,6 @@ main(int argc, char **argv){
|
||||
}
|
||||
|
||||
end:
|
||||
- dm_lib_release();
|
||||
dm_lib_exit();
|
||||
|
||||
return r;
|
||||
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
||||
index 4b3f3e0d..cc4a088d 100644
|
||||
--- a/libmpathpersist/mpath_persist.c
|
||||
+++ b/libmpathpersist/mpath_persist.c
|
||||
@@ -56,7 +56,6 @@ mpath_lib_init (void)
|
||||
int
|
||||
mpath_lib_exit (struct config *conf)
|
||||
{
|
||||
- dm_lib_release();
|
||||
dm_lib_exit();
|
||||
cleanup_prio();
|
||||
cleanup_checkers();
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 9e920d89..dc4974b9 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -1063,7 +1063,6 @@ main (int argc, char *argv[])
|
||||
condlog(3, "restart multipath configuration process");
|
||||
|
||||
out:
|
||||
- dm_lib_release();
|
||||
dm_lib_exit();
|
||||
|
||||
cleanup_foreign();
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index 235e2a2e..54635738 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -860,7 +860,6 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
|
||||
!= CP_OK)
|
||||
condlog(2, "%s: coalesce_paths failed",
|
||||
param);
|
||||
- dm_lib_release();
|
||||
FREE(refwwid);
|
||||
}
|
||||
} /*we attempt to create device only once*/
|
||||
@@ -1032,7 +1031,6 @@ cli_resize(void *v, char **reply, int *len, void *data)
|
||||
if (resize_map(mpp, size, vecs) != 0)
|
||||
return 1;
|
||||
|
||||
- dm_lib_release();
|
||||
if (setup_multipath(vecs, mpp) != 0)
|
||||
return 1;
|
||||
sync_map_state(mpp);
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index d1f8cc1b..5cc34357 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -510,7 +510,6 @@ retry:
|
||||
sleep(1);
|
||||
goto retry;
|
||||
}
|
||||
- dm_lib_release();
|
||||
|
||||
fail:
|
||||
if (new_map && (retries < 0 || wait_for_events(mpp, vecs))) {
|
||||
@@ -611,10 +610,8 @@ coalesce_maps(struct vectors *vecs, vector nmpv)
|
||||
vector_del_slot(ompv, i);
|
||||
i--;
|
||||
}
|
||||
- else {
|
||||
- dm_lib_release();
|
||||
+ else
|
||||
condlog(2, "%s devmap removed", ompp->alias);
|
||||
- }
|
||||
} else if (reassign_maps) {
|
||||
condlog(3, "%s: Reassign existing device-mapper"
|
||||
" devices", ompp->alias);
|
||||
@@ -660,10 +657,8 @@ flush_map(struct multipath * mpp, struct vectors * vecs, int nopaths)
|
||||
}
|
||||
return r;
|
||||
}
|
||||
- else {
|
||||
- dm_lib_release();
|
||||
+ else
|
||||
condlog(2, "%s: map flushed", mpp->alias);
|
||||
- }
|
||||
|
||||
orphan_paths(vecs->pathvec, mpp, "map flushed");
|
||||
remove_map_and_stop_waiter(mpp, vecs);
|
||||
@@ -1080,7 +1075,6 @@ rescan:
|
||||
else
|
||||
goto fail_map;
|
||||
}
|
||||
- dm_lib_release();
|
||||
|
||||
if ((mpp->action == ACT_CREATE ||
|
||||
(mpp->action == ACT_NOTHING && start_waiter && !mpp->waiter)) &&
|
||||
@@ -1947,8 +1941,6 @@ int reload_and_sync_map(struct multipath *mpp,
|
||||
{
|
||||
if (reload_map(vecs, mpp, refresh, 1))
|
||||
return 1;
|
||||
-
|
||||
- dm_lib_release();
|
||||
if (setup_multipath(vecs, mpp) != 0)
|
||||
return 2;
|
||||
sync_map_state(mpp);
|
||||
@@ -2631,8 +2623,6 @@ configure (struct vectors * vecs)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- dm_lib_release();
|
||||
-
|
||||
if (should_exit())
|
||||
goto fail;
|
||||
|
||||
@@ -3115,7 +3105,6 @@ child (__attribute__((unused)) void *param)
|
||||
if (poll_dmevents)
|
||||
cleanup_dmevent_waiter();
|
||||
|
||||
- dm_lib_release();
|
||||
dm_lib_exit();
|
||||
|
||||
/* We're done here */
|
||||
--
|
||||
2.17.2
|
||||
|
506
0023-libmultipath-devmapper-refactor-libdm-version-determ.patch
Normal file
506
0023-libmultipath-devmapper-refactor-libdm-version-determ.patch
Normal file
@ -0,0 +1,506 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 23:12:15 +0200
|
||||
Subject: [PATCH] libmultipath: devmapper: refactor libdm version determination
|
||||
|
||||
As one step towards bundling all possibly racy libdm init calls into a single
|
||||
function, split the code for determining and checking versions of
|
||||
libdm and kernel components. Provide a generic helper
|
||||
libmp_get_version() that makes sure the versions are "lazily" initialized.
|
||||
|
||||
External callers may use dm_prereq(), like before.
|
||||
Minor API change: dm_prereq() does not nullify the argument any more
|
||||
if an error is encountered.
|
||||
|
||||
Remove the conf->version field, which isn't needed any more after this
|
||||
change. This makes it necessary to fixup the hwtable test. Also, it
|
||||
represents an incompatible ABI change as offsets in "struct config" are
|
||||
changed, and two symbols removed. Bump the ABI major version to 2.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.h | 1 -
|
||||
libmultipath/devmapper.c | 162 ++++++++++++++++++++----------
|
||||
libmultipath/devmapper.h | 10 +-
|
||||
libmultipath/libmultipath.version | 5 +-
|
||||
libmultipath/propsel.c | 10 +-
|
||||
multipathd/dmevents.c | 2 +-
|
||||
multipathd/main.c | 1 -
|
||||
tests/Makefile | 2 +-
|
||||
tests/hwtable.c | 3 -
|
||||
tests/test-lib.c | 13 +++
|
||||
10 files changed, 141 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 290aea58..7af19844 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -192,7 +192,6 @@ struct config {
|
||||
int find_multipaths_timeout;
|
||||
int marginal_pathgroups;
|
||||
int skip_delegate;
|
||||
- unsigned int version[3];
|
||||
unsigned int sequence_nr;
|
||||
|
||||
char * multipath_dir;
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 0bc1d16e..3e36129b 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "sysfs.h"
|
||||
#include "config.h"
|
||||
#include "wwids.h"
|
||||
+#include "version.h"
|
||||
|
||||
#include "log_pthread.h"
|
||||
#include <sys/types.h>
|
||||
@@ -34,7 +35,13 @@
|
||||
#define MAX_WAIT 5
|
||||
#define LOOPS_PER_SEC 5
|
||||
|
||||
+#define INVALID_VERSION ~0U
|
||||
+static unsigned int dm_library_version[3] = { INVALID_VERSION, };
|
||||
+static unsigned int dm_kernel_version[3] = { INVALID_VERSION, };
|
||||
+static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, };
|
||||
+
|
||||
static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
|
||||
+static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
static int dm_conf_verbosity;
|
||||
|
||||
@@ -102,7 +109,7 @@ dm_write_log (int level, const char *file, int line, const char *f, ...)
|
||||
return;
|
||||
}
|
||||
|
||||
-void dm_init(int v)
|
||||
+static void dm_init(int v)
|
||||
{
|
||||
/*
|
||||
* This maps libdm's standard loglevel _LOG_WARN (= 4), which is rather
|
||||
@@ -112,61 +119,68 @@ void dm_init(int v)
|
||||
dm_log_init(&dm_write_log);
|
||||
}
|
||||
|
||||
+static void init_dm_library_version(void)
|
||||
+{
|
||||
+ char version[64];
|
||||
+ unsigned int v[3];
|
||||
+
|
||||
+ dm_get_library_version(version, sizeof(version));
|
||||
+ if (sscanf(version, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) {
|
||||
+ condlog(0, "invalid libdevmapper version %s", version);
|
||||
+ return;
|
||||
+ }
|
||||
+ memcpy(dm_library_version, v, sizeof(dm_library_version));
|
||||
+ condlog(3, "libdevmapper version %u.%.2u.%.2u",
|
||||
+ dm_library_version[0], dm_library_version[1],
|
||||
+ dm_library_version[2]);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
dm_lib_prereq (void)
|
||||
{
|
||||
- char version[64];
|
||||
- int v[3];
|
||||
+
|
||||
#if defined(LIBDM_API_HOLD_CONTROL)
|
||||
- int minv[3] = {1, 2, 111};
|
||||
+ unsigned int minv[3] = {1, 2, 111};
|
||||
#elif defined(LIBDM_API_GET_ERRNO)
|
||||
- int minv[3] = {1, 2, 99};
|
||||
+ unsigned int minv[3] = {1, 2, 99};
|
||||
#elif defined(LIBDM_API_DEFERRED)
|
||||
- int minv[3] = {1, 2, 89};
|
||||
+ unsigned int minv[3] = {1, 2, 89};
|
||||
#elif defined(DM_SUBSYSTEM_UDEV_FLAG0)
|
||||
- int minv[3] = {1, 2, 82};
|
||||
+ unsigned int minv[3] = {1, 2, 82};
|
||||
#elif defined(LIBDM_API_COOKIE)
|
||||
- int minv[3] = {1, 2, 38};
|
||||
+ unsigned int minv[3] = {1, 2, 38};
|
||||
#else
|
||||
- int minv[3] = {1, 2, 8};
|
||||
+ unsigned int minv[3] = {1, 2, 8};
|
||||
#endif
|
||||
|
||||
- dm_get_library_version(version, sizeof(version));
|
||||
- condlog(3, "libdevmapper version %s", version);
|
||||
- if (sscanf(version, "%d.%d.%d ", &v[0], &v[1], &v[2]) != 3) {
|
||||
- condlog(0, "invalid libdevmapper version %s", version);
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- if VERSION_GE(v, minv)
|
||||
+ if (VERSION_GE(dm_library_version, minv))
|
||||
return 0;
|
||||
- condlog(0, "libdevmapper version must be >= %d.%.2d.%.2d",
|
||||
+ condlog(0, "libdevmapper version must be >= %u.%.2u.%.2u",
|
||||
minv[0], minv[1], minv[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
-int
|
||||
-dm_drv_version(unsigned int *v)
|
||||
+static void init_dm_drv_version(void)
|
||||
{
|
||||
char buff[64];
|
||||
-
|
||||
- v[0] = 0;
|
||||
- v[1] = 0;
|
||||
- v[2] = 0;
|
||||
+ unsigned int v[3];
|
||||
|
||||
if (!dm_driver_version(buff, sizeof(buff))) {
|
||||
condlog(0, "cannot get kernel dm version");
|
||||
- return 1;
|
||||
+ return;
|
||||
}
|
||||
if (sscanf(buff, "%u.%u.%u ", &v[0], &v[1], &v[2]) != 3) {
|
||||
condlog(0, "invalid kernel dm version '%s'", buff);
|
||||
- return 1;
|
||||
+ return;
|
||||
}
|
||||
- return 0;
|
||||
+ memcpy(dm_kernel_version, v, sizeof(dm_library_version));
|
||||
+ condlog(3, "kernel device mapper v%u.%u.%u",
|
||||
+ dm_kernel_version[0],
|
||||
+ dm_kernel_version[1],
|
||||
+ dm_kernel_version[2]);
|
||||
}
|
||||
|
||||
-int
|
||||
-dm_tgt_version (unsigned int * version, char * str)
|
||||
+static int dm_tgt_version (unsigned int *version, char *str)
|
||||
{
|
||||
int r = 2;
|
||||
struct dm_task *dmt;
|
||||
@@ -174,10 +188,11 @@ dm_tgt_version (unsigned int * version, char * str)
|
||||
struct dm_versions *last_target;
|
||||
unsigned int *v;
|
||||
|
||||
- version[0] = 0;
|
||||
- version[1] = 0;
|
||||
- version[2] = 0;
|
||||
-
|
||||
+ /*
|
||||
+ * We have to call dm_task_create() and not libmp_dm_task_create()
|
||||
+ * here to avoid a recursive invocation of
|
||||
+ * pthread_once(&dm_initialized), which would cause a deadlock.
|
||||
+ */
|
||||
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
|
||||
return 1;
|
||||
|
||||
@@ -213,26 +228,25 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
-static int
|
||||
-dm_tgt_prereq (unsigned int *ver)
|
||||
+static void init_dm_mpath_version(void)
|
||||
{
|
||||
- unsigned int minv[3] = {1, 0, 3};
|
||||
- unsigned int version[3] = {0, 0, 0};
|
||||
- unsigned int * v = version;
|
||||
-
|
||||
- if (dm_tgt_version(v, TGT_MPATH)) {
|
||||
- /* in doubt return not capable */
|
||||
- return 1;
|
||||
- }
|
||||
+ if (!dm_tgt_version(dm_mpath_target_version, TGT_MPATH))
|
||||
+ condlog(3, "DM multipath kernel driver v%u.%u.%u",
|
||||
+ dm_mpath_target_version[0],
|
||||
+ dm_mpath_target_version[1],
|
||||
+ dm_mpath_target_version[2]);
|
||||
+}
|
||||
|
||||
- /* test request based multipath capability */
|
||||
- condlog(3, "DM multipath kernel driver v%u.%u.%u",
|
||||
- v[0], v[1], v[2]);
|
||||
+static int dm_tgt_prereq (unsigned int *ver)
|
||||
+{
|
||||
+ unsigned int minv[3] = {1, 0, 3};
|
||||
|
||||
- if (VERSION_GE(v, minv)) {
|
||||
- ver[0] = v[0];
|
||||
- ver[1] = v[1];
|
||||
- ver[2] = v[2];
|
||||
+ if (VERSION_GE(dm_mpath_target_version, minv)) {
|
||||
+ if (ver) {
|
||||
+ ver[0] = dm_mpath_target_version[0];
|
||||
+ ver[1] = dm_mpath_target_version[1];
|
||||
+ ver[2] = dm_mpath_target_version[2];
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,13 +255,60 @@ dm_tgt_prereq (unsigned int *ver)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void _init_versions(void)
|
||||
+{
|
||||
+ dlog(logsink, 3, VERSION_STRING);
|
||||
+ init_dm_library_version();
|
||||
+ init_dm_drv_version();
|
||||
+ init_dm_mpath_version();
|
||||
+}
|
||||
+
|
||||
+static int init_versions(void) {
|
||||
+ pthread_once(&versions_initialized, _init_versions);
|
||||
+ return (dm_library_version[0] == INVALID_VERSION ||
|
||||
+ dm_kernel_version[0] == INVALID_VERSION ||
|
||||
+ dm_mpath_target_version[0] == INVALID_VERSION);
|
||||
+}
|
||||
+
|
||||
int dm_prereq(unsigned int *v)
|
||||
{
|
||||
+ if (init_versions())
|
||||
+ return 1;
|
||||
if (dm_lib_prereq())
|
||||
return 1;
|
||||
return dm_tgt_prereq(v);
|
||||
}
|
||||
|
||||
+int libmp_get_version(int which, unsigned int version[3])
|
||||
+{
|
||||
+ unsigned int *src_version;
|
||||
+
|
||||
+ init_versions();
|
||||
+ switch (which) {
|
||||
+ case DM_LIBRARY_VERSION:
|
||||
+ src_version = dm_library_version;
|
||||
+ break;
|
||||
+ case DM_KERNEL_VERSION:
|
||||
+ src_version = dm_kernel_version;
|
||||
+ break;
|
||||
+ case DM_MPATH_TARGET_VERSION:
|
||||
+ src_version = dm_mpath_target_version;
|
||||
+ break;
|
||||
+ case MULTIPATH_VERSION:
|
||||
+ version[0] = (VERSION_CODE >> 16) & 0xff;
|
||||
+ version[1] = (VERSION_CODE >> 8) & 0xff;
|
||||
+ version[2] = VERSION_CODE & 0xff;
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ condlog(0, "%s: invalid value for 'which'", __func__);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (src_version[0] == INVALID_VERSION)
|
||||
+ return 1;
|
||||
+ memcpy(version, src_version, 3 * sizeof(*version));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int libmp_dm_udev_sync = 0;
|
||||
|
||||
void libmp_udev_set_sync_support(int on)
|
||||
@@ -265,7 +326,6 @@ static void libmp_dm_init(void)
|
||||
exit(1);
|
||||
conf = get_multipath_config();
|
||||
verbosity = conf->verbosity;
|
||||
- memcpy(conf->version, version, sizeof(version));
|
||||
put_multipath_config(conf);
|
||||
dm_init(verbosity);
|
||||
#ifdef LIBDM_API_HOLD_CONTROL
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index f469c98a..a0bcd137 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -33,13 +33,10 @@ enum {
|
||||
DMP_NOT_FOUND,
|
||||
};
|
||||
|
||||
-void dm_init(int verbosity);
|
||||
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);
|
||||
-int dm_tgt_version (unsigned int * version, char * str);
|
||||
int dm_simplecmd_flush (int, const char *, uint16_t);
|
||||
int dm_simplecmd_noflush (int, const char *, uint16_t);
|
||||
int dm_addmap_create (struct multipath *mpp, char *params);
|
||||
@@ -89,6 +86,13 @@ struct multipath *dm_get_multipath(const char *name);
|
||||
#include <errno.h>
|
||||
#define dm_task_get_errno(x) errno
|
||||
#endif
|
||||
+enum {
|
||||
+ DM_LIBRARY_VERSION,
|
||||
+ DM_KERNEL_VERSION,
|
||||
+ DM_MPATH_TARGET_VERSION,
|
||||
+ MULTIPATH_VERSION
|
||||
+};
|
||||
+int libmp_get_version(int which, unsigned int version[3]);
|
||||
|
||||
#define dm_log_error(lvl, cmd, dmt) \
|
||||
condlog(lvl, "%s: libdm task=%d error: %s", __func__, \
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index a6bf8218..ab5bb0ad 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -31,7 +31,7 @@
|
||||
* The new version inherits the previous ones.
|
||||
*/
|
||||
|
||||
-LIBMULTIPATH_1.0.0 {
|
||||
+LIBMULTIPATH_2.0.0 {
|
||||
global:
|
||||
/* symbols referenced by multipath and multipathd */
|
||||
add_foreign;
|
||||
@@ -65,7 +65,6 @@ global:
|
||||
disassemble_status;
|
||||
dlog;
|
||||
dm_cancel_deferred_remove;
|
||||
- dm_drv_version;
|
||||
dm_enablegroup;
|
||||
dm_fail_path;
|
||||
_dm_flush_map;
|
||||
@@ -87,7 +86,6 @@ global:
|
||||
dm_reinstate_path;
|
||||
dm_simplecmd_noflush;
|
||||
dm_switchgroup;
|
||||
- dm_tgt_version;
|
||||
domap;
|
||||
ensure_directories_exist;
|
||||
extract_hwe_from_path;
|
||||
@@ -128,6 +126,7 @@ global:
|
||||
is_path_valid;
|
||||
is_quote;
|
||||
libmp_dm_task_create;
|
||||
+ libmp_get_version;
|
||||
libmp_udev_set_sync_support;
|
||||
load_config;
|
||||
log_thread_reset;
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 40201344..3f2c2cfa 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -735,9 +735,10 @@ out:
|
||||
|
||||
int select_minio(struct config *conf, struct multipath *mp)
|
||||
{
|
||||
- unsigned int minv_dmrq[3] = {1, 1, 0};
|
||||
+ unsigned int minv_dmrq[3] = {1, 1, 0}, version[3];
|
||||
|
||||
- if (VERSION_GE(conf->version, minv_dmrq))
|
||||
+ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version)
|
||||
+ && VERSION_GE(version, minv_dmrq))
|
||||
return select_minio_rq(conf, mp);
|
||||
else
|
||||
return select_minio_bio(conf, mp);
|
||||
@@ -820,9 +821,10 @@ out:
|
||||
int select_retain_hwhandler(struct config *conf, struct multipath *mp)
|
||||
{
|
||||
const char *origin;
|
||||
- unsigned int minv_dm_retain[3] = {1, 5, 0};
|
||||
+ unsigned int minv_dm_retain[3] = {1, 5, 0}, version[3];
|
||||
|
||||
- if (!VERSION_GE(conf->version, minv_dm_retain)) {
|
||||
+ if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) &&
|
||||
+ !VERSION_GE(version, minv_dm_retain)) {
|
||||
mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
|
||||
origin = "(setting: WARNING, requires kernel dm-mpath version >= 1.5.0)";
|
||||
goto out;
|
||||
diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c
|
||||
index 5f2d210d..fc97c8a2 100644
|
||||
--- a/multipathd/dmevents.c
|
||||
+++ b/multipathd/dmevents.c
|
||||
@@ -60,7 +60,7 @@ int dmevent_poll_supported(void)
|
||||
{
|
||||
unsigned int v[3];
|
||||
|
||||
- if (dm_drv_version(v))
|
||||
+ if (libmp_get_version(DM_KERNEL_VERSION, v))
|
||||
return 0;
|
||||
|
||||
if (VERSION_GE(v, DM_VERSION_FOR_ARM_POLL))
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 5cc34357..00b66ba4 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2709,7 +2709,6 @@ reconfigure (struct vectors * vecs)
|
||||
/* Re-read any timezone changes */
|
||||
tzset();
|
||||
|
||||
- dm_tgt_version(conf->version, TGT_MPATH);
|
||||
if (verbosity)
|
||||
conf->verbosity = verbosity;
|
||||
if (bindings_read_only)
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index 9658c9fd..78777bec 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -43,7 +43,7 @@ endif
|
||||
dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu
|
||||
hwtable-test_TESTDEPS := test-lib.o
|
||||
hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \
|
||||
- ../libmultipath/structs.o
|
||||
+ ../libmultipath/structs.o ../libmultipath/propsel.o
|
||||
hwtable-test_LIBDEPS := -ludev -lpthread -ldl
|
||||
blacklist-test_TESTDEPS := test-log.o
|
||||
blacklist-test_OBJDEPS := ../libmultipath/blacklist.o
|
||||
diff --git a/tests/hwtable.c b/tests/hwtable.c
|
||||
index 12660da2..57f832b7 100644
|
||||
--- a/tests/hwtable.c
|
||||
+++ b/tests/hwtable.c
|
||||
@@ -30,8 +30,6 @@
|
||||
#define N_CONF_FILES 2
|
||||
|
||||
static const char tmplate[] = "/tmp/hwtable-XXXXXX";
|
||||
-/* pretend new dm, use minio_rq */
|
||||
-static const unsigned int dm_tgt_version[3] = { 1, 1, 1 };
|
||||
|
||||
struct key_value {
|
||||
const char *key;
|
||||
@@ -360,7 +358,6 @@ static void write_device(FILE *ff, int nkv, const struct key_value *kv)
|
||||
assert_ptr_not_equal(__cf, NULL); \
|
||||
assert_ptr_not_equal(__cf->hwtable, NULL); \
|
||||
__cf->verbosity = VERBOSITY; \
|
||||
- memcpy(&__cf->version, dm_tgt_version, sizeof(__cf->version)); \
|
||||
__cf; })
|
||||
|
||||
#define FREE_CONFIG(conf) do { \
|
||||
diff --git a/tests/test-lib.c b/tests/test-lib.c
|
||||
index b7c09cc2..e7663f9a 100644
|
||||
--- a/tests/test-lib.c
|
||||
+++ b/tests/test-lib.c
|
||||
@@ -56,6 +56,15 @@ int __wrap_execute_program(char *path, char *value, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int __wrap_libmp_get_version(int which, unsigned int version[3])
|
||||
+{
|
||||
+ unsigned int *vers = mock_ptr_type(unsigned int *);
|
||||
+
|
||||
+ condlog(4, "%s: %d", __func__, which);
|
||||
+ memcpy(version, vers, 3 * sizeof(unsigned int));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
struct udev_list_entry
|
||||
*__wrap_udev_device_get_properties_list_entry(struct udev_device *ud)
|
||||
{
|
||||
@@ -339,6 +348,8 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp)
|
||||
struct multipath *mp;
|
||||
struct config *conf;
|
||||
struct mocked_path mop;
|
||||
+ /* pretend new dm, use minio_rq, */
|
||||
+ static const unsigned int fake_dm_tgt_version[3] = { 1, 1, 1 };
|
||||
|
||||
mocked_path_from_path(&mop, pp);
|
||||
/* pathinfo() call in adopt_paths */
|
||||
@@ -351,7 +362,9 @@ struct multipath *__mock_multipath(struct vectors *vecs, struct path *pp)
|
||||
conf = get_multipath_config();
|
||||
select_pgpolicy(conf, mp);
|
||||
select_no_path_retry(conf, mp);
|
||||
+ will_return(__wrap_libmp_get_version, fake_dm_tgt_version);
|
||||
select_retain_hwhandler(conf, mp);
|
||||
+ will_return(__wrap_libmp_get_version, fake_dm_tgt_version);
|
||||
select_minio(conf, mp);
|
||||
put_multipath_config(conf);
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,89 +0,0 @@
|
||||
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
|
||||
|
@ -1,108 +0,0 @@
|
||||
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
|
||||
|
437
0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch
Normal file
437
0024-libmultipath-protect-racy-libdevmapper-calls-with-a-.patch
Normal file
@ -0,0 +1,437 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 15 Sep 2020 23:38:48 +0200
|
||||
Subject: [PATCH] libmultipath: protect racy libdevmapper calls with a mutex
|
||||
|
||||
dm_udev_wait() and dm_task_run() may access global / static state
|
||||
in libdevmapper. They need to be protected by a lock in in our
|
||||
multithreaded library.
|
||||
|
||||
The modified call sequence requires fixing the dmevents test:
|
||||
devmapper.c must be added to dmevents-test_OBJDEPS to catch calls
|
||||
to dm_task_run(). Also, the call to dmevent_poll_supported() in
|
||||
setup() will cause init_versions() to be called, which requires
|
||||
bypassing the wrappers in the test setup phase.
|
||||
|
||||
Cc: lixiaokeng@huawei.com
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/devmapper.c | 73 +++++++++++++++++++------------
|
||||
libmultipath/devmapper.h | 2 +
|
||||
libmultipath/libmultipath.version | 6 +++
|
||||
libmultipath/util.c | 5 +++
|
||||
libmultipath/util.h | 1 +
|
||||
multipathd/dmevents.c | 2 +-
|
||||
multipathd/waiter.c | 2 +-
|
||||
tests/Makefile | 1 +
|
||||
tests/dmevents.c | 12 +++++
|
||||
9 files changed, 75 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 3e36129b..4eb6f539 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -42,6 +42,7 @@ static unsigned int dm_mpath_target_version[3] = { INVALID_VERSION, };
|
||||
|
||||
static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
|
||||
static pthread_once_t versions_initialized = PTHREAD_ONCE_INIT;
|
||||
+static pthread_mutex_t libmp_dm_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int dm_conf_verbosity;
|
||||
|
||||
@@ -59,16 +60,34 @@ static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-void dm_udev_wait(unsigned int c)
|
||||
+static void libmp_udev_wait(unsigned int c)
|
||||
{
|
||||
}
|
||||
|
||||
-void dm_udev_set_sync_support(int c)
|
||||
+static void dm_udev_set_sync_support(int c)
|
||||
{
|
||||
}
|
||||
-
|
||||
+#else
|
||||
+static void libmp_udev_wait(unsigned int c)
|
||||
+{
|
||||
+ pthread_mutex_lock(&libmp_dm_lock);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock);
|
||||
+ dm_udev_wait(c);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+}
|
||||
#endif
|
||||
|
||||
+int libmp_dm_task_run(struct dm_task *dmt)
|
||||
+{
|
||||
+ int r;
|
||||
+
|
||||
+ pthread_mutex_lock(&libmp_dm_lock);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &libmp_dm_lock);
|
||||
+ r = dm_task_run(dmt);
|
||||
+ pthread_cleanup_pop(1);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
__attribute__((format(printf, 4, 5))) static void
|
||||
dm_write_log (int level, const char *file, int line, const char *f, ...)
|
||||
{
|
||||
@@ -198,7 +217,7 @@ static int dm_tgt_version (unsigned int *version, char *str)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(2, DM_DEVICE_LIST_VERSIONS, dmt);
|
||||
condlog(0, "Can not communicate with kernel DM");
|
||||
goto out;
|
||||
@@ -382,12 +401,12 @@ dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t
|
||||
DM_UDEV_DISABLE_LIBRARY_FALLBACK | udev_flags))
|
||||
goto out;
|
||||
|
||||
- r = dm_task_run (dmt);
|
||||
+ r = libmp_dm_task_run (dmt);
|
||||
if (!r)
|
||||
dm_log_error(2, task, dmt);
|
||||
|
||||
if (udev_wait_flag)
|
||||
- dm_udev_wait(cookie);
|
||||
+ libmp_udev_wait(cookie);
|
||||
out:
|
||||
dm_task_destroy (dmt);
|
||||
return r;
|
||||
@@ -474,12 +493,12 @@ dm_addmap (int task, const char *target, struct multipath *mpp,
|
||||
!dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto freeout;
|
||||
|
||||
- r = dm_task_run (dmt);
|
||||
+ r = libmp_dm_task_run (dmt);
|
||||
if (!r)
|
||||
dm_log_error(2, task, dmt);
|
||||
|
||||
if (task == DM_DEVICE_CREATE)
|
||||
- dm_udev_wait(cookie);
|
||||
+ libmp_udev_wait(cookie);
|
||||
freeout:
|
||||
if (prefixed_uuid)
|
||||
FREE(prefixed_uuid);
|
||||
@@ -589,7 +608,7 @@ do_get_info(const char *name, struct dm_info *info)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_INFO, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -630,7 +649,7 @@ int dm_get_map(const char *name, unsigned long long *size, char *outparams)
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
errno = 0;
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_TABLE, dmt);
|
||||
if (dm_task_get_errno(dmt) == ENXIO)
|
||||
r = DMP_NOT_FOUND;
|
||||
@@ -672,7 +691,7 @@ dm_get_prefixed_uuid(const char *name, char *uuid, int uuid_len)
|
||||
if (!dm_task_set_name (dmt, name))
|
||||
goto uuidout;
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_INFO, dmt);
|
||||
goto uuidout;
|
||||
}
|
||||
@@ -743,7 +762,7 @@ int dm_get_status(const char *name, char *outstatus)
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
errno = 0;
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_STATUS, dmt);
|
||||
if (dm_task_get_errno(dmt) == ENXIO)
|
||||
r = DMP_NOT_FOUND;
|
||||
@@ -796,7 +815,7 @@ int dm_type(const char *name, char *type)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_TABLE, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -840,7 +859,7 @@ int dm_is_mpath(const char *name)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_TABLE, dmt);
|
||||
goto out_task;
|
||||
}
|
||||
@@ -904,7 +923,7 @@ dm_map_present_by_uuid(const char *uuid)
|
||||
if (!dm_task_set_uuid(dmt, prefixed_uuid))
|
||||
goto out_task;
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_INFO, dmt);
|
||||
goto out_task;
|
||||
}
|
||||
@@ -950,7 +969,7 @@ dm_get_opencount (const char * mapname)
|
||||
if (!dm_task_set_name(dmt, mapname))
|
||||
goto out;
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_INFO, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1110,7 +1129,7 @@ int dm_flush_maps (int need_suspend, int retries)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run (dmt)) {
|
||||
+ if (!libmp_dm_task_run (dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_LIST, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1156,7 +1175,7 @@ dm_message(const char * mapname, char * message)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(2, DM_DEVICE_TARGET_MSG, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1276,7 +1295,7 @@ dm_get_maps (vector mp)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_LIST, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1361,7 +1380,7 @@ dm_mapname(int major, int minor)
|
||||
* daemon uev_trigger -> uev_add_map
|
||||
*/
|
||||
while (--loop) {
|
||||
- r = dm_task_run(dmt);
|
||||
+ r = libmp_dm_task_run(dmt);
|
||||
|
||||
if (r)
|
||||
break;
|
||||
@@ -1406,7 +1425,7 @@ do_foreach_partmaps (const char * mapname,
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_LIST, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1641,11 +1660,11 @@ dm_rename (const char * old, char * new, char *delim, int skip_kpartx)
|
||||
|
||||
if (!dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
- r = dm_task_run(dmt);
|
||||
+ r = libmp_dm_task_run(dmt);
|
||||
if (!r)
|
||||
dm_log_error(2, DM_DEVICE_RENAME, dmt);
|
||||
|
||||
- dm_udev_wait(cookie);
|
||||
+ libmp_udev_wait(cookie);
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
@@ -1687,7 +1706,7 @@ int dm_reassign_table(const char *name, char *old, char *new)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_TABLE, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1720,7 +1739,7 @@ int dm_reassign_table(const char *name, char *old, char *new)
|
||||
if (modified) {
|
||||
dm_task_no_open_count(reload_dmt);
|
||||
|
||||
- if (!dm_task_run(reload_dmt)) {
|
||||
+ if (!libmp_dm_task_run(reload_dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_RELOAD, reload_dmt);
|
||||
condlog(3, "%s: failed to reassign targets", name);
|
||||
goto out_reload;
|
||||
@@ -1767,7 +1786,7 @@ int dm_reassign(const char *mapname)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_DEPS, dmt);
|
||||
goto out;
|
||||
}
|
||||
@@ -1835,7 +1854,7 @@ int dm_setgeometry(struct multipath *mpp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- r = dm_task_run(dmt);
|
||||
+ r = libmp_dm_task_run(dmt);
|
||||
if (!r)
|
||||
dm_log_error(3, DM_DEVICE_SET_GEOMETRY, dmt);
|
||||
out:
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index a0bcd137..fa6b3c53 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -93,6 +93,8 @@ enum {
|
||||
MULTIPATH_VERSION
|
||||
};
|
||||
int libmp_get_version(int which, unsigned int version[3]);
|
||||
+struct dm_task;
|
||||
+int libmp_dm_task_run(struct dm_task *dmt);
|
||||
|
||||
#define dm_log_error(lvl, cmd, dmt) \
|
||||
condlog(lvl, "%s: libdm task=%d error: %s", __func__, \
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index ab5bb0ad..97acdbb2 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -245,3 +245,9 @@ global:
|
||||
local:
|
||||
*;
|
||||
};
|
||||
+
|
||||
+LIBMULTIPATH_2.1.0 {
|
||||
+global:
|
||||
+ libmp_dm_task_run;
|
||||
+ cleanup_mutex;
|
||||
+} LIBMULTIPATH_2.0.0;
|
||||
diff --git a/libmultipath/util.c b/libmultipath/util.c
|
||||
index 1f977792..0e37f3ff 100644
|
||||
--- a/libmultipath/util.c
|
||||
+++ b/libmultipath/util.c
|
||||
@@ -424,6 +424,11 @@ void cleanup_free_ptr(void *arg)
|
||||
free(*p);
|
||||
}
|
||||
|
||||
+void cleanup_mutex(void *arg)
|
||||
+{
|
||||
+ pthread_mutex_unlock(arg);
|
||||
+}
|
||||
+
|
||||
struct bitfield *alloc_bitfield(unsigned int maxbit)
|
||||
{
|
||||
unsigned int n;
|
||||
diff --git a/libmultipath/util.h b/libmultipath/util.h
|
||||
index ac19473e..e9b48f9f 100644
|
||||
--- a/libmultipath/util.h
|
||||
+++ b/libmultipath/util.h
|
||||
@@ -49,6 +49,7 @@ int should_exit(void);
|
||||
|
||||
void close_fd(void *arg);
|
||||
void cleanup_free_ptr(void *arg);
|
||||
+void cleanup_mutex(void *arg);
|
||||
|
||||
struct scandir_result {
|
||||
struct dirent **di;
|
||||
diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c
|
||||
index fc97c8a2..b561cbfd 100644
|
||||
--- a/multipathd/dmevents.c
|
||||
+++ b/multipathd/dmevents.c
|
||||
@@ -156,7 +156,7 @@ static int dm_get_events(void)
|
||||
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
- if (!dm_task_run(dmt)) {
|
||||
+ if (!libmp_dm_task_run(dmt)) {
|
||||
dm_log_error(3, DM_DEVICE_LIST, dmt);
|
||||
goto fail;
|
||||
}
|
||||
diff --git a/multipathd/waiter.c b/multipathd/waiter.c
|
||||
index 3bc69807..bbe6c2a1 100644
|
||||
--- a/multipathd/waiter.c
|
||||
+++ b/multipathd/waiter.c
|
||||
@@ -118,7 +118,7 @@ static int waiteventloop (struct event_thread *waiter)
|
||||
pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
|
||||
|
||||
pthread_testcancel();
|
||||
- r = dm_task_run(waiter->dmt);
|
||||
+ r = libmp_dm_task_run(waiter->dmt);
|
||||
if (!r)
|
||||
dm_log_error(2, DM_DEVICE_WAITEVENT, waiter->dmt);
|
||||
pthread_testcancel();
|
||||
diff --git a/tests/Makefile b/tests/Makefile
|
||||
index 78777bec..908407ea 100644
|
||||
--- a/tests/Makefile
|
||||
+++ b/tests/Makefile
|
||||
@@ -40,6 +40,7 @@ endif
|
||||
# linker input file).
|
||||
# XYZ-test_LIBDEPS: Additional libs to link for this test
|
||||
|
||||
+dmevents-test_OBJDEPS = ../libmultipath/devmapper.o
|
||||
dmevents-test_LIBDEPS = -lpthread -ldevmapper -lurcu
|
||||
hwtable-test_TESTDEPS := test-lib.o
|
||||
hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \
|
||||
diff --git a/tests/dmevents.c b/tests/dmevents.c
|
||||
index bee117ac..b7c5122b 100644
|
||||
--- a/tests/dmevents.c
|
||||
+++ b/tests/dmevents.c
|
||||
@@ -179,6 +179,8 @@ struct dm_names *build_dm_names(void)
|
||||
return names;
|
||||
}
|
||||
|
||||
+static bool setup_done;
|
||||
+
|
||||
static int setup(void **state)
|
||||
{
|
||||
if (dmevent_poll_supported()) {
|
||||
@@ -186,6 +188,7 @@ static int setup(void **state)
|
||||
*state = &data;
|
||||
} else
|
||||
*state = NULL;
|
||||
+ setup_done = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -262,14 +265,20 @@ struct dm_task *__wrap_libmp_dm_task_create(int task)
|
||||
return mock_type(struct dm_task *);
|
||||
}
|
||||
|
||||
+int __real_dm_task_no_open_count(struct dm_task *dmt);
|
||||
int __wrap_dm_task_no_open_count(struct dm_task *dmt)
|
||||
{
|
||||
+ if (!setup_done)
|
||||
+ return __real_dm_task_no_open_count(dmt);
|
||||
assert_ptr_equal((struct test_data *)dmt, &data);
|
||||
return mock_type(int);
|
||||
}
|
||||
|
||||
+int __real_dm_task_run(struct dm_task *dmt);
|
||||
int __wrap_dm_task_run(struct dm_task *dmt)
|
||||
{
|
||||
+ if (!setup_done)
|
||||
+ return __real_dm_task_run(dmt);
|
||||
assert_ptr_equal((struct test_data *)dmt, &data);
|
||||
return mock_type(int);
|
||||
}
|
||||
@@ -291,8 +300,11 @@ struct dm_names * __wrap_dm_task_get_names(struct dm_task *dmt)
|
||||
return data.names;
|
||||
}
|
||||
|
||||
+void __real_dm_task_destroy(struct dm_task *dmt);
|
||||
void __wrap_dm_task_destroy(struct dm_task *dmt)
|
||||
{
|
||||
+ if (!setup_done)
|
||||
+ return __real_dm_task_destroy(dmt);
|
||||
assert_ptr_equal((struct test_data *)dmt, &data);
|
||||
|
||||
if (data.names) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,10 +1,9 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:07 +0200
|
||||
Date: Wed, 16 Sep 2020 12:02:01 +0200
|
||||
Subject: [PATCH] libmultipath: constify file argument in config parser
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 3 +--
|
||||
@ -14,10 +13,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
4 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index a253a936..1818f8b9 100644
|
||||
index df0f8f45..5c91a09d 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -718,8 +718,7 @@ static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
@@ -719,8 +719,7 @@ static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -28,10 +27,10 @@ index a253a936..1818f8b9 100644
|
||||
struct config *conf = alloc_config();
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index c7a73fba..78375f2f 100644
|
||||
index 7af19844..ace403b8 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -253,7 +253,7 @@ void free_mptable (vector mptable);
|
||||
@@ -251,7 +251,7 @@ void free_mptable (vector mptable);
|
||||
|
||||
int store_hwe (vector hwtable, struct hwentry *);
|
||||
|
||||
@ -41,10 +40,10 @@ index c7a73fba..78375f2f 100644
|
||||
void free_config (struct config * conf);
|
||||
extern struct config *get_multipath_config(void);
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index a7285a35..d150e7b2 100644
|
||||
index ed6d5d6d..163ffbc9 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -400,7 +400,7 @@ set_regex_value(vector strvec)
|
||||
@@ -390,7 +390,7 @@ oom:
|
||||
/* non-recursive configuration stream handler */
|
||||
static int kw_level = 0;
|
||||
|
||||
@ -53,16 +52,16 @@ index a7285a35..d150e7b2 100644
|
||||
{
|
||||
char *tmp;
|
||||
int i;
|
||||
@@ -444,7 +444,7 @@ is_sublevel_keyword(char *str)
|
||||
@@ -434,7 +434,7 @@ is_sublevel_keyword(char *str)
|
||||
}
|
||||
|
||||
int
|
||||
-validate_config_strvec(vector strvec, char *file)
|
||||
+validate_config_strvec(vector strvec, const char *file)
|
||||
{
|
||||
char *str;
|
||||
char *str = NULL;
|
||||
int i;
|
||||
@@ -507,7 +507,8 @@ validate_config_strvec(vector strvec, char *file)
|
||||
@@ -499,7 +499,8 @@ validate_config_strvec(vector strvec, char *file)
|
||||
}
|
||||
|
||||
static int
|
||||
@ -72,7 +71,7 @@ index a7285a35..d150e7b2 100644
|
||||
{
|
||||
int i;
|
||||
int r = 0, t;
|
||||
@@ -592,7 +593,7 @@ out:
|
||||
@@ -584,7 +585,7 @@ out:
|
||||
|
||||
/* Data initialization */
|
||||
int
|
||||
@ -82,13 +81,13 @@ index a7285a35..d150e7b2 100644
|
||||
int r;
|
||||
FILE *stream;
|
||||
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
|
||||
index b7917052..b385fb9e 100644
|
||||
index 62906e98..06666ccf 100644
|
||||
--- a/libmultipath/parser.h
|
||||
+++ b/libmultipath/parser.h
|
||||
@@ -78,7 +78,7 @@ extern void free_keywords(vector keywords);
|
||||
@@ -77,7 +77,7 @@ extern void dump_keywords(vector keydump, int level);
|
||||
extern void free_keywords(vector keywords);
|
||||
extern vector alloc_strvec(char *string);
|
||||
extern void *set_value(vector strvec);
|
||||
extern void *set_regex_value(vector strvec);
|
||||
-extern int process_file(struct config *conf, char *conf_file);
|
||||
+extern int process_file(struct config *conf, const char *conf_file);
|
||||
extern struct keyword * find_keyword(vector keywords, vector v, char * name);
|
@ -1,777 +0,0 @@
|
||||
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
|
||||
|
@ -1,530 +0,0 @@
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:08 +0200
|
||||
Date: Wed, 16 Sep 2020 12:06:56 +0200
|
||||
Subject: [PATCH] libmultipath: provide defaults for {get,put}_multipath_config
|
||||
|
||||
Add an implementation of get_multipath_config() and put_multipath_config()
|
||||
@ -14,24 +14,28 @@ It must be initialized with init_config() rather than load_config(),
|
||||
which always allocates a new struct for backward compatibility, and must
|
||||
be teared down using uninit_config().
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 72 +++++++++++++++++++++++++++++++++++++------
|
||||
libmultipath/config.h | 21 +++++++++++--
|
||||
2 files changed, 80 insertions(+), 13 deletions(-)
|
||||
libmultipath/config.c | 75 ++++++++++++++++++++++++++-----
|
||||
libmultipath/config.h | 21 +++++++--
|
||||
libmultipath/libmultipath.version | 10 +++++
|
||||
3 files changed, 93 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 1818f8b9..422e923d 100644
|
||||
index 5c91a09d..01b77dfe 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -28,6 +28,23 @@
|
||||
@@ -27,6 +27,26 @@
|
||||
#include "mpath_cmd.h"
|
||||
#include "propsel.h"
|
||||
#include "version.h"
|
||||
|
||||
+static struct config __internal_config;
|
||||
+struct config *libmp_get_multipath_config(void)
|
||||
+{
|
||||
+ if (!__internal_config.hwtable)
|
||||
+ /* not initialized */
|
||||
+ return NULL;
|
||||
+ return &__internal_config;
|
||||
+}
|
||||
+
|
||||
@ -49,7 +53,7 @@ index 1818f8b9..422e923d 100644
|
||||
static int
|
||||
hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2)
|
||||
{
|
||||
@@ -575,17 +592,15 @@ restart:
|
||||
@@ -574,17 +594,15 @@ restart:
|
||||
return;
|
||||
}
|
||||
|
||||
@ -70,7 +74,7 @@ index 1818f8b9..422e923d 100644
|
||||
|
||||
if (conf->multipath_dir)
|
||||
FREE(conf->multipath_dir);
|
||||
@@ -649,7 +664,27 @@ free_config (struct config * conf)
|
||||
@@ -650,7 +668,27 @@ free_config (struct config * conf)
|
||||
free_hwtable(conf->hwtable);
|
||||
free_hwe(conf->overrides);
|
||||
free_keywords(conf->keywords);
|
||||
@ -99,7 +103,7 @@ index 1818f8b9..422e923d 100644
|
||||
}
|
||||
|
||||
/* if multipath fails to process the config directory, it should continue,
|
||||
@@ -718,12 +753,29 @@ static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
@@ -719,12 +757,29 @@ static void set_max_checkint_from_watchdog(struct config *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -130,7 +134,7 @@ index 1818f8b9..422e923d 100644
|
||||
|
||||
/*
|
||||
* internal defaults
|
||||
@@ -911,10 +963,10 @@ struct config *load_config(const char *file)
|
||||
@@ -896,10 +951,10 @@ struct config *load_config(const char *file)
|
||||
!conf->wwids_file || !conf->prkeys_file)
|
||||
goto out;
|
||||
|
||||
@ -145,10 +149,10 @@ index 1818f8b9..422e923d 100644
|
||||
|
||||
char *get_uid_attribute_by_attrs(struct config *conf,
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 78375f2f..83d179ac 100644
|
||||
index ace403b8..0329de29 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -254,10 +254,25 @@ void free_mptable (vector mptable);
|
||||
@@ -252,10 +252,25 @@ void free_mptable (vector mptable);
|
||||
int store_hwe (vector hwtable, struct hwentry *);
|
||||
|
||||
struct config *load_config (const char *file);
|
||||
@ -177,6 +181,24 @@ index 78375f2f..83d179ac 100644
|
||||
|
||||
int parse_uid_attrs(char *uid_attrs, struct config *conf);
|
||||
char *get_uid_attribute_by_attrs(struct config *conf,
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 97acdbb2..3e780fce 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -251,3 +251,13 @@ global:
|
||||
libmp_dm_task_run;
|
||||
cleanup_mutex;
|
||||
} LIBMULTIPATH_2.0.0;
|
||||
+
|
||||
+LIBMULTIPATH_2.2.0 {
|
||||
+global:
|
||||
+ libmp_get_multipath_config;
|
||||
+ get_multipath_config;
|
||||
+ libmp_put_multipath_config;
|
||||
+ put_multipath_config;
|
||||
+ init_config;
|
||||
+ uninit_config;
|
||||
+} LIBMULTIPATH_2.1.0;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,23 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:09 +0200
|
||||
Date: Wed, 16 Sep 2020 12:11:46 +0200
|
||||
Subject: [PATCH] libmpathpersist: allow using libmultipath
|
||||
{get,put}_multipath_config
|
||||
|
||||
Provide an alternative init function libmpathpersist_init() which
|
||||
avoids allocating a new struct config, simply using libmultipath's
|
||||
internal implementation.
|
||||
internal implementation. This causes a minor version bump for
|
||||
libmpathpersist.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_persist.c | 42 ++++++++++++++++++++++++++++-----
|
||||
libmpathpersist/mpath_persist.h | 28 ++++++++++++++++++++++
|
||||
2 files changed, 64 insertions(+), 6 deletions(-)
|
||||
libmpathpersist/libmpathpersist.version | 6 ++++
|
||||
libmpathpersist/mpath_persist.c | 42 +++++++++++++++++++++----
|
||||
libmpathpersist/mpath_persist.h | 28 +++++++++++++++++
|
||||
3 files changed, 70 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version
|
||||
index dc648ce6..e0748138 100644
|
||||
--- a/libmpathpersist/libmpathpersist.version
|
||||
+++ b/libmpathpersist/libmpathpersist.version
|
||||
@@ -30,3 +30,9 @@ global:
|
||||
|
||||
local: *;
|
||||
};
|
||||
+
|
||||
+LIBMPATHPERSIST_1.1.0 {
|
||||
+global:
|
||||
+ libmpathpersist_init;
|
||||
+ libmpathpersist_exit;
|
||||
+} LIBMPATHPERSIST_1.0.0;
|
||||
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
||||
index a132f4e9..9dfc98cd 100644
|
||||
index cc4a088d..febf4758 100644
|
||||
--- a/libmpathpersist/mpath_persist.c
|
||||
+++ b/libmpathpersist/mpath_persist.c
|
||||
@@ -37,6 +37,27 @@
|
||||
@ -48,7 +63,7 @@ index a132f4e9..9dfc98cd 100644
|
||||
struct config *
|
||||
mpath_lib_init (void)
|
||||
{
|
||||
@@ -47,21 +68,30 @@ mpath_lib_init (void)
|
||||
@@ -47,20 +68,29 @@ mpath_lib_init (void)
|
||||
condlog(0, "Failed to initialize multipath config.");
|
||||
return NULL;
|
||||
}
|
||||
@ -63,7 +78,6 @@ index a132f4e9..9dfc98cd 100644
|
||||
-mpath_lib_exit (struct config *conf)
|
||||
+static void libmpathpersist_cleanup(void)
|
||||
{
|
||||
dm_lib_release();
|
||||
dm_lib_exit();
|
||||
cleanup_prio();
|
||||
cleanup_checkers();
|
@ -1,205 +0,0 @@
|
||||
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
|
||||
|
@ -1,96 +0,0 @@
|
||||
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
|
||||
|
@ -1,20 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:10 +0200
|
||||
Date: Wed, 16 Sep 2020 12:27:09 +0200
|
||||
Subject: [PATCH] multipath: use {get_put}_multipath_config from libmultipath
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 20 ++++----------------
|
||||
1 file changed, 4 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index ce48a932..879d7ac9 100644
|
||||
index dc4974b9..4bbfce9a 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -67,7 +67,6 @@
|
||||
@@ -68,7 +68,6 @@
|
||||
|
||||
int logsink;
|
||||
struct udev *udev;
|
||||
@ -22,7 +21,7 @@ index ce48a932..879d7ac9 100644
|
||||
|
||||
/*
|
||||
* Return values of configure(), check_path_valid(), and main().
|
||||
@@ -78,16 +77,6 @@ enum {
|
||||
@@ -79,16 +78,6 @@ enum {
|
||||
RTVL_RETRY, /* returned by configure(), not by main() */
|
||||
};
|
||||
|
||||
@ -39,7 +38,7 @@ index ce48a932..879d7ac9 100644
|
||||
static int
|
||||
dump_config (struct config *conf, vector hwes, vector mpvec)
|
||||
{
|
||||
@@ -892,10 +881,9 @@ main (int argc, char *argv[])
|
||||
@@ -823,10 +812,9 @@ main (int argc, char *argv[])
|
||||
|
||||
udev = udev_new();
|
||||
logsink = 0;
|
||||
@ -51,8 +50,8 @@ index ce48a932..879d7ac9 100644
|
||||
+ conf = get_multipath_config();
|
||||
conf->retrigger_tries = 0;
|
||||
conf->force_sync = 1;
|
||||
while ((arg = getopt(argc, argv, ":aAdDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
@@ -1148,8 +1136,8 @@ out_free_config:
|
||||
while ((arg = getopt(argc, argv, ":adDcChl::eFfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||
@@ -1078,8 +1066,8 @@ out_free_config:
|
||||
* the logging function (dm_write_log()), which is called there,
|
||||
* references the config.
|
||||
*/
|
@ -1,41 +0,0 @@
|
||||
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,18 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:11 +0200
|
||||
Date: Wed, 16 Sep 2020 12:39:01 +0200
|
||||
Subject: [PATCH] mpathpersist: use {get,put}_multipath_config() from
|
||||
libmultipath
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
mpathpersist/main.c | 16 ++--------------
|
||||
1 file changed, 2 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/mpathpersist/main.c b/mpathpersist/main.c
|
||||
index 28bfe410..0f0db4b8 100644
|
||||
index a6a3bcf6..278e48f7 100644
|
||||
--- a/mpathpersist/main.c
|
||||
+++ b/mpathpersist/main.c
|
||||
@@ -43,17 +43,6 @@ void mpath_print_transport_id(struct prin_fulldescr *fdesc);
|
||||
@ -33,7 +32,7 @@ index 28bfe410..0f0db4b8 100644
|
||||
|
||||
void rcu_register_thread_memb(void) {}
|
||||
|
||||
@@ -620,15 +609,14 @@ int main(int argc, char *argv[])
|
||||
@@ -653,15 +642,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
udev = udev_new();
|
@ -1,6 +1,6 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:12 +0200
|
||||
Date: Wed, 16 Sep 2020 15:06:12 +0200
|
||||
Subject: [PATCH] libmultipath: add udev and logsink symbols
|
||||
|
||||
With these symbols added, applications using libmultipath don't
|
||||
@ -16,21 +16,22 @@ libmultipath_init() can be skipped, but like before,
|
||||
udev should be initialized (using udev_new()) before making any
|
||||
libmultipath calls.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 46 +++++++++++++++++++++++++++++++++++++++++++
|
||||
libmultipath/config.h | 46 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
libmultipath/debug.c | 2 ++
|
||||
3 files changed, 93 insertions(+), 1 deletion(-)
|
||||
libmultipath/config.c | 41 +++++++++++++++++++++++++++
|
||||
libmultipath/config.h | 46 ++++++++++++++++++++++++++++++-
|
||||
libmultipath/debug.c | 2 ++
|
||||
libmultipath/libmultipath.version | 8 ++++++
|
||||
4 files changed, 96 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 422e923d..b3809433 100644
|
||||
index 01b77dfe..f74417c6 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -28,6 +28,52 @@
|
||||
@@ -27,6 +27,47 @@
|
||||
#include "mpath_cmd.h"
|
||||
#include "propsel.h"
|
||||
#include "version.h"
|
||||
|
||||
+/*
|
||||
+ * We don't support re-initialization after
|
||||
@ -51,11 +52,6 @@ index 422e923d..b3809433 100644
|
||||
+ condlog(0, "%s: failed to initialize udev", __func__);
|
||||
+}
|
||||
+
|
||||
+static void _libmultipath_init(void)
|
||||
+{
|
||||
+ _udev_init();
|
||||
+}
|
||||
+
|
||||
+static bool _is_libmultipath_initialized(void)
|
||||
+{
|
||||
+ return !libmultipath_exit_called && !!udev;
|
||||
@ -63,7 +59,7 @@ index 422e923d..b3809433 100644
|
||||
+
|
||||
+int libmultipath_init(void)
|
||||
+{
|
||||
+ pthread_once(&_init_once, _libmultipath_init);
|
||||
+ pthread_once(&_init_once, _udev_init);
|
||||
+ return !_is_libmultipath_initialized();
|
||||
+}
|
||||
+
|
||||
@ -82,10 +78,10 @@ index 422e923d..b3809433 100644
|
||||
struct config *libmp_get_multipath_config(void)
|
||||
{
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index 83d179ac..089b2ac2 100644
|
||||
index 0329de29..f478df71 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -235,7 +235,51 @@ struct config {
|
||||
@@ -233,7 +233,51 @@ struct config {
|
||||
char *enable_foreign;
|
||||
};
|
||||
|
||||
@ -151,6 +147,22 @@ index 4128cb90..b3a1de9e 100644
|
||||
void dlog (int sink, int prio, const char * fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 3e780fce..0c300c81 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -261,3 +261,11 @@ global:
|
||||
init_config;
|
||||
uninit_config;
|
||||
} LIBMULTIPATH_2.1.0;
|
||||
+
|
||||
+LIBMULTIPATH_2.3.0 {
|
||||
+global:
|
||||
+ udev;
|
||||
+ logsink;
|
||||
+ libmultipath_init;
|
||||
+ libmultipath_exit;
|
||||
+} LIBMULTIPATH_2.2.0;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 4 Jun 2020 18:20:06 -0500
|
||||
Subject: [PATCH] libmultipath: fix condlog NULL argument in uevent_get_env_var
|
||||
|
||||
uevent_get_env_var() could call condlog with p == NULL. On gcc 10,
|
||||
this triggers warnings like:
|
||||
|
||||
In file included from uevent.c:47:
|
||||
In function 'uevent_get_env_var',
|
||||
inlined from 'uevent_get_wwid' at uevent.c:170:8:
|
||||
debug.h:13:2: error: '%s' directive argument is null
|
||||
[-Werror=format-overflow=]
|
||||
13 | dlog(logsink, prio, fmt "\n", ##args)
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
uevent.c:132:2: note: in expansion of macro 'condlog'
|
||||
132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p);
|
||||
| ^~~~~~~
|
||||
uevent.c: In function 'uevent_get_wwid':
|
||||
uevent.c:132:25: note: format string is defined here
|
||||
132 | condlog(4, "%s: %s -> '%s'", __func__, attr, p);
|
||||
| ^~
|
||||
|
||||
If p is NULL, use "(null)" instead.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/uevent.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
|
||||
index d38e8a7f..e0d13b11 100644
|
||||
--- a/libmultipath/uevent.c
|
||||
+++ b/libmultipath/uevent.c
|
||||
@@ -129,7 +129,7 @@ static const char* uevent_get_env_var(const struct uevent *uev,
|
||||
}
|
||||
}
|
||||
|
||||
- condlog(4, "%s: %s -> '%s'", __func__, attr, p);
|
||||
+ condlog(4, "%s: %s -> '%s'", __func__, attr, p ?: "(null)");
|
||||
return p;
|
||||
|
||||
invalid:
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,49 +0,0 @@
|
||||
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
|
||||
|
@ -1,24 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:13 +0200
|
||||
Date: Wed, 16 Sep 2020 16:06:17 +0200
|
||||
Subject: [PATCH] multipath: remove logsink and udev
|
||||
|
||||
We can use libmultipath's symbols now.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 879d7ac9..322b30e0 100644
|
||||
index 4bbfce9a..9ae46ed5 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -65,9 +65,6 @@
|
||||
#include "file.h"
|
||||
@@ -66,9 +66,6 @@
|
||||
#include "valid.h"
|
||||
#include "alias.h"
|
||||
|
||||
-int logsink;
|
||||
-struct udev *udev;
|
||||
@ -26,7 +25,7 @@ index 879d7ac9..322b30e0 100644
|
||||
/*
|
||||
* Return values of configure(), check_path_valid(), and main().
|
||||
*/
|
||||
@@ -879,7 +876,7 @@ main (int argc, char *argv[])
|
||||
@@ -810,7 +807,7 @@ main (int argc, char *argv[])
|
||||
int retries = -1;
|
||||
bool enable_foreign = false;
|
||||
|
||||
@ -35,7 +34,7 @@ index 879d7ac9..322b30e0 100644
|
||||
logsink = 0;
|
||||
if (init_config(DEFAULT_CONFIGFILE))
|
||||
exit(RTVL_FAIL);
|
||||
@@ -1138,7 +1135,7 @@ out_free_config:
|
||||
@@ -1068,7 +1065,7 @@ out_free_config:
|
||||
*/
|
||||
put_multipath_config(conf);
|
||||
uninit_config();
|
@ -1,19 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:14 +0200
|
||||
Date: Tue, 22 Sep 2020 14:23:14 +0200
|
||||
Subject: [PATCH] libmpathpersist: call libmultipath_{init,exit}()
|
||||
|
||||
Have libmpathpersist_{init,exit} do the udev initialization, too.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathpersist/mpath_persist.c | 13 +++++++++----
|
||||
libmpathpersist/mpath_persist.c | 11 ++++++++---
|
||||
libmpathpersist/mpath_persist.h | 9 ++++++---
|
||||
2 files changed, 15 insertions(+), 7 deletions(-)
|
||||
2 files changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
||||
index 9dfc98cd..d1538195 100644
|
||||
index febf4758..e1d1cb76 100644
|
||||
--- a/libmpathpersist/mpath_persist.c
|
||||
+++ b/libmpathpersist/mpath_persist.c
|
||||
@@ -48,6 +48,10 @@ int libmpathpersist_init(void)
|
||||
@ -27,16 +27,14 @@ index 9dfc98cd..d1538195 100644
|
||||
if (init_config(DEFAULT_CONFIGFILE)) {
|
||||
condlog(0, "Failed to initialize multipath config.");
|
||||
return 1;
|
||||
@@ -74,24 +78,25 @@ mpath_lib_init (void)
|
||||
@@ -74,23 +78,24 @@ mpath_lib_init (void)
|
||||
|
||||
static void libmpathpersist_cleanup(void)
|
||||
{
|
||||
- dm_lib_release();
|
||||
- dm_lib_exit();
|
||||
cleanup_prio();
|
||||
cleanup_checkers();
|
||||
+ libmultipath_exit();
|
||||
+ dm_lib_release();
|
||||
+ dm_lib_exit();
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
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
|
||||
|
@ -1,139 +0,0 @@
|
||||
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
|
||||
|
@ -1,19 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:15 +0200
|
||||
Date: Wed, 16 Sep 2020 16:08:43 +0200
|
||||
Subject: [PATCH] mpathpersist: remove logsink and udev
|
||||
|
||||
We can use libmultipath's internal symbols now. The libmultipath
|
||||
initialization is taken care of by libmpathpersist_init().
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
mpathpersist/main.c | 6 ------
|
||||
1 file changed, 6 deletions(-)
|
||||
|
||||
diff --git a/mpathpersist/main.c b/mpathpersist/main.c
|
||||
index 0f0db4b8..a25b08f0 100644
|
||||
index 278e48f7..3c2e6576 100644
|
||||
--- a/mpathpersist/main.c
|
||||
+++ b/mpathpersist/main.c
|
||||
@@ -42,13 +42,10 @@ void * mpath_alloc_prin_response(int prin_sa);
|
||||
@ -30,7 +30,7 @@ index 0f0db4b8..a25b08f0 100644
|
||||
|
||||
static int verbose, loglevel, noisy;
|
||||
|
||||
@@ -608,16 +605,13 @@ int main(int argc, char *argv[])
|
||||
@@ -641,16 +638,13 @@ int main(int argc, char *argv[])
|
||||
exit (1);
|
||||
}
|
||||
|
@ -1,95 +0,0 @@
|
||||
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
|
||||
|
@ -1,21 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Thu, 24 Sep 2020 15:37:16 +0200
|
||||
Date: Wed, 23 Sep 2020 11:28:22 +0200
|
||||
Subject: [PATCH] multipathd: remove logsink and udev
|
||||
|
||||
We can use the symbols from libmultipath now.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 48b62937..6a4b8b83 100644
|
||||
index 00b66ba4..c5c374b7 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -113,7 +113,6 @@ struct mpath_event_param
|
||||
@@ -115,7 +115,6 @@ struct mpath_event_param
|
||||
struct multipath *mpp;
|
||||
};
|
||||
|
||||
@ -23,7 +23,7 @@ index 48b62937..6a4b8b83 100644
|
||||
int uxsock_timeout;
|
||||
int verbosity;
|
||||
int bindings_read_only;
|
||||
@@ -144,8 +143,6 @@ static inline enum daemon_status get_running_state(void)
|
||||
@@ -151,8 +150,6 @@ int should_exit(void)
|
||||
*/
|
||||
struct vectors * gvecs;
|
||||
|
||||
@ -32,7 +32,7 @@ index 48b62937..6a4b8b83 100644
|
||||
struct config *multipath_conf;
|
||||
|
||||
/* Local variables */
|
||||
@@ -3009,8 +3006,6 @@ child (__attribute__((unused)) void *param)
|
||||
@@ -3123,8 +3120,6 @@ child (__attribute__((unused)) void *param)
|
||||
conf = rcu_dereference(multipath_conf);
|
||||
rcu_assign_pointer(multipath_conf, NULL);
|
||||
call_rcu(&conf->rcu, rcu_free_config);
|
||||
@ -41,7 +41,7 @@ index 48b62937..6a4b8b83 100644
|
||||
pthread_attr_destroy(&waiter_attr);
|
||||
pthread_attr_destroy(&io_err_stat_attr);
|
||||
#ifdef _DEBUG_
|
||||
@@ -3114,7 +3109,9 @@ main (int argc, char *argv[])
|
||||
@@ -3228,7 +3223,9 @@ main (int argc, char *argv[])
|
||||
|
||||
pthread_cond_init_mono(&config_cond);
|
||||
|
@ -1,435 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Date: Wed, 16 Dec 2020 23:17:39 +0100
|
||||
Subject: [PATCH] multipath-tools: add Vexata(by StorCentric) VX arrays
|
||||
|
||||
https://support.sas.com/resources/papers/performance-tuning-sas-vexata-systems.pdf
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index cd65afcc..c1d6f7ae 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -1191,6 +1191,14 @@ static struct hwentry default_hw[] = {
|
||||
.product = "Magnitude",
|
||||
.pgpolicy = MULTIBUS,
|
||||
.no_path_retry = 30,
|
||||
+ },
|
||||
+ /* Vexata */
|
||||
+ {
|
||||
+ /* VX */
|
||||
+ .vendor = "Vexata",
|
||||
+ .product = "VX",
|
||||
+ .pgpolicy = MULTIBUS,
|
||||
+ .no_path_retry = 30,
|
||||
},
|
||||
/*
|
||||
* Promise Technology
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,111 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Date: Wed, 16 Dec 2020 23:17:40 +0100
|
||||
Subject: [PATCH] multipath-tools: Violin and Nexsan were bought by StorCentric
|
||||
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index c1d6f7ae..a54cc0a3 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -1113,8 +1113,9 @@ static struct hwentry default_hw[] = {
|
||||
.pgpolicy = MULTIBUS,
|
||||
},
|
||||
/*
|
||||
- * Imation/Nexsan
|
||||
+ * StorCentric
|
||||
*/
|
||||
+ /* Nexsan */
|
||||
{
|
||||
/* E-Series */
|
||||
.vendor = "NEXSAN",
|
||||
@@ -1143,9 +1144,7 @@ static struct hwentry default_hw[] = {
|
||||
.prio_name = PRIO_ALUA,
|
||||
.no_path_retry = 30,
|
||||
},
|
||||
- /*
|
||||
- * Violin Systems
|
||||
- */
|
||||
+ /* Violin Systems */
|
||||
{
|
||||
/* 3000 / 6000 Series */
|
||||
.vendor = "VIOLIN",
|
||||
--
|
||||
2.17.2
|
||||
|
117
0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch
Normal file
117
0037-libmultipath-fix-memory-leaks-in-coalesce_paths.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: lixiaokeng <lixiaokeng@huawei.com>
|
||||
Date: Mon, 9 Nov 2020 12:32:05 +0800
|
||||
Subject: [PATCH] libmultipath: fix memory leaks in coalesce_paths
|
||||
|
||||
When multipath -F are executed first and multipath -v2 or
|
||||
-d are executed later, asan will warn memory leaks. The
|
||||
reason is that the mpp allocated in coalesce_paths isn't
|
||||
freed. Here we use newmp to store mpp. If newmp need not
|
||||
be copied to mpvec, we free newmp at the end of the func.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
|
||||
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
|
||||
Signed-off-by: Linfeilong <linfeilong@huawei.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/configure.c | 40 +++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 29 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 1c8aac08..d36f0d0d 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -1139,7 +1139,7 @@ out:
|
||||
* FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only
|
||||
* reloaded in DM if there's a difference. This is useful during startup.
|
||||
*/
|
||||
-int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
+int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
|
||||
int force_reload, enum mpath_cmds cmd)
|
||||
{
|
||||
int ret = CP_FAIL;
|
||||
@@ -1151,6 +1151,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
struct path * pp2;
|
||||
vector curmp = vecs->mpvec;
|
||||
vector pathvec = vecs->pathvec;
|
||||
+ vector newmp;
|
||||
struct config *conf;
|
||||
int allow_queueing;
|
||||
struct bitfield *size_mismatch_seen;
|
||||
@@ -1171,6 +1172,15 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
if (size_mismatch_seen == NULL)
|
||||
return CP_FAIL;
|
||||
|
||||
+ if (mpvec)
|
||||
+ newmp = mpvec;
|
||||
+ else
|
||||
+ newmp = vector_alloc();
|
||||
+ if (!newmp) {
|
||||
+ condlog(0, "can not allocate newmp");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
vector_foreach_slot (pathvec, pp1, k) {
|
||||
int invalid;
|
||||
|
||||
@@ -1283,8 +1293,14 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
- if (r == DOMAP_DRY)
|
||||
+ if (r == DOMAP_DRY) {
|
||||
+ if (!vector_alloc_slot(newmp)) {
|
||||
+ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ vector_set_slot(newmp, mpp);
|
||||
continue;
|
||||
+ }
|
||||
|
||||
if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING &&
|
||||
force_reload == FORCE_RELOAD_WEAK)
|
||||
@@ -1320,22 +1336,22 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
print_multipath_topology(mpp, verbosity);
|
||||
}
|
||||
|
||||
- if (newmp) {
|
||||
- if (mpp->action != ACT_REJECT) {
|
||||
- if (!vector_alloc_slot(newmp))
|
||||
- goto out;
|
||||
- vector_set_slot(newmp, mpp);
|
||||
+ if (mpp->action != ACT_REJECT) {
|
||||
+ if (!vector_alloc_slot(newmp)) {
|
||||
+ remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC);
|
||||
+ goto out;
|
||||
}
|
||||
- else
|
||||
- remove_map(mpp, vecs->pathvec, vecs->mpvec,
|
||||
- KEEP_VEC);
|
||||
+ vector_set_slot(newmp, mpp);
|
||||
}
|
||||
+ else
|
||||
+ remove_map(mpp, vecs->pathvec, vecs->mpvec,
|
||||
+ KEEP_VEC);
|
||||
}
|
||||
/*
|
||||
* Flush maps with only dead paths (ie not in sysfs)
|
||||
* Keep maps with only failed paths
|
||||
*/
|
||||
- if (newmp) {
|
||||
+ if (mpvec) {
|
||||
vector_foreach_slot (newmp, mpp, i) {
|
||||
char alias[WWID_SIZE];
|
||||
|
||||
@@ -1358,6 +1374,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
|
||||
ret = CP_OK;
|
||||
out:
|
||||
free(size_mismatch_seen);
|
||||
+ if (!mpvec)
|
||||
+ free_multipathvec(newmp, KEEP_PATHS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,43 +0,0 @@
|
||||
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
|
||||
|
@ -1,267 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Date: Thu, 17 Dec 2020 16:49:38 +0100
|
||||
Subject: [PATCH] multipath-tools: replace hidden tab by space in hwtable
|
||||
|
||||
Cc: Martin Wilck <mwilck@suse.com>
|
||||
Cc: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Cc: Christophe Varoqui <christophe.varoqui@opensvc.com>
|
||||
Cc: DM-DEVEL ML <dm-devel@redhat.com>
|
||||
Signed-off-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index a54cc0a3..921aadc5 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -819,7 +819,7 @@ static struct hwentry default_hw[] = {
|
||||
*
|
||||
* The hwtable is searched backwards, so place this after "Generic NVMe"
|
||||
*/
|
||||
- .vendor = "NVME",
|
||||
+ .vendor = "NVME",
|
||||
.product = "^NetApp ONTAP Controller",
|
||||
.pgpolicy = MULTIBUS,
|
||||
.no_path_retry = NO_PATH_RETRY_QUEUE,
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,53 +0,0 @@
|
||||
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
|
||||
|
105
0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch
Normal file
105
0039-multipathd-uxlsnr-avoid-deadlock-on-exit.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Tue, 22 Sep 2020 20:59:25 +0200
|
||||
Subject: [PATCH] multipathd: uxlsnr: avoid deadlock on exit
|
||||
|
||||
The uxlsnr wouldn't always release the client lock when cancelled,
|
||||
causing a deadlock in uxsock_cleanup(). While this hasn't been
|
||||
caused by commit 3d611a2, the deadlock seems to have become much
|
||||
more likely after that patch. Solving this means that we have to
|
||||
treat reallocation failure of the pollfd array differently.
|
||||
We will now just ignore any clients above the last valid pfd index.
|
||||
That's a minor problem, as we're in an OOM situation anyway.
|
||||
|
||||
Moreover, client_lock is not a "struct lock", but a plain
|
||||
pthread_mutex_t.
|
||||
|
||||
Fixes: 3d611a2 ("multipathd: cancel threads early during shutdown")
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/uxlsnr.c | 24 ++++++++++++++----------
|
||||
1 file changed, 14 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
|
||||
index 1c5ce9d2..ce2b6800 100644
|
||||
--- a/multipathd/uxlsnr.c
|
||||
+++ b/multipathd/uxlsnr.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "config.h"
|
||||
#include "mpath_cmd.h"
|
||||
#include "time-util.h"
|
||||
+#include "util.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "cli.h"
|
||||
@@ -116,7 +117,7 @@ static void _dead_client(struct client *c)
|
||||
|
||||
static void dead_client(struct client *c)
|
||||
{
|
||||
- pthread_cleanup_push(cleanup_lock, &client_lock);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &client_lock);
|
||||
pthread_mutex_lock(&client_lock);
|
||||
_dead_client(c);
|
||||
pthread_cleanup_pop(1);
|
||||
@@ -302,10 +303,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
sigdelset(&mask, SIGUSR1);
|
||||
while (1) {
|
||||
struct client *c, *tmp;
|
||||
- int i, poll_count, num_clients;
|
||||
+ int i, n_pfds, poll_count, num_clients;
|
||||
|
||||
/* setup for a poll */
|
||||
pthread_mutex_lock(&client_lock);
|
||||
+ pthread_cleanup_push(cleanup_mutex, &client_lock);
|
||||
num_clients = 0;
|
||||
list_for_each_entry(c, &clients, node) {
|
||||
num_clients++;
|
||||
@@ -322,14 +324,13 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
sizeof(struct pollfd));
|
||||
}
|
||||
if (!new) {
|
||||
- pthread_mutex_unlock(&client_lock);
|
||||
condlog(0, "%s: failed to realloc %d poll fds",
|
||||
"uxsock", 2 + num_clients);
|
||||
- sched_yield();
|
||||
- continue;
|
||||
+ num_clients = old_clients;
|
||||
+ } else {
|
||||
+ old_clients = num_clients;
|
||||
+ polls = new;
|
||||
}
|
||||
- old_clients = num_clients;
|
||||
- polls = new;
|
||||
}
|
||||
polls[0].fd = ux_sock;
|
||||
polls[0].events = POLLIN;
|
||||
@@ -347,11 +348,14 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
polls[i].fd = c->fd;
|
||||
polls[i].events = POLLIN;
|
||||
i++;
|
||||
+ if (i >= 2 + num_clients)
|
||||
+ break;
|
||||
}
|
||||
- pthread_mutex_unlock(&client_lock);
|
||||
+ n_pfds = i;
|
||||
+ pthread_cleanup_pop(1);
|
||||
|
||||
/* most of our life is spent in this call */
|
||||
- poll_count = ppoll(polls, i, &sleep_time, &mask);
|
||||
+ poll_count = ppoll(polls, n_pfds, &sleep_time, &mask);
|
||||
|
||||
handle_signals(false);
|
||||
if (poll_count == -1) {
|
||||
@@ -384,7 +388,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
}
|
||||
|
||||
/* see if a client wants to speak to us */
|
||||
- for (i = 2; i < num_clients + 2; i++) {
|
||||
+ for (i = 2; i < n_pfds; i++) {
|
||||
if (polls[i].revents & POLLIN) {
|
||||
struct timespec start_time;
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,62 +0,0 @@
|
||||
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
|
||||
|
98
0040-multipathd-Fix-liburcu-memory-leak.patch
Normal file
98
0040-multipathd-Fix-liburcu-memory-leak.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 18:02:39 +0200
|
||||
Subject: [PATCH] multipathd: Fix liburcu memory leak
|
||||
|
||||
Fix this leak in multipathd, reported by valgrind, that messes up
|
||||
multipathd's otherwise clean leak report:
|
||||
|
||||
==23823== 336 bytes in 1 blocks are possibly lost in loss record 3 of 3
|
||||
==23823== at 0x483AB65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
|
||||
==23823== by 0x4012F16: _dl_allocate_tls (in /lib64/ld-2.31.so)
|
||||
==23823== by 0x493BB8E: pthread_create@@GLIBC_2.2.5 (in /lib64/libpthread-2.31.so)
|
||||
==23823== by 0x492A9A9: call_rcu_data_init (urcu-call-rcu-impl.h:437)
|
||||
==23823== by 0x492AD2F: UnknownInlinedFun (urcu-call-rcu-impl.h:492)
|
||||
==23823== by 0x492AD2F: create_call_rcu_data_memb (urcu-call-rcu-impl.h:504)
|
||||
==23823== by 0x1164E3: child.constprop.0.isra.0 (main.c:2915)
|
||||
==23823== by 0x10F50C: main (main.c:3335)
|
||||
==23823==
|
||||
==23823== LEAK SUMMARY:
|
||||
==23823== definitely lost: 0 bytes in 0 blocks
|
||||
==23823== indirectly lost: 0 bytes in 0 blocks
|
||||
==23823== possibly lost: 336 bytes in 1 blocks
|
||||
|
||||
The problem is caused by using liburcu's default RCU call handler,
|
||||
which liburcu refuses to stop/join. See comments in the code.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index c5c374b7..ce14bb66 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2889,6 +2889,48 @@ set_oom_adj (void)
|
||||
condlog(0, "couldn't adjust oom score");
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Use a non-default call_rcu_data for child().
|
||||
+ *
|
||||
+ * We do this to avoid a memory leak from liburcu.
|
||||
+ * liburcu never frees the default rcu handler (see comments on
|
||||
+ * call_rcu_data_free() in urcu-call-rcu-impl.h), its thread
|
||||
+ * can't be joined with pthread_join(), leaving a memory leak.
|
||||
+ *
|
||||
+ * Therefore we create our own, which can be destroyed and joined.
|
||||
+ */
|
||||
+static struct call_rcu_data *setup_rcu(void)
|
||||
+{
|
||||
+ struct call_rcu_data *crdp;
|
||||
+
|
||||
+ rcu_init();
|
||||
+ rcu_register_thread();
|
||||
+ crdp = create_call_rcu_data(0UL, -1);
|
||||
+ if (crdp != NULL)
|
||||
+ set_thread_call_rcu_data(crdp);
|
||||
+ return crdp;
|
||||
+}
|
||||
+
|
||||
+static struct call_rcu_data *mp_rcu_data;
|
||||
+
|
||||
+static void cleanup_rcu(void)
|
||||
+{
|
||||
+ pthread_t rcu_thread;
|
||||
+
|
||||
+ /* Wait for any pending RCU calls */
|
||||
+ rcu_barrier();
|
||||
+ if (mp_rcu_data != NULL) {
|
||||
+ rcu_thread = get_call_rcu_thread(mp_rcu_data);
|
||||
+ /* detach this thread from the RCU thread */
|
||||
+ set_thread_call_rcu_data(NULL);
|
||||
+ synchronize_rcu();
|
||||
+ /* tell RCU thread to exit */
|
||||
+ call_rcu_data_free(mp_rcu_data);
|
||||
+ pthread_join(rcu_thread, NULL);
|
||||
+ }
|
||||
+ rcu_unregister_thread();
|
||||
+}
|
||||
+
|
||||
static int
|
||||
child (__attribute__((unused)) void *param)
|
||||
{
|
||||
@@ -2906,7 +2948,8 @@ child (__attribute__((unused)) void *param)
|
||||
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
signal_init();
|
||||
- rcu_init();
|
||||
+ mp_rcu_data = setup_rcu();
|
||||
+ atexit(cleanup_rcu);
|
||||
|
||||
setup_thread_attr(&misc_attr, 64 * 1024, 0);
|
||||
setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,322 +0,0 @@
|
||||
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
|
||||
|
146
0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch
Normal file
146
0041-multipathd-move-handling-of-io_err_stat_attr-into-li.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 10:33:12 +0200
|
||||
Subject: [PATCH] multipathd: move handling of io_err_stat_attr into
|
||||
libmultipath
|
||||
|
||||
This thread attribute can be dynamically initialized and destroyed.
|
||||
No need to carry it along in multipathd. Removal of the symbol
|
||||
requires to bump the ABI version to 3.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 7 +++++--
|
||||
libmultipath/libmultipath.version | 23 ++++++++---------------
|
||||
multipathd/main.c | 2 --
|
||||
3 files changed, 13 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 58bc1dd2..5363049d 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "lock.h"
|
||||
#include "time-util.h"
|
||||
#include "io_err_stat.h"
|
||||
+#include "util.h"
|
||||
|
||||
#define TIMEOUT_NO_IO_NSEC 10000000 /*10ms = 10000000ns*/
|
||||
#define FLAKY_PATHFAIL_THRESHOLD 2
|
||||
@@ -70,8 +71,7 @@ struct io_err_stat_path {
|
||||
int err_rate_threshold;
|
||||
};
|
||||
|
||||
-pthread_t io_err_stat_thr;
|
||||
-pthread_attr_t io_err_stat_attr;
|
||||
+static pthread_t io_err_stat_thr;
|
||||
|
||||
static pthread_mutex_t io_err_thread_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t io_err_thread_cond = PTHREAD_COND_INITIALIZER;
|
||||
@@ -727,6 +727,7 @@ static void *io_err_stat_loop(void *data)
|
||||
int start_io_err_stat_thread(void *data)
|
||||
{
|
||||
int ret;
|
||||
+ pthread_attr_t io_err_stat_attr;
|
||||
|
||||
if (uatomic_read(&io_err_thread_running) == 1)
|
||||
return 0;
|
||||
@@ -739,6 +740,7 @@ int start_io_err_stat_thread(void *data)
|
||||
if (!paths)
|
||||
goto destroy_ctx;
|
||||
|
||||
+ setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0);
|
||||
pthread_mutex_lock(&io_err_thread_lock);
|
||||
pthread_cleanup_push(cleanup_unlock, &io_err_thread_lock);
|
||||
|
||||
@@ -750,6 +752,7 @@ int start_io_err_stat_thread(void *data)
|
||||
&io_err_thread_lock) == 0);
|
||||
|
||||
pthread_cleanup_pop(1);
|
||||
+ pthread_attr_destroy(&io_err_stat_attr);
|
||||
|
||||
if (ret) {
|
||||
io_err_stat_log(0, "cannot create io_error statistic thread");
|
||||
diff --git a/libmultipath/libmultipath.version b/libmultipath/libmultipath.version
|
||||
index 0c300c81..84beb7f0 100644
|
||||
--- a/libmultipath/libmultipath.version
|
||||
+++ b/libmultipath/libmultipath.version
|
||||
@@ -31,7 +31,7 @@
|
||||
* The new version inherits the previous ones.
|
||||
*/
|
||||
|
||||
-LIBMULTIPATH_2.0.0 {
|
||||
+LIBMULTIPATH_3.0.0 {
|
||||
global:
|
||||
/* symbols referenced by multipath and multipathd */
|
||||
add_foreign;
|
||||
@@ -121,7 +121,6 @@ global:
|
||||
init_checkers;
|
||||
init_foreign;
|
||||
init_prio;
|
||||
- io_err_stat_attr;
|
||||
io_err_stat_handle_pathfail;
|
||||
is_path_valid;
|
||||
is_quote;
|
||||
@@ -242,30 +241,24 @@ global:
|
||||
free_scandir_result;
|
||||
sysfs_attr_get_value;
|
||||
|
||||
-local:
|
||||
- *;
|
||||
-};
|
||||
-
|
||||
-LIBMULTIPATH_2.1.0 {
|
||||
-global:
|
||||
+ /* added in 2.1.0 */
|
||||
libmp_dm_task_run;
|
||||
cleanup_mutex;
|
||||
-} LIBMULTIPATH_2.0.0;
|
||||
|
||||
-LIBMULTIPATH_2.2.0 {
|
||||
-global:
|
||||
+ /* added in 2.2.0 */
|
||||
libmp_get_multipath_config;
|
||||
get_multipath_config;
|
||||
libmp_put_multipath_config;
|
||||
put_multipath_config;
|
||||
init_config;
|
||||
uninit_config;
|
||||
-} LIBMULTIPATH_2.1.0;
|
||||
|
||||
-LIBMULTIPATH_2.3.0 {
|
||||
-global:
|
||||
+ /* added in 2.3.0 */
|
||||
udev;
|
||||
logsink;
|
||||
libmultipath_init;
|
||||
libmultipath_exit;
|
||||
-} LIBMULTIPATH_2.2.0;
|
||||
+
|
||||
+local:
|
||||
+ *;
|
||||
+};
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index ce14bb66..abc6a9f7 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2954,7 +2954,6 @@ child (__attribute__((unused)) void *param)
|
||||
setup_thread_attr(&misc_attr, 64 * 1024, 0);
|
||||
setup_thread_attr(&uevent_attr, DEFAULT_UEVENT_STACKSIZE * 1024, 0);
|
||||
setup_thread_attr(&waiter_attr, 32 * 1024, 1);
|
||||
- setup_thread_attr(&io_err_stat_attr, 32 * 1024, 0);
|
||||
|
||||
if (logsink == 1) {
|
||||
setup_thread_attr(&log_attr, 64 * 1024, 0);
|
||||
@@ -3164,7 +3163,6 @@ child (__attribute__((unused)) void *param)
|
||||
rcu_assign_pointer(multipath_conf, NULL);
|
||||
call_rcu(&conf->rcu, rcu_free_config);
|
||||
pthread_attr_destroy(&waiter_attr);
|
||||
- pthread_attr_destroy(&io_err_stat_attr);
|
||||
#ifdef _DEBUG_
|
||||
dbg_free_final(NULL);
|
||||
#endif
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,116 +0,0 @@
|
||||
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
|
||||
|
125
0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch
Normal file
125
0042-multipathd-move-vecs-desctruction-into-cleanup-funct.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 18:05:40 +0200
|
||||
Subject: [PATCH] multipathd: move vecs desctruction into cleanup function
|
||||
|
||||
This will make it easer to move the stuff around later.
|
||||
The only functional change is that map destuction now happens after
|
||||
joining all threads, which should actually improve robustness.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 64 +++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 40 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index abc6a9f7..3da0d7cc 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -148,7 +148,7 @@ int should_exit(void)
|
||||
/*
|
||||
* global copy of vecs for use in sig handlers
|
||||
*/
|
||||
-struct vectors * gvecs;
|
||||
+static struct vectors * gvecs;
|
||||
|
||||
struct config *multipath_conf;
|
||||
|
||||
@@ -2889,6 +2889,44 @@ set_oom_adj (void)
|
||||
condlog(0, "couldn't adjust oom score");
|
||||
}
|
||||
|
||||
+static void cleanup_maps(struct vectors *vecs)
|
||||
+{
|
||||
+ int queue_without_daemon, i;
|
||||
+ struct multipath *mpp;
|
||||
+ struct config *conf;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ queue_without_daemon = conf->queue_without_daemon;
|
||||
+ put_multipath_config(conf);
|
||||
+ if (queue_without_daemon == QUE_NO_DAEMON_OFF)
|
||||
+ vector_foreach_slot(vecs->mpvec, mpp, i)
|
||||
+ dm_queue_if_no_path(mpp->alias, 0);
|
||||
+ remove_maps_and_stop_waiters(vecs);
|
||||
+ vecs->mpvec = NULL;
|
||||
+}
|
||||
+
|
||||
+static void cleanup_paths(struct vectors *vecs)
|
||||
+{
|
||||
+ free_pathvec(vecs->pathvec, FREE_PATHS);
|
||||
+ vecs->pathvec = NULL;
|
||||
+}
|
||||
+
|
||||
+static void cleanup_vecs(void)
|
||||
+{
|
||||
+ if (!gvecs)
|
||||
+ return;
|
||||
+ /*
|
||||
+ * We can't take the vecs lock here, because exit() may
|
||||
+ * have been called from the child() thread, holding the lock already.
|
||||
+ * Anyway, by the time we get here, all threads that might access
|
||||
+ * vecs should have been joined already (in cleanup_threads).
|
||||
+ */
|
||||
+ cleanup_maps(gvecs);
|
||||
+ cleanup_paths(gvecs);
|
||||
+ pthread_mutex_destroy(&gvecs->lock.mutex);
|
||||
+ FREE(gvecs);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Use a non-default call_rcu_data for child().
|
||||
*
|
||||
@@ -2937,13 +2975,10 @@ child (__attribute__((unused)) void *param)
|
||||
pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr;
|
||||
pthread_attr_t log_attr, misc_attr, uevent_attr;
|
||||
struct vectors * vecs;
|
||||
- struct multipath * mpp;
|
||||
- int i;
|
||||
int rc;
|
||||
int pid_fd = -1;
|
||||
struct config *conf;
|
||||
char *envp;
|
||||
- int queue_without_daemon;
|
||||
enum daemon_status state;
|
||||
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
@@ -3108,17 +3143,6 @@ child (__attribute__((unused)) void *param)
|
||||
if (poll_dmevents)
|
||||
pthread_cancel(dmevent_thr);
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- queue_without_daemon = conf->queue_without_daemon;
|
||||
- put_multipath_config(conf);
|
||||
-
|
||||
- lock(&vecs->lock);
|
||||
- if (queue_without_daemon == QUE_NO_DAEMON_OFF)
|
||||
- vector_foreach_slot(vecs->mpvec, mpp, i)
|
||||
- dm_queue_if_no_path(mpp->alias, 0);
|
||||
- remove_maps_and_stop_waiters(vecs);
|
||||
- unlock(&vecs->lock);
|
||||
-
|
||||
pthread_join(check_thr, NULL);
|
||||
pthread_join(uevent_thr, NULL);
|
||||
pthread_join(uxlsnr_thr, NULL);
|
||||
@@ -3128,15 +3152,7 @@ child (__attribute__((unused)) void *param)
|
||||
|
||||
stop_io_err_stat_thread();
|
||||
|
||||
- lock(&vecs->lock);
|
||||
- free_pathvec(vecs->pathvec, FREE_PATHS);
|
||||
- vecs->pathvec = NULL;
|
||||
- unlock(&vecs->lock);
|
||||
-
|
||||
- pthread_mutex_destroy(&vecs->lock.mutex);
|
||||
- FREE(vecs);
|
||||
- vecs = NULL;
|
||||
-
|
||||
+ cleanup_vecs();
|
||||
cleanup_foreign();
|
||||
cleanup_checkers();
|
||||
cleanup_prio();
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,46 +0,0 @@
|
||||
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
|
||||
|
45
0043-multipathd-make-some-globals-static.patch
Normal file
45
0043-multipathd-make-some-globals-static.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 11:18:02 +0200
|
||||
Subject: [PATCH] multipathd: make some globals static
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 3da0d7cc..eb760a71 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -116,19 +116,19 @@ struct mpath_event_param
|
||||
};
|
||||
|
||||
int uxsock_timeout;
|
||||
-int verbosity;
|
||||
-int bindings_read_only;
|
||||
+static int verbosity;
|
||||
+static int bindings_read_only;
|
||||
int ignore_new_devs;
|
||||
#ifdef NO_DMEVENTS_POLL
|
||||
-int poll_dmevents = 0;
|
||||
+static int poll_dmevents = 0;
|
||||
#else
|
||||
-int poll_dmevents = 1;
|
||||
+static int poll_dmevents = 1;
|
||||
#endif
|
||||
/* Don't access this variable without holding config_lock */
|
||||
-volatile enum daemon_status running_state = DAEMON_INIT;
|
||||
+static volatile enum daemon_status running_state = DAEMON_INIT;
|
||||
pid_t daemon_pid;
|
||||
-pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
-pthread_cond_t config_cond;
|
||||
+static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_cond_t config_cond;
|
||||
|
||||
static inline enum daemon_status get_running_state(void)
|
||||
{
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,161 +0,0 @@
|
||||
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
|
||||
|
164
0044-multipathd-move-threads-destruction-into-separate-fu.patch
Normal file
164
0044-multipathd-move-threads-destruction-into-separate-fu.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 11:18:44 +0200
|
||||
Subject: [PATCH] multipathd: move threads destruction into separate function
|
||||
|
||||
Also, introduce booleans that indicate a certain thread has
|
||||
been started successfully. Using these booleans, we can avoid
|
||||
crashing by cancelling threads that have never been started.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 76 +++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 51 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index eb760a71..9eb658d4 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -129,6 +129,9 @@ static volatile enum daemon_status running_state = DAEMON_INIT;
|
||||
pid_t daemon_pid;
|
||||
static pthread_mutex_t config_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t config_cond;
|
||||
+static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr;
|
||||
+static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started,
|
||||
+ uevq_thr_started, dmevent_thr_started;
|
||||
|
||||
static inline enum daemon_status get_running_state(void)
|
||||
{
|
||||
@@ -2927,6 +2930,39 @@ static void cleanup_vecs(void)
|
||||
FREE(gvecs);
|
||||
}
|
||||
|
||||
+static void cleanup_threads(void)
|
||||
+{
|
||||
+ stop_io_err_stat_thread();
|
||||
+
|
||||
+ if (check_thr_started)
|
||||
+ pthread_cancel(check_thr);
|
||||
+ if (uevent_thr_started)
|
||||
+ pthread_cancel(uevent_thr);
|
||||
+ if (uxlsnr_thr_started)
|
||||
+ pthread_cancel(uxlsnr_thr);
|
||||
+ if (uevq_thr_started)
|
||||
+ pthread_cancel(uevq_thr);
|
||||
+ if (dmevent_thr_started)
|
||||
+ pthread_cancel(dmevent_thr);
|
||||
+
|
||||
+ if (check_thr_started)
|
||||
+ pthread_join(check_thr, NULL);
|
||||
+ if (uevent_thr_started)
|
||||
+ pthread_join(uevent_thr, NULL);
|
||||
+ if (uxlsnr_thr_started)
|
||||
+ pthread_join(uxlsnr_thr, NULL);
|
||||
+ if (uevq_thr_started)
|
||||
+ pthread_join(uevq_thr, NULL);
|
||||
+ if (dmevent_thr_started)
|
||||
+ pthread_join(dmevent_thr, NULL);
|
||||
+
|
||||
+ /*
|
||||
+ * As all threads are joined now, and we're in DAEMON_SHUTDOWN
|
||||
+ * state, no new waiter threads will be created any more.
|
||||
+ */
|
||||
+ pthread_attr_destroy(&waiter_attr);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Use a non-default call_rcu_data for child().
|
||||
*
|
||||
@@ -2972,7 +3008,6 @@ static void cleanup_rcu(void)
|
||||
static int
|
||||
child (__attribute__((unused)) void *param)
|
||||
{
|
||||
- pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr;
|
||||
pthread_attr_t log_attr, misc_attr, uevent_attr;
|
||||
struct vectors * vecs;
|
||||
int rc;
|
||||
@@ -3070,9 +3105,12 @@ child (__attribute__((unused)) void *param)
|
||||
condlog(0, "failed to create cli listener: %d", rc);
|
||||
goto failed;
|
||||
}
|
||||
- else if (state != DAEMON_CONFIGURE) {
|
||||
- condlog(0, "cli listener failed to start");
|
||||
- goto failed;
|
||||
+ else {
|
||||
+ uxlsnr_thr_started = true;
|
||||
+ if (state != DAEMON_CONFIGURE) {
|
||||
+ condlog(0, "cli listener failed to start");
|
||||
+ goto failed;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (poll_dmevents) {
|
||||
@@ -3085,7 +3123,8 @@ child (__attribute__((unused)) void *param)
|
||||
condlog(0, "failed to create dmevent waiter thread: %d",
|
||||
rc);
|
||||
goto failed;
|
||||
- }
|
||||
+ } else
|
||||
+ dmevent_thr_started = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3094,7 +3133,8 @@ child (__attribute__((unused)) void *param)
|
||||
if ((rc = pthread_create(&uevent_thr, &uevent_attr, ueventloop, udev))) {
|
||||
condlog(0, "failed to create uevent thread: %d", rc);
|
||||
goto failed;
|
||||
- }
|
||||
+ } else
|
||||
+ uevent_thr_started = true;
|
||||
pthread_attr_destroy(&uevent_attr);
|
||||
|
||||
/*
|
||||
@@ -3103,11 +3143,13 @@ child (__attribute__((unused)) void *param)
|
||||
if ((rc = pthread_create(&check_thr, &misc_attr, checkerloop, vecs))) {
|
||||
condlog(0,"failed to create checker loop thread: %d", rc);
|
||||
goto failed;
|
||||
- }
|
||||
+ } else
|
||||
+ check_thr_started = true;
|
||||
if ((rc = pthread_create(&uevq_thr, &misc_attr, uevqloop, vecs))) {
|
||||
condlog(0, "failed to create uevent dispatcher: %d", rc);
|
||||
goto failed;
|
||||
- }
|
||||
+ } else
|
||||
+ uevq_thr_started = true;
|
||||
pthread_attr_destroy(&misc_attr);
|
||||
|
||||
while (1) {
|
||||
@@ -3136,22 +3178,7 @@ child (__attribute__((unused)) void *param)
|
||||
}
|
||||
}
|
||||
|
||||
- pthread_cancel(check_thr);
|
||||
- pthread_cancel(uevent_thr);
|
||||
- pthread_cancel(uxlsnr_thr);
|
||||
- pthread_cancel(uevq_thr);
|
||||
- if (poll_dmevents)
|
||||
- pthread_cancel(dmevent_thr);
|
||||
-
|
||||
- pthread_join(check_thr, NULL);
|
||||
- pthread_join(uevent_thr, NULL);
|
||||
- pthread_join(uxlsnr_thr, NULL);
|
||||
- pthread_join(uevq_thr, NULL);
|
||||
- if (poll_dmevents)
|
||||
- pthread_join(dmevent_thr, NULL);
|
||||
-
|
||||
- stop_io_err_stat_thread();
|
||||
-
|
||||
+ cleanup_threads();
|
||||
cleanup_vecs();
|
||||
cleanup_foreign();
|
||||
cleanup_checkers();
|
||||
@@ -3178,7 +3205,6 @@ child (__attribute__((unused)) void *param)
|
||||
conf = rcu_dereference(multipath_conf);
|
||||
rcu_assign_pointer(multipath_conf, NULL);
|
||||
call_rcu(&conf->rcu, rcu_free_config);
|
||||
- pthread_attr_destroy(&waiter_attr);
|
||||
#ifdef _DEBUG_
|
||||
dbg_free_final(NULL);
|
||||
#endif
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,104 +0,0 @@
|
||||
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
|
||||
|
@ -0,0 +1,56 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 12:38:50 +0200
|
||||
Subject: [PATCH] multipathd: move conf destruction into separate function
|
||||
|
||||
Also removing the comment about dlog() and dm_write_log().
|
||||
dlog() can cope with get_multipath_config() returning NULL,
|
||||
and dm_write_log() hasn't accessed the configuration for a while.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 20 +++++++++++---------
|
||||
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 9eb658d4..07973e85 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2892,6 +2892,16 @@ set_oom_adj (void)
|
||||
condlog(0, "couldn't adjust oom score");
|
||||
}
|
||||
|
||||
+static void cleanup_conf(void) {
|
||||
+ struct config *conf;
|
||||
+
|
||||
+ conf = rcu_dereference(multipath_conf);
|
||||
+ if (!conf)
|
||||
+ return;
|
||||
+ rcu_assign_pointer(multipath_conf, NULL);
|
||||
+ call_rcu(&conf->rcu, rcu_free_config);
|
||||
+}
|
||||
+
|
||||
static void cleanup_maps(struct vectors *vecs)
|
||||
{
|
||||
int queue_without_daemon, i;
|
||||
@@ -3196,15 +3206,7 @@ child (__attribute__((unused)) void *param)
|
||||
|
||||
if (logsink == 1)
|
||||
log_thread_stop();
|
||||
-
|
||||
- /*
|
||||
- * Freeing config must be done after condlog() and dm_lib_exit(),
|
||||
- * because logging functions like dlog() and dm_write_log()
|
||||
- * reference the config.
|
||||
- */
|
||||
- conf = rcu_dereference(multipath_conf);
|
||||
- rcu_assign_pointer(multipath_conf, NULL);
|
||||
- call_rcu(&conf->rcu, rcu_free_config);
|
||||
+ cleanup_conf();
|
||||
#ifdef _DEBUG_
|
||||
dbg_free_final(NULL);
|
||||
#endif
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,64 +0,0 @@
|
||||
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,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 16:10:19 +0200
|
||||
Subject: [PATCH] multipathd: move pid destruction into separate function
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 07973e85..fc1f8d7f 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2892,6 +2892,12 @@ set_oom_adj (void)
|
||||
condlog(0, "couldn't adjust oom score");
|
||||
}
|
||||
|
||||
+static void cleanup_pidfile(void)
|
||||
+{
|
||||
+ condlog(3, "unlink pidfile");
|
||||
+ unlink(DEFAULT_PIDFILE);
|
||||
+}
|
||||
+
|
||||
static void cleanup_conf(void) {
|
||||
struct config *conf;
|
||||
|
||||
@@ -3199,9 +3205,7 @@ child (__attribute__((unused)) void *param)
|
||||
dm_lib_exit();
|
||||
|
||||
/* We're done here */
|
||||
- condlog(3, "unlink pidfile");
|
||||
- unlink(DEFAULT_PIDFILE);
|
||||
-
|
||||
+ cleanup_pidfile();
|
||||
condlog(2, "--------shut down-------");
|
||||
|
||||
if (logsink == 1)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,63 +0,0 @@
|
||||
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
|
||||
|
45
0047-multipathd-close-pidfile-on-exit.patch
Normal file
45
0047-multipathd-close-pidfile-on-exit.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 16:27:33 +0200
|
||||
Subject: [PATCH] multipathd: close pidfile on exit
|
||||
|
||||
It seems we've been doing this only in the failure case, for ages.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fc1f8d7f..f6b80668 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -132,6 +132,7 @@ static pthread_cond_t config_cond;
|
||||
static pthread_t check_thr, uevent_thr, uxlsnr_thr, uevq_thr, dmevent_thr;
|
||||
static bool check_thr_started, uevent_thr_started, uxlsnr_thr_started,
|
||||
uevq_thr_started, dmevent_thr_started;
|
||||
+static int pid_fd = -1;
|
||||
|
||||
static inline enum daemon_status get_running_state(void)
|
||||
{
|
||||
@@ -2894,6 +2895,8 @@ set_oom_adj (void)
|
||||
|
||||
static void cleanup_pidfile(void)
|
||||
{
|
||||
+ if (pid_fd >= 0)
|
||||
+ close(pid_fd);
|
||||
condlog(3, "unlink pidfile");
|
||||
unlink(DEFAULT_PIDFILE);
|
||||
}
|
||||
@@ -3027,7 +3030,6 @@ child (__attribute__((unused)) void *param)
|
||||
pthread_attr_t log_attr, misc_attr, uevent_attr;
|
||||
struct vectors * vecs;
|
||||
int rc;
|
||||
- int pid_fd = -1;
|
||||
struct config *conf;
|
||||
char *envp;
|
||||
enum daemon_status state;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Schremmer <steve.schremmer@netapp.com>
|
||||
Date: Mon, 6 Jul 2020 20:22:35 +0000
|
||||
Subject: [PATCH] libmultipath: add device to hwtable.c
|
||||
|
||||
Add FUJITSU ETERNUS_AHB defaults.
|
||||
|
||||
Signed-off-by: Steve Schremmer <steve.schremmer@netapp.com>
|
||||
Reviewed-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index d1fcfdb3..d680bdfc 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -428,6 +428,22 @@ static struct hwentry default_hw[] = {
|
||||
.pgpolicy = MULTIBUS,
|
||||
.no_path_retry = 10,
|
||||
},
|
||||
+ {
|
||||
+ /*
|
||||
+ * ETERNUS AB/HB
|
||||
+ * Maintainer: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
|
||||
+ */
|
||||
+ .vendor = "FUJITSU",
|
||||
+ .product = "ETERNUS_AHB",
|
||||
+ .bl_product = "Universal Xport",
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .checker_name = RDAC,
|
||||
+ .features = "2 pg_init_retries 50",
|
||||
+ .hwhandler = "1 rdac",
|
||||
+ .prio_name = PRIO_RDAC,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .no_path_retry = 30,
|
||||
+ },
|
||||
/*
|
||||
* Hitachi Vantara
|
||||
*
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 17:49:02 +0200
|
||||
Subject: [PATCH] multipathd: add helper for systemd notification at exit
|
||||
|
||||
Add sd_notify_exit().
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 22 +++++++++++++---------
|
||||
1 file changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index f6b80668..07068e4a 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -3024,6 +3024,17 @@ static void cleanup_rcu(void)
|
||||
rcu_unregister_thread();
|
||||
}
|
||||
|
||||
+static int sd_notify_exit(int err)
|
||||
+{
|
||||
+#ifdef USE_SYSTEMD
|
||||
+ char msg[24];
|
||||
+
|
||||
+ snprintf(msg, sizeof(msg), "ERRNO=%d", err);
|
||||
+ sd_notify(0, msg);
|
||||
+#endif
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
child (__attribute__((unused)) void *param)
|
||||
{
|
||||
@@ -3216,19 +3227,12 @@ child (__attribute__((unused)) void *param)
|
||||
#ifdef _DEBUG_
|
||||
dbg_free_final(NULL);
|
||||
#endif
|
||||
-
|
||||
-#ifdef USE_SYSTEMD
|
||||
- sd_notify(0, "ERRNO=0");
|
||||
-#endif
|
||||
- exit(0);
|
||||
+ exit(sd_notify_exit(0));
|
||||
|
||||
failed:
|
||||
-#ifdef USE_SYSTEMD
|
||||
- sd_notify(0, "ERRNO=1");
|
||||
-#endif
|
||||
if (pid_fd >= 0)
|
||||
close(pid_fd);
|
||||
- exit(1);
|
||||
+ exit(sd_notify_exit(1));
|
||||
}
|
||||
|
||||
static int
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: lixiaokeng <lixiaokeng@huawei.com>
|
||||
Date: Mon, 13 Jul 2020 13:07:40 +0200
|
||||
Subject: [PATCH] master - libmultipath: fix use after free when iscsi logs in
|
||||
|
||||
When two iscsi ips log in and out alternately and the following scripts run
|
||||
at the same time,
|
||||
|
||||
#!/bin/bash
|
||||
interval=5
|
||||
while true
|
||||
do
|
||||
iscsiadm -m node -p 9.41.147.171 &> /dev/null
|
||||
iscsiadm -m node -p 9.41.148.172 &> /dev/null
|
||||
iscsiadm -m session &> /dev/null
|
||||
rescan-scsi-bus.sh &> /dev/null
|
||||
multipath -v2 &> /dev/null
|
||||
multipath -ll &> /dev/null
|
||||
sleep $interval
|
||||
done
|
||||
|
||||
multipathd will have a segfault after about 30 mins.
|
||||
|
||||
The reason is that mpp->hwe is accessed after hwe is already freed. In
|
||||
extract_hwe_from_path func, mpp->hwe is set to pp->hwe, so they points to the
|
||||
same hwe. For some reasons, pp->mpp will be set to NULL in orphan_path func.
|
||||
Then, pp and hwe will be freed with (pp->mpp == NULL) in free_path func
|
||||
called by ev_remove_path func. However, mpp->hwe is not set to NULL while hwe
|
||||
is already freed. So, when iscsi device logs in and new path is added to mpp,
|
||||
mpp->hwe will be accessed in select_pgfailback func. Finally, use-after-free
|
||||
problem occurs.
|
||||
|
||||
The procedure details given as follows,
|
||||
1.wait_dmevents thread
|
||||
wait_dmevents
|
||||
->dmevent_loop
|
||||
->update_multipath
|
||||
->__setup_multipath
|
||||
->update_multipath_strings
|
||||
-> sync_paths
|
||||
->orphan_path
|
||||
2.uevqloop thread (iscsi log out, remove path)
|
||||
uevqloop
|
||||
->uevent_dispatch
|
||||
->service_uevq
|
||||
->uev_remove_path
|
||||
->ev_remove_path //pp->mpp is NULL
|
||||
->free_path(pp)
|
||||
//pp->hew are freed but mpp->hwe is not set to NULL
|
||||
3.ev_remove_path (iscsi log in, add path)
|
||||
uevqloop
|
||||
->uevent_dispatch
|
||||
->service_uevq
|
||||
->ev_add_path
|
||||
->select_pgfailback //mpp->hwe is accessed
|
||||
|
||||
Here, we will set mpp->hwe to NULL before setting pp->map to NULL in orphan_path
|
||||
func.
|
||||
|
||||
Signed-off-by: Tianxiong Lu <lutianxiong@huawei.com>
|
||||
Signed-off-by: lixiaokeng <lixiaokeng@huawei.com>
|
||||
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 8137ea21..430eaad7 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -93,6 +93,8 @@ int adopt_paths(vector pathvec, struct multipath *mpp)
|
||||
void orphan_path(struct path *pp, const char *reason)
|
||||
{
|
||||
condlog(3, "%s: orphan path, %s", pp->dev, reason);
|
||||
+ if (pp->mpp && pp->mpp->hwe == pp->hwe)
|
||||
+ pp->mpp->hwe = NULL;
|
||||
pp->mpp = NULL;
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
pp->uid_attribute = NULL;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 23 Sep 2020 17:57:16 +0200
|
||||
Subject: [PATCH] multipathd: child(): call cleanups in failure case, too
|
||||
|
||||
So far we haven't called any cleanup code if child() failed.
|
||||
Fix it.
|
||||
|
||||
Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 07068e4a..6b9e323e 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -3044,6 +3044,7 @@ child (__attribute__((unused)) void *param)
|
||||
struct config *conf;
|
||||
char *envp;
|
||||
enum daemon_status state;
|
||||
+ int exit_code = 1;
|
||||
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
signal_init();
|
||||
@@ -3207,6 +3208,8 @@ child (__attribute__((unused)) void *param)
|
||||
}
|
||||
}
|
||||
|
||||
+ exit_code = 0;
|
||||
+failed:
|
||||
cleanup_threads();
|
||||
cleanup_vecs();
|
||||
cleanup_foreign();
|
||||
@@ -3227,12 +3230,7 @@ child (__attribute__((unused)) void *param)
|
||||
#ifdef _DEBUG_
|
||||
dbg_free_final(NULL);
|
||||
#endif
|
||||
- exit(sd_notify_exit(0));
|
||||
-
|
||||
-failed:
|
||||
- if (pid_fd >= 0)
|
||||
- close(pid_fd);
|
||||
- exit(sd_notify_exit(1));
|
||||
+ return sd_notify_exit(exit_code);
|
||||
}
|
||||
|
||||
static int
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 13 Jul 2020 13:07:41 +0200
|
||||
Subject: [PATCH] libmultipath: warn if freeing path that holds mpp->hwe
|
||||
|
||||
This just adds an error message to the previous patch.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs_vec.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 430eaad7..cde4dbe6 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -93,8 +93,11 @@ int adopt_paths(vector pathvec, struct multipath *mpp)
|
||||
void orphan_path(struct path *pp, const char *reason)
|
||||
{
|
||||
condlog(3, "%s: orphan path, %s", pp->dev, reason);
|
||||
- if (pp->mpp && pp->mpp->hwe == pp->hwe)
|
||||
+ if (pp->mpp && pp->hwe && pp->mpp->hwe == pp->hwe) {
|
||||
+ condlog(0, "BUG: orphaning path %s that holds hwe of %s",
|
||||
+ pp->dev, pp->mpp->alias);
|
||||
pp->mpp->hwe = NULL;
|
||||
+ }
|
||||
pp->mpp = NULL;
|
||||
pp->dmstate = PSTATE_UNDEF;
|
||||
pp->uid_attribute = NULL;
|
||||
--
|
||||
2.17.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user