This source file includes following definitions.
- do_timer_control
- get_timer_desc
- crm_timer_popped
- controld_init_fsa_timers
- controld_free_fsa_timers
- is_timer_started
- controld_start_timer
- controld_start_recheck_timer
- controld_stop_timer
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <time.h>
13 #include <stdlib.h>
14
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <pacemaker-controld.h>
18
19
20 fsa_timer_t *wait_timer = NULL;
21
22
23 fsa_timer_t *recheck_timer = NULL;
24
25
26 fsa_timer_t *election_trigger = NULL;
27
28
29 fsa_timer_t *transition_timer = NULL;
30
31
32 fsa_timer_t *integration_timer = NULL;
33
34
35 fsa_timer_t *finalization_timer = NULL;
36
37
38 fsa_timer_t *shutdown_escalation_timer = NULL;
39
40
41 guint recheck_interval_ms = 0;
42
43
44 time_t recheck_by = 0;
45
46
47
48
49
50 void
51 do_timer_control(long long action,
52 enum crmd_fsa_cause cause,
53 enum crmd_fsa_state cur_state,
54 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
55 {
56 gboolean timer_op_ok = TRUE;
57
58 if (action & A_DC_TIMER_STOP) {
59 timer_op_ok = controld_stop_timer(election_trigger);
60
61 } else if (action & A_FINALIZE_TIMER_STOP) {
62 timer_op_ok = controld_stop_timer(finalization_timer);
63
64 } else if (action & A_INTEGRATE_TIMER_STOP) {
65 timer_op_ok = controld_stop_timer(integration_timer);
66 }
67
68
69 if (action & A_DC_TIMER_START && timer_op_ok) {
70 controld_start_timer(election_trigger);
71 if (AM_I_DC) {
72
73 register_fsa_input(cause, I_ELECTION, NULL);
74 }
75
76 } else if (action & A_FINALIZE_TIMER_START) {
77 controld_start_timer(finalization_timer);
78
79 } else if (action & A_INTEGRATE_TIMER_START) {
80 controld_start_timer(integration_timer);
81 }
82 }
83
84 const char *
85 get_timer_desc(fsa_timer_t * timer)
86 {
87 if (timer == election_trigger) {
88 return "Election Trigger";
89
90 } else if (timer == shutdown_escalation_timer) {
91 return "Shutdown Escalation";
92
93 } else if (timer == integration_timer) {
94 return "Integration Timer";
95
96 } else if (timer == finalization_timer) {
97 return "Finalization Timer";
98
99 } else if (timer == transition_timer) {
100 return "New Transition Timer";
101
102 } else if (timer == wait_timer) {
103 return "Wait Timer";
104
105 } else if (timer == recheck_timer) {
106 return "Cluster Recheck Timer";
107
108 }
109 return "Unknown Timer";
110 }
111
112 static gboolean
113 crm_timer_popped(gpointer data)
114 {
115 fsa_timer_t *timer = (fsa_timer_t *) data;
116
117 if (timer->log_error) {
118 crm_err("%s just popped in state %s! " CRM_XS " input=%s time=%ums",
119 get_timer_desc(timer), fsa_state2string(fsa_state),
120 fsa_input2string(timer->fsa_input), timer->period_ms);
121 } else {
122 crm_info("%s just popped " CRM_XS " input=%s time=%ums",
123 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
124 timer->period_ms);
125 timer->counter++;
126 }
127
128 if (timer == election_trigger && election_trigger->counter > 5) {
129 crm_notice("We appear to be in an election loop, something may be wrong");
130 crm_write_blackbox(0, NULL);
131 election_trigger->counter = 0;
132 }
133
134 controld_stop_timer(timer);
135
136 if (timer->fsa_input == I_INTEGRATED) {
137 crm_info("Welcomed: %d, Integrated: %d",
138 crmd_join_phase_count(crm_join_welcomed),
139 crmd_join_phase_count(crm_join_integrated));
140 if (crmd_join_phase_count(crm_join_welcomed) == 0) {
141
142 register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, NULL,
143 __func__);
144
145 } else {
146 register_fsa_input_before(C_TIMER_POPPED, timer->fsa_input, NULL);
147 }
148
149 } else if (timer == recheck_timer && fsa_state != S_IDLE) {
150 crm_debug("Discarding %s event in state: %s",
151 fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
152
153 } else if (timer == finalization_timer && fsa_state != S_FINALIZE_JOIN) {
154 crm_debug("Discarding %s event in state: %s",
155 fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
156
157 } else if (timer->fsa_input != I_NULL) {
158 register_fsa_input(C_TIMER_POPPED, timer->fsa_input, NULL);
159 }
160
161 crm_trace("Triggering FSA: %s", __func__);
162 mainloop_set_trigger(fsa_source);
163
164 return TRUE;
165 }
166
167 bool
168 controld_init_fsa_timers()
169 {
170 transition_timer = calloc(1, sizeof(fsa_timer_t));
171 if (transition_timer == NULL) {
172 return FALSE;
173 }
174
175 integration_timer = calloc(1, sizeof(fsa_timer_t));
176 if (integration_timer == NULL) {
177 return FALSE;
178 }
179
180 finalization_timer = calloc(1, sizeof(fsa_timer_t));
181 if (finalization_timer == NULL) {
182 return FALSE;
183 }
184
185 election_trigger = calloc(1, sizeof(fsa_timer_t));
186 if (election_trigger == NULL) {
187 return FALSE;
188 }
189
190 shutdown_escalation_timer = calloc(1, sizeof(fsa_timer_t));
191 if (shutdown_escalation_timer == NULL) {
192 return FALSE;
193 }
194
195 wait_timer = calloc(1, sizeof(fsa_timer_t));
196 if (wait_timer == NULL) {
197 return FALSE;
198 }
199
200 recheck_timer = calloc(1, sizeof(fsa_timer_t));
201 if (recheck_timer == NULL) {
202 return FALSE;
203 }
204
205 election_trigger->source_id = 0;
206 election_trigger->period_ms = 0;
207 election_trigger->fsa_input = I_DC_TIMEOUT;
208 election_trigger->callback = crm_timer_popped;
209 election_trigger->log_error = FALSE;
210
211 transition_timer->source_id = 0;
212 transition_timer->period_ms = 0;
213 transition_timer->fsa_input = I_PE_CALC;
214 transition_timer->callback = crm_timer_popped;
215 transition_timer->log_error = FALSE;
216
217 integration_timer->source_id = 0;
218 integration_timer->period_ms = 0;
219 integration_timer->fsa_input = I_INTEGRATED;
220 integration_timer->callback = crm_timer_popped;
221 integration_timer->log_error = TRUE;
222
223 finalization_timer->source_id = 0;
224 finalization_timer->period_ms = 0;
225 finalization_timer->fsa_input = I_FINALIZED;
226 finalization_timer->callback = crm_timer_popped;
227 finalization_timer->log_error = FALSE;
228
229
230
231
232
233
234
235
236
237
238
239
240 finalization_timer->fsa_input = I_ELECTION;
241
242 shutdown_escalation_timer->source_id = 0;
243 shutdown_escalation_timer->period_ms = 0;
244 shutdown_escalation_timer->fsa_input = I_STOP;
245 shutdown_escalation_timer->callback = crm_timer_popped;
246 shutdown_escalation_timer->log_error = TRUE;
247
248 wait_timer->source_id = 0;
249 wait_timer->period_ms = 2000;
250 wait_timer->fsa_input = I_NULL;
251 wait_timer->callback = crm_timer_popped;
252 wait_timer->log_error = FALSE;
253
254 recheck_timer->source_id = 0;
255 recheck_timer->period_ms = 0;
256 recheck_timer->fsa_input = I_PE_CALC;
257 recheck_timer->callback = crm_timer_popped;
258 recheck_timer->log_error = FALSE;
259
260 return TRUE;
261 }
262
263 void
264 controld_free_fsa_timers()
265 {
266 controld_stop_timer(transition_timer);
267 controld_stop_timer(integration_timer);
268 controld_stop_timer(finalization_timer);
269 controld_stop_timer(election_trigger);
270 controld_stop_timer(shutdown_escalation_timer);
271 controld_stop_timer(wait_timer);
272 controld_stop_timer(recheck_timer);
273
274 free(transition_timer); transition_timer = NULL;
275 free(integration_timer); integration_timer = NULL;
276 free(finalization_timer); finalization_timer = NULL;
277 free(election_trigger); election_trigger = NULL;
278 free(shutdown_escalation_timer); shutdown_escalation_timer = NULL;
279 free(wait_timer); wait_timer = NULL;
280 free(recheck_timer); recheck_timer = NULL;
281 }
282
283 gboolean
284 is_timer_started(fsa_timer_t * timer)
285 {
286 return (timer->period_ms > 0) && (timer->source_id != 0);
287 }
288
289 void
290 controld_start_timer(fsa_timer_t *timer)
291 {
292 if (timer->source_id == 0 && timer->period_ms > 0) {
293 timer->source_id = g_timeout_add(timer->period_ms, timer->callback, (void *)timer);
294 CRM_ASSERT(timer->source_id != 0);
295 crm_debug("Started %s (inject %s if pops after %ums, source=%d)",
296 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
297 timer->period_ms, timer->source_id);
298 } else {
299 crm_debug("%s already running (inject %s if pops after %ums, source=%d)",
300 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
301 timer->period_ms, timer->source_id);
302 }
303 }
304
305 void
306 controld_start_recheck_timer()
307 {
308
309 guint period_ms = recheck_interval_ms;
310
311
312 if (recheck_by > 0) {
313 time_t diff_seconds = recheck_by - time(NULL);
314
315 if (diff_seconds < 1) {
316
317 period_ms = 500;
318 } else {
319 period_ms = (guint) diff_seconds * 1000;
320 }
321
322
323 if (period_ms > recheck_interval_ms) {
324 period_ms = recheck_interval_ms;
325 }
326 }
327
328 if (period_ms > 0) {
329 recheck_timer->period_ms = period_ms;
330 controld_start_timer(recheck_timer);
331 }
332 }
333
334 gboolean
335 controld_stop_timer(fsa_timer_t *timer)
336 {
337 CRM_CHECK(timer != NULL, return FALSE);
338
339 if (timer->source_id != 0) {
340 crm_trace("Stopping %s (would inject %s if popped after %ums, src=%d)",
341 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
342 timer->period_ms, timer->source_id);
343 g_source_remove(timer->source_id);
344 timer->source_id = 0;
345
346 } else {
347 crm_trace("%s already stopped (would inject %s if popped after %ums)",
348 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
349 timer->period_ms);
350 return FALSE;
351 }
352 return TRUE;
353 }