]>
Commit | Line | Data |
---|---|---|
d8602e2a SS |
1 | --- |
2 | libmultipath/dict.c | 12 ++++++++++++ | |
3 | libmultipath/discovery.c | 6 +++--- | |
4 | libmultipath/print.c | 2 ++ | |
5 | libmultipath/structs.h | 4 +++- | |
6 | multipath/main.c | 2 +- | |
7 | multipath/multipath.conf.5 | 5 +++++ | |
8 | multipathd/main.c | 35 ++++++++++++++++++++++++++++++++++- | |
9 | 7 files changed, 60 insertions(+), 6 deletions(-) | |
10 | ||
11 | Index: multipath-tools-120518/libmultipath/dict.c | |
12 | =================================================================== | |
13 | --- multipath-tools-120518.orig/libmultipath/dict.c | |
14 | +++ multipath-tools-120518/libmultipath/dict.c | |
15 | @@ -398,6 +398,8 @@ default_failback_handler(vector strvec) | |
16 | conf->pgfailback = -FAILBACK_MANUAL; | |
17 | else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) | |
18 | conf->pgfailback = -FAILBACK_IMMEDIATE; | |
19 | + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) | |
20 | + conf->pgfailback = -FAILBACK_FOLLOWOVER; | |
21 | else | |
22 | conf->pgfailback = atoi(buff); | |
23 | ||
24 | @@ -1053,6 +1055,8 @@ hw_failback_handler(vector strvec) | |
25 | hwe->pgfailback = -FAILBACK_MANUAL; | |
26 | else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) | |
27 | hwe->pgfailback = -FAILBACK_IMMEDIATE; | |
28 | + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) | |
29 | + hwe->pgfailback = -FAILBACK_FOLLOWOVER; | |
30 | else | |
31 | hwe->pgfailback = atoi(buff); | |
32 | ||
33 | @@ -1351,6 +1355,8 @@ mp_failback_handler(vector strvec) | |
34 | mpe->pgfailback = -FAILBACK_MANUAL; | |
35 | else if (strlen(buff) == 9 && !strcmp(buff, "immediate")) | |
36 | mpe->pgfailback = -FAILBACK_IMMEDIATE; | |
37 | + else if (strlen(buff) == 10 && !strcmp(buff, "followover")) | |
38 | + mpe->pgfailback = -FAILBACK_FOLLOWOVER; | |
39 | else | |
40 | mpe->pgfailback = atoi(buff); | |
41 | ||
42 | @@ -1769,6 +1775,8 @@ snprint_mp_failback (char * buff, int le | |
43 | return snprintf(buff, len, "manual"); | |
44 | case -FAILBACK_IMMEDIATE: | |
45 | return snprintf(buff, len, "immediate"); | |
46 | + case -FAILBACK_FOLLOWOVER: | |
47 | + return snprintf(buff, len, "followover"); | |
48 | default: | |
49 | return snprintf(buff, len, "%i", mpe->pgfailback); | |
50 | } | |
51 | @@ -2130,6 +2138,8 @@ snprint_hw_failback (char * buff, int le | |
52 | return snprintf(buff, len, "manual"); | |
53 | case -FAILBACK_IMMEDIATE: | |
54 | return snprintf(buff, len, "immediate"); | |
55 | + case -FAILBACK_FOLLOWOVER: | |
56 | + return snprintf(buff, len, "followover"); | |
57 | default: | |
58 | return snprintf(buff, len, "%i", hwe->pgfailback); | |
59 | } | |
60 | @@ -2394,6 +2404,8 @@ snprint_def_failback (char * buff, int l | |
61 | return snprintf(buff, len, "manual"); | |
62 | case -FAILBACK_IMMEDIATE: | |
63 | return snprintf(buff, len, "immediate"); | |
64 | + case -FAILBACK_FOLLOWOVER: | |
65 | + return snprintf(buff, len, "followover"); | |
66 | default: | |
67 | return snprintf(buff, len, "%i", conf->pgfailback); | |
68 | } | |
69 | Index: multipath-tools-120518/libmultipath/print.c | |
70 | =================================================================== | |
71 | --- multipath-tools-120518.orig/libmultipath/print.c | |
72 | +++ multipath-tools-120518/libmultipath/print.c | |
73 | @@ -143,6 +143,8 @@ snprint_failback (char * buff, size_t le | |
74 | { | |
75 | if (mpp->pgfailback == -FAILBACK_IMMEDIATE) | |
76 | return snprintf(buff, len, "immediate"); | |
77 | + if (mpp->pgfailback == -FAILBACK_FOLLOWOVER) | |
78 | + return snprintf(buff, len, "followover"); | |
79 | ||
80 | if (!mpp->failback_tick) | |
81 | return snprintf(buff, len, "-"); | |
82 | Index: multipath-tools-120518/libmultipath/structs.h | |
83 | =================================================================== | |
84 | --- multipath-tools-120518.orig/libmultipath/structs.h | |
85 | +++ multipath-tools-120518/libmultipath/structs.h | |
86 | @@ -39,7 +39,8 @@ enum rr_weight_mode { | |
87 | enum failback_mode { | |
88 | FAILBACK_UNDEF, | |
89 | FAILBACK_MANUAL, | |
90 | - FAILBACK_IMMEDIATE | |
91 | + FAILBACK_IMMEDIATE, | |
92 | + FAILBACK_FOLLOWOVER | |
93 | }; | |
94 | ||
95 | enum sysfs_buses { | |
96 | @@ -151,6 +152,7 @@ struct path { | |
97 | int offline; | |
98 | int state; | |
99 | int dmstate; | |
100 | + int chkrstate; | |
101 | int failcount; | |
102 | int priority; | |
103 | int pgindex; | |
104 | Index: multipath-tools-120518/multipathd/main.c | |
105 | =================================================================== | |
106 | --- multipath-tools-120518.orig/multipathd/main.c | |
107 | +++ multipath-tools-120518/multipathd/main.c | |
108 | @@ -995,6 +995,32 @@ mpvec_garbage_collector (struct vectors | |
109 | } | |
110 | } | |
111 | ||
112 | +/* This is called after a path has started working again. It the multipath | |
113 | + * device for this path uses the followover failback type, and this is the | |
114 | + * best pathgroup, and this is the first path in the pathgroup to come back | |
115 | + * up, then switch to this pathgroup */ | |
116 | +static int | |
117 | +followover_should_failback(struct path * pp) | |
118 | +{ | |
119 | + struct pathgroup * pgp; | |
120 | + struct path *pp1; | |
121 | + int i; | |
122 | + | |
123 | + if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER || | |
124 | + !pp->mpp->pg || !pp->pgindex || | |
125 | + pp->pgindex != pp->mpp->bestpg) | |
126 | + return 0; | |
127 | + | |
128 | + pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1); | |
129 | + vector_foreach_slot(pgp->paths, pp1, i) { | |
130 | + if (pp1 == pp) | |
131 | + continue; | |
132 | + if (pp1->chkrstate != PATH_DOWN && pp1->chkrstate != PATH_SHAKY) | |
133 | + return 0; | |
134 | + } | |
135 | + return 1; | |
136 | +} | |
137 | + | |
138 | static void | |
139 | defered_failback_tick (vector mpvec) | |
140 | { | |
141 | @@ -1092,6 +1118,8 @@ check_path (struct vectors * vecs, struc | |
142 | { | |
143 | int newstate; | |
144 | int new_path_up = 0; | |
145 | + int chkr_new_path_up = 0; | |
146 | + int oldchkrstate = pp->chkrstate; | |
147 | ||
148 | if (!pp->mpp) | |
149 | return; | |
150 | @@ -1130,6 +1158,7 @@ check_path (struct vectors * vecs, struc | |
151 | pp->dev); | |
152 | pp->dmstate = PSTATE_UNDEF; | |
153 | } | |
154 | + pp->chkrstate = newstate; | |
155 | if (newstate != pp->state) { | |
156 | int oldstate = pp->state; | |
157 | pp->state = newstate; | |
158 | @@ -1182,6 +1211,9 @@ check_path (struct vectors * vecs, struc | |
159 | ||
160 | new_path_up = 1; | |
161 | ||
162 | + if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) | |
163 | + chkr_new_path_up = 1; | |
164 | + | |
165 | /* | |
166 | * if at least one path is up in a group, and | |
167 | * the group is disabled, re-enable it | |
168 | @@ -1233,7 +1265,8 @@ check_path (struct vectors * vecs, struc | |
169 | (new_path_up || pp->mpp->failback_tick <= 0)) | |
170 | pp->mpp->failback_tick = | |
171 | pp->mpp->pgfailback + 1; | |
172 | - else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) | |
173 | + else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE || | |
174 | + (chkr_new_path_up && followover_should_failback(pp))) | |
175 | switch_pathgroup(pp->mpp); | |
176 | } | |
177 | } | |
178 | Index: multipath-tools-120518/multipath/multipath.conf.5 | |
179 | =================================================================== | |
180 | --- multipath-tools-120518.orig/multipath/multipath.conf.5 | |
181 | +++ multipath-tools-120518/multipath/multipath.conf.5 | |
182 | @@ -254,6 +254,11 @@ active paths. | |
183 | .B manual | |
184 | Do not perform automatic failback. | |
185 | .TP | |
186 | +.B followover | |
187 | +Only perform automatic failback when the first path of a pathgroup | |
188 | +becomes active. This keeps a node from automatically failing back when | |
189 | +another node requested the failover. | |
190 | +.TP | |
191 | .B values > 0 | |
192 | deferred failback (time to defer in seconds) | |
193 | .TP | |
194 | Index: multipath-tools-120518/libmultipath/discovery.c | |
195 | =================================================================== | |
196 | --- multipath-tools-120518.orig/libmultipath/discovery.c | |
197 | +++ multipath-tools-120518/libmultipath/discovery.c | |
198 | @@ -878,13 +878,13 @@ pathinfo (struct path *pp, vector hwtabl | |
199 | ||
200 | if (mask & DI_CHECKER) { | |
201 | if (path_state == PATH_UP) { | |
202 | - pp->state = get_state(pp, 0); | |
203 | + pp->chkrstate = pp->state = get_state(pp, 0); | |
204 | if (pp->state == PATH_UNCHECKED || | |
205 | pp->state == PATH_WILD) | |
206 | goto blank; | |
207 | } else { | |
208 | condlog(3, "%s: path inaccessible", pp->dev); | |
209 | - pp->state = path_state; | |
210 | + pp->chkrstate = pp->state = path_state; | |
211 | } | |
212 | } | |
213 | ||
214 | @@ -912,7 +912,7 @@ blank: | |
215 | * Recoverable error, for example faulty or offline path | |
216 | */ | |
217 | memset(pp->wwid, 0, WWID_SIZE); | |
218 | - pp->state = PATH_DOWN; | |
219 | + pp->chkrstate = pp->state = PATH_DOWN; | |
220 | ||
221 | return 0; | |
222 | } | |
223 | Index: multipath-tools-120518/multipath/main.c | |
224 | =================================================================== | |
225 | --- multipath-tools-120518.orig/multipath/main.c | |
226 | +++ multipath-tools-120518/multipath/main.c | |
227 | @@ -144,7 +144,7 @@ update_paths (struct multipath * mpp) | |
228 | /* | |
229 | * path is not in sysfs anymore | |
230 | */ | |
231 | - pp->state = PATH_DOWN; | |
232 | + pp->chkrstate = pp->state = PATH_DOWN; | |
233 | continue; | |
234 | } | |
235 | pp->mpp = mpp; |