35f5570500
Update Source to upstream version 0.8.0 * Previous patches 0006 & 0007 are included in this commit Rename files * Previous patches 0008-0016 & 0100 are now patches 0018-0027 Add 0006-multipathd-Fix-miscounting-active-paths.patch Add 0007-multipathd-ignore-failed-wwid-recheck.patch * multipathd will no longer disable paths if it is unable to get their wwid on a change event Add 0008-libmutipath-continue-to-use-old-state-on-PATH_PENDIN.patch Add 0009-multipathd-use-update_path_groups-instead-of-reload_.patch Add 0010-multipath.conf-add-missing-options-to-man-page.patch Add 0011-libmultipath-add-get_uid-fallback-code-for-NVMe-devi.patch Add 0012-libmulitpath-cleanup-uid_fallback-code.patch Add 0013-multipathd-handle-changed-wwids-by-removal-and-addit.patch * if a path device changes wwid, it will now be removed and re-added to the correct multipath device. Add 0014-multipathd-remove-wwid_changed-path-attribute.patch Add 0015-multipathd-ignore-disable_changed_wwids.patch Add 0016-multipathd-Don-t-use-fallback-code-after-getting-wwi.patch Add 0017-libmultipath-silence-dm_is_mpath-error-messages.patch * The above 12 patches have been submitted upstream
93 lines
3.5 KiB
Diff
93 lines
3.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Benjamin Marzinski <bmarzins@redhat.com>
|
|
Date: Fri, 15 Feb 2019 17:19:46 -0600
|
|
Subject: [PATCH] multipathd: Fix miscounting active paths
|
|
|
|
When multipathd gets a change uevent, it calls pathinfo with DI_NOIO.
|
|
This sets the path state to the return value of path_offline(). If a
|
|
path is in the PATH_DOWN state but path_offline() returns PATH_UP, when
|
|
that path gets a change event, its state will get moved to PATH_UP
|
|
without either reinstating the path, or reloading the map. The next
|
|
call to check_path() will move the path back to PATH_DOWN. Since
|
|
check_path() simply increments and decrements nr_active instead of
|
|
calculating it based on the actual number of active paths, nr_active
|
|
will get decremented a second time for this failed path, potentially
|
|
putting the multipath device into recovery mode.
|
|
|
|
This commit does two things to avoid this situation. It makes the
|
|
DI_NOIO flag only set pp->state in pathinfo() if DI_CHECKER is also set.
|
|
This isn't set in uev_update_path() to avoid changing the path state in
|
|
this case. Also, to guard against pp->state getting changed in some
|
|
other code path without properly updating the map state, check_path()
|
|
now calls set_no_path_retry, which recalculates nr_active based on the
|
|
actual number of active paths, and makes sure that the queue_if_no_path
|
|
value in the features line is correct.
|
|
|
|
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
|
|
---
|
|
libmultipath/discovery.c | 11 ++++++-----
|
|
multipath/main.c | 2 +-
|
|
multipathd/main.c | 4 +++-
|
|
3 files changed, 10 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
|
index 10bd8cd..729bcb9 100644
|
|
--- a/libmultipath/discovery.c
|
|
+++ b/libmultipath/discovery.c
|
|
@@ -1914,11 +1914,12 @@ int pathinfo(struct path *pp, struct config *conf, int mask)
|
|
if (path_state == PATH_REMOVED)
|
|
goto blank;
|
|
else if (mask & DI_NOIO) {
|
|
- /*
|
|
- * Avoid any IO on the device itself.
|
|
- * Behave like DI_CHECKER in the "path unavailable" case.
|
|
- */
|
|
- pp->chkrstate = pp->state = path_state;
|
|
+ if (mask & DI_CHECKER)
|
|
+ /*
|
|
+ * Avoid any IO on the device itself.
|
|
+ * simply use the path_offline() return as its state
|
|
+ */
|
|
+ pp->chkrstate = pp->state = path_state;
|
|
return PATHINFO_OK;
|
|
}
|
|
|
|
diff --git a/multipath/main.c b/multipath/main.c
|
|
index 5abb118..69141db 100644
|
|
--- a/multipath/main.c
|
|
+++ b/multipath/main.c
|
|
@@ -356,7 +356,7 @@ static int check_usable_paths(struct config *conf,
|
|
pp->udev = get_udev_device(pp->dev_t, DEV_DEVT);
|
|
if (pp->udev == NULL)
|
|
continue;
|
|
- if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) != PATHINFO_OK)
|
|
+ if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO|DI_CHECKER) != PATHINFO_OK)
|
|
continue;
|
|
|
|
if (pp->state == PATH_UP &&
|
|
diff --git a/multipathd/main.c b/multipathd/main.c
|
|
index 43830e8..678ecf8 100644
|
|
--- a/multipathd/main.c
|
|
+++ b/multipathd/main.c
|
|
@@ -392,7 +392,8 @@ static void set_no_path_retry(struct multipath *mpp)
|
|
default:
|
|
if (mpp->nr_active > 0) {
|
|
mpp->retry_tick = 0;
|
|
- dm_queue_if_no_path(mpp->alias, 1);
|
|
+ if (!is_queueing)
|
|
+ dm_queue_if_no_path(mpp->alias, 1);
|
|
} else if (is_queueing && mpp->retry_tick == 0)
|
|
enter_recovery_mode(mpp);
|
|
break;
|
|
@@ -2072,6 +2073,7 @@ check_path (struct vectors * vecs, struct path * pp, int ticks)
|
|
/* if update_multipath_strings orphaned the path, quit early */
|
|
if (!pp->mpp)
|
|
return 0;
|
|
+ set_no_path_retry(pp->mpp);
|
|
|
|
if ((newstate == PATH_UP || newstate == PATH_GHOST) &&
|
|
check_path_reinstate_state(pp)) {
|
|
--
|
|
2.17.2
|
|
|