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
This commit is contained in:
Benjamin Marzinski 2018-09-27 17:56:43 -05:00
parent 57b6cee02c
commit 3ec0ebefcd
42 changed files with 1361 additions and 1755 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,182 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bart.vanassche@wdc.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,150 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,144 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,152 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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<unset>\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

View File

@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Tue, 26 Jun 2018 16:45:48 -0500
Subject: [PATCH] libmutipath: remove unused IDE bus type
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/structs.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 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

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,92 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,425 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,296 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,31 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,559 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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 <https://www.gnu.org/licenses/>.
+ *
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#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

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Mon, 16 Jul 2018 16:43:57 -0500
Subject: [PATCH] mpathpersist: add missing --param-rk usage info
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
mpathpersist/main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/mpathpersist/main.c b/mpathpersist/main.c
index 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

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,50 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,42 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,67 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,94 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -0,0 +1,59 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
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 <bmarzins@redhat.com>
---
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

View File

@ -18,7 +18,7 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
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,

View File

@ -13,19 +13,20 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
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)

View File

@ -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)

View File

@ -16,10 +16,10 @@ Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
3 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
index 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;
}

View File

@ -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 <bmarzins@redhat.com> 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 <bmarzins@redhat.com> 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

View File

@ -1,2 +1,2 @@
SHA512 (multipath-tools-ef6d98b.tgz) = 03ed4b01d653d91f8a76d98f2a25af817213310f55d5015b89f0d1a69c55390a9e5cb3cb441a38f0497b51716423cee2061b5ec49bfdb05812e70766a0e724ef
SHA512 (multipath-tools-1a8625a.tgz) = fc7763ec80f8df9ddafd2510dcc8cdc72f6870e5b3bad17e5580126042b5b4a3f4cbeb6517eb119c8ec82fed43dfd0def6a5e3cb60f08e7ad4f7802c169979ca
SHA512 (multipath.conf) = 71953dce5a68adcf60a942305f5a66023e6f4c4baf53b1bfdb4edf65ed5b8e03db804363c36d1dcfd85591f4766f52b515269904c53b84d7b076da0b80b09942