157 lines
5.4 KiB
Diff
157 lines
5.4 KiB
Diff
|
---
|
||
|
libmultipath/dict.c | 12 ++++++++++++
|
||
|
libmultipath/print.c | 2 ++
|
||
|
libmultipath/structs.h | 3 ++-
|
||
|
multipath/multipath.conf.5 | 5 +++++
|
||
|
multipathd/main.c | 29 ++++++++++++++++++++++++++++-
|
||
|
5 files changed, 49 insertions(+), 2 deletions(-)
|
||
|
|
||
|
Index: multipath-tools-120123/libmultipath/dict.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-120123.orig/libmultipath/dict.c
|
||
|
+++ multipath-tools-120123/libmultipath/dict.c
|
||
|
@@ -406,6 +406,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);
|
||
|
|
||
|
@@ -1031,6 +1033,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);
|
||
|
|
||
|
@@ -1303,6 +1307,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);
|
||
|
|
||
|
@@ -1646,6 +1652,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);
|
||
|
}
|
||
|
@@ -1985,6 +1993,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);
|
||
|
}
|
||
|
@@ -2243,6 +2253,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", conf->pgfailback);
|
||
|
}
|
||
|
Index: multipath-tools-120123/libmultipath/print.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-120123.orig/libmultipath/print.c
|
||
|
+++ multipath-tools-120123/libmultipath/print.c
|
||
|
@@ -143,6 +143,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-120123/libmultipath/structs.h
|
||
|
===================================================================
|
||
|
--- multipath-tools-120123.orig/libmultipath/structs.h
|
||
|
+++ multipath-tools-120123/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-120123/multipathd/main.c
|
||
|
===================================================================
|
||
|
--- multipath-tools-120123.orig/multipathd/main.c
|
||
|
+++ multipath-tools-120123/multipathd/main.c
|
||
|
@@ -1011,6 +1011,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)
|
||
|
{
|
||
|
@@ -1238,7 +1264,8 @@ check_path (struct vectors * vecs, struc
|
||
|
(new_path_up || pp->mpp->failback_tick <= 0))
|
||
|
pp->mpp->failback_tick =
|
||
|
pp->mpp->pgfailback + 1;
|
||
|
- else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE)
|
||
|
+ else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
|
||
|
+ followover_should_failback(pp))
|
||
|
switch_pathgroup(pp->mpp);
|
||
|
}
|
||
|
}
|
||
|
Index: multipath-tools-120123/multipath/multipath.conf.5
|
||
|
===================================================================
|
||
|
--- multipath-tools-120123.orig/multipath/multipath.conf.5
|
||
|
+++ multipath-tools-120123/multipath/multipath.conf.5
|
||
|
@@ -258,6 +258,11 @@ active paths.
|
||
|
.B manual
|
||
|
Do not perform automatic failback.
|
||
|
.TP
|
||
|
+.B followover
|
||
|
+Only perform automatic failback when the first path of a pathgroup
|
||
|
+becomes active. This keeps a node from automatically failing back when
|
||
|
+another node requested the failover.
|
||
|
+.TP
|
||
|
.B values > 0
|
||
|
deferred failback (time to defer in seconds)
|
||
|
.TP
|