multipathd: fix check_path could not resume path state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From fb655da18aefccaa09c70036b08c88a03609ec45 Mon Sep 17 00:00:00 2001
From: wangjufeng <wangjufeng@xxxxxxxxxx>
Date: Sat, 21 Mar 2020 22:23:10 +0800
Subject: [PATCH] multipathd: fix check_path could not resume path state

For some unknown reason, after network recovery from disconnection,
the paths in a multipath are still in fail state. Use gdb attached
multipathd, the paths seem to be changed by orphan_path function,
pp->initialized is INIT_OK while pp->mpp is NULL, pp->dmstate is
PSTATE_UNDEF, pp->fd is -1. And the multipath could not be found in
gvecs->mpvec while it could be found by dmsetup table command.

It will lead to that the path state could not be activated by
check_path even if the iscsi device is already available.

This patch intend to add the multipath map again to avoid IO failure
or IO blocked when the above phenomenon occur.

Signed-off-by: wangjufeng <wangjufeng@xxxxxxxxxx>
Reviewed-by: linfeilong <linfeilong@xxxxxxxxxx>
---
 multipathd/main.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/multipathd/main.c b/multipathd/main.c
index 8baf9ab..4ca622c 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1962,10 +1962,59 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks)
 	struct config *conf;
 	int marginal_pathgroups, marginal_changed = 0;
 	int ret;
+	char *param;
+        int major;
+        int minor;
+        int invalid = 0;
+        char dev_path[PATH_SIZE];
+        char *alias = NULL;
+	struct multipath *mpp;
 
 	if ((pp->initialized == INIT_OK ||
-	     pp->initialized == INIT_REQUESTED_UDEV) && !pp->mpp)
-		return 0;
+	     pp->initialized == INIT_REQUESTED_UDEV) && !pp->mpp) {
+		if (pp->initialized == INIT_OK && !pp->mpp &&
+		    pp->dmstate == PSTATE_UNDEF && pp->fd == -1) {
+			mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
+			if (mpp != NULL) {
+				return 0;
+			}
+			/*
+			 * If a multipath is not in gvecs->mpvec, while it could be found in
+			 * device-mapper devices. It should be mapped again, or multipathd
+			 * can not add it again because of that check_path early return.
+			 */
+			param = convert_dev(pp->wwid, 0);
+			conf = get_multipath_config();
+			pthread_cleanup_push(put_multipath_config, conf);
+			if (filter_wwid(conf->blist_wwid, conf->elist_wwid, param, NULL) > 0) {
+				invalid = 1;
+			}
+			pthread_cleanup_pop(1);
+			if (invalid) {
+				condlog(2, "%s: map blacklisted", param);
+				return 0;
+			}
+
+			if (dm_get_major_minor(param, &major, &minor) < 0) {
+				return 0;
+			} else {
+				sprintf(dev_path, "dm-%d", minor);
+				alias = dm_mapname(major, minor);
+				if (!alias) {
+					condlog(2, "fail to get alias of %s %d:%d", param, major, minor);
+					return 0;
+				}
+				if (ev_add_map(dev_path, alias, vecs)) {
+					condlog(2, "fail to add map for mpp %s", alias);
+					return 0;
+				} else {
+					condlog(2, "success to add map for mpp %s", alias);
+				}
+			}
+		} else {
+			return 0;
+		}
+	}
 
 	if (pp->tick)
 		pp->tick -= (pp->tick > ticks) ? ticks : pp->tick;
-- 
1.8.3.1

Attachment: multipathd-fix-check_path-could-not-resume-path-stat.patch
Description: multipathd-fix-check_path-could-not-resume-path-stat.patch

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux