import device-mapper-multipath-0.8.3-3.el8
This commit is contained in:
commit
9192a4abe3
1
.device-mapper-multipath.metadata
Normal file
1
.device-mapper-multipath.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
f700dc1e4ce1d6952051467d4b245f9bd80286e3 SOURCES/multipath-tools-0.8.3.tgz
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
SOURCES/multipath-tools-0.8.3.tgz
|
@ -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
|
||||||
|
|
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
|
||||||
|
|
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
|
||||||
|
|
@ -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
|
||||||
|
|
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
|
||||||
|
|
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
|
||||||
|
|
@ -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
|
||||||
|
|
66
SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch
Normal file
66
SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 13 Apr 2017 07:22:23 -0500
|
||||||
|
Subject: [PATCH] RH: fixup udev rules for redhat
|
||||||
|
|
||||||
|
The multipath rules need to run after scsi_id is run. This means moving
|
||||||
|
them after 60-persistent-storage.rules for redhat. Redhat also uses a
|
||||||
|
different naming scheme for partitions than SuSE.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
Makefile.inc | 2 +-
|
||||||
|
kpartx/kpartx.rules | 2 +-
|
||||||
|
multipath/Makefile | 4 ++--
|
||||||
|
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile.inc b/Makefile.inc
|
||||||
|
index 56c3eda0..2e8946ca 100644
|
||||||
|
--- a/Makefile.inc
|
||||||
|
+++ b/Makefile.inc
|
||||||
|
@@ -53,7 +53,7 @@ endif
|
||||||
|
prefix =
|
||||||
|
exec_prefix = $(prefix)
|
||||||
|
usr_prefix = $(prefix)
|
||||||
|
-bindir = $(exec_prefix)/sbin
|
||||||
|
+bindir = $(exec_prefix)/usr/sbin
|
||||||
|
libudevdir = $(prefix)/$(SYSTEMDPATH)/udev
|
||||||
|
udevrulesdir = $(libudevdir)/rules.d
|
||||||
|
multipathdir = $(TOPDIR)/libmultipath
|
||||||
|
diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules
|
||||||
|
index 8f990494..8a3a1718 100644
|
||||||
|
--- a/kpartx/kpartx.rules
|
||||||
|
+++ b/kpartx/kpartx.rules
|
||||||
|
@@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end"
|
||||||
|
GOTO="kpartx_end"
|
||||||
|
|
||||||
|
LABEL="run_kpartx"
|
||||||
|
-RUN+="/sbin/kpartx -un -p -part /dev/$name"
|
||||||
|
+RUN+="/sbin/kpartx -un /dev/$name"
|
||||||
|
|
||||||
|
LABEL="kpartx_end"
|
||||||
|
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||||
|
index 0828a8f7..b9bbb3cf 100644
|
||||||
|
--- a/multipath/Makefile
|
||||||
|
+++ b/multipath/Makefile
|
||||||
|
@@ -24,7 +24,7 @@ install:
|
||||||
|
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||||
|
- $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||||
|
+ $(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man8dir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||||
|
@@ -33,7 +33,7 @@ install:
|
||||||
|
uninstall:
|
||||||
|
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||||
|
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||||
|
- $(RM) $(DESTDIR)$(libudevdir)/rules.d/56-multipath.rules
|
||||||
|
+ $(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||||
|
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||||
|
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||||
|
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
@ -0,0 +1,105 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 2 Jul 2014 12:49:53 -0500
|
||||||
|
Subject: [PATCH] RH: Remove the property blacklist exception builtin
|
||||||
|
|
||||||
|
Multipath set the default property blacklist exceptions to
|
||||||
|
(ID_SCSI_VPD|ID_WWN). This has the effect of blacklisting some internal
|
||||||
|
devices. These devices may never have multiple paths, but it is nice
|
||||||
|
to be able to set multipath up on them all the same. This patch simply
|
||||||
|
removes the default, and makes it so that if no property
|
||||||
|
blacklist_exception is given, then devices aren't failed for not matching
|
||||||
|
it.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
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 00e8dbdb..d9691b17 100644
|
||||||
|
--- a/libmultipath/blacklist.c
|
||||||
|
+++ b/libmultipath/blacklist.c
|
||||||
|
@@ -204,12 +204,6 @@ setup_default_blist (struct config * conf)
|
||||||
|
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
- str = STRDUP("(SCSI_IDENT_|ID_WWN)");
|
||||||
|
- if (!str)
|
||||||
|
- return 1;
|
||||||
|
- if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT))
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
vector_foreach_slot (conf->hwtable, hwe, i) {
|
||||||
|
if (hwe->bl_product) {
|
||||||
|
if (find_blacklist_device(conf->blist_device,
|
||||||
|
@@ -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;
|
||||||
|
udev_list_entry_foreach(list_entry,
|
||||||
|
udev_device_get_properties_list_entry(udev)) {
|
||||||
|
|
||||||
|
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||||
|
index dc103fd8..b8697d47 100644
|
||||||
|
--- a/multipath/multipath.conf.5
|
||||||
|
+++ b/multipath/multipath.conf.5
|
||||||
|
@@ -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,
|
||||||
|
-because devices \fBmust\fR have at least one whitelisted udev property;
|
||||||
|
+because if a property blacklist_exception is set, devices \fBmust\fR have at
|
||||||
|
+least one whitelisted udev property;
|
||||||
|
otherwise they're treated as blacklisted, and the message
|
||||||
|
"\fIblacklisted, udev property missing\fR" is displayed in the logs.
|
||||||
|
+For example, setting the property blacklist_exception to
|
||||||
|
+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices
|
||||||
|
+that provide a WWN (World Wide Number) to be included, and all others to be
|
||||||
|
+excluded. This works to exclude most non-multipathable devices.
|
||||||
|
.
|
||||||
|
.RS
|
||||||
|
.PP
|
||||||
|
@@ -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
|
||||||
|
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
|
||||||
|
|
106
SOURCES/0012-RH-don-t-start-without-a-config-file.patch
Normal file
106
SOURCES/0012-RH-don-t-start-without-a-config-file.patch
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 15 Oct 2014 10:39:30 -0500
|
||||||
|
Subject: [PATCH] RH: don't start without a config file
|
||||||
|
|
||||||
|
If /etc/multipath.conf doesn't exist, don't start multipathd and blacklist
|
||||||
|
all devices when running multipath. A completely blank configuration file
|
||||||
|
is almost never what users want. Also, people may have the multipath
|
||||||
|
packages installed but don't want to use them. This patch provides a
|
||||||
|
simple way to disable multipath. Simply removing or renaming
|
||||||
|
/etc/multipath.conf will keep multipath from doing anything.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/config.c | 15 +++++++++++++++
|
||||||
|
libmultipath/config.h | 1 +
|
||||||
|
multipath/multipath.rules | 1 +
|
||||||
|
multipathd/multipathd.8 | 2 ++
|
||||||
|
multipathd/multipathd.service | 1 +
|
||||||
|
5 files changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||||
|
index 72b8d37c..4032c4c4 100644
|
||||||
|
--- a/libmultipath/config.c
|
||||||
|
+++ b/libmultipath/config.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include "devmapper.h"
|
||||||
|
#include "mpath_cmd.h"
|
||||||
|
#include "propsel.h"
|
||||||
|
+#include "version.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2)
|
||||||
|
@@ -755,6 +756,20 @@ load_config (char * file)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
factorize_hwtable(conf->hwtable, builtin_hwtable_size, file);
|
||||||
|
+ } else {
|
||||||
|
+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
|
||||||
|
+ if (conf->blist_devnode == NULL) {
|
||||||
|
+ conf->blist_devnode = vector_alloc();
|
||||||
|
+ if (!conf->blist_devnode) {
|
||||||
|
+ condlog(0, "cannot allocate blacklist\n");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (store_ble(conf->blist_devnode, strdup(".*"),
|
||||||
|
+ ORIGIN_NO_CONFIG)) {
|
||||||
|
+ condlog(0, "cannot store default no-config blacklist\n");
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
conf->processed_main_config = 1;
|
||||||
|
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||||
|
index 589146de..2adbd077 100644
|
||||||
|
--- a/libmultipath/config.h
|
||||||
|
+++ b/libmultipath/config.h
|
||||||
|
@@ -9,6 +9,7 @@
|
||||||
|
|
||||||
|
#define ORIGIN_DEFAULT 0
|
||||||
|
#define ORIGIN_CONFIG 1
|
||||||
|
+#define ORIGIN_NO_CONFIG 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In kernel, fast_io_fail == 0 means immediate failure on rport delete.
|
||||||
|
diff --git a/multipath/multipath.rules b/multipath/multipath.rules
|
||||||
|
index 9df11a95..0486bf70 100644
|
||||||
|
--- a/multipath/multipath.rules
|
||||||
|
+++ b/multipath/multipath.rules
|
||||||
|
@@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath"
|
||||||
|
ENV{nompath}=="?*", GOTO="end_mpath"
|
||||||
|
IMPORT{cmdline}="multipath"
|
||||||
|
ENV{multipath}=="off", GOTO="end_mpath"
|
||||||
|
+TEST!="/etc/multipath.conf", GOTO="end_mpath"
|
||||||
|
|
||||||
|
ENV{DEVTYPE}!="partition", GOTO="test_dev"
|
||||||
|
IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH"
|
||||||
|
diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8
|
||||||
|
index 048a838d..8bd47a80 100644
|
||||||
|
--- a/multipathd/multipathd.8
|
||||||
|
+++ b/multipathd/multipathd.8
|
||||||
|
@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy.
|
||||||
|
This daemon executes the external \fBmultipath\fR tool when events occur.
|
||||||
|
In turn, the multipath tool signals the multipathd daemon when it is done with
|
||||||
|
devmap reconfiguration, so that it can refresh its failed path list.
|
||||||
|
+
|
||||||
|
+In this Linux distribution, multipathd does not run unless a /etc/multipath.conf file exists.
|
||||||
|
.
|
||||||
|
.
|
||||||
|
.\" ----------------------------------------------------------------------------
|
||||||
|
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||||
|
index ba24983e..17434cef 100644
|
||||||
|
--- a/multipathd/multipathd.service
|
||||||
|
+++ b/multipathd/multipathd.service
|
||||||
|
@@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service
|
||||||
|
Before=iscsi.service iscsid.service lvm2-activation-early.service
|
||||||
|
Before=local-fs-pre.target blk-availability.service
|
||||||
|
After=multipathd.socket systemd-udev-trigger.service systemd-udev-settle.service
|
||||||
|
+ConditionPathExists=/etc/multipath.conf
|
||||||
|
DefaultDependencies=no
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
ConditionKernelCommandLine=!nompath
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
53
SOURCES/0013-RH-use-rpm-optflags-if-present.patch
Normal file
53
SOURCES/0013-RH-use-rpm-optflags-if-present.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Wed, 19 Apr 2017 06:10:01 -0500
|
||||||
|
Subject: [PATCH] RH: use rpm optflags if present
|
||||||
|
|
||||||
|
Use the passed in optflags when compiling as an RPM, and keep the
|
||||||
|
default flags as close as possible to the current fedora flags, while
|
||||||
|
still being generic.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
Makefile.inc | 24 ++++++++++++++++--------
|
||||||
|
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile.inc b/Makefile.inc
|
||||||
|
index 2e8946ca..1b2f47a8 100644
|
||||||
|
--- a/Makefile.inc
|
||||||
|
+++ b/Makefile.inc
|
||||||
|
@@ -88,15 +88,23 @@ TEST_CC_OPTION = $(shell \
|
||||||
|
echo "$(2)"; \
|
||||||
|
fi)
|
||||||
|
|
||||||
|
-STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||||
|
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
|
||||||
|
-
|
||||||
|
-OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \
|
||||||
|
- -Werror=implicit-function-declaration -Werror=format-security \
|
||||||
|
- -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \
|
||||||
|
- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \
|
||||||
|
- -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \
|
||||||
|
- --param=ssp-buffer-size=4
|
||||||
|
+ifndef RPM_OPT_FLAGS
|
||||||
|
+ STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
|
||||||
|
+ OPTFLAGS = -O2 -g -pipe -Wall -Werror=format-security \
|
||||||
|
+ -Wp,-D_FORTIFY_SOURCE=2 -fexceptions \
|
||||||
|
+ $(STACKPROT) --param=ssp-buffer-size=4 \
|
||||||
|
+ -grecord-gcc-switches
|
||||||
|
+ ifeq ($(shell test -f /usr/lib/rpm/redhat/redhat-hardened-cc1 && echo 1),1)
|
||||||
|
+ OPTFLAGS += -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
|
||||||
|
+ endif
|
||||||
|
+else
|
||||||
|
+ OPTFLAGS = $(RPM_OPT_FLAGS)
|
||||||
|
+endif
|
||||||
|
+OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \
|
||||||
|
+ -Werror=implicit-function-declaration -Wno-sign-compare \
|
||||||
|
+ -Wno-unused-parameter $(ERROR_DISCARDED_QUALIFIERS) \
|
||||||
|
+ -Werror=cast-qual
|
||||||
|
|
||||||
|
CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \
|
||||||
|
-MMD -MP $(CFLAGS)
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
774
SOURCES/0014-RH-add-mpathconf.patch
Normal file
774
SOURCES/0014-RH-add-mpathconf.patch
Normal file
@ -0,0 +1,774 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 16 Oct 2014 15:49:01 -0500
|
||||||
|
Subject: [PATCH] RH: add mpathconf
|
||||||
|
|
||||||
|
mpathconf is a program (largely based on lvmcomf) to help users
|
||||||
|
configure /etc/multipath.conf and enable or disable multipathing. It
|
||||||
|
has a couple of built-in options that can be set directly from the
|
||||||
|
command line. But, mostly it is used to get a multipath.conf file
|
||||||
|
with the OS defaults, and to enable and disable multipathing via
|
||||||
|
a single command.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/config.c | 2 +
|
||||||
|
multipath/Makefile | 5 +
|
||||||
|
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 4032c4c4..2c32acf7 100644
|
||||||
|
--- a/libmultipath/config.c
|
||||||
|
+++ b/libmultipath/config.c
|
||||||
|
@@ -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.");
|
||||||
|
+ condlog(0, "You can run \"/sbin/mpathconf --enable\" to create");
|
||||||
|
+ condlog(0, "/etc/multipath.conf. See man mpathconf(8) for more details");
|
||||||
|
if (conf->blist_devnode == NULL) {
|
||||||
|
conf->blist_devnode = vector_alloc();
|
||||||
|
if (!conf->blist_devnode) {
|
||||||
|
diff --git a/multipath/Makefile b/multipath/Makefile
|
||||||
|
index b9bbb3cf..e720c7f6 100644
|
||||||
|
--- a/multipath/Makefile
|
||||||
|
+++ b/multipath/Makefile
|
||||||
|
@@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so
|
||||||
|
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS) $(LIBDEPS)
|
||||||
|
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
|
||||||
|
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
|
||||||
|
+ $(GZIP) mpathconf.8 > mpathconf.8.gz
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
|
||||||
|
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
|
||||||
|
+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(udevrulesdir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 11-dm-mpath.rules $(DESTDIR)$(udevrulesdir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 $(EXEC).rules $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||||
|
@@ -29,13 +31,16 @@ install:
|
||||||
|
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(man8dir)
|
||||||
|
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
|
||||||
|
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
|
||||||
|
+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(man8dir)
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
$(RM) $(DESTDIR)$(bindir)/$(EXEC)
|
||||||
|
$(RM) $(DESTDIR)$(udevrulesdir)/11-dm-mpath.rules
|
||||||
|
$(RM) $(DESTDIR)$(libudevdir)/rules.d/62-multipath.rules
|
||||||
|
+ $(RM) $(DESTDIR)$(bindir)/mpathconf
|
||||||
|
$(RM) $(DESTDIR)$(man8dir)/$(EXEC).8.gz
|
||||||
|
$(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
|
||||||
|
+ $(RM) $(DESTDIR)$(man8dir)/mpathconf.8.gz
|
||||||
|
|
||||||
|
clean: dep_clean
|
||||||
|
$(RM) core *.o $(EXEC) *.gz
|
||||||
|
diff --git a/multipath/mpathconf b/multipath/mpathconf
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..f34003c9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/multipath/mpathconf
|
||||||
|
@@ -0,0 +1,555 @@
|
||||||
|
+#!/bin/bash
|
||||||
|
+#
|
||||||
|
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# This file is part of the device-mapper-multipath package.
|
||||||
|
+#
|
||||||
|
+# This copyrighted material is made available to anyone wishing to use,
|
||||||
|
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||||
|
+# of the GNU General Public License v.2.
|
||||||
|
+#
|
||||||
|
+# You should have received a copy of the GNU General Public License
|
||||||
|
+# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
+
|
||||||
|
+#
|
||||||
|
+# Simple editting of /etc/multipath.conf
|
||||||
|
+# This program was largely ripped off from lvmconf
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST
|
||||||
|
+
|
||||||
|
+DEFAULT_CONFIG="# device-mapper-multipath configuration file
|
||||||
|
+
|
||||||
|
+# For a complete list of the default configuration values, run either:
|
||||||
|
+# # multipath -t
|
||||||
|
+# or
|
||||||
|
+# # multipathd show config
|
||||||
|
+
|
||||||
|
+# For a list of configuration options with descriptions, see the
|
||||||
|
+# multipath.conf man page.
|
||||||
|
+
|
||||||
|
+defaults {
|
||||||
|
+ user_friendly_names yes
|
||||||
|
+ find_multipaths yes
|
||||||
|
+ enable_foreign \"^$\"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+blacklist_exceptions {
|
||||||
|
+ property \"(SCSI_IDENT_|ID_WWN)\"
|
||||||
|
+}"
|
||||||
|
+
|
||||||
|
+CONFIGFILE="/etc/multipath.conf"
|
||||||
|
+OUTPUTFILE="/etc/multipath.conf"
|
||||||
|
+MULTIPATHDIR="/etc/multipath"
|
||||||
|
+TMPFILE="/etc/multipath/.multipath.conf.tmp"
|
||||||
|
+WWIDS=0
|
||||||
|
+
|
||||||
|
+function usage
|
||||||
|
+{
|
||||||
|
+ echo "usage: $0 <command>"
|
||||||
|
+ echo ""
|
||||||
|
+ echo "Commands:"
|
||||||
|
+ echo "Enable: --enable "
|
||||||
|
+ echo "Disable: --disable"
|
||||||
|
+ echo "Only allow certain wwids (instead of enable): --allow <WWID>"
|
||||||
|
+ echo "Set user_friendly_names (Default y): --user_friendly_names <y|n>"
|
||||||
|
+ echo "Set find_multipaths (Default y): --find_multipaths <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>"
|
||||||
|
+ echo ""
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function add_wwid
|
||||||
|
+{
|
||||||
|
+ INDEX=0
|
||||||
|
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||||
|
+ if [ "$1" = "${WWID_LIST[$INDEX]}" ] ; then
|
||||||
|
+ return
|
||||||
|
+ fi
|
||||||
|
+ ((INDEX++))
|
||||||
|
+ done
|
||||||
|
+ WWID_LIST[$WWIDS]="$1"
|
||||||
|
+ ((WWIDS++))
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function get_dm_deps
|
||||||
|
+{
|
||||||
|
+ shift 3
|
||||||
|
+ while [ -n "$1" -a -n "$2" ]; do
|
||||||
|
+ MAJOR=$(echo $1 | tr -d '(,')
|
||||||
|
+ MINOR=$(echo $2 | tr -d ')')
|
||||||
|
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||||
|
+ if [ -n "$UUID" ] ; then
|
||||||
|
+ set_dm_wwid $UUID
|
||||||
|
+ fi
|
||||||
|
+ shift 2
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function set_dm_wwid
|
||||||
|
+{
|
||||||
|
+ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then
|
||||||
|
+ add_wwid "${1##part*-mpath-}"
|
||||||
|
+ elif [[ "$1" =~ ^mpath- ]] ; then
|
||||||
|
+ add_wwid "${1##mpath-}"
|
||||||
|
+ else
|
||||||
|
+ get_dm_deps `dmsetup deps -u $1`
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function set_wwid
|
||||||
|
+{
|
||||||
|
+ UUID=""
|
||||||
|
+ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then
|
||||||
|
+ MAJOR=${1%%:*}
|
||||||
|
+ MINOR=${1##*:}
|
||||||
|
+ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null`
|
||||||
|
+ else
|
||||||
|
+ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null`
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$UUID" ] ; then
|
||||||
|
+ set_dm_wwid $UUID
|
||||||
|
+ else
|
||||||
|
+ add_wwid "$1"
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function parse_args
|
||||||
|
+{
|
||||||
|
+ while [ -n "$1" ]; do
|
||||||
|
+ case $1 in
|
||||||
|
+ --enable)
|
||||||
|
+ ENABLE=1
|
||||||
|
+ shift
|
||||||
|
+ ;;
|
||||||
|
+ --disable)
|
||||||
|
+ ENABLE=0
|
||||||
|
+ shift
|
||||||
|
+ ;;
|
||||||
|
+ --allow)
|
||||||
|
+ ENABLE=2
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ set_wwid $2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --user_friendly_names)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ FRIENDLY=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --find_multipaths)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ FIND=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --property_blacklist)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ PROPERTY=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --enable_foreign)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ FOREIGN=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --with_module)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ MODULE=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --with_multipathd)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ MULTIPATHD=$2
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ --outfile)
|
||||||
|
+ if [ -n "$2" ]; then
|
||||||
|
+ OUTPUTFILE=$2
|
||||||
|
+ HAVE_OUTFILE=1
|
||||||
|
+ shift 2
|
||||||
|
+ else
|
||||||
|
+ usage
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ usage
|
||||||
|
+ exit
|
||||||
|
+ esac
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function validate_args
|
||||||
|
+{
|
||||||
|
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then
|
||||||
|
+ echo "ignoring extra parameters on disable"
|
||||||
|
+ FRIENDLY=""
|
||||||
|
+ FIND=""
|
||||||
|
+ PROPERTY=""
|
||||||
|
+ MODULE=""
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
|
||||||
|
+ echo "--user_friendly_names must be either 'y' or 'n'"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
|
||||||
|
+ echo "--find_multipaths must be either 'y' or 'n'"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then
|
||||||
|
+ 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
|
||||||
|
+ echo "--with_module must be either 'y' or 'n'"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
|
||||||
|
+ echo "--with_multipathd must be either 'y' or 'n'"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then
|
||||||
|
+ echo "Because --allow makes changes that cannot be automatically reversed,"
|
||||||
|
+ echo "you must set --outfile when you set --allow"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function add_blacklist_exceptions
|
||||||
|
+{
|
||||||
|
+ INDEX=0
|
||||||
|
+ while [ "$INDEX" -lt "$WWIDS" ] ; do
|
||||||
|
+ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\
|
||||||
|
+ wwid '"\"${WWID_LIST[$INDEX]}\""'
|
||||||
|
+' $TMPFILE
|
||||||
|
+ ((INDEX++))
|
||||||
|
+ done
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+umask 0077
|
||||||
|
+
|
||||||
|
+parse_args "$@"
|
||||||
|
+
|
||||||
|
+validate_args
|
||||||
|
+
|
||||||
|
+if [ ! -d "$MULTIPATHDIR" ]; then
|
||||||
|
+ echo "/etc/multipath/ does not exist. failing"
|
||||||
|
+ exit 1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+rm $TMPFILE 2> /dev/null
|
||||||
|
+echo "$DEFAULT_CONFIG" > $TMPFILE
|
||||||
|
+if [ -f "$CONFIGFILE" ]; then
|
||||||
|
+ cp $CONFIGFILE $TMPFILE
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
|
||||||
|
+ HAVE_BLACKLIST=1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then
|
||||||
|
+ HAVE_EXCEPTIONS=1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
|
||||||
|
+ HAVE_DEFAULTS=1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
|
||||||
|
+ if lsmod | grep -q "dm_multipath" ; then
|
||||||
|
+ HAVE_MODULE=1
|
||||||
|
+ else
|
||||||
|
+ HAVE_MODULE=0
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$MULTIPATHD" = "y" ]; then
|
||||||
|
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||||
|
+ HAVE_MULTIPATHD=1
|
||||||
|
+ else
|
||||||
|
+ HAVE_MULTIPATHD=0
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||||
|
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||||
|
+ HAVE_DISABLE=1
|
||||||
|
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then
|
||||||
|
+ HAVE_DISABLE=0
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$HAVE_BLACKLIST" = "1" ]; then
|
||||||
|
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||||
|
+ HAVE_WWID_DISABLE=1
|
||||||
|
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then
|
||||||
|
+ HAVE_WWID_DISABLE=0
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$HAVE_DEFAULTS" = "1" ]; then
|
||||||
|
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
|
||||||
|
+ HAVE_FIND=1
|
||||||
|
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
|
||||||
|
+ HAVE_FIND=0
|
||||||
|
+ fi
|
||||||
|
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
|
||||||
|
+ HAVE_FRIENDLY=1
|
||||||
|
+ 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
|
||||||
|
+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
|
||||||
|
+ echo "multipath is enabled"
|
||||||
|
+ else
|
||||||
|
+ echo "multipath is disabled"
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
|
||||||
|
+ echo "find_multipaths is disabled"
|
||||||
|
+ else
|
||||||
|
+ echo "find_multipaths is enabled"
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
|
||||||
|
+ echo "user_friendly_names is disabled"
|
||||||
|
+ else
|
||||||
|
+ echo "user_friendly_names is enabled"
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then
|
||||||
|
+ echo "default property blacklist is disabled"
|
||||||
|
+ else
|
||||||
|
+ echo "default property blacklist is enabled"
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then
|
||||||
|
+ echo "enable_foreign is not set (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"
|
||||||
|
+ else
|
||||||
|
+ echo "dm_multipath module is not loaded"
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_MULTIPATHD" ]; then
|
||||||
|
+ if /bin/systemctl status multipathd.service > /dev/null 2>&1 ; then
|
||||||
|
+ HAVE_MULTIPATHD=1
|
||||||
|
+ else
|
||||||
|
+ HAVE_MULTIPATHD=0
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||||
|
+ echo "multipathd is running"
|
||||||
|
+ else
|
||||||
|
+ echo "multipathd is not running"
|
||||||
|
+ fi
|
||||||
|
+ exit 0
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ -z "$HAVE_BLACKLIST" ]; then
|
||||||
|
+ cat >> $TMPFILE <<- _EOF_
|
||||||
|
+
|
||||||
|
+blacklist {
|
||||||
|
+}
|
||||||
|
+_EOF_
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ -z "$HAVE_DEFAULTS" ]; then
|
||||||
|
+ cat >> $TMPFILE <<- _EOF_
|
||||||
|
+
|
||||||
|
+defaults {
|
||||||
|
+}
|
||||||
|
+_EOF_
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$ENABLE" = 2 ]; then
|
||||||
|
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||||
|
+ fi
|
||||||
|
+ if [ -z "$HAVE_WWID_DISABLE" ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||||
|
+ wwid ".*"
|
||||||
|
+' $TMPFILE
|
||||||
|
+ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE
|
||||||
|
+ fi
|
||||||
|
+ if [ "$HAVE_EXCEPTIONS" = 1 ]; then
|
||||||
|
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ {/^[[:space:]]*wwid/ d}' $TMPFILE
|
||||||
|
+ else
|
||||||
|
+ cat >> $TMPFILE <<- _EOF_
|
||||||
|
+
|
||||||
|
+blacklist_exceptions {
|
||||||
|
+}
|
||||||
|
+_EOF_
|
||||||
|
+ fi
|
||||||
|
+ add_blacklist_exceptions
|
||||||
|
+elif [ "$ENABLE" = 1 ]; then
|
||||||
|
+ if [ "$HAVE_DISABLE" = 1 ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
|
||||||
|
+ fi
|
||||||
|
+elif [ "$ENABLE" = 0 ]; then
|
||||||
|
+ if [ -z "$HAVE_DISABLE" ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/ a\
|
||||||
|
+ devnode ".*"
|
||||||
|
+' $TMPFILE
|
||||||
|
+ elif [ "$HAVE_DISABLE" = 0 ]; then
|
||||||
|
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$FIND" = "n" ]; then
|
||||||
|
+ if [ "$HAVE_FIND" = 1 ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ fi
|
||||||
|
+elif [ "$FIND" = "y" ]; then
|
||||||
|
+ if [ -z "$HAVE_FIND" ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||||
|
+ find_multipaths yes
|
||||||
|
+' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ elif [ "$HAVE_FIND" = 0 ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$FRIENDLY" = "n" ]; then
|
||||||
|
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ fi
|
||||||
|
+elif [ "$FRIENDLY" = "y" ]; then
|
||||||
|
+ if [ -z "$HAVE_FRIENDLY" ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/ a\
|
||||||
|
+ user_friendly_names yes
|
||||||
|
+' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ elif [ "$HAVE_FRIENDLY" = 0 ]; then
|
||||||
|
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
|
||||||
|
+ CHANGED_CONFIG=1
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [ "$PROPERTY" = "n" ]; then
|
||||||
|
+ if [ "$HAVE_PROPERTY" = 1 ]; then
|
||||||
|
+ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(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
|
||||||
|
+ echo "failed to backup old config file, $OUTPUTFILE not updated"
|
||||||
|
+ exit 1
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+cp $TMPFILE $OUTPUTFILE
|
||||||
|
+if [ $? != 0 ]; then
|
||||||
|
+ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK"
|
||||||
|
+ exit 1
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+rm -f $TMPFILE
|
||||||
|
+
|
||||||
|
+if [ "$ENABLE" = 1 ]; then
|
||||||
|
+ if [ "$HAVE_MODULE" = 0 ]; then
|
||||||
|
+ modprobe dm_multipath
|
||||||
|
+ fi
|
||||||
|
+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
|
||||||
|
+ systemctl start multipathd.service
|
||||||
|
+ fi
|
||||||
|
+elif [ "$ENABLE" = 0 ]; then
|
||||||
|
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
|
||||||
|
+ systemctl stop multipathd.service
|
||||||
|
+ fi
|
||||||
|
+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
|
||||||
|
+ systemctl reload multipathd.service
|
||||||
|
+fi
|
||||||
|
diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..7937ea05
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/multipath/mpathconf.8
|
||||||
|
@@ -0,0 +1,135 @@
|
||||||
|
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
|
||||||
|
+.SH NAME
|
||||||
|
+mpathconf - A tool for configuring device-mapper-multipath
|
||||||
|
+.SH SYNOPSIS
|
||||||
|
+.B mpathconf
|
||||||
|
+.RB [\| commands \|]
|
||||||
|
+.RB [\| options \|]
|
||||||
|
+.SH DESCRIPTION
|
||||||
|
+.B mpathconf
|
||||||
|
+is a utility that creates or modifies
|
||||||
|
+.B /etc/multipath.conf.
|
||||||
|
+It can enable or disable multipathing and configure some common options.
|
||||||
|
+.B mpathconf
|
||||||
|
+can also load the
|
||||||
|
+.B dm_multipath
|
||||||
|
+module, start and stop the
|
||||||
|
+.B multipathd
|
||||||
|
+daemon, and configure the
|
||||||
|
+.B multipathd
|
||||||
|
+service to start automatically or not. If
|
||||||
|
+.B mpathconf
|
||||||
|
+is called with no commands, it will display the current configuration, but
|
||||||
|
+will not create of modify
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+
|
||||||
|
+The default options for mpathconf are
|
||||||
|
+.B --with_module
|
||||||
|
+The
|
||||||
|
+.B --with_multipathd
|
||||||
|
+option is not set by default. Enabling multipathing will load the
|
||||||
|
+.B dm_multipath
|
||||||
|
+module but it will not immediately start it. This is so
|
||||||
|
+that users can manually edit their config file if necessary, before starting
|
||||||
|
+.B multipathd.
|
||||||
|
+
|
||||||
|
+If
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
|
||||||
|
+create a default file with
|
||||||
|
+.B user_friendly_names
|
||||||
|
+and
|
||||||
|
+.B find_multipaths
|
||||||
|
+set. To disable these, use the
|
||||||
|
+.B --user_friendly_names n
|
||||||
|
+and
|
||||||
|
+.B --find_multipaths n
|
||||||
|
+options
|
||||||
|
+.SH COMMANDS
|
||||||
|
+.TP
|
||||||
|
+.B --enable
|
||||||
|
+Removes any line that blacklists all device nodes from the
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+blacklist section. Also, creates
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+if it doesn't exist.
|
||||||
|
+.TP
|
||||||
|
+.B --disable
|
||||||
|
+Adds a line that blacklists all device nodes to the
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+blacklist section. If no blacklist section exists, it will create one.
|
||||||
|
+.TP
|
||||||
|
+.B --allow \fB<device>\fP
|
||||||
|
+Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all
|
||||||
|
+wwids and the blacklist_exceptions to whitelist \fB<device>\fP. \fB<device>\fP
|
||||||
|
+can be in the form of MAJOR:MINOR, a wwid, or the name of a device-mapper
|
||||||
|
+device, either a multipath device, or any device on stacked on top of one or
|
||||||
|
+more multipath devices. This command can be used multiple times to allow
|
||||||
|
+multiple devices. \fBNOTE:\fP This action will create a configuration file that
|
||||||
|
+mpathconf will not be able to revert back to its previous state. Because
|
||||||
|
+of this, \fB--outfile\fP is required when using \fB--allow\fP.
|
||||||
|
+.TP
|
||||||
|
+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP }
|
||||||
|
+If set to \fBy\fP, this adds the line
|
||||||
|
+.B user_friendly_names yes
|
||||||
|
+to the
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+defaults section. If set to \fBn\fP, this removes the line, if present. This
|
||||||
|
+command can be used along with any other command.
|
||||||
|
+.TP
|
||||||
|
+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
|
||||||
|
+If set to \fBy\fP, this adds the line
|
||||||
|
+.B find_multipaths yes
|
||||||
|
+to the
|
||||||
|
+.B /etc/multipath.conf
|
||||||
|
+defaults section. If set to \fBn\fP, this removes the line, if present. This
|
||||||
|
+command can be used along with any other command.
|
||||||
|
+.TP
|
||||||
|
+.B --property_blacklist \fP { \fBy\fP | \fBn\fP }
|
||||||
|
+If set to \fBy\fP, this adds the line
|
||||||
|
+.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
|
||||||
|
+\fB/etc/multipath.conf\fP.
|
||||||
|
+.SH OPTIONS
|
||||||
|
+.TP
|
||||||
|
+.B --with_module\fP { \fBy\fP | \fBn\fP }
|
||||||
|
+If set to \fBy\fP, this runs
|
||||||
|
+.B modprobe dm_multipath
|
||||||
|
+to install the multipath modules. This option only works with the
|
||||||
|
+.B --enable
|
||||||
|
+command. This option is set to \fBy\fP by default.
|
||||||
|
+.TP
|
||||||
|
+.B --with_multipathd { \fBy\fP | \fBn\fP }
|
||||||
|
+If set to \fBy\fP, this runs
|
||||||
|
+.B service multipathd start
|
||||||
|
+to start the multipathd daemon on \fB--enable\fP,
|
||||||
|
+.B service multipathd stop
|
||||||
|
+to stop the multipathd daemon on \fB--disable\fP, and
|
||||||
|
+.B service multipathd reload
|
||||||
|
+to reconfigure multipathd on \fB--user_frindly_names\fP and
|
||||||
|
+\fB--find_multipaths\fP.
|
||||||
|
+This option is set to \fBn\fP by default.
|
||||||
|
+.SH FILES
|
||||||
|
+.BR /etc/multipath.conf
|
||||||
|
+.SH "SEE ALSO"
|
||||||
|
+.BR multipath.conf (5),
|
||||||
|
+.BR modprobe (8),
|
||||||
|
+.BR multipath (8),
|
||||||
|
+.BR multipathd (8),
|
||||||
|
+.BR service (8),
|
||||||
|
+.SH AUTHOR
|
||||||
|
+Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
@ -0,0 +1,169 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 17 Oct 2014 11:20:34 -0500
|
||||||
|
Subject: [PATCH] RH: add wwids from kernel cmdline mpath.wwids with -A
|
||||||
|
|
||||||
|
This patch adds another option to multipath, "-A", which reads
|
||||||
|
/proc/cmdline for mpath.wwid=<WWID> options, and adds any wwids it finds
|
||||||
|
to /etc/multipath/wwids. While this isn't usually important during
|
||||||
|
normal operation, since these wwids should already be added, it can be
|
||||||
|
helpful during installation, to make sure that multipath can claim
|
||||||
|
devices as its own, before LVM or something else makes use of them. The
|
||||||
|
patch also execs "/sbin/multipath -A" before running multipathd in
|
||||||
|
multipathd.service
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/wwids.c | 44 +++++++++++++++++++++++++++++++++++
|
||||||
|
libmultipath/wwids.h | 1 +
|
||||||
|
multipath/main.c | 10 ++++++--
|
||||||
|
multipath/multipath.8 | 7 +++++-
|
||||||
|
multipathd/multipathd.service | 1 +
|
||||||
|
5 files changed, 60 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c
|
||||||
|
index ef748125..349da8b7 100644
|
||||||
|
--- a/libmultipath/wwids.c
|
||||||
|
+++ b/libmultipath/wwids.c
|
||||||
|
@@ -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)
|
||||||
|
+
|
||||||
|
+int remember_cmdline_wwid(void)
|
||||||
|
+{
|
||||||
|
+ FILE *f = NULL;
|
||||||
|
+ char buf[LINE_MAX], *next, *ptr;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ f = fopen("/proc/cmdline", "re");
|
||||||
|
+ if (!f) {
|
||||||
|
+ condlog(0, "can't open /proc/cmdline : %s", strerror(errno));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!fgets(buf, sizeof(buf), f)) {
|
||||||
|
+ if (ferror(f))
|
||||||
|
+ condlog(0, "read of /proc/cmdline failed : %s",
|
||||||
|
+ strerror(errno));
|
||||||
|
+ else
|
||||||
|
+ condlog(0, "couldn't read /proc/cmdline");
|
||||||
|
+ fclose(f);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ fclose(f);
|
||||||
|
+ next = buf;
|
||||||
|
+ while((ptr = strstr(next, "mpath.wwid="))) {
|
||||||
|
+ ptr += 11;
|
||||||
|
+ next = strpbrk(ptr, " \t\n");
|
||||||
|
+ if (next) {
|
||||||
|
+ *next = '\0';
|
||||||
|
+ next++;
|
||||||
|
+ }
|
||||||
|
+ if (strlen(ptr)) {
|
||||||
|
+ if (remember_wwid(ptr) != 0)
|
||||||
|
+ ret = -1;
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ condlog(0, "empty mpath.wwid kernel command line option");
|
||||||
|
+ ret = -1;
|
||||||
|
+ }
|
||||||
|
+ if (!next)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h
|
||||||
|
index 0c6ee54d..e32a0b0e 100644
|
||||||
|
--- a/libmultipath/wwids.h
|
||||||
|
+++ b/libmultipath/wwids.h
|
||||||
|
@@ -17,6 +17,7 @@ int remember_wwid(char *wwid);
|
||||||
|
int check_wwids_file(char *wwid, int write_wwid);
|
||||||
|
int remove_wwid(char *wwid);
|
||||||
|
int replace_wwids(vector mp);
|
||||||
|
+int remember_cmdline_wwid(void);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WWID_IS_NOT_FAILED = 0,
|
||||||
|
diff --git a/multipath/main.c b/multipath/main.c
|
||||||
|
index 4f4d8e89..22aff7be 100644
|
||||||
|
--- a/multipath/main.c
|
||||||
|
+++ b/multipath/main.c
|
||||||
|
@@ -138,7 +138,7 @@ usage (char * progname)
|
||||||
|
fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname);
|
||||||
|
fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname);
|
||||||
|
fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname);
|
||||||
|
- fprintf (stderr, " %s [-v level] -W\n", progname);
|
||||||
|
+ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname);
|
||||||
|
fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname);
|
||||||
|
fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname);
|
||||||
|
fprintf (stderr, " %s [-h|-t|-T]\n", progname);
|
||||||
|
@@ -151,6 +151,8 @@ usage (char * progname)
|
||||||
|
" -f flush a multipath device map\n"
|
||||||
|
" -F flush all multipath device maps\n"
|
||||||
|
" -a add a device wwid to the wwids file\n"
|
||||||
|
+ " -A add devices from kernel command line mpath.wwids\n"
|
||||||
|
+ " parameters to wwids file\n"
|
||||||
|
" -c check if a device should be a path in a multipath device\n"
|
||||||
|
" -C check if a multipath device has usable paths\n"
|
||||||
|
" -q allow queue_if_no_path when multipathd is not running\n"
|
||||||
|
@@ -905,7 +907,7 @@ main (int argc, char *argv[])
|
||||||
|
exit(RTVL_FAIL);
|
||||||
|
multipath_conf = conf;
|
||||||
|
conf->retrigger_tries = 0;
|
||||||
|
- while ((arg = getopt(argc, argv, ":adcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||||
|
+ while ((arg = getopt(argc, argv, ":aAdcChl::FfM:v:p:b:BrR:itTquUwW")) != EOF ) {
|
||||||
|
switch(arg) {
|
||||||
|
case 1: printf("optarg : %s\n",optarg);
|
||||||
|
break;
|
||||||
|
@@ -975,6 +977,10 @@ main (int argc, char *argv[])
|
||||||
|
case 'T':
|
||||||
|
cmd = CMD_DUMP_CONFIG;
|
||||||
|
break;
|
||||||
|
+ case 'A':
|
||||||
|
+ if (remember_cmdline_wwid() != 0)
|
||||||
|
+ exit(RTVL_FAIL);
|
||||||
|
+ exit(RTVL_OK);
|
||||||
|
case 'h':
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(RTVL_OK);
|
||||||
|
diff --git a/multipath/multipath.8 b/multipath/multipath.8
|
||||||
|
index 9cdd05a3..8befc45a 100644
|
||||||
|
--- a/multipath/multipath.8
|
||||||
|
+++ b/multipath/multipath.8
|
||||||
|
@@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig.
|
||||||
|
.B multipath
|
||||||
|
.RB [\| \-v\ \c
|
||||||
|
.IR level \|]
|
||||||
|
-.B -W
|
||||||
|
+.RB [\| \-A | \-W \|]
|
||||||
|
.
|
||||||
|
.LP
|
||||||
|
.B multipath
|
||||||
|
@@ -145,6 +145,11 @@ device mapper, path checkers ...).
|
||||||
|
Add the WWID for the specified device to the WWIDs file.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
+.B \-A
|
||||||
|
+Add the WWIDs from any kernel command line \fImpath.wwid\fR parameters to the
|
||||||
|
+WWIDs file.
|
||||||
|
+.
|
||||||
|
+.TP
|
||||||
|
.B \-w
|
||||||
|
Remove the WWID for the specified device from the WWIDs file.
|
||||||
|
.
|
||||||
|
diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service
|
||||||
|
index 17434cef..0fbcc46b 100644
|
||||||
|
--- a/multipathd/multipathd.service
|
||||||
|
+++ b/multipathd/multipathd.service
|
||||||
|
@@ -15,6 +15,7 @@ Type=notify
|
||||||
|
NotifyAccess=main
|
||||||
|
LimitCORE=infinity
|
||||||
|
ExecStartPre=-/sbin/modprobe -a scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm-multipath
|
||||||
|
+ExecStartPre=-/sbin/multipath -A
|
||||||
|
ExecStart=/sbin/multipathd -d -s
|
||||||
|
ExecReload=/sbin/multipathd reconfigure
|
||||||
|
TasksMax=infinity
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
121
SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch
Normal file
121
SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Mon, 6 Nov 2017 21:39:28 -0600
|
||||||
|
Subject: [PATCH] RH: warn on invalid regex instead of failing
|
||||||
|
|
||||||
|
multipath.conf used to allow "*" as a match everything regular expression,
|
||||||
|
instead of requiring ".*". Instead of erroring when the old style
|
||||||
|
regular expressions are used, it should print a warning and convert
|
||||||
|
them.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/dict.c | 27 +++++++++++++++++++++------
|
||||||
|
libmultipath/parser.c | 13 +++++++++++++
|
||||||
|
libmultipath/parser.h | 1 +
|
||||||
|
3 files changed, 35 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||||
|
index d6d8b79b..07d2ba8f 100644
|
||||||
|
--- a/libmultipath/dict.c
|
||||||
|
+++ b/libmultipath/dict.c
|
||||||
|
@@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+set_regex(vector strvec, void *ptr)
|
||||||
|
+{
|
||||||
|
+ char **str_ptr = (char **)ptr;
|
||||||
|
+
|
||||||
|
+ if (*str_ptr)
|
||||||
|
+ FREE(*str_ptr);
|
||||||
|
+ *str_ptr = set_regex_value(strvec);
|
||||||
|
+
|
||||||
|
+ if (!*str_ptr)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
set_yes_no(vector strvec, void *ptr)
|
||||||
|
{
|
||||||
|
@@ -1455,7 +1470,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \
|
||||||
|
if (!conf->option) \
|
||||||
|
return 1; \
|
||||||
|
\
|
||||||
|
- buff = set_value(strvec); \
|
||||||
|
+ buff = set_regex_value(strvec); \
|
||||||
|
if (!buff) \
|
||||||
|
return 1; \
|
||||||
|
\
|
||||||
|
@@ -1471,7 +1486,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \
|
||||||
|
if (!conf->option) \
|
||||||
|
return 1; \
|
||||||
|
\
|
||||||
|
- buff = set_value(strvec); \
|
||||||
|
+ buff = set_regex_value(strvec); \
|
||||||
|
if (!buff) \
|
||||||
|
return 1; \
|
||||||
|
\
|
||||||
|
@@ -1574,16 +1589,16 @@ device_handler(struct config *conf, vector strvec)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-declare_hw_handler(vendor, set_str)
|
||||||
|
+declare_hw_handler(vendor, set_regex)
|
||||||
|
declare_hw_snprint(vendor, print_str)
|
||||||
|
|
||||||
|
-declare_hw_handler(product, set_str)
|
||||||
|
+declare_hw_handler(product, set_regex)
|
||||||
|
declare_hw_snprint(product, print_str)
|
||||||
|
|
||||||
|
-declare_hw_handler(revision, set_str)
|
||||||
|
+declare_hw_handler(revision, set_regex)
|
||||||
|
declare_hw_snprint(revision, print_str)
|
||||||
|
|
||||||
|
-declare_hw_handler(bl_product, set_str)
|
||||||
|
+declare_hw_handler(bl_product, set_regex)
|
||||||
|
declare_hw_snprint(bl_product, print_str)
|
||||||
|
|
||||||
|
declare_hw_handler(hwhandler, set_str)
|
||||||
|
diff --git a/libmultipath/parser.c b/libmultipath/parser.c
|
||||||
|
index e00c5fff..15495d26 100644
|
||||||
|
--- a/libmultipath/parser.c
|
||||||
|
+++ b/libmultipath/parser.c
|
||||||
|
@@ -382,6 +382,19 @@ oom:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void *
|
||||||
|
+set_regex_value(vector strvec)
|
||||||
|
+{
|
||||||
|
+ char *buff = set_value(strvec);
|
||||||
|
+
|
||||||
|
+ if (buff && strcmp("*", buff) == 0) {
|
||||||
|
+ condlog(0, "Invalid regular expression \"*\" in multipath.conf. Using \".*\"");
|
||||||
|
+ FREE(buff);
|
||||||
|
+ return strdup(".*");
|
||||||
|
+ }
|
||||||
|
+ return buff;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* non-recursive configuration stream handler */
|
||||||
|
static int kw_level = 0;
|
||||||
|
|
||||||
|
diff --git a/libmultipath/parser.h b/libmultipath/parser.h
|
||||||
|
index 62906e98..b7917052 100644
|
||||||
|
--- a/libmultipath/parser.h
|
||||||
|
+++ b/libmultipath/parser.h
|
||||||
|
@@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level);
|
||||||
|
extern void free_keywords(vector keywords);
|
||||||
|
extern vector alloc_strvec(char *string);
|
||||||
|
extern void *set_value(vector strvec);
|
||||||
|
+extern void *set_regex_value(vector strvec);
|
||||||
|
extern int process_file(struct config *conf, char *conf_file);
|
||||||
|
extern struct keyword * find_keyword(vector keywords, vector v, char * name);
|
||||||
|
int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw,
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 7 Jun 2018 17:43:52 -0500
|
||||||
|
Subject: [PATCH] RH: reset default find_mutipaths value to off
|
||||||
|
|
||||||
|
Upstream has changed to default find_multipaths to "strict". For now
|
||||||
|
Redhat will retain the previous default of "off".
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/defaults.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
|
||||||
|
index 4dfe007c..d910da51 100644
|
||||||
|
--- a/libmultipath/defaults.h
|
||||||
|
+++ b/libmultipath/defaults.h
|
||||||
|
@@ -20,7 +20,7 @@
|
||||||
|
#define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF
|
||||||
|
#define DEFAULT_VERBOSITY 2
|
||||||
|
#define DEFAULT_REASSIGN_MAPS 0
|
||||||
|
-#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_STRICT
|
||||||
|
+#define DEFAULT_FIND_MULTIPATHS FIND_MULTIPATHS_OFF
|
||||||
|
#define DEFAULT_FAST_IO_FAIL 5
|
||||||
|
#define DEFAULT_DEV_LOSS_TMO 600
|
||||||
|
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_ON
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
26
SOURCES/0018-RH-Fix-nvme-compilation-warning.patch
Normal file
26
SOURCES/0018-RH-Fix-nvme-compilation-warning.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Fri, 25 Jan 2019 14:54:56 -0600
|
||||||
|
Subject: [PATCH] RH: Fix nvme compilation warning
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/nvme/argconfig.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h
|
||||||
|
index adb192b6..bfd10ef8 100644
|
||||||
|
--- a/libmultipath/nvme/argconfig.h
|
||||||
|
+++ b/libmultipath/nvme/argconfig.h
|
||||||
|
@@ -76,7 +76,7 @@ struct argconfig_commandline_options {
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-typedef void argconfig_help_func();
|
||||||
|
+typedef void argconfig_help_func(void);
|
||||||
|
void argconfig_append_usage(const char *str);
|
||||||
|
void argconfig_print_help(const char *program_desc,
|
||||||
|
const struct argconfig_commandline_options *options);
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
Date: Thu, 11 Apr 2019 13:25:42 -0500
|
||||||
|
Subject: [PATCH] RH: attempt to get ANA info via sysfs first
|
||||||
|
|
||||||
|
When the ANA prioritizer is run, first see if the "ana_state" sysfs file
|
||||||
|
exists, and if it does, try to read the state from there. If that fails,
|
||||||
|
fallback to using an ioctl.
|
||||||
|
|
||||||
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
||||||
|
---
|
||||||
|
libmultipath/prioritizers/ana.c | 31 +++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 29 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c
|
||||||
|
index 2673d9d9..f34ade28 100644
|
||||||
|
--- a/libmultipath/prioritizers/ana.c
|
||||||
|
+++ b/libmultipath/prioritizers/ana.c
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
#include "prio.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "structs.h"
|
||||||
|
+#include "sysfs.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ANA_ERR_GETCTRL_FAILED = 1,
|
||||||
|
@@ -36,6 +37,7 @@ enum {
|
||||||
|
ANA_ERR_GETNS_FAILED,
|
||||||
|
ANA_ERR_NO_MEMORY,
|
||||||
|
ANA_ERR_NO_INFORMATION,
|
||||||
|
+ ANA_ERR_INVALID_STATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *ana_errmsg[] = {
|
||||||
|
@@ -49,6 +51,7 @@ static const char *ana_errmsg[] = {
|
||||||
|
[ANA_ERR_GETNS_FAILED] = "couldn't get namespace info",
|
||||||
|
[ANA_ERR_NO_MEMORY] = "out of memory",
|
||||||
|
[ANA_ERR_NO_INFORMATION] = "invalid fd",
|
||||||
|
+ [ANA_ERR_INVALID_STATE] = "invalid state",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *anas_string[] = {
|
||||||
|
@@ -106,6 +109,27 @@ static int get_ana_state(__u32 nsid, __u32 anagrpid, void *ana_log,
|
||||||
|
return -ANA_ERR_GETANAS_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int get_ana_info_sysfs(struct path *pp)
|
||||||
|
+{
|
||||||
|
+ char state[32];
|
||||||
|
+
|
||||||
|
+ if (!pp->udev || sysfs_attr_get_value(pp->udev, "ana_state", state,
|
||||||
|
+ sizeof(state)) <= 0)
|
||||||
|
+ return -ANA_ERR_NO_INFORMATION;
|
||||||
|
+
|
||||||
|
+ if (strcmp(state, "optimized") == 0)
|
||||||
|
+ return NVME_ANA_OPTIMIZED;
|
||||||
|
+ if (strcmp(state, "non-optimized") == 0)
|
||||||
|
+ return NVME_ANA_NONOPTIMIZED;
|
||||||
|
+ if (strcmp(state, "inaccessible") == 0)
|
||||||
|
+ return NVME_ANA_INACCESSIBLE;
|
||||||
|
+ if (strcmp(state, "persistent-loss") == 0)
|
||||||
|
+ return NVME_ANA_PERSISTENT_LOSS;
|
||||||
|
+ if (strcmp(state, "change") == 0)
|
||||||
|
+ return NVME_ANA_CHANGE;
|
||||||
|
+ return -ANA_ERR_INVALID_STATE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int get_ana_info(struct path * pp, unsigned int timeout)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
@@ -208,8 +232,11 @@ int getprio(struct path *pp, char *args, unsigned int timeout)
|
||||||
|
|
||||||
|
if (pp->fd < 0)
|
||||||
|
rc = -ANA_ERR_NO_INFORMATION;
|
||||||
|
- else
|
||||||
|
- rc = get_ana_info(pp, timeout);
|
||||||
|
+ else {
|
||||||
|
+ rc = get_ana_info_sysfs(pp);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ rc = get_ana_info(pp, timeout);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
switch (rc) {
|
||||||
|
case NVME_ANA_OPTIMIZED:
|
||||||
|
--
|
||||||
|
2.17.2
|
||||||
|
|
93
SOURCES/multipath.conf
Normal file
93
SOURCES/multipath.conf
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
# This is a basic configuration file with some examples, for device mapper
|
||||||
|
# multipath.
|
||||||
|
#
|
||||||
|
# For a complete list of the default configuration values, run either
|
||||||
|
# multipath -t
|
||||||
|
# or
|
||||||
|
# multipathd show config
|
||||||
|
#
|
||||||
|
# For a list of configuration options with descriptions, see the multipath.conf
|
||||||
|
# man page
|
||||||
|
|
||||||
|
## By default, devices with vendor = "IBM" and product = "S/390.*" are
|
||||||
|
## blacklisted. To enable mulitpathing on these devies, uncomment the
|
||||||
|
## following lines.
|
||||||
|
#blacklist_exceptions {
|
||||||
|
# device {
|
||||||
|
# vendor "IBM"
|
||||||
|
# product "S/390.*"
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
|
||||||
|
## Use user friendly names, instead of using WWIDs as names.
|
||||||
|
defaults {
|
||||||
|
user_friendly_names yes
|
||||||
|
find_multipaths yes
|
||||||
|
}
|
||||||
|
##
|
||||||
|
## Here is an example of how to configure some standard options.
|
||||||
|
##
|
||||||
|
#
|
||||||
|
#defaults {
|
||||||
|
# udev_dir /dev
|
||||||
|
# polling_interval 10
|
||||||
|
# selector "round-robin 0"
|
||||||
|
# path_grouping_policy multibus
|
||||||
|
# prio alua
|
||||||
|
# path_checker readsector0
|
||||||
|
# rr_min_io 100
|
||||||
|
# max_fds 8192
|
||||||
|
# rr_weight priorities
|
||||||
|
# failback immediate
|
||||||
|
# no_path_retry fail
|
||||||
|
# user_friendly_names yes
|
||||||
|
#}
|
||||||
|
##
|
||||||
|
## The wwid line in the following blacklist section is shown as an example
|
||||||
|
## of how to blacklist devices by wwid. The 2 devnode lines are the
|
||||||
|
## compiled in default blacklist. If you want to blacklist entire types
|
||||||
|
## of devices, such as all scsi devices, you should use a devnode line.
|
||||||
|
## However, if you want to blacklist specific devices, you should use
|
||||||
|
## a wwid line. Since there is no guarantee that a specific device will
|
||||||
|
## not change names on reboot (from /dev/sda to /dev/sdb for example)
|
||||||
|
## devnode lines are not recommended for blacklisting specific devices.
|
||||||
|
##
|
||||||
|
#blacklist {
|
||||||
|
# wwid 26353900f02796769
|
||||||
|
# devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
|
||||||
|
# devnode "^hd[a-z]"
|
||||||
|
#}
|
||||||
|
#multipaths {
|
||||||
|
# multipath {
|
||||||
|
# wwid 3600508b4000156d700012000000b0000
|
||||||
|
# alias yellow
|
||||||
|
# path_grouping_policy multibus
|
||||||
|
# path_checker readsector0
|
||||||
|
# path_selector "round-robin 0"
|
||||||
|
# failback manual
|
||||||
|
# rr_weight priorities
|
||||||
|
# no_path_retry 5
|
||||||
|
# }
|
||||||
|
# multipath {
|
||||||
|
# wwid 1DEC_____321816758474
|
||||||
|
# alias red
|
||||||
|
# }
|
||||||
|
#}
|
||||||
|
#devices {
|
||||||
|
# device {
|
||||||
|
# vendor "COMPAQ "
|
||||||
|
# product "HSV110 (C)COMPAQ"
|
||||||
|
# path_grouping_policy multibus
|
||||||
|
# path_checker readsector0
|
||||||
|
# path_selector "round-robin 0"
|
||||||
|
# hardware_handler "0"
|
||||||
|
# failback 15
|
||||||
|
# rr_weight priorities
|
||||||
|
# no_path_retry queue
|
||||||
|
# }
|
||||||
|
# device {
|
||||||
|
# vendor "COMPAQ "
|
||||||
|
# product "MSA1000 "
|
||||||
|
# path_grouping_policy multibus
|
||||||
|
# }
|
||||||
|
#}
|
1706
SPECS/device-mapper-multipath.spec
Normal file
1706
SPECS/device-mapper-multipath.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user