From 4a4414b83f9ea31b044256ac5e0bd13e45b56dae Mon Sep 17 00:00:00 2001 From: Lixiaokeng Date: Thu, 25 Nov 2021 17:20:05 +0800 Subject: [PATCH] count pending path as actvie on loads (cherry picked from commit a5d5f8502195cff98a82b318bed7be1edb5ef6be) --- ...-libmultipath-refactor-path-counting.patch | 110 ++++++++++++++++++ ...unt-pending-paths-as-active-on-loads.patch | 74 ++++++++++++ multipath-tools.spec | 7 +- 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 0027-libmultipath-refactor-path-counting.patch create mode 100644 0028-libmultipath-count-pending-paths-as-active-on-loads.patch diff --git a/0027-libmultipath-refactor-path-counting.patch b/0027-libmultipath-refactor-path-counting.patch new file mode 100644 index 0000000..2d52247 --- /dev/null +++ b/0027-libmultipath-refactor-path-counting.patch @@ -0,0 +1,110 @@ +From 292397632df7b5048d09285e7a8506a7a67ff645 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +Reviewed-by: Martin Wilck +--- + 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) + diff --git a/0028-libmultipath-count-pending-paths-as-active-on-loads.patch b/0028-libmultipath-count-pending-paths-as-active-on-loads.patch new file mode 100644 index 0000000..d76199b --- /dev/null +++ b/0028-libmultipath-count-pending-paths-as-active-on-loads.patch @@ -0,0 +1,74 @@ +From ff103a993fbc0124b92f387765360c32d34cdd5b Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +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 +Signed-off-by: Benjamin Marzinski +--- + 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) + diff --git a/multipath-tools.spec b/multipath-tools.spec index 1d2bdce..ef540f1 100644 --- a/multipath-tools.spec +++ b/multipath-tools.spec @@ -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 - 0.8.4-12 +- count pending paths as active on loads + * Thu Sep 23 2021 lixiaokeng - 0.8.4-11 - Type:testcode - ID:NA