From 3ec0ebefcd5c48f75177eb67aa9f35a03effda52 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Thu, 27 Sep 2018 17:56:43 -0500 Subject: [PATCH] device-mapper-multipath-0.7.7-6.git1a8625a - Update Source to latest upstream commit * Previous patches 0001-0011 are included in this commit - Rename files * Previous patches 0012-0019 are now patches 0021-0028 - Add 0001-libmultipath-fix-tur-checker-timeout.patch - Add 0002-libmultipath-fix-tur-checker-double-locking.patch - Add 0003-libmultipath-fix-tur-memory-misuse.patch - Add 0004-libmultipath-cleanup-tur-locking.patch - Add 0005-libmultipath-fix-tur-checker-timeout-issue.patch * The above 5 patches cleanup locking issues with the tur checker threads - Add 0006-libmultipath-fix-set_int-error-path.patch - Add 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch - Add 0008-libmultipath-_install_keyword-cleanup.patch - Add 0009-libmultipath-remove-unused-code.patch - Add 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch - Add 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch - Add 0012-libmutipath-don-t-use-malformed-uevents.patch - Add 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch - Add 0014-multipathd-function-return-value-tweaks.patch - Add 0015-multipathd-minor-fixes.patch - Add 0016-multipathd-remove-useless-check-and-fix-format.patch - Add 0017-multipathd-fix-memory-leak-on-error-in-configure.patch * The above 12 patches fix minor issues found by coverity - Add 0018-libmultipath-Don-t-blank-intialized-paths.patch - Add 0019-libmultipath-Fixup-updating-paths.patch * Fix issues with paths whose wwid was not set or later changes - Add 0020-multipath-tweak-logging-style.patch * multipathd interactive commands now send errors to stderr, instead of syslog * The above 20 patches have been submitted upstream --- .gitignore | 1 + ...libmultipath-fix-tur-checker-timeout.patch | 52 ++ ...libmultipath-remove-last-of-rbd-code.patch | 41 -- ...ultipath-fix-detect-alua-corner-case.patch | 35 -- ...ipath-fix-tur-checker-double-locking.patch | 182 ++++++ 0003-libmultipath-fix-tur-memory-misuse.patch | 150 +++++ 0003-multipath-fix-setting-conf-version.patch | 39 -- 0004-libmultipath-cleanup-tur-locking.patch | 144 +++++ ...pathpersist-add-param-alltgpt-option.patch | 152 ----- ...tipath-fix-tur-checker-timeout-issue.patch | 48 ++ ...bmutipath-remove-unused-IDE-bus-type.patch | 25 - ...-libmultipath-fix-set_int-error-path.patch | 33 ++ ...pathd-add-new-protocol-path-wildcard.patch | 92 --- ...tipath-add-protocol-blacklist-option.patch | 425 ------------- ...th-fix-length-issues-in-get_vpd_sgio.patch | 50 ++ ...ibmultipath-_install_keyword-cleanup.patch | 42 ++ ...-remove-_filter_-blacklist-functions.patch | 296 ---------- 0009-libmultipath-remove-unused-code.patch | 57 ++ ...change-to-work-with-old-make-version.patch | 28 - ...ix-memory-issue-in-path_latency-prio.patch | 31 + ...-multipath-tests-add-blacklist-tests.patch | 559 ------------------ ...-null-dereference-int-alloc_path_gro.patch | 30 + ...sist-add-missing-param-rk-usage-info.patch | 25 - ...mutipath-don-t-use-malformed-uevents.patch | 34 ++ ...ix-max-array-size-in-print_cmd_valid.patch | 30 + ...tipathd-function-return-value-tweaks.patch | 50 ++ 0015-multipathd-minor-fixes.patch | 40 ++ ...-remove-useless-check-and-fix-format.patch | 42 ++ ...ix-memory-leak-on-error-in-configure.patch | 67 +++ ...ltipath-Don-t-blank-intialized-paths.patch | 35 ++ 0019-libmultipath-Fixup-updating-paths.patch | 94 +++ 0020-multipath-tweak-logging-style.patch | 59 ++ ... 0021-RH-fixup-udev-rules-for-redhat.patch | 4 +- ...property-blacklist-exception-builtin.patch | 0 ...RH-don-t-start-without-a-config-file.patch | 0 ... 0024-RH-use-rpm-optflags-if-present.patch | 11 +- ...hconf.patch => 0025-RH-add-mpathconf.patch | 0 ...om-kernel-cmdline-mpath.wwids-with-A.patch | 2 +- ...-on-invalid-regex-instead-of-failing.patch | 14 +- ...-default-find_mutipaths-value-to-off.patch | 0 device-mapper-multipath.spec | 95 ++- sources | 2 +- 42 files changed, 1361 insertions(+), 1755 deletions(-) create mode 100644 0001-libmultipath-fix-tur-checker-timeout.patch delete mode 100644 0001-libmultipath-remove-last-of-rbd-code.patch delete mode 100644 0002-libmultipath-fix-detect-alua-corner-case.patch create mode 100644 0002-libmultipath-fix-tur-checker-double-locking.patch create mode 100644 0003-libmultipath-fix-tur-memory-misuse.patch delete mode 100644 0003-multipath-fix-setting-conf-version.patch create mode 100644 0004-libmultipath-cleanup-tur-locking.patch delete mode 100644 0004-mpathpersist-add-param-alltgpt-option.patch create mode 100644 0005-libmultipath-fix-tur-checker-timeout-issue.patch delete mode 100644 0005-libmutipath-remove-unused-IDE-bus-type.patch create mode 100644 0006-libmultipath-fix-set_int-error-path.patch delete mode 100644 0006-multipathd-add-new-protocol-path-wildcard.patch delete mode 100644 0007-libmultipath-add-protocol-blacklist-option.patch create mode 100644 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch create mode 100644 0008-libmultipath-_install_keyword-cleanup.patch delete mode 100644 0008-libmultipath-remove-_filter_-blacklist-functions.patch create mode 100644 0009-libmultipath-remove-unused-code.patch delete mode 100644 0009-multipath-tests-change-to-work-with-old-make-version.patch create mode 100644 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch delete mode 100644 0010-multipath-tests-add-blacklist-tests.patch create mode 100644 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch delete mode 100644 0011-mpathpersist-add-missing-param-rk-usage-info.patch create mode 100644 0012-libmutipath-don-t-use-malformed-uevents.patch create mode 100644 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch create mode 100644 0014-multipathd-function-return-value-tweaks.patch create mode 100644 0015-multipathd-minor-fixes.patch create mode 100644 0016-multipathd-remove-useless-check-and-fix-format.patch create mode 100644 0017-multipathd-fix-memory-leak-on-error-in-configure.patch create mode 100644 0018-libmultipath-Don-t-blank-intialized-paths.patch create mode 100644 0019-libmultipath-Fixup-updating-paths.patch create mode 100644 0020-multipath-tweak-logging-style.patch rename 0012-RH-fixup-udev-rules-for-redhat.patch => 0021-RH-fixup-udev-rules-for-redhat.patch (97%) rename 0013-RH-Remove-the-property-blacklist-exception-builtin.patch => 0022-RH-Remove-the-property-blacklist-exception-builtin.patch (100%) rename 0014-RH-don-t-start-without-a-config-file.patch => 0023-RH-don-t-start-without-a-config-file.patch (100%) rename 0015-RH-use-rpm-optflags-if-present.patch => 0024-RH-use-rpm-optflags-if-present.patch (85%) rename 0016-RH-add-mpathconf.patch => 0025-RH-add-mpathconf.patch (100%) rename 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch => 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch (99%) rename 0018-RH-warn-on-invalid-regex-instead-of-failing.patch => 0027-RH-warn-on-invalid-regex-instead-of-failing.patch (89%) rename 0019-RH-reset-default-find_mutipaths-value-to-off.patch => 0028-RH-reset-default-find_mutipaths-value-to-off.patch (100%) diff --git a/.gitignore b/.gitignore index 0a86d83..5d64e6b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ multipath-tools-091027.tar.gz /multipath-tools-1cb704b.tgz /multipath-tools-0.7.7.tgz /multipath-tools-ef6d98b.tgz +/multipath-tools-1a8625a.tgz diff --git a/0001-libmultipath-fix-tur-checker-timeout.patch b/0001-libmultipath-fix-tur-checker-timeout.patch new file mode 100644 index 0000000..01c6600 --- /dev/null +++ b/0001-libmultipath-fix-tur-checker-timeout.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 26 Jul 2018 12:29:30 -0500 +Subject: [PATCH] libmultipath: fix tur checker timeout + +The code previously was timing out mode if ct->thread was 0 but +ct->running wasn't. This combination never happens. The idea was to +timeout if for some reason the path checker tried to kill the thread, +but it didn't die. The correct thing to check for this is ct->holders. +ct->holders will always be at least one when libcheck_check() is called, +since libcheck_free() won't get called until the device is no longer +being checked. So, if ct->holders is 2, that means that the tur thread +is has not shut down yet. + +Also, instead of returning PATH_TIMEOUT whenever the thread hasn't died, +it should only time out if the thread didn't successfully get a value, +which means the previous state was already PATH_TIMEOUT. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers/tur.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index bf8486d..275541f 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -355,12 +355,15 @@ int libcheck_check(struct checker * c) + } + pthread_mutex_unlock(&ct->lock); + } else { +- if (uatomic_read(&ct->running) != 0) { +- /* pthread cancel failed. continue in sync mode */ +- pthread_mutex_unlock(&ct->lock); +- condlog(3, "%s: tur thread not responding", +- tur_devt(devt, sizeof(devt), ct)); +- return PATH_TIMEOUT; ++ if (uatomic_read(&ct->holders) > 1) { ++ /* pthread cancel failed. If it didn't get the path ++ state already, timeout */ ++ if (ct->state == PATH_PENDING) { ++ pthread_mutex_unlock(&ct->lock); ++ condlog(3, "%s: tur thread not responding", ++ tur_devt(devt, sizeof(devt), ct)); ++ return PATH_TIMEOUT; ++ } + } + /* Start new TUR checker */ + ct->state = PATH_UNCHECKED; +-- +2.7.4 + diff --git a/0001-libmultipath-remove-last-of-rbd-code.patch b/0001-libmultipath-remove-last-of-rbd-code.patch deleted file mode 100644 index 7f26eb8..0000000 --- a/0001-libmultipath-remove-last-of-rbd-code.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 1 Jun 2018 16:30:44 -0500 -Subject: [PATCH] libmultipath: remove last of rbd code - -My previous patch to remove the rbd code missed a little bit. - -Signed-off-by: Benjamin Marzinski ---- - kpartx/del-part-nodes.rules | 2 +- - libmultipath/structs.h | 1 - - 2 files changed, 1 insertion(+), 2 deletions(-) - -diff --git a/kpartx/del-part-nodes.rules b/kpartx/del-part-nodes.rules -index 17bc505..0ceecf5 100644 ---- a/kpartx/del-part-nodes.rules -+++ b/kpartx/del-part-nodes.rules -@@ -10,7 +10,7 @@ - # or create an udev rule file that sets ENV{DONT_DEL_PART_NODES}="1". - - SUBSYSTEM!="block", GOTO="end_del_part_nodes" --KERNEL!="sd*|dasd*|rbd*", GOTO="end_del_part_nodes" -+KERNEL!="sd*|dasd*", GOTO="end_del_part_nodes" - ACTION!="add|change", GOTO="end_del_part_nodes" - ENV{DEVTYPE}=="partition", GOTO="end_del_part_nodes" - -diff --git a/libmultipath/structs.h b/libmultipath/structs.h -index e5b698b..ca14315 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -61,7 +61,6 @@ enum sysfs_buses { - SYSFS_BUS_IDE, - SYSFS_BUS_CCW, - SYSFS_BUS_CCISS, -- SYSFS_BUS_RBD, - SYSFS_BUS_NVME, - }; - --- -2.7.4 - diff --git a/0002-libmultipath-fix-detect-alua-corner-case.patch b/0002-libmultipath-fix-detect-alua-corner-case.patch deleted file mode 100644 index 6d6fa64..0000000 --- a/0002-libmultipath-fix-detect-alua-corner-case.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 8 Jun 2018 17:12:37 -0500 -Subject: [PATCH] libmultipath: fix detect alua corner case - -If retain_attach_hw_handler = no, then the paths tpgs state will never -be checked, and the multipath device will always select the alua -handler, if no other handler is selected. the paths tpgs state -should be checked, regardless of the retain_hwhandler value. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/propsel.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c -index af3ed62..fdb5953 100644 ---- a/libmultipath/propsel.c -+++ b/libmultipath/propsel.c -@@ -420,9 +420,11 @@ int select_hwhandler(struct config *conf, struct multipath *mp) - bool all_tpgs = true; - - dh_state = &handler[2]; -+ -+ vector_foreach_slot(mp->paths, pp, i) -+ all_tpgs = all_tpgs && (pp->tpgs > 0); - if (mp->retain_hwhandler != RETAIN_HWHANDLER_OFF) { - vector_foreach_slot(mp->paths, pp, i) { -- all_tpgs = all_tpgs && (pp->tpgs > 0); - if (get_dh_state(pp, dh_state, sizeof(handler) - 2) > 0 - && strcmp(dh_state, "detached")) { - memcpy(handler, "1 ", 2); --- -2.7.4 - diff --git a/0002-libmultipath-fix-tur-checker-double-locking.patch b/0002-libmultipath-fix-tur-checker-double-locking.patch new file mode 100644 index 0000000..08a6398 --- /dev/null +++ b/0002-libmultipath-fix-tur-checker-double-locking.patch @@ -0,0 +1,182 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 26 Jul 2018 14:01:45 -0500 +Subject: [PATCH] libmultipath: fix tur checker double locking + +tur_devt() locks ct->lock. However, it is ocassionally called while +ct->lock is already locked. In reality, there is no reason why we need +to lock all the accesses to ct->devt. The tur checker only needs to +write to this variable one time, when it first gets the file descripter +that it is checking. It also never uses ct->devt directly. Instead, it +always graps the major and minor, and turns them into a string. This +patch changes ct->devt into that string, and sets it in libcheck_init() +when it is first initializing the checker context. After that, ct->devt +is only ever read. + +Cc: Bart Van Assche +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers/tur.c | 55 +++++++++++++-------------------------------- + 1 file changed, 16 insertions(+), 39 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index 275541f..d173648 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -37,36 +37,24 @@ + #define MSG_TUR_FAILED "tur checker failed to initialize" + + struct tur_checker_context { +- dev_t devt; ++ char devt[32]; + int state; +- int running; ++ int running; /* uatomic access only */ + int fd; + unsigned int timeout; + time_t time; + pthread_t thread; + pthread_mutex_t lock; + pthread_cond_t active; +- int holders; ++ int holders; /* uatomic access only */ + char message[CHECKER_MSG_LEN]; + }; + +-static const char *tur_devt(char *devt_buf, int size, +- struct tur_checker_context *ct) +-{ +- dev_t devt; +- +- pthread_mutex_lock(&ct->lock); +- devt = ct->devt; +- pthread_mutex_unlock(&ct->lock); +- +- snprintf(devt_buf, size, "%d:%d", major(devt), minor(devt)); +- return devt_buf; +-} +- + int libcheck_init (struct checker * c) + { + struct tur_checker_context *ct; + pthread_mutexattr_t attr; ++ struct stat sb; + + ct = malloc(sizeof(struct tur_checker_context)); + if (!ct) +@@ -81,6 +69,9 @@ int libcheck_init (struct checker * c) + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&ct->lock, &attr); + pthread_mutexattr_destroy(&attr); ++ if (fstat(c->fd, &sb) == 0) ++ snprintf(ct->devt, sizeof(ct->devt), "%d:%d", major(sb.st_rdev), ++ minor(sb.st_rdev)); + c->context = ct; + + return 0; +@@ -232,14 +223,12 @@ static void *tur_thread(void *ctx) + { + struct tur_checker_context *ct = ctx; + int state, running; +- char devt[32]; + + /* This thread can be canceled, so setup clean up */ + tur_thread_cleanup_push(ct); + rcu_register_thread(); + +- condlog(3, "%s: tur checker starting up", +- tur_devt(devt, sizeof(devt), ct)); ++ condlog(3, "%s: tur checker starting up", ct->devt); + + /* TUR checker start up */ + pthread_mutex_lock(&ct->lock); +@@ -256,8 +245,8 @@ static void *tur_thread(void *ctx) + pthread_cond_signal(&ct->active); + pthread_mutex_unlock(&ct->lock); + +- condlog(3, "%s: tur checker finished, state %s", +- tur_devt(devt, sizeof(devt), ct), checker_state_name(state)); ++ condlog(3, "%s: tur checker finished, state %s", ct->devt, ++ checker_state_name(state)); + + running = uatomic_xchg(&ct->running, 0); + if (!running) +@@ -305,20 +294,12 @@ int libcheck_check(struct checker * c) + { + struct tur_checker_context *ct = c->context; + struct timespec tsp; +- struct stat sb; + pthread_attr_t attr; + int tur_status, r; +- char devt[32]; + + if (!ct) + return PATH_UNCHECKED; + +- if (fstat(c->fd, &sb) == 0) { +- pthread_mutex_lock(&ct->lock); +- ct->devt = sb.st_rdev; +- pthread_mutex_unlock(&ct->lock); +- } +- + if (c->sync) + return tur_check(c->fd, c->timeout, copy_msg_to_checker, c); + +@@ -327,8 +308,7 @@ int libcheck_check(struct checker * c) + */ + r = pthread_mutex_lock(&ct->lock); + if (r != 0) { +- condlog(2, "%s: tur mutex lock failed with %d", +- tur_devt(devt, sizeof(devt), ct), r); ++ condlog(2, "%s: tur mutex lock failed with %d", ct->devt, r); + MSG(c, MSG_TUR_FAILED); + return PATH_WILD; + } +@@ -338,14 +318,12 @@ int libcheck_check(struct checker * c) + int running = uatomic_xchg(&ct->running, 0); + if (running) + pthread_cancel(ct->thread); +- condlog(3, "%s: tur checker timeout", +- tur_devt(devt, sizeof(devt), ct)); ++ condlog(3, "%s: tur checker timeout", ct->devt); + ct->thread = 0; + MSG(c, MSG_TUR_TIMEOUT); + tur_status = PATH_TIMEOUT; + } else if (uatomic_read(&ct->running) != 0) { +- condlog(3, "%s: tur checker not finished", +- tur_devt(devt, sizeof(devt), ct)); ++ condlog(3, "%s: tur checker not finished", ct->devt); + tur_status = PATH_PENDING; + } else { + /* TUR checker done */ +@@ -361,7 +339,7 @@ int libcheck_check(struct checker * c) + if (ct->state == PATH_PENDING) { + pthread_mutex_unlock(&ct->lock); + condlog(3, "%s: tur thread not responding", +- tur_devt(devt, sizeof(devt), ct)); ++ ct->devt); + return PATH_TIMEOUT; + } + } +@@ -381,7 +359,7 @@ int libcheck_check(struct checker * c) + ct->thread = 0; + pthread_mutex_unlock(&ct->lock); + condlog(3, "%s: failed to start tur thread, using" +- " sync mode", tur_devt(devt, sizeof(devt), ct)); ++ " sync mode", ct->devt); + return tur_check(c->fd, c->timeout, + copy_msg_to_checker, c); + } +@@ -392,8 +370,7 @@ int libcheck_check(struct checker * c) + pthread_mutex_unlock(&ct->lock); + if (uatomic_read(&ct->running) != 0 && + (tur_status == PATH_PENDING || tur_status == PATH_UNCHECKED)) { +- condlog(3, "%s: tur checker still running", +- tur_devt(devt, sizeof(devt), ct)); ++ condlog(3, "%s: tur checker still running", ct->devt); + tur_status = PATH_PENDING; + } else { + int running = uatomic_xchg(&ct->running, 0); +-- +2.7.4 + diff --git a/0003-libmultipath-fix-tur-memory-misuse.patch b/0003-libmultipath-fix-tur-memory-misuse.patch new file mode 100644 index 0000000..8d58ee1 --- /dev/null +++ b/0003-libmultipath-fix-tur-memory-misuse.patch @@ -0,0 +1,150 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 26 Jul 2018 16:17:17 -0500 +Subject: [PATCH] libmultipath: fix tur memory misuse + +when tur_thread() was calling tur_check(), it was passing ct->message as +the copy argument, but copy_msg_to_tcc() was assuming that it was +getting a tur_checker_context pointer. This means it was treating +ct->message as ct. This is why the tur checker never printed checker +messages. Intead of simply changing the copy argument passed in, I just +removed all the copying code, since it is completely unnecessary. The +callers of tur_check() can just pass in a buffer that it is safe to +write to, and copy it later, if necessary. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers/tur.c | 46 +++++++++++---------------------------------- + 1 file changed, 11 insertions(+), 35 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index d173648..abda162 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -103,17 +103,8 @@ void libcheck_free (struct checker * c) + return; + } + +-#define TUR_MSG(fmt, args...) \ +- do { \ +- char msg[CHECKER_MSG_LEN]; \ +- \ +- snprintf(msg, sizeof(msg), fmt, ##args); \ +- copy_message(cb_arg, msg); \ +- } while (0) +- + static int +-tur_check(int fd, unsigned int timeout, +- void (*copy_message)(void *, const char *), void *cb_arg) ++tur_check(int fd, unsigned int timeout, char *msg) + { + struct sg_io_hdr io_hdr; + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; +@@ -132,7 +123,7 @@ retry: + io_hdr.timeout = timeout * 1000; + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { +- TUR_MSG(MSG_TUR_DOWN); ++ snprintf(msg, CHECKER_MSG_LEN, MSG_TUR_DOWN); + return PATH_DOWN; + } + if ((io_hdr.status & 0x7e) == 0x18) { +@@ -140,7 +131,7 @@ retry: + * SCSI-3 arrays might return + * reservation conflict on TUR + */ +- TUR_MSG(MSG_TUR_UP); ++ snprintf(msg, CHECKER_MSG_LEN, MSG_TUR_UP); + return PATH_UP; + } + if (io_hdr.info & SG_INFO_OK_MASK) { +@@ -185,14 +176,14 @@ retry: + * LOGICAL UNIT NOT ACCESSIBLE, + * TARGET PORT IN STANDBY STATE + */ +- TUR_MSG(MSG_TUR_GHOST); ++ snprintf(msg, CHECKER_MSG_LEN, MSG_TUR_GHOST); + return PATH_GHOST; + } + } +- TUR_MSG(MSG_TUR_DOWN); ++ snprintf(msg, CHECKER_MSG_LEN, MSG_TUR_DOWN); + return PATH_DOWN; + } +- TUR_MSG(MSG_TUR_UP); ++ snprintf(msg, CHECKER_MSG_LEN, MSG_TUR_UP); + return PATH_UP; + } + +@@ -210,19 +201,11 @@ static void cleanup_func(void *data) + rcu_unregister_thread(); + } + +-static void copy_msg_to_tcc(void *ct_p, const char *msg) +-{ +- struct tur_checker_context *ct = ct_p; +- +- pthread_mutex_lock(&ct->lock); +- strlcpy(ct->message, msg, sizeof(ct->message)); +- pthread_mutex_unlock(&ct->lock); +-} +- + static void *tur_thread(void *ctx) + { + struct tur_checker_context *ct = ctx; + int state, running; ++ char msg[CHECKER_MSG_LEN]; + + /* This thread can be canceled, so setup clean up */ + tur_thread_cleanup_push(ct); +@@ -236,12 +219,13 @@ static void *tur_thread(void *ctx) + ct->message[0] = '\0'; + pthread_mutex_unlock(&ct->lock); + +- state = tur_check(ct->fd, ct->timeout, copy_msg_to_tcc, ct->message); ++ state = tur_check(ct->fd, ct->timeout, msg); + pthread_testcancel(); + + /* TUR checker done */ + pthread_mutex_lock(&ct->lock); + ct->state = state; ++ strlcpy(ct->message, msg, sizeof(ct->message)); + pthread_cond_signal(&ct->active); + pthread_mutex_unlock(&ct->lock); + +@@ -283,13 +267,6 @@ static int tur_check_async_timeout(struct checker *c) + return (now.tv_sec > ct->time); + } + +-static void copy_msg_to_checker(void *c_p, const char *msg) +-{ +- struct checker *c = c_p; +- +- strlcpy(c->message, msg, sizeof(c->message)); +-} +- + int libcheck_check(struct checker * c) + { + struct tur_checker_context *ct = c->context; +@@ -301,7 +278,7 @@ int libcheck_check(struct checker * c) + return PATH_UNCHECKED; + + if (c->sync) +- return tur_check(c->fd, c->timeout, copy_msg_to_checker, c); ++ return tur_check(c->fd, c->timeout, c->message); + + /* + * Async mode +@@ -360,8 +337,7 @@ int libcheck_check(struct checker * c) + pthread_mutex_unlock(&ct->lock); + condlog(3, "%s: failed to start tur thread, using" + " sync mode", ct->devt); +- return tur_check(c->fd, c->timeout, +- copy_msg_to_checker, c); ++ return tur_check(c->fd, c->timeout, c->message); + } + tur_timeout(&tsp); + r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp); +-- +2.7.4 + diff --git a/0003-multipath-fix-setting-conf-version.patch b/0003-multipath-fix-setting-conf-version.patch deleted file mode 100644 index 624f45e..0000000 --- a/0003-multipath-fix-setting-conf-version.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Fri, 8 Jun 2018 17:23:07 -0500 -Subject: [PATCH] multipath: fix setting conf->version - -Commit d3b71498 stopped multipath from setting conf->version. Instead, -it was always being set to 0.0.0. Multipathd was still setting this -correctly. - -Fixes: d3b71498 "multipath: fix rcu thread cancellation hang" -Signed-off-by: Benjamin Marzinski ---- - libmultipath/devmapper.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c -index f2befad..8136d15 100644 ---- a/libmultipath/devmapper.c -+++ b/libmultipath/devmapper.c -@@ -245,13 +245,13 @@ void libmp_dm_init(void) - int verbosity; - unsigned int version[3]; - -+ if (dm_prereq(version)) -+ exit(1); - conf = get_multipath_config(); - verbosity = conf->verbosity; -- memcpy(version, conf->version, sizeof(version)); -+ memcpy(conf->version, version, sizeof(version)); - put_multipath_config(conf); - dm_init(verbosity); -- if (dm_prereq(version)) -- exit(1); - dm_udev_set_sync_support(libmp_dm_udev_sync); - } - --- -2.7.4 - diff --git a/0004-libmultipath-cleanup-tur-locking.patch b/0004-libmultipath-cleanup-tur-locking.patch new file mode 100644 index 0000000..a75e54e --- /dev/null +++ b/0004-libmultipath-cleanup-tur-locking.patch @@ -0,0 +1,144 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Thu, 26 Jul 2018 17:58:11 -0500 +Subject: [PATCH] libmultipath: cleanup tur locking + +There are only three variables whose access needs to be synchronized +between the tur thread and the path checker itself: state, message, and +active. The rest of the variables are either only written when the tur +thread isn't running, or they aren't accessed by the tur thread, or they +are atomics that are themselves used to synchronize things. + +This patch limits the amount of code that is covered by ct->lock to +only what needs to be locked. It also makes ct->lock no longer a +recursive lock. To make this simpler, tur_thread now only sets the +state and message one time, instead of twice, since PATH_UNCHECKED +was never able to be returned anyway. + +One benefit of this is that the tur checker thread gets more time to +call tur_check() and return before libcheck_check() gives up and +return PATH_PENDING. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers/tur.c | 49 ++++++++++++++++++--------------------------- + 1 file changed, 20 insertions(+), 29 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index abda162..9f6ef51 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -53,7 +53,6 @@ struct tur_checker_context { + int libcheck_init (struct checker * c) + { + struct tur_checker_context *ct; +- pthread_mutexattr_t attr; + struct stat sb; + + ct = malloc(sizeof(struct tur_checker_context)); +@@ -65,10 +64,7 @@ int libcheck_init (struct checker * c) + ct->fd = -1; + uatomic_set(&ct->holders, 1); + pthread_cond_init_mono(&ct->active); +- pthread_mutexattr_init(&attr); +- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +- pthread_mutex_init(&ct->lock, &attr); +- pthread_mutexattr_destroy(&attr); ++ pthread_mutex_init(&ct->lock, NULL); + if (fstat(c->fd, &sb) == 0) + snprintf(ct->devt, sizeof(ct->devt), "%d:%d", major(sb.st_rdev), + minor(sb.st_rdev)); +@@ -213,12 +209,6 @@ static void *tur_thread(void *ctx) + + condlog(3, "%s: tur checker starting up", ct->devt); + +- /* TUR checker start up */ +- pthread_mutex_lock(&ct->lock); +- ct->state = PATH_PENDING; +- ct->message[0] = '\0'; +- pthread_mutex_unlock(&ct->lock); +- + state = tur_check(ct->fd, ct->timeout, msg); + pthread_testcancel(); + +@@ -283,13 +273,6 @@ int libcheck_check(struct checker * c) + /* + * Async mode + */ +- r = pthread_mutex_lock(&ct->lock); +- if (r != 0) { +- condlog(2, "%s: tur mutex lock failed with %d", ct->devt, r); +- MSG(c, MSG_TUR_FAILED); +- return PATH_WILD; +- } +- + if (ct->thread) { + if (tur_check_async_timeout(c)) { + int running = uatomic_xchg(&ct->running, 0); +@@ -305,23 +288,29 @@ int libcheck_check(struct checker * c) + } else { + /* TUR checker done */ + ct->thread = 0; ++ pthread_mutex_lock(&ct->lock); + tur_status = ct->state; + strlcpy(c->message, ct->message, sizeof(c->message)); ++ pthread_mutex_unlock(&ct->lock); + } +- pthread_mutex_unlock(&ct->lock); + } else { + if (uatomic_read(&ct->holders) > 1) { + /* pthread cancel failed. If it didn't get the path + state already, timeout */ +- if (ct->state == PATH_PENDING) { +- pthread_mutex_unlock(&ct->lock); ++ pthread_mutex_lock(&ct->lock); ++ tur_status = ct->state; ++ pthread_mutex_unlock(&ct->lock); ++ if (tur_status == PATH_PENDING) { + condlog(3, "%s: tur thread not responding", + ct->devt); + return PATH_TIMEOUT; + } + } + /* Start new TUR checker */ +- ct->state = PATH_UNCHECKED; ++ pthread_mutex_lock(&ct->lock); ++ tur_status = ct->state = PATH_PENDING; ++ ct->message[0] = '\0'; ++ pthread_mutex_unlock(&ct->lock); + ct->fd = c->fd; + ct->timeout = c->timeout; + uatomic_add(&ct->holders, 1); +@@ -334,20 +323,22 @@ int libcheck_check(struct checker * c) + uatomic_sub(&ct->holders, 1); + uatomic_set(&ct->running, 0); + ct->thread = 0; +- pthread_mutex_unlock(&ct->lock); + condlog(3, "%s: failed to start tur thread, using" + " sync mode", ct->devt); + return tur_check(c->fd, c->timeout, c->message); + } + tur_timeout(&tsp); +- r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp); +- tur_status = ct->state; +- strlcpy(c->message, ct->message, sizeof(c->message)); ++ pthread_mutex_lock(&ct->lock); ++ if (ct->state == PATH_PENDING) ++ r = pthread_cond_timedwait(&ct->active, &ct->lock, ++ &tsp); ++ if (!r) { ++ tur_status = ct->state; ++ strlcpy(c->message, ct->message, sizeof(c->message)); ++ } + pthread_mutex_unlock(&ct->lock); +- if (uatomic_read(&ct->running) != 0 && +- (tur_status == PATH_PENDING || tur_status == PATH_UNCHECKED)) { ++ if (tur_status == PATH_PENDING) { + condlog(3, "%s: tur checker still running", ct->devt); +- tur_status = PATH_PENDING; + } else { + int running = uatomic_xchg(&ct->running, 0); + if (running) +-- +2.7.4 + diff --git a/0004-mpathpersist-add-param-alltgpt-option.patch b/0004-mpathpersist-add-param-alltgpt-option.patch deleted file mode 100644 index 8485d37..0000000 --- a/0004-mpathpersist-add-param-alltgpt-option.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 16:30:11 -0500 -Subject: [PATCH] mpathpersist: add --param-alltgpt option - -From the limited testing I've been able to do, commit 5b54e772 -"mpathpersist: add all_tg_pt option", does appear to enable ---param-alltgpt to work correctly on devices that accept the ALL_TG_PT -flag, so I've added the option to mpathpersist. - -Signed-off-by: Benjamin Marzinski ---- - libmpathpersist/mpath_persist.c | 10 ++++------ - mpathpersist/main.c | 11 ++++++++--- - mpathpersist/main.h | 1 + - mpathpersist/mpathpersist.8 | 4 ++++ - multipath/multipath.conf.5 | 8 +++++--- - 5 files changed, 22 insertions(+), 12 deletions(-) - -diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c -index 6e9e67f..61818e0 100644 ---- a/libmpathpersist/mpath_persist.c -+++ b/libmpathpersist/mpath_persist.c -@@ -466,11 +466,14 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - int rc; - int count=0; - int status = MPATH_PR_SUCCESS; -+ int all_tg_pt; - uint64_t sa_key = 0; - - if (!mpp) - return MPATH_PR_DMMP_ERROR; - -+ all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON || -+ paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK); - active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST); - - if (active_pathcount == 0) { -@@ -478,10 +481,6 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - return MPATH_PR_DMMP_ERROR; - } - -- if ( paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK ) { -- condlog (1, "Warning: ALL_TG_PT is set. Configuration not supported"); -- } -- - struct threadinfo thread[active_pathcount]; - int hosts[active_pathcount]; - -@@ -518,8 +517,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev); - continue; - } -- if (mpp->all_tg_pt == ALL_TG_PT_ON && -- pp->sg_id.host_no != -1) { -+ if (all_tg_pt && pp->sg_id.host_no != -1) { - for (k = 0; k < count; k++) { - if (pp->sg_id.host_no == hosts[k]) { - condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no); -diff --git a/mpathpersist/main.c b/mpathpersist/main.c -index 5b37f3a..99151fe 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -118,7 +118,7 @@ int main (int argc, char * argv[]) - { - int option_index = 0; - -- c = getopt_long (argc, argv, "v:Cd:hHioZK:S:PAT:skrGILcRX:l:", -+ c = getopt_long (argc, argv, "v:Cd:hHioYZK:S:PAT:skrGILcRX:l:", - long_options, &option_index); - if (c == -1) - break; -@@ -158,6 +158,10 @@ int main (int argc, char * argv[]) - prout_flag = 1; - break; - -+ case 'Y': -+ param_alltgpt = 1; -+ ++num_prout_param; -+ break; - case 'Z': - param_aptpl = 1; - ++num_prout_param; -@@ -443,9 +447,9 @@ int main (int argc, char * argv[]) - } - - if (param_alltgpt) -- paramp->sa_flags |= 0x4; -+ paramp->sa_flags |= MPATH_F_ALL_TG_PT_MASK; - if (param_aptpl) -- paramp->sa_flags |= 0x1; -+ paramp->sa_flags |= MPATH_F_APTPL_MASK; - - if (num_transport) - { -@@ -698,6 +702,7 @@ static void usage(void) - " --hex|-H output response in hex\n" - " --in|-i request PR In command \n" - " --out|-o request PR Out command\n" -+ " --param-alltgpt|-Y PR Out parameter 'ALL_TG_PT\n" - " --param-aptpl|-Z PR Out parameter 'APTPL'\n" - " --read-keys|-k PR In: Read Keys\n" - " --param-sark=SARK|-S SARK PR Out parameter service " -diff --git a/mpathpersist/main.h b/mpathpersist/main.h -index 5c0e089..beb8a21 100644 ---- a/mpathpersist/main.h -+++ b/mpathpersist/main.h -@@ -6,6 +6,7 @@ static struct option long_options[] = { - {"hex", 0, NULL, 'H'}, - {"in", 0, NULL, 'i'}, - {"out", 0, NULL, 'o'}, -+ {"param-alltgpt", 0, NULL, 'Y'}, - {"param-aptpl", 0, NULL, 'Z'}, - {"param-rk", 1, NULL, 'K'}, - {"param-sark", 1, NULL, 'S'}, -diff --git a/mpathpersist/mpathpersist.8 b/mpathpersist/mpathpersist.8 -index a8982e6..885491d 100644 ---- a/mpathpersist/mpathpersist.8 -+++ b/mpathpersist/mpathpersist.8 -@@ -87,6 +87,10 @@ Request PR In command. - Request PR Out command. - . - .TP -+.B \--param-alltgpt|\-Y -+PR Out parameter 'ALL_TG_PT'. -+. -+.TP - .B \--param-aptpl|\-Z - PR Out parameter 'APTPL'. - . -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index e4b25a0..fb863fd 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -756,9 +756,11 @@ The default is: \fB\fR - . - .TP - .B all_tg_pt --This must be set to \fByes\fR to successfully use mpathpersist on arrays that --automatically set and clear registration keys on all target ports from a --host, instead of per target port per host. -+Set the 'all targets ports' flag when registering keys with mpathpersist. Some -+arrays automatically set and clear registration keys on all target ports from a -+host, instead of per target port per host. The ALL_TG_PT flag must be set to -+successfully use mpathpersist on these arrays. Setting this option is identical -+to calling mpathpersist with \fI--param-alltgpt\fR - .RS - .TP - The default is: \fBno\fR --- -2.7.4 - diff --git a/0005-libmultipath-fix-tur-checker-timeout-issue.patch b/0005-libmultipath-fix-tur-checker-timeout-issue.patch new file mode 100644 index 0000000..ca7c5be --- /dev/null +++ b/0005-libmultipath-fix-tur-checker-timeout-issue.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 27 Jul 2018 11:25:23 -0500 +Subject: [PATCH] libmultipath: fix tur checker timeout issue + +If the tur checker is run, and the tur_thread has timed out, +libcheck_check() doesn't actually check if the thread is still running. +This means that the thread could have already completed successfully, +but the tur checker would still return PATH_TIMEOUT, instead of the +value returned by the thread. This patch makes libcheck_check() actually +check if the thread completed, and if so, it returns the proper value. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/checkers/tur.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index 9f6ef51..4e2c7a8 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -276,12 +276,19 @@ int libcheck_check(struct checker * c) + if (ct->thread) { + if (tur_check_async_timeout(c)) { + int running = uatomic_xchg(&ct->running, 0); +- if (running) ++ if (running) { + pthread_cancel(ct->thread); +- condlog(3, "%s: tur checker timeout", ct->devt); ++ condlog(3, "%s: tur checker timeout", ct->devt); ++ MSG(c, MSG_TUR_TIMEOUT); ++ tur_status = PATH_TIMEOUT; ++ } else { ++ pthread_mutex_lock(&ct->lock); ++ tur_status = ct->state; ++ strlcpy(c->message, ct->message, ++ sizeof(c->message)); ++ pthread_mutex_unlock(&ct->lock); ++ } + ct->thread = 0; +- MSG(c, MSG_TUR_TIMEOUT); +- tur_status = PATH_TIMEOUT; + } else if (uatomic_read(&ct->running) != 0) { + condlog(3, "%s: tur checker not finished", ct->devt); + tur_status = PATH_PENDING; +-- +2.7.4 + diff --git a/0005-libmutipath-remove-unused-IDE-bus-type.patch b/0005-libmutipath-remove-unused-IDE-bus-type.patch deleted file mode 100644 index 5dda5a7..0000000 --- a/0005-libmutipath-remove-unused-IDE-bus-type.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 16:45:48 -0500 -Subject: [PATCH] libmutipath: remove unused IDE bus type - -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 ca14315..0a2623a 100644 ---- a/libmultipath/structs.h -+++ b/libmultipath/structs.h -@@ -58,7 +58,6 @@ enum failback_mode { - enum sysfs_buses { - SYSFS_BUS_UNDEF, - SYSFS_BUS_SCSI, -- SYSFS_BUS_IDE, - SYSFS_BUS_CCW, - SYSFS_BUS_CCISS, - SYSFS_BUS_NVME, --- -2.7.4 - diff --git a/0006-libmultipath-fix-set_int-error-path.patch b/0006-libmultipath-fix-set_int-error-path.patch new file mode 100644 index 0000000..8cbd459 --- /dev/null +++ b/0006-libmultipath-fix-set_int-error-path.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 27 Jul 2018 13:38:49 -0500 +Subject: [PATCH] libmultipath: fix set_int error path + +set_int() wasn't checking if the line actually had a value before +converting it to an integer. Found by coverity. Also, it should +be using set_value(). + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/dict.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/dict.c b/libmultipath/dict.c +index 32524d5..bf4701e 100644 +--- a/libmultipath/dict.c ++++ b/libmultipath/dict.c +@@ -33,7 +33,10 @@ set_int(vector strvec, void *ptr) + int *int_ptr = (int *)ptr; + char * buff; + +- buff = VECTOR_SLOT(strvec, 1); ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ + *int_ptr = atoi(buff); + + return 0; +-- +2.7.4 + diff --git a/0006-multipathd-add-new-protocol-path-wildcard.patch b/0006-multipathd-add-new-protocol-path-wildcard.patch deleted file mode 100644 index 479788e..0000000 --- a/0006-multipathd-add-new-protocol-path-wildcard.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 26 Jun 2018 17:04:57 -0500 -Subject: [PATCH] multipathd: add new protocol path wildcard - -This patch adds a new path wildcard 'P', that will print the path's -protocol. For scsi devices, it will additionally print the transport -protocol being used. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/print.c | 43 +++++++++++++++++++++++++++++++++++++++++++ - libmultipath/print.h | 2 ++ - 2 files changed, 45 insertions(+) - -diff --git a/libmultipath/print.c b/libmultipath/print.c -index 222d270..ecfcb48 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -638,6 +638,48 @@ snprint_path_failures(char * buff, size_t len, const struct path * pp) - return snprint_int(buff, len, pp->failcount); - } - -+/* if you add a protocol string bigger than "scsi:unspec" you must -+ * also change PROTOCOL_BUF_SIZE */ -+int -+snprint_path_protocol(char * buff, size_t len, const struct path * pp) -+{ -+ switch (pp->bus) { -+ case SYSFS_BUS_SCSI: -+ switch (pp->sg_id.proto_id) { -+ case SCSI_PROTOCOL_FCP: -+ return snprintf(buff, len, "scsi:fcp"); -+ case SCSI_PROTOCOL_SPI: -+ return snprintf(buff, len, "scsi:spi"); -+ case SCSI_PROTOCOL_SSA: -+ return snprintf(buff, len, "scsi:ssa"); -+ case SCSI_PROTOCOL_SBP: -+ return snprintf(buff, len, "scsi:sbp"); -+ case SCSI_PROTOCOL_SRP: -+ return snprintf(buff, len, "scsi:srp"); -+ case SCSI_PROTOCOL_ISCSI: -+ return snprintf(buff, len, "scsi:iscsi"); -+ case SCSI_PROTOCOL_SAS: -+ return snprintf(buff, len, "scsi:sas"); -+ case SCSI_PROTOCOL_ADT: -+ return snprintf(buff, len, "scsi:adt"); -+ case SCSI_PROTOCOL_ATA: -+ return snprintf(buff, len, "scsi:ata"); -+ case SCSI_PROTOCOL_UNSPEC: -+ default: -+ return snprintf(buff, len, "scsi:unspec"); -+ } -+ case SYSFS_BUS_CCW: -+ return snprintf(buff, len, "ccw"); -+ case SYSFS_BUS_CCISS: -+ return snprintf(buff, len, "cciss"); -+ case SYSFS_BUS_NVME: -+ return snprintf(buff, len, "nvme"); -+ case SYSFS_BUS_UNDEF: -+ default: -+ return snprintf(buff, len, "undef"); -+ } -+} -+ - struct multipath_data mpd[] = { - {'n', "name", 0, snprint_name}, - {'w', "uuid", 0, snprint_multipath_uuid}, -@@ -687,6 +729,7 @@ struct path_data pd[] = { - {'a', "host adapter", 0, snprint_host_adapter}, - {'G', "foreign", 0, snprint_path_foreign}, - {'0', "failures", 0, snprint_path_failures}, -+ {'P', "protocol", 0, snprint_path_protocol}, - {0, NULL, 0 , NULL} - }; - -diff --git a/libmultipath/print.h b/libmultipath/print.h -index 608b7d5..e2fb865 100644 ---- a/libmultipath/print.h -+++ b/libmultipath/print.h -@@ -133,6 +133,8 @@ int snprint_host_wwnn (char *, size_t, const struct path *); - int snprint_host_wwpn (char *, size_t, const struct path *); - int snprint_tgt_wwnn (char *, size_t, const struct path *); - int snprint_tgt_wwpn (char *, size_t, const struct path *); -+#define PROTOCOL_BUF_SIZE sizeof("scsi:unspec") -+int snprint_path_protocol(char *, size_t, const struct path *); - - void _print_multipath_topology (const struct gen_multipath * gmp, - int verbosity); --- -2.7.4 - diff --git a/0007-libmultipath-add-protocol-blacklist-option.patch b/0007-libmultipath-add-protocol-blacklist-option.patch deleted file mode 100644 index 16a1899..0000000 --- a/0007-libmultipath-add-protocol-blacklist-option.patch +++ /dev/null @@ -1,425 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 28 Jun 2018 13:16:11 -0500 -Subject: [PATCH] libmultipath: add "protocol" blacklist option. - -Multiple users have requested an easy way to setup blacklists that do -things such as blacklisting all non FC and iSCSI devices. Currently -there is no easy way to do this, without knowing in advance what the -devices are. Looking into the udev property values, I didn't see a -consistent set of values that would worked for all the different types -of requests like this (which would have allowed us to solve this by -extending the "property" blacklist option to allow comparing values, -instead of just keywords). - -Instead I've opted to allow multipath to blacklist/whitelist devices -by the protocol strings printed by "multipathd: add new protocol path -wildcard". This check happens after multipath checks the "device" -keyword, and before it checks wwid. This gives users an easily -understandible method to set up these types of blacklists, without -needing to know the exact arrays being used. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 51 ++++++++++++++++++++++++++++++++++++++-------- - libmultipath/blacklist.h | 3 +++ - libmultipath/config.c | 15 ++++++++++++++ - libmultipath/config.h | 2 ++ - libmultipath/dict.c | 14 +++++++++++-- - libmultipath/discovery.c | 5 +++-- - libmultipath/print.c | 31 ++++++++++++++++++++++++++++ - multipath/multipath.conf.5 | 16 +++++++++++++-- - 8 files changed, 123 insertions(+), 14 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index 361c603..fdd36f7 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -12,6 +12,8 @@ - #include "structs.h" - #include "config.h" - #include "blacklist.h" -+#include "structs_vec.h" -+#include "print.h" - - int store_ble(vector blist, char * str, int origin) - { -@@ -240,12 +242,14 @@ setup_default_blist (struct config * conf) - condlog(3, "%s: %s %s %s", dev, (M), wwid, (S)); \ - else if (env) \ - condlog(3, "%s: %s %s %s", dev, (M), env, (S)); \ -+ else if (protocol) \ -+ condlog(3, "%s: %s %s %s", dev, (M), protocol, (S)); \ - else \ - condlog(3, "%s: %s %s", dev, (M), (S)) - - void - log_filter (const char *dev, char *vendor, char *product, char *wwid, -- const char *env, int r) -+ const char *env, const char *protocol, int r) - { - /* - * Try to sort from most likely to least. -@@ -265,6 +269,9 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - case MATCH_PROPERTY_BLIST: - LOG_BLIST("udev property", "blacklisted"); - break; -+ case MATCH_PROTOCOL_BLIST: -+ LOG_BLIST("protocol", "blacklisted"); -+ break; - case MATCH_DEVICE_BLIST_EXCEPT: - LOG_BLIST("vendor/product", "whitelisted"); - break; -@@ -280,6 +287,9 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - case MATCH_PROPERTY_BLIST_MISSING: - LOG_BLIST("blacklisted,", "udev property missing"); - break; -+ case MATCH_PROTOCOL_BLIST_EXCEPT: -+ LOG_BLIST("protocol", "whitelisted"); -+ break; - } - } - -@@ -299,7 +309,7 @@ int - filter_device (vector blist, vector elist, char * vendor, char * product) - { - int r = _filter_device(blist, elist, vendor, product); -- log_filter(NULL, vendor, product, NULL, NULL, r); -+ log_filter(NULL, vendor, product, NULL, NULL, NULL, r); - return r; - } - -@@ -319,7 +329,7 @@ int - filter_devnode (vector blist, vector elist, char * dev) - { - int r = _filter_devnode(blist, elist, dev); -- log_filter(dev, NULL, NULL, NULL, NULL, r); -+ log_filter(dev, NULL, NULL, NULL, NULL, NULL, r); - return r; - } - -@@ -339,7 +349,29 @@ int - filter_wwid (vector blist, vector elist, char * wwid, char * dev) - { - int r = _filter_wwid(blist, elist, wwid); -- log_filter(dev, NULL, NULL, wwid, NULL, r); -+ log_filter(dev, NULL, NULL, wwid, NULL, NULL, r); -+ return r; -+} -+ -+static int -+_filter_protocol (vector blist, vector elist, const char * protocol_str) -+{ -+ if (_blacklist_exceptions(elist, protocol_str)) -+ return MATCH_PROTOCOL_BLIST_EXCEPT; -+ if (_blacklist(blist, protocol_str)) -+ return MATCH_PROTOCOL_BLIST; -+ return 0; -+} -+ -+int -+filter_protocol(vector blist, vector elist, struct path * pp) -+{ -+ char buf[PROTOCOL_BUF_SIZE]; -+ int r; -+ -+ snprint_path_protocol(buf, sizeof(buf), pp); -+ r = _filter_protocol(blist, elist, buf); -+ log_filter(pp->dev, NULL, NULL, NULL, NULL, buf, r); - return r; - } - -@@ -351,7 +383,6 @@ _filter_path (struct config * conf, struct path * pp) - r = filter_property(conf, pp->udev); - if (r > 0) - return r; -- - r = _filter_devnode(conf->blist_devnode, conf->elist_devnode,pp->dev); - if (r > 0) - return r; -@@ -359,6 +390,9 @@ _filter_path (struct config * conf, struct path * pp) - pp->vendor_id, pp->product_id); - if (r > 0) - return r; -+ r = filter_protocol(conf->blist_protocol, conf->elist_protocol, pp); -+ if (r > 0) -+ return r; - r = _filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid); - return r; - } -@@ -367,7 +401,8 @@ int - filter_path (struct config * conf, struct path * pp) - { - int r=_filter_path(conf, pp); -- log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, r); -+ log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, -+ NULL, r); - return r; - } - -@@ -402,7 +437,7 @@ filter_property(struct config * conf, struct udev_device * udev) - - r = _filter_property(conf, env); - if (r) { -- log_filter(devname, NULL, NULL, NULL, env, r); -+ log_filter(devname, NULL, NULL, NULL, env, NULL, r); - return r; - } - } -@@ -411,7 +446,7 @@ filter_property(struct config * conf, struct udev_device * udev) - * This is the inverse of the 'normal' matching; - * the environment variable _has_ to match. - */ -- log_filter(devname, NULL, NULL, NULL, NULL, -+ log_filter(devname, NULL, NULL, NULL, NULL, NULL, - MATCH_PROPERTY_BLIST_MISSING); - return MATCH_PROPERTY_BLIST_MISSING; - } -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index 0b028d4..f7beef2 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -10,10 +10,12 @@ - #define MATCH_DEVNODE_BLIST 3 - #define MATCH_PROPERTY_BLIST 4 - #define MATCH_PROPERTY_BLIST_MISSING 5 -+#define MATCH_PROTOCOL_BLIST 6 - #define MATCH_WWID_BLIST_EXCEPT -MATCH_WWID_BLIST - #define MATCH_DEVICE_BLIST_EXCEPT -MATCH_DEVICE_BLIST - #define MATCH_DEVNODE_BLIST_EXCEPT -MATCH_DEVNODE_BLIST - #define MATCH_PROPERTY_BLIST_EXCEPT -MATCH_PROPERTY_BLIST -+#define MATCH_PROTOCOL_BLIST_EXCEPT -MATCH_PROTOCOL_BLIST - - struct blentry { - char * str; -@@ -36,6 +38,7 @@ int filter_wwid (vector, vector, char *, char *); - int filter_device (vector, vector, char *, char *); - int filter_path (struct config *, struct path *); - int filter_property(struct config *, struct udev_device *); -+int filter_protocol(vector, vector, struct path *); - int store_ble (vector, char *, int); - int set_ble_device (vector, char *, char *, int); - void free_blacklist (vector); -diff --git a/libmultipath/config.c b/libmultipath/config.c -index afa309d..0aef186 100644 ---- a/libmultipath/config.c -+++ b/libmultipath/config.c -@@ -623,11 +623,13 @@ free_config (struct config * conf) - free_blacklist(conf->blist_devnode); - free_blacklist(conf->blist_wwid); - free_blacklist(conf->blist_property); -+ free_blacklist(conf->blist_protocol); - free_blacklist_device(conf->blist_device); - - free_blacklist(conf->elist_devnode); - free_blacklist(conf->elist_wwid); - free_blacklist(conf->elist_property); -+ free_blacklist(conf->elist_protocol); - free_blacklist_device(conf->elist_device); - - free_mptable(conf->mptable); -@@ -780,6 +782,12 @@ load_config (char * file) - if (!conf->blist_property) - goto out; - } -+ if (conf->blist_protocol == NULL) { -+ conf->blist_protocol = vector_alloc(); -+ -+ if (!conf->blist_protocol) -+ goto out; -+ } - - if (conf->elist_devnode == NULL) { - conf->elist_devnode = vector_alloc(); -@@ -807,6 +815,13 @@ load_config (char * file) - if (!conf->elist_property) - goto out; - } -+ if (conf->elist_protocol == NULL) { -+ conf->elist_protocol = vector_alloc(); -+ -+ if (!conf->elist_protocol) -+ goto out; -+ } -+ - if (setup_default_blist(conf)) - goto out; - -diff --git a/libmultipath/config.h b/libmultipath/config.h -index 6bd42f0..7d0cd9a 100644 ---- a/libmultipath/config.h -+++ b/libmultipath/config.h -@@ -210,10 +210,12 @@ struct config { - vector blist_wwid; - vector blist_device; - vector blist_property; -+ vector blist_protocol; - vector elist_devnode; - vector elist_wwid; - vector elist_device; - vector elist_property; -+ vector elist_protocol; - }; - - extern struct udev * udev; -diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 15e7582..32524d5 100644 ---- a/libmultipath/dict.c -+++ b/libmultipath/dict.c -@@ -1291,9 +1291,12 @@ blacklist_handler(struct config *conf, vector strvec) - conf->blist_device = vector_alloc(); - if (!conf->blist_property) - conf->blist_property = vector_alloc(); -+ if (!conf->blist_protocol) -+ conf->blist_protocol = vector_alloc(); - - if (!conf->blist_devnode || !conf->blist_wwid || -- !conf->blist_device || !conf->blist_property) -+ !conf->blist_device || !conf->blist_property || -+ !conf->blist_protocol) - return 1; - - return 0; -@@ -1310,9 +1313,12 @@ blacklist_exceptions_handler(struct config *conf, vector strvec) - conf->elist_device = vector_alloc(); - if (!conf->elist_property) - conf->elist_property = vector_alloc(); -+ if (!conf->elist_protocol) -+ conf->elist_protocol = vector_alloc(); - - if (!conf->elist_devnode || !conf->elist_wwid || -- !conf->elist_device || !conf->elist_property) -+ !conf->elist_device || !conf->elist_property || -+ !conf->elist_protocol) - return 1; - - return 0; -@@ -1356,6 +1362,8 @@ declare_ble_handler(blist_wwid) - declare_ble_handler(elist_wwid) - declare_ble_handler(blist_property) - declare_ble_handler(elist_property) -+declare_ble_handler(blist_protocol) -+declare_ble_handler(elist_protocol) - - static int - snprint_def_uxsock_timeout(struct config *conf, char * buff, int len, -@@ -1627,6 +1635,7 @@ init_keywords(vector keywords) - install_keyword_multi("devnode", &ble_blist_devnode_handler, &snprint_ble_simple); - install_keyword_multi("wwid", &ble_blist_wwid_handler, &snprint_ble_simple); - install_keyword_multi("property", &ble_blist_property_handler, &snprint_ble_simple); -+ install_keyword_multi("protocol", &ble_blist_protocol_handler, &snprint_ble_simple); - install_keyword_multi("device", &ble_device_handler, NULL); - install_sublevel(); - install_keyword("vendor", &ble_blist_device_vendor_handler, &snprint_bled_vendor); -@@ -1636,6 +1645,7 @@ init_keywords(vector keywords) - install_keyword_multi("devnode", &ble_elist_devnode_handler, &snprint_ble_simple); - install_keyword_multi("wwid", &ble_elist_wwid_handler, &snprint_ble_simple); - install_keyword_multi("property", &ble_elist_property_handler, &snprint_ble_simple); -+ install_keyword_multi("protocol", &ble_elist_protocol_handler, &snprint_ble_simple); - install_keyword_multi("device", &ble_except_device_handler, NULL); - install_sublevel(); - install_keyword("vendor", &ble_elist_device_vendor_handler, &snprint_bled_vendor); -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index 573d98b..e58a3fa 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1887,9 +1887,10 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id) > 0) { -+ pp->vendor_id, pp->product_id) > 0 || -+ filter_protocol(conf->blist_protocol, conf->elist_protocol, -+ pp) > 0) - return PATHINFO_SKIPPED; -- } - } - - path_state = path_offline(pp); -diff --git a/libmultipath/print.c b/libmultipath/print.c -index ecfcb48..9da6a77 100644 ---- a/libmultipath/print.c -+++ b/libmultipath/print.c -@@ -1688,6 +1688,19 @@ int snprint_blacklist_report(struct config *conf, char *buff, int len) - - if ((len - fwd - threshold) <= 0) - return len; -+ fwd += snprintf(buff + fwd, len - fwd, "protocol rules:\n" -+ "- blacklist:\n"); -+ if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_protocol)) -+ return len; -+ -+ if ((len - fwd - threshold) <= 0) -+ return len; -+ fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n"); -+ if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_protocol) == 0) -+ return len; -+ -+ if ((len - fwd - threshold) <= 0) -+ return len; - fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n" - "- blacklist:\n"); - if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0) -@@ -1761,6 +1774,15 @@ static int snprint_blacklist(const struct config *conf, char *buff, int len) - if (fwd >= len) - return len; - } -+ vector_foreach_slot (conf->blist_protocol, ble, i) { -+ kw = find_keyword(conf->keywords, rootkw->sub, "protocol"); -+ if (!kw) -+ return 0; -+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", -+ kw, ble); -+ if (fwd >= len) -+ return len; -+ } - rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); - if (!rootkw) - return 0; -@@ -1838,6 +1860,15 @@ static int snprint_blacklist_except(const struct config *conf, - if (fwd >= len) - return len; - } -+ vector_foreach_slot (conf->elist_protocol, ele, i) { -+ kw = find_keyword(conf->keywords, rootkw->sub, "protocol"); -+ if (!kw) -+ return 0; -+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n", -+ kw, ele); -+ if (fwd >= len) -+ return len; -+ } - rootkw = find_keyword(conf->keywords, rootkw->sub, "device"); - if (!rootkw) - return 0; -diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 -index fb863fd..6333366 100644 ---- a/multipath/multipath.conf.5 -+++ b/multipath/multipath.conf.5 -@@ -1205,9 +1205,21 @@ 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. -+.RS -+.PP -+The protocol strings that multipath recognizes are \fIscsi:fcp\fR, -+\fIscsi:spi\fR, \fIscsi:ssa\fR, \fIscsi:sbp\fR, \fIscsi:srp\fR, -+\fIscsi:iscsi\fR, \fIscsi:sas\fR, \fIscsi:adt\fR, \fIscsi:ata\fR, -+\fIscsi:unspec\fR, \fIccw\fR, \fIcciss\fR, \fInvme\fR, and \fIundef\fR. -+The protocol that a path is using can be viewed by running -+\fBmultipathd show paths format "%d %P"\fR -+.RE - .LP --For every device, these 4 blacklist criteria are evaluated in the the order --"property, dev\%node, device, wwid". If a device turns out to be -+For every device, these 5 blacklist criteria are evaluated in the the order -+"property, dev\%node, device, protocol, wwid". If a device turns out to be - blacklisted by any criterion, it's excluded from handling by multipathd, and - the later criteria aren't evaluated any more. For each - criterion, the whitelist takes precedence over the blacklist if a device --- -2.7.4 - diff --git a/0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch b/0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch new file mode 100644 index 0000000..aea9ed1 --- /dev/null +++ b/0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 27 Jul 2018 15:36:01 -0500 +Subject: [PATCH] libmultipath: fix length issues in get_vpd_sgio + +When get_vpd_sgio() finds out that the vpd info needed to be truncated +to fit in the buffer, it doesn't trucate the size as well, which allows +it to overwrite the buffer. Also, in once len is set to -ENODATA, +get_vpd_sgio() should exit, instead of using the negative len in +memcpy(). Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 0b1855d..3e0db7f 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1116,17 +1116,21 @@ get_vpd_sgio (int fd, int pg, char * str, int maxlen) + return -ENODATA; + } + buff_len = get_unaligned_be16(&buff[2]) + 4; +- if (buff_len > 4096) ++ if (buff_len > 4096) { + condlog(3, "vpd pg%02x page truncated", pg); +- ++ buff_len = 4096; ++ } + if (pg == 0x80) + len = parse_vpd_pg80(buff, str, maxlen); + else if (pg == 0x83) + len = parse_vpd_pg83(buff, buff_len, str, maxlen); + else if (pg == 0xc9 && maxlen >= 8) { +- len = buff_len < 8 ? -ENODATA : +- (buff_len <= maxlen ? buff_len : maxlen); +- memcpy (str, buff, len); ++ if (buff_len < 8) ++ len = -ENODATA; ++ else { ++ len = (buff_len <= maxlen)? buff_len : maxlen; ++ memcpy (str, buff, len); ++ } + } else + len = -ENOSYS; + +-- +2.7.4 + diff --git a/0008-libmultipath-_install_keyword-cleanup.patch b/0008-libmultipath-_install_keyword-cleanup.patch new file mode 100644 index 0000000..0976967 --- /dev/null +++ b/0008-libmultipath-_install_keyword-cleanup.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 27 Jul 2018 18:01:14 -0500 +Subject: [PATCH] libmultipath: _install_keyword cleanup + +_install_keyword should use VECTOR_LAST_SLOT(), which has better error +checking. It should also fail if it gets a NULL pointer, instead of +dereferencing it. Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/parser.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/parser.c b/libmultipath/parser.c +index b8b7e0d..92ef7cf 100644 +--- a/libmultipath/parser.c ++++ b/libmultipath/parser.c +@@ -79,12 +79,16 @@ _install_keyword(vector keywords, char *string, + struct keyword *keyword; + + /* fetch last keyword */ +- keyword = VECTOR_SLOT(keywords, VECTOR_SIZE(keywords) - 1); ++ keyword = VECTOR_LAST_SLOT(keywords); ++ if (!keyword) ++ return 1; + + /* position to last sub level */ +- for (i = 0; i < sublevel; i++) +- keyword = +- VECTOR_SLOT(keyword->sub, VECTOR_SIZE(keyword->sub) - 1); ++ for (i = 0; i < sublevel; i++) { ++ keyword = VECTOR_LAST_SLOT(keyword->sub); ++ if (!keyword) ++ return 1; ++ } + + /* First sub level allocation */ + if (!keyword->sub) +-- +2.7.4 + diff --git a/0008-libmultipath-remove-_filter_-blacklist-functions.patch b/0008-libmultipath-remove-_filter_-blacklist-functions.patch deleted file mode 100644 index b8e8e07..0000000 --- a/0008-libmultipath-remove-_filter_-blacklist-functions.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 3 Jul 2018 19:15:03 -0500 -Subject: [PATCH] libmultipath: remove _filter_* blacklist functions - -The one point of these functions was for _filter_path(), and that wasn't -improved by using them. Since filter_path() only printed one message at -the end, you could have situations where the wwid was blacklisted, but -the blacklist message included the vendor/product instead. Also, the -protocol and property messages were printed twice, and if the device was -on multiple whitelists, only the last one is printed. - -Signed-off-by: Benjamin Marzinski ---- - libmultipath/blacklist.c | 168 +++++++++++++++++++---------------------------- - libmultipath/blacklist.h | 2 +- - libmultipath/configure.c | 2 +- - libmultipath/discovery.c | 2 +- - 4 files changed, 71 insertions(+), 103 deletions(-) - -diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c -index fdd36f7..318ec03 100644 ---- a/libmultipath/blacklist.c -+++ b/libmultipath/blacklist.c -@@ -294,161 +294,129 @@ log_filter (const char *dev, char *vendor, char *product, char *wwid, - } - - int --_filter_device (vector blist, vector elist, char * vendor, char * product) -+filter_device (vector blist, vector elist, char * vendor, char * product, -+ char * dev) - { -- if (!vendor || !product) -- return 0; -- if (_blacklist_exceptions_device(elist, vendor, product)) -- return MATCH_DEVICE_BLIST_EXCEPT; -- if (_blacklist_device(blist, vendor, product)) -- return MATCH_DEVICE_BLIST; -- return 0; --} -+ int r = MATCH_NOTHING; - --int --filter_device (vector blist, vector elist, char * vendor, char * product) --{ -- int r = _filter_device(blist, elist, vendor, product); -- log_filter(NULL, vendor, product, NULL, NULL, NULL, r); -- return r; --} -+ if (vendor && product) { -+ if (_blacklist_exceptions_device(elist, vendor, product)) -+ r = MATCH_DEVICE_BLIST_EXCEPT; -+ else if (_blacklist_device(blist, vendor, product)) -+ r = MATCH_DEVICE_BLIST; -+ } - --int --_filter_devnode (vector blist, vector elist, char * dev) --{ -- if (!dev) -- return 0; -- if (_blacklist_exceptions(elist, dev)) -- return MATCH_DEVNODE_BLIST_EXCEPT; -- if (_blacklist(blist, dev)) -- return MATCH_DEVNODE_BLIST; -- return 0; -+ log_filter(dev, vendor, product, NULL, NULL, NULL, r); -+ return r; - } - - int - filter_devnode (vector blist, vector elist, char * dev) - { -- int r = _filter_devnode(blist, elist, dev); -+ int r = MATCH_NOTHING; -+ -+ if (dev) { -+ if (_blacklist_exceptions(elist, dev)) -+ r = MATCH_DEVNODE_BLIST_EXCEPT; -+ else if (_blacklist(blist, dev)) -+ r = MATCH_DEVNODE_BLIST; -+ } -+ - log_filter(dev, NULL, NULL, NULL, NULL, NULL, r); - return r; - } - - int --_filter_wwid (vector blist, vector elist, char * wwid) --{ -- if (!wwid) -- return 0; -- if (_blacklist_exceptions(elist, wwid)) -- return MATCH_WWID_BLIST_EXCEPT; -- if (_blacklist(blist, wwid)) -- return MATCH_WWID_BLIST; -- return 0; --} -- --int - filter_wwid (vector blist, vector elist, char * wwid, char * dev) - { -- int r = _filter_wwid(blist, elist, wwid); -+ int r = MATCH_NOTHING; -+ -+ if (wwid) { -+ if (_blacklist_exceptions(elist, wwid)) -+ r = MATCH_WWID_BLIST_EXCEPT; -+ else if (_blacklist(blist, wwid)) -+ r = MATCH_WWID_BLIST; -+ } -+ - log_filter(dev, NULL, NULL, wwid, NULL, NULL, r); - return r; - } - --static int --_filter_protocol (vector blist, vector elist, const char * protocol_str) --{ -- if (_blacklist_exceptions(elist, protocol_str)) -- return MATCH_PROTOCOL_BLIST_EXCEPT; -- if (_blacklist(blist, protocol_str)) -- return MATCH_PROTOCOL_BLIST; -- return 0; --} -- - int - filter_protocol(vector blist, vector elist, struct path * pp) - { - char buf[PROTOCOL_BUF_SIZE]; -- int r; -+ int r = MATCH_NOTHING; -+ -+ if (pp) { -+ snprint_path_protocol(buf, sizeof(buf), pp); -+ -+ if (_blacklist_exceptions(elist, buf)) -+ r = MATCH_PROTOCOL_BLIST_EXCEPT; -+ else if (_blacklist(blist, buf)) -+ r = MATCH_PROTOCOL_BLIST; -+ } - -- snprint_path_protocol(buf, sizeof(buf), pp); -- r = _filter_protocol(blist, elist, buf); - log_filter(pp->dev, NULL, NULL, NULL, NULL, buf, r); - return r; - } - - int --_filter_path (struct config * conf, struct path * pp) -+filter_path (struct config * conf, struct path * pp) - { - int r; - - r = filter_property(conf, pp->udev); - if (r > 0) - return r; -- r = _filter_devnode(conf->blist_devnode, conf->elist_devnode,pp->dev); -+ r = filter_devnode(conf->blist_devnode, conf->elist_devnode, pp->dev); - if (r > 0) - return r; -- r = _filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id); -+ r = filter_device(conf->blist_device, conf->elist_device, -+ pp->vendor_id, pp->product_id, pp->dev); - if (r > 0) - return r; - r = filter_protocol(conf->blist_protocol, conf->elist_protocol, pp); - if (r > 0) - return r; -- r = _filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid); -+ r = filter_wwid(conf->blist_wwid, conf->elist_wwid, pp->wwid, pp->dev); - return r; - } - - int --filter_path (struct config * conf, struct path * pp) --{ -- int r=_filter_path(conf, pp); -- log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, -- NULL, r); -- return r; --} -- --int --_filter_property (struct config *conf, const char *env) --{ -- if (_blacklist_exceptions(conf->elist_property, env)) -- return MATCH_PROPERTY_BLIST_EXCEPT; -- if (_blacklist(conf->blist_property, env)) -- return MATCH_PROPERTY_BLIST; -- -- return 0; --} -- --int - filter_property(struct config * conf, struct udev_device * udev) - { - const char *devname = udev_device_get_sysname(udev); - struct udev_list_entry *list_entry; -- int r; -- -- if (!udev) -- return 0; -- -- udev_list_entry_foreach(list_entry, -+ const char *env = NULL; -+ int r = MATCH_NOTHING; -+ -+ if (udev) { -+ /* -+ * This is the inverse of the 'normal' matching; -+ * the environment variable _has_ to match. -+ */ -+ r = MATCH_PROPERTY_BLIST_MISSING; -+ udev_list_entry_foreach(list_entry, - udev_device_get_properties_list_entry(udev)) { -- const char *env; -- -- env = udev_list_entry_get_name(list_entry); -- if (!env) -- continue; - -- r = _filter_property(conf, env); -- if (r) { -- log_filter(devname, NULL, NULL, NULL, env, NULL, r); -- return r; -+ env = udev_list_entry_get_name(list_entry); -+ if (!env) -+ continue; -+ if (_blacklist_exceptions(conf->elist_property, env)) { -+ r = MATCH_PROPERTY_BLIST_EXCEPT; -+ break; -+ } -+ if (_blacklist(conf->blist_property, env)) { -+ r = MATCH_PROPERTY_BLIST; -+ break; -+ } -+ env = NULL; - } - } - -- /* -- * This is the inverse of the 'normal' matching; -- * the environment variable _has_ to match. -- */ -- log_filter(devname, NULL, NULL, NULL, NULL, NULL, -- MATCH_PROPERTY_BLIST_MISSING); -- return MATCH_PROPERTY_BLIST_MISSING; -+ log_filter(devname, NULL, NULL, NULL, env, NULL, r); -+ return r; - } - - static void free_ble(struct blentry *ble) -diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h -index f7beef2..18903b6 100644 ---- a/libmultipath/blacklist.h -+++ b/libmultipath/blacklist.h -@@ -35,7 +35,7 @@ int setup_default_blist (struct config *); - int alloc_ble_device (vector); - int filter_devnode (vector, vector, char *); - int filter_wwid (vector, vector, char *, char *); --int filter_device (vector, vector, char *, char *); -+int filter_device (vector, vector, char *, char *, char *); - int filter_path (struct config *, struct path *); - int filter_property(struct config *, struct udev_device *); - int filter_protocol(vector, vector, struct path *); -diff --git a/libmultipath/configure.c b/libmultipath/configure.c -index 5c54f9b..09c3dcf 100644 ---- a/libmultipath/configure.c -+++ b/libmultipath/configure.c -@@ -1030,7 +1030,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, - invalid = 1; - pthread_cleanup_pop(1); - if (invalid) { -- orphan_path(pp1, "wwid blacklisted"); -+ orphan_path(pp1, "blacklisted"); - continue; - } - -diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c -index e58a3fa..0b1855d 100644 ---- a/libmultipath/discovery.c -+++ b/libmultipath/discovery.c -@@ -1887,7 +1887,7 @@ int pathinfo(struct path *pp, struct config *conf, int mask) - - if (mask & DI_BLACKLIST && mask & DI_SYSFS) { - if (filter_device(conf->blist_device, conf->elist_device, -- pp->vendor_id, pp->product_id) > 0 || -+ pp->vendor_id, pp->product_id, pp->dev) > 0 || - filter_protocol(conf->blist_protocol, conf->elist_protocol, - pp) > 0) - return PATHINFO_SKIPPED; --- -2.7.4 - diff --git a/0009-libmultipath-remove-unused-code.patch b/0009-libmultipath-remove-unused-code.patch new file mode 100644 index 0000000..7780391 --- /dev/null +++ b/0009-libmultipath-remove-unused-code.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 30 Jul 2018 14:28:02 -0500 +Subject: [PATCH] libmultipath: remove unused code + +since vector_foreach_slot() already checks if the entry is NULL, there's +no point in checking it in the loop, since it can't be NULL there. Found +by coverity. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/print.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/libmultipath/print.c b/libmultipath/print.c +index 9da6a77..7b610b9 100644 +--- a/libmultipath/print.c ++++ b/libmultipath/print.c +@@ -275,8 +275,6 @@ snprint_multipath_vpr (char * buff, size_t len, const struct multipath * mpp) + int i, j; + + vector_foreach_slot(mpp->pg, pgp, i) { +- if (!pgp) +- continue; + vector_foreach_slot(pgp->paths, pp, j) { + if (strlen(pp->vendor_id) && strlen(pp->product_id)) + return snprintf(buff, len, "%s,%s", +@@ -295,8 +293,6 @@ snprint_multipath_vend (char * buff, size_t len, const struct multipath * mpp) + int i, j; + + vector_foreach_slot(mpp->pg, pgp, i) { +- if (!pgp) +- continue; + vector_foreach_slot(pgp->paths, pp, j) { + if (strlen(pp->vendor_id)) + return snprintf(buff, len, "%s", pp->vendor_id); +@@ -313,8 +309,6 @@ snprint_multipath_prod (char * buff, size_t len, const struct multipath * mpp) + int i, j; + + vector_foreach_slot(mpp->pg, pgp, i) { +- if (!pgp) +- continue; + vector_foreach_slot(pgp->paths, pp, j) { + if (strlen(pp->product_id)) + return snprintf(buff, len, "%s", pp->product_id); +@@ -331,8 +325,6 @@ snprint_multipath_rev (char * buff, size_t len, const struct multipath * mpp) + int i, j; + + vector_foreach_slot(mpp->pg, pgp, i) { +- if (!pgp) +- continue; + vector_foreach_slot(pgp->paths, pp, j) { + if (strlen(pp->rev)) + return snprintf(buff, len, "%s", pp->rev); +-- +2.7.4 + diff --git a/0009-multipath-tests-change-to-work-with-old-make-version.patch b/0009-multipath-tests-change-to-work-with-old-make-version.patch deleted file mode 100644 index 186015a..0000000 --- a/0009-multipath-tests-change-to-work-with-old-make-version.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Tue, 3 Jul 2018 19:59:33 -0500 -Subject: [PATCH] multipath tests: change to work with old make versions - -the $(file <) operation only works with make 4.2 and above. I tried -running the tests on an old machine and it failed. The $shell function -can do the same thing and multipath has been using that in its -Makefiles for a while. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/Makefile b/tests/Makefile -index 78755ed..d293c87 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -51,4 +51,4 @@ COLON:=: - $(multipathdir)/libmultipath.so Makefile - $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< $($@_TESTDEPS) $($@_OBJDEPS) \ - $(LIBDEPS) $($@_LIBDEPS) \ -- $(file <$<.wrap) $(foreach dep,$($@_TESTDEPS),$(file <$(dep).wrap)) -+ $(shell cat $<.wrap) $(foreach dep,$($@_TESTDEPS),$(shell cat $(dep).wrap)) --- -2.7.4 - diff --git a/0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch b/0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch new file mode 100644 index 0000000..f500c90 --- /dev/null +++ b/0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 30 Jul 2018 14:41:55 -0500 +Subject: [PATCH] libmultipath: fix memory issue in path_latency prio + +The path_latency prioriziter was assuming that prepare_directio_read() +always succeeds. However, it doesn't, and when it fails, the prioritizer +used buf without it pointing to alloced memory. Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/prioritizers/path_latency.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libmultipath/prioritizers/path_latency.c b/libmultipath/prioritizers/path_latency.c +index 765265c..eeee01e 100644 +--- a/libmultipath/prioritizers/path_latency.c ++++ b/libmultipath/prioritizers/path_latency.c +@@ -237,7 +237,8 @@ int getprio(struct path *pp, char *args, unsigned int timeout) + lg_maxavglatency = log(MAX_AVG_LATENCY) / lg_base; + lg_minavglatency = log(MIN_AVG_LATENCY) / lg_base; + +- prepare_directio_read(pp->fd, &blksize, &buf, &restore_flags); ++ if (prepare_directio_read(pp->fd, &blksize, &buf, &restore_flags) < 0) ++ return PRIO_UNDEF; + + temp = io_num; + while (temp-- > 0) { +-- +2.7.4 + diff --git a/0010-multipath-tests-add-blacklist-tests.patch b/0010-multipath-tests-add-blacklist-tests.patch deleted file mode 100644 index cf7eff8..0000000 --- a/0010-multipath-tests-add-blacklist-tests.patch +++ /dev/null @@ -1,559 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Thu, 12 Jul 2018 17:53:38 -0500 -Subject: [PATCH] multipath tests: add blacklist tests - -These are tests to validate the filter_* blacklist functions. They not -only verify that the device is correctly blacklisted/whitelisted, but -they also verify the log messages that are printed out. - -Signed-off-by: Benjamin Marzinski ---- - tests/Makefile | 4 +- - tests/blacklist.c | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 515 insertions(+), 1 deletion(-) - create mode 100644 tests/blacklist.c - -diff --git a/tests/Makefile b/tests/Makefile -index d293c87..98b5c93 100644 ---- a/tests/Makefile -+++ b/tests/Makefile -@@ -3,7 +3,7 @@ include ../Makefile.inc - CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) - LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka - --TESTS := uevent parser util dmevents hwtable -+TESTS := uevent parser util dmevents hwtable blacklist - - .SILENT: $(TESTS:%=%.o) - .PRECIOUS: $(TESTS:%=%-test) -@@ -23,6 +23,8 @@ hwtable-test_TESTDEPS := test-lib.o - hwtable-test_OBJDEPS := ../libmultipath/discovery.o ../libmultipath/blacklist.o \ - ../libmultipath/prio.o ../libmultipath/callout.o ../libmultipath/structs.o - hwtable-test_LIBDEPS := -ludev -lpthread -ldl -+blacklist-test_OBJDEPS := ../libmultipath/blacklist.o -+blacklist-test_LIBDEPS := -ludev - - %.out: %-test - @echo == running $< == -diff --git a/tests/blacklist.c b/tests/blacklist.c -new file mode 100644 -index 0000000..a55c1c0 ---- /dev/null -+++ b/tests/blacklist.c -@@ -0,0 +1,512 @@ -+/* -+ * Copyright (c) 2018 Benjamin Marzinski, Redhat -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+#include -+#include -+#include -+#include -+#include "globals.c" -+#include "blacklist.h" -+#include "log.h" -+ -+struct udev_device { -+ const char *sysname; -+ char *property_list[]; -+}; -+ -+const char * -+__wrap_udev_device_get_sysname(struct udev_device *udev_device) -+{ -+ assert_non_null(udev_device); -+ assert_non_null(udev_device->sysname); -+ return udev_device->sysname; -+} -+ -+struct udev_list_entry * -+__wrap_udev_device_get_properties_list_entry(struct udev_device *udev_device) -+{ -+ assert_non_null(udev_device); -+ if (!udev_device->property_list) -+ return NULL; -+ if (!*udev_device->property_list) -+ return NULL; -+ return (struct udev_list_entry *)udev_device->property_list; -+} -+ -+struct udev_list_entry * -+__wrap_udev_list_entry_get_next(struct udev_list_entry *list_entry) -+{ -+ assert_non_null(list_entry); -+ if (!*((char **)list_entry + 1)) -+ return NULL; -+ return (struct udev_list_entry *)(((char **)list_entry) + 1); -+} -+ -+const char * -+__wrap_udev_list_entry_get_name(struct udev_list_entry *list_entry) -+{ -+ return *(const char **)list_entry; -+} -+ -+void __wrap_dlog (int sink, int prio, const char * fmt, ...) -+{ -+ char buff[MAX_MSG_SIZE]; -+ va_list ap; -+ -+ assert_int_equal(prio, mock_type(int)); -+ va_start(ap, fmt); -+ vsnprintf(buff, MAX_MSG_SIZE, fmt, ap); -+ va_end(ap); -+ assert_string_equal(buff, mock_ptr_type(char *)); -+} -+ -+void expect_condlog(int prio, char *string) -+{ -+ will_return(__wrap_dlog, prio); -+ will_return(__wrap_dlog, string); -+} -+ -+vector blist_devnode_sdb; -+vector blist_all; -+vector blist_device_foo_bar; -+vector blist_device_all; -+vector blist_wwid_xyzzy; -+vector blist_protocol_fcp; -+vector blist_property_wwn; -+ -+static int setup(void **state) -+{ -+ blist_devnode_sdb = vector_alloc(); -+ if (!blist_devnode_sdb || -+ store_ble(blist_devnode_sdb, strdup("sdb"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_all = vector_alloc(); -+ if (!blist_all || store_ble(blist_all, strdup(".*"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_device_foo_bar = vector_alloc(); -+ if (!blist_device_foo_bar || alloc_ble_device(blist_device_foo_bar) || -+ set_ble_device(blist_device_foo_bar, strdup("foo"), strdup("bar"), -+ ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_device_all = vector_alloc(); -+ if (!blist_device_all || alloc_ble_device(blist_device_all) || -+ set_ble_device(blist_device_all, strdup(".*"), strdup(".*"), -+ ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_wwid_xyzzy = vector_alloc(); -+ if (!blist_wwid_xyzzy || -+ store_ble(blist_wwid_xyzzy, strdup("xyzzy"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_protocol_fcp = vector_alloc(); -+ if (!blist_protocol_fcp || -+ store_ble(blist_protocol_fcp, strdup("scsi:fcp"), ORIGIN_CONFIG)) -+ return -1; -+ -+ blist_property_wwn = vector_alloc(); -+ if (!blist_property_wwn || -+ store_ble(blist_property_wwn, strdup("ID_WWN"), ORIGIN_CONFIG)) -+ return -1; -+ -+ return 0; -+} -+ -+static int teardown(void **state) -+{ -+ free_blacklist(blist_devnode_sdb); -+ free_blacklist(blist_all); -+ free_blacklist_device(blist_device_foo_bar); -+ free_blacklist_device(blist_device_all); -+ free_blacklist(blist_wwid_xyzzy); -+ free_blacklist(blist_protocol_fcp); -+ free_blacklist(blist_property_wwn); -+ return 0; -+} -+ -+static int reset_blists(void **state) -+{ -+ conf.blist_devnode = NULL; -+ conf.blist_wwid = NULL; -+ conf.blist_property = NULL; -+ conf.blist_protocol = NULL; -+ conf.blist_device = NULL; -+ conf.elist_devnode = NULL; -+ conf.elist_wwid = NULL; -+ conf.elist_property = NULL; -+ conf.elist_protocol = NULL; -+ conf.elist_device = NULL; -+ return 0; -+} -+ -+static void test_devnode_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdb"), -+ MATCH_DEVNODE_BLIST); -+} -+ -+static void test_devnode_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ assert_int_equal(filter_devnode(blist_all, blist_devnode_sdb, "sdb"), -+ MATCH_DEVNODE_BLIST_EXCEPT); -+ expect_condlog(3, "sdc: device node name blacklisted\n"); -+ assert_int_equal(filter_devnode(blist_all, blist_devnode_sdb, "sdc"), -+ MATCH_DEVNODE_BLIST); -+} -+ -+static void test_devnode_missing(void **state) -+{ -+ assert_int_equal(filter_devnode(blist_devnode_sdb, NULL, "sdc"), -+ MATCH_NOTHING); -+} -+ -+static void test_device_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", -+ "bar", "sdb"), -+ MATCH_DEVICE_BLIST); -+} -+ -+static void test_device_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ assert_int_equal(filter_device(blist_device_all, blist_device_foo_bar, -+ "foo", "bar", "sdb"), -+ MATCH_DEVICE_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: (foo:baz) vendor/product blacklisted\n"); -+ assert_int_equal(filter_device(blist_device_all, blist_device_foo_bar, -+ "foo", "baz", "sdb"), -+ MATCH_DEVICE_BLIST); -+} -+ -+static void test_device_missing(void **state) -+{ -+ assert_int_equal(filter_device(blist_device_foo_bar, NULL, "foo", -+ "baz", "sdb"), -+ MATCH_NOTHING); -+} -+ -+static void test_wwid_blacklist(void **state) -+{ -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "xyzzy", "sdb"), -+ MATCH_WWID_BLIST); -+} -+ -+static void test_wwid_whitelist(void **state) -+{ -+ expect_condlog(3, "sdb: wwid xyzzy whitelisted\n"); -+ assert_int_equal(filter_wwid(blist_all, blist_wwid_xyzzy, -+ "xyzzy", "sdb"), -+ MATCH_WWID_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: wwid plugh blacklisted\n"); -+ assert_int_equal(filter_wwid(blist_all, blist_wwid_xyzzy, -+ "plugh", "sdb"), -+ MATCH_WWID_BLIST); -+} -+ -+static void test_wwid_missing(void **state) -+{ -+ assert_int_equal(filter_wwid(blist_wwid_xyzzy, NULL, "plugh", "sdb"), -+ MATCH_NOTHING); -+} -+ -+static void test_protocol_blacklist(void **state) -+{ -+ struct path pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP }; -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), -+ MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_protocol_whitelist(void **state) -+{ -+ struct path pp1 = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP }; -+ struct path pp2 = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI }; -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ assert_int_equal(filter_protocol(blist_all, blist_protocol_fcp, &pp1), -+ MATCH_PROTOCOL_BLIST_EXCEPT); -+ expect_condlog(3, "sdb: protocol scsi:iscsi blacklisted\n"); -+ assert_int_equal(filter_protocol(blist_all, blist_protocol_fcp, &pp2), -+ MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_protocol_missing(void **state) -+{ -+ struct path pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI }; -+ assert_int_equal(filter_protocol(blist_protocol_fcp, NULL, &pp), -+ MATCH_NOTHING); -+} -+ -+static void test_property_blacklist(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_property(&conf, &udev), MATCH_PROPERTY_BLIST); -+} -+ -+/* the property check works different in that you check all the property -+ * names, so setting a blacklist value will blacklist the device if any -+ * of the property on the blacklist are found before the property names -+ * in the whitelist. This might be worth changing. although it would -+ * force multipath to go through the properties twice */ -+static void test_property_whitelist(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ conf.elist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ assert_int_equal(filter_property(&conf, &udev), -+ MATCH_PROPERTY_BLIST_EXCEPT); -+} -+ -+static void test_property_missing(void **state) -+{ -+ static struct udev_device udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", NULL } }; -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: blacklisted, udev property missing\n"); -+ assert_int_equal(filter_property(&conf, &udev), -+ MATCH_PROPERTY_BLIST_MISSING); -+} -+ -+struct udev_device test_udev = { "sdb", { "ID_FOO", "ID_WWN", "ID_BAR", NULL } }; -+ -+struct path test_pp = { .dev = "sdb", .bus = SYSFS_BUS_SCSI, .udev = &test_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_FCP, .vendor_id = "foo", -+ .product_id = "bar", .wwid = "xyzzy" }; -+ -+static void test_filter_path_property(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROPERTY_BLIST); -+} -+ -+static void test_filter_path_devnode(void **state) -+{ -+ /* always must include property elist, to avoid "missing property" -+ * blacklisting */ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVNODE_BLIST); -+} -+ -+static void test_filter_path_device(void **state) -+{ -+ /* always must include property elist, to avoid "missing property" -+ * blacklisting */ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_device = blist_device_foo_bar; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVICE_BLIST); -+} -+ -+static void test_filter_path_protocol(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_protocol = blist_protocol_fcp; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_filter_path_wwid(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_WWID_BLIST); -+} -+ -+struct udev_device miss_udev = { "sdb", { "ID_FOO", "ID_BAZ", "ID_BAR", NULL } }; -+ -+struct path miss1_pp = { .dev = "sdc", .bus = SYSFS_BUS_SCSI, -+ .udev = &miss_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI, -+ .vendor_id = "foo", .product_id = "baz", -+ .wwid = "plugh" }; -+ -+struct path miss2_pp = { .dev = "sdc", .bus = SYSFS_BUS_SCSI, -+ .udev = &test_udev, -+ .sg_id.proto_id = SCSI_PROTOCOL_ISCSI, -+ .vendor_id = "foo", .product_id = "baz", -+ .wwid = "plugh" }; -+ -+static void test_filter_path_missing1(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ 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); -+} -+ -+/* This one matches the property whitelist, to test the other missing -+ * functions */ -+static void test_filter_path_missing2(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ conf.blist_device = blist_device_foo_bar; -+ conf.blist_protocol = blist_protocol_fcp; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ assert_int_equal(filter_path(&conf, &miss2_pp), -+ MATCH_NOTHING); -+} -+ -+static void test_filter_path_whitelist(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy whitelisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), -+ MATCH_WWID_BLIST_EXCEPT); -+} -+ -+static void test_filter_path_whitelist_property(void **state) -+{ -+ conf.blist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROPERTY_BLIST); -+} -+ -+static void test_filter_path_whitelist_devnode(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.blist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVNODE_BLIST); -+} -+ -+static void test_filter_path_whitelist_device(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.blist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_DEVICE_BLIST); -+} -+ -+static void test_filter_path_whitelist_protocol(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.blist_protocol = blist_protocol_fcp; -+ conf.elist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_PROTOCOL_BLIST); -+} -+ -+static void test_filter_path_whitelist_wwid(void **state) -+{ -+ conf.elist_property = blist_property_wwn; -+ conf.elist_devnode = blist_devnode_sdb; -+ conf.elist_device = blist_device_foo_bar; -+ conf.elist_protocol = blist_protocol_fcp; -+ conf.blist_wwid = blist_wwid_xyzzy; -+ expect_condlog(3, "sdb: udev property ID_WWN whitelisted\n"); -+ expect_condlog(3, "sdb: device node name whitelisted\n"); -+ expect_condlog(3, "sdb: (foo:bar) vendor/product whitelisted\n"); -+ expect_condlog(3, "sdb: protocol scsi:fcp whitelisted\n"); -+ expect_condlog(3, "sdb: wwid xyzzy blacklisted\n"); -+ assert_int_equal(filter_path(&conf, &test_pp), MATCH_WWID_BLIST); -+} -+ -+#define test_and_reset(x) cmocka_unit_test_teardown((x), reset_blists) -+ -+int test_blacklist(void) -+{ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test(test_devnode_blacklist), -+ cmocka_unit_test(test_devnode_whitelist), -+ cmocka_unit_test(test_devnode_missing), -+ cmocka_unit_test(test_device_blacklist), -+ cmocka_unit_test(test_device_whitelist), -+ cmocka_unit_test(test_device_missing), -+ cmocka_unit_test(test_wwid_blacklist), -+ cmocka_unit_test(test_wwid_whitelist), -+ cmocka_unit_test(test_wwid_missing), -+ cmocka_unit_test(test_protocol_blacklist), -+ cmocka_unit_test(test_protocol_whitelist), -+ cmocka_unit_test(test_protocol_missing), -+ test_and_reset(test_property_blacklist), -+ test_and_reset(test_property_whitelist), -+ test_and_reset(test_property_missing), -+ test_and_reset(test_filter_path_property), -+ test_and_reset(test_filter_path_devnode), -+ test_and_reset(test_filter_path_device), -+ test_and_reset(test_filter_path_protocol), -+ test_and_reset(test_filter_path_wwid), -+ test_and_reset(test_filter_path_missing1), -+ test_and_reset(test_filter_path_missing2), -+ test_and_reset(test_filter_path_whitelist), -+ test_and_reset(test_filter_path_whitelist_property), -+ test_and_reset(test_filter_path_whitelist_devnode), -+ test_and_reset(test_filter_path_whitelist_device), -+ test_and_reset(test_filter_path_whitelist_protocol), -+ test_and_reset(test_filter_path_whitelist_wwid), -+ }; -+ return cmocka_run_group_tests(tests, setup, teardown); -+} -+ -+int main(void) -+{ -+ int ret = 0; -+ ret += test_blacklist(); -+ return ret; -+} --- -2.7.4 - diff --git a/0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch b/0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch new file mode 100644 index 0000000..d893f7b --- /dev/null +++ b/0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 30 Jul 2018 15:41:53 -0500 +Subject: [PATCH] libmultipath: fix null dereference int alloc_path_group + +If all_pathgroup failed to allocate a vector for pgp->paths, instead of +failing after it freed pgp, it would set pgp to NULL and then +dereference it. This patch fixes that. Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/structs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libmultipath/structs.c b/libmultipath/structs.c +index ae847d6..caa178a 100644 +--- a/libmultipath/structs.c ++++ b/libmultipath/structs.c +@@ -165,7 +165,7 @@ alloc_pathgroup (void) + + if (!pgp->paths) { + FREE(pgp); +- pgp = NULL; ++ return NULL; + } + + dm_pathgroup_to_gen(pgp)->ops = &dm_gen_pathgroup_ops; +-- +2.7.4 + diff --git a/0011-mpathpersist-add-missing-param-rk-usage-info.patch b/0011-mpathpersist-add-missing-param-rk-usage-info.patch deleted file mode 100644 index e05d9e6..0000000 --- a/0011-mpathpersist-add-missing-param-rk-usage-info.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Marzinski -Date: Mon, 16 Jul 2018 16:43:57 -0500 -Subject: [PATCH] mpathpersist: add missing --param-rk usage info - -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 99151fe..0e4d3f2 100644 ---- a/mpathpersist/main.c -+++ b/mpathpersist/main.c -@@ -705,6 +705,7 @@ static void usage(void) - " --param-alltgpt|-Y PR Out parameter 'ALL_TG_PT\n" - " --param-aptpl|-Z PR Out parameter 'APTPL'\n" - " --read-keys|-k PR In: Read Keys\n" -+ " --param-rk=RK|-K RK PR Out parameter reservation key\n" - " --param-sark=SARK|-S SARK PR Out parameter service " - "action\n" - " reservation key (SARK is in " --- -2.7.4 - diff --git a/0012-libmutipath-don-t-use-malformed-uevents.patch b/0012-libmutipath-don-t-use-malformed-uevents.patch new file mode 100644 index 0000000..1c860cc --- /dev/null +++ b/0012-libmutipath-don-t-use-malformed-uevents.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 30 Jul 2018 16:26:59 -0500 +Subject: [PATCH] libmutipath: don't use malformed uevents + +A uevent that doesn't include the ACTION and DEVPATH fields is +malformed. It should be ignored, instead of used with those fields being +NULL. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/uevent.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c +index fd8ca35..5f910e6 100644 +--- a/libmultipath/uevent.c ++++ b/libmultipath/uevent.c +@@ -729,6 +729,12 @@ struct uevent *uevent_from_udev_device(struct udev_device *dev) + if (i == HOTPLUG_NUM_ENVP - 1) + break; + } ++ if (!uev->devpath || ! uev->action) { ++ udev_device_unref(dev); ++ condlog(1, "uevent missing necessary fields"); ++ FREE(uev); ++ return NULL; ++ } + uev->udev = dev; + uev->envp[i] = NULL; + +-- +2.7.4 + diff --git a/0013-multipath-fix-max-array-size-in-print_cmd_valid.patch b/0013-multipath-fix-max-array-size-in-print_cmd_valid.patch new file mode 100644 index 0000000..e66cff1 --- /dev/null +++ b/0013-multipath-fix-max-array-size-in-print_cmd_valid.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Mon, 30 Jul 2018 18:06:11 -0500 +Subject: [PATCH] multipath: fix max array size in print_cmd_valid + +The code is attempting to verify that 0 <= k < 3 +However, sizeof(val) is 12, assuming 4 byte integers. The check needs to +take integer size into account. Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + multipath/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/multipath/main.c b/multipath/main.c +index fc5bf16..d5aad95 100644 +--- a/multipath/main.c ++++ b/multipath/main.c +@@ -482,7 +482,7 @@ static int print_cmd_valid(int k, const vector pathvec, + struct timespec until; + struct path *pp; + +- if (k < 0 || k >= sizeof(vals)) ++ if (k < 0 || k >= (sizeof(vals) / sizeof(int))) + return 1; + + if (k == 2) { +-- +2.7.4 + diff --git a/0014-multipathd-function-return-value-tweaks.patch b/0014-multipathd-function-return-value-tweaks.patch new file mode 100644 index 0000000..428971f --- /dev/null +++ b/0014-multipathd-function-return-value-tweaks.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jul 2018 12:04:43 -0500 +Subject: [PATCH] multipathd: function return value tweaks + +In cli_add_map() the return value of get_refwwid is never used, and +refwwid is checked to see if the function returned successfully, so the +return value doesn't need to be saved. + +In resize_map, if setup_map fails, multipathd shouldn't attempt to +create the device with resulting params string. It should just fail +instead. Found by coverity. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/cli_handlers.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c +index 5682b5c..bb16472 100644 +--- a/multipathd/cli_handlers.c ++++ b/multipathd/cli_handlers.c +@@ -796,8 +796,8 @@ cli_add_map (void * v, char ** reply, int * len, void * data) + if (!alias && !count) { + condlog(2, "%s: mapname not found for %d:%d", + param, major, minor); +- rc = get_refwwid(CMD_NONE, param, DEV_DEVMAP, +- vecs->pathvec, &refwwid); ++ get_refwwid(CMD_NONE, param, DEV_DEVMAP, ++ vecs->pathvec, &refwwid); + if (refwwid) { + if (coalesce_paths(vecs, NULL, refwwid, + FORCE_RELOAD_NONE, CMD_NONE)) +@@ -881,7 +881,12 @@ int resize_map(struct multipath *mpp, unsigned long long size, + + mpp->size = size; + update_mpp_paths(mpp, vecs->pathvec); +- setup_map(mpp, params, PARAMS_SIZE, vecs); ++ if (setup_map(mpp, params, PARAMS_SIZE, vecs) != 0) { ++ condlog(0, "%s: failed to setup map for resize : %s", ++ mpp->alias, strerror(errno)); ++ mpp->size = orig_size; ++ return 1; ++ } + mpp->action = ACT_RESIZE; + mpp->force_udev_reload = 1; + if (domap(mpp, params, 1) <= 0) { +-- +2.7.4 + diff --git a/0015-multipathd-minor-fixes.patch b/0015-multipathd-minor-fixes.patch new file mode 100644 index 0000000..b58a9c3 --- /dev/null +++ b/0015-multipathd-minor-fixes.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jul 2018 14:52:23 -0500 +Subject: [PATCH] multipathd: minor fixes + +In update_multipath(), conf is set again in a couple of lines, and +nothing uses it before then, so there's no point in setting it twice. +Also, in ev_remove_path(), strncpy() could end up unterminated, so +use strlcpy() instead. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index cc493c1..125a805 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -429,7 +429,7 @@ int update_multipath (struct vectors *vecs, char *mapname, int reset) + continue; + + if (pp->state != PATH_DOWN) { +- struct config *conf = get_multipath_config(); ++ struct config *conf; + int oldstate = pp->state; + int checkint; + +@@ -1096,7 +1096,7 @@ ev_remove_path (struct path *pp, struct vectors * vecs, int need_do_map) + /* + * flush_map will fail if the device is open + */ +- strncpy(alias, mpp->alias, WWID_SIZE); ++ strlcpy(alias, mpp->alias, WWID_SIZE); + if (mpp->flush_on_last_del == FLUSH_ENABLED) { + condlog(2, "%s Last path deleted, disabling queueing", mpp->alias); + mpp->retry_tick = 0; +-- +2.7.4 + diff --git a/0016-multipathd-remove-useless-check-and-fix-format.patch b/0016-multipathd-remove-useless-check-and-fix-format.patch new file mode 100644 index 0000000..acf3175 --- /dev/null +++ b/0016-multipathd-remove-useless-check-and-fix-format.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jul 2018 16:00:20 -0500 +Subject: [PATCH] multipathd: remove useless check and fix format + +The only thing this patch changes is to remove the check for pp->mpp +before the check for pp->mpp->prflags, since check_path() already +verified that pp->mpp != NULL. This fixes a number of coverity warnings. +Also, I normalized the spacing and indenting of the nearby code. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 125a805..3c2fe7b 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1978,14 +1978,14 @@ check_path (struct vectors * vecs, struct path * pp, int ticks) + return 1; + } + +- if(newstate == PATH_UP || newstate == PATH_GHOST){ +- if ( pp->mpp && pp->mpp->prflag ){ ++ if (newstate == PATH_UP || newstate == PATH_GHOST) { ++ if (pp->mpp->prflag) { + /* + * Check Persistent Reservation. + */ +- condlog(2, "%s: checking persistent reservation " +- "registration", pp->dev); +- mpath_pr_event_handle(pp); ++ condlog(2, "%s: checking persistent " ++ "reservation registration", pp->dev); ++ mpath_pr_event_handle(pp); + } + } + +-- +2.7.4 + diff --git a/0017-multipathd-fix-memory-leak-on-error-in-configure.patch b/0017-multipathd-fix-memory-leak-on-error-in-configure.patch new file mode 100644 index 0000000..60c19dc --- /dev/null +++ b/0017-multipathd-fix-memory-leak-on-error-in-configure.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 31 Jul 2018 16:35:53 -0500 +Subject: [PATCH] multipathd: fix memory leak on error in configure + +If configure fails after allocing mpvec, it must free it. Found by +coverity. + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 3c2fe7b..61ca455 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2277,7 +2277,7 @@ configure (struct vectors * vecs) + ret = path_discovery(vecs->pathvec, DI_ALL); + if (ret < 0) { + condlog(0, "configure failed at path discovery"); +- return 1; ++ goto fail; + } + + vector_foreach_slot (vecs->pathvec, pp, i){ +@@ -2294,7 +2294,7 @@ configure (struct vectors * vecs) + } + if (map_discovery(vecs)) { + condlog(0, "configure failed at map discovery"); +- return 1; ++ goto fail; + } + + /* +@@ -2308,7 +2308,7 @@ configure (struct vectors * vecs) + force_reload = FORCE_RELOAD_YES; + if (ret) { + condlog(0, "configure failed while coalescing paths"); +- return 1; ++ goto fail; + } + + /* +@@ -2317,7 +2317,7 @@ configure (struct vectors * vecs) + */ + if (coalesce_maps(vecs, mpvec)) { + condlog(0, "configure failed while coalescing maps"); +- return 1; ++ goto fail; + } + + dm_lib_release(); +@@ -2353,6 +2353,10 @@ configure (struct vectors * vecs) + i--; + } + return 0; ++ ++fail: ++ vector_free(mpvec); ++ return 1; + } + + int +-- +2.7.4 + diff --git a/0018-libmultipath-Don-t-blank-intialized-paths.patch b/0018-libmultipath-Don-t-blank-intialized-paths.patch new file mode 100644 index 0000000..37a8243 --- /dev/null +++ b/0018-libmultipath-Don-t-blank-intialized-paths.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 21 Sep 2018 16:03:35 -0500 +Subject: [PATCH] libmultipath: Don't blank intialized paths + +When pathinfo fails for some likely transient reason, it clears the path +wwid, but otherwise returns successfully, to keep the path around but +not usable until it gets fully initialized. However, if the path has +already been initialized, and pathinfo hits a transient error, it +shouldn't clear the wwid. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/discovery.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c +index 3e0db7f..33815dc 100644 +--- a/libmultipath/discovery.c ++++ b/libmultipath/discovery.c +@@ -1991,9 +1991,9 @@ blank: + /* + * Recoverable error, for example faulty or offline path + */ +- memset(pp->wwid, 0, WWID_SIZE); + pp->chkrstate = pp->state = PATH_DOWN; +- pp->initialized = INIT_FAILED; ++ if (pp->initialized == INIT_FAILED) ++ memset(pp->wwid, 0, WWID_SIZE); + + return PATHINFO_OK; + } +-- +2.7.4 + diff --git a/0019-libmultipath-Fixup-updating-paths.patch b/0019-libmultipath-Fixup-updating-paths.patch new file mode 100644 index 0000000..b8bef98 --- /dev/null +++ b/0019-libmultipath-Fixup-updating-paths.patch @@ -0,0 +1,94 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Fri, 21 Sep 2018 16:05:43 -0500 +Subject: [PATCH] libmultipath: Fixup updating paths + +Commit 582c56cc broke some code paths in uev_update_path. First, it +changed the handling of paths that were not fully initialized. +uev_update_path was simply setting the wwids for all of these paths. +Instead, it should ignore the ones that had not requested a new uevent. +These paths are likely down, and are already getting handled by +check_path, after it verifies that they have become active. Also, +setting the wwid doesn't update all of the other information that +may have been missed when the path was initially added. + +Also, it wasn't possible for pp->wwid_changed to transition back to +zero, unless the path's wwid was empty, in which case there was no +reason to worry about the wwid change in the first place, since the path +hadn't been fully initialized yet. So, even if a path's wwid changed and +then changed back to the original value, the path still could not be +used. + +This patch fixes these issues, and also moves the check for paths that +have requested a new uevent up in the functions. These paths will get +fully reinitialized anyway, so there is no reason to do all the other +work first. + +Fixes: 582c56cc ("libmultipath: uev_update_path: always warn if WWID +changed") + +Signed-off-by: Benjamin Marzinski +--- + multipathd/main.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/multipathd/main.c b/multipathd/main.c +index 61ca455..d6d122a 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -1207,6 +1207,15 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + struct multipath *mpp = pp->mpp; + char wwid[WWID_SIZE]; + ++ if (pp->initialized == INIT_REQUESTED_UDEV) { ++ needs_reinit = 1; ++ goto out; ++ } ++ /* Don't deal with other types of failed initialization ++ * now. check_path will handle it */ ++ if (!strlen(pp->wwid)) ++ goto out; ++ + strcpy(wwid, pp->wwid); + get_uid(pp, pp->state, uev->udev); + +@@ -1215,9 +1224,8 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + uev->kernel, wwid, pp->wwid, + (disable_changed_wwids ? "disallowing" : + "continuing")); +- if (disable_changed_wwids && +- (strlen(wwid) || pp->wwid_changed)) { +- strcpy(pp->wwid, wwid); ++ strcpy(pp->wwid, wwid); ++ if (disable_changed_wwids) { + if (!pp->wwid_changed) { + pp->wwid_changed = 1; + pp->tick = 1; +@@ -1225,11 +1233,9 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + dm_fail_path(pp->mpp->alias, pp->dev_t); + } + goto out; +- } else if (!disable_changed_wwids) +- strcpy(pp->wwid, wwid); +- else +- pp->wwid_changed = 0; ++ } + } else { ++ pp->wwid_changed = 0; + udev_device_unref(pp->udev); + pp->udev = udev_device_ref(uev->udev); + conf = get_multipath_config(); +@@ -1240,9 +1246,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs) + pthread_cleanup_pop(1); + } + +- if (pp->initialized == INIT_REQUESTED_UDEV) +- needs_reinit = 1; +- else if (mpp && ro >= 0) { ++ if (mpp && ro >= 0) { + condlog(2, "%s: update path write_protect to '%d' (uevent)", uev->kernel, ro); + + if (mpp->wait_for_udev) +-- +2.7.4 + diff --git a/0020-multipath-tweak-logging-style.patch b/0020-multipath-tweak-logging-style.patch new file mode 100644 index 0000000..121e734 --- /dev/null +++ b/0020-multipath-tweak-logging-style.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 26 Sep 2018 16:08:59 -0500 +Subject: [PATCH] multipath: tweak logging style + +When multipathd commands are run, errors should be printed to stderr, +instead of syslog. Also, when the multipath is run and calls +device-mapper, device-mapper should log to stderr instead of stdout, +just like multipath does now. + +Signed-off-by: Benjamin Marzinski +--- + libmultipath/devmapper.c | 8 ++++---- + multipathd/main.c | 2 ++ + 2 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c +index 8136d15..0433b49 100644 +--- a/libmultipath/devmapper.c ++++ b/libmultipath/devmapper.c +@@ -80,11 +80,11 @@ dm_write_log (int level, const char *file, int line, const char *f, ...) + strftime(buff, sizeof(buff), "%b %d %H:%M:%S", tb); + buff[sizeof(buff)-1] = '\0'; + +- fprintf(stdout, "%s | ", buff); ++ fprintf(stderr, "%s | ", buff); + } +- fprintf(stdout, "libdevmapper: %s(%i): ", file, line); +- vfprintf(stdout, f, ap); +- fprintf(stdout, "\n"); ++ fprintf(stderr, "libdevmapper: %s(%i): ", file, line); ++ vfprintf(stderr, f, ap); ++ fprintf(stderr, "\n"); + } else { + condlog(level, "libdevmapper: %s(%i): ", file, line); + log_safe(level + 3, f, ap); +diff --git a/multipathd/main.c b/multipathd/main.c +index d6d122a..3c1d89f 100644 +--- a/multipathd/main.c ++++ b/multipathd/main.c +@@ -2983,6 +2983,7 @@ main (int argc, char *argv[]) + logsink = -1; + break; + case 'k': ++ logsink = 0; + conf = load_config(DEFAULT_CONFIGFILE); + if (!conf) + exit(1); +@@ -3012,6 +3013,7 @@ main (int argc, char *argv[]) + char * s = cmd; + char * c = s; + ++ logsink = 0; + conf = load_config(DEFAULT_CONFIGFILE); + if (!conf) + exit(1); +-- +2.7.4 + diff --git a/0012-RH-fixup-udev-rules-for-redhat.patch b/0021-RH-fixup-udev-rules-for-redhat.patch similarity index 97% rename from 0012-RH-fixup-udev-rules-for-redhat.patch rename to 0021-RH-fixup-udev-rules-for-redhat.patch index 0c0fa55..8f08ae2 100644 --- a/0012-RH-fixup-udev-rules-for-redhat.patch +++ b/0021-RH-fixup-udev-rules-for-redhat.patch @@ -18,7 +18,7 @@ Signed-off-by: Benjamin Marzinski 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index af2f5ba..0b271ea 100644 +index a83f02c..b86cba6 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -51,7 +51,7 @@ endif @@ -65,7 +65,7 @@ index 0828a8f..b9bbb3c 100644 $(RM) $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz diff --git a/multipath/main.c b/multipath/main.c -index fc5bf16..39f6f1f 100644 +index d5aad95..8086b76 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -403,7 +403,7 @@ static int find_multipaths_check_timeout(const struct path *pp, long tmo, diff --git a/0013-RH-Remove-the-property-blacklist-exception-builtin.patch b/0022-RH-Remove-the-property-blacklist-exception-builtin.patch similarity index 100% rename from 0013-RH-Remove-the-property-blacklist-exception-builtin.patch rename to 0022-RH-Remove-the-property-blacklist-exception-builtin.patch diff --git a/0014-RH-don-t-start-without-a-config-file.patch b/0023-RH-don-t-start-without-a-config-file.patch similarity index 100% rename from 0014-RH-don-t-start-without-a-config-file.patch rename to 0023-RH-don-t-start-without-a-config-file.patch diff --git a/0015-RH-use-rpm-optflags-if-present.patch b/0024-RH-use-rpm-optflags-if-present.patch similarity index 85% rename from 0015-RH-use-rpm-optflags-if-present.patch rename to 0024-RH-use-rpm-optflags-if-present.patch index 9330bf0..dd221ac 100644 --- a/0015-RH-use-rpm-optflags-if-present.patch +++ b/0024-RH-use-rpm-optflags-if-present.patch @@ -13,19 +13,20 @@ Signed-off-by: Benjamin Marzinski 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Makefile.inc b/Makefile.inc -index 0b271ea..5ff69a3 100644 +index b86cba6..70accd7 100644 --- a/Makefile.inc +++ b/Makefile.inc -@@ -85,14 +85,22 @@ TEST_CC_OPTION = $(shell \ +@@ -85,15 +85,23 @@ TEST_CC_OPTION = $(shell \ echo "$(2)"; \ fi) -STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector) + ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,) - -OPTFLAGS = -O2 -g -pipe -Wall -Wextra -Wformat=2 -Werror=implicit-int \ - -Werror=implicit-function-declaration -Werror=format-security \ - -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered \ -- -Werror=cast-qual -Werror=discarded-qualifiers \ +- -Werror=cast-qual $(ERROR_DISCARDED_QUALIFIERS) \ - -Wp,-D_FORTIFY_SOURCE=2 $(STACKPROT) \ - --param=ssp-buffer-size=4 +ifndef RPM_OPT_FLAGS @@ -42,8 +43,8 @@ index 0b271ea..5ff69a3 100644 +endif +OPTFLAGS += -Wextra -Wstrict-prototypes -Wformat=2 -Werror=implicit-int \ + -Werror=implicit-function-declaration -Wno-sign-compare \ -+ -Wno-unused-parameter -Werror=cast-qual \ -+ -Werror=discarded-qualifiers ++ -Wno-unused-parameter $(ERROR_DISCARDED_QUALIFIERS) \ ++ -Werror=cast-qual CFLAGS := $(OPTFLAGS) -DBIN_DIR=\"$(bindir)\" -DLIB_STRING=\"${LIB}\" -DRUN_DIR=\"${RUN}\" \ -MMD -MP $(CFLAGS) diff --git a/0016-RH-add-mpathconf.patch b/0025-RH-add-mpathconf.patch similarity index 100% rename from 0016-RH-add-mpathconf.patch rename to 0025-RH-add-mpathconf.patch diff --git a/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch b/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch similarity index 99% rename from 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch rename to 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch index a8ccd2b..546c7c5 100644 --- a/0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +++ b/0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch @@ -86,7 +86,7 @@ index 0c6ee54..e32a0b0 100644 enum { WWID_IS_NOT_FAILED = 0, diff --git a/multipath/main.c b/multipath/main.c -index 39f6f1f..cc94f56 100644 +index 8086b76..85b60e8 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -122,7 +122,7 @@ usage (char * progname) diff --git a/0018-RH-warn-on-invalid-regex-instead-of-failing.patch b/0027-RH-warn-on-invalid-regex-instead-of-failing.patch similarity index 89% rename from 0018-RH-warn-on-invalid-regex-instead-of-failing.patch rename to 0027-RH-warn-on-invalid-regex-instead-of-failing.patch index b414639..aa64be1 100644 --- a/0018-RH-warn-on-invalid-regex-instead-of-failing.patch +++ b/0027-RH-warn-on-invalid-regex-instead-of-failing.patch @@ -16,10 +16,10 @@ Signed-off-by: Benjamin Marzinski 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libmultipath/dict.c b/libmultipath/dict.c -index 32524d5..cce05e7 100644 +index bf4701e..9d63d26 100644 --- a/libmultipath/dict.c +++ b/libmultipath/dict.c -@@ -55,6 +55,21 @@ set_str(vector strvec, void *ptr) +@@ -58,6 +58,21 @@ set_str(vector strvec, void *ptr) } static int @@ -41,7 +41,7 @@ index 32524d5..cce05e7 100644 set_yes_no(vector strvec, void *ptr) { char * buff; -@@ -1333,7 +1348,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ +@@ -1336,7 +1351,7 @@ ble_ ## option ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -50,7 +50,7 @@ index 32524d5..cce05e7 100644 if (!buff) \ return 1; \ \ -@@ -1349,7 +1364,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ +@@ -1352,7 +1367,7 @@ ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec) \ if (!conf->option) \ return 1; \ \ @@ -59,7 +59,7 @@ index 32524d5..cce05e7 100644 if (!buff) \ return 1; \ \ -@@ -1452,16 +1467,16 @@ device_handler(struct config *conf, vector strvec) +@@ -1455,16 +1470,16 @@ device_handler(struct config *conf, vector strvec) return 0; } @@ -81,10 +81,10 @@ index 32524d5..cce05e7 100644 declare_hw_handler(hwhandler, set_str) diff --git a/libmultipath/parser.c b/libmultipath/parser.c -index b8b7e0d..34b4ad2 100644 +index 92ef7cf..4289336 100644 --- a/libmultipath/parser.c +++ b/libmultipath/parser.c -@@ -380,6 +380,19 @@ set_value(vector strvec) +@@ -384,6 +384,19 @@ set_value(vector strvec) return alloc; } diff --git a/0019-RH-reset-default-find_mutipaths-value-to-off.patch b/0028-RH-reset-default-find_mutipaths-value-to-off.patch similarity index 100% rename from 0019-RH-reset-default-find_mutipaths-value-to-off.patch rename to 0028-RH-reset-default-find_mutipaths-value-to-off.patch diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 323b1a9..1d00631 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.7.7 -Release: 5.gitef6d98b%{?dist} +Release: 6.git1a8625a%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -8,27 +8,36 @@ 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=ef6d98b;sf=tgz" -o multipath-tools-ef6d98b.tgz -Source0: multipath-tools-ef6d98b.tgz +Source0: multipath-tools-1a8625a.tgz Source1: multipath.conf -Patch0001: 0001-libmultipath-remove-last-of-rbd-code.patch -Patch0002: 0002-libmultipath-fix-detect-alua-corner-case.patch -Patch0003: 0003-multipath-fix-setting-conf-version.patch -Patch0004: 0004-mpathpersist-add-param-alltgpt-option.patch -Patch0005: 0005-libmutipath-remove-unused-IDE-bus-type.patch -Patch0006: 0006-multipathd-add-new-protocol-path-wildcard.patch -Patch0007: 0007-libmultipath-add-protocol-blacklist-option.patch -Patch0008: 0008-libmultipath-remove-_filter_-blacklist-functions.patch -Patch0009: 0009-multipath-tests-change-to-work-with-old-make-version.patch -Patch0010: 0010-multipath-tests-add-blacklist-tests.patch -Patch0011: 0011-mpathpersist-add-missing-param-rk-usage-info.patch -Patch0012: 0012-RH-fixup-udev-rules-for-redhat.patch -Patch0013: 0013-RH-Remove-the-property-blacklist-exception-builtin.patch -Patch0014: 0014-RH-don-t-start-without-a-config-file.patch -Patch0015: 0015-RH-use-rpm-optflags-if-present.patch -Patch0016: 0016-RH-add-mpathconf.patch -Patch0017: 0017-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch -Patch0018: 0018-RH-warn-on-invalid-regex-instead-of-failing.patch -Patch0019: 0019-RH-reset-default-find_mutipaths-value-to-off.patch +Patch0001: 0001-libmultipath-fix-tur-checker-timeout.patch +Patch0002: 0002-libmultipath-fix-tur-checker-double-locking.patch +Patch0003: 0003-libmultipath-fix-tur-memory-misuse.patch +Patch0004: 0004-libmultipath-cleanup-tur-locking.patch +Patch0005: 0005-libmultipath-fix-tur-checker-timeout-issue.patch +Patch0006: 0006-libmultipath-fix-set_int-error-path.patch +Patch0007: 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch +Patch0008: 0008-libmultipath-_install_keyword-cleanup.patch +Patch0009: 0009-libmultipath-remove-unused-code.patch +Patch0010: 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch +Patch0011: 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch +Patch0012: 0012-libmutipath-don-t-use-malformed-uevents.patch +Patch0013: 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch +Patch0014: 0014-multipathd-function-return-value-tweaks.patch +Patch0015: 0015-multipathd-minor-fixes.patch +Patch0016: 0016-multipathd-remove-useless-check-and-fix-format.patch +Patch0017: 0017-multipathd-fix-memory-leak-on-error-in-configure.patch +Patch0018: 0018-libmultipath-Don-t-blank-intialized-paths.patch +Patch0019: 0019-libmultipath-Fixup-updating-paths.patch +Patch0020: 0020-multipath-tweak-logging-style.patch +Patch0021: 0021-RH-fixup-udev-rules-for-redhat.patch +Patch0022: 0022-RH-Remove-the-property-blacklist-exception-builtin.patch +Patch0023: 0023-RH-don-t-start-without-a-config-file.patch +Patch0024: 0024-RH-use-rpm-optflags-if-present.patch +Patch0025: 0025-RH-add-mpathconf.patch +Patch0026: 0026-RH-add-wwids-from-kernel-cmdline-mpath.wwids-with-A.patch +Patch0027: 0027-RH-warn-on-invalid-regex-instead-of-failing.patch +Patch0028: 0028-RH-reset-default-find_mutipaths-value-to-off.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -111,7 +120,7 @@ This package contains the files needed to develop applications that use device-mapper-multipath's libdmmp C API library %prep -%setup -q -n multipath-tools-ef6d98b +%setup -q -n multipath-tools-1a8625a %patch0001 -p1 %patch0002 -p1 %patch0003 -p1 @@ -131,6 +140,15 @@ device-mapper-multipath's libdmmp C API library %patch0017 -p1 %patch0018 -p1 %patch0019 -p1 +%patch0020 -p1 +%patch0021 -p1 +%patch0022 -p1 +%patch0023 -p1 +%patch0024 -p1 +%patch0025 -p1 +%patch0026 -p1 +%patch0027 -p1 +%patch0028 -p1 cp %{SOURCE1} . %build @@ -246,6 +264,39 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Thu Sep 27 2018 Benjamin Marzinski 0.7.7-6.git1a8625a +- Update Source to latest upstream commit + * Previous patches 0001-0011 are included in this commit +- Rename files + * Previous patches 0012-0019 are now patches 0021-0028 +- Add 0001-libmultipath-fix-tur-checker-timeout.patch +- Add 0002-libmultipath-fix-tur-checker-double-locking.patch +- Add 0003-libmultipath-fix-tur-memory-misuse.patch +- Add 0004-libmultipath-cleanup-tur-locking.patch +- Add 0005-libmultipath-fix-tur-checker-timeout-issue.patch + * The above 5 patches cleanup locking issues with the + tur checker threads +- Add 0006-libmultipath-fix-set_int-error-path.patch +- Add 0007-libmultipath-fix-length-issues-in-get_vpd_sgio.patch +- Add 0008-libmultipath-_install_keyword-cleanup.patch +- Add 0009-libmultipath-remove-unused-code.patch +- Add 0010-libmultipath-fix-memory-issue-in-path_latency-prio.patch +- Add 0011-libmultipath-fix-null-dereference-int-alloc_path_gro.patch +- Add 0012-libmutipath-don-t-use-malformed-uevents.patch +- Add 0013-multipath-fix-max-array-size-in-print_cmd_valid.patch +- Add 0014-multipathd-function-return-value-tweaks.patch +- Add 0015-multipathd-minor-fixes.patch +- Add 0016-multipathd-remove-useless-check-and-fix-format.patch +- Add 0017-multipathd-fix-memory-leak-on-error-in-configure.patch + * The above 12 patches fix minor issues found by coverity +- Add 0018-libmultipath-Don-t-blank-intialized-paths.patch +- Add 0019-libmultipath-Fixup-updating-paths.patch + * Fix issues with paths whose wwid was not set or later changes +- Add 0020-multipath-tweak-logging-style.patch + * multipathd interactive commands now send errors to stderr, instead + of syslog + * The above 20 patches have been submitted upstream + * Fri Sep 14 2018 Benjamin Marzinski 0.7.7-5.gitef6d98b - Add Conflicts for mdadm < 4.1-rc2.0.2 and udisks2 < 2.8.0-2 * Multipath udev rule update from 0.7.7-1 is incompatible with older versions diff --git a/sources b/sources index 8155f49..90a35d5 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (multipath-tools-ef6d98b.tgz) = 03ed4b01d653d91f8a76d98f2a25af817213310f55d5015b89f0d1a69c55390a9e5cb3cb441a38f0497b51716423cee2061b5ec49bfdb05812e70766a0e724ef +SHA512 (multipath-tools-1a8625a.tgz) = fc7763ec80f8df9ddafd2510dcc8cdc72f6870e5b3bad17e5580126042b5b4a3f4cbeb6517eb119c8ec82fed43dfd0def6a5e3cb60f08e7ad4f7802c169979ca SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942