]> git.ipfire.org Git - people/stevee/ipfire-3.x.git/blobdiff - multipath-tools/patches/0003-RH-add-followover.patch
multipath-tools: Update to latest development snapshot (120613).
[people/stevee/ipfire-3.x.git] / multipath-tools / patches / 0003-RH-add-followover.patch
diff --git a/multipath-tools/patches/0003-RH-add-followover.patch b/multipath-tools/patches/0003-RH-add-followover.patch
new file mode 100644 (file)
index 0000000..9aeecf4
--- /dev/null
@@ -0,0 +1,235 @@
+---
+ libmultipath/dict.c        |   12 ++++++++++++
+ libmultipath/discovery.c   |    6 +++---
+ libmultipath/print.c       |    2 ++
+ libmultipath/structs.h     |    4 +++-
+ multipath/main.c           |    2 +-
+ multipath/multipath.conf.5 |    5 +++++
+ multipathd/main.c          |   35 ++++++++++++++++++++++++++++++++++-
+ 7 files changed, 60 insertions(+), 6 deletions(-)
+
+Index: multipath-tools-120518/libmultipath/dict.c
+===================================================================
+--- multipath-tools-120518.orig/libmultipath/dict.c
++++ multipath-tools-120518/libmultipath/dict.c
+@@ -398,6 +398,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);
+@@ -1053,6 +1055,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);
+@@ -1351,6 +1355,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);
+@@ -1769,6 +1775,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);
+       }
+@@ -2130,6 +2138,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);
+       }
+@@ -2394,6 +2404,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-120518/libmultipath/print.c
+===================================================================
+--- multipath-tools-120518.orig/libmultipath/print.c
++++ multipath-tools-120518/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-120518/libmultipath/structs.h
+===================================================================
+--- multipath-tools-120518.orig/libmultipath/structs.h
++++ multipath-tools-120518/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 {
+@@ -151,6 +152,7 @@ struct path {
+       int offline;
+       int state;
+       int dmstate;
++      int chkrstate;
+       int failcount;
+       int priority;
+       int pgindex;
+Index: multipath-tools-120518/multipathd/main.c
+===================================================================
+--- multipath-tools-120518.orig/multipathd/main.c
++++ multipath-tools-120518/multipathd/main.c
+@@ -995,6 +995,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->chkrstate != PATH_DOWN && pp1->chkrstate != PATH_SHAKY)
++                      return 0;
++      }
++      return 1;
++}
++
+ static void
+ defered_failback_tick (vector mpvec)
+ {
+@@ -1092,6 +1118,8 @@ check_path (struct vectors * vecs, struc
+ {
+       int newstate;
+       int new_path_up = 0;
++      int chkr_new_path_up = 0;
++      int oldchkrstate = pp->chkrstate;
+       if (!pp->mpp)
+               return;
+@@ -1130,6 +1158,7 @@ check_path (struct vectors * vecs, struc
+                       pp->dev);
+               pp->dmstate = PSTATE_UNDEF;
+       }
++      pp->chkrstate = newstate;
+       if (newstate != pp->state) {
+               int oldstate = pp->state;
+               pp->state = newstate;
+@@ -1182,6 +1211,9 @@ check_path (struct vectors * vecs, struc
+               new_path_up = 1;
++              if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST)
++                      chkr_new_path_up = 1;
++
+               /*
+                * if at least one path is up in a group, and
+                * the group is disabled, re-enable it
+@@ -1233,7 +1265,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 ||
++                       (chkr_new_path_up && followover_should_failback(pp)))
+                       switch_pathgroup(pp->mpp);
+       }
+ }
+Index: multipath-tools-120518/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-120518.orig/multipath/multipath.conf.5
++++ multipath-tools-120518/multipath/multipath.conf.5
+@@ -254,6 +254,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
+Index: multipath-tools-120518/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-120518.orig/libmultipath/discovery.c
++++ multipath-tools-120518/libmultipath/discovery.c
+@@ -878,13 +878,13 @@ pathinfo (struct path *pp, vector hwtabl
+       if (mask & DI_CHECKER) {
+               if (path_state == PATH_UP) {
+-                      pp->state = get_state(pp, 0);
++                      pp->chkrstate = pp->state = get_state(pp, 0);
+                       if (pp->state == PATH_UNCHECKED ||
+                           pp->state == PATH_WILD)
+                               goto blank;
+               } else {
+                       condlog(3, "%s: path inaccessible", pp->dev);
+-                      pp->state = path_state;
++                      pp->chkrstate = pp->state = path_state;
+               }
+       }
+@@ -912,7 +912,7 @@ blank:
+        * Recoverable error, for example faulty or offline path
+        */
+       memset(pp->wwid, 0, WWID_SIZE);
+-      pp->state = PATH_DOWN;
++      pp->chkrstate = pp->state = PATH_DOWN;
+       return 0;
+ }
+Index: multipath-tools-120518/multipath/main.c
+===================================================================
+--- multipath-tools-120518.orig/multipath/main.c
++++ multipath-tools-120518/multipath/main.c
+@@ -144,7 +144,7 @@ update_paths (struct multipath * mpp)
+                                       /*
+                                        * path is not in sysfs anymore
+                                        */
+-                                      pp->state = PATH_DOWN;
++                                      pp->chkrstate = pp->state = PATH_DOWN;
+                                       continue;
+                               }
+                               pp->mpp = mpp;