device-mapper-multipath/0009-libmultipath-make-group_paths-handle-marginal-paths.patch
Benjamin Marzinski 942c9b6ed8 device-mapper-multipath-0.8.2-1
Update Source to upstream version 0.8.2
  * Previoud patches 0001-0017 & 0027 are included in this commit
Rename files
  * Previous patches 0018-0026 & 0028 are not patches 0021-0030
Add 0001-libmultipath-make-vector_foreach_slot_backwards-work.patch
Add 0002-libmultipath-add-marginal-paths-and-groups-infrastru.patch
Add 0003-tests-add-path-grouping-policy-unit-tests.patch
Add 0004-libmultipath-add-wrapper-function-around-pgpolicyfn.patch
Add 0005-tests-update-pgpolicy-tests-to-work-with-group_paths.patch
Add 0006-libmultipath-fix-double-free-in-pgpolicyfn-error-pat.patch
Add 0007-libmultipath-consolidate-group_by_-functions.patch
Add 0008-libmultipath-make-pgpolicyfn-take-a-paths-vector.patch
Add 0009-libmultipath-make-group_paths-handle-marginal-paths.patch
Add 0010-tests-add-tests-for-grouping-marginal-paths.patch
Add 0011-libmultipath-add-marginal_pathgroups-config-option.patch
Add 0012-libmutipath-deprecate-delay_-_checks.patch
Add 0013-multipathd-use-marginal_pathgroups.patch
Add 0014-multipath-update-man-pages.patch
  * The above 13 patches add the marinal_pathgroups option
Add 0015-multipath.conf-add-enable_foreign-parameter.patch
Add 0016-multipath.conf.5-document-foreign-library-support.patch
  * The above 2 patches add the enable_foreign option
Add 0017-mpathpersist-remove-broken-unused-code.patch
Add 0018-libmultipath-EMC-PowerMax-NVMe-device-config.patch
Add 0019-mpathpersist-fix-leaks.patch
Add 0020-libmultipath-fix-mpcontext-initialization.patch
  * The above 20 patches have been submitted upstream
2019-09-11 17:06:10 -05:00

186 lines
4.6 KiB
Diff

From 227a9fceb8c20f153f4f136caeb28faff5bd80fe Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Fri, 12 Jul 2019 15:39:26 -0500
Subject: [PATCH] libmultipath: make group_paths handle marginal paths
group_paths() will now create seperate path groups for marginal and
normal paths, and place all of the marginal path groups after the normal
ones, in order by priority.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmultipath/pgpolicies.c | 83 +++++++++++++++++++++++++++++++++-----
libmultipath/switchgroup.c | 15 ++++++-
2 files changed, 88 insertions(+), 10 deletions(-)
diff --git a/libmultipath/pgpolicies.c b/libmultipath/pgpolicies.c
index 2e7c0502..6fb2d28a 100644
--- a/libmultipath/pgpolicies.c
+++ b/libmultipath/pgpolicies.c
@@ -72,9 +72,11 @@ sort_pathgroups (struct multipath *mp) {
pgp2 = VECTOR_SLOT(mp->pg, j);
if (!pgp2)
continue;
- if (pgp2->priority > pgp1->priority ||
- (pgp2->priority == pgp1->priority &&
- pgp2->enabled_paths >= pgp1->enabled_paths)) {
+ if (pgp2->marginal < pgp1->marginal ||
+ (pgp2->marginal == pgp1->marginal &&
+ (pgp2->priority > pgp1->priority ||
+ (pgp2->priority == pgp1->priority &&
+ pgp2->enabled_paths >= pgp1->enabled_paths)))) {
vector_move_up(mp->pg, i, j + 1);
break;
}
@@ -84,25 +86,88 @@ sort_pathgroups (struct multipath *mp) {
}
}
+static int
+split_marginal_paths(vector paths, vector *normal_p, vector *marginal_p)
+{
+ int i;
+ int has_marginal = 0;
+ int has_normal = 0;
+ struct path *pp;
+ vector normal = NULL;
+ vector marginal = NULL;
+
+ *normal_p = *marginal_p = NULL;
+ vector_foreach_slot(paths, pp, i) {
+ if (pp->marginal)
+ has_marginal = 1;
+ else
+ has_normal = 1;
+ }
+
+ if (!has_marginal || !has_normal)
+ return -1;
+
+ normal = vector_alloc();
+ marginal = vector_alloc();
+ if (!normal || !marginal)
+ goto fail;
+
+ vector_foreach_slot(paths, pp, i) {
+ if (pp->marginal) {
+ if (store_path(marginal, pp))
+ goto fail;
+ }
+ else {
+ if (store_path(normal, pp))
+ goto fail;
+ }
+ }
+ *normal_p = normal;
+ *marginal_p = marginal;
+ return 0;
+fail:
+ vector_free(normal);
+ vector_free(marginal);
+ return -1;
+}
int group_paths(struct multipath *mp)
{
+ vector normal, marginal;
+
if (!mp->pg)
mp->pg = vector_alloc();
if (!mp->pg)
return 1;
- if (VECTOR_SIZE(mp->paths) > 0 &&
- (!mp->pgpolicyfn || mp->pgpolicyfn(mp, mp->paths))) {
- vector_free(mp->pg);
- mp->pg = NULL;
- return 1;
+ if (VECTOR_SIZE(mp->paths) == 0)
+ goto out;
+ if (!mp->pgpolicyfn)
+ goto fail;
+
+ if (split_marginal_paths(mp->paths, &normal, &marginal) != 0) {
+ if (mp->pgpolicyfn(mp, mp->paths) != 0)
+ goto fail;
+ } else {
+ if (mp->pgpolicyfn(mp, normal) != 0)
+ goto fail_marginal;
+ if (mp->pgpolicyfn(mp, marginal) != 0)
+ goto fail_marginal;
+ vector_free(normal);
+ vector_free(marginal);
}
-
sort_pathgroups(mp);
+out:
vector_free(mp->paths);
mp->paths = NULL;
return 0;
+fail_marginal:
+ vector_free(normal);
+ vector_free(marginal);
+fail:
+ vector_free(mp->pg);
+ mp->pg = NULL;
+ return 1;
}
typedef bool (path_match_fn)(struct path *pp1, struct path *pp2);
diff --git a/libmultipath/switchgroup.c b/libmultipath/switchgroup.c
index 9632ce2d..6fdfcfa7 100644
--- a/libmultipath/switchgroup.c
+++ b/libmultipath/switchgroup.c
@@ -11,6 +11,7 @@ void path_group_prio_update(struct pathgroup *pgp)
{
int i;
int priority = 0;
+ int marginal = 0;
struct path * pp;
pgp->enabled_paths = 0;
@@ -19,6 +20,8 @@ void path_group_prio_update(struct pathgroup *pgp)
return;
}
vector_foreach_slot (pgp->paths, pp, i) {
+ if (pp->marginal)
+ marginal++;
if (pp->state == PATH_UP ||
pp->state == PATH_GHOST) {
priority += pp->priority;
@@ -29,11 +32,14 @@ void path_group_prio_update(struct pathgroup *pgp)
pgp->priority = priority / pgp->enabled_paths;
else
pgp->priority = 0;
+ if (marginal && marginal == i)
+ pgp->marginal = 1;
}
int select_path_group(struct multipath *mpp)
{
int i;
+ int normal_pgp = 0;
int max_priority = 0;
int bestpg = 1;
int max_enabled_paths = 1;
@@ -47,8 +53,15 @@ int select_path_group(struct multipath *mpp)
continue;
path_group_prio_update(pgp);
+ if (pgp->marginal && normal_pgp)
+ continue;
if (pgp->enabled_paths) {
- if (pgp->priority > max_priority) {
+ if (!pgp->marginal && !normal_pgp) {
+ normal_pgp = 1;
+ max_priority = pgp->priority;
+ max_enabled_paths = pgp->enabled_paths;
+ bestpg = i + 1;
+ } else if (pgp->priority > max_priority) {
max_priority = pgp->priority;
max_enabled_paths = pgp->enabled_paths;
bestpg = i + 1;
--
2.17.2