import device-mapper-multipath-0.8.3-3.el8
This commit is contained in:
parent
70e223f212
commit
6ef0bbb6c3
@ -1 +1 @@
|
||||
30bf38b713001c2b80b86d67473fbe20dc0f28cc SOURCES/multipath-tools-0.8.0.tgz
|
||||
f700dc1e4ce1d6952051467d4b245f9bd80286e3 SOURCES/multipath-tools-0.8.3.tgz
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/multipath-tools-0.8.0.tgz
|
||||
SOURCES/multipath-tools-0.8.3.tgz
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 24 Jan 2019 14:09:23 -0600
|
||||
Subject: [PATCH] BZ 1668693: disable user_friendly_names for NetApp
|
||||
|
||||
NetApp has tools that rely on devices using WWID names. To avoid
|
||||
breaking these, NetApp devices should continue to use WWID names, even
|
||||
if the default config is set to enable user_friendly_names. If users
|
||||
want to use user_friendly_names on NetApp devices, the must specifically
|
||||
override the device config.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index d3a8d9b..8776411 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -719,6 +719,7 @@ static struct hwentry default_hw[] = {
|
||||
.flush_on_last_del = FLUSH_ENABLED,
|
||||
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||
.prio_name = PRIO_ONTAP,
|
||||
+ .user_friendly_names = USER_FRIENDLY_NAMES_OFF,
|
||||
},
|
||||
{
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,277 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 19 Sep 2019 13:46:03 -0500
|
||||
Subject: [PATCH] multipathd: warn when configuration has been changed.
|
||||
|
||||
It would be helpful if multipathd could log a message when
|
||||
multipath.conf or files in the config_dir have been written to, both so
|
||||
that it can be used to send a notification to users, and to help with
|
||||
determining after the fact if multipathd was running with an older
|
||||
config, when the logs of multipathd's behaviour don't match with the
|
||||
current multipath.conf.
|
||||
|
||||
To do this, the multipathd uxlsnr thread now sets up inotify watches on
|
||||
both /etc/multipath.conf and the config_dir to watch if the files are
|
||||
deleted or closed after being opened for writing. In order to keep
|
||||
uxlsnr from polling repeatedly if the multipath.conf or the config_dir
|
||||
aren't present, it will only set up the watches once per reconfigure.
|
||||
However, since multipath.conf is far more likely to be replaced by a
|
||||
text editor than modified in place, if it gets removed, multipathd will
|
||||
immediately try to restart the watch on it (which will succeed if the
|
||||
file was simply replaced by a new copy). This does mean that if
|
||||
multipath.conf or the config_dir are actually removed and then later
|
||||
re-added, multipathd won't log any more messages for changes until the
|
||||
next reconfigure. But that seems like a fair trade-off to avoid
|
||||
repeatedly polling for files that aren't likely to appear.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.h | 1 +
|
||||
multipathd/main.c | 1 +
|
||||
multipathd/uxlsnr.c | 134 ++++++++++++++++++++++++++++++++++++++++--
|
||||
3 files changed, 130 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index ffec3103..e69aa07c 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -188,6 +188,7 @@ struct config {
|
||||
int find_multipaths_timeout;
|
||||
int marginal_pathgroups;
|
||||
unsigned int version[3];
|
||||
+ unsigned int sequence_nr;
|
||||
|
||||
char * multipath_dir;
|
||||
char * selector;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 34a57689..7b364cfe 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2618,6 +2618,7 @@ reconfigure (struct vectors * vecs)
|
||||
uxsock_timeout = conf->uxsock_timeout;
|
||||
|
||||
old = rcu_dereference(multipath_conf);
|
||||
+ conf->sequence_nr = old->sequence_nr + 1;
|
||||
rcu_assign_pointer(multipath_conf, conf);
|
||||
call_rcu(&old->rcu, rcu_free_config);
|
||||
|
||||
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
|
||||
index bc71679e..92d9a79a 100644
|
||||
--- a/multipathd/uxlsnr.c
|
||||
+++ b/multipathd/uxlsnr.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
+#include <sys/inotify.h>
|
||||
#include "checkers.h"
|
||||
#include "memory.h"
|
||||
#include "debug.h"
|
||||
@@ -51,6 +52,8 @@ struct client {
|
||||
LIST_HEAD(clients);
|
||||
pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
struct pollfd *polls;
|
||||
+int notify_fd = -1;
|
||||
+char *config_dir;
|
||||
|
||||
static bool _socket_client_is_root(int fd);
|
||||
|
||||
@@ -151,6 +154,8 @@ void uxsock_cleanup(void *arg)
|
||||
long ux_sock = (long)arg;
|
||||
|
||||
close(ux_sock);
|
||||
+ close(notify_fd);
|
||||
+ free(config_dir);
|
||||
|
||||
pthread_mutex_lock(&client_lock);
|
||||
list_for_each_entry_safe(client_loop, client_tmp, &clients, node) {
|
||||
@@ -162,6 +167,106 @@ void uxsock_cleanup(void *arg)
|
||||
free_polls();
|
||||
}
|
||||
|
||||
+/* failing to set the watch descriptor is o.k. we just miss a warning
|
||||
+ * message */
|
||||
+void reset_watch(int notify_fd, int *wds, unsigned int *sequence_nr)
|
||||
+{
|
||||
+ struct config *conf;
|
||||
+ int dir_reset = 0;
|
||||
+ int conf_reset = 0;
|
||||
+
|
||||
+ if (notify_fd == -1)
|
||||
+ return;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ /* instead of repeatedly try to reset the inotify watch if
|
||||
+ * the config directory or multipath.conf isn't there, just
|
||||
+ * do it once per reconfigure */
|
||||
+ if (*sequence_nr != conf->sequence_nr) {
|
||||
+ *sequence_nr = conf->sequence_nr;
|
||||
+ if (wds[0] == -1)
|
||||
+ conf_reset = 1;
|
||||
+ if (!config_dir || !conf->config_dir ||
|
||||
+ strcmp(config_dir, conf->config_dir)) {
|
||||
+ dir_reset = 1;
|
||||
+ if (config_dir)
|
||||
+ free(config_dir);
|
||||
+ if (conf->config_dir)
|
||||
+ config_dir = strdup(conf->config_dir);
|
||||
+ else
|
||||
+ config_dir = NULL;
|
||||
+ } else if (wds[1] == -1)
|
||||
+ dir_reset = 1;
|
||||
+ }
|
||||
+ put_multipath_config(conf);
|
||||
+
|
||||
+ if (dir_reset) {
|
||||
+ if (wds[1] != -1) {
|
||||
+ inotify_rm_watch(notify_fd, wds[1]);
|
||||
+ wds[1] = -1;
|
||||
+ }
|
||||
+ if (config_dir) {
|
||||
+ wds[1] = inotify_add_watch(notify_fd, config_dir,
|
||||
+ IN_CLOSE_WRITE | IN_DELETE |
|
||||
+ IN_ONLYDIR);
|
||||
+ if (wds[1] == -1)
|
||||
+ condlog(3, "didn't set up notifications on %s: %s", config_dir, strerror(errno));
|
||||
+ }
|
||||
+ }
|
||||
+ if (conf_reset) {
|
||||
+ wds[0] = inotify_add_watch(notify_fd, DEFAULT_CONFIGFILE,
|
||||
+ IN_CLOSE_WRITE);
|
||||
+ if (wds[0] == -1)
|
||||
+ condlog(3, "didn't set up notifications on /etc/multipath.conf: %s", strerror(errno));
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+void handle_inotify(int fd, int *wds)
|
||||
+{
|
||||
+ char buff[1024]
|
||||
+ __attribute__ ((aligned(__alignof__(struct inotify_event))));
|
||||
+ const struct inotify_event *event;
|
||||
+ ssize_t len;
|
||||
+ char *ptr;
|
||||
+ int i, got_notify = 0;
|
||||
+
|
||||
+ for (;;) {
|
||||
+ len = read(fd, buff, sizeof(buff));
|
||||
+ if (len <= 0) {
|
||||
+ if (len < 0 && errno != EAGAIN) {
|
||||
+ condlog(3, "error reading from inotify_fd");
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ if (wds[i] != -1) {
|
||||
+ inotify_rm_watch(fd, wds[i]);
|
||||
+ wds[i] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ got_notify = 1;
|
||||
+ for (ptr = buff; ptr < buff + len;
|
||||
+ ptr += sizeof(struct inotify_event) + event->len) {
|
||||
+ event = (const struct inotify_event *) ptr;
|
||||
+
|
||||
+ if (event->mask & IN_IGNORED) {
|
||||
+ /* multipathd.conf may have been overwritten.
|
||||
+ * Try once to reset the notification */
|
||||
+ if (wds[0] == event->wd)
|
||||
+ wds[0] = inotify_add_watch(notify_fd,
|
||||
+ DEFAULT_CONFIGFILE,
|
||||
+ IN_CLOSE_WRITE);
|
||||
+ else if (wds[1] == event->wd)
|
||||
+ wds[1] = -1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (got_notify)
|
||||
+ condlog(1, "Multipath configuration updated.\nReload multipathd for changes to take effect");
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* entry point
|
||||
*/
|
||||
@@ -173,13 +278,19 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
char *reply;
|
||||
sigset_t mask;
|
||||
int old_clients = MIN_POLLS;
|
||||
+ /* conf->sequence_nr will be 1 when uxsock_listen is first called */
|
||||
+ unsigned int sequence_nr = 0;
|
||||
+ int wds[2] = { -1, -1 };
|
||||
|
||||
condlog(3, "uxsock: startup listener");
|
||||
- polls = (struct pollfd *)MALLOC((MIN_POLLS + 1) * sizeof(struct pollfd));
|
||||
+ polls = (struct pollfd *)MALLOC((MIN_POLLS + 2) * sizeof(struct pollfd));
|
||||
if (!polls) {
|
||||
condlog(0, "uxsock: failed to allocate poll fds");
|
||||
exit_daemon();
|
||||
}
|
||||
+ notify_fd = inotify_init1(IN_NONBLOCK);
|
||||
+ if (notify_fd == -1) /* it's fine if notifications fail */
|
||||
+ condlog(3, "failed to start up configuration notifications");
|
||||
sigfillset(&mask);
|
||||
sigdelset(&mask, SIGINT);
|
||||
sigdelset(&mask, SIGTERM);
|
||||
@@ -198,18 +309,18 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
if (num_clients != old_clients) {
|
||||
struct pollfd *new;
|
||||
if (num_clients <= MIN_POLLS && old_clients > MIN_POLLS) {
|
||||
- new = REALLOC(polls, (1 + MIN_POLLS) *
|
||||
+ new = REALLOC(polls, (2 + MIN_POLLS) *
|
||||
sizeof(struct pollfd));
|
||||
} else if (num_clients <= MIN_POLLS && old_clients <= MIN_POLLS) {
|
||||
new = polls;
|
||||
} else {
|
||||
- new = REALLOC(polls, (1+num_clients) *
|
||||
+ new = REALLOC(polls, (2 + num_clients) *
|
||||
sizeof(struct pollfd));
|
||||
}
|
||||
if (!new) {
|
||||
pthread_mutex_unlock(&client_lock);
|
||||
condlog(0, "%s: failed to realloc %d poll fds",
|
||||
- "uxsock", 1 + num_clients);
|
||||
+ "uxsock", 2 + num_clients);
|
||||
sched_yield();
|
||||
continue;
|
||||
}
|
||||
@@ -219,8 +330,15 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
polls[0].fd = ux_sock;
|
||||
polls[0].events = POLLIN;
|
||||
|
||||
+ reset_watch(notify_fd, wds, &sequence_nr);
|
||||
+ if (notify_fd == -1 || (wds[0] == -1 && wds[1] == -1))
|
||||
+ polls[1].fd = -1;
|
||||
+ else
|
||||
+ polls[1].fd = notify_fd;
|
||||
+ polls[1].events = POLLIN;
|
||||
+
|
||||
/* setup the clients */
|
||||
- i = 1;
|
||||
+ i = 2;
|
||||
list_for_each_entry(c, &clients, node) {
|
||||
polls[i].fd = c->fd;
|
||||
polls[i].events = POLLIN;
|
||||
@@ -262,7 +380,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
}
|
||||
|
||||
/* see if a client wants to speak to us */
|
||||
- for (i = 1; i < num_clients + 1; i++) {
|
||||
+ for (i = 2; i < num_clients + 2; i++) {
|
||||
if (polls[i].revents & POLLIN) {
|
||||
struct timespec start_time;
|
||||
|
||||
@@ -321,6 +439,10 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, long ux_sock,
|
||||
if (polls[0].revents & POLLIN) {
|
||||
new_client(ux_sock);
|
||||
}
|
||||
+
|
||||
+ /* handle inotify events on config files */
|
||||
+ if (polls[1].revents & POLLIN)
|
||||
+ handle_inotify(notify_fd, wds);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
--
|
||||
2.17.2
|
||||
|
59
SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch
Normal file
59
SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 7 Oct 2019 17:17:13 -0500
|
||||
Subject: [PATCH] libmultipath: fix leak in foreign code
|
||||
|
||||
If scandir fails or finds no foreign libraries, enable_re needs to be
|
||||
freed before exitting.
|
||||
|
||||
Fixes: 8d03eda4 'multipath.conf: add "enable_foreign" parameter'
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/foreign.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/foreign.c b/libmultipath/foreign.c
|
||||
index 4b34e141..68e9a9b8 100644
|
||||
--- a/libmultipath/foreign.c
|
||||
+++ b/libmultipath/foreign.c
|
||||
@@ -129,7 +129,7 @@ static int _init_foreign(const char *multipath_dir, const char *enable)
|
||||
char pathbuf[PATH_MAX];
|
||||
struct dirent **di;
|
||||
struct scandir_result sr;
|
||||
- int r, i;
|
||||
+ int r, i, ret = 0;
|
||||
regex_t *enable_re = NULL;
|
||||
|
||||
foreigns = vector_alloc();
|
||||
@@ -157,13 +157,15 @@ static int _init_foreign(const char *multipath_dir, const char *enable)
|
||||
if (r == 0) {
|
||||
condlog(3, "%s: no foreign multipath libraries found",
|
||||
__func__);
|
||||
- return 0;
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
} else if (r < 0) {
|
||||
r = errno;
|
||||
condlog(1, "%s: error %d scanning foreign multipath libraries",
|
||||
__func__, r);
|
||||
_cleanup_foreign();
|
||||
- return -r;
|
||||
+ ret = -r;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
sr.di = di;
|
||||
@@ -250,8 +252,9 @@ static int _init_foreign(const char *multipath_dir, const char *enable)
|
||||
free_foreign(fgn);
|
||||
}
|
||||
pthread_cleanup_pop(1); /* free_scandir_result */
|
||||
+out:
|
||||
pthread_cleanup_pop(1); /* free_pre */
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
int init_foreign(const char *multipath_dir, const char *enable)
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 16:45:26 -0600
|
||||
Subject: [PATCH] libmultipath: handle existing paths in marginal_path enqueue
|
||||
|
||||
If the path that enqueue_io_err_stat_by_path() is trying to add
|
||||
is already on the list, just return success. There's no reason
|
||||
to fail in this case.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 02b1453..1cb3ffe 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -254,7 +254,6 @@ static void free_io_err_pathvec(struct io_err_stat_pathvec *p)
|
||||
* return value
|
||||
* 0: enqueue OK
|
||||
* 1: fails because of internal error
|
||||
- * 2: fails because of existing already
|
||||
*/
|
||||
static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
{
|
||||
@@ -264,7 +263,7 @@ static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
p = find_err_path_by_dev(paths->pathvec, path->dev);
|
||||
if (p) {
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
- return 2;
|
||||
+ return 0;
|
||||
}
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
|
||||
@@ -418,9 +417,8 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(3, "%s: enqueue fails, to recover",
|
||||
pp->dev);
|
||||
goto recover;
|
||||
- } else if (!r) {
|
||||
+ } else
|
||||
pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING;
|
||||
- }
|
||||
}
|
||||
|
||||
return 1;
|
||||
--
|
||||
2.17.2
|
||||
|
28
SOURCES/0003-Fix-leak-in-mpathpersist.patch
Normal file
28
SOURCES/0003-Fix-leak-in-mpathpersist.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 8 Oct 2019 10:17:11 -0500
|
||||
Subject: [PATCH] Fix leak in mpathpersist
|
||||
|
||||
If the persistent in command fails, the response buffer must be freed.
|
||||
Found by Coverity
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
mpathpersist/main.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/mpathpersist/main.c b/mpathpersist/main.c
|
||||
index 278b8d51..920e686c 100644
|
||||
--- a/mpathpersist/main.c
|
||||
+++ b/mpathpersist/main.c
|
||||
@@ -499,6 +499,7 @@ static int handle_args(int argc, char * argv[], int nline)
|
||||
if (ret != MPATH_PR_SUCCESS )
|
||||
{
|
||||
fprintf (stderr, "Persistent Reserve IN command failed\n");
|
||||
+ free(resp);
|
||||
goto out_fd;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,70 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 25 Jan 2019 17:09:42 -0600
|
||||
Subject: [PATCH] multipathd: cleanup marginal paths checking timers
|
||||
|
||||
When a path gets recovered in hit_io_err_recheck_time(), it will
|
||||
continue running in check_path(), so there is no reason to schedule
|
||||
another path check as soon as possible (since one is currently
|
||||
happening).
|
||||
|
||||
Also, there isn't much point in restarting the io err stat checking when
|
||||
the path is down, so hit_io_err_recheck_time() should only be run when
|
||||
the path is up. Downed marginal paths can be treated just like any other
|
||||
downed path.
|
||||
|
||||
Finally, there is no reason to set reset pp->io_err_dis_reinstate_time
|
||||
when we decide to enqueue a path. Either th enqueue will fail and the
|
||||
path will get recovered, or it will succeed, and we won't check the
|
||||
reinstate time again until poll_io_err_stat() marks the path as needing
|
||||
a requeue.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 8 --------
|
||||
multipathd/main.c | 3 ++-
|
||||
2 files changed, 2 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 1cb3ffe..416e13a 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -400,13 +400,6 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(4, "%s: reschedule checking after %d seconds",
|
||||
pp->dev,
|
||||
pp->mpp->marginal_path_err_recheck_gap_time);
|
||||
- /*
|
||||
- * to reschedule io error checking again
|
||||
- * if the path is good enough, we claim it is good
|
||||
- * and can be reinsated as soon as possible in the
|
||||
- * check_path routine.
|
||||
- */
|
||||
- pp->io_err_dis_reinstate_time = curr_time.tv_sec;
|
||||
r = enqueue_io_err_stat_by_path(pp);
|
||||
/*
|
||||
* Enqueue fails because of internal error.
|
||||
@@ -426,7 +419,6 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
recover:
|
||||
pp->io_err_pathfail_cnt = 0;
|
||||
pp->io_err_disable_reinstate = 0;
|
||||
- pp->tick = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fb520b6..fe6d8ef 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2079,7 +2079,8 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
+ if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
+ pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
pp->state = PATH_SHAKY;
|
||||
/*
|
||||
* to reschedule as soon as possible,so that this path can
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,176 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 28 Jan 2019 00:20:53 -0600
|
||||
Subject: [PATCH] libmultipath: fix marginal paths queueing errors
|
||||
|
||||
The current marginal paths code tries to enqueue paths for io error
|
||||
checking when multipathd receives a uevent on path failure. This can run
|
||||
into a couple of problems. First, this uevent could happen before or
|
||||
after multipathd actually fails the path, so simply checking nr_active
|
||||
doesn't tell us if this is the last active path. Also, The code to fail
|
||||
the path in enqueue_io_err_stat_by_path() doesn't ever update the path
|
||||
state. This can cause the path to get failed twice, temporarily leading
|
||||
to incorrect nr_active counts. Further, The point when multipathd should
|
||||
care if this is the last active path is when the path has come up again,
|
||||
not when it goes down. Lastly, if the path is down, it is often
|
||||
impossible to open the path device, causing setup_directio_ctx() to
|
||||
fail, which causes multipathd to skip io error checking and mark the
|
||||
path as not marginal.
|
||||
|
||||
Instead, multipathd should just make sure that if the path is marginal,
|
||||
it gets failed in the uevent, so as not to race with the checkerloop
|
||||
thread. Then, when the path comes back up, check_path() can enqueue it,
|
||||
just like it does for paths that need to get rechecked. To make it
|
||||
obvious that the state PATH_IO_ERR_IN_POLLING_RECHECK and the function
|
||||
hit_io_err_recheck_time() now apply to paths waiting to be enqueued for
|
||||
the first time as well, I've also changed their names to
|
||||
PATH_IO_ERR_WAITING_TO_CHECK and need_io_err_check(), respectively.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 55 +++++++++++++++++---------------------
|
||||
libmultipath/io_err_stat.h | 2 +-
|
||||
multipathd/main.c | 2 +-
|
||||
3 files changed, 27 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 416e13a..72aacf3 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -41,7 +41,7 @@
|
||||
#define CONCUR_NR_EVENT 32
|
||||
|
||||
#define PATH_IO_ERR_IN_CHECKING -1
|
||||
-#define PATH_IO_ERR_IN_POLLING_RECHECK -2
|
||||
+#define PATH_IO_ERR_WAITING_TO_CHECK -2
|
||||
|
||||
#define io_err_stat_log(prio, fmt, args...) \
|
||||
condlog(prio, "io error statistic: " fmt, ##args)
|
||||
@@ -283,24 +283,6 @@ static int enqueue_io_err_stat_by_path(struct path *path)
|
||||
vector_set_slot(paths->pathvec, p);
|
||||
pthread_mutex_unlock(&paths->mutex);
|
||||
|
||||
- if (!path->io_err_disable_reinstate) {
|
||||
- /*
|
||||
- *fail the path in the kernel for the time of the to make
|
||||
- *the test more reliable
|
||||
- */
|
||||
- io_err_stat_log(3, "%s: fail dm path %s before checking",
|
||||
- path->mpp->alias, path->dev);
|
||||
- path->io_err_disable_reinstate = 1;
|
||||
- dm_fail_path(path->mpp->alias, path->dev_t);
|
||||
- update_queue_mode_del_path(path->mpp);
|
||||
-
|
||||
- /*
|
||||
- * schedule path check as soon as possible to
|
||||
- * update path state to delayed state
|
||||
- */
|
||||
- path->tick = 1;
|
||||
-
|
||||
- }
|
||||
io_err_stat_log(2, "%s: enqueue path %s to check",
|
||||
path->mpp->alias, path->dev);
|
||||
return 0;
|
||||
@@ -317,7 +299,6 @@ free_ioerr_path:
|
||||
int io_err_stat_handle_pathfail(struct path *path)
|
||||
{
|
||||
struct timespec curr_time;
|
||||
- int res;
|
||||
|
||||
if (uatomic_read(&io_err_thread_running) == 0)
|
||||
return 1;
|
||||
@@ -332,8 +313,6 @@ int io_err_stat_handle_pathfail(struct path *path)
|
||||
|
||||
if (!path->mpp)
|
||||
return 1;
|
||||
- if (path->mpp->nr_active <= 1)
|
||||
- return 1;
|
||||
if (path->mpp->marginal_path_double_failed_time <= 0 ||
|
||||
path->mpp->marginal_path_err_sample_time <= 0 ||
|
||||
path->mpp->marginal_path_err_recheck_gap_time <= 0 ||
|
||||
@@ -371,17 +350,33 @@ int io_err_stat_handle_pathfail(struct path *path)
|
||||
}
|
||||
path->io_err_pathfail_cnt++;
|
||||
if (path->io_err_pathfail_cnt >= FLAKY_PATHFAIL_THRESHOLD) {
|
||||
- res = enqueue_io_err_stat_by_path(path);
|
||||
- if (!res)
|
||||
- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING;
|
||||
- else
|
||||
- path->io_err_pathfail_cnt = 0;
|
||||
+ path->io_err_disable_reinstate = 1;
|
||||
+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
+ /* enqueue path as soon as it comes up */
|
||||
+ path->io_err_dis_reinstate_time = 0;
|
||||
+ if (path->state != PATH_DOWN) {
|
||||
+ struct config *conf;
|
||||
+ int oldstate = path->state;
|
||||
+ int checkint;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ checkint = conf->checkint;
|
||||
+ put_multipath_config(conf);
|
||||
+ io_err_stat_log(2, "%s: mark as failed", path->dev);
|
||||
+ path->mpp->stat_path_failures++;
|
||||
+ path->state = PATH_DOWN;
|
||||
+ path->dmstate = PSTATE_FAILED;
|
||||
+ if (oldstate == PATH_UP || oldstate == PATH_GHOST)
|
||||
+ update_queue_mode_del_path(path->mpp);
|
||||
+ if (path->tick > checkint)
|
||||
+ path->tick = checkint;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int hit_io_err_recheck_time(struct path *pp)
|
||||
+int need_io_err_check(struct path *pp)
|
||||
{
|
||||
struct timespec curr_time;
|
||||
int r;
|
||||
@@ -392,7 +387,7 @@ int hit_io_err_recheck_time(struct path *pp)
|
||||
io_err_stat_log(2, "%s: recover path early", pp->dev);
|
||||
goto recover;
|
||||
}
|
||||
- if (pp->io_err_pathfail_cnt != PATH_IO_ERR_IN_POLLING_RECHECK)
|
||||
+ if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK)
|
||||
return 1;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 ||
|
||||
(curr_time.tv_sec - pp->io_err_dis_reinstate_time) >
|
||||
@@ -489,7 +484,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp)
|
||||
} else if (path->mpp && path->mpp->nr_active > 1) {
|
||||
io_err_stat_log(3, "%s: keep failing the dm path %s",
|
||||
path->mpp->alias, path->dev);
|
||||
- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_POLLING_RECHECK;
|
||||
+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
path->io_err_disable_reinstate = 1;
|
||||
path->io_err_dis_reinstate_time = currtime.tv_sec;
|
||||
io_err_stat_log(3, "%s: disable reinstating of %s",
|
||||
diff --git a/libmultipath/io_err_stat.h b/libmultipath/io_err_stat.h
|
||||
index bbf31b4..53d6d7d 100644
|
||||
--- a/libmultipath/io_err_stat.h
|
||||
+++ b/libmultipath/io_err_stat.h
|
||||
@@ -10,6 +10,6 @@ extern pthread_attr_t io_err_stat_attr;
|
||||
int start_io_err_stat_thread(void *data);
|
||||
void stop_io_err_stat_thread(void);
|
||||
int io_err_stat_handle_pathfail(struct path *path);
|
||||
-int hit_io_err_recheck_time(struct path *pp);
|
||||
+int need_io_err_check(struct path *pp);
|
||||
|
||||
#endif /* _IO_ERR_STAT_H */
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fe6d8ef..43830e8 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2080,7 +2080,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
}
|
||||
|
||||
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
- pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) {
|
||||
+ pp->io_err_disable_reinstate && need_io_err_check(pp)) {
|
||||
pp->state = PATH_SHAKY;
|
||||
/*
|
||||
* to reschedule as soon as possible,so that this path can
|
||||
--
|
||||
2.17.2
|
||||
|
25
SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch
Normal file
25
SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 5 Nov 2019 13:53:29 -0600
|
||||
Subject: [PATCH] libmultipath: remove unused path->prio_args
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index a3adf906..1c32a799 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -272,7 +272,6 @@ struct path {
|
||||
char * uid_attribute;
|
||||
char * getuid;
|
||||
struct prio prio;
|
||||
- char * prio_args;
|
||||
struct checker checker;
|
||||
struct multipath * mpp;
|
||||
int fd;
|
||||
--
|
||||
2.17.2
|
||||
|
34
SOURCES/0005-libmultipath-constify-get_unaligned_be.patch
Normal file
34
SOURCES/0005-libmultipath-constify-get_unaligned_be.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 6 Nov 2019 16:49:40 -0600
|
||||
Subject: [PATCH] libmultipath: constify get_unaligned_be*
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/unaligned.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/unaligned.h b/libmultipath/unaligned.h
|
||||
index 68c07742..b9eaa7cb 100644
|
||||
--- a/libmultipath/unaligned.h
|
||||
+++ b/libmultipath/unaligned.h
|
||||
@@ -10,14 +10,14 @@ static inline uint16_t get_unaligned_be16(const void *ptr)
|
||||
return p[0] << 8 | p[1];
|
||||
}
|
||||
|
||||
-static inline uint32_t get_unaligned_be32(void *ptr)
|
||||
+static inline uint32_t get_unaligned_be32(const void *ptr)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
|
||||
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
||||
}
|
||||
|
||||
-static inline uint64_t get_unaligned_be64(void *ptr)
|
||||
+static inline uint64_t get_unaligned_be64(const void *ptr)
|
||||
{
|
||||
uint32_t low = get_unaligned_be32(ptr + 4);
|
||||
uint64_t high = get_unaligned_be32(ptr);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 29 Jan 2019 18:26:04 -0600
|
||||
Subject: [PATCH] libmultipath: fix marginal_paths nr_active check
|
||||
|
||||
Marginal paths are SHAKY, so they don't count towards the number of
|
||||
active paths. poll_io_err_stat() shouldn't automatically reinstate a
|
||||
marginal path if there already is an active path.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/io_err_stat.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c
|
||||
index 72aacf3..554b777 100644
|
||||
--- a/libmultipath/io_err_stat.c
|
||||
+++ b/libmultipath/io_err_stat.c
|
||||
@@ -481,7 +481,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp)
|
||||
*/
|
||||
path->tick = 1;
|
||||
|
||||
- } else if (path->mpp && path->mpp->nr_active > 1) {
|
||||
+ } else if (path->mpp && path->mpp->nr_active > 0) {
|
||||
io_err_stat_log(3, "%s: keep failing the dm path %s",
|
||||
path->mpp->alias, path->dev);
|
||||
path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK;
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 5 Nov 2019 12:37:58 -0600
|
||||
Subject: [PATCH] libmultipath: add missing hwe mpe variable merges
|
||||
|
||||
There were some variables in the hwe and mpe structs that weren't being
|
||||
merged by merge_hwe() and merge_mpe().
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 20e3b8bf..85626e96 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -372,6 +372,10 @@ merge_hwe (struct hwentry * dst, struct hwentry * src)
|
||||
merge_num(san_path_err_threshold);
|
||||
merge_num(san_path_err_forget_rate);
|
||||
merge_num(san_path_err_recovery_time);
|
||||
+ merge_num(marginal_path_err_sample_time);
|
||||
+ merge_num(marginal_path_err_rate_threshold);
|
||||
+ merge_num(marginal_path_err_recheck_gap_time);
|
||||
+ merge_num(marginal_path_double_failed_time);
|
||||
|
||||
snprintf(id, sizeof(id), "%s/%s", dst->vendor, dst->product);
|
||||
reconcile_features_with_options(id, &dst->features,
|
||||
@@ -397,6 +401,7 @@ merge_mpe(struct mpentry *dst, struct mpentry *src)
|
||||
if (dst->prkey_source == PRKEY_SOURCE_NONE &&
|
||||
src->prkey_source != PRKEY_SOURCE_NONE) {
|
||||
dst->prkey_source = src->prkey_source;
|
||||
+ dst->sa_flags = src->sa_flags;
|
||||
memcpy(&dst->reservation_key, &src->reservation_key,
|
||||
sizeof(dst->reservation_key));
|
||||
}
|
||||
@@ -413,6 +418,9 @@ merge_mpe(struct mpentry *dst, struct mpentry *src)
|
||||
merge_num(deferred_remove);
|
||||
merge_num(delay_watch_checks);
|
||||
merge_num(delay_wait_checks);
|
||||
+ merge_num(san_path_err_threshold);
|
||||
+ merge_num(san_path_err_forget_rate);
|
||||
+ merge_num(san_path_err_recovery_time);
|
||||
merge_num(marginal_path_err_sample_time);
|
||||
merge_num(marginal_path_err_rate_threshold);
|
||||
merge_num(marginal_path_err_recheck_gap_time);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 15 Feb 2019 17:19:46 -0600
|
||||
Subject: [PATCH] multipathd: Fix miscounting active paths
|
||||
|
||||
When multipathd gets a change uevent, it calls pathinfo with DI_NOIO.
|
||||
This sets the path state to the return value of path_offline(). If a
|
||||
path is in the PATH_DOWN state but path_offline() returns PATH_UP, when
|
||||
that path gets a change event, its state will get moved to PATH_UP
|
||||
without either reinstating the path, or reloading the map. The next
|
||||
call to check_path() will move the path back to PATH_DOWN. Since
|
||||
check_path() simply increments and decrements nr_active instead of
|
||||
calculating it based on the actual number of active paths, nr_active
|
||||
will get decremented a second time for this failed path, potentially
|
||||
putting the multipath device into recovery mode.
|
||||
|
||||
This commit does two things to avoid this situation. It makes the
|
||||
DI_NOIO flag only set pp->state in pathinfo() if DI_CHECKER is also set.
|
||||
This isn't set in uev_update_path() to avoid changing the path state in
|
||||
this case. Also, to guard against pp->state getting changed in some
|
||||
other code path without properly updating the map state, check_path()
|
||||
now calls set_no_path_retry, which recalculates nr_active based on the
|
||||
actual number of active paths, and makes sure that the queue_if_no_path
|
||||
value in the features line is correct.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 11 ++++++-----
|
||||
multipath/main.c | 2 +-
|
||||
multipathd/main.c | 4 +++-
|
||||
3 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 10bd8cd..729bcb9 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1914,11 +1914,12 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
if (path_state == PATH_REMOVED)
|
||||
goto blank;
|
||||
else if (mask & DI_NOIO) {
|
||||
- /*
|
||||
- * Avoid any IO on the device itself.
|
||||
- * Behave like DI_CHECKER in the "path unavailable" case.
|
||||
- */
|
||||
- pp->chkrstate = pp->state = path_state;
|
||||
+ if (mask & DI_CHECKER)
|
||||
+ /*
|
||||
+ * Avoid any IO on the device itself.
|
||||
+ * simply use the path_offline() return as its state
|
||||
+ */
|
||||
+ pp->chkrstate = pp->state = path_state;
|
||||
return PATHINFO_OK;
|
||||
}
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 5abb118..69141db 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -356,7 +356,7 @@ static int check_usable_paths(struct config *conf,
|
||||
pp->udev = get_udev_device(pp->dev_t, DEV_DEVT);
|
||||
if (pp->udev == NULL)
|
||||
continue;
|
||||
- if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) != PATHINFO_OK)
|
||||
+ if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO|DI_CHECKER) != PATHINFO_OK)
|
||||
continue;
|
||||
|
||||
if (pp->state == PATH_UP &&
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 43830e8..678ecf8 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -392,7 +392,8 @@ static void set_no_path_retry(struct multipath *mpp)
|
||||
default:
|
||||
if (mpp->nr_active > 0) {
|
||||
mpp->retry_tick = 0;
|
||||
- dm_queue_if_no_path(mpp->alias, 1);
|
||||
+ if (!is_queueing)
|
||||
+ dm_queue_if_no_path(mpp->alias, 1);
|
||||
} else if (is_queueing && mpp->retry_tick == 0)
|
||||
enter_recovery_mode(mpp);
|
||||
break;
|
||||
@@ -2072,6 +2073,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
/* if update_multipath_strings orphaned the path, quit early */
|
||||
if (!pp->mpp)
|
||||
return 0;
|
||||
+ set_no_path_retry(pp->mpp);
|
||||
|
||||
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
||||
check_path_reinstate_state(pp)) {
|
||||
--
|
||||
2.17.2
|
||||
|
204
SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch
Normal file
204
SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch
Normal file
@ -0,0 +1,204 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 1 Nov 2019 10:33:04 -0500
|
||||
Subject: [PATCH] libmultipath: fix sgio_get_vpd looping
|
||||
|
||||
If do_inq returns a page with a length that is less than maxlen, but
|
||||
larger than DEFAULT_SGIO_LEN, this function will loop forever. Also
|
||||
if do_inq returns with a length equal to or greater than maxlen,
|
||||
sgio_get_vpd will exit immediately, even if it hasn't read the entire
|
||||
page. Fix these issues, modify the tests to verify the new behavior.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 12 +++---
|
||||
tests/vpd.c | 84 ++++++++++++++++++++++++----------------
|
||||
2 files changed, 57 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 72f455e8..3c72a80a 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -870,6 +870,7 @@ static int
|
||||
sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg)
|
||||
{
|
||||
int len = DEFAULT_SGIO_LEN;
|
||||
+ int rlen;
|
||||
|
||||
if (fd < 0) {
|
||||
errno = EBADF;
|
||||
@@ -877,12 +878,11 @@ sgio_get_vpd (unsigned char * buff, int maxlen, int fd, int pg)
|
||||
}
|
||||
retry:
|
||||
if (0 == do_inq(fd, 0, 1, pg, buff, len)) {
|
||||
- len = get_unaligned_be16(&buff[2]) + 4;
|
||||
- if (len >= maxlen)
|
||||
- return len;
|
||||
- if (len > DEFAULT_SGIO_LEN)
|
||||
- goto retry;
|
||||
- return len;
|
||||
+ rlen = get_unaligned_be16(&buff[2]) + 4;
|
||||
+ if (rlen <= len || len >= maxlen)
|
||||
+ return rlen;
|
||||
+ len = (rlen < maxlen)? rlen : maxlen;
|
||||
+ goto retry;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
diff --git a/tests/vpd.c b/tests/vpd.c
|
||||
index d9f80eaa..4dbce010 100644
|
||||
--- a/tests/vpd.c
|
||||
+++ b/tests/vpd.c
|
||||
@@ -306,7 +306,7 @@ static int create_vpd83(unsigned char *buf, size_t bufsiz, const char *id,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
- put_unaligned_be16(n, buf + 2);
|
||||
+ put_unaligned_be16(bufsiz, buf + 2);
|
||||
return n + 4;
|
||||
}
|
||||
|
||||
@@ -429,6 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \
|
||||
free(exp_wwid); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
+ will_return(__wrap_ioctl, n); \
|
||||
+ will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \
|
||||
exp_len, ret, '1', 0, false, \
|
||||
@@ -459,6 +461,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \
|
||||
exp_len = wlen - 1; \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
+ will_return(__wrap_ioctl, n); \
|
||||
+ will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \
|
||||
exp_len, ret, byte0[type], 0, \
|
||||
@@ -496,6 +500,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \
|
||||
3, naa, 0); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
+ will_return(__wrap_ioctl, n); \
|
||||
+ will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \
|
||||
exp_len, ret, '3', '0' + naa, true, \
|
||||
@@ -506,22 +512,26 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \
|
||||
* test_vpd_eui_LEN_WLEN() - test code for VPD 83, EUI64
|
||||
* @LEN: EUI64 length (8, 12, or 16)
|
||||
* @WLEN: WWID buffer size
|
||||
+ * @SML: Use small VPD page size
|
||||
*/
|
||||
-#define make_test_vpd_eui(len, wlen) \
|
||||
-static void test_vpd_eui_ ## len ## _ ## wlen(void **state) \
|
||||
+#define make_test_vpd_eui(len, wlen, sml) \
|
||||
+static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \
|
||||
{ \
|
||||
struct vpdtest *vt = *state; \
|
||||
int n, ret; \
|
||||
/* returned size is always uneven */ \
|
||||
int exp_len = wlen > 2 * len + 1 ? 2 * len + 1 : \
|
||||
wlen % 2 == 0 ? wlen - 1 : wlen - 2; \
|
||||
+ int bufsize = sml ? 255 : sizeof(vt->vpdbuf); \
|
||||
\
|
||||
- n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, \
|
||||
+ n = create_vpd83(vt->vpdbuf, bufsize, test_id, \
|
||||
2, 0, len); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
+ will_return(__wrap_ioctl, n); \
|
||||
+ will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
- assert_correct_wwid("test_vpd_eui_" #len "_" #wlen, \
|
||||
+ assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \
|
||||
exp_len, ret, '2', 0, true, \
|
||||
test_id, vt->wwid); \
|
||||
}
|
||||
@@ -603,25 +613,30 @@ make_test_vpd_vnd(20, 10);
|
||||
make_test_vpd_vnd(10, 10);
|
||||
|
||||
/* EUI64 tests */
|
||||
+/* small vpd page test */
|
||||
+make_test_vpd_eui(8, 32, 1);
|
||||
+make_test_vpd_eui(12, 32, 1);
|
||||
+make_test_vpd_eui(16, 40, 1);
|
||||
+
|
||||
/* 64bit, WWID size: 18 */
|
||||
-make_test_vpd_eui(8, 32);
|
||||
-make_test_vpd_eui(8, 18);
|
||||
-make_test_vpd_eui(8, 17);
|
||||
-make_test_vpd_eui(8, 16);
|
||||
-make_test_vpd_eui(8, 10);
|
||||
+make_test_vpd_eui(8, 32, 0);
|
||||
+make_test_vpd_eui(8, 18, 0);
|
||||
+make_test_vpd_eui(8, 17, 0);
|
||||
+make_test_vpd_eui(8, 16, 0);
|
||||
+make_test_vpd_eui(8, 10, 0);
|
||||
|
||||
/* 96 bit, WWID size: 26 */
|
||||
-make_test_vpd_eui(12, 32);
|
||||
-make_test_vpd_eui(12, 26);
|
||||
-make_test_vpd_eui(12, 25);
|
||||
-make_test_vpd_eui(12, 20);
|
||||
-make_test_vpd_eui(12, 10);
|
||||
+make_test_vpd_eui(12, 32, 0);
|
||||
+make_test_vpd_eui(12, 26, 0);
|
||||
+make_test_vpd_eui(12, 25, 0);
|
||||
+make_test_vpd_eui(12, 20, 0);
|
||||
+make_test_vpd_eui(12, 10, 0);
|
||||
|
||||
/* 128 bit, WWID size: 34 */
|
||||
-make_test_vpd_eui(16, 40);
|
||||
-make_test_vpd_eui(16, 34);
|
||||
-make_test_vpd_eui(16, 33);
|
||||
-make_test_vpd_eui(16, 20);
|
||||
+make_test_vpd_eui(16, 40, 0);
|
||||
+make_test_vpd_eui(16, 34, 0);
|
||||
+make_test_vpd_eui(16, 33, 0);
|
||||
+make_test_vpd_eui(16, 20, 0);
|
||||
|
||||
/* NAA IEEE registered extended (36), WWID size: 34 */
|
||||
make_test_vpd_naa(6, 40);
|
||||
@@ -722,20 +737,23 @@ static int test_vpd(void)
|
||||
cmocka_unit_test(test_vpd_vnd_19_20),
|
||||
cmocka_unit_test(test_vpd_vnd_20_10),
|
||||
cmocka_unit_test(test_vpd_vnd_10_10),
|
||||
- cmocka_unit_test(test_vpd_eui_8_32),
|
||||
- cmocka_unit_test(test_vpd_eui_8_18),
|
||||
- cmocka_unit_test(test_vpd_eui_8_17),
|
||||
- cmocka_unit_test(test_vpd_eui_8_16),
|
||||
- cmocka_unit_test(test_vpd_eui_8_10),
|
||||
- cmocka_unit_test(test_vpd_eui_12_32),
|
||||
- cmocka_unit_test(test_vpd_eui_12_26),
|
||||
- cmocka_unit_test(test_vpd_eui_12_25),
|
||||
- cmocka_unit_test(test_vpd_eui_12_20),
|
||||
- cmocka_unit_test(test_vpd_eui_12_10),
|
||||
- cmocka_unit_test(test_vpd_eui_16_40),
|
||||
- cmocka_unit_test(test_vpd_eui_16_34),
|
||||
- cmocka_unit_test(test_vpd_eui_16_33),
|
||||
- cmocka_unit_test(test_vpd_eui_16_20),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_32_1),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_32_1),
|
||||
+ cmocka_unit_test(test_vpd_eui_16_40_1),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_32_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_18_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_17_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_16_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_8_10_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_32_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_26_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_25_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_20_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_12_10_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_16_40_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_16_34_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_16_33_0),
|
||||
+ cmocka_unit_test(test_vpd_eui_16_20_0),
|
||||
cmocka_unit_test(test_vpd_naa_6_40),
|
||||
cmocka_unit_test(test_vpd_naa_6_34),
|
||||
cmocka_unit_test(test_vpd_naa_6_33),
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,71 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 20 Feb 2019 17:05:08 -0600
|
||||
Subject: [PATCH] multipathd: ignore failed wwid recheck
|
||||
|
||||
If disable_changed_wwids is set, when multipathd gets a change event on
|
||||
a path, it verifies that the wwid hasn't changed in uev_update_path().
|
||||
If get_uid() failed, uev_update_path treated this as a wwid change to 0.
|
||||
This could cause paths to suddenly be dropped due to an issue with
|
||||
getting the wwid. Even if get_uid() failed because the path was down,
|
||||
it no change uevent happend when it later became active, multipathd
|
||||
would continue to ignore the path. Also, scsi_uid_fallback() clears the
|
||||
failure return if it doesn't attempt to fallback, causing get_uid()
|
||||
to return success, when it actually failed.
|
||||
|
||||
Multipathd should neither set nor clear wwid_changed if get_uid()
|
||||
returned failure. Also, scsi_uid_fallback() should retain the old return
|
||||
value if it doesn't attempt to fallback.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 6 +++---
|
||||
multipathd/main.c | 6 ++++--
|
||||
2 files changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 729bcb9..b08cb2d 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1755,9 +1755,9 @@ get_vpd_uid(struct path * pp)
|
||||
}
|
||||
|
||||
static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin)
|
||||
+ const char **origin, ssize_t old_len)
|
||||
{
|
||||
- ssize_t len = 0;
|
||||
+ ssize_t len = old_len;
|
||||
int retrigger;
|
||||
struct config *conf;
|
||||
|
||||
@@ -1828,7 +1828,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
origin = "sysfs";
|
||||
}
|
||||
if (len <= 0 && pp->bus == SYSFS_BUS_SCSI)
|
||||
- len = scsi_uid_fallback(pp, path_state, &origin);
|
||||
+ len = scsi_uid_fallback(pp, path_state, &origin, len);
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 678ecf8..fd83a6a 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1234,9 +1234,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
goto out;
|
||||
|
||||
strcpy(wwid, pp->wwid);
|
||||
- get_uid(pp, pp->state, uev->udev);
|
||||
+ rc = get_uid(pp, pp->state, uev->udev);
|
||||
|
||||
- if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
+ if (rc != 0)
|
||||
+ strcpy(pp->wwid, wwid);
|
||||
+ else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
condlog(0, "%s: path wwid changed from '%s' to '%s'. %s",
|
||||
uev->kernel, wwid, pp->wwid,
|
||||
(disable_changed_wwids ? "disallowing" :
|
||||
--
|
||||
2.17.2
|
||||
|
116
SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch
Normal file
116
SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 1 Nov 2019 12:35:47 -0500
|
||||
Subject: [PATCH] libmultipath: add vend_id to get_vpd_sgio
|
||||
|
||||
This tells multipath how it should decode vendor specific pages. It will
|
||||
be used by a future patch.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 4 ++--
|
||||
libmultipath/discovery.h | 2 +-
|
||||
libmultipath/propsel.c | 2 +-
|
||||
tests/vpd.c | 10 +++++-----
|
||||
4 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 3c72a80a..1d79cbae 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1135,7 +1135,7 @@ get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
|
||||
}
|
||||
|
||||
int
|
||||
-get_vpd_sgio (int fd, int pg, char * str, int maxlen)
|
||||
+get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
{
|
||||
int len, buff_len;
|
||||
unsigned char buff[4096];
|
||||
@@ -1810,7 +1810,7 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
if (len < 0 && path_state == PATH_UP) {
|
||||
condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
pp->dev, strerror(-len));
|
||||
- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ len = get_vpd_sgio(pp->fd, 0x83, 0, pp->wwid,
|
||||
WWID_SIZE);
|
||||
*origin = "sgio";
|
||||
}
|
||||
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
||||
index 8d04c2af..2f2fd9eb 100644
|
||||
--- a/libmultipath/discovery.h
|
||||
+++ b/libmultipath/discovery.h
|
||||
@@ -35,7 +35,7 @@ int path_get_tpgs(struct path *pp); /* This function never returns TPGS_UNDEF */
|
||||
int do_tur (char *);
|
||||
int path_offline (struct path *);
|
||||
int get_state (struct path * pp, struct config * conf, int daemon, int state);
|
||||
-int get_vpd_sgio (int fd, int pg, char * str, int maxlen);
|
||||
+int get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen);
|
||||
int pathinfo (struct path * pp, struct config * conf, int mask);
|
||||
int alloc_path_with_pathinfo (struct config *conf, struct udev_device *udevice,
|
||||
const char *wwid, int flag, struct path **pp_ptr);
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 27e8d68a..b5b5b89f 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -490,7 +490,7 @@ check_rdac(struct path * pp)
|
||||
if (__do_set_from_hwe(checker_name, pp, checker_name) &&
|
||||
strcmp(checker_name, RDAC))
|
||||
return 0;
|
||||
- len = get_vpd_sgio(pp->fd, 0xC9, buff, 44);
|
||||
+ len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44);
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
return !(memcmp(buff + 4, "vac1", 4));
|
||||
diff --git a/tests/vpd.c b/tests/vpd.c
|
||||
index 4dbce010..02d6e0bb 100644
|
||||
--- a/tests/vpd.c
|
||||
+++ b/tests/vpd.c
|
||||
@@ -431,7 +431,7 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state) \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
- ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
+ ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen, \
|
||||
exp_len, ret, '1', 0, false, \
|
||||
exp_subst, vt->wwid); \
|
||||
@@ -463,7 +463,7 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
- ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
+ ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen, \
|
||||
exp_len, ret, byte0[type], 0, \
|
||||
type != STR_IQN, \
|
||||
@@ -502,7 +502,7 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state) \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
- ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
+ ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen, \
|
||||
exp_len, ret, '3', '0' + naa, true, \
|
||||
test_id, vt->wwid); \
|
||||
@@ -530,7 +530,7 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state) \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
- ret = get_vpd_sgio(10, 0x83, vt->wwid, wlen); \
|
||||
+ ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml, \
|
||||
exp_len, ret, '2', 0, true, \
|
||||
test_id, vt->wwid); \
|
||||
@@ -557,7 +557,7 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state) \
|
||||
size, len); \
|
||||
will_return(__wrap_ioctl, n); \
|
||||
will_return(__wrap_ioctl, vt->vpdbuf); \
|
||||
- ret = get_vpd_sgio(10, 0x80, vt->wwid, wlen); \
|
||||
+ ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen); \
|
||||
assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen, \
|
||||
exp_len, ret, 0, 0, false, \
|
||||
input, vt->wwid); \
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 13:05:43 -0600
|
||||
Subject: [PATCH] libmutipath: continue to use old state on PATH_PENDING
|
||||
|
||||
When pathinfo() sets pp->state to PATH_PENDING, it can cause problems
|
||||
with path checking. It should act more like check_path(). When
|
||||
check_path() sees a new state of PATH_PENDING, it doesn't update the
|
||||
path state at all, so a path's old state is normally never PATH_PENDING.
|
||||
|
||||
As and example of the problems of setting a path to PATH_PENDING, If
|
||||
check_path() sets a path's state to PATH_UP, then a call to pathinfo()
|
||||
sets the state to PATH_PENDING, and then another call the check_path()
|
||||
sets the state to PATH_DOWN, multipathd won't fail the path in the
|
||||
kernel. Also, if a path's state is PATH_PENDING, and nr_active is
|
||||
recalculated, that path will count as down, even if the state was
|
||||
previously PATH_UP. If a path already has a state of PATH_WILD or
|
||||
PATH_UNCHECKED, changing it to PATH_PENDING won't hurt anything, and it
|
||||
will help anyone who sees it know what's actually happening. But
|
||||
otherwise, pathinfo() should leave the previous state alone.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index b08cb2d..28c00e5 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1946,8 +1946,11 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
|
||||
if (mask & DI_CHECKER) {
|
||||
if (path_state == PATH_UP) {
|
||||
- pp->chkrstate = pp->state = get_state(pp, conf, 0,
|
||||
- path_state);
|
||||
+ int newstate = get_state(pp, conf, 0, path_state);
|
||||
+ if (newstate != PATH_PENDING ||
|
||||
+ pp->state == PATH_UNCHECKED ||
|
||||
+ pp->state == PATH_WILD)
|
||||
+ pp->chkrstate = pp->state = newstate;
|
||||
if (pp->state == PATH_TIMEOUT)
|
||||
pp->state = PATH_DOWN;
|
||||
if (pp->state == PATH_UP && !pp->size) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -0,0 +1,350 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Mon, 4 Nov 2019 15:38:25 -0600
|
||||
Subject: [PATCH] libmultipath: add code to get vendor specific vpd data
|
||||
|
||||
This adds the wildcard 'g' for multipath and path formatted printing,
|
||||
which returns extra data from a device's vendor specific vpd page. The
|
||||
specific vendor vpd page to use, and the vendor/product id to decode it
|
||||
can be set in the hwentry with vpd_vendor_pg and vpd_vendor_id. It can
|
||||
be configured in the devices section of multipath.conf with the
|
||||
vpd_vendor parameter. Currently, the only devices that use this are HPE
|
||||
3PAR arrays, to return the Volume Name.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 4 ++++
|
||||
libmultipath/config.h | 2 ++
|
||||
libmultipath/dict.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
libmultipath/discovery.c | 34 +++++++++++++++++++++++++++++++++-
|
||||
libmultipath/hwtable.c | 2 ++
|
||||
libmultipath/print.c | 27 +++++++++++++++++++++++++++
|
||||
libmultipath/propsel.c | 24 ++++++++++++++++++++++++
|
||||
libmultipath/propsel.h | 2 ++
|
||||
libmultipath/structs.h | 9 +++++++++
|
||||
multipath/multipath.conf.5 | 8 ++++++++
|
||||
10 files changed, 145 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 85626e96..72b8d37c 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -369,6 +369,8 @@ merge_hwe (struct hwentry * dst, struct hwentry * src)
|
||||
merge_num(max_sectors_kb);
|
||||
merge_num(ghost_delay);
|
||||
merge_num(all_tg_pt);
|
||||
+ merge_num(vpd_vendor_pg);
|
||||
+ merge_num(vpd_vendor_id);
|
||||
merge_num(san_path_err_threshold);
|
||||
merge_num(san_path_err_forget_rate);
|
||||
merge_num(san_path_err_recovery_time);
|
||||
@@ -517,6 +519,8 @@ store_hwe (vector hwtable, struct hwentry * dhwe)
|
||||
hwe->detect_prio = dhwe->detect_prio;
|
||||
hwe->detect_checker = dhwe->detect_checker;
|
||||
hwe->ghost_delay = dhwe->ghost_delay;
|
||||
+ hwe->vpd_vendor_pg = dhwe->vpd_vendor_pg;
|
||||
+ hwe->vpd_vendor_id = dhwe->vpd_vendor_id;
|
||||
|
||||
if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
|
||||
goto out;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index e69aa07c..589146de 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -87,6 +87,8 @@ struct hwentry {
|
||||
int max_sectors_kb;
|
||||
int ghost_delay;
|
||||
int all_tg_pt;
|
||||
+ int vpd_vendor_pg;
|
||||
+ int vpd_vendor_id;
|
||||
char * bl_product;
|
||||
};
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 2b046e1d..d6d8b79b 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -1366,6 +1366,39 @@ def_uxsock_timeout_handler(struct config *conf, vector strvec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+hw_vpd_vendor_handler(struct config *conf, vector strvec)
|
||||
+{
|
||||
+ int rc = 0;
|
||||
+ char *buff;
|
||||
+
|
||||
+ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
||||
+ if (!hwe)
|
||||
+ return 1;
|
||||
+
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
+ return 1;
|
||||
+ if (strcmp(buff, "hp3par") == 0) {
|
||||
+ hwe->vpd_vendor_pg = 0xc0;
|
||||
+ hwe->vpd_vendor_id = VPD_VP_HP3PAR;
|
||||
+ } else
|
||||
+ rc = 1;
|
||||
+ FREE(buff);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+snprint_hw_vpd_vendor(struct config *conf, char * buff, int len,
|
||||
+ const void * data)
|
||||
+{
|
||||
+ const struct hwentry * hwe = (const struct hwentry *)data;
|
||||
+
|
||||
+ if (hwe->vpd_vendor_pg == 0xc0 && hwe->vpd_vendor_id == VPD_VP_HP3PAR)
|
||||
+ return snprintf(buff, len, "hp3par");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* blacklist block handlers
|
||||
*/
|
||||
@@ -1806,6 +1839,7 @@ init_keywords(vector keywords)
|
||||
install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb);
|
||||
install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay);
|
||||
install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt);
|
||||
+ install_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor);
|
||||
install_sublevel_end();
|
||||
|
||||
install_keyword_root("overrides", &overrides_handler);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 1d79cbae..d2773c3a 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1103,6 +1103,30 @@ parse_vpd_pg83(const unsigned char *in, size_t in_len,
|
||||
return len;
|
||||
}
|
||||
|
||||
+static int
|
||||
+parse_vpd_c0_hp3par(const unsigned char *in, size_t in_len,
|
||||
+ char *out, size_t out_len)
|
||||
+{
|
||||
+ size_t 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);
|
||||
+ 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",
|
||||
+ len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ memcpy(out, &in[44], len);
|
||||
+ out[out_len - 1] = '\0';
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
get_vpd_sysfs (struct udev_device *parent, int pg, char * str, int maxlen)
|
||||
{
|
||||
@@ -1170,7 +1194,9 @@ get_vpd_sgio (int fd, int pg, int vend_id, char * str, int maxlen)
|
||||
len = (buff_len <= maxlen)? buff_len : maxlen;
|
||||
memcpy (str, buff, len);
|
||||
}
|
||||
- } else
|
||||
+ } else if (pg == 0xc0 && vend_id == VPD_VP_HP3PAR)
|
||||
+ len = parse_vpd_c0_hp3par(buff, buff_len, str, maxlen);
|
||||
+ else
|
||||
len = -ENOSYS;
|
||||
|
||||
return len;
|
||||
@@ -1544,6 +1570,12 @@ scsi_ioctl_pathinfo (struct path * pp, struct config *conf, int mask)
|
||||
if (!(mask & DI_SERIAL))
|
||||
return;
|
||||
|
||||
+ select_vpd_vendor_pg(conf, pp);
|
||||
+ select_vpd_vendor_id(conf, pp);
|
||||
+
|
||||
+ if (pp->vpd_vendor_pg != 0 && get_vpd_sgio(pp->fd, pp->vpd_vendor_pg, pp->vpd_vendor_id, pp->vpd_data, sizeof(pp->vpd_data)) < 0)
|
||||
+ condlog(3, "%s: failed to get extra vpd data", pp->dev);
|
||||
+
|
||||
parent = pp->udev;
|
||||
while (parent) {
|
||||
const char *subsys = udev_device_get_subsystem(parent);
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index 16627ec5..1f27450c 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -117,6 +117,8 @@ static struct hwentry default_hw[] = {
|
||||
.no_path_retry = 18,
|
||||
.fast_io_fail = 10,
|
||||
.dev_loss = MAX_DEV_LOSS_TMO,
|
||||
+ .vpd_vendor_pg = 0xc0,
|
||||
+ .vpd_vendor_id = VPD_VP_HP3PAR,
|
||||
},
|
||||
{
|
||||
/* RA8000 / ESA12000 */
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 907469ad..0aafe3cb 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -358,6 +358,23 @@ snprint_action (char * buff, size_t len, const struct multipath * mpp)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+snprint_multipath_vpd_data(char * buff, size_t len,
|
||||
+ const struct multipath * mpp)
|
||||
+{
|
||||
+ struct pathgroup * pgp;
|
||||
+ struct path * pp;
|
||||
+ int i, j;
|
||||
+
|
||||
+ vector_foreach_slot(mpp->pg, pgp, i) {
|
||||
+ vector_foreach_slot(pgp->paths, pp, j) {
|
||||
+ if (strlen(pp->vpd_data))
|
||||
+ return snprintf(buff, len, "%s", pp->vpd_data);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* path info printing functions
|
||||
*/
|
||||
@@ -688,6 +705,14 @@ snprint_path_marginal(char * buff, size_t len, const struct path * pp)
|
||||
return snprintf(buff, len, "normal");
|
||||
}
|
||||
|
||||
+static int
|
||||
+snprint_path_vpd_data(char * buff, size_t len, const struct path * pp)
|
||||
+{
|
||||
+ if (strlen(pp->vpd_data) > 0)
|
||||
+ return snprintf(buff, len, "%s", pp->vpd_data);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
struct multipath_data mpd[] = {
|
||||
{'n', "name", 0, snprint_name},
|
||||
{'w', "uuid", 0, snprint_multipath_uuid},
|
||||
@@ -712,6 +737,7 @@ struct multipath_data mpd[] = {
|
||||
{'p', "prod", 0, snprint_multipath_prod},
|
||||
{'e', "rev", 0, snprint_multipath_rev},
|
||||
{'G', "foreign", 0, snprint_multipath_foreign},
|
||||
+ {'g', "vpd page data", 0, snprint_multipath_vpd_data},
|
||||
{0, NULL, 0 , NULL}
|
||||
};
|
||||
|
||||
@@ -737,6 +763,7 @@ struct path_data pd[] = {
|
||||
{'r', "target WWPN", 0, snprint_tgt_wwpn},
|
||||
{'a', "host adapter", 0, snprint_host_adapter},
|
||||
{'G', "foreign", 0, snprint_path_foreign},
|
||||
+ {'g', "vpd page data", 0, snprint_path_vpd_data},
|
||||
{'0', "failures", 0, snprint_path_failures},
|
||||
{'P', "protocol", 0, snprint_path_protocol},
|
||||
{0, NULL, 0 , NULL}
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index b5b5b89f..3c99f2d4 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -1203,3 +1203,27 @@ out:
|
||||
origin);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+int select_vpd_vendor_pg (struct config *conf, struct path *pp)
|
||||
+{
|
||||
+ const char *origin;
|
||||
+
|
||||
+ pp_set_hwe(vpd_vendor_pg);
|
||||
+ pp_set_default(vpd_vendor_pg, 0);
|
||||
+out:
|
||||
+ condlog(3, "%s: vpd_vendor_pg = 0x%x %s", pp->dev, pp->vpd_vendor_pg,
|
||||
+ origin);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int select_vpd_vendor_id (struct config *conf, struct path *pp)
|
||||
+{
|
||||
+ const char *origin;
|
||||
+
|
||||
+ pp_set_hwe(vpd_vendor_id);
|
||||
+ pp_set_default(vpd_vendor_id, 0);
|
||||
+out:
|
||||
+ condlog(3, "%s: vpd_vendor_id = 0x%x %s", pp->dev, pp->vpd_vendor_id,
|
||||
+ origin);
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/libmultipath/propsel.h b/libmultipath/propsel.h
|
||||
index ddfd6262..3f6d319a 100644
|
||||
--- a/libmultipath/propsel.h
|
||||
+++ b/libmultipath/propsel.h
|
||||
@@ -37,3 +37,5 @@ void reconcile_features_with_options(const char *id, char **features,
|
||||
int* no_path_retry,
|
||||
int *retain_hwhandler);
|
||||
int select_all_tg_pt (struct config *conf, struct multipath * mp);
|
||||
+int select_vpd_vendor_pg (struct config *conf, struct path *pp);
|
||||
+int select_vpd_vendor_id (struct config *conf, struct path *pp);
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 1c32a799..1ad5f64a 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -21,6 +21,7 @@
|
||||
#define HOST_NAME_LEN 16
|
||||
#define SLOT_NAME_SIZE 40
|
||||
#define PRKEY_SIZE 19
|
||||
+#define VPD_DATA_SIZE 128
|
||||
|
||||
#define SCSI_VENDOR_SIZE 9
|
||||
#define SCSI_PRODUCT_SIZE 17
|
||||
@@ -243,6 +244,11 @@ struct hd_geometry {
|
||||
};
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * from sg_vpd_vendor.c
|
||||
+ */
|
||||
+#define VPD_VP_HP3PAR 4
|
||||
+
|
||||
struct path {
|
||||
char dev[FILE_NAME_SIZE];
|
||||
char dev_t[BLK_DEV_SIZE];
|
||||
@@ -255,6 +261,7 @@ struct path {
|
||||
char rev[PATH_REV_SIZE];
|
||||
char serial[SERIAL_SIZE];
|
||||
char tgt_node_name[NODE_NAME_SIZE];
|
||||
+ char vpd_data[VPD_DATA_SIZE];
|
||||
unsigned long long size;
|
||||
unsigned int checkint;
|
||||
unsigned int tick;
|
||||
@@ -287,6 +294,8 @@ struct path {
|
||||
int io_err_pathfail_starttime;
|
||||
int find_multipaths_timeout;
|
||||
int marginal;
|
||||
+ int vpd_vendor_pg;
|
||||
+ int vpd_vendor_id;
|
||||
/* configlet pointers */
|
||||
vector hwe;
|
||||
struct gen_path generic_path;
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index e866da23..dc103fd8 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1472,6 +1472,14 @@ the \fIproduct\fR attribute set to the value of \fIproduct_blacklist\fR.
|
||||
The user_friendly_names prefix to use for this
|
||||
device type, instead of the default "mpath".
|
||||
.TP
|
||||
+.B vpd_vendor
|
||||
+The vendor specific vpd page information, using the vpd page abbreviation.
|
||||
+The vpd page abbreviation can be found by running \fIsg_vpd -e\fR. multipathd
|
||||
+will use this information to gather device specific information that can be
|
||||
+displayed with the \fI%g\fR wilcard for the \fImultipathd show maps format\fR
|
||||
+and \fImultipathd show paths format\fR commands. Currently only the
|
||||
+\fBhp3par\fR vpd page is supported.
|
||||
+.TP
|
||||
.B hardware_handler
|
||||
The hardware handler to use for this device type.
|
||||
The following hardware handler are implemented:
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,76 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 21 Feb 2019 17:00:17 -0600
|
||||
Subject: [PATCH] multipathd: use update_path_groups instead of reload_map
|
||||
|
||||
reload_map() doesn't do the work to sync the state after reloading the
|
||||
map. Instead of calling it directly, cli_reload() and uev_update_path()
|
||||
should call update_path_groups(), which calls reload_map() with all the
|
||||
necessary syncing.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli_handlers.c | 2 +-
|
||||
multipathd/main.c | 13 ++++++++-----
|
||||
multipathd/main.h | 2 ++
|
||||
3 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index f95813e..60e17d6 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -877,7 +877,7 @@ cli_reload(void *v, char **reply, int *len, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- return reload_map(vecs, mpp, 0, 1);
|
||||
+ return update_path_groups(mpp, vecs, 0);
|
||||
}
|
||||
|
||||
int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index fd83a6a..7a317d9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1273,10 +1273,13 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
else {
|
||||
if (ro == 1)
|
||||
pp->mpp->force_readonly = 1;
|
||||
- retval = reload_map(vecs, mpp, 0, 1);
|
||||
- pp->mpp->force_readonly = 0;
|
||||
- condlog(2, "%s: map %s reloaded (retval %d)",
|
||||
- uev->kernel, mpp->alias, retval);
|
||||
+ retval = update_path_groups(mpp, vecs, 0);
|
||||
+ if (retval == 2)
|
||||
+ condlog(2, "%s: map removed during reload", pp->dev);
|
||||
+ else {
|
||||
+ pp->mpp->force_readonly = 0;
|
||||
+ condlog(2, "%s: map %s reloaded (retval %d)", uev->kernel, mpp->alias, retval);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1832,7 +1835,7 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
|
||||
|
||||
dm_lib_release();
|
||||
if (setup_multipath(vecs, mpp) != 0)
|
||||
- return 1;
|
||||
+ return 2;
|
||||
sync_map_state(mpp);
|
||||
|
||||
return 0;
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index 8fd426b..e5c1398 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -43,5 +43,7 @@ int __setup_multipath (struct vectors * vecs, struct multipath * mpp,
|
||||
int reset);
|
||||
#define setup_multipath(vecs, mpp) __setup_multipath(vecs, mpp, 1)
|
||||
int update_multipath (struct vectors *vecs, char *mapname, int reset);
|
||||
+int update_path_groups(struct multipath *mpp, struct vectors *vecs,
|
||||
+ int refresh);
|
||||
|
||||
#endif /* MAIN_H */
|
||||
--
|
||||
2.17.2
|
||||
|
@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index fc728ca..2f0bcea 100644
|
||||
index 56c3eda0..2e8946ca 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -48,7 +48,7 @@ endif
|
||||
@@ -53,7 +53,7 @@ endif
|
||||
prefix =
|
||||
exec_prefix = $(prefix)
|
||||
usr_prefix = $(prefix)
|
||||
@ -28,7 +28,7 @@ index fc728ca..2f0bcea 100644
|
||||
udevrulesdir = $(libudevdir)/rules.d
|
||||
multipathdir = $(TOPDIR)/libmultipath
|
||||
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||
index 8f99049..8a3a171 100644
|
||||
index 8f990494..8a3a1718 100644
|
||||
--- a/kpartx/kpartx.rules
|
||||
+++ b/kpartx/kpartx.rules
|
||||
@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end"
|
||||
@ -40,7 +40,7 @@ index 8f99049..8a3a171 100644
|
||||
|
||||
LABEL="kpartx_end"
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index 0828a8f..b9bbb3c 100644
|
||||
index 0828a8f7..b9bbb3cf 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -24,7 +24,7 @@ install:
|
@ -1,56 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Tue, 26 Feb 2019 12:22:59 -0600
|
||||
Subject: [PATCH] multipath.conf: add missing options to man page
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/multipath.conf.5 | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 0fe8461..864d7eb 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1468,6 +1468,8 @@ section:
|
||||
.TP
|
||||
.B uid_attribute
|
||||
.TP
|
||||
+.B getuid_callout
|
||||
+.TP
|
||||
.B path_selector
|
||||
.TP
|
||||
.B path_checker
|
||||
@@ -1494,6 +1496,8 @@ section:
|
||||
.TP
|
||||
.B flush_on_last_del
|
||||
.TP
|
||||
+.B user_friendly_names
|
||||
+.TP
|
||||
.B retain_attached_hw_handler
|
||||
.TP
|
||||
.B detect_prio
|
||||
@@ -1525,6 +1529,8 @@ section:
|
||||
.B max_sectors_kb
|
||||
.TP
|
||||
.B ghost_delay
|
||||
+.TP
|
||||
+.B all_tg_pt
|
||||
.RE
|
||||
.PD
|
||||
.LP
|
||||
@@ -1604,7 +1610,11 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections:
|
||||
.TP
|
||||
.B skip_kpartx
|
||||
.TP
|
||||
+.B max_sectors_kb
|
||||
+.TP
|
||||
.B ghost_delay
|
||||
+.TP
|
||||
+.B all_tg_pt
|
||||
.RE
|
||||
.PD
|
||||
.LP
|
||||
--
|
||||
2.17.2
|
||||
|
@ -13,12 +13,13 @@ it.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/blacklist.c | 12 ++++--------
|
||||
multipath/multipath.conf.5 | 14 ++++++--------
|
||||
2 files changed, 10 insertions(+), 16 deletions(-)
|
||||
libmultipath/blacklist.c | 9 ++-------
|
||||
multipath/multipath.conf.5 | 11 ++++++-----
|
||||
tests/blacklist.c | 6 ++----
|
||||
3 files changed, 10 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
|
||||
index e0d0279..556c0b9 100644
|
||||
index 00e8dbdb..d9691b17 100644
|
||||
--- a/libmultipath/blacklist.c
|
||||
+++ b/libmultipath/blacklist.c
|
||||
@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf)
|
||||
@ -34,14 +35,10 @@ index e0d0279..556c0b9 100644
|
||||
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||
if (hwe->bl_product) {
|
||||
if (find_blacklist_device(conf->blist_device,
|
||||
@@ -394,9 +388,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl)
|
||||
if (udev) {
|
||||
/*
|
||||
* This is the inverse of the 'normal' matching;
|
||||
- * the environment variable _has_ to match.
|
||||
+ * the environment variable _has_ to match
|
||||
+ * if a whitelist is present.
|
||||
*/
|
||||
@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl,
|
||||
*uid_attribute != '\0';
|
||||
bool uid_attr_seen = false;
|
||||
|
||||
- r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
+ if (VECTOR_SIZE(conf->elist_property))
|
||||
+ r = MATCH_PROPERTY_BLIST_MISSING;
|
||||
@ -49,10 +46,10 @@ index e0d0279..556c0b9 100644
|
||||
udev_device_get_properties_list_entry(udev)) {
|
||||
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 646c156..768ab83 100644
|
||||
index dc103fd8..b8697d47 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1235,16 +1235,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
@@ -1285,9 +1285,14 @@ keywords. Both are regular expressions. For a full description of these keywords
|
||||
Regular expression for an udev property. All
|
||||
devices that have matching udev properties will be excluded/included.
|
||||
The handling of the \fIproperty\fR keyword is special,
|
||||
@ -61,20 +58,48 @@ index 646c156..768ab83 100644
|
||||
+least one whitelisted udev property;
|
||||
otherwise they're treated as blacklisted, and the message
|
||||
"\fIblacklisted, udev property missing\fR" is displayed in the logs.
|
||||
-.
|
||||
-.RS
|
||||
-.PP
|
||||
-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing
|
||||
-well-behaved SCSI devices and devices that provide a WWN (World Wide Number)
|
||||
-to be included, and all others to be excluded.
|
||||
-.RE
|
||||
+For example, setting the property blacklist_exception to
|
||||
+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices
|
||||
+that provide a WWN (World Wide Number) to be included, and all others to be
|
||||
+excluded. This works to exclude most non-multipathable devices.
|
||||
.
|
||||
.RS
|
||||
.PP
|
||||
@@ -1298,10 +1303,6 @@ Blacklisting by missing properties is only applied to devices which do have the
|
||||
property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR)
|
||||
set. Previously, it was applied to every device, possibly causing devices to be
|
||||
blacklisted because of temporary I/O error conditions.
|
||||
-.PP
|
||||
-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing
|
||||
-well-behaved SCSI devices and devices that provide a WWN (World Wide Number)
|
||||
-to be included, and all others to be excluded.
|
||||
.RE
|
||||
.TP
|
||||
.B protocol
|
||||
Regular expression for the protocol of a device to be excluded/included.
|
||||
diff --git a/tests/blacklist.c b/tests/blacklist.c
|
||||
index 362c44d9..ea284939 100644
|
||||
--- a/tests/blacklist.c
|
||||
+++ b/tests/blacklist.c
|
||||
@@ -291,7 +291,7 @@ static void test_property_missing(void **state)
|
||||
conf.blist_property = blist_property_wwn;
|
||||
expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"),
|
||||
- MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"),
|
||||
MATCH_NOTHING);
|
||||
assert_int_equal(filter_property(&conf, &udev, 3, ""),
|
||||
@@ -383,9 +383,7 @@ static void test_filter_path_missing1(void **state)
|
||||
conf.blist_device = blist_device_foo_bar;
|
||||
conf.blist_protocol = blist_protocol_fcp;
|
||||
conf.blist_wwid = blist_wwid_xyzzy;
|
||||
- expect_condlog(3, "sdb: blacklisted, udev property missing\n");
|
||||
- assert_int_equal(filter_path(&conf, &miss1_pp),
|
||||
- MATCH_PROPERTY_BLIST_MISSING);
|
||||
+ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING);
|
||||
}
|
||||
|
||||
/* This one matches the property whitelist, to test the other missing
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 7 Mar 2019 16:14:35 -0600
|
||||
Subject: [PATCH] libmultipath: add get_uid fallback code for NVMe devices
|
||||
|
||||
If multipath can't get the uid for NVMe devices from udev, it can get it
|
||||
directly from sysfs.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 49 ++++++++++++++++++++++++++++------------
|
||||
1 file changed, 34 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 28c00e5..bece67c 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1754,8 +1754,8 @@ get_vpd_uid(struct path * pp)
|
||||
return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE);
|
||||
}
|
||||
|
||||
-static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin, ssize_t old_len)
|
||||
+static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
+ const char **origin, ssize_t old_len)
|
||||
{
|
||||
ssize_t len = old_len;
|
||||
int retrigger;
|
||||
@@ -1764,17 +1764,36 @@ static ssize_t scsi_uid_fallback(struct path *pp, int path_state,
|
||||
conf = get_multipath_config();
|
||||
retrigger = conf->retrigger_tries;
|
||||
put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger &&
|
||||
- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
- len = get_vpd_uid(pp);
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
- if (len < 0 && path_state == PATH_UP) {
|
||||
- condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
- pp->dev, strerror(-len));
|
||||
- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
- WWID_SIZE);
|
||||
- *origin = "sgio";
|
||||
+ if (pp->retriggers >= retrigger) {
|
||||
+ if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
+ len = get_vpd_uid(pp);
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
+ if (len < 0 && path_state == PATH_UP) {
|
||||
+ condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
+ pp->dev, strerror(-len));
|
||||
+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ WWID_SIZE);
|
||||
+ *origin = "sgio";
|
||||
+ }
|
||||
+ } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
+ char value[256];
|
||||
+ len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
+ sizeof(value));
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
+ len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
+ if (len >= WWID_SIZE) {
|
||||
+ len = fix_broken_nvme_wwid(pp, value,
|
||||
+ WWID_SIZE);
|
||||
+ if (len > 0)
|
||||
+ return len;
|
||||
+ condlog(0, "%s: wwid overflow", pp->dev);
|
||||
+ len = WWID_SIZE;
|
||||
+ }
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
@@ -1827,8 +1846,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0 && pp->bus == SYSFS_BUS_SCSI)
|
||||
- len = scsi_uid_fallback(pp, path_state, &origin, len);
|
||||
+ if (len <= 0)
|
||||
+ len = uid_fallback(pp, path_state, &origin, len);
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
--
|
||||
2.17.2
|
||||
|
@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
5 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 141f092..544d2fb 100644
|
||||
index 72b8d37c..4032c4c4 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -31,7 +31,7 @@ index 141f092..544d2fb 100644
|
||||
|
||||
static int
|
||||
hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2)
|
||||
@@ -745,6 +746,20 @@ load_config (char * file)
|
||||
@@ -755,6 +756,20 @@ load_config (char * file)
|
||||
goto out;
|
||||
}
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
@ -53,7 +53,7 @@ index 141f092..544d2fb 100644
|
||||
|
||||
conf->processed_main_config = 1;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index f5bf5b1..8803967 100644
|
||||
index 589146de..2adbd077 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -9,6 +9,7 @@
|
||||
@ -65,7 +65,7 @@ index f5bf5b1..8803967 100644
|
||||
/*
|
||||
* In kernel, fast_io_fail == 0 means immediate failure on rport delete.
|
||||
diff --git a/multipath/multipath.rules b/multipath/multipath.rules
|
||||
index 9df11a9..0486bf7 100644
|
||||
index 9df11a95..0486bf70 100644
|
||||
--- a/multipath/multipath.rules
|
||||
+++ b/multipath/multipath.rules
|
||||
@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath"
|
||||
@ -77,10 +77,10 @@ index 9df11a9..0486bf7 100644
|
||||
ENV{DEVTYPE}!="partition", GOTO="test_dev"
|
||||
IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH"
|
||||
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||
index 94c3f97..ed13efd 100644
|
||||
index 048a838d..8bd47a80 100644
|
||||
--- a/multipathd/multipathd.8
|
||||
+++ b/multipathd/multipathd.8
|
||||
@@ -38,6 +38,8 @@ map regains its maximum performance and redundancy.
|
||||
@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy.
|
||||
This daemon executes the external \fBmultipath\fR tool when events occur.
|
||||
In turn, the multipath tool signals the multipathd daemon when it is done with
|
||||
devmap reconfiguration, so that it can refresh its failed path list.
|
||||
@ -90,7 +90,7 @@ index 94c3f97..ed13efd 100644
|
||||
.
|
||||
.\" ----------------------------------------------------------------------------
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index ba24983..17434ce 100644
|
||||
index ba24983e..17434cef 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service
|
@ -1,129 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 27 Mar 2019 12:21:57 -0500
|
||||
Subject: [PATCH] libmulitpath: cleanup uid_fallback code
|
||||
|
||||
Instead of always calling uid_fallback() if the configured method to get
|
||||
the uid failed, get_uid now checks if the path supports fallbacks and if
|
||||
all the retriggers have occurred. If so, it calls uid_fallback(), which
|
||||
just attempts to get the uid using the appropriate fallback method. None
|
||||
of these changes should make the code function any differently.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 85 ++++++++++++++++++++++------------------
|
||||
1 file changed, 46 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index bece67c..3ec60d6 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1755,50 +1755,50 @@ get_vpd_uid(struct path * pp)
|
||||
}
|
||||
|
||||
static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
- const char **origin, ssize_t old_len)
|
||||
+ const char **origin)
|
||||
{
|
||||
- ssize_t len = old_len;
|
||||
- int retrigger;
|
||||
- struct config *conf;
|
||||
-
|
||||
- conf = get_multipath_config();
|
||||
- retrigger = conf->retrigger_tries;
|
||||
- put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger) {
|
||||
- if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
- len = get_vpd_uid(pp);
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
- if (len < 0 && path_state == PATH_UP) {
|
||||
- condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
- pp->dev, strerror(-len));
|
||||
- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ ssize_t len = -1;
|
||||
+
|
||||
+ if (pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
+ len = get_vpd_uid(pp);
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
+ if (len < 0 && path_state == PATH_UP) {
|
||||
+ condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
+ pp->dev, strerror(-len));
|
||||
+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid,
|
||||
+ WWID_SIZE);
|
||||
+ *origin = "sgio";
|
||||
+ }
|
||||
+ } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
+ char value[256];
|
||||
+ len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
+ sizeof(value));
|
||||
+ if (len <= 0)
|
||||
+ return -1;
|
||||
+ len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
+ if (len >= WWID_SIZE) {
|
||||
+ len = fix_broken_nvme_wwid(pp, value,
|
||||
WWID_SIZE);
|
||||
- *origin = "sgio";
|
||||
- }
|
||||
- } else if (pp->bus == SYSFS_BUS_NVME) {
|
||||
- char value[256];
|
||||
- len = sysfs_attr_get_value(pp->udev, "wwid", value,
|
||||
- sizeof(value));
|
||||
- if (len <= 0)
|
||||
- return -1;
|
||||
- len = strlcpy(pp->wwid, value, WWID_SIZE);
|
||||
- if (len >= WWID_SIZE) {
|
||||
- len = fix_broken_nvme_wwid(pp, value,
|
||||
- WWID_SIZE);
|
||||
- if (len > 0)
|
||||
- return len;
|
||||
- condlog(0, "%s: wwid overflow", pp->dev);
|
||||
- len = WWID_SIZE;
|
||||
- }
|
||||
- *origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
+ if (len > 0)
|
||||
+ return len;
|
||||
+ condlog(0, "%s: wwid overflow", pp->dev);
|
||||
+ len = WWID_SIZE;
|
||||
}
|
||||
+ *origin = "sysfs";
|
||||
+ pp->uid_attribute = NULL;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
+static int has_uid_fallback(struct path *pp)
|
||||
+{
|
||||
+ return ((pp->bus == SYSFS_BUS_SCSI &&
|
||||
+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) ||
|
||||
+ pp->bus == SYSFS_BUS_NVME);
|
||||
+}
|
||||
+
|
||||
int
|
||||
get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
{
|
||||
@@ -1846,8 +1846,15 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0)
|
||||
- len = uid_fallback(pp, path_state, &origin, len);
|
||||
+ if (len <= 0 && has_uid_fallback(pp)) {
|
||||
+ int retrigger_tries;
|
||||
+
|
||||
+ conf = get_multipath_config();
|
||||
+ retrigger_tries = conf->retrigger_tries;
|
||||
+ put_multipath_config(conf);
|
||||
+ if (pp->retriggers >= retrigger_tries)
|
||||
+ len = uid_fallback(pp, path_state, &origin);
|
||||
+ }
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
condlog(1, "%s: failed to get %s uid: %s",
|
||||
--
|
||||
2.17.2
|
||||
|
@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Makefile.inc b/Makefile.inc
|
||||
index 2f0bcea..b98800a 100644
|
||||
index 2e8946ca..1b2f47a8 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -83,15 +83,23 @@ TEST_CC_OPTION = $(shell \
|
||||
@@ -88,15 +88,23 @@ TEST_CC_OPTION = $(shell \
|
||||
echo "$(2)"; \
|
||||
fi)
|
||||
|
@ -1,83 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Wed, 27 Mar 2019 23:27:47 -0500
|
||||
Subject: [PATCH] multipathd: handle changed wwids by removal and addition
|
||||
|
||||
If a path's WWID changes, it's not necessarily failed. But it certainly
|
||||
has to be removed from an existing map, otherwise data corruption is
|
||||
imminent. Instead of keeping the path in the map, failing it, and
|
||||
remembering the "changed WWID" state, this patch simply removes and
|
||||
re-adds the path.
|
||||
|
||||
This is patch is heavily based on the previous patch of the same name
|
||||
by Martin Wilck.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/main.c | 28 ++++++----------------------
|
||||
1 file changed, 6 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 7a317d9..b3571d9 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1191,7 +1191,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
int ro, retval = 0, rc;
|
||||
struct path * pp;
|
||||
struct config *conf;
|
||||
- int disable_changed_wwids;
|
||||
int needs_reinit = 0;
|
||||
|
||||
switch ((rc = change_foreign(uev->udev))) {
|
||||
@@ -1209,12 +1208,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
break;
|
||||
}
|
||||
|
||||
- conf = get_multipath_config();
|
||||
- disable_changed_wwids = conf->disable_changed_wwids;
|
||||
- put_multipath_config(conf);
|
||||
-
|
||||
- ro = uevent_get_disk_ro(uev);
|
||||
-
|
||||
pthread_cleanup_push(cleanup_lock, &vecs->lock);
|
||||
lock(&vecs->lock);
|
||||
pthread_testcancel();
|
||||
@@ -1239,22 +1232,12 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
if (rc != 0)
|
||||
strcpy(pp->wwid, wwid);
|
||||
else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) {
|
||||
- condlog(0, "%s: path wwid changed from '%s' to '%s'. %s",
|
||||
- uev->kernel, wwid, pp->wwid,
|
||||
- (disable_changed_wwids ? "disallowing" :
|
||||
- "continuing"));
|
||||
- strcpy(pp->wwid, wwid);
|
||||
- if (disable_changed_wwids) {
|
||||
- if (!pp->wwid_changed) {
|
||||
- pp->wwid_changed = 1;
|
||||
- pp->tick = 1;
|
||||
- if (pp->mpp)
|
||||
- dm_fail_path(pp->mpp->alias, pp->dev_t);
|
||||
- }
|
||||
- goto out;
|
||||
- }
|
||||
+ condlog(0, "%s: path wwid changed from '%s' to '%s'",
|
||||
+ uev->kernel, wwid, pp->wwid);
|
||||
+ ev_remove_path(pp, vecs, 1);
|
||||
+ needs_reinit = 1;
|
||||
+ goto out;
|
||||
} else {
|
||||
- pp->wwid_changed = 0;
|
||||
udev_device_unref(pp->udev);
|
||||
pp->udev = udev_device_ref(uev->udev);
|
||||
conf = get_multipath_config();
|
||||
@@ -1265,6 +1248,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
||||
|
||||
+ ro = uevent_get_disk_ro(uev);
|
||||
if (mpp && ro >= 0) {
|
||||
condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro);
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 2 +
|
||||
multipath/Makefile | 5 +
|
||||
multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 119 +++++++++++
|
||||
4 files changed, 590 insertions(+)
|
||||
multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++
|
||||
multipath/mpathconf.8 | 135 ++++++++++
|
||||
4 files changed, 697 insertions(+)
|
||||
create mode 100644 multipath/mpathconf
|
||||
create mode 100644 multipath/mpathconf.8
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 544d2fb..deb80c2 100644
|
||||
index 4032c4c4..2c32acf7 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -748,6 +748,8 @@ load_config (char * file)
|
||||
@@ -758,6 +758,8 @@ load_config (char * file)
|
||||
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||
} else {
|
||||
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||
@ -34,7 +34,7 @@ index 544d2fb..deb80c2 100644
|
||||
conf->blist_devnode = vector_alloc();
|
||||
if (!conf->blist_devnode) {
|
||||
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||
index b9bbb3c..e720c7f 100644
|
||||
index b9bbb3cf..e720c7f6 100644
|
||||
--- a/multipath/Makefile
|
||||
+++ b/multipath/Makefile
|
||||
@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||
@ -69,10 +69,10 @@ index b9bbb3c..e720c7f 100644
|
||||
$(RM) core *.o $(EXEC) *.gz
|
||||
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||
new file mode 100644
|
||||
index 0000000..e839134
|
||||
index 00000000..f34003c9
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf
|
||||
@@ -0,0 +1,464 @@
|
||||
@@ -0,0 +1,555 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
||||
@ -92,7 +92,7 @@ index 0000000..e839134
|
||||
+# This program was largely ripped off from lvmconf
|
||||
+#
|
||||
+
|
||||
+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST
|
||||
+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST
|
||||
+
|
||||
+DEFAULT_CONFIG="# device-mapper-multipath configuration file
|
||||
+
|
||||
@ -107,6 +107,7 @@ index 0000000..e839134
|
||||
+defaults {
|
||||
+ user_friendly_names yes
|
||||
+ find_multipaths yes
|
||||
+ enable_foreign \"^$\"
|
||||
+}
|
||||
+
|
||||
+blacklist_exceptions {
|
||||
@ -129,6 +130,8 @@ index 0000000..e839134
|
||||
+ echo "Only allow certain wwids (instead of enable): --allow <WWID>"
|
||||
+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
|
||||
+ echo "Set find_multipaths (Default y): --find_multipaths <y|n>"
|
||||
+ echo "Set default property blacklist (Default y): --property_blacklist <y|n>"
|
||||
+ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign <y|n>"
|
||||
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
|
||||
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
|
||||
+ echo "select output file (Default /etc/multipath.conf): --outfile <FILE>"
|
||||
@ -230,6 +233,24 @@ index 0000000..e839134
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --property_blacklist)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ PROPERTY=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --enable_foreign)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ FOREIGN=$2
|
||||
+ shift 2
|
||||
+ else
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ ;;
|
||||
+ --with_module)
|
||||
+ if [ -n "$2" ]; then
|
||||
+ MODULE=$2
|
||||
@ -267,10 +288,11 @@ index 0000000..e839134
|
||||
+
|
||||
+function validate_args
|
||||
+{
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then
|
||||
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then
|
||||
+ echo "ignoring extra parameters on disable"
|
||||
+ FRIENDLY=""
|
||||
+ FIND=""
|
||||
+ PROPERTY=""
|
||||
+ MODULE=""
|
||||
+ fi
|
||||
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
|
||||
@ -281,7 +303,15 @@ index 0000000..e839134
|
||||
+ echo "--find_multipaths must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
|
||||
+ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then
|
||||
+ echo "--property_blacklist must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then
|
||||
+ echo "--enable_foreign must be either 'y' or 'n'"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then
|
||||
+ SHOW_STATUS=1
|
||||
+ fi
|
||||
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
|
||||
@ -382,6 +412,21 @@ index 0000000..e839134
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
|
||||
+ HAVE_FRIENDLY=0
|
||||
+ fi
|
||||
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=0
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then
|
||||
+ HAVE_FOREIGN=1
|
||||
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then
|
||||
+ HAVE_FOREIGN=2
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$HAVE_EXCEPTIONS" = "1" ]; then
|
||||
+ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=1
|
||||
+ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then
|
||||
+ HAVE_PROPERTY=0
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -n "$SHOW_STATUS" ]; then
|
||||
@ -400,6 +445,18 @@ index 0000000..e839134
|
||||
+ else
|
||||
+ echo "user_friendly_names is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then
|
||||
+ echo "default property blacklist is disabled"
|
||||
+ else
|
||||
+ echo "default property blacklist is enabled"
|
||||
+ fi
|
||||
+ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then
|
||||
+ echo "enable_foreign is not set (all foreign multipath devices will be shown)"
|
||||
+ elif [ "$HAVE_FOREIGN" = 1 ]; then
|
||||
+ echo "enable_foreign is set (no foreign multipath devices will be shown)"
|
||||
+ else
|
||||
+ echo "enable_foreign is set (foreign multipath devices may not be shown)"
|
||||
+ fi
|
||||
+ if [ -n "$HAVE_MODULE" ]; then
|
||||
+ if [ "$HAVE_MODULE" = 1 ]; then
|
||||
+ echo "dm_multipath module is loaded"
|
||||
@ -507,6 +564,40 @@ index 0000000..e839134
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$PROPERTY" = "n" ]; then
|
||||
+ if [ "$HAVE_PROPERTY" = 1 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$PROPERTY" = "y" ]; then
|
||||
+ if [ -z "$HAVE_PROPERTY" ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
|
||||
+ property "(SCSI_IDENT_|ID_WWN)"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_PROPERTY" = 0 ]; then
|
||||
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ "$FOREIGN" = "y" ]; then
|
||||
+ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+elif [ "$FOREIGN" = "n" ]; then
|
||||
+ if [ -z "$HAVE_FOREIGN" ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||
+ enable_foreign "^$"
|
||||
+' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then
|
||||
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE
|
||||
+ CHANGED_CONFIG=1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+if [ -f "$OUTPUTFILE" ]; then
|
||||
+ cp $OUTPUTFILE $OUTPUTFILE.old
|
||||
+ if [ $? != 0 ]; then
|
||||
@ -539,10 +630,10 @@ index 0000000..e839134
|
||||
+fi
|
||||
diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8
|
||||
new file mode 100644
|
||||
index 0000000..5b7ae0c
|
||||
index 00000000..7937ea05
|
||||
--- /dev/null
|
||||
+++ b/multipath/mpathconf.8
|
||||
@@ -0,0 +1,119 @@
|
||||
@@ -0,0 +1,135 @@
|
||||
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
|
||||
+.SH NAME
|
||||
+mpathconf - A tool for configuring device-mapper-multipath
|
||||
@ -628,7 +719,23 @@ index 0000000..5b7ae0c
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. If set to \fBn\fP, this removes the line, if present. This
|
||||
+command can be used aldong with any other command.
|
||||
+command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --property_blacklist \fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBy\fP, this adds the line
|
||||
+.B property "(SCSI_IDENT_|ID_WWN)"
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+blacklist_exceptions section. If set to \fBn\fP, this removes the line, if
|
||||
+present. This command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --enable_foreign\fP { \fBy\fP | \fBn\fP }
|
||||
+If set to \fBn\fP, this adds the line
|
||||
+.B enable_foreign "^$"
|
||||
+to the
|
||||
+.B /etc/multipath.conf
|
||||
+defaults section. if set to \fBy\fP, this removes the line, if present. This
|
||||
+command can be used along with any other command.
|
||||
+.TP
|
||||
+.B --outfile \fB<filename>\fP
|
||||
+Write the resulting multipath configuration to \fB<filename>\fP instead of
|
@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 13:12:34 +0100
|
||||
Subject: [PATCH] multipathd: remove "wwid_changed" path attribute
|
||||
|
||||
This is now not needed any more.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/structs.h | 1 -
|
||||
multipathd/main.c | 6 ------
|
||||
2 files changed, 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index b794b0d..7879d76 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -280,7 +280,6 @@ struct path {
|
||||
int fd;
|
||||
int initialized;
|
||||
int retriggers;
|
||||
- int wwid_changed;
|
||||
unsigned int path_failures;
|
||||
time_t dis_reinstate_time;
|
||||
int disable_reinstate;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index b3571d9..e4f95a0 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -2001,12 +2001,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
||||
if (newstate == PATH_REMOVED)
|
||||
newstate = PATH_DOWN;
|
||||
|
||||
- if (pp->wwid_changed) {
|
||||
- condlog(2, "%s: path wwid has changed. Refusing to use",
|
||||
- pp->dev);
|
||||
- newstate = PATH_DOWN;
|
||||
- }
|
||||
-
|
||||
if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
|
||||
condlog(2, "%s: unusable path (%s) - checker failed",
|
||||
pp->dev, checker_state_name(newstate));
|
||||
--
|
||||
2.17.2
|
||||
|
@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
5 files changed, 60 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||
index 53e7951..39e08cd 100644
|
||||
index ef748125..349da8b7 100644
|
||||
--- a/libmultipath/wwids.c
|
||||
+++ b/libmultipath/wwids.c
|
||||
@@ -443,3 +443,47 @@ int op ## _wwid(const char *wwid) \
|
||||
@@ -444,3 +444,47 @@ int op ## _wwid(const char *wwid) \
|
||||
declare_failed_wwid_op(is_failed, false)
|
||||
declare_failed_wwid_op(mark_failed, true)
|
||||
declare_failed_wwid_op(unmark_failed, true)
|
||||
@ -74,7 +74,7 @@ index 53e7951..39e08cd 100644
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
|
||||
index 0c6ee54..e32a0b0 100644
|
||||
index 0c6ee54d..e32a0b0e 100644
|
||||
--- a/libmultipath/wwids.h
|
||||
+++ b/libmultipath/wwids.h
|
||||
@@ -17,6 +17,7 @@ int remember_wwid(char *wwid);
|
||||
@ -86,19 +86,19 @@ index 0c6ee54..e32a0b0 100644
|
||||
enum {
|
||||
WWID_IS_NOT_FAILED = 0,
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 69141db..e7771c0 100644
|
||||
index 4f4d8e89..22aff7be 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -133,7 +133,7 @@ usage (char * progname)
|
||||
{
|
||||
fprintf (stderr, VERSION_STRING);
|
||||
fprintf (stderr, "Usage:\n");
|
||||
- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
|
||||
+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
|
||||
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname);
|
||||
fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname);
|
||||
fprintf (stderr, " %s [-t|-T]\n", progname);
|
||||
@@ -147,6 +147,8 @@ usage (char * progname)
|
||||
@@ -138,7 +138,7 @@ usage (char * progname)
|
||||
fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname);
|
||||
- fprintf (stderr, " %s [-v level] -W\n", progname);
|
||||
+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname);
|
||||
fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname);
|
||||
fprintf (stderr, " %s [-h|-t|-T]\n", progname);
|
||||
@@ -151,6 +151,8 @@ usage (char * progname)
|
||||
" -f flush a multipath device map\n"
|
||||
" -F flush all multipath device maps\n"
|
||||
" -a add a device wwid to the wwids file\n"
|
||||
@ -107,7 +107,7 @@ index 69141db..e7771c0 100644
|
||||
" -c check if a device should be a path in a multipath device\n"
|
||||
" -C check if a multipath device has usable paths\n"
|
||||
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||
@@ -870,7 +872,7 @@ main (int argc, char *argv[])
|
||||
@@ -905,7 +907,7 @@ main (int argc, char *argv[])
|
||||
exit(RTVL_FAIL);
|
||||
multipath_conf = conf;
|
||||
conf->retrigger_tries = 0;
|
||||
@ -116,7 +116,7 @@ index 69141db..e7771c0 100644
|
||||
switch(arg) {
|
||||
case 1: printf("optarg : %s\n",optarg);
|
||||
break;
|
||||
@@ -940,6 +942,10 @@ main (int argc, char *argv[])
|
||||
@@ -975,6 +977,10 @@ main (int argc, char *argv[])
|
||||
case 'T':
|
||||
cmd = CMD_DUMP_CONFIG;
|
||||
break;
|
||||
@ -128,7 +128,7 @@ index 69141db..e7771c0 100644
|
||||
usage(argv[0]);
|
||||
exit(RTVL_OK);
|
||||
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||
index 9cdd05a..8befc45 100644
|
||||
index 9cdd05a3..8befc45a 100644
|
||||
--- a/multipath/multipath.8
|
||||
+++ b/multipath/multipath.8
|
||||
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
||||
@ -153,7 +153,7 @@ index 9cdd05a..8befc45 100644
|
||||
Remove the WWID for the specified device from the WWIDs file.
|
||||
.
|
||||
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||
index 17434ce..0fbcc46 100644
|
||||
index 17434cef..0fbcc46b 100644
|
||||
--- a/multipathd/multipathd.service
|
||||
+++ b/multipathd/multipathd.service
|
||||
@@ -15,6 +15,7 @@ Type=notify
|
@ -1,98 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 13:12:35 +0100
|
||||
Subject: [PATCH] multipathd: ignore "disable_changed_wwids"
|
||||
|
||||
This option has no effect any more.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/config.c | 1 -
|
||||
libmultipath/config.h | 1 -
|
||||
libmultipath/dict.c | 18 +++++++++++++++---
|
||||
multipath/multipath.conf.5 | 8 ++------
|
||||
4 files changed, 17 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 24d71ae..141f092 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -715,7 +715,6 @@ load_config (char * file)
|
||||
conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES;
|
||||
conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
|
||||
conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
|
||||
- conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS;
|
||||
conf->remove_retries = 0;
|
||||
conf->ghost_delay = DEFAULT_GHOST_DELAY;
|
||||
conf->all_tg_pt = DEFAULT_ALL_TG_PT;
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index b938c26..f5bf5b1 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -182,7 +182,6 @@ struct config {
|
||||
int delayed_reconfig;
|
||||
int uev_wait_timeout;
|
||||
int skip_kpartx;
|
||||
- int disable_changed_wwids;
|
||||
int remove_retries;
|
||||
int max_sectors_kb;
|
||||
int ghost_delay;
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index eaad4f1..96815f8 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -156,6 +156,12 @@ out:
|
||||
return len;
|
||||
}
|
||||
|
||||
+static int
|
||||
+print_ignored (char *buff, int len)
|
||||
+{
|
||||
+ return snprintf(buff, len, "ignored");
|
||||
+}
|
||||
+
|
||||
static int
|
||||
print_yes_no (char *buff, int len, long v)
|
||||
{
|
||||
@@ -548,9 +554,15 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef)
|
||||
declare_hw_snprint(skip_kpartx, print_yes_no_undef)
|
||||
declare_mp_handler(skip_kpartx, set_yes_no_undef)
|
||||
declare_mp_snprint(skip_kpartx, print_yes_no_undef)
|
||||
-
|
||||
-declare_def_handler(disable_changed_wwids, set_yes_no)
|
||||
-declare_def_snprint(disable_changed_wwids, print_yes_no)
|
||||
+static int def_disable_changed_wwids_handler(struct config *conf, vector strvec)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+static int snprint_def_disable_changed_wwids(struct config *conf, char *buff,
|
||||
+ int len, const void *data)
|
||||
+{
|
||||
+ return print_ignored(buff, len);
|
||||
+}
|
||||
|
||||
declare_def_handler(remove_retries, set_int)
|
||||
declare_def_snprint(remove_retries, print_int)
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index 864d7eb..646c156 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -1148,12 +1148,8 @@ The default is: \fBno\fR
|
||||
.
|
||||
.TP
|
||||
.B disable_changed_wwids
|
||||
-If set to \fIyes\fR, multipathd will check the path wwid on change events, and
|
||||
-if it has changed from the wwid of the multipath device, multipathd will
|
||||
-disable access to the path until the wwid changes back.
|
||||
-.RS
|
||||
-.TP
|
||||
-The default is: \fBno\fR
|
||||
+This option is deprecated and ignored. If the WWID of a path suddenly changes,
|
||||
+multipathd handles it as if it was removed and then added again.
|
||||
.RE
|
||||
.
|
||||
.
|
||||
--
|
||||
2.17.2
|
||||
|
@ -16,7 +16,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
3 files changed, 35 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 96815f8..3b1b652 100644
|
||||
index d6d8b79b..07d2ba8f 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr)
|
||||
@ -41,7 +41,7 @@ index 96815f8..3b1b652 100644
|
||||
static int
|
||||
set_yes_no(vector strvec, void *ptr)
|
||||
{
|
||||
@@ -1386,7 +1401,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \
|
||||
@@ -1455,7 +1470,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
@ -50,7 +50,7 @@ index 96815f8..3b1b652 100644
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1402,7 +1417,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \
|
||||
@@ -1471,7 +1486,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \
|
||||
if (!conf->option) \
|
||||
return 1; \
|
||||
\
|
||||
@ -59,7 +59,7 @@ index 96815f8..3b1b652 100644
|
||||
if (!buff) \
|
||||
return 1; \
|
||||
\
|
||||
@@ -1505,16 +1520,16 @@ device_handler(struct config *conf, vector strvec)
|
||||
@@ -1574,16 +1589,16 @@ device_handler(struct config *conf, vector strvec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -81,11 +81,11 @@ index 96815f8..3b1b652 100644
|
||||
|
||||
declare_hw_handler(hwhandler, set_str)
|
||||
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||
index 92ef7cf..4289336 100644
|
||||
index e00c5fff..15495d26 100644
|
||||
--- a/libmultipath/parser.c
|
||||
+++ b/libmultipath/parser.c
|
||||
@@ -384,6 +384,19 @@ set_value(vector strvec)
|
||||
return alloc;
|
||||
@@ -382,6 +382,19 @@ oom:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+void *
|
||||
@ -105,7 +105,7 @@ index 92ef7cf..4289336 100644
|
||||
static int kw_level = 0;
|
||||
|
||||
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
|
||||
index 62906e9..b791705 100644
|
||||
index 62906e98..b7917052 100644
|
||||
--- a/libmultipath/parser.h
|
||||
+++ b/libmultipath/parser.h
|
||||
@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level);
|
@ -1,135 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 28 Mar 2019 15:17:48 -0500
|
||||
Subject: [PATCH] multipathd: Don't use fallback code after getting wwid
|
||||
|
||||
The fallback code is necessary to set up mutipath devices, if multipath
|
||||
temporarily can't get the information from udev. However, once the
|
||||
devices are set up, udev is the definitive source of this information.
|
||||
|
||||
The wwid gotten from the fallback code and the udev code should always
|
||||
be the same, in which case it doesn't matter where we get the wwid
|
||||
from. But if they are different, it's important to try to do the
|
||||
right thing.
|
||||
|
||||
Working under the assumption that udev will either never give us this
|
||||
information, or that it usually will. multipath should assume that if
|
||||
there are multiple paths to a device, either they will all never get
|
||||
a wwid from udev, or some of them will likely already have gotten the
|
||||
correct wwid from udev. In this case, we should fix this as soon as
|
||||
possible.
|
||||
|
||||
This does mean that devices where udev will never give out the uuid
|
||||
will not notice if the wwid changes, but that's a small price to pay
|
||||
for doing the right thing most of the time.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/discovery.c | 22 +++++++++-------------
|
||||
libmultipath/discovery.h | 3 ++-
|
||||
multipathd/main.c | 2 +-
|
||||
3 files changed, 12 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 3ec60d6..744cf2c 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -1763,7 +1763,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
!strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) {
|
||||
len = get_vpd_uid(pp);
|
||||
*origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
if (len < 0 && path_state == PATH_UP) {
|
||||
condlog(1, "%s: failed to get sysfs uid: %s",
|
||||
pp->dev, strerror(-len));
|
||||
@@ -1787,7 +1786,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state,
|
||||
len = WWID_SIZE;
|
||||
}
|
||||
*origin = "sysfs";
|
||||
- pp->uid_attribute = NULL;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@@ -1800,12 +1798,14 @@ static int has_uid_fallback(struct path *pp)
|
||||
}
|
||||
|
||||
int
|
||||
-get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
+get_uid (struct path * pp, int path_state, struct udev_device *udev,
|
||||
+ int allow_fallback)
|
||||
{
|
||||
char *c;
|
||||
const char *origin = "unknown";
|
||||
ssize_t len = 0;
|
||||
struct config *conf;
|
||||
+ int used_fallback = 0;
|
||||
|
||||
if (!pp->uid_attribute && !pp->getuid) {
|
||||
conf = get_multipath_config();
|
||||
@@ -1846,14 +1846,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
len = get_vpd_uid(pp);
|
||||
origin = "sysfs";
|
||||
}
|
||||
- if (len <= 0 && has_uid_fallback(pp)) {
|
||||
- int retrigger_tries;
|
||||
-
|
||||
- conf = get_multipath_config();
|
||||
- retrigger_tries = conf->retrigger_tries;
|
||||
- put_multipath_config(conf);
|
||||
- if (pp->retriggers >= retrigger_tries)
|
||||
- len = uid_fallback(pp, path_state, &origin);
|
||||
+ if (len <= 0 && allow_fallback && has_uid_fallback(pp)) {
|
||||
+ used_fallback = 1;
|
||||
+ len = uid_fallback(pp, path_state, &origin);
|
||||
}
|
||||
}
|
||||
if ( len < 0 ) {
|
||||
@@ -1870,7 +1865,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev)
|
||||
c--;
|
||||
}
|
||||
}
|
||||
- condlog(3, "%s: uid = %s (%s)", pp->dev,
|
||||
+ condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev,
|
||||
*pp->wwid == '\0' ? "<empty>" : pp->wwid, origin);
|
||||
return 0;
|
||||
}
|
||||
@@ -1994,7 +1989,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
||||
}
|
||||
|
||||
if ((mask & DI_WWID) && !strlen(pp->wwid)) {
|
||||
- get_uid(pp, path_state, pp->udev);
|
||||
+ get_uid(pp, path_state, pp->udev,
|
||||
+ (pp->retriggers >= conf->retrigger_tries));
|
||||
if (!strlen(pp->wwid)) {
|
||||
if (pp->bus == SYSFS_BUS_UNDEF)
|
||||
return PATHINFO_SKIPPED;
|
||||
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
||||
index 9aacf75..8fd126b 100644
|
||||
--- a/libmultipath/discovery.h
|
||||
+++ b/libmultipath/discovery.h
|
||||
@@ -52,7 +52,8 @@ ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff,
|
||||
size_t len);
|
||||
int sysfs_get_asymmetric_access_state(struct path *pp,
|
||||
char *buff, int buflen);
|
||||
-int get_uid(struct path * pp, int path_state, struct udev_device *udev);
|
||||
+int get_uid(struct path * pp, int path_state, struct udev_device *udev,
|
||||
+ int allow_fallback);
|
||||
|
||||
/*
|
||||
* discovery bitmask
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index e4f95a0..1413c6d 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -1227,7 +1227,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
|
||||
goto out;
|
||||
|
||||
strcpy(wwid, pp->wwid);
|
||||
- rc = get_uid(pp, pp->state, uev->udev);
|
||||
+ rc = get_uid(pp, pp->state, uev->udev, 0);
|
||||
|
||||
if (rc != 0)
|
||||
strcpy(pp->wwid, wwid);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||
index 6576939..2ad6308 100644
|
||||
index 4dfe007c..d910da51 100644
|
||||
--- a/libmultipath/defaults.h
|
||||
+++ b/libmultipath/defaults.h
|
||||
@@ -17,7 +17,7 @@
|
||||
@@ -20,7 +20,7 @@
|
||||
#define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF
|
||||
#define DEFAULT_VERBOSITY 2
|
||||
#define DEFAULT_REASSIGN_MAPS 0
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 28 Mar 2019 17:49:38 -0500
|
||||
Subject: [PATCH] libmultipath: silence dm_is_mpath error messages
|
||||
|
||||
When "multipath -F" is run, dm_is_mpath was printing error messages
|
||||
about partition devices, because they had already been removed, when
|
||||
it checked. Lower the error logging level so this doesn't happen on
|
||||
the default verbosity.
|
||||
|
||||
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 3294bd4..2e79667 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -746,7 +746,7 @@ out_task:
|
||||
dm_task_destroy(dmt);
|
||||
out:
|
||||
if (r < 0)
|
||||
- condlog(2, "%s: dm command failed in %s", name, __FUNCTION__);
|
||||
+ condlog(3, "%s: dm command failed in %s: %s", name, __FUNCTION__, strerror(errno));
|
||||
return r;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -9,7 +9,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h
|
||||
index adb192b..bfd10ef 100644
|
||||
index adb192b6..bfd10ef8 100644
|
||||
--- a/libmultipath/nvme/argconfig.h
|
||||
+++ b/libmultipath/nvme/argconfig.h
|
||||
@@ -76,7 +76,7 @@ struct argconfig_commandline_options {
|
@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c
|
||||
index 990d935..d84571b 100644
|
||||
index 2673d9d9..f34ade28 100644
|
||||
--- a/libmultipath/prioritizers/ana.c
|
||||
+++ b/libmultipath/prioritizers/ana.c
|
||||
@@ -24,6 +24,7 @@
|
@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
|
||||
Date: Tue, 26 Mar 2019 16:34:32 -0500
|
||||
Subject: [PATCH] Fix systemd version detection
|
||||
|
||||
Signed-off-by: Igor Gnatenko <ignatenkobrain@fedoraproject.org>
|
||||
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 b98800a..da49852 100644
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -37,7 +37,7 @@ endif
|
||||
|
||||
ifndef SYSTEMD
|
||||
ifeq ($(shell systemctl --version > /dev/null 2>&1 && echo 1), 1)
|
||||
- SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\)/\1/p')
|
||||
+ SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p')
|
||||
endif
|
||||
endif
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,118 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 18 Apr 2019 12:49:46 -0500
|
||||
Subject: [PATCH] BZ 1700451: check on multipathd without starting it
|
||||
|
||||
When "multipath -u" is run, it checks if multipathd is running.
|
||||
Currently it does this by trying to connect to the mutipathd socket.
|
||||
This can cause problems during boot. The multipathd.socket systemd unit
|
||||
file will cause "multipath -u" to wait until multipathd has been started
|
||||
before continuing. If there is a lot of activity on the system,
|
||||
multipathd may not start up immediately, causing block device
|
||||
initialization to be delayed, potentially until after systemd times
|
||||
waiting for the device. To avoid this, multipath now checks if
|
||||
multipathd is running by reading /run/multipathd.pid and checking the
|
||||
/proc/<pid>/comm to verify that multipathd is really running with this
|
||||
pid. This avoids forcing "multipath -u" to wait on multipathd starting
|
||||
up.
|
||||
|
||||
As an alternative to this patch, multipath could simply switch the order
|
||||
of the calls to systemd_service_enabled() and mpath_connect(). This would
|
||||
make multipath only try to connect with multipathd if it wasn't enabled in
|
||||
systemd, so that it wouldn't autostart.
|
||||
|
||||
Another alternative is to do away with multipathd.socket. Since multipathd
|
||||
needs to always be running in order to get uevents, there isn't much value
|
||||
in having it autoactivate when it gets an interactive command.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipath/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 54 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index e7771c0..632ce4d 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -852,6 +852,58 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
+int is_multipathd_running(void)
|
||||
+{
|
||||
+ FILE *f = NULL;
|
||||
+ char buf[16];
|
||||
+ char path[PATH_MAX];
|
||||
+ int pid;
|
||||
+ char *end;
|
||||
+
|
||||
+ f = fopen(DEFAULT_PIDFILE, "r");
|
||||
+ if (!f) {
|
||||
+ if (errno != ENOENT)
|
||||
+ condlog(4, "can't open " DEFAULT_PIDFILE ": %s",
|
||||
+ strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(4, "read of " DEFAULT_PIDFILE " failed: %s",
|
||||
+ strerror(errno));
|
||||
+ fclose(f);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ errno = 0;
|
||||
+ strchop(buf);
|
||||
+ pid = strtol(buf, &end, 10);
|
||||
+ if (errno != 0 || pid <= 0 || *end != '\0') {
|
||||
+ condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'",
|
||||
+ buf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ snprintf(path, sizeof(path), "/proc/%d/comm", pid);
|
||||
+ f = fopen(path, "r");
|
||||
+ if (!f) {
|
||||
+ if (errno != ENOENT)
|
||||
+ condlog(4, "can't open %s: %s", path, strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||
+ if (ferror(f))
|
||||
+ condlog(4, "read of %s failed: %s", path,
|
||||
+ strerror(errno));
|
||||
+ fclose(f);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ fclose(f);
|
||||
+ strchop(buf);
|
||||
+ if (strcmp(buf, "multipathd") != 0)
|
||||
+ return 0;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -1034,17 +1086,13 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (cmd == CMD_VALID_PATH &&
|
||||
dev_type == DEV_UEVENT) {
|
||||
- int fd;
|
||||
-
|
||||
- fd = mpath_connect();
|
||||
- if (fd == -1) {
|
||||
+ if (!is_multipathd_running()) {
|
||||
condlog(3, "%s: daemon is not running", dev);
|
||||
if (!systemd_service_enabled(dev)) {
|
||||
r = print_cmd_valid(RTVL_NO, NULL, conf);
|
||||
goto out;
|
||||
}
|
||||
- } else
|
||||
- mpath_disconnect(fd);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (cmd == CMD_REMOVE_WWID && !dev) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,223 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Wed, 24 Apr 2019 11:07:59 +0200
|
||||
Subject: [PATCH] BZ 1700451: test socket connection in non-blocking mode
|
||||
|
||||
Since commit d7188fcd "multipathd: start daemon after udev trigger",
|
||||
multipathd startup is delayed during boot until after "udev settle"
|
||||
terminates. But "multipath -u" is run by udev workers for storage devices,
|
||||
and attempts to connect to the multipathd socket. This causes a start job
|
||||
for multipathd to be scheduled by systemd, but that job won't be started
|
||||
until "udev settle" finishes. This is not a problem on systems with 129 or
|
||||
less storage units, because the connect() call of "multipath -u" will
|
||||
succeed anyway. But on larger systems, the listen backlog of the systemd
|
||||
socket can be exceeded, which causes connect() calls for the socket to
|
||||
block until multipathd starts up and begins calling accept(). This creates
|
||||
a deadlock situation, because "multipath -u" (called by udev workers)
|
||||
blocks, and thus "udev settle" doesn't finish, delaying multipathd
|
||||
startup. This situation then persists until either the workers or "udev
|
||||
settle" time out. In the former case, path devices might be misclassified
|
||||
as non-multipath devices by "multipath -u".
|
||||
|
||||
Fix this by using a non-blocking socket fd for connect() and interpret the
|
||||
errno appropriately.
|
||||
|
||||
This patch reverts most of the changes from commit 8cdf6661 "multipath:
|
||||
check on multipathd without starting it". Instead, "multipath -u" does
|
||||
access the socket and start multipath again (which is what we want IMO),
|
||||
but it is now able to detect and handle the "full backlog" situation.
|
||||
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
|
||||
V2:
|
||||
|
||||
Use same error reporting convention in __mpath_connect() as in
|
||||
mpath_connect() (Hannes Reinecke). We can't easily change the latter,
|
||||
because it's part of the "public" libmpathcmd API.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmpathcmd/mpath_cmd.c | 24 +++++++++++++-
|
||||
libmpathcmd/mpath_cmd.h | 15 +++++++++
|
||||
multipath/main.c | 70 +++++++++++++----------------------------
|
||||
3 files changed, 60 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c
|
||||
index df4ca54..b681311 100644
|
||||
--- a/libmpathcmd/mpath_cmd.c
|
||||
+++ b/libmpathcmd/mpath_cmd.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
|
||||
#include "mpath_cmd.h"
|
||||
|
||||
@@ -93,10 +94,11 @@ static size_t write_all(int fd, const void *buf, size_t len)
|
||||
/*
|
||||
* connect to a unix domain socket
|
||||
*/
|
||||
-int mpath_connect(void)
|
||||
+int __mpath_connect(int nonblocking)
|
||||
{
|
||||
int fd, len;
|
||||
struct sockaddr_un addr;
|
||||
+ int flags = 0;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_LOCAL;
|
||||
@@ -108,14 +110,34 @@ int mpath_connect(void)
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
+ if (nonblocking) {
|
||||
+ flags = fcntl(fd, F_GETFL, 0);
|
||||
+ if (flags != -1)
|
||||
+ (void)fcntl(fd, F_SETFL, flags|O_NONBLOCK);
|
||||
+ }
|
||||
+
|
||||
if (connect(fd, (struct sockaddr *)&addr, len) == -1) {
|
||||
+ int err = errno;
|
||||
+
|
||||
close(fd);
|
||||
+ errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ if (nonblocking && flags != -1)
|
||||
+ (void)fcntl(fd, F_SETFL, flags);
|
||||
+
|
||||
return fd;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * connect to a unix domain socket
|
||||
+ */
|
||||
+int mpath_connect(void)
|
||||
+{
|
||||
+ return __mpath_connect(0);
|
||||
+}
|
||||
+
|
||||
int mpath_disconnect(int fd)
|
||||
{
|
||||
return close(fd);
|
||||
diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h
|
||||
index 15aeb06..ccfd35f 100644
|
||||
--- a/libmpathcmd/mpath_cmd.h
|
||||
+++ b/libmpathcmd/mpath_cmd.h
|
||||
@@ -34,6 +34,21 @@ extern "C" {
|
||||
#define DEFAULT_REPLY_TIMEOUT 4000
|
||||
|
||||
|
||||
+/*
|
||||
+ * DESCRIPTION:
|
||||
+ * Same as mpath_connect() (see below) except for the "nonblocking"
|
||||
+ * parameter.
|
||||
+ * If "nonblocking" is set, connects in non-blocking mode. This is
|
||||
+ * useful to avoid blocking if the listening socket's backlog is
|
||||
+ * exceeded. In this case, errno will be set to EAGAIN.
|
||||
+ * In case of success, the returned file descriptor is in in blocking
|
||||
+ * mode, even if "nonblocking" was true.
|
||||
+ *
|
||||
+ * RETURNS:
|
||||
+ * A file descriptor on success. -1 on failure (with errno set).
|
||||
+ */
|
||||
+int __mpath_connect(int nonblocking);
|
||||
+
|
||||
/*
|
||||
* DESCRIPTION:
|
||||
* Connect to the running multipathd daemon. On systems with the
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 632ce4d..3fb6699 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -852,55 +852,29 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
-int is_multipathd_running(void)
|
||||
+static int test_multipathd_socket(void)
|
||||
{
|
||||
- FILE *f = NULL;
|
||||
- char buf[16];
|
||||
- char path[PATH_MAX];
|
||||
- int pid;
|
||||
- char *end;
|
||||
+ 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.
|
||||
+ */
|
||||
|
||||
- f = fopen(DEFAULT_PIDFILE, "r");
|
||||
- if (!f) {
|
||||
- if (errno != ENOENT)
|
||||
- condlog(4, "can't open " DEFAULT_PIDFILE ": %s",
|
||||
- strerror(errno));
|
||||
- return 0;
|
||||
- }
|
||||
- if (!fgets(buf, sizeof(buf), f)) {
|
||||
- if (ferror(f))
|
||||
- condlog(4, "read of " DEFAULT_PIDFILE " failed: %s",
|
||||
- strerror(errno));
|
||||
- fclose(f);
|
||||
- return 0;
|
||||
- }
|
||||
- fclose(f);
|
||||
- errno = 0;
|
||||
- strchop(buf);
|
||||
- pid = strtol(buf, &end, 10);
|
||||
- if (errno != 0 || pid <= 0 || *end != '\0') {
|
||||
- condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'",
|
||||
- buf);
|
||||
- return 0;
|
||||
- }
|
||||
- snprintf(path, sizeof(path), "/proc/%d/comm", pid);
|
||||
- f = fopen(path, "r");
|
||||
- if (!f) {
|
||||
- if (errno != ENOENT)
|
||||
- condlog(4, "can't open %s: %s", path, strerror(errno));
|
||||
- return 0;
|
||||
- }
|
||||
- if (!fgets(buf, sizeof(buf), f)) {
|
||||
- if (ferror(f))
|
||||
- condlog(4, "read of %s failed: %s", path,
|
||||
- strerror(errno));
|
||||
- fclose(f);
|
||||
- return 0;
|
||||
- }
|
||||
- fclose(f);
|
||||
- strchop(buf);
|
||||
- if (strcmp(buf, "multipathd") != 0)
|
||||
- return 0;
|
||||
+ fd = __mpath_connect(1);
|
||||
+ if (fd == -1) {
|
||||
+ if (errno == EAGAIN)
|
||||
+ condlog(3, "daemon backlog exceeded");
|
||||
+ else
|
||||
+ return 0;
|
||||
+ } else
|
||||
+ close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1060,7 @@ main (int argc, char *argv[])
|
||||
}
|
||||
if (cmd == CMD_VALID_PATH &&
|
||||
dev_type == DEV_UEVENT) {
|
||||
- if (!is_multipathd_running()) {
|
||||
+ 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);
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,61 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 12:41:33 -0500
|
||||
Subject: [PATCH] libmultipath: handle clock_gettime failures in tur checker
|
||||
|
||||
If clock_gettime() fails, and multipathd can't figure out when it should
|
||||
time out, it should just default to assuming that it has already timed
|
||||
out. Found by coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/checkers/tur.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
||||
index 6b08dbb..717353e 100644
|
||||
--- a/libmultipath/checkers/tur.c
|
||||
+++ b/libmultipath/checkers/tur.c
|
||||
@@ -290,7 +290,12 @@ static void *tur_thread(void *ctx)
|
||||
|
||||
static void tur_timeout(struct timespec *tsp)
|
||||
{
|
||||
- clock_gettime(CLOCK_MONOTONIC, tsp);
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, tsp) != 0) {
|
||||
+ /* can't get time. clear tsp to not wait */
|
||||
+ tsp->tv_sec = 0;
|
||||
+ tsp->tv_nsec = 0;
|
||||
+ return;
|
||||
+ }
|
||||
tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
|
||||
normalize_timespec(tsp);
|
||||
}
|
||||
@@ -300,8 +305,12 @@ static void tur_set_async_timeout(struct checker *c)
|
||||
struct tur_checker_context *ct = c->context;
|
||||
struct timespec now;
|
||||
|
||||
- clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
- ct->time = now.tv_sec + c->timeout;
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
|
||||
+ /* can't get time. clear time to always timeout on
|
||||
+ * next path check */
|
||||
+ ct->time = 0;
|
||||
+ else
|
||||
+ ct->time = now.tv_sec + c->timeout;
|
||||
}
|
||||
|
||||
static int tur_check_async_timeout(struct checker *c)
|
||||
@@ -309,7 +318,9 @@ static int tur_check_async_timeout(struct checker *c)
|
||||
struct tur_checker_context *ct = c->context;
|
||||
struct timespec now;
|
||||
|
||||
- clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
|
||||
+ /* can't get time. assume we've timed out */
|
||||
+ return 1;
|
||||
return (now.tv_sec > ct->time);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 12:55:16 -0500
|
||||
Subject: [PATCH] kpartx: fail if dup() of dasd file descriptor fails
|
||||
|
||||
If kpartx fails to create a copy of the dasd file descriptor, it should
|
||||
fail, instead of treating the error value as a valid fd. Found by
|
||||
coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
kpartx/dasd.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/kpartx/dasd.c b/kpartx/dasd.c
|
||||
index 61b609a..d95d8ca 100644
|
||||
--- a/kpartx/dasd.c
|
||||
+++ b/kpartx/dasd.c
|
||||
@@ -138,6 +138,8 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns)
|
||||
return -1;
|
||||
} else {
|
||||
fd_dasd = dup(fd);
|
||||
+ if (fd_dasd < 0)
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) {
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 13:31:35 -0500
|
||||
Subject: [PATCH] multipathd: fix REALLOC_REPLY with max length reply
|
||||
|
||||
Commit cd5a9797e added code to REALLOC_REPLY() that intended to stop
|
||||
growing the reply buffer after it reached a maximum size. However this
|
||||
coded didn't stop the realloc() from happening. Worse, if the realloci()
|
||||
failed, multipathd would double free the reply buffer. Found by
|
||||
Coverity.
|
||||
|
||||
Fixes: cd5a9797e "libmpathcmd(coverity): limit reply length"
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli.h | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/multipathd/cli.h b/multipathd/cli.h
|
||||
index f3fa077..32dcffa 100644
|
||||
--- a/multipathd/cli.h
|
||||
+++ b/multipathd/cli.h
|
||||
@@ -100,15 +100,16 @@ enum {
|
||||
if (m >= MAX_REPLY_LEN) { \
|
||||
condlog(1, "Warning: max reply length exceeded"); \
|
||||
free(tmp); \
|
||||
- r = NULL; \
|
||||
+ (r) = NULL; \
|
||||
+ } else { \
|
||||
+ (r) = REALLOC((r), (m) * 2); \
|
||||
+ if ((r)) { \
|
||||
+ memset((r) + (m), 0, (m)); \
|
||||
+ (m) *= 2; \
|
||||
+ } \
|
||||
+ else \
|
||||
+ free(tmp); \
|
||||
} \
|
||||
- (r) = REALLOC((r), (m) * 2); \
|
||||
- if ((r)) { \
|
||||
- memset((r) + (m), 0, (m)); \
|
||||
- (m) *= 2; \
|
||||
- } \
|
||||
- else \
|
||||
- free(tmp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Thu, 16 May 2019 15:44:20 -0500
|
||||
Subject: [PATCH] multipathd: handle NULL return from genhelp_handler
|
||||
|
||||
If parse_cmd() wasn't checking if genhelp_handler() returned NULL. It
|
||||
was simply assuming that it got a string. Instead, it should just return
|
||||
and error. Found by Coverity.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
multipathd/cli.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
||||
index ca176a9..17795b6 100644
|
||||
--- a/multipathd/cli.c
|
||||
+++ b/multipathd/cli.c
|
||||
@@ -467,6 +467,8 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
|
||||
|
||||
if (r) {
|
||||
*reply = genhelp_handler(cmd, r);
|
||||
+ if (*reply == NULL)
|
||||
+ return EINVAL;
|
||||
*len = strlen(*reply) + 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -474,9 +476,11 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout )
|
||||
h = find_handler(fingerprint(cmdvec));
|
||||
|
||||
if (!h || !h->fn) {
|
||||
+ free_keys(cmdvec);
|
||||
*reply = genhelp_handler(cmd, EINVAL);
|
||||
+ if (*reply == NULL)
|
||||
+ return EINVAL;
|
||||
*len = strlen(*reply) + 1;
|
||||
- free_keys(cmdvec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Wilck <mwilck@suse.com>
|
||||
Date: Mon, 18 Mar 2019 12:24:45 +0100
|
||||
Subject: [PATCH] BZ 1700911: hwtable: add Lenovo DE series
|
||||
|
||||
I got this from Steven.
|
||||
|
||||
Cc: Steve.Schremmer@netapp.com
|
||||
Cc: NetApp RDAC team <ng-eseries-upstream-maintainers@netapp.com>
|
||||
Cc: xose.vazquez@gmail.com
|
||||
Signed-off-by: Martin Wilck <mwilck@suse.com>
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/hwtable.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index 8776411..f13591d 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -701,6 +701,26 @@ static struct hwentry default_hw[] = {
|
||||
.no_path_retry = (300 / DEFAULT_CHECKINT),
|
||||
.prio_name = PRIO_ALUA,
|
||||
},
|
||||
+ /*
|
||||
+ * Lenovo
|
||||
+ */
|
||||
+ {
|
||||
+ /*
|
||||
+ * DE Series
|
||||
+ *
|
||||
+ * Maintainer: ng-eseries-upstream-maintainers@netapp.com
|
||||
+ */
|
||||
+ .vendor = "LENOVO",
|
||||
+ .product = "DE_Series",
|
||||
+ .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,
|
||||
+ },
|
||||
/*
|
||||
* NetApp
|
||||
*/
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
Date: Fri, 24 May 2019 17:30:07 -0500
|
||||
Subject: [PATCH] libmultipath: make vector_foreach_slot_backwards work as
|
||||
expected
|
||||
|
||||
All of the code that uses vector_foreach_slot_backwards() treats "i" as
|
||||
the index of the entry "p", but the way it was coded, that wasn't the
|
||||
case. "i" was the number of the entry counting from 1, not 0.
|
||||
|
||||
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||
---
|
||||
libmultipath/vector.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libmultipath/vector.h b/libmultipath/vector.h
|
||||
index 41d2b89..344dffd 100644
|
||||
--- a/libmultipath/vector.h
|
||||
+++ b/libmultipath/vector.h
|
||||
@@ -40,7 +40,7 @@ typedef struct _vector *vector;
|
||||
#define vector_foreach_slot_after(v,p,i) \
|
||||
for (; (v) && i < VECTOR_SIZE(v) && ((p) = (v)->slot[i]); i++)
|
||||
#define vector_foreach_slot_backwards(v,p,i) \
|
||||
- for (i = VECTOR_SIZE(v); i > 0 && ((p) = (v)->slot[i-1]); i--)
|
||||
+ for (i = VECTOR_SIZE(v) - 1; (int)i >= 0 && ((p) = (v)->slot[i]); i--)
|
||||
|
||||
#define identity(x) (x)
|
||||
/*
|
||||
--
|
||||
2.17.2
|
||||
|
@ -1,52 +1,35 @@
|
||||
Summary: Tools to manage multipath devices using device-mapper
|
||||
Name: device-mapper-multipath
|
||||
Version: 0.8.0
|
||||
Release: 5%{?dist}
|
||||
Version: 0.8.3
|
||||
Release: 3%{?dist}
|
||||
License: GPLv2
|
||||
Group: System Environment/Base
|
||||
URL: http://christophe.varoqui.free.fr/
|
||||
|
||||
# The source for this package was pulled from upstream's git repo. Use the
|
||||
# following command to generate the tarball
|
||||
#curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.0;sf=tgz" -o multipath-tools-0.8.0.tgz
|
||||
Source0: multipath-tools-0.8.0.tgz
|
||||
#curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.3;sf=tgz" -o multipath-tools-0.8.3.tgz
|
||||
Source0: multipath-tools-0.8.3.tgz
|
||||
Source1: multipath.conf
|
||||
Patch0001: 0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch
|
||||
Patch0002: 0002-libmultipath-handle-existing-paths-in-marginal_path-.patch
|
||||
Patch0003: 0003-multipathd-cleanup-marginal-paths-checking-timers.patch
|
||||
Patch0004: 0004-libmultipath-fix-marginal-paths-queueing-errors.patch
|
||||
Patch0005: 0005-libmultipath-fix-marginal_paths-nr_active-check.patch
|
||||
Patch0006: 0006-multipathd-Fix-miscounting-active-paths.patch
|
||||
Patch0007: 0007-multipathd-ignore-failed-wwid-recheck.patch
|
||||
Patch0008: 0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch
|
||||
Patch0009: 0009-multipathd-use-update_path_groups-instead-of-reload_.patch
|
||||
Patch0010: 0010-multipath.conf-add-missing-options-to-man-page.patch
|
||||
Patch0011: 0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch
|
||||
Patch0012: 0012-libmulitpath-cleanup-uid_fallback-code.patch
|
||||
Patch0013: 0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch
|
||||
Patch0014: 0014-multipathd-remove-wwid_changed-path-attribute.patch
|
||||
Patch0015: 0015-multipathd-ignore-disable_changed_wwids.patch
|
||||
Patch0016: 0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch
|
||||
Patch0017: 0017-libmultipath-silence-dm_is_mpath-error-messages.patch
|
||||
Patch0018: 0018-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch0019: 0019-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch0020: 0020-RH-don-t-start-without-a-config-file.patch
|
||||
Patch0021: 0021-RH-use-rpm-optflags-if-present.patch
|
||||
Patch0022: 0022-RH-add-mpathconf.patch
|
||||
Patch0023: 0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch0024: 0024-RH-warn-on-invalid-regex-instead-of-failing.patch
|
||||
Patch0025: 0025-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch0026: 0026-RH-Fix-nvme-compilation-warning.patch
|
||||
Patch0027: 0027-Fix-systemd-version-detection.patch
|
||||
Patch0028: 0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
Patch0029: 0029-BZ-1700451-check-on-multipathd-without-starting-it.patch
|
||||
Patch0030: 0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch
|
||||
Patch0031: 0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch
|
||||
Patch0032: 0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch
|
||||
Patch0033: 0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch
|
||||
Patch0034: 0034-multipathd-handle-NULL-return-from-genhelp_handler.patch
|
||||
Patch0035: 0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch
|
||||
Patch0036: 0036-libmultipath-make-vector_foreach_slot_backwards-work.patch
|
||||
Patch00001: 0001-multipathd-warn-when-configuration-has-been-changed.patch
|
||||
Patch00002: 0002-libmultipath-fix-leak-in-foreign-code.patch
|
||||
Patch00003: 0003-Fix-leak-in-mpathpersist.patch
|
||||
Patch00004: 0004-libmultipath-remove-unused-path-prio_args.patch
|
||||
Patch00005: 0005-libmultipath-constify-get_unaligned_be.patch
|
||||
Patch00006: 0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch
|
||||
Patch00007: 0007-libmultipath-fix-sgio_get_vpd-looping.patch
|
||||
Patch00008: 0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch
|
||||
Patch00009: 0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch
|
||||
Patch00010: 0010-RH-fixup-udev-rules-for-redhat.patch
|
||||
Patch00011: 0011-RH-Remove-the-property-blacklist-exception-builtin.patch
|
||||
Patch00012: 0012-RH-don-t-start-without-a-config-file.patch
|
||||
Patch00013: 0013-RH-use-rpm-optflags-if-present.patch
|
||||
Patch00014: 0014-RH-add-mpathconf.patch
|
||||
Patch00015: 0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch
|
||||
Patch00016: 0016-RH-warn-on-invalid-regex-instead-of-failing.patch
|
||||
Patch00017: 0017-RH-reset-default-find_mutipaths-value-to-off.patch
|
||||
Patch00018: 0018-RH-Fix-nvme-compilation-warning.patch
|
||||
Patch00019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch
|
||||
|
||||
# runtime
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
@ -124,7 +107,7 @@ This package contains the files needed to develop applications that use
|
||||
device-mapper-multipath's libdmmp C API library
|
||||
|
||||
%prep
|
||||
%autosetup -n multipath-tools-0.8.0 -p1
|
||||
%autosetup -n multipath-tools-0.8.3 -p1
|
||||
cp %{SOURCE1} .
|
||||
|
||||
%build
|
||||
@ -248,6 +231,42 @@ fi
|
||||
%{_pkgconfdir}/libdmmp.pc
|
||||
|
||||
%changelog
|
||||
* Fri Nov 8 2019 Benjamin Marzinski <bmarzins@redhat.com> 0.8.3-3
|
||||
- Rename files
|
||||
* Previous patches 0004-0013 are now 0010-0019
|
||||
* 0014-RH-add-mpathconf.patch now makes mpathconf default to not
|
||||
printing foreign devices (bz #1760709)
|
||||
- Add 0004-libmultipath-remove-unused-path-prio_args.patch
|
||||
- Add 0005-libmultipath-constify-get_unaligned_be.patch
|
||||
- Add 0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch
|
||||
- Add 0007-libmultipath-fix-sgio_get_vpd-looping.patch
|
||||
- Add 0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch
|
||||
- Add 0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch
|
||||
* Add the '%g' maps and paths format wildcard, and the vpd_vendor
|
||||
multipath.conf devices section parameter. (bz #1527212)
|
||||
- Resolves: bz #1527212, #1760709
|
||||
|
||||
* Mon Oct 14 2019 Benjamin Marzinski <bmarzins@redhat.com> 0.8.3-2
|
||||
- Update CI tests
|
||||
- Related: bz #1690515
|
||||
|
||||
* Tue Oct 8 2019 Benjamin Marzinski <bmarzins@redhat.com> 0.8.3-1
|
||||
- Update Source to upstream version 0.8.3
|
||||
* This version includes the fixes for bz #1690515, #1703439,
|
||||
#1719562 & #1747534
|
||||
* Previous patches 0001-0017 & 0031-0036 are included in this version
|
||||
- Rename files
|
||||
* Previous patches 0018-0026 & 0028 are now 0004-0013
|
||||
* 0008-RH-add-mpathconf.patch has been modified to add a
|
||||
--property_blacklist option to fix bz #1753729
|
||||
- Add 0001-multipathd-warn-when-configuration-has-been-changed.patch
|
||||
* Multipath now logs a warning message when the configuration file
|
||||
has been changed to fix bz #1750594
|
||||
- Add 0002-libmultipath-fix-leak-in-foreign-code.patch
|
||||
- Add 0003-Fix-leak-in-mpathpersist.patch
|
||||
* The above 3 patches have been submitted upstream
|
||||
- Resolves: bz #1690515, #1703439, #1719562, #1747534, #1750594, #1753729
|
||||
|
||||
* Mon Jun 3 2019 Benjamin Marzinski <bmarzins@redhat.com> 0.8.0-5
|
||||
- Bump release number for test fix commit 0b68e623
|
||||
- Related: bz #1666322
|
||||
|
Loading…
Reference in New Issue
Block a user