From 8444ee229612834a5bc77ebca2ad44934f577985 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 28 2020 09:35:36 +0000 Subject: import device-mapper-multipath-0.8.3-3.el8 --- diff --git a/.device-mapper-multipath.metadata b/.device-mapper-multipath.metadata index 8a1df89..1dca87b 100644 --- a/.device-mapper-multipath.metadata +++ b/.device-mapper-multipath.metadata @@ -1 +1 @@ -30bf38b713001c2b80b86d67473fbe20dc0f28cc SOURCES/multipath-tools-0.8.0.tgz +f700dc1e4ce1d6952051467d4b245f9bd80286e3 SOURCES/multipath-tools-0.8.3.tgz diff --git a/.gitignore b/.gitignore index 512d533..8d47c38 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/multipath-tools-0.8.0.tgz +SOURCES/multipath-tools-0.8.3.tgz diff --git a/SOURCES/0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch b/SOURCES/0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch deleted file mode 100644 index 491a21d..0000000 --- a/SOURCES/0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 24 Jan 2019 14:09:23 -0600 -Subject: [PATCH] BZ 1668693: disable user_friendly_names for NetApp - -NetApp has tools that rely on devices using WWID names. To avoid -breaking these, NetApp devices should continue to use WWID names, even -if the default config is set to enable user_friendly_names. If users -want to use user_friendly_names on NetApp devices, the must specifically -override the device config. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index d3a8d9b..8776411 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -719,6 +719,7 @@ static struct hwentry default_hw[] = { - .flush_on_last_del = FLUSH_ENABLED, - .dev_loss = MAX_DEV_LOSS_TMO, - .prio_name = PRIO_ONTAP, -+ .user_friendly_names = USER_FRIENDLY_NAMES_OFF, - }, - { - /* --- -2.17.2 - diff --git a/SOURCES/0001-multipathd-warn-when-configuration-has-been-changed.patch b/SOURCES/0001-multipathd-warn-when-configuration-has-been-changed.patch new file mode 100644 index 0000000..207eac8 --- /dev/null +++ b/SOURCES/0001-multipathd-warn-when-configuration-has-been-changed.patch @@ -0,0 +1,277 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + #include + #include ++#include + #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 + diff --git a/SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch b/SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch new file mode 100644 index 0000000..3ee5965 --- /dev/null +++ b/SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0002-libmultipath-handle-existing-paths-in-marginal_path-.patch b/SOURCES/0002-libmultipath-handle-existing-paths-in-marginal_path-.patch deleted file mode 100644 index 93a3d7c..0000000 --- a/SOURCES/0002-libmultipath-handle-existing-paths-in-marginal_path-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 25 Jan 2019 16:45:26 -0600 -Subject: [PATCH] libmultipath: handle existing paths in marginal_path enqueue - -If the path that enqueue_io_err_stat_by_path() is trying to add -is already on the list, just return success. There's no reason -to fail in this case. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 02b1453..1cb3ffe 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -254,7 +254,6 @@ static void free_io_err_pathvec(struct io_err_stat_pathvec *p) - * return value - * 0: enqueue OK - * 1: fails because of internal error -- * 2: fails because of existing already - */ - static int enqueue_io_err_stat_by_path(struct path *path) - { -@@ -264,7 +263,7 @@ static int enqueue_io_err_stat_by_path(struct path *path) - p = find_err_path_by_dev(paths->pathvec, path->dev); - if (p) { - pthread_mutex_unlock(&paths->mutex); -- return 2; -+ return 0; - } - pthread_mutex_unlock(&paths->mutex); - -@@ -418,9 +417,8 @@ int hit_io_err_recheck_time(struct path *pp) - io_err_stat_log(3, "%s: enqueue fails, to recover", - pp->dev); - goto recover; -- } else if (!r) { -+ } else - pp->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING; -- } - } - - return 1; --- -2.17.2 - diff --git a/SOURCES/0003-Fix-leak-in-mpathpersist.patch b/SOURCES/0003-Fix-leak-in-mpathpersist.patch new file mode 100644 index 0000000..b9bc55e --- /dev/null +++ b/SOURCES/0003-Fix-leak-in-mpathpersist.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0003-multipathd-cleanup-marginal-paths-checking-timers.patch b/SOURCES/0003-multipathd-cleanup-marginal-paths-checking-timers.patch deleted file mode 100644 index ece5218..0000000 --- a/SOURCES/0003-multipathd-cleanup-marginal-paths-checking-timers.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 25 Jan 2019 17:09:42 -0600 -Subject: [PATCH] multipathd: cleanup marginal paths checking timers - -When a path gets recovered in hit_io_err_recheck_time(), it will -continue running in check_path(), so there is no reason to schedule -another path check as soon as possible (since one is currently -happening). - -Also, there isn't much point in restarting the io err stat checking when -the path is down, so hit_io_err_recheck_time() should only be run when -the path is up. Downed marginal paths can be treated just like any other -downed path. - -Finally, there is no reason to set reset pp->io_err_dis_reinstate_time -when we decide to enqueue a path. Either th enqueue will fail and the -path will get recovered, or it will succeed, and we won't check the -reinstate time again until poll_io_err_stat() marks the path as needing -a requeue. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 8 -------- - multipathd/main.c | 3 ++- - 2 files changed, 2 insertions(+), 9 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 1cb3ffe..416e13a 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -400,13 +400,6 @@ int hit_io_err_recheck_time(struct path *pp) - io_err_stat_log(4, "%s: reschedule checking after %d seconds", - pp->dev, - pp->mpp->marginal_path_err_recheck_gap_time); -- /* -- * to reschedule io error checking again -- * if the path is good enough, we claim it is good -- * and can be reinsated as soon as possible in the -- * check_path routine. -- */ -- pp->io_err_dis_reinstate_time = curr_time.tv_sec; - r = enqueue_io_err_stat_by_path(pp); - /* - * Enqueue fails because of internal error. -@@ -426,7 +419,6 @@ int hit_io_err_recheck_time(struct path *pp) - recover: - pp->io_err_pathfail_cnt = 0; - pp->io_err_disable_reinstate = 0; -- pp->tick = 1; - return 0; - } - -diff --git a/multipathd/main.c b/multipathd/main.c -index fb520b6..fe6d8ef 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2079,7 +2079,8 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - return 1; - } - -- if (pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) { -+ if ((newstate == PATH_UP || newstate == PATH_GHOST) && -+ pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) { - pp->state = PATH_SHAKY; - /* - * to reschedule as soon as possible,so that this path can --- -2.17.2 - diff --git a/SOURCES/0004-libmultipath-fix-marginal-paths-queueing-errors.patch b/SOURCES/0004-libmultipath-fix-marginal-paths-queueing-errors.patch deleted file mode 100644 index 9417741..0000000 --- a/SOURCES/0004-libmultipath-fix-marginal-paths-queueing-errors.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 28 Jan 2019 00:20:53 -0600 -Subject: [PATCH] libmultipath: fix marginal paths queueing errors - -The current marginal paths code tries to enqueue paths for io error -checking when multipathd receives a uevent on path failure. This can run -into a couple of problems. First, this uevent could happen before or -after multipathd actually fails the path, so simply checking nr_active -doesn't tell us if this is the last active path. Also, The code to fail -the path in enqueue_io_err_stat_by_path() doesn't ever update the path -state. This can cause the path to get failed twice, temporarily leading -to incorrect nr_active counts. Further, The point when multipathd should -care if this is the last active path is when the path has come up again, -not when it goes down. Lastly, if the path is down, it is often -impossible to open the path device, causing setup_directio_ctx() to -fail, which causes multipathd to skip io error checking and mark the -path as not marginal. - -Instead, multipathd should just make sure that if the path is marginal, -it gets failed in the uevent, so as not to race with the checkerloop -thread. Then, when the path comes back up, check_path() can enqueue it, -just like it does for paths that need to get rechecked. To make it -obvious that the state PATH_IO_ERR_IN_POLLING_RECHECK and the function -hit_io_err_recheck_time() now apply to paths waiting to be enqueued for -the first time as well, I've also changed their names to -PATH_IO_ERR_WAITING_TO_CHECK and need_io_err_check(), respectively. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 55 +++++++++++++++++--------------------- - libmultipath/io_err_stat.h | 2 +- - multipathd/main.c | 2 +- - 3 files changed, 27 insertions(+), 32 deletions(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 416e13a..72aacf3 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -41,7 +41,7 @@ - #define CONCUR_NR_EVENT 32 - - #define PATH_IO_ERR_IN_CHECKING -1 --#define PATH_IO_ERR_IN_POLLING_RECHECK -2 -+#define PATH_IO_ERR_WAITING_TO_CHECK -2 - - #define io_err_stat_log(prio, fmt, args...) \ - condlog(prio, "io error statistic: " fmt, ##args) -@@ -283,24 +283,6 @@ static int enqueue_io_err_stat_by_path(struct path *path) - vector_set_slot(paths->pathvec, p); - pthread_mutex_unlock(&paths->mutex); - -- if (!path->io_err_disable_reinstate) { -- /* -- *fail the path in the kernel for the time of the to make -- *the test more reliable -- */ -- io_err_stat_log(3, "%s: fail dm path %s before checking", -- path->mpp->alias, path->dev); -- path->io_err_disable_reinstate = 1; -- dm_fail_path(path->mpp->alias, path->dev_t); -- update_queue_mode_del_path(path->mpp); -- -- /* -- * schedule path check as soon as possible to -- * update path state to delayed state -- */ -- path->tick = 1; -- -- } - io_err_stat_log(2, "%s: enqueue path %s to check", - path->mpp->alias, path->dev); - return 0; -@@ -317,7 +299,6 @@ free_ioerr_path: - int io_err_stat_handle_pathfail(struct path *path) - { - struct timespec curr_time; -- int res; - - if (uatomic_read(&io_err_thread_running) == 0) - return 1; -@@ -332,8 +313,6 @@ int io_err_stat_handle_pathfail(struct path *path) - - if (!path->mpp) - return 1; -- if (path->mpp->nr_active <= 1) -- return 1; - if (path->mpp->marginal_path_double_failed_time <= 0 || - path->mpp->marginal_path_err_sample_time <= 0 || - path->mpp->marginal_path_err_recheck_gap_time <= 0 || -@@ -371,17 +350,33 @@ int io_err_stat_handle_pathfail(struct path *path) - } - path->io_err_pathfail_cnt++; - if (path->io_err_pathfail_cnt >= FLAKY_PATHFAIL_THRESHOLD) { -- res = enqueue_io_err_stat_by_path(path); -- if (!res) -- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_CHECKING; -- else -- path->io_err_pathfail_cnt = 0; -+ path->io_err_disable_reinstate = 1; -+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK; -+ /* enqueue path as soon as it comes up */ -+ path->io_err_dis_reinstate_time = 0; -+ if (path->state != PATH_DOWN) { -+ struct config *conf; -+ int oldstate = path->state; -+ int checkint; -+ -+ conf = get_multipath_config(); -+ checkint = conf->checkint; -+ put_multipath_config(conf); -+ io_err_stat_log(2, "%s: mark as failed", path->dev); -+ path->mpp->stat_path_failures++; -+ path->state = PATH_DOWN; -+ path->dmstate = PSTATE_FAILED; -+ if (oldstate == PATH_UP || oldstate == PATH_GHOST) -+ update_queue_mode_del_path(path->mpp); -+ if (path->tick > checkint) -+ path->tick = checkint; -+ } - } - - return 0; - } - --int hit_io_err_recheck_time(struct path *pp) -+int need_io_err_check(struct path *pp) - { - struct timespec curr_time; - int r; -@@ -392,7 +387,7 @@ int hit_io_err_recheck_time(struct path *pp) - io_err_stat_log(2, "%s: recover path early", pp->dev); - goto recover; - } -- if (pp->io_err_pathfail_cnt != PATH_IO_ERR_IN_POLLING_RECHECK) -+ if (pp->io_err_pathfail_cnt != PATH_IO_ERR_WAITING_TO_CHECK) - return 1; - if (clock_gettime(CLOCK_MONOTONIC, &curr_time) != 0 || - (curr_time.tv_sec - pp->io_err_dis_reinstate_time) > -@@ -489,7 +484,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) - } else if (path->mpp && path->mpp->nr_active > 1) { - io_err_stat_log(3, "%s: keep failing the dm path %s", - path->mpp->alias, path->dev); -- path->io_err_pathfail_cnt = PATH_IO_ERR_IN_POLLING_RECHECK; -+ path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK; - path->io_err_disable_reinstate = 1; - path->io_err_dis_reinstate_time = currtime.tv_sec; - io_err_stat_log(3, "%s: disable reinstating of %s", -diff --git a/libmultipath/io_err_stat.h b/libmultipath/io_err_stat.h -index bbf31b4..53d6d7d 100644 ---- a/libmultipath/io_err_stat.h -+++ b/libmultipath/io_err_stat.h -@@ -10,6 +10,6 @@ extern pthread_attr_t io_err_stat_attr; - int start_io_err_stat_thread(void *data); - void stop_io_err_stat_thread(void); - int io_err_stat_handle_pathfail(struct path *path); --int hit_io_err_recheck_time(struct path *pp); -+int need_io_err_check(struct path *pp); - - #endif /* _IO_ERR_STAT_H */ -diff --git a/multipathd/main.c b/multipathd/main.c -index fe6d8ef..43830e8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2080,7 +2080,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - } - - if ((newstate == PATH_UP || newstate == PATH_GHOST) && -- pp->io_err_disable_reinstate && hit_io_err_recheck_time(pp)) { -+ pp->io_err_disable_reinstate && need_io_err_check(pp)) { - pp->state = PATH_SHAKY; - /* - * to reschedule as soon as possible,so that this path can --- -2.17.2 - diff --git a/SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch b/SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch new file mode 100644 index 0000000..0274032 --- /dev/null +++ b/SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 5 Nov 2019 13:53:29 -0600 +Subject: [PATCH] libmultipath: remove unused path->prio_args + +Signed-off-by: Benjamin Marzinski +--- + 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 + diff --git a/SOURCES/0005-libmultipath-constify-get_unaligned_be.patch b/SOURCES/0005-libmultipath-constify-get_unaligned_be.patch new file mode 100644 index 0000000..415e061 --- /dev/null +++ b/SOURCES/0005-libmultipath-constify-get_unaligned_be.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 6 Nov 2019 16:49:40 -0600 +Subject: [PATCH] libmultipath: constify get_unaligned_be* + +Signed-off-by: Benjamin Marzinski +--- + 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 + diff --git a/SOURCES/0005-libmultipath-fix-marginal_paths-nr_active-check.patch b/SOURCES/0005-libmultipath-fix-marginal_paths-nr_active-check.patch deleted file mode 100644 index 486e03a..0000000 --- a/SOURCES/0005-libmultipath-fix-marginal_paths-nr_active-check.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 29 Jan 2019 18:26:04 -0600 -Subject: [PATCH] libmultipath: fix marginal_paths nr_active check - -Marginal paths are SHAKY, so they don't count towards the number of -active paths. poll_io_err_stat() shouldn't automatically reinstate a -marginal path if there already is an active path. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/io_err_stat.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/io_err_stat.c b/libmultipath/io_err_stat.c -index 72aacf3..554b777 100644 ---- a/libmultipath/io_err_stat.c -+++ b/libmultipath/io_err_stat.c -@@ -481,7 +481,7 @@ static int poll_io_err_stat(struct vectors *vecs, struct io_err_stat_path *pp) - */ - path->tick = 1; - -- } else if (path->mpp && path->mpp->nr_active > 1) { -+ } else if (path->mpp && path->mpp->nr_active > 0) { - io_err_stat_log(3, "%s: keep failing the dm path %s", - path->mpp->alias, path->dev); - path->io_err_pathfail_cnt = PATH_IO_ERR_WAITING_TO_CHECK; --- -2.17.2 - diff --git a/SOURCES/0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch b/SOURCES/0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch new file mode 100644 index 0000000..e3a3fbc --- /dev/null +++ b/SOURCES/0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch b/SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch deleted file mode 100644 index 4eb50f5..0000000 --- a/SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 15 Feb 2019 17:19:46 -0600 -Subject: [PATCH] multipathd: Fix miscounting active paths - -When multipathd gets a change uevent, it calls pathinfo with DI_NOIO. -This sets the path state to the return value of path_offline(). If a -path is in the PATH_DOWN state but path_offline() returns PATH_UP, when -that path gets a change event, its state will get moved to PATH_UP -without either reinstating the path, or reloading the map. The next -call to check_path() will move the path back to PATH_DOWN. Since -check_path() simply increments and decrements nr_active instead of -calculating it based on the actual number of active paths, nr_active -will get decremented a second time for this failed path, potentially -putting the multipath device into recovery mode. - -This commit does two things to avoid this situation. It makes the -DI_NOIO flag only set pp->state in pathinfo() if DI_CHECKER is also set. -This isn't set in uev_update_path() to avoid changing the path state in -this case. Also, to guard against pp->state getting changed in some -other code path without properly updating the map state, check_path() -now calls set_no_path_retry, which recalculates nr_active based on the -actual number of active paths, and makes sure that the queue_if_no_path -value in the features line is correct. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 11 ++++++----- - multipath/main.c | 2 +- - multipathd/main.c | 4 +++- - 3 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 10bd8cd..729bcb9 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1914,11 +1914,12 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - if (path_state == PATH_REMOVED) - goto blank; - else if (mask & DI_NOIO) { -- /* -- * Avoid any IO on the device itself. -- * Behave like DI_CHECKER in the "path unavailable" case. -- */ -- pp->chkrstate = pp->state = path_state; -+ if (mask & DI_CHECKER) -+ /* -+ * Avoid any IO on the device itself. -+ * simply use the path_offline() return as its state -+ */ -+ pp->chkrstate = pp->state = path_state; - return PATHINFO_OK; - } - -diff --git a/multipath/main.c b/multipath/main.c -index 5abb118..69141db 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -356,7 +356,7 @@ static int check_usable_paths(struct config *conf, - pp->udev = get_udev_device(pp->dev_t, DEV_DEVT); - if (pp->udev == NULL) - continue; -- if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) != PATHINFO_OK) -+ if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO|DI_CHECKER) != PATHINFO_OK) - continue; - - if (pp->state == PATH_UP && -diff --git a/multipathd/main.c b/multipathd/main.c -index 43830e8..678ecf8 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -392,7 +392,8 @@ static void set_no_path_retry(struct multipath *mpp) - default: - if (mpp->nr_active > 0) { - mpp->retry_tick = 0; -- dm_queue_if_no_path(mpp->alias, 1); -+ if (!is_queueing) -+ dm_queue_if_no_path(mpp->alias, 1); - } else if (is_queueing && mpp->retry_tick == 0) - enter_recovery_mode(mpp); - break; -@@ -2072,6 +2073,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - /* if update_multipath_strings orphaned the path, quit early */ - if (!pp->mpp) - return 0; -+ set_no_path_retry(pp->mpp); - - if ((newstate == PATH_UP || newstate == PATH_GHOST) && - check_path_reinstate_state(pp)) { --- -2.17.2 - diff --git a/SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch b/SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch new file mode 100644 index 0000000..a6fcc31 --- /dev/null +++ b/SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch @@ -0,0 +1,204 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch b/SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch deleted file mode 100644 index 37fdae1..0000000 --- a/SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 20 Feb 2019 17:05:08 -0600 -Subject: [PATCH] multipathd: ignore failed wwid recheck - -If disable_changed_wwids is set, when multipathd gets a change event on -a path, it verifies that the wwid hasn't changed in uev_update_path(). -If get_uid() failed, uev_update_path treated this as a wwid change to 0. -This could cause paths to suddenly be dropped due to an issue with -getting the wwid. Even if get_uid() failed because the path was down, -it no change uevent happend when it later became active, multipathd -would continue to ignore the path. Also, scsi_uid_fallback() clears the -failure return if it doesn't attempt to fallback, causing get_uid() -to return success, when it actually failed. - -Multipathd should neither set nor clear wwid_changed if get_uid() -returned failure. Also, scsi_uid_fallback() should retain the old return -value if it doesn't attempt to fallback. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 6 +++--- - multipathd/main.c | 6 ++++-- - 2 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 729bcb9..b08cb2d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1755,9 +1755,9 @@ get_vpd_uid(struct path * pp) - } - - static ssize_t scsi_uid_fallback(struct path *pp, int path_state, -- const char **origin) -+ const char **origin, ssize_t old_len) - { -- ssize_t len = 0; -+ ssize_t len = old_len; - int retrigger; - struct config *conf; - -@@ -1828,7 +1828,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - origin = "sysfs"; - } - if (len <= 0 && pp->bus == SYSFS_BUS_SCSI) -- len = scsi_uid_fallback(pp, path_state, &origin); -+ len = scsi_uid_fallback(pp, path_state, &origin, len); - } - if ( len < 0 ) { - condlog(1, "%s: failed to get %s uid: %s", -diff --git a/multipathd/main.c b/multipathd/main.c -index 678ecf8..fd83a6a 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1234,9 +1234,11 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- get_uid(pp, pp->state, uev->udev); -+ rc = get_uid(pp, pp->state, uev->udev); - -- if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { -+ if (rc != 0) -+ strcpy(pp->wwid, wwid); -+ else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { - condlog(0, "%s: path wwid changed from '%s' to '%s'. %s", - uev->kernel, wwid, pp->wwid, - (disable_changed_wwids ? "disallowing" : --- -2.17.2 - diff --git a/SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch b/SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch new file mode 100644 index 0000000..94620cd --- /dev/null +++ b/SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch b/SOURCES/0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch deleted file mode 100644 index aa43b94..0000000 --- a/SOURCES/0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 21 Feb 2019 13:05:43 -0600 -Subject: [PATCH] libmutipath: continue to use old state on PATH_PENDING - -When pathinfo() sets pp->state to PATH_PENDING, it can cause problems -with path checking. It should act more like check_path(). When -check_path() sees a new state of PATH_PENDING, it doesn't update the -path state at all, so a path's old state is normally never PATH_PENDING. - -As and example of the problems of setting a path to PATH_PENDING, If -check_path() sets a path's state to PATH_UP, then a call to pathinfo() -sets the state to PATH_PENDING, and then another call the check_path() -sets the state to PATH_DOWN, multipathd won't fail the path in the -kernel. Also, if a path's state is PATH_PENDING, and nr_active is -recalculated, that path will count as down, even if the state was -previously PATH_UP. If a path already has a state of PATH_WILD or -PATH_UNCHECKED, changing it to PATH_PENDING won't hurt anything, and it -will help anyone who sees it know what's actually happening. But -otherwise, pathinfo() should leave the previous state alone. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index b08cb2d..28c00e5 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1946,8 +1946,11 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_CHECKER) { - if (path_state == PATH_UP) { -- pp->chkrstate = pp->state = get_state(pp, conf, 0, -- path_state); -+ int newstate = get_state(pp, conf, 0, path_state); -+ if (newstate != PATH_PENDING || -+ pp->state == PATH_UNCHECKED || -+ pp->state == PATH_WILD) -+ pp->chkrstate = pp->state = newstate; - if (pp->state == PATH_TIMEOUT) - pp->state = PATH_DOWN; - if (pp->state == PATH_UP && !pp->size) { --- -2.17.2 - diff --git a/SOURCES/0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch b/SOURCES/0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch new file mode 100644 index 0000000..c94c00f --- /dev/null +++ b/SOURCES/0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch @@ -0,0 +1,350 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0009-multipathd-use-update_path_groups-instead-of-reload_.patch b/SOURCES/0009-multipathd-use-update_path_groups-instead-of-reload_.patch deleted file mode 100644 index cc429c5..0000000 --- a/SOURCES/0009-multipathd-use-update_path_groups-instead-of-reload_.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 21 Feb 2019 17:00:17 -0600 -Subject: [PATCH] multipathd: use update_path_groups instead of reload_map - -reload_map() doesn't do the work to sync the state after reloading the -map. Instead of calling it directly, cli_reload() and uev_update_path() -should call update_path_groups(), which calls reload_map() with all the -necessary syncing. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli_handlers.c | 2 +- - multipathd/main.c | 13 ++++++++----- - multipathd/main.h | 2 ++ - 3 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c -index f95813e..60e17d6 100644 ---- a/multipathd/cli_handlers.c -+++ b/multipathd/cli_handlers.c -@@ -877,7 +877,7 @@ cli_reload(void *v, char **reply, int *len, void *data) - return 1; - } - -- return reload_map(vecs, mpp, 0, 1); -+ return update_path_groups(mpp, vecs, 0); - } - - int resize_map(struct multipath *mpp, unsigned long long size, -diff --git a/multipathd/main.c b/multipathd/main.c -index fd83a6a..7a317d9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1273,10 +1273,13 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - else { - if (ro == 1) - pp->mpp->force_readonly = 1; -- retval = reload_map(vecs, mpp, 0, 1); -- pp->mpp->force_readonly = 0; -- condlog(2, "%s: map %s reloaded (retval %d)", -- uev->kernel, mpp->alias, retval); -+ retval = update_path_groups(mpp, vecs, 0); -+ if (retval == 2) -+ condlog(2, "%s: map removed during reload", pp->dev); -+ else { -+ pp->mpp->force_readonly = 0; -+ condlog(2, "%s: map %s reloaded (retval %d)", uev->kernel, mpp->alias, retval); -+ } - } - } - } -@@ -1832,7 +1835,7 @@ int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh) - - dm_lib_release(); - if (setup_multipath(vecs, mpp) != 0) -- return 1; -+ return 2; - sync_map_state(mpp); - - return 0; -diff --git a/multipathd/main.h b/multipathd/main.h -index 8fd426b..e5c1398 100644 ---- a/multipathd/main.h -+++ b/multipathd/main.h -@@ -43,5 +43,7 @@ int __setup_multipath (struct vectors * vecs, struct multipath * mpp, - int reset); - #define setup_multipath(vecs, mpp) __setup_multipath(vecs, mpp, 1) - int update_multipath (struct vectors *vecs, char *mapname, int reset); -+int update_path_groups(struct multipath *mpp, struct vectors *vecs, -+ int refresh); - - #endif /* MAIN_H */ --- -2.17.2 - diff --git a/SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch new file mode 100644 index 0000000..d560bc4 --- /dev/null +++ b/SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0010-multipath.conf-add-missing-options-to-man-page.patch b/SOURCES/0010-multipath.conf-add-missing-options-to-man-page.patch deleted file mode 100644 index 394952d..0000000 --- a/SOURCES/0010-multipath.conf-add-missing-options-to-man-page.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Feb 2019 12:22:59 -0600 -Subject: [PATCH] multipath.conf: add missing options to man page - -Signed-off-by: Benjamin Marzinski ---- - multipath/multipath.conf.5 | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 0fe8461..864d7eb 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1468,6 +1468,8 @@ section: - .TP - .B uid_attribute - .TP -+.B getuid_callout -+.TP - .B path_selector - .TP - .B path_checker -@@ -1494,6 +1496,8 @@ section: - .TP - .B flush_on_last_del - .TP -+.B user_friendly_names -+.TP - .B retain_attached_hw_handler - .TP - .B detect_prio -@@ -1525,6 +1529,8 @@ section: - .B max_sectors_kb - .TP - .B ghost_delay -+.TP -+.B all_tg_pt - .RE - .PD - .LP -@@ -1604,7 +1610,11 @@ the values are taken from the \fIdevices\fR or \fIdefaults\fR sections: - .TP - .B skip_kpartx - .TP -+.B max_sectors_kb -+.TP - .B ghost_delay -+.TP -+.B all_tg_pt - .RE - .PD - .LP --- -2.17.2 - diff --git a/SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch new file mode 100644 index 0000000..8aaabc7 --- /dev/null +++ b/SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -0,0 +1,105 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch b/SOURCES/0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch deleted file mode 100644 index 31cabca..0000000 --- a/SOURCES/0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 7 Mar 2019 16:14:35 -0600 -Subject: [PATCH] libmultipath: add get_uid fallback code for NVMe devices - -If multipath can't get the uid for NVMe devices from udev, it can get it -directly from sysfs. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 49 ++++++++++++++++++++++++++++------------ - 1 file changed, 34 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 28c00e5..bece67c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1754,8 +1754,8 @@ get_vpd_uid(struct path * pp) - return get_vpd_sysfs(parent, 0x83, pp->wwid, WWID_SIZE); - } - --static ssize_t scsi_uid_fallback(struct path *pp, int path_state, -- const char **origin, ssize_t old_len) -+static ssize_t uid_fallback(struct path *pp, int path_state, -+ const char **origin, ssize_t old_len) - { - ssize_t len = old_len; - int retrigger; -@@ -1764,17 +1764,36 @@ static ssize_t scsi_uid_fallback(struct path *pp, int path_state, - conf = get_multipath_config(); - retrigger = conf->retrigger_tries; - put_multipath_config(conf); -- if (pp->retriggers >= retrigger && -- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { -- len = get_vpd_uid(pp); -- *origin = "sysfs"; -- pp->uid_attribute = NULL; -- if (len < 0 && path_state == PATH_UP) { -- condlog(1, "%s: failed to get sysfs uid: %s", -- pp->dev, strerror(-len)); -- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid, -- WWID_SIZE); -- *origin = "sgio"; -+ if (pp->retriggers >= retrigger) { -+ if (pp->bus == SYSFS_BUS_SCSI && -+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { -+ len = get_vpd_uid(pp); -+ *origin = "sysfs"; -+ pp->uid_attribute = NULL; -+ if (len < 0 && path_state == PATH_UP) { -+ condlog(1, "%s: failed to get sysfs uid: %s", -+ pp->dev, strerror(-len)); -+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid, -+ WWID_SIZE); -+ *origin = "sgio"; -+ } -+ } else if (pp->bus == SYSFS_BUS_NVME) { -+ char value[256]; -+ len = sysfs_attr_get_value(pp->udev, "wwid", value, -+ sizeof(value)); -+ if (len <= 0) -+ return -1; -+ len = strlcpy(pp->wwid, value, WWID_SIZE); -+ if (len >= WWID_SIZE) { -+ len = fix_broken_nvme_wwid(pp, value, -+ WWID_SIZE); -+ if (len > 0) -+ return len; -+ condlog(0, "%s: wwid overflow", pp->dev); -+ len = WWID_SIZE; -+ } -+ *origin = "sysfs"; -+ pp->uid_attribute = NULL; - } - } - return len; -@@ -1827,8 +1846,8 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - len = get_vpd_uid(pp); - origin = "sysfs"; - } -- if (len <= 0 && pp->bus == SYSFS_BUS_SCSI) -- len = scsi_uid_fallback(pp, path_state, &origin, len); -+ if (len <= 0) -+ len = uid_fallback(pp, path_state, &origin, len); - } - if ( len < 0 ) { - condlog(1, "%s: failed to get %s uid: %s", --- -2.17.2 - diff --git a/SOURCES/0012-RH-don-t-start-without-a-config-file.patch b/SOURCES/0012-RH-don-t-start-without-a-config-file.patch new file mode 100644 index 0000000..e98296e --- /dev/null +++ b/SOURCES/0012-RH-don-t-start-without-a-config-file.patch @@ -0,0 +1,106 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch b/SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch deleted file mode 100644 index c47f70a..0000000 --- a/SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 27 Mar 2019 12:21:57 -0500 -Subject: [PATCH] libmulitpath: cleanup uid_fallback code - -Instead of always calling uid_fallback() if the configured method to get -the uid failed, get_uid now checks if the path supports fallbacks and if -all the retriggers have occurred. If so, it calls uid_fallback(), which -just attempts to get the uid using the appropriate fallback method. None -of these changes should make the code function any differently. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 85 ++++++++++++++++++++++------------------ - 1 file changed, 46 insertions(+), 39 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index bece67c..3ec60d6 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1755,50 +1755,50 @@ get_vpd_uid(struct path * pp) - } - - static ssize_t uid_fallback(struct path *pp, int path_state, -- const char **origin, ssize_t old_len) -+ const char **origin) - { -- ssize_t len = old_len; -- int retrigger; -- struct config *conf; -- -- conf = get_multipath_config(); -- retrigger = conf->retrigger_tries; -- put_multipath_config(conf); -- if (pp->retriggers >= retrigger) { -- if (pp->bus == SYSFS_BUS_SCSI && -- !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { -- len = get_vpd_uid(pp); -- *origin = "sysfs"; -- pp->uid_attribute = NULL; -- if (len < 0 && path_state == PATH_UP) { -- condlog(1, "%s: failed to get sysfs uid: %s", -- pp->dev, strerror(-len)); -- len = get_vpd_sgio(pp->fd, 0x83, pp->wwid, -+ ssize_t len = -1; -+ -+ if (pp->bus == SYSFS_BUS_SCSI && -+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { -+ len = get_vpd_uid(pp); -+ *origin = "sysfs"; -+ pp->uid_attribute = NULL; -+ if (len < 0 && path_state == PATH_UP) { -+ condlog(1, "%s: failed to get sysfs uid: %s", -+ pp->dev, strerror(-len)); -+ len = get_vpd_sgio(pp->fd, 0x83, pp->wwid, -+ WWID_SIZE); -+ *origin = "sgio"; -+ } -+ } else if (pp->bus == SYSFS_BUS_NVME) { -+ char value[256]; -+ len = sysfs_attr_get_value(pp->udev, "wwid", value, -+ sizeof(value)); -+ if (len <= 0) -+ return -1; -+ len = strlcpy(pp->wwid, value, WWID_SIZE); -+ if (len >= WWID_SIZE) { -+ len = fix_broken_nvme_wwid(pp, value, - WWID_SIZE); -- *origin = "sgio"; -- } -- } else if (pp->bus == SYSFS_BUS_NVME) { -- char value[256]; -- len = sysfs_attr_get_value(pp->udev, "wwid", value, -- sizeof(value)); -- if (len <= 0) -- return -1; -- len = strlcpy(pp->wwid, value, WWID_SIZE); -- if (len >= WWID_SIZE) { -- len = fix_broken_nvme_wwid(pp, value, -- WWID_SIZE); -- if (len > 0) -- return len; -- condlog(0, "%s: wwid overflow", pp->dev); -- len = WWID_SIZE; -- } -- *origin = "sysfs"; -- pp->uid_attribute = NULL; -+ if (len > 0) -+ return len; -+ condlog(0, "%s: wwid overflow", pp->dev); -+ len = WWID_SIZE; - } -+ *origin = "sysfs"; -+ pp->uid_attribute = NULL; - } - return len; - } - -+static int has_uid_fallback(struct path *pp) -+{ -+ return ((pp->bus == SYSFS_BUS_SCSI && -+ !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) || -+ pp->bus == SYSFS_BUS_NVME); -+} -+ - int - get_uid (struct path * pp, int path_state, struct udev_device *udev) - { -@@ -1846,8 +1846,15 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - len = get_vpd_uid(pp); - origin = "sysfs"; - } -- if (len <= 0) -- len = uid_fallback(pp, path_state, &origin, len); -+ if (len <= 0 && has_uid_fallback(pp)) { -+ int retrigger_tries; -+ -+ conf = get_multipath_config(); -+ retrigger_tries = conf->retrigger_tries; -+ put_multipath_config(conf); -+ if (pp->retriggers >= retrigger_tries) -+ len = uid_fallback(pp, path_state, &origin); -+ } - } - if ( len < 0 ) { - condlog(1, "%s: failed to get %s uid: %s", --- -2.17.2 - diff --git a/SOURCES/0013-RH-use-rpm-optflags-if-present.patch b/SOURCES/0013-RH-use-rpm-optflags-if-present.patch new file mode 100644 index 0000000..2234168 --- /dev/null +++ b/SOURCES/0013-RH-use-rpm-optflags-if-present.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch b/SOURCES/0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch deleted file mode 100644 index 45c0366..0000000 --- a/SOURCES/0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Wed, 27 Mar 2019 23:27:47 -0500 -Subject: [PATCH] multipathd: handle changed wwids by removal and addition - -If a path's WWID changes, it's not necessarily failed. But it certainly -has to be removed from an existing map, otherwise data corruption is -imminent. Instead of keeping the path in the map, failing it, and -remembering the "changed WWID" state, this patch simply removes and -re-adds the path. - -This is patch is heavily based on the previous patch of the same name -by Martin Wilck. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/main.c | 28 ++++++---------------------- - 1 file changed, 6 insertions(+), 22 deletions(-) - -diff --git a/multipathd/main.c b/multipathd/main.c -index 7a317d9..b3571d9 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1191,7 +1191,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - int ro, retval = 0, rc; - struct path * pp; - struct config *conf; -- int disable_changed_wwids; - int needs_reinit = 0; - - switch ((rc = change_foreign(uev->udev))) { -@@ -1209,12 +1208,6 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - break; - } - -- conf = get_multipath_config(); -- disable_changed_wwids = conf->disable_changed_wwids; -- put_multipath_config(conf); -- -- ro = uevent_get_disk_ro(uev); -- - pthread_cleanup_push(cleanup_lock, &vecs->lock); - lock(&vecs->lock); - pthread_testcancel(); -@@ -1239,22 +1232,12 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - if (rc != 0) - strcpy(pp->wwid, wwid); - else if (strncmp(wwid, pp->wwid, WWID_SIZE) != 0) { -- condlog(0, "%s: path wwid changed from '%s' to '%s'. %s", -- uev->kernel, wwid, pp->wwid, -- (disable_changed_wwids ? "disallowing" : -- "continuing")); -- strcpy(pp->wwid, wwid); -- if (disable_changed_wwids) { -- if (!pp->wwid_changed) { -- pp->wwid_changed = 1; -- pp->tick = 1; -- if (pp->mpp) -- dm_fail_path(pp->mpp->alias, pp->dev_t); -- } -- goto out; -- } -+ condlog(0, "%s: path wwid changed from '%s' to '%s'", -+ uev->kernel, wwid, pp->wwid); -+ ev_remove_path(pp, vecs, 1); -+ needs_reinit = 1; -+ goto out; - } else { -- pp->wwid_changed = 0; - udev_device_unref(pp->udev); - pp->udev = udev_device_ref(uev->udev); - conf = get_multipath_config(); -@@ -1265,6 +1248,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - pthread_cleanup_pop(1); - } - -+ ro = uevent_get_disk_ro(uev); - if (mpp && ro >= 0) { - condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); - --- -2.17.2 - diff --git a/SOURCES/0014-RH-add-mpathconf.patch b/SOURCES/0014-RH-add-mpathconf.patch new file mode 100644 index 0000000..8917f33 --- /dev/null +++ b/SOURCES/0014-RH-add-mpathconf.patch @@ -0,0 +1,774 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 " ++ echo "" ++ echo "Commands:" ++ echo "Enable: --enable " ++ echo "Disable: --disable" ++ echo "Only allow certain wwids (instead of enable): --allow " ++ echo "Set user_friendly_names (Default y): --user_friendly_names " ++ echo "Set find_multipaths (Default y): --find_multipaths " ++ echo "Set default property blacklist (Default y): --property_blacklist " ++ echo "Set enable_foreign to show foreign devices (Default n): --enable_foreign " ++ echo "Load the dm-multipath modules on enable (Default y): --with_module " ++ echo "start/stop/reload multipathd (Default n): --with_multipathd " ++ echo "select output file (Default /etc/multipath.conf): --outfile " ++ 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\fP ++Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all ++wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\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\fP ++Write the resulting multipath configuration to \fB\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 +-- +2.17.2 + diff --git a/SOURCES/0014-multipathd-remove-wwid_changed-path-attribute.patch b/SOURCES/0014-multipathd-remove-wwid_changed-path-attribute.patch deleted file mode 100644 index 59279e5..0000000 --- a/SOURCES/0014-multipathd-remove-wwid_changed-path-attribute.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 18 Mar 2019 13:12:34 +0100 -Subject: [PATCH] multipathd: remove "wwid_changed" path attribute - -This is now not needed any more. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/structs.h | 1 - - multipathd/main.c | 6 ------ - 2 files changed, 7 deletions(-) - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index b794b0d..7879d76 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -280,7 +280,6 @@ struct path { - int fd; - int initialized; - int retriggers; -- int wwid_changed; - unsigned int path_failures; - time_t dis_reinstate_time; - int disable_reinstate; -diff --git a/multipathd/main.c b/multipathd/main.c -index b3571d9..e4f95a0 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -2001,12 +2001,6 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) - if (newstate == PATH_REMOVED) - newstate = PATH_DOWN; - -- if (pp->wwid_changed) { -- condlog(2, "%s: path wwid has changed. Refusing to use", -- pp->dev); -- newstate = PATH_DOWN; -- } -- - if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) { - condlog(2, "%s: unusable path (%s) - checker failed", - pp->dev, checker_state_name(newstate)); --- -2.17.2 - diff --git a/SOURCES/0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/SOURCES/0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch new file mode 100644 index 0000000..51be806 --- /dev/null +++ b/SOURCES/0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -0,0 +1,169 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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= 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 +--- + 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 + diff --git a/SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch b/SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch deleted file mode 100644 index 8565203..0000000 --- a/SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 18 Mar 2019 13:12:35 +0100 -Subject: [PATCH] multipathd: ignore "disable_changed_wwids" - -This option has no effect any more. - -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/config.c | 1 - - libmultipath/config.h | 1 - - libmultipath/dict.c | 18 +++++++++++++++--- - multipath/multipath.conf.5 | 8 ++------ - 4 files changed, 17 insertions(+), 11 deletions(-) - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 24d71ae..141f092 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -715,7 +715,6 @@ load_config (char * file) - conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; - conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; - conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT; -- conf->disable_changed_wwids = DEFAULT_DISABLE_CHANGED_WWIDS; - conf->remove_retries = 0; - conf->ghost_delay = DEFAULT_GHOST_DELAY; - conf->all_tg_pt = DEFAULT_ALL_TG_PT; -diff --git a/libmultipath/config.h b/libmultipath/config.h -index b938c26..f5bf5b1 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -182,7 +182,6 @@ struct config { - int delayed_reconfig; - int uev_wait_timeout; - int skip_kpartx; -- int disable_changed_wwids; - int remove_retries; - int max_sectors_kb; - int ghost_delay; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index eaad4f1..96815f8 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -156,6 +156,12 @@ out: - return len; - } - -+static int -+print_ignored (char *buff, int len) -+{ -+ return snprintf(buff, len, "ignored"); -+} -+ - static int - print_yes_no (char *buff, int len, long v) - { -@@ -548,9 +554,15 @@ declare_hw_handler(skip_kpartx, set_yes_no_undef) - declare_hw_snprint(skip_kpartx, print_yes_no_undef) - declare_mp_handler(skip_kpartx, set_yes_no_undef) - declare_mp_snprint(skip_kpartx, print_yes_no_undef) -- --declare_def_handler(disable_changed_wwids, set_yes_no) --declare_def_snprint(disable_changed_wwids, print_yes_no) -+static int def_disable_changed_wwids_handler(struct config *conf, vector strvec) -+{ -+ return 0; -+} -+static int snprint_def_disable_changed_wwids(struct config *conf, char *buff, -+ int len, const void *data) -+{ -+ return print_ignored(buff, len); -+} - - declare_def_handler(remove_retries, set_int) - declare_def_snprint(remove_retries, print_int) -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 864d7eb..646c156 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1148,12 +1148,8 @@ The default is: \fBno\fR - . - .TP - .B disable_changed_wwids --If set to \fIyes\fR, multipathd will check the path wwid on change events, and --if it has changed from the wwid of the multipath device, multipathd will --disable access to the path until the wwid changes back. --.RS --.TP --The default is: \fBno\fR -+This option is deprecated and ignored. If the WWID of a path suddenly changes, -+multipathd handles it as if it was removed and then added again. - .RE - . - . --- -2.17.2 - diff --git a/SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch b/SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch new file mode 100644 index 0000000..6835f65 --- /dev/null +++ b/SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -0,0 +1,121 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch b/SOURCES/0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch deleted file mode 100644 index 61e0f0d..0000000 --- a/SOURCES/0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 28 Mar 2019 15:17:48 -0500 -Subject: [PATCH] multipathd: Don't use fallback code after getting wwid - -The fallback code is necessary to set up mutipath devices, if multipath -temporarily can't get the information from udev. However, once the -devices are set up, udev is the definitive source of this information. - -The wwid gotten from the fallback code and the udev code should always -be the same, in which case it doesn't matter where we get the wwid -from. But if they are different, it's important to try to do the -right thing. - -Working under the assumption that udev will either never give us this -information, or that it usually will. multipath should assume that if -there are multiple paths to a device, either they will all never get -a wwid from udev, or some of them will likely already have gotten the -correct wwid from udev. In this case, we should fix this as soon as -possible. - -This does mean that devices where udev will never give out the uuid -will not notice if the wwid changes, but that's a small price to pay -for doing the right thing most of the time. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/discovery.c | 22 +++++++++------------- - libmultipath/discovery.h | 3 ++- - multipathd/main.c | 2 +- - 3 files changed, 12 insertions(+), 15 deletions(-) - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 3ec60d6..744cf2c 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1763,7 +1763,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - !strcmp(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE)) { - len = get_vpd_uid(pp); - *origin = "sysfs"; -- pp->uid_attribute = NULL; - if (len < 0 && path_state == PATH_UP) { - condlog(1, "%s: failed to get sysfs uid: %s", - pp->dev, strerror(-len)); -@@ -1787,7 +1786,6 @@ static ssize_t uid_fallback(struct path *pp, int path_state, - len = WWID_SIZE; - } - *origin = "sysfs"; -- pp->uid_attribute = NULL; - } - return len; - } -@@ -1800,12 +1798,14 @@ static int has_uid_fallback(struct path *pp) - } - - int --get_uid (struct path * pp, int path_state, struct udev_device *udev) -+get_uid (struct path * pp, int path_state, struct udev_device *udev, -+ int allow_fallback) - { - char *c; - const char *origin = "unknown"; - ssize_t len = 0; - struct config *conf; -+ int used_fallback = 0; - - if (!pp->uid_attribute && !pp->getuid) { - conf = get_multipath_config(); -@@ -1846,14 +1846,9 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - len = get_vpd_uid(pp); - origin = "sysfs"; - } -- if (len <= 0 && has_uid_fallback(pp)) { -- int retrigger_tries; -- -- conf = get_multipath_config(); -- retrigger_tries = conf->retrigger_tries; -- put_multipath_config(conf); -- if (pp->retriggers >= retrigger_tries) -- len = uid_fallback(pp, path_state, &origin); -+ if (len <= 0 && allow_fallback && has_uid_fallback(pp)) { -+ used_fallback = 1; -+ len = uid_fallback(pp, path_state, &origin); - } - } - if ( len < 0 ) { -@@ -1870,7 +1865,7 @@ get_uid (struct path * pp, int path_state, struct udev_device *udev) - c--; - } - } -- condlog(3, "%s: uid = %s (%s)", pp->dev, -+ condlog((used_fallback)? 1 : 3, "%s: uid = %s (%s)", pp->dev, - *pp->wwid == '\0' ? "" : pp->wwid, origin); - return 0; - } -@@ -1994,7 +1989,8 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - } - - if ((mask & DI_WWID) && !strlen(pp->wwid)) { -- get_uid(pp, path_state, pp->udev); -+ get_uid(pp, path_state, pp->udev, -+ (pp->retriggers >= conf->retrigger_tries)); - if (!strlen(pp->wwid)) { - if (pp->bus == SYSFS_BUS_UNDEF) - return PATHINFO_SKIPPED; -diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h -index 9aacf75..8fd126b 100644 ---- a/libmultipath/discovery.h -+++ b/libmultipath/discovery.h -@@ -52,7 +52,8 @@ ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff, - size_t len); - int sysfs_get_asymmetric_access_state(struct path *pp, - char *buff, int buflen); --int get_uid(struct path * pp, int path_state, struct udev_device *udev); -+int get_uid(struct path * pp, int path_state, struct udev_device *udev, -+ int allow_fallback); - - /* - * discovery bitmask -diff --git a/multipathd/main.c b/multipathd/main.c -index e4f95a0..1413c6d 100644 ---- a/multipathd/main.c -+++ b/multipathd/main.c -@@ -1227,7 +1227,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) - goto out; - - strcpy(wwid, pp->wwid); -- rc = get_uid(pp, pp->state, uev->udev); -+ rc = get_uid(pp, pp->state, uev->udev, 0); - - if (rc != 0) - strcpy(pp->wwid, wwid); --- -2.17.2 - diff --git a/SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch new file mode 100644 index 0000000..e48fc59 --- /dev/null +++ b/SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0017-libmultipath-silence-dm_is_mpath-error-messages.patch b/SOURCES/0017-libmultipath-silence-dm_is_mpath-error-messages.patch deleted file mode 100644 index 203ed74..0000000 --- a/SOURCES/0017-libmultipath-silence-dm_is_mpath-error-messages.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 28 Mar 2019 17:49:38 -0500 -Subject: [PATCH] libmultipath: silence dm_is_mpath error messages - -When "multipath -F" is run, dm_is_mpath was printing error messages -about partition devices, because they had already been removed, when -it checked. Lower the error logging level so this doesn't happen on -the default verbosity. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index 3294bd4..2e79667 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -746,7 +746,7 @@ out_task: - dm_task_destroy(dmt); - out: - if (r < 0) -- condlog(2, "%s: dm command failed in %s", name, __FUNCTION__); -+ condlog(3, "%s: dm command failed in %s: %s", name, __FUNCTION__, strerror(errno)); - return r; - } - --- -2.17.2 - diff --git a/SOURCES/0018-RH-Fix-nvme-compilation-warning.patch b/SOURCES/0018-RH-Fix-nvme-compilation-warning.patch new file mode 100644 index 0000000..fc6ccd7 --- /dev/null +++ b/SOURCES/0018-RH-Fix-nvme-compilation-warning.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 25 Jan 2019 14:54:56 -0600 +Subject: [PATCH] RH: Fix nvme compilation warning + +Signed-off-by: Benjamin Marzinski +--- + 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 + diff --git a/SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch deleted file mode 100644 index 6c1bf63..0000000 --- a/SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - 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 fc728ca..2f0bcea 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -48,7 +48,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 8f99049..8a3a171 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 0828a8f..b9bbb3c 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 - diff --git a/SOURCES/0019-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0019-RH-Remove-the-property-blacklist-exception-builtin.patch deleted file mode 100644 index 81c12b9..0000000 --- a/SOURCES/0019-RH-Remove-the-property-blacklist-exception-builtin.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - libmultipath/blacklist.c | 12 ++++-------- - multipath/multipath.conf.5 | 14 ++++++-------- - 2 files changed, 10 insertions(+), 16 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index e0d0279..556c0b9 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, -@@ -394,9 +388,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl) - if (udev) { - /* - * This is the inverse of the 'normal' matching; -- * the environment variable _has_ to match. -+ * the environment variable _has_ to match -+ * if a whitelist is present. - */ -- 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 646c156..768ab83 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1235,16 +1235,14 @@ keywords. Both are regular expressions. For a full description of these keywords - 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. --. --.RS --.PP --The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing --well-behaved SCSI devices and devices that provide a WWN (World Wide Number) --to be included, and all others to be excluded. --.RE -+For example, setting the property blacklist_exception to -+\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices -+that provide a WWN (World Wide Number) to be included, and all others to be -+excluded. This works to exclude most non-multipathable devices. - .TP - .B protocol - Regular expression for the protocol of a device to be excluded/included. --- -2.17.2 - diff --git a/SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch new file mode 100644 index 0000000..24c3ebd --- /dev/null +++ b/SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +--- + 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 + diff --git a/SOURCES/0020-RH-don-t-start-without-a-config-file.patch b/SOURCES/0020-RH-don-t-start-without-a-config-file.patch deleted file mode 100644 index d840c33..0000000 --- a/SOURCES/0020-RH-don-t-start-without-a-config-file.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - 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 141f092..544d2fb 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) -@@ -745,6 +746,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 f5bf5b1..8803967 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 9df11a9..0486bf7 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 94c3f97..ed13efd 100644 ---- a/multipathd/multipathd.8 -+++ b/multipathd/multipathd.8 -@@ -38,6 +38,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 ba24983..17434ce 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 - diff --git a/SOURCES/0021-RH-use-rpm-optflags-if-present.patch b/SOURCES/0021-RH-use-rpm-optflags-if-present.patch deleted file mode 100644 index 4b41d9e..0000000 --- a/SOURCES/0021-RH-use-rpm-optflags-if-present.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - Makefile.inc | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/Makefile.inc b/Makefile.inc -index 2f0bcea..b98800a 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -83,15 +83,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 - diff --git a/SOURCES/0022-RH-add-mpathconf.patch b/SOURCES/0022-RH-add-mpathconf.patch deleted file mode 100644 index afa2761..0000000 --- a/SOURCES/0022-RH-add-mpathconf.patch +++ /dev/null @@ -1,667 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - libmultipath/config.c | 2 + - multipath/Makefile | 5 + - multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 119 +++++++++++ - 4 files changed, 590 insertions(+) - create mode 100644 multipath/mpathconf - create mode 100644 multipath/mpathconf.8 - -diff --git a/libmultipath/config.c b/libmultipath/config.c -index 544d2fb..deb80c2 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -748,6 +748,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 b9bbb3c..e720c7f 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 0000000..e839134 ---- /dev/null -+++ b/multipath/mpathconf -@@ -0,0 +1,464 @@ -+#!/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 MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST -+ -+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 -+} -+ -+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 " -+ echo "" -+ echo "Commands:" -+ echo "Enable: --enable " -+ echo "Disable: --disable" -+ echo "Only allow certain wwids (instead of enable): --allow " -+ echo "Set user_friendly_names (Default y): --user_friendly_names " -+ echo "Set find_multipaths (Default y): --find_multipaths " -+ echo "Load the dm-multipath modules on enable (Default y): --with_module " -+ echo "start/stop/reload multipathd (Default n): --with_multipathd " -+ echo "select output file (Default /etc/multipath.conf): --outfile " -+ 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 -+ ;; -+ --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 "$MODULE" ]; then -+ echo "ignoring extra parameters on disable" -+ FRIENDLY="" -+ FIND="" -+ 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 [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; 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 -+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 [ -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 [ -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 0000000..5b7ae0c ---- /dev/null -+++ b/multipath/mpathconf.8 -@@ -0,0 +1,119 @@ -+.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\fP -+Modifies the \fB/etc/multipath/conf\fP blacklist to blacklist all -+wwids and the blacklist_exceptions to whitelist \fB\fP. \fB\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 aldong with any other command. -+.TP -+.B --outfile \fB\fP -+Write the resulting multipath configuration to \fB\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 --- -2.17.2 - diff --git a/SOURCES/0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/SOURCES/0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch deleted file mode 100644 index 86bb2db..0000000 --- a/SOURCES/0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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= 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 ---- - 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 53e7951..39e08cd 100644 ---- a/libmultipath/wwids.c -+++ b/libmultipath/wwids.c -@@ -443,3 +443,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 0c6ee54..e32a0b0 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 69141db..e7771c0 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -133,7 +133,7 @@ usage (char * progname) - { - fprintf (stderr, VERSION_STRING); - fprintf (stderr, "Usage:\n"); -- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); -+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); - fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); - fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); - fprintf (stderr, " %s [-t|-T]\n", progname); -@@ -147,6 +147,8 @@ usage (char * progname) - " -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" -@@ -870,7 +872,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; -@@ -940,6 +942,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 9cdd05a..8befc45 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 17434ce..0fbcc46 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 - diff --git a/SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch b/SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch deleted file mode 100644 index ded4ccb..0000000 --- a/SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - 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 96815f8..3b1b652 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) - { -@@ -1386,7 +1401,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; \ - \ -@@ -1402,7 +1417,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; \ - \ -@@ -1505,16 +1520,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 92ef7cf..4289336 100644 ---- a/libmultipath/parser.c -+++ b/libmultipath/parser.c -@@ -384,6 +384,19 @@ set_value(vector strvec) - return alloc; - } - -+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 62906e9..b791705 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 - diff --git a/SOURCES/0025-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0025-RH-reset-default-find_mutipaths-value-to-off.patch deleted file mode 100644 index 2f6bbe9..0000000 --- a/SOURCES/0025-RH-reset-default-find_mutipaths-value-to-off.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - libmultipath/defaults.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 6576939..2ad6308 100644 ---- a/libmultipath/defaults.h -+++ b/libmultipath/defaults.h -@@ -17,7 +17,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 - diff --git a/SOURCES/0026-RH-Fix-nvme-compilation-warning.patch b/SOURCES/0026-RH-Fix-nvme-compilation-warning.patch deleted file mode 100644 index 6de061a..0000000 --- a/SOURCES/0026-RH-Fix-nvme-compilation-warning.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 25 Jan 2019 14:54:56 -0600 -Subject: [PATCH] RH: Fix nvme compilation warning - -Signed-off-by: Benjamin Marzinski ---- - 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 adb192b..bfd10ef 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 - diff --git a/SOURCES/0027-Fix-systemd-version-detection.patch b/SOURCES/0027-Fix-systemd-version-detection.patch deleted file mode 100644 index 7414638..0000000 --- a/SOURCES/0027-Fix-systemd-version-detection.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Igor Gnatenko -Date: Tue, 26 Mar 2019 16:34:32 -0500 -Subject: [PATCH] Fix systemd version detection - -Signed-off-by: Igor Gnatenko -Signed-off-by: Benjamin Marzinski ---- - Makefile.inc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.inc b/Makefile.inc -index b98800a..da49852 100644 ---- a/Makefile.inc -+++ b/Makefile.inc -@@ -37,7 +37,7 @@ endif - - ifndef SYSTEMD - ifeq ($(shell systemctl --version > /dev/null 2>&1 && echo 1), 1) -- SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\)/\1/p') -+ SYSTEMD = $(shell systemctl --version 2> /dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p') - endif - endif - --- -2.17.2 - diff --git a/SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch deleted file mode 100644 index 36954ad..0000000 --- a/SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -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 ---- - 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 990d935..d84571b 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 - diff --git a/SOURCES/0029-BZ-1700451-check-on-multipathd-without-starting-it.patch b/SOURCES/0029-BZ-1700451-check-on-multipathd-without-starting-it.patch deleted file mode 100644 index e2e57c7..0000000 --- a/SOURCES/0029-BZ-1700451-check-on-multipathd-without-starting-it.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 18 Apr 2019 12:49:46 -0500 -Subject: [PATCH] BZ 1700451: check on multipathd without starting it - -When "multipath -u" is run, it checks if multipathd is running. -Currently it does this by trying to connect to the mutipathd socket. -This can cause problems during boot. The multipathd.socket systemd unit -file will cause "multipath -u" to wait until multipathd has been started -before continuing. If there is a lot of activity on the system, -multipathd may not start up immediately, causing block device -initialization to be delayed, potentially until after systemd times -waiting for the device. To avoid this, multipath now checks if -multipathd is running by reading /run/multipathd.pid and checking the -/proc//comm to verify that multipathd is really running with this -pid. This avoids forcing "multipath -u" to wait on multipathd starting -up. - -As an alternative to this patch, multipath could simply switch the order -of the calls to systemd_service_enabled() and mpath_connect(). This would -make multipath only try to connect with multipathd if it wasn't enabled in -systemd, so that it wouldn't autostart. - -Another alternative is to do away with multipathd.socket. Since multipathd -needs to always be running in order to get uevents, there isn't much value -in having it autoactivate when it gets an interactive command. - -Signed-off-by: Benjamin Marzinski ---- - multipath/main.c | 60 +++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 54 insertions(+), 6 deletions(-) - -diff --git a/multipath/main.c b/multipath/main.c -index e7771c0..632ce4d 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -852,6 +852,58 @@ out: - return r; - } - -+int is_multipathd_running(void) -+{ -+ FILE *f = NULL; -+ char buf[16]; -+ char path[PATH_MAX]; -+ int pid; -+ char *end; -+ -+ f = fopen(DEFAULT_PIDFILE, "r"); -+ if (!f) { -+ if (errno != ENOENT) -+ condlog(4, "can't open " DEFAULT_PIDFILE ": %s", -+ strerror(errno)); -+ return 0; -+ } -+ if (!fgets(buf, sizeof(buf), f)) { -+ if (ferror(f)) -+ condlog(4, "read of " DEFAULT_PIDFILE " failed: %s", -+ strerror(errno)); -+ fclose(f); -+ return 0; -+ } -+ fclose(f); -+ errno = 0; -+ strchop(buf); -+ pid = strtol(buf, &end, 10); -+ if (errno != 0 || pid <= 0 || *end != '\0') { -+ condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'", -+ buf); -+ return 0; -+ } -+ snprintf(path, sizeof(path), "/proc/%d/comm", pid); -+ f = fopen(path, "r"); -+ if (!f) { -+ if (errno != ENOENT) -+ condlog(4, "can't open %s: %s", path, strerror(errno)); -+ return 0; -+ } -+ if (!fgets(buf, sizeof(buf), f)) { -+ if (ferror(f)) -+ condlog(4, "read of %s failed: %s", path, -+ strerror(errno)); -+ fclose(f); -+ return 0; -+ } -+ fclose(f); -+ strchop(buf); -+ if (strcmp(buf, "multipathd") != 0) -+ return 0; -+ return 1; -+} -+ - int - main (int argc, char *argv[]) - { -@@ -1034,17 +1086,13 @@ main (int argc, char *argv[]) - } - if (cmd == CMD_VALID_PATH && - dev_type == DEV_UEVENT) { -- int fd; -- -- fd = mpath_connect(); -- if (fd == -1) { -+ if (!is_multipathd_running()) { - condlog(3, "%s: daemon is not running", dev); - if (!systemd_service_enabled(dev)) { - r = print_cmd_valid(RTVL_NO, NULL, conf); - goto out; - } -- } else -- mpath_disconnect(fd); -+ } - } - - if (cmd == CMD_REMOVE_WWID && !dev) { --- -2.17.2 - diff --git a/SOURCES/0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch b/SOURCES/0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch deleted file mode 100644 index 36bed26..0000000 --- a/SOURCES/0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch +++ /dev/null @@ -1,223 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Wed, 24 Apr 2019 11:07:59 +0200 -Subject: [PATCH] BZ 1700451: test socket connection in non-blocking mode - -Since commit d7188fcd "multipathd: start daemon after udev trigger", -multipathd startup is delayed during boot until after "udev settle" -terminates. But "multipath -u" is run by udev workers for storage devices, -and attempts to connect to the multipathd socket. This causes a start job -for multipathd to be scheduled by systemd, but that job won't be started -until "udev settle" finishes. This is not a problem on systems with 129 or -less storage units, because the connect() call of "multipath -u" will -succeed anyway. But on larger systems, the listen backlog of the systemd -socket can be exceeded, which causes connect() calls for the socket to -block until multipathd starts up and begins calling accept(). This creates -a deadlock situation, because "multipath -u" (called by udev workers) -blocks, and thus "udev settle" doesn't finish, delaying multipathd -startup. This situation then persists until either the workers or "udev -settle" time out. In the former case, path devices might be misclassified -as non-multipath devices by "multipath -u". - -Fix this by using a non-blocking socket fd for connect() and interpret the -errno appropriately. - -This patch reverts most of the changes from commit 8cdf6661 "multipath: -check on multipathd without starting it". Instead, "multipath -u" does -access the socket and start multipath again (which is what we want IMO), -but it is now able to detect and handle the "full backlog" situation. - -Signed-off-by: Martin Wilck - -V2: - -Use same error reporting convention in __mpath_connect() as in -mpath_connect() (Hannes Reinecke). We can't easily change the latter, -because it's part of the "public" libmpathcmd API. - -Signed-off-by: Benjamin Marzinski ---- - libmpathcmd/mpath_cmd.c | 24 +++++++++++++- - libmpathcmd/mpath_cmd.h | 15 +++++++++ - multipath/main.c | 70 +++++++++++++---------------------------- - 3 files changed, 60 insertions(+), 49 deletions(-) - -diff --git a/libmpathcmd/mpath_cmd.c b/libmpathcmd/mpath_cmd.c -index df4ca54..b681311 100644 ---- a/libmpathcmd/mpath_cmd.c -+++ b/libmpathcmd/mpath_cmd.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include "mpath_cmd.h" - -@@ -93,10 +94,11 @@ static size_t write_all(int fd, const void *buf, size_t len) - /* - * connect to a unix domain socket - */ --int mpath_connect(void) -+int __mpath_connect(int nonblocking) - { - int fd, len; - struct sockaddr_un addr; -+ int flags = 0; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_LOCAL; -@@ -108,14 +110,34 @@ int mpath_connect(void) - if (fd == -1) - return -1; - -+ if (nonblocking) { -+ flags = fcntl(fd, F_GETFL, 0); -+ if (flags != -1) -+ (void)fcntl(fd, F_SETFL, flags|O_NONBLOCK); -+ } -+ - if (connect(fd, (struct sockaddr *)&addr, len) == -1) { -+ int err = errno; -+ - close(fd); -+ errno = err; - return -1; - } - -+ if (nonblocking && flags != -1) -+ (void)fcntl(fd, F_SETFL, flags); -+ - return fd; - } - -+/* -+ * connect to a unix domain socket -+ */ -+int mpath_connect(void) -+{ -+ return __mpath_connect(0); -+} -+ - int mpath_disconnect(int fd) - { - return close(fd); -diff --git a/libmpathcmd/mpath_cmd.h b/libmpathcmd/mpath_cmd.h -index 15aeb06..ccfd35f 100644 ---- a/libmpathcmd/mpath_cmd.h -+++ b/libmpathcmd/mpath_cmd.h -@@ -34,6 +34,21 @@ extern "C" { - #define DEFAULT_REPLY_TIMEOUT 4000 - - -+/* -+ * DESCRIPTION: -+ * Same as mpath_connect() (see below) except for the "nonblocking" -+ * parameter. -+ * If "nonblocking" is set, connects in non-blocking mode. This is -+ * useful to avoid blocking if the listening socket's backlog is -+ * exceeded. In this case, errno will be set to EAGAIN. -+ * In case of success, the returned file descriptor is in in blocking -+ * mode, even if "nonblocking" was true. -+ * -+ * RETURNS: -+ * A file descriptor on success. -1 on failure (with errno set). -+ */ -+int __mpath_connect(int nonblocking); -+ - /* - * DESCRIPTION: - * Connect to the running multipathd daemon. On systems with the -diff --git a/multipath/main.c b/multipath/main.c -index 632ce4d..3fb6699 100644 ---- a/multipath/main.c -+++ b/multipath/main.c -@@ -852,55 +852,29 @@ out: - return r; - } - --int is_multipathd_running(void) -+static int test_multipathd_socket(void) - { -- FILE *f = NULL; -- char buf[16]; -- char path[PATH_MAX]; -- int pid; -- char *end; -+ int fd; -+ /* -+ * "multipath -u" may be run before the daemon is started. In this -+ * case, systemd might own the socket but might delay multipathd -+ * startup until some other unit (udev settle!) has finished -+ * starting. With many LUNs, the listen backlog may be exceeded, which -+ * would cause connect() to block. This causes udev workers calling -+ * "multipath -u" to hang, and thus creates a deadlock, until "udev -+ * settle" times out. To avoid this, call connect() in non-blocking -+ * mode here, and take EAGAIN as indication for a filled-up systemd -+ * backlog. -+ */ - -- f = fopen(DEFAULT_PIDFILE, "r"); -- if (!f) { -- if (errno != ENOENT) -- condlog(4, "can't open " DEFAULT_PIDFILE ": %s", -- strerror(errno)); -- return 0; -- } -- if (!fgets(buf, sizeof(buf), f)) { -- if (ferror(f)) -- condlog(4, "read of " DEFAULT_PIDFILE " failed: %s", -- strerror(errno)); -- fclose(f); -- return 0; -- } -- fclose(f); -- errno = 0; -- strchop(buf); -- pid = strtol(buf, &end, 10); -- if (errno != 0 || pid <= 0 || *end != '\0') { -- condlog(4, "invalid contents in " DEFAULT_PIDFILE ": '%s'", -- buf); -- return 0; -- } -- snprintf(path, sizeof(path), "/proc/%d/comm", pid); -- f = fopen(path, "r"); -- if (!f) { -- if (errno != ENOENT) -- condlog(4, "can't open %s: %s", path, strerror(errno)); -- return 0; -- } -- if (!fgets(buf, sizeof(buf), f)) { -- if (ferror(f)) -- condlog(4, "read of %s failed: %s", path, -- strerror(errno)); -- fclose(f); -- return 0; -- } -- fclose(f); -- strchop(buf); -- if (strcmp(buf, "multipathd") != 0) -- return 0; -+ fd = __mpath_connect(1); -+ if (fd == -1) { -+ if (errno == EAGAIN) -+ condlog(3, "daemon backlog exceeded"); -+ else -+ return 0; -+ } else -+ close(fd); - return 1; - } - -@@ -1086,7 +1060,7 @@ main (int argc, char *argv[]) - } - if (cmd == CMD_VALID_PATH && - dev_type == DEV_UEVENT) { -- if (!is_multipathd_running()) { -+ if (!test_multipathd_socket()) { - condlog(3, "%s: daemon is not running", dev); - if (!systemd_service_enabled(dev)) { - r = print_cmd_valid(RTVL_NO, NULL, conf); --- -2.17.2 - diff --git a/SOURCES/0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch b/SOURCES/0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch deleted file mode 100644 index cb3aa70..0000000 --- a/SOURCES/0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 16 May 2019 12:41:33 -0500 -Subject: [PATCH] libmultipath: handle clock_gettime failures in tur checker - -If clock_gettime() fails, and multipathd can't figure out when it should -time out, it should just default to assuming that it has already timed -out. Found by coverity. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/checkers/tur.c | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c -index 6b08dbb..717353e 100644 ---- a/libmultipath/checkers/tur.c -+++ b/libmultipath/checkers/tur.c -@@ -290,7 +290,12 @@ static void *tur_thread(void *ctx) - - static void tur_timeout(struct timespec *tsp) - { -- clock_gettime(CLOCK_MONOTONIC, tsp); -+ if (clock_gettime(CLOCK_MONOTONIC, tsp) != 0) { -+ /* can't get time. clear tsp to not wait */ -+ tsp->tv_sec = 0; -+ tsp->tv_nsec = 0; -+ return; -+ } - tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */ - normalize_timespec(tsp); - } -@@ -300,8 +305,12 @@ static void tur_set_async_timeout(struct checker *c) - struct tur_checker_context *ct = c->context; - struct timespec now; - -- clock_gettime(CLOCK_MONOTONIC, &now); -- ct->time = now.tv_sec + c->timeout; -+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) -+ /* can't get time. clear time to always timeout on -+ * next path check */ -+ ct->time = 0; -+ else -+ ct->time = now.tv_sec + c->timeout; - } - - static int tur_check_async_timeout(struct checker *c) -@@ -309,7 +318,9 @@ static int tur_check_async_timeout(struct checker *c) - struct tur_checker_context *ct = c->context; - struct timespec now; - -- clock_gettime(CLOCK_MONOTONIC, &now); -+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) -+ /* can't get time. assume we've timed out */ -+ return 1; - return (now.tv_sec > ct->time); - } - --- -2.17.2 - diff --git a/SOURCES/0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch b/SOURCES/0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch deleted file mode 100644 index 4b25518..0000000 --- a/SOURCES/0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 16 May 2019 12:55:16 -0500 -Subject: [PATCH] kpartx: fail if dup() of dasd file descriptor fails - -If kpartx fails to create a copy of the dasd file descriptor, it should -fail, instead of treating the error value as a valid fd. Found by -coverity. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/dasd.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kpartx/dasd.c b/kpartx/dasd.c -index 61b609a..d95d8ca 100644 ---- a/kpartx/dasd.c -+++ b/kpartx/dasd.c -@@ -138,6 +138,8 @@ read_dasd_pt(int fd, struct slice all, struct slice *sp, int ns) - return -1; - } else { - fd_dasd = dup(fd); -+ if (fd_dasd < 0) -+ return -1; - } - - if (ioctl(fd_dasd, BIODASDINFO, (unsigned long)&info) != 0) { --- -2.17.2 - diff --git a/SOURCES/0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch b/SOURCES/0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch deleted file mode 100644 index aeede71..0000000 --- a/SOURCES/0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 16 May 2019 13:31:35 -0500 -Subject: [PATCH] multipathd: fix REALLOC_REPLY with max length reply - -Commit cd5a9797e added code to REALLOC_REPLY() that intended to stop -growing the reply buffer after it reached a maximum size. However this -coded didn't stop the realloc() from happening. Worse, if the realloci() -failed, multipathd would double free the reply buffer. Found by -Coverity. - -Fixes: cd5a9797e "libmpathcmd(coverity): limit reply length" -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli.h | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/multipathd/cli.h b/multipathd/cli.h -index f3fa077..32dcffa 100644 ---- a/multipathd/cli.h -+++ b/multipathd/cli.h -@@ -100,15 +100,16 @@ enum { - if (m >= MAX_REPLY_LEN) { \ - condlog(1, "Warning: max reply length exceeded"); \ - free(tmp); \ -- r = NULL; \ -+ (r) = NULL; \ -+ } else { \ -+ (r) = REALLOC((r), (m) * 2); \ -+ if ((r)) { \ -+ memset((r) + (m), 0, (m)); \ -+ (m) *= 2; \ -+ } \ -+ else \ -+ free(tmp); \ - } \ -- (r) = REALLOC((r), (m) * 2); \ -- if ((r)) { \ -- memset((r) + (m), 0, (m)); \ -- (m) *= 2; \ -- } \ -- else \ -- free(tmp); \ - } \ - } while (0) - --- -2.17.2 - diff --git a/SOURCES/0034-multipathd-handle-NULL-return-from-genhelp_handler.patch b/SOURCES/0034-multipathd-handle-NULL-return-from-genhelp_handler.patch deleted file mode 100644 index 5cdb6f5..0000000 --- a/SOURCES/0034-multipathd-handle-NULL-return-from-genhelp_handler.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 16 May 2019 15:44:20 -0500 -Subject: [PATCH] multipathd: handle NULL return from genhelp_handler - -If parse_cmd() wasn't checking if genhelp_handler() returned NULL. It -was simply assuming that it got a string. Instead, it should just return -and error. Found by Coverity. - -Signed-off-by: Benjamin Marzinski ---- - multipathd/cli.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/multipathd/cli.c b/multipathd/cli.c -index ca176a9..17795b6 100644 ---- a/multipathd/cli.c -+++ b/multipathd/cli.c -@@ -467,6 +467,8 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) - - if (r) { - *reply = genhelp_handler(cmd, r); -+ if (*reply == NULL) -+ return EINVAL; - *len = strlen(*reply) + 1; - return 0; - } -@@ -474,9 +476,11 @@ parse_cmd (char * cmd, char ** reply, int * len, void * data, int timeout ) - h = find_handler(fingerprint(cmdvec)); - - if (!h || !h->fn) { -+ free_keys(cmdvec); - *reply = genhelp_handler(cmd, EINVAL); -+ if (*reply == NULL) -+ return EINVAL; - *len = strlen(*reply) + 1; -- free_keys(cmdvec); - return 0; - } - --- -2.17.2 - diff --git a/SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch b/SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch deleted file mode 100644 index b761baf..0000000 --- a/SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martin Wilck -Date: Mon, 18 Mar 2019 12:24:45 +0100 -Subject: [PATCH] BZ 1700911: hwtable: add Lenovo DE series - -I got this from Steven. - -Cc: Steve.Schremmer@netapp.com -Cc: NetApp RDAC team -Cc: xose.vazquez@gmail.com -Signed-off-by: Martin Wilck -Signed-off-by: Benjamin Marzinski ---- - libmultipath/hwtable.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c -index 8776411..f13591d 100644 ---- a/libmultipath/hwtable.c -+++ b/libmultipath/hwtable.c -@@ -701,6 +701,26 @@ static struct hwentry default_hw[] = { - .no_path_retry = (300 / DEFAULT_CHECKINT), - .prio_name = PRIO_ALUA, - }, -+ /* -+ * Lenovo -+ */ -+ { -+ /* -+ * DE Series -+ * -+ * Maintainer: ng-eseries-upstream-maintainers@netapp.com -+ */ -+ .vendor = "LENOVO", -+ .product = "DE_Series", -+ .bl_product = "Universal Xport", -+ .pgpolicy = GROUP_BY_PRIO, -+ .checker_name = RDAC, -+ .features = "2 pg_init_retries 50", -+ .hwhandler = "1 rdac", -+ .prio_name = PRIO_RDAC, -+ .pgfailback = -FAILBACK_IMMEDIATE, -+ .no_path_retry = 30, -+ }, - /* - * NetApp - */ --- -2.17.2 - diff --git a/SOURCES/0036-libmultipath-make-vector_foreach_slot_backwards-work.patch b/SOURCES/0036-libmultipath-make-vector_foreach_slot_backwards-work.patch deleted file mode 100644 index adf1f4f..0000000 --- a/SOURCES/0036-libmultipath-make-vector_foreach_slot_backwards-work.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 24 May 2019 17:30:07 -0500 -Subject: [PATCH] libmultipath: make vector_foreach_slot_backwards work as - expected - -All of the code that uses vector_foreach_slot_backwards() treats "i" as -the index of the entry "p", but the way it was coded, that wasn't the -case. "i" was the number of the entry counting from 1, not 0. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/vector.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libmultipath/vector.h b/libmultipath/vector.h -index 41d2b89..344dffd 100644 ---- a/libmultipath/vector.h -+++ b/libmultipath/vector.h -@@ -40,7 +40,7 @@ typedef struct _vector *vector; - #define vector_foreach_slot_after(v,p,i) \ - for (; (v) && i < VECTOR_SIZE(v) && ((p) = (v)->slot[i]); i++) - #define vector_foreach_slot_backwards(v,p,i) \ -- for (i = VECTOR_SIZE(v); i > 0 && ((p) = (v)->slot[i-1]); i--) -+ for (i = VECTOR_SIZE(v) - 1; (int)i >= 0 && ((p) = (v)->slot[i]); i--) - - #define identity(x) (x) - /* --- -2.17.2 - diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 85e1c7e..637e17a 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,52 +1,35 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath -Version: 0.8.0 -Release: 5%{?dist} +Version: 0.8.3 +Release: 3%{?dist} License: GPLv2 Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ # The source for this package was pulled from upstream's git repo. Use the # following command to generate the tarball -#curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.0;sf=tgz" -o multipath-tools-0.8.0.tgz -Source0: multipath-tools-0.8.0.tgz +#curl "https://git.opensvc.com/?p=multipath-tools/.git;a=snapshot;h=refs/tags/0.8.3;sf=tgz" -o multipath-tools-0.8.3.tgz +Source0: multipath-tools-0.8.3.tgz Source1: multipath.conf -Patch0001: 0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch -Patch0002: 0002-libmultipath-handle-existing-paths-in-marginal_path-.patch -Patch0003: 0003-multipathd-cleanup-marginal-paths-checking-timers.patch -Patch0004: 0004-libmultipath-fix-marginal-paths-queueing-errors.patch -Patch0005: 0005-libmultipath-fix-marginal_paths-nr_active-check.patch -Patch0006: 0006-multipathd-Fix-miscounting-active-paths.patch -Patch0007: 0007-multipathd-ignore-failed-wwid-recheck.patch -Patch0008: 0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch -Patch0009: 0009-multipathd-use-update_path_groups-instead-of-reload_.patch -Patch0010: 0010-multipath.conf-add-missing-options-to-man-page.patch -Patch0011: 0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch -Patch0012: 0012-libmulitpath-cleanup-uid_fallback-code.patch -Patch0013: 0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch -Patch0014: 0014-multipathd-remove-wwid_changed-path-attribute.patch -Patch0015: 0015-multipathd-ignore-disable_changed_wwids.patch -Patch0016: 0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch -Patch0017: 0017-libmultipath-silence-dm_is_mpath-error-messages.patch -Patch0018: 0018-RH-fixup-udev-rules-for-redhat.patch -Patch0019: 0019-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0020: 0020-RH-don-t-start-without-a-config-file.patch -Patch0021: 0021-RH-use-rpm-optflags-if-present.patch -Patch0022: 0022-RH-add-mpathconf.patch -Patch0023: 0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0024: 0024-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0025: 0025-RH-reset-default-find_mutipaths-value-to-off.patch -Patch0026: 0026-RH-Fix-nvme-compilation-warning.patch -Patch0027: 0027-Fix-systemd-version-detection.patch -Patch0028: 0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch -Patch0029: 0029-BZ-1700451-check-on-multipathd-without-starting-it.patch -Patch0030: 0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch -Patch0031: 0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch -Patch0032: 0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch -Patch0033: 0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch -Patch0034: 0034-multipathd-handle-NULL-return-from-genhelp_handler.patch -Patch0035: 0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch -Patch0036: 0036-libmultipath-make-vector_foreach_slot_backwards-work.patch +Patch00001: 0001-multipathd-warn-when-configuration-has-been-changed.patch +Patch00002: 0002-libmultipath-fix-leak-in-foreign-code.patch +Patch00003: 0003-Fix-leak-in-mpathpersist.patch +Patch00004: 0004-libmultipath-remove-unused-path-prio_args.patch +Patch00005: 0005-libmultipath-constify-get_unaligned_be.patch +Patch00006: 0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch +Patch00007: 0007-libmultipath-fix-sgio_get_vpd-looping.patch +Patch00008: 0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch +Patch00009: 0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch +Patch00010: 0010-RH-fixup-udev-rules-for-redhat.patch +Patch00011: 0011-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch00012: 0012-RH-don-t-start-without-a-config-file.patch +Patch00013: 0013-RH-use-rpm-optflags-if-present.patch +Patch00014: 0014-RH-add-mpathconf.patch +Patch00015: 0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch00016: 0016-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch00017: 0017-RH-reset-default-find_mutipaths-value-to-off.patch +Patch00018: 0018-RH-Fix-nvme-compilation-warning.patch +Patch00019: 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -124,7 +107,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%autosetup -n multipath-tools-0.8.0 -p1 +%autosetup -n multipath-tools-0.8.3 -p1 cp %{SOURCE1} . %build @@ -248,6 +231,42 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Fri Nov 8 2019 Benjamin Marzinski 0.8.3-3 +- Rename files + * Previous patches 0004-0013 are now 0010-0019 + * 0014-RH-add-mpathconf.patch now makes mpathconf default to not + printing foreign devices (bz #1760709) +- Add 0004-libmultipath-remove-unused-path-prio_args.patch +- Add 0005-libmultipath-constify-get_unaligned_be.patch +- Add 0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch +- Add 0007-libmultipath-fix-sgio_get_vpd-looping.patch +- Add 0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch +- Add 0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch + * Add the '%g' maps and paths format wildcard, and the vpd_vendor + multipath.conf devices section parameter. (bz #1527212) +- Resolves: bz #1527212, #1760709 + +* Mon Oct 14 2019 Benjamin Marzinski 0.8.3-2 +- Update CI tests +- Related: bz #1690515 + +* Tue Oct 8 2019 Benjamin Marzinski 0.8.3-1 +- Update Source to upstream version 0.8.3 + * This version includes the fixes for bz #1690515, #1703439, + #1719562 & #1747534 + * Previous patches 0001-0017 & 0031-0036 are included in this version +- Rename files + * Previous patches 0018-0026 & 0028 are now 0004-0013 + * 0008-RH-add-mpathconf.patch has been modified to add a + --property_blacklist option to fix bz #1753729 +- Add 0001-multipathd-warn-when-configuration-has-been-changed.patch + * Multipath now logs a warning message when the configuration file + has been changed to fix bz #1750594 +- Add 0002-libmultipath-fix-leak-in-foreign-code.patch +- Add 0003-Fix-leak-in-mpathpersist.patch + * The above 3 patches have been submitted upstream +- Resolves: bz #1690515, #1703439, #1719562, #1747534, #1750594, #1753729 + * Mon Jun 3 2019 Benjamin Marzinski 0.8.0-5 - Bump release number for test fix commit 0b68e623 - Related: bz #1666322