170e923cae
Update Source to upstream version 0.7.9 * Previous patches 0001-0006 are included in this version Rename files * Previous patches 0007-0014 are now patches 0004-0011 Add 0001-multipathd-fix-mpp-hwe-handling-when-paths-are-freed.patch Add 0002-libmultipath-cleanup-pthread_cleanup_pop-call.patch Add 0003-libmultipath-fix-false-removes-in-dmevents-polling-c.patch * The above 3 patches have been submitted upstream
205 lines
6.1 KiB
Diff
205 lines
6.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
|
Date: Tue, 27 Nov 2018 22:50:57 -0600
|
|
Subject: [PATCH] libmultipath: fix false removes in dmevents polling code
|
|
|
|
dm_is_mpath() would return 0 if either a device was not a multipath
|
|
device or if the libdevmapper command failed. Because dm_is_mpath()
|
|
didn't distinguish between these situations, dm_get_events() could
|
|
assume that a device was not really a multipath device, when in fact it
|
|
was, and the libdevmapper command simply failed. This would cause the
|
|
dmevents polling waiter to stop monitoring the device.
|
|
|
|
In reality, the call to dm_is_mpath() isn't necessary, because
|
|
dm_get_events() will already verify that the device name is on the list
|
|
of devices to wait for. However, if there are a large number of
|
|
non-multipath devices on the system, ignoring them can be useful. Thus,
|
|
if dm_is_mpath() successfully runs the libdevmapper command and verifies
|
|
that the device is not a multipath device, dm_get_events() should skip
|
|
it. But if the libdevmapper command fails, dm_get_events() should still
|
|
check the device list, to see if the device should be monitored.
|
|
|
|
This commit makes dm_is_mpath() return -1 for situations where
|
|
the libdevmapper command failed, and makes dm_get_events() only ignore
|
|
the device on a return of 0.
|
|
|
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|
---
|
|
libmpathpersist/mpath_persist.c | 4 ++--
|
|
libmultipath/devmapper.c | 41 +++++++++++++++++++++++----------
|
|
multipath/main.c | 2 +-
|
|
multipathd/dmevents.c | 8 +++++--
|
|
multipathd/main.c | 2 +-
|
|
5 files changed, 39 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
|
|
index 2ffe56e..7e8a676 100644
|
|
--- a/libmpathpersist/mpath_persist.c
|
|
+++ b/libmpathpersist/mpath_persist.c
|
|
@@ -188,7 +188,7 @@ int mpath_persistent_reserve_in (int fd, int rq_servact,
|
|
|
|
condlog(3, "alias = %s", alias);
|
|
map_present = dm_map_present(alias);
|
|
- if (map_present && !dm_is_mpath(alias)){
|
|
+ if (map_present && dm_is_mpath(alias) != 1){
|
|
condlog( 0, "%s: not a multipath device.", alias);
|
|
ret = MPATH_PR_DMMP_ERROR;
|
|
goto out;
|
|
@@ -283,7 +283,7 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
|
|
condlog(3, "alias = %s", alias);
|
|
map_present = dm_map_present(alias);
|
|
|
|
- if (map_present && !dm_is_mpath(alias)){
|
|
+ if (map_present && dm_is_mpath(alias) != 1){
|
|
condlog(3, "%s: not a multipath device.", alias);
|
|
ret = MPATH_PR_DMMP_ERROR;
|
|
goto out;
|
|
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
|
index 0433b49..3294bd4 100644
|
|
--- a/libmultipath/devmapper.c
|
|
+++ b/libmultipath/devmapper.c
|
|
@@ -692,9 +692,15 @@ out:
|
|
return r;
|
|
}
|
|
|
|
+/*
|
|
+ * returns:
|
|
+ * 1 : is multipath device
|
|
+ * 0 : is not multipath device
|
|
+ * -1 : error
|
|
+ */
|
|
int dm_is_mpath(const char *name)
|
|
{
|
|
- int r = 0;
|
|
+ int r = -1;
|
|
struct dm_task *dmt;
|
|
struct dm_info info;
|
|
uint64_t start, length;
|
|
@@ -703,33 +709,44 @@ int dm_is_mpath(const char *name)
|
|
const char *uuid;
|
|
|
|
if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
|
|
- return 0;
|
|
+ goto out;
|
|
|
|
if (!dm_task_set_name(dmt, name))
|
|
- goto out;
|
|
+ goto out_task;
|
|
|
|
dm_task_no_open_count(dmt);
|
|
|
|
if (!dm_task_run(dmt))
|
|
- goto out;
|
|
+ goto out_task;
|
|
|
|
- if (!dm_task_get_info(dmt, &info) || !info.exists)
|
|
- goto out;
|
|
+ if (!dm_task_get_info(dmt, &info))
|
|
+ goto out_task;
|
|
+
|
|
+ r = 0;
|
|
+
|
|
+ if (!info.exists)
|
|
+ goto out_task;
|
|
|
|
uuid = dm_task_get_uuid(dmt);
|
|
|
|
if (!uuid || strncmp(uuid, UUID_PREFIX, UUID_PREFIX_LEN) != 0)
|
|
- goto out;
|
|
+ goto out_task;
|
|
|
|
/* Fetch 1st target */
|
|
- dm_get_next_target(dmt, NULL, &start, &length, &target_type, ¶ms);
|
|
+ if (dm_get_next_target(dmt, NULL, &start, &length, &target_type,
|
|
+ ¶ms) != NULL)
|
|
+ /* multiple targets */
|
|
+ goto out_task;
|
|
|
|
if (!target_type || strcmp(target_type, TGT_MPATH) != 0)
|
|
- goto out;
|
|
+ goto out_task;
|
|
|
|
r = 1;
|
|
-out:
|
|
+out_task:
|
|
dm_task_destroy(dmt);
|
|
+out:
|
|
+ if (r < 0)
|
|
+ condlog(2, "%s: dm command failed in %s", name, __FUNCTION__);
|
|
return r;
|
|
}
|
|
|
|
@@ -823,7 +840,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
|
|
unsigned long long mapsize;
|
|
char params[PARAMS_SIZE] = {0};
|
|
|
|
- if (!dm_is_mpath(mapname))
|
|
+ if (dm_is_mpath(mapname) != 1)
|
|
return 0; /* nothing to do */
|
|
|
|
/* if the device currently has no partitions, do not
|
|
@@ -1087,7 +1104,7 @@ dm_get_maps (vector mp)
|
|
}
|
|
|
|
do {
|
|
- if (!dm_is_mpath(names->name))
|
|
+ if (dm_is_mpath(names->name) != 1)
|
|
goto next;
|
|
|
|
mpp = dm_get_multipath(names->name);
|
|
diff --git a/multipath/main.c b/multipath/main.c
|
|
index 05b7bf0..98fee1c 100644
|
|
--- a/multipath/main.c
|
|
+++ b/multipath/main.c
|
|
@@ -319,7 +319,7 @@ static int check_usable_paths(struct config *conf,
|
|
goto out;
|
|
}
|
|
|
|
- if (!dm_is_mpath(mapname)) {
|
|
+ if (dm_is_mpath(mapname) != 1) {
|
|
condlog(1, "%s is not a multipath map", devpath);
|
|
goto free;
|
|
}
|
|
diff --git a/multipathd/dmevents.c b/multipathd/dmevents.c
|
|
index 31e64a7..0034892 100644
|
|
--- a/multipathd/dmevents.c
|
|
+++ b/multipathd/dmevents.c
|
|
@@ -168,7 +168,9 @@ static int dm_get_events(void)
|
|
while (names->dev) {
|
|
uint32_t event_nr;
|
|
|
|
- if (!dm_is_mpath(names->name))
|
|
+ /* Don't delete device if dm_is_mpath() fails without
|
|
+ * checking the device type */
|
|
+ if (dm_is_mpath(names->name) == 0)
|
|
goto next;
|
|
|
|
event_nr = dm_event_nr(names);
|
|
@@ -204,7 +206,9 @@ int watch_dmevents(char *name)
|
|
struct dev_event *dev_evt, *old_dev_evt;
|
|
int i;
|
|
|
|
- if (!dm_is_mpath(name)) {
|
|
+ /* We know that this is a multipath device, so only fail if
|
|
+ * device-mapper tells us that we're wrong */
|
|
+ if (dm_is_mpath(name) == 0) {
|
|
condlog(0, "%s: not a multipath device. can't watch events",
|
|
name);
|
|
return -1;
|
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
|
index 2e5f9ed..c781115 100644
|
|
--- a/multipathd/main.c
|
|
+++ b/multipathd/main.c
|
|
@@ -699,7 +699,7 @@ ev_add_map (char * dev, const char * alias, struct vectors * vecs)
|
|
int delayed_reconfig, reassign_maps;
|
|
struct config *conf;
|
|
|
|
- if (!dm_is_mpath(alias)) {
|
|
+ if (dm_is_mpath(alias) != 1) {
|
|
condlog(4, "%s: not a multipath map", alias);
|
|
return 0;
|
|
}
|
|
--
|
|
2.17.2
|
|
|