From 6ef0bbb6c3c98a0e632f8ce1d797271d99c6047b Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 21 Jan 2020 17:50:29 -0500 Subject: [PATCH] import device-mapper-multipath-0.8.3-3.el8 --- .device-mapper-multipath.metadata | 2 +- .gitignore | 2 +- ...sable-user_friendly_names-for-NetApp.patch | 31 -- ...-when-configuration-has-been-changed.patch | 277 ++++++++++++++ ...ibmultipath-fix-leak-in-foreign-code.patch | 59 +++ ...dle-existing-paths-in-marginal_path-.patch | 49 --- SOURCES/0003-Fix-leak-in-mpathpersist.patch | 28 ++ ...eanup-marginal-paths-checking-timers.patch | 70 ---- ...h-fix-marginal-paths-queueing-errors.patch | 176 --------- ...ltipath-remove-unused-path-prio_args.patch | 25 ++ ...bmultipath-constify-get_unaligned_be.patch | 34 ++ ...h-fix-marginal_paths-nr_active-check.patch | 30 -- ...-add-missing-hwe-mpe-variable-merges.patch | 49 +++ ...tipathd-Fix-miscounting-active-paths.patch | 92 ----- ...ibmultipath-fix-sgio_get_vpd-looping.patch | 204 ++++++++++ ...ultipathd-ignore-failed-wwid-recheck.patch | 71 ---- ...ultipath-add-vend_id-to-get_vpd_sgio.patch | 116 ++++++ ...inue-to-use-old-state-on-PATH_PENDIN.patch | 47 --- ...-code-to-get-vendor-specific-vpd-dat.patch | 350 ++++++++++++++++++ ...pdate_path_groups-instead-of-reload_.patch | 76 ---- ...0010-RH-fixup-udev-rules-for-redhat.patch} | 8 +- ...conf-add-missing-options-to-man-page.patch | 56 --- ...roperty-blacklist-exception-builtin.patch} | 69 ++-- ...-get_uid-fallback-code-for-NVMe-devi.patch | 90 ----- ...H-don-t-start-without-a-config-file.patch} | 14 +- ...bmulitpath-cleanup-uid_fallback-code.patch | 129 ------- ...0013-RH-use-rpm-optflags-if-present.patch} | 4 +- ...e-changed-wwids-by-removal-and-addit.patch | 83 ----- ...conf.patch => 0014-RH-add-mpathconf.patch} | 135 ++++++- ...d-remove-wwid_changed-path-attribute.patch | 46 --- ...m-kernel-cmdline-mpath.wwids-with-A.patch} | 36 +- ...tipathd-ignore-disable_changed_wwids.patch | 98 ----- ...on-invalid-regex-instead-of-failing.patch} | 16 +- ...-use-fallback-code-after-getting-wwi.patch | 135 ------- ...default-find_mutipaths-value-to-off.patch} | 4 +- ...h-silence-dm_is_mpath-error-messages.patch | 31 -- ...018-RH-Fix-nvme-compilation-warning.patch} | 2 +- ...mpt-to-get-ANA-info-via-sysfs-first.patch} | 2 +- .../0027-Fix-systemd-version-detection.patch | 27 -- ...ck-on-multipathd-without-starting-it.patch | 118 ------ ...socket-connection-in-non-blocking-mo.patch | 223 ----------- ...dle-clock_gettime-failures-in-tur-ch.patch | 61 --- ...if-dup-of-dasd-file-descriptor-fails.patch | 30 -- ...-REALLOC_REPLY-with-max-length-reply.patch | 49 --- ...dle-NULL-return-from-genhelp_handler.patch | 43 --- ...1700911-hwtable-add-Lenovo-DE-series.patch | 50 --- ...e-vector_foreach_slot_backwards-work.patch | 31 -- SPECS/device-mapper-multipath.spec | 101 +++-- 48 files changed, 1415 insertions(+), 2064 deletions(-) delete mode 100644 SOURCES/0001-BZ-1668693-disable-user_friendly_names-for-NetApp.patch create mode 100644 SOURCES/0001-multipathd-warn-when-configuration-has-been-changed.patch create mode 100644 SOURCES/0002-libmultipath-fix-leak-in-foreign-code.patch delete mode 100644 SOURCES/0002-libmultipath-handle-existing-paths-in-marginal_path-.patch create mode 100644 SOURCES/0003-Fix-leak-in-mpathpersist.patch delete mode 100644 SOURCES/0003-multipathd-cleanup-marginal-paths-checking-timers.patch delete mode 100644 SOURCES/0004-libmultipath-fix-marginal-paths-queueing-errors.patch create mode 100644 SOURCES/0004-libmultipath-remove-unused-path-prio_args.patch create mode 100644 SOURCES/0005-libmultipath-constify-get_unaligned_be.patch delete mode 100644 SOURCES/0005-libmultipath-fix-marginal_paths-nr_active-check.patch create mode 100644 SOURCES/0006-libmultipath-add-missing-hwe-mpe-variable-merges.patch delete mode 100644 SOURCES/0006-multipathd-Fix-miscounting-active-paths.patch create mode 100644 SOURCES/0007-libmultipath-fix-sgio_get_vpd-looping.patch delete mode 100644 SOURCES/0007-multipathd-ignore-failed-wwid-recheck.patch create mode 100644 SOURCES/0008-libmultipath-add-vend_id-to-get_vpd_sgio.patch delete mode 100644 SOURCES/0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch create mode 100644 SOURCES/0009-libmultipath-add-code-to-get-vendor-specific-vpd-dat.patch delete mode 100644 SOURCES/0009-multipathd-use-update_path_groups-instead-of-reload_.patch rename SOURCES/{0018-RH-fixup-udev-rules-for-redhat.patch => 0010-RH-fixup-udev-rules-for-redhat.patch} (94%) delete mode 100644 SOURCES/0010-multipath.conf-add-missing-options-to-man-page.patch rename SOURCES/{0019-RH-Remove-the-property-blacklist-exception-builtin.patch => 0011-RH-Remove-the-property-blacklist-exception-builtin.patch} (57%) delete mode 100644 SOURCES/0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch rename SOURCES/{0020-RH-don-t-start-without-a-config-file.patch => 0012-RH-don-t-start-without-a-config-file.patch} (93%) delete mode 100644 SOURCES/0012-libmulitpath-cleanup-uid_fallback-code.patch rename SOURCES/{0021-RH-use-rpm-optflags-if-present.patch => 0013-RH-use-rpm-optflags-if-present.patch} (96%) delete mode 100644 SOURCES/0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch rename SOURCES/{0022-RH-add-mpathconf.patch => 0014-RH-add-mpathconf.patch} (79%) delete mode 100644 SOURCES/0014-multipathd-remove-wwid_changed-path-attribute.patch rename SOURCES/{0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch} (83%) delete mode 100644 SOURCES/0015-multipathd-ignore-disable_changed_wwids.patch rename SOURCES/{0024-RH-warn-on-invalid-regex-instead-of-failing.patch => 0016-RH-warn-on-invalid-regex-instead-of-failing.patch} (90%) delete mode 100644 SOURCES/0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch rename SOURCES/{0025-RH-reset-default-find_mutipaths-value-to-off.patch => 0017-RH-reset-default-find_mutipaths-value-to-off.patch} (95%) delete mode 100644 SOURCES/0017-libmultipath-silence-dm_is_mpath-error-messages.patch rename SOURCES/{0026-RH-Fix-nvme-compilation-warning.patch => 0018-RH-Fix-nvme-compilation-warning.patch} (96%) rename SOURCES/{0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch => 0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch} (98%) delete mode 100644 SOURCES/0027-Fix-systemd-version-detection.patch delete mode 100644 SOURCES/0029-BZ-1700451-check-on-multipathd-without-starting-it.patch delete mode 100644 SOURCES/0030-BZ-1700451-test-socket-connection-in-non-blocking-mo.patch delete mode 100644 SOURCES/0031-libmultipath-handle-clock_gettime-failures-in-tur-ch.patch delete mode 100644 SOURCES/0032-kpartx-fail-if-dup-of-dasd-file-descriptor-fails.patch delete mode 100644 SOURCES/0033-multipathd-fix-REALLOC_REPLY-with-max-length-reply.patch delete mode 100644 SOURCES/0034-multipathd-handle-NULL-return-from-genhelp_handler.patch delete mode 100644 SOURCES/0035-BZ-1700911-hwtable-add-Lenovo-DE-series.patch delete mode 100644 SOURCES/0036-libmultipath-make-vector_foreach_slot_backwards-work.patch 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/0018-RH-fixup-udev-rules-for-redhat.patch b/SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch similarity index 94% rename from SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch rename to SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch index 6c1bf63..d560bc4 100644 --- a/SOURCES/0018-RH-fixup-udev-rules-for-redhat.patch +++ b/SOURCES/0010-RH-fixup-udev-rules-for-redhat.patch @@ -15,10 +15,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index fc728ca..2f0bcea 100644 +index 56c3eda0..2e8946ca 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -48,7 +48,7 @@ endif +@@ -53,7 +53,7 @@ endif prefix = exec_prefix = $(prefix) usr_prefix = $(prefix) @@ -28,7 +28,7 @@ index fc728ca..2f0bcea 100644 udevrulesdir = $(libudevdir)/rules.d multipathdir = $(TOPDIR)/libmultipath diff --git a/kpartx/kpartx.rules b/kpartx/kpartx.rules -index 8f99049..8a3a171 100644 +index 8f990494..8a3a1718 100644 --- a/kpartx/kpartx.rules +++ b/kpartx/kpartx.rules @@ -32,6 +32,6 @@ LABEL="mpath_kpartx_end" @@ -40,7 +40,7 @@ index 8f99049..8a3a171 100644 LABEL="kpartx_end" diff --git a/multipath/Makefile b/multipath/Makefile -index 0828a8f..b9bbb3c 100644 +index 0828a8f7..b9bbb3cf 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -24,7 +24,7 @@ install: 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/0019-RH-Remove-the-property-blacklist-exception-builtin.patch b/SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 57% rename from SOURCES/0019-RH-Remove-the-property-blacklist-exception-builtin.patch rename to SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch index 81c12b9..8aaabc7 100644 --- a/SOURCES/0019-RH-Remove-the-property-blacklist-exception-builtin.patch +++ b/SOURCES/0011-RH-Remove-the-property-blacklist-exception-builtin.patch @@ -13,12 +13,13 @@ it. Signed-off-by: Benjamin Marzinski --- - libmultipath/blacklist.c | 12 ++++-------- - multipath/multipath.conf.5 | 14 ++++++-------- - 2 files changed, 10 insertions(+), 16 deletions(-) + libmultipath/blacklist.c | 9 ++------- + multipath/multipath.conf.5 | 11 ++++++----- + tests/blacklist.c | 6 ++---- + 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index e0d0279..556c0b9 100644 +index 00e8dbdb..d9691b17 100644 --- a/libmultipath/blacklist.c +++ b/libmultipath/blacklist.c @@ -204,12 +204,6 @@ setup_default_blist (struct config * conf) @@ -34,14 +35,10 @@ index e0d0279..556c0b9 100644 vector_foreach_slot (conf->hwtable, hwe, i) { if (hwe->bl_product) { if (find_blacklist_device(conf->blist_device, -@@ -394,9 +388,11 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl) - if (udev) { - /* - * This is the inverse of the 'normal' matching; -- * the environment variable _has_ to match. -+ * the environment variable _has_ to match -+ * if a whitelist is present. - */ +@@ -411,7 +405,8 @@ filter_property(struct config *conf, struct udev_device *udev, int lvl, + *uid_attribute != '\0'; + bool uid_attr_seen = false; + - r = MATCH_PROPERTY_BLIST_MISSING; + if (VECTOR_SIZE(conf->elist_property)) + r = MATCH_PROPERTY_BLIST_MISSING; @@ -49,10 +46,10 @@ index e0d0279..556c0b9 100644 udev_device_get_properties_list_entry(udev)) { diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index 646c156..768ab83 100644 +index dc103fd8..b8697d47 100644 --- a/multipath/multipath.conf.5 +++ b/multipath/multipath.conf.5 -@@ -1235,16 +1235,14 @@ keywords. Both are regular expressions. For a full description of these keywords +@@ -1285,9 +1285,14 @@ keywords. Both are regular expressions. For a full description of these keywords Regular expression for an udev property. All devices that have matching udev properties will be excluded/included. The handling of the \fIproperty\fR keyword is special, @@ -61,20 +58,48 @@ index 646c156..768ab83 100644 +least one whitelisted udev property; otherwise they're treated as blacklisted, and the message "\fIblacklisted, udev property missing\fR" is displayed in the logs. --. --.RS --.PP --The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing --well-behaved SCSI devices and devices that provide a WWN (World Wide Number) --to be included, and all others to be excluded. --.RE +For example, setting the property blacklist_exception to +\fB(SCSI_IDENT_|ID_WWN)\fR, will cause well-behaved SCSI devices and devices +that provide a WWN (World Wide Number) to be included, and all others to be +excluded. This works to exclude most non-multipathable devices. + . + .RS + .PP +@@ -1298,10 +1303,6 @@ Blacklisting by missing properties is only applied to devices which do have the + property specified by \fIuid_attribute\fR (e.g. \fIID_SERIAL\fR) + set. Previously, it was applied to every device, possibly causing devices to be + blacklisted because of temporary I/O error conditions. +-.PP +-The default \fIblacklist exception\fR is: \fB(SCSI_IDENT_|ID_WWN)\fR, causing +-well-behaved SCSI devices and devices that provide a WWN (World Wide Number) +-to be included, and all others to be excluded. + .RE .TP .B protocol - Regular expression for the protocol of a device to be excluded/included. +diff --git a/tests/blacklist.c b/tests/blacklist.c +index 362c44d9..ea284939 100644 +--- a/tests/blacklist.c ++++ b/tests/blacklist.c +@@ -291,7 +291,7 @@ static void test_property_missing(void **state) + conf.blist_property = blist_property_wwn; + expect_condlog(3, "sdb: blacklisted, udev property missing\n"); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_SERIAL"), +- MATCH_PROPERTY_BLIST_MISSING); ++ MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, "ID_BLAH"), + MATCH_NOTHING); + assert_int_equal(filter_property(&conf, &udev, 3, ""), +@@ -383,9 +383,7 @@ static void test_filter_path_missing1(void **state) + conf.blist_device = blist_device_foo_bar; + conf.blist_protocol = blist_protocol_fcp; + conf.blist_wwid = blist_wwid_xyzzy; +- expect_condlog(3, "sdb: blacklisted, udev property missing\n"); +- assert_int_equal(filter_path(&conf, &miss1_pp), +- MATCH_PROPERTY_BLIST_MISSING); ++ assert_int_equal(filter_path(&conf, &miss1_pp), MATCH_NOTHING); + } + + /* This one matches the property whitelist, to test the other missing -- 2.17.2 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/0020-RH-don-t-start-without-a-config-file.patch b/SOURCES/0012-RH-don-t-start-without-a-config-file.patch similarity index 93% rename from SOURCES/0020-RH-don-t-start-without-a-config-file.patch rename to SOURCES/0012-RH-don-t-start-without-a-config-file.patch index d840c33..e98296e 100644 --- a/SOURCES/0020-RH-don-t-start-without-a-config-file.patch +++ b/SOURCES/0012-RH-don-t-start-without-a-config-file.patch @@ -20,7 +20,7 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 20 insertions(+) diff --git a/libmultipath/config.c b/libmultipath/config.c -index 141f092..544d2fb 100644 +index 72b8d37c..4032c4c4 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c @@ -26,6 +26,7 @@ @@ -31,7 +31,7 @@ index 141f092..544d2fb 100644 static int hwe_strmatch (const struct hwentry *hwe1, const struct hwentry *hwe2) -@@ -745,6 +746,20 @@ load_config (char * file) +@@ -755,6 +756,20 @@ load_config (char * file) goto out; } factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); @@ -53,7 +53,7 @@ index 141f092..544d2fb 100644 conf->processed_main_config = 1; diff --git a/libmultipath/config.h b/libmultipath/config.h -index f5bf5b1..8803967 100644 +index 589146de..2adbd077 100644 --- a/libmultipath/config.h +++ b/libmultipath/config.h @@ -9,6 +9,7 @@ @@ -65,7 +65,7 @@ index f5bf5b1..8803967 100644 /* * In kernel, fast_io_fail == 0 means immediate failure on rport delete. diff --git a/multipath/multipath.rules b/multipath/multipath.rules -index 9df11a9..0486bf7 100644 +index 9df11a95..0486bf70 100644 --- a/multipath/multipath.rules +++ b/multipath/multipath.rules @@ -9,6 +9,7 @@ IMPORT{cmdline}="nompath" @@ -77,10 +77,10 @@ index 9df11a9..0486bf7 100644 ENV{DEVTYPE}!="partition", GOTO="test_dev" IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH" diff --git a/multipathd/multipathd.8 b/multipathd/multipathd.8 -index 94c3f97..ed13efd 100644 +index 048a838d..8bd47a80 100644 --- a/multipathd/multipathd.8 +++ b/multipathd/multipathd.8 -@@ -38,6 +38,8 @@ map regains its maximum performance and redundancy. +@@ -39,6 +39,8 @@ map regains its maximum performance and redundancy. This daemon executes the external \fBmultipath\fR tool when events occur. In turn, the multipath tool signals the multipathd daemon when it is done with devmap reconfiguration, so that it can refresh its failed path list. @@ -90,7 +90,7 @@ index 94c3f97..ed13efd 100644 . .\" ---------------------------------------------------------------------------- diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index ba24983..17434ce 100644 +index ba24983e..17434cef 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -4,6 +4,7 @@ Wants=systemd-udev-trigger.service systemd-udev-settle.service 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/0021-RH-use-rpm-optflags-if-present.patch b/SOURCES/0013-RH-use-rpm-optflags-if-present.patch similarity index 96% rename from SOURCES/0021-RH-use-rpm-optflags-if-present.patch rename to SOURCES/0013-RH-use-rpm-optflags-if-present.patch index 4b41d9e..2234168 100644 --- a/SOURCES/0021-RH-use-rpm-optflags-if-present.patch +++ b/SOURCES/0013-RH-use-rpm-optflags-if-present.patch @@ -13,10 +13,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 2f0bcea..b98800a 100644 +index 2e8946ca..1b2f47a8 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -83,15 +83,23 @@ TEST_CC_OPTION = $(shell \ +@@ -88,15 +88,23 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) 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/0022-RH-add-mpathconf.patch b/SOURCES/0014-RH-add-mpathconf.patch similarity index 79% rename from SOURCES/0022-RH-add-mpathconf.patch rename to SOURCES/0014-RH-add-mpathconf.patch index afa2761..8917f33 100644 --- a/SOURCES/0022-RH-add-mpathconf.patch +++ b/SOURCES/0014-RH-add-mpathconf.patch @@ -14,17 +14,17 @@ Signed-off-by: Benjamin Marzinski --- libmultipath/config.c | 2 + multipath/Makefile | 5 + - multipath/mpathconf | 464 ++++++++++++++++++++++++++++++++++++++++++ - multipath/mpathconf.8 | 119 +++++++++++ - 4 files changed, 590 insertions(+) + multipath/mpathconf | 555 ++++++++++++++++++++++++++++++++++++++++++ + multipath/mpathconf.8 | 135 ++++++++++ + 4 files changed, 697 insertions(+) create mode 100644 multipath/mpathconf create mode 100644 multipath/mpathconf.8 diff --git a/libmultipath/config.c b/libmultipath/config.c -index 544d2fb..deb80c2 100644 +index 4032c4c4..2c32acf7 100644 --- a/libmultipath/config.c +++ b/libmultipath/config.c -@@ -748,6 +748,8 @@ load_config (char * file) +@@ -758,6 +758,8 @@ load_config (char * file) factorize_hwtable(conf->hwtable, builtin_hwtable_size, file); } else { condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); @@ -34,7 +34,7 @@ index 544d2fb..deb80c2 100644 conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { diff --git a/multipath/Makefile b/multipath/Makefile -index b9bbb3c..e720c7f 100644 +index b9bbb3cf..e720c7f6 100644 --- a/multipath/Makefile +++ b/multipath/Makefile @@ -18,10 +18,12 @@ $(EXEC): $(OBJS) $(multipathdir)/libmultipath.so $(mpathcmddir)/libmpathcmd.so @@ -69,10 +69,10 @@ index b9bbb3c..e720c7f 100644 $(RM) core *.o $(EXEC) *.gz diff --git a/multipath/mpathconf b/multipath/mpathconf new file mode 100644 -index 0000000..e839134 +index 00000000..f34003c9 --- /dev/null +++ b/multipath/mpathconf -@@ -0,0 +1,464 @@ +@@ -0,0 +1,555 @@ +#!/bin/bash +# +# Copyright (C) 2010 Red Hat, Inc. All rights reserved. @@ -92,7 +92,7 @@ index 0000000..e839134 +# This program was largely ripped off from lvmconf +# + -+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST ++unset ENABLE FIND FRIENDLY PROPERTY FOREIGN MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_PROPERTY HAVE_FOREIGN HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST + +DEFAULT_CONFIG="# device-mapper-multipath configuration file + @@ -107,6 +107,7 @@ index 0000000..e839134 +defaults { + user_friendly_names yes + find_multipaths yes ++ enable_foreign \"^$\" +} + +blacklist_exceptions { @@ -129,6 +130,8 @@ index 0000000..e839134 + echo "Only allow certain wwids (instead of enable): --allow " + 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 " @@ -230,6 +233,24 @@ index 0000000..e839134 + exit 1 + fi + ;; ++ --property_blacklist) ++ if [ -n "$2" ]; then ++ PROPERTY=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; ++ --enable_foreign) ++ if [ -n "$2" ]; then ++ FOREIGN=$2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --with_module) + if [ -n "$2" ]; then + MODULE=$2 @@ -267,10 +288,11 @@ index 0000000..e839134 + +function validate_args +{ -+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then ++ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$PROPERTY" -o -n "$MODULE" ]; then + echo "ignoring extra parameters on disable" + FRIENDLY="" + FIND="" ++ PROPERTY="" + MODULE="" + fi + if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then @@ -281,7 +303,15 @@ index 0000000..e839134 + echo "--find_multipaths must be either 'y' or 'n'" + exit 1 + fi -+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then ++ if [ -n "$PROPERTY" ] && [ "$PROPERTY" != "y" -a "$PROPERTY" != "n" ]; then ++ echo "--property_blacklist must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "y" -a "$FOREIGN" != "n" ]; then ++ echo "--enable_foreign must be either 'y' or 'n'" ++ exit 1 ++ fi ++ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" -a -z "$PROPERTY" ]; then + SHOW_STATUS=1 + fi + if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then @@ -382,6 +412,21 @@ index 0000000..e839134 + elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then + HAVE_FRIENDLY=0 + fi ++ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=0 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign[[:space:]]*\"\^\$\"" ; then ++ HAVE_FOREIGN=1 ++ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*enable_foreign" ; then ++ HAVE_FOREIGN=2 ++ fi ++fi ++ ++if [ "$HAVE_EXCEPTIONS" = "1" ]; then ++ if sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=1 ++ elif sed -n '/^blacklist_exceptions[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"" ; then ++ HAVE_PROPERTY=0 ++ fi +fi + +if [ -n "$SHOW_STATUS" ]; then @@ -400,6 +445,18 @@ index 0000000..e839134 + else + echo "user_friendly_names is enabled" + fi ++ if [ -z "$HAVE_PROPERTY" -o "$HAVE_PROPERTY" = 0 ]; then ++ echo "default property blacklist is disabled" ++ else ++ echo "default property blacklist is enabled" ++ fi ++ if [ -z "$HAVE_FOREIGN" -o "$HAVE_FOREIGN" = 0 ]; then ++ echo "enable_foreign is not set (all foreign multipath devices will be shown)" ++ elif [ "$HAVE_FOREIGN" = 1 ]; then ++ echo "enable_foreign is set (no foreign multipath devices will be shown)" ++ else ++ echo "enable_foreign is set (foreign multipath devices may not be shown)" ++ fi + if [ -n "$HAVE_MODULE" ]; then + if [ "$HAVE_MODULE" = 1 ]; then + echo "dm_multipath module is loaded" @@ -507,6 +564,40 @@ index 0000000..e839134 + fi +fi + ++if [ "$PROPERTY" = "n" ]; then ++ if [ "$HAVE_PROPERTY" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/# property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$PROPERTY" = "y" ]; then ++ if [ -z "$HAVE_PROPERTY" ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/ a\ ++ property "(SCSI_IDENT_|ID_WWN)" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_PROPERTY" = 0 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*property[[:space:]]*\"(SCSI_IDENT_|ID_WWN)\"/ property \"(SCSI_IDENT_|ID_WWN)\"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ ++if [ "$FOREIGN" = "y" ]; then ++ if [ "$HAVE_FOREIGN" = 1 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*enable_foreign/# enable_foreign/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++elif [ "$FOREIGN" = "n" ]; then ++ if [ -z "$HAVE_FOREIGN" ]; then ++ sed -i '/^defaults[[:space:]]*{/ a\ ++ enable_foreign "^$" ++' $TMPFILE ++ CHANGED_CONFIG=1 ++ elif [ "$HAVE_FOREIGN" = 0 -o "$HAVE_FOREIGN" = 2 ]; then ++ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*#\?[[:space:]]*enable_foreign.*$/ enable_foreign "^$"/' $TMPFILE ++ CHANGED_CONFIG=1 ++ fi ++fi ++ +if [ -f "$OUTPUTFILE" ]; then + cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then @@ -539,10 +630,10 @@ index 0000000..e839134 +fi diff --git a/multipath/mpathconf.8 b/multipath/mpathconf.8 new file mode 100644 -index 0000000..5b7ae0c +index 00000000..7937ea05 --- /dev/null +++ b/multipath/mpathconf.8 -@@ -0,0 +1,119 @@ +@@ -0,0 +1,135 @@ +.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual" +.SH NAME +mpathconf - A tool for configuring device-mapper-multipath @@ -628,7 +719,23 @@ index 0000000..5b7ae0c +to the +.B /etc/multipath.conf +defaults section. If set to \fBn\fP, this removes the line, if present. This -+command can be used aldong with any other command. ++command can be used along with any other command. ++.TP ++.B --property_blacklist \fP { \fBy\fP | \fBn\fP } ++If set to \fBy\fP, this adds the line ++.B property "(SCSI_IDENT_|ID_WWN)" ++to the ++.B /etc/multipath.conf ++blacklist_exceptions section. If set to \fBn\fP, this removes the line, if ++present. This command can be used along with any other command. ++.TP ++.B --enable_foreign\fP { \fBy\fP | \fBn\fP } ++If set to \fBn\fP, this adds the line ++.B enable_foreign "^$" ++to the ++.B /etc/multipath.conf ++defaults section. if set to \fBy\fP, this removes the line, if present. This ++command can be used along with any other command. +.TP +.B --outfile \fB\fP +Write the resulting multipath configuration to \fB\fP instead of 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/0023-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 similarity index 83% rename from SOURCES/0023-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to SOURCES/0015-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index 86bb2db..51be806 100644 --- a/SOURCES/0023-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 @@ -22,10 +22,10 @@ Signed-off-by: Benjamin Marzinski 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/libmultipath/wwids.c b/libmultipath/wwids.c -index 53e7951..39e08cd 100644 +index ef748125..349da8b7 100644 --- a/libmultipath/wwids.c +++ b/libmultipath/wwids.c -@@ -443,3 +443,47 @@ int op ## _wwid(const char *wwid) \ +@@ -444,3 +444,47 @@ int op ## _wwid(const char *wwid) \ declare_failed_wwid_op(is_failed, false) declare_failed_wwid_op(mark_failed, true) declare_failed_wwid_op(unmark_failed, true) @@ -74,7 +74,7 @@ index 53e7951..39e08cd 100644 + return ret; +} diff --git a/libmultipath/wwids.h b/libmultipath/wwids.h -index 0c6ee54..e32a0b0 100644 +index 0c6ee54d..e32a0b0e 100644 --- a/libmultipath/wwids.h +++ b/libmultipath/wwids.h @@ -17,6 +17,7 @@ int remember_wwid(char *wwid); @@ -86,19 +86,19 @@ index 0c6ee54..e32a0b0 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index 69141db..e7771c0 100644 +index 4f4d8e89..22aff7be 100644 --- a/multipath/main.c +++ b/multipath/main.c -@@ -133,7 +133,7 @@ usage (char * progname) - { - fprintf (stderr, VERSION_STRING); - fprintf (stderr, "Usage:\n"); -- fprintf (stderr, " %s [-a|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); -+ fprintf (stderr, " %s [-a|-A|-c|-w|-W] [-d] [-r] [-i] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname); - fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [-R num] [dev]\n", progname); - fprintf (stderr, " %s -F [-v lvl] [-R num]\n", progname); - fprintf (stderr, " %s [-t|-T]\n", progname); -@@ -147,6 +147,8 @@ usage (char * progname) +@@ -138,7 +138,7 @@ usage (char * progname) + fprintf (stderr, " %s [-v level] [-R retries] -F\n", progname); + fprintf (stderr, " %s [-v level] [-l|-ll] [device]\n", progname); + fprintf (stderr, " %s [-v level] [-a|-w] device\n", progname); +- fprintf (stderr, " %s [-v level] -W\n", progname); ++ fprintf (stderr, " %s [-v level] [-A|-W]\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-c|-C] device\n", progname); + fprintf (stderr, " %s [-v level] [-i] [-u|-U]\n", progname); + fprintf (stderr, " %s [-h|-t|-T]\n", progname); +@@ -151,6 +151,8 @@ usage (char * progname) " -f flush a multipath device map\n" " -F flush all multipath device maps\n" " -a add a device wwid to the wwids file\n" @@ -107,7 +107,7 @@ index 69141db..e7771c0 100644 " -c check if a device should be a path in a multipath device\n" " -C check if a multipath device has usable paths\n" " -q allow queue_if_no_path when multipathd is not running\n" -@@ -870,7 +872,7 @@ main (int argc, char *argv[]) +@@ -905,7 +907,7 @@ main (int argc, char *argv[]) exit(RTVL_FAIL); multipath_conf = conf; conf->retrigger_tries = 0; @@ -116,7 +116,7 @@ index 69141db..e7771c0 100644 switch(arg) { case 1: printf("optarg : %s\n",optarg); break; -@@ -940,6 +942,10 @@ main (int argc, char *argv[]) +@@ -975,6 +977,10 @@ main (int argc, char *argv[]) case 'T': cmd = CMD_DUMP_CONFIG; break; @@ -128,7 +128,7 @@ index 69141db..e7771c0 100644 usage(argv[0]); exit(RTVL_OK); diff --git a/multipath/multipath.8 b/multipath/multipath.8 -index 9cdd05a..8befc45 100644 +index 9cdd05a3..8befc45a 100644 --- a/multipath/multipath.8 +++ b/multipath/multipath.8 @@ -63,7 +63,7 @@ multipath \- Device mapper target autoconfig. @@ -153,7 +153,7 @@ index 9cdd05a..8befc45 100644 Remove the WWID for the specified device from the WWIDs file. . diff --git a/multipathd/multipathd.service b/multipathd/multipathd.service -index 17434ce..0fbcc46 100644 +index 17434cef..0fbcc46b 100644 --- a/multipathd/multipathd.service +++ b/multipathd/multipathd.service @@ -15,6 +15,7 @@ Type=notify 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/0024-RH-warn-on-invalid-regex-instead-of-failing.patch b/SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 90% rename from SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch rename to SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch index ded4ccb..6835f65 100644 --- a/SOURCES/0024-RH-warn-on-invalid-regex-instead-of-failing.patch +++ b/SOURCES/0016-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -16,7 +16,7 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 96815f8..3b1b652 100644 +index d6d8b79b..07d2ba8f 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c @@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr) @@ -41,7 +41,7 @@ index 96815f8..3b1b652 100644 static int set_yes_no(vector strvec, void *ptr) { -@@ -1386,7 +1401,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ +@@ -1455,7 +1470,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -50,7 +50,7 @@ index 96815f8..3b1b652 100644 if (!buff) \ return 1; \ \ -@@ -1402,7 +1417,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ +@@ -1471,7 +1486,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -59,7 +59,7 @@ index 96815f8..3b1b652 100644 if (!buff) \ return 1; \ \ -@@ -1505,16 +1520,16 @@ device_handler(struct config *conf, vector strvec) +@@ -1574,16 +1589,16 @@ device_handler(struct config *conf, vector strvec) return 0; } @@ -81,11 +81,11 @@ index 96815f8..3b1b652 100644 declare_hw_handler(hwhandler, set_str) diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index 92ef7cf..4289336 100644 +index e00c5fff..15495d26 100644 --- a/libmultipath/parser.c +++ b/libmultipath/parser.c -@@ -384,6 +384,19 @@ set_value(vector strvec) - return alloc; +@@ -382,6 +382,19 @@ oom: + return NULL; } +void * @@ -105,7 +105,7 @@ index 92ef7cf..4289336 100644 static int kw_level = 0; diff --git a/libmultipath/parser.h b/libmultipath/parser.h -index 62906e9..b791705 100644 +index 62906e98..b7917052 100644 --- a/libmultipath/parser.h +++ b/libmultipath/parser.h @@ -77,6 +77,7 @@ extern void dump_keywords(vector keydump, int level); 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/0025-RH-reset-default-find_mutipaths-value-to-off.patch b/SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 95% rename from SOURCES/0025-RH-reset-default-find_mutipaths-value-to-off.patch rename to SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch index 2f6bbe9..e48fc59 100644 --- a/SOURCES/0025-RH-reset-default-find_mutipaths-value-to-off.patch +++ b/SOURCES/0017-RH-reset-default-find_mutipaths-value-to-off.patch @@ -12,10 +12,10 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h -index 6576939..2ad6308 100644 +index 4dfe007c..d910da51 100644 --- a/libmultipath/defaults.h +++ b/libmultipath/defaults.h -@@ -17,7 +17,7 @@ +@@ -20,7 +20,7 @@ #define DEFAULT_NO_PATH_RETRY NO_PATH_RETRY_UNDEF #define DEFAULT_VERBOSITY 2 #define DEFAULT_REASSIGN_MAPS 0 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/0026-RH-Fix-nvme-compilation-warning.patch b/SOURCES/0018-RH-Fix-nvme-compilation-warning.patch similarity index 96% rename from SOURCES/0026-RH-Fix-nvme-compilation-warning.patch rename to SOURCES/0018-RH-Fix-nvme-compilation-warning.patch index 6de061a..fc6ccd7 100644 --- a/SOURCES/0026-RH-Fix-nvme-compilation-warning.patch +++ b/SOURCES/0018-RH-Fix-nvme-compilation-warning.patch @@ -9,7 +9,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmultipath/nvme/argconfig.h b/libmultipath/nvme/argconfig.h -index adb192b..bfd10ef 100644 +index adb192b6..bfd10ef8 100644 --- a/libmultipath/nvme/argconfig.h +++ b/libmultipath/nvme/argconfig.h @@ -76,7 +76,7 @@ struct argconfig_commandline_options { diff --git a/SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch b/SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch similarity index 98% rename from SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch rename to SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch index 36954ad..24c3ebd 100644 --- a/SOURCES/0028-RH-attempt-to-get-ANA-info-via-sysfs-first.patch +++ b/SOURCES/0019-RH-attempt-to-get-ANA-info-via-sysfs-first.patch @@ -13,7 +13,7 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/libmultipath/prioritizers/ana.c b/libmultipath/prioritizers/ana.c -index 990d935..d84571b 100644 +index 2673d9d9..f34ade28 100644 --- a/libmultipath/prioritizers/ana.c +++ b/libmultipath/prioritizers/ana.c @@ -24,6 +24,7 @@ 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/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