!84 [sync] PR-80: 在load多路径设备时,将pending状态的路径作为active路径处理,防止多路径设备被标记为unready

From: @openeuler-sync-bot
Reviewed-by: @liuzhiqiang26
Signed-off-by: @liuzhiqiang26
This commit is contained in:
openeuler-ci-bot 2021-11-26 07:53:06 +00:00 committed by Gitee
commit a9799bec7b
3 changed files with 190 additions and 1 deletions

View File

@ -0,0 +1,110 @@
From 292397632df7b5048d09285e7a8506a7a67ff645 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Tue, 11 Aug 2020 16:58:38 -0500
Subject: [PATCH] libmultipath: refactor path counting
pathcountgr() is never used except by pathcount(), and neither is the
special case for PATH_WILD. Simplify this and change it into a helper
function that is called by pathcount, and will be used again in a future
patch. Leave count_active_paths alone for the sake of compiler
optimization.
Also use count_active_paths() in mpath_persist.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmpathpersist/mpath_persist.c | 4 ++--
libmultipath/structs.c | 31 +++++++++++++++++--------------
libmultipath/structs.h | 1 -
3 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
index aeb3271..7cbb299 100644
--- a/libmpathpersist/mpath_persist.c
+++ b/libmpathpersist/mpath_persist.c
@@ -451,7 +451,7 @@ int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON ||
paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK);
- active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
+ active_pathcount = count_active_paths(mpp);
if (active_pathcount == 0) {
condlog (0, "%s: no path available", mpp->wwid);
@@ -663,7 +663,7 @@ int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
if (!mpp)
return MPATH_PR_DMMP_ERROR;
- active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST);
+ active_pathcount = count_active_paths(mpp);
struct threadinfo thread[active_pathcount];
memset(thread, 0, sizeof(thread));
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index 6a66817..b0360f1 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -456,30 +456,33 @@ find_path_by_devt (const struct _vector *pathvec, const char * dev_t)
return NULL;
}
-int pathcountgr(const struct pathgroup *pgp, int state)
+static int do_pathcount(const struct multipath *mpp, const int *states,
+ unsigned int nr_states)
{
+ struct pathgroup *pgp;
struct path *pp;
int count = 0;
- int i;
+ unsigned int i, j, k;
- vector_foreach_slot (pgp->paths, pp, i)
- if ((pp->state == state) || (state == PATH_WILD))
- count++;
+ if (!mpp->pg || !nr_states)
+ return count;
+ vector_foreach_slot (mpp->pg, pgp, i) {
+ vector_foreach_slot (pgp->paths, pp, j) {
+ for (k = 0; k < nr_states; k++) {
+ if (pp->state == states[k]) {
+ count++;
+ break;
+ }
+ }
+ }
+ }
return count;
}
int pathcount(const struct multipath *mpp, int state)
{
- struct pathgroup *pgp;
- int count = 0;
- int i;
-
- if (mpp->pg) {
- vector_foreach_slot (mpp->pg, pgp, i)
- count += pathcountgr(pgp, state);
- }
- return count;
+ return do_pathcount(mpp, &state, 1);
}
int count_active_paths(const struct multipath *mpp)
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index 719a994..a218c06 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -463,7 +463,6 @@ struct path * find_path_by_devt (const struct _vector *pathvec, const char *devt
struct path * find_path_by_dev (const struct _vector *pathvec, const char *dev);
struct path * first_path (const struct multipath *mpp);
-int pathcountgr (const struct pathgroup *, int);
int pathcount (const struct multipath *, int);
int count_active_paths(const struct multipath *);
int pathcmp (const struct pathgroup *, const struct pathgroup *);
--
2.14.3 (Apple Git-98)

View File

@ -0,0 +1,74 @@
From ff103a993fbc0124b92f387765360c32d34cdd5b Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Tue, 11 Aug 2020 16:58:39 -0500
Subject: [PATCH] libmultipath: count pending paths as active on loads
When multipath loads a table, it signals to udev if there are no active
paths. Multipath wasn't counting pending paths as active. This meant
that if all the paths were pending, udev would treat the device as not
ready, and not run kpartx on it. Even if the pending paths later
because active and were reinstated, the kernel would not send a new
uevent, because from its point of view, they were always up.
The alternative would be to continue to treat them as failed in the udev
rules, but then also tell the kernel that they were down, so that it
would trigger a uevent when they were reinstated. However, this could
lead to newly created multipath devices failing IO, simply because the
path checkers hadn't returned yet. Having udev assume that the the
device is up, like the kernel does, seems like the safer option.
Reviewed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/devmapper.c | 3 ++-
libmultipath/structs.c | 7 +++++++
libmultipath/structs.h | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
index bed8ddc..4b6d75e 100644
--- a/libmultipath/devmapper.c
+++ b/libmultipath/devmapper.c
@@ -403,7 +403,8 @@ static uint16_t build_udev_flags(const struct multipath *mpp, int reload)
/* DM_UDEV_DISABLE_LIBRARY_FALLBACK is added in dm_addmap */
return (mpp->skip_kpartx == SKIP_KPARTX_ON ?
MPATH_UDEV_NO_KPARTX_FLAG : 0) |
- ((count_active_paths(mpp) == 0 || mpp->ghost_delay_tick > 0) ?
+ ((count_active_pending_paths(mpp) == 0 ||
+ mpp->ghost_delay_tick > 0) ?
MPATH_UDEV_NO_PATHS_FLAG : 0) |
(reload && !mpp->force_udev_reload ?
MPATH_UDEV_RELOAD_FLAG : 0);
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
index b0360f1..532e50e 100644
--- a/libmultipath/structs.c
+++ b/libmultipath/structs.c
@@ -504,6 +504,13 @@ int count_active_paths(const struct multipath *mpp)
return count;
}
+int count_active_pending_paths(const struct multipath *mpp)
+{
+ int states[] = {PATH_UP, PATH_GHOST, PATH_PENDING};
+
+ return do_pathcount(mpp, states, 3);
+}
+
int pathcmp(const struct pathgroup *pgp, const struct pathgroup *cpgp)
{
int i, j;
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
index a218c06..45f229d 100644
--- a/libmultipath/structs.h
+++ b/libmultipath/structs.h
@@ -465,6 +465,7 @@ struct path * first_path (const struct multipath *mpp);
int pathcount (const struct multipath *, int);
int count_active_paths(const struct multipath *);
+int count_active_pending_paths(const struct multipath *);
int pathcmp (const struct pathgroup *, const struct pathgroup *);
int add_feature (char **, const char *);
int remove_feature (char **, const char *);
--
2.14.3 (Apple Git-98)

View File

@ -2,7 +2,7 @@
Name: multipath-tools
Version: 0.8.4
Release: 11
Release: 12
Summary: Tools to manage multipath devices with the device-mapper
License: GPL-2.0-or-later and LGPL-2.0-only
URL: http://christophe.varoqui.free.fr/
@ -36,6 +36,8 @@ Patch23: 0023-libmultipath-warn-about-NULL-value-of-mpp-hwe.patch
Patch24: 0024-libmultipath-fix-mpp-hwe-handling-in-sync_paths.patch
Patch25: 0025-fix-boolean-value-with-json-c-0.14.patch
Patch26: 0026-multipath-tools-tests-directio-fix-Wmaybe-uninitaliz.patch
Patch27: 0027-libmultipath-refactor-path-counting.patch
Patch28: 0028-libmultipath-count-pending-paths-as-active-on-loads.patch
BuildRequires: multipath-tools, libcmocka, libcmocka-devel
BuildRequires: gcc, libaio-devel, userspace-rcu-devel, device-mapper-devel >= 1.02.89
@ -182,6 +184,9 @@ fi
%changelog
* Thu Nov 25 2021 lixiaokeng<lixiaokeng@huawei.com> - 0.8.4-12
- count pending paths as active on loads
* Thu Sep 23 2021 lixiaokeng<lixiaokeng@huawei.com> - 0.8.4-11
- Type:testcode
- ID:NA