device-mapper-multipath/0035-RHBZ-467709-add-followover.patch

142 lines
4.7 KiB
Diff
Raw Normal View History

---
libmultipath/dict.c | 12 ++++++++++++
libmultipath/print.c | 2 ++
libmultipath/structs.h | 3 ++-
multipathd/main.c | 31 +++++++++++++++++++++++++++++--
4 files changed, 45 insertions(+), 3 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -348,6 +348,8 @@ default_failback_handler(vector strvec)
conf->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
conf->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ conf->pgfailback = -FAILBACK_FOLLOWOVER;
else
conf->pgfailback = atoi(buff);
@@ -917,6 +919,8 @@ hw_failback_handler(vector strvec)
hwe->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
hwe->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ hwe->pgfailback = -FAILBACK_FOLLOWOVER;
else
hwe->pgfailback = atoi(buff);
@@ -1169,6 +1173,8 @@ mp_failback_handler(vector strvec)
mpe->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
mpe->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ mpe->pgfailback = -FAILBACK_FOLLOWOVER;
else
mpe->pgfailback = atoi(buff);
@@ -1472,6 +1478,8 @@ snprint_mp_failback (char * buff, int le
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", mpe->pgfailback);
}
@@ -1748,6 +1756,8 @@ snprint_hw_failback (char * buff, int le
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", hwe->pgfailback);
}
@@ -1970,6 +1980,8 @@ snprint_def_failback (char * buff, int l
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", pgfailback);
}
Index: multipath-tools/libmultipath/print.c
===================================================================
--- multipath-tools.orig/libmultipath/print.c
+++ multipath-tools/libmultipath/print.c
@@ -142,6 +142,8 @@ snprint_failback (char * buff, size_t le
{
if (mpp->pgfailback == -FAILBACK_IMMEDIATE)
return snprintf(buff, len, "immediate");
+ if (mpp->pgfailback == -FAILBACK_FOLLOWOVER)
+ return snprintf(buff, len, "followover");
if (!mpp->failback_tick)
return snprintf(buff, len, "-");
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -39,7 +39,8 @@ enum rr_weight_mode {
enum failback_mode {
FAILBACK_UNDEF,
FAILBACK_MANUAL,
- FAILBACK_IMMEDIATE
+ FAILBACK_IMMEDIATE,
+ FAILBACK_FOLLOWOVER
};
enum sysfs_buses {
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -875,6 +875,32 @@ mpvec_garbage_collector (struct vectors
}
}
+/* This is called after a path has started working again. It the multipath
+ * device for this path uses the followover failback type, and this is the
+ * best pathgroup, and this is the first path in the pathgroup to come back
+ * up, then switch to this pathgroup */
+static int
+followover_should_failback(struct path * pp)
+{
+ struct pathgroup * pgp;
+ struct path *pp1;
+ int i;
+
+ if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER ||
+ !pp->mpp->pg || !pp->pgindex ||
+ pp->pgindex != pp->mpp->bestpg)
+ return 0;
+
+ pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
+ vector_foreach_slot(pgp->paths, pp1, i) {
+ if (pp1 == pp)
+ continue;
+ if (pp1->state != PATH_DOWN && pp1->state != PATH_SHAKY)
+ return 0;
+ }
+ return 1;
+}
+
static void
defered_failback_tick (vector mpvec)
{
@@ -1013,8 +1039,9 @@ check_path (struct vectors * vecs, struc
if (pp->mpp->pgfailback > 0)
pp->mpp->failback_tick =
pp->mpp->pgfailback + 1;
- else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE &&
- need_switch_pathgroup(pp->mpp, 1))
+ else if (need_switch_pathgroup(pp->mpp, 1) &&
+ (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
+ followover_should_failback(pp)))
switch_pathgroup(pp->mpp);
/*