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