Blame SOURCES/0037-libmultipath-count-pending-paths-as-active-on-loads.patch

a7a17c
From 7159242be31dbb3f25aa67920462107bc2bc5fe0 Mon Sep 17 00:00:00 2001
a7a17c
From: Benjamin Marzinski <bmarzins@redhat.com>
a7a17c
Date: Thu, 9 Jul 2020 18:20:18 -0500
a7a17c
Subject: [PATCH] libmultipath: count pending paths as active on loads
a7a17c
a7a17c
When multipath loads a table, it signals to udev if there are no active
a7a17c
paths.  Multipath wasn't counting pending paths as active.  This meant
a7a17c
that if all the paths were pending, udev would treat the device as not
a7a17c
ready, and not run kpartx on it.  Even if the pending paths later
a7a17c
because active and were reinstated, the kernel would not send a new
a7a17c
uevent, because from its point of view, they were always up.
a7a17c
a7a17c
The alternative would be to continue to treat them as failed in the udev
a7a17c
rules, but then also tell the kernel that they were down, so that it
a7a17c
would trigger a uevent when they were reinstated. However, this could
a7a17c
lead to newly created multipath devices failing IO, simply because the
a7a17c
path checkers hadn't returned yet. Having udev assume that the the
a7a17c
device is up, like the kernel does, seems like the safer option.
a7a17c
a7a17c
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
a7a17c
---
a7a17c
 libmultipath/devmapper.c |  3 ++-
a7a17c
 libmultipath/structs.c   | 20 ++++++++++++++++++++
a7a17c
 libmultipath/structs.h   |  1 +
a7a17c
 3 files changed, 23 insertions(+), 1 deletion(-)
a7a17c
a7a17c
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
a7a17c
index 7f98bf9d..91ff0b3d 100644
a7a17c
--- a/libmultipath/devmapper.c
a7a17c
+++ b/libmultipath/devmapper.c
a7a17c
@@ -408,7 +408,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload)
a7a17c
 	/* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */
a7a17c
 	return	(mpp->skip_kpartx == SKIP_KPARTX_ON ?
a7a17c
 		 MPATH_UDEV_NO_KPARTX_FLAG : 0) |
a7a17c
-		((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ?
a7a17c
+		((count_active_pending_paths(mpp) == 0 ||
a7a17c
+		  mpp->ghost_delay_tick > 0) ?
a7a17c
 		 MPATH_UDEV_NO_PATHS_FLAG : 0) |
a7a17c
 		(reload && !mpp->force_udev_reload ?
a7a17c
 		 MPATH_UDEV_RELOAD_FLAG : 0);
a7a17c
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
a7a17c
index 2dd378c4..dda9884c 100644
a7a17c
--- a/libmultipath/structs.c
a7a17c
+++ b/libmultipath/structs.c
a7a17c
@@ -500,6 +500,26 @@ int count_active_paths(const struct multipath *mpp)
a7a17c
 	return count;
a7a17c
 }
a7a17c
 
a7a17c
+int count_active_pending_paths(const struct multipath *mpp)
a7a17c
+{
a7a17c
+	struct pathgroup *pgp;
a7a17c
+	struct path *pp;
a7a17c
+	int count = 0;
a7a17c
+	int i, j;
a7a17c
+
a7a17c
+	if (!mpp->pg)
a7a17c
+		return 0;
a7a17c
+
a7a17c
+	vector_foreach_slot (mpp->pg, pgp, i) {
a7a17c
+		vector_foreach_slot (pgp->paths, pp, j) {
a7a17c
+			if (pp->state == PATH_UP || pp->state == PATH_GHOST ||
a7a17c
+			    pp->state == PATH_PENDING)
a7a17c
+				count++;
a7a17c
+		}
a7a17c
+	}
a7a17c
+	return count;
a7a17c
+}
a7a17c
+
a7a17c
 int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp)
a7a17c
 {
a7a17c
 	int i, j;
a7a17c
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
a7a17c
index 9bd39eb1..8e78b8c0 100644
a7a17c
--- a/libmultipath/structs.h
a7a17c
+++ b/libmultipath/structs.h
a7a17c
@@ -465,6 +465,7 @@ struct path * first_path (const struct multipath *mpp);
a7a17c
 int pathcountgr (const struct pathgroup *, int);
a7a17c
 int pathcount (const struct multipath *, int);
a7a17c
 int count_active_paths(const struct multipath *);
a7a17c
+int count_active_pending_paths(const struct multipath *);
a7a17c
 int pathcmp (const struct pathgroup *, const struct pathgroup *);
a7a17c
 int add_feature (char **, const char *);
a7a17c
 int remove_feature (char **, const char *);
a7a17c
-- 
a7a17c
2.17.2
a7a17c