This source file includes following definitions.
- do_timer_control
- get_timer_desc
- crm_timer_popped
- is_timer_started
- crm_timer_start
- crm_timer_stop
- fsa_input2string
- fsa_state2string
- fsa_cause2string
- fsa_action2string
- fsa_dump_inputs
- fsa_dump_actions
- update_dc
- erase_xpath_callback
- erase_status_tag
- crmd_peer_down
- cib_op_timeout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #include <crm/crm.h>
22 #include <crm/cib.h>
23 #include <crm/msg_xml.h>
24 #include <crm/common/xml.h>
25 #include <crm/cluster.h>
26
27 #include <crmd_fsa.h>
28 #include <crmd_utils.h>
29 #include <crmd_messages.h>
30
31
32
33
34
35 void
36 do_timer_control(long long action,
37 enum crmd_fsa_cause cause,
38 enum crmd_fsa_state cur_state,
39 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
40 {
41 gboolean timer_op_ok = TRUE;
42
43 if (action & A_DC_TIMER_STOP) {
44 timer_op_ok = crm_timer_stop(election_trigger);
45
46 } else if (action & A_FINALIZE_TIMER_STOP) {
47 timer_op_ok = crm_timer_stop(finalization_timer);
48
49 } else if (action & A_INTEGRATE_TIMER_STOP) {
50 timer_op_ok = crm_timer_stop(integration_timer);
51
52
53
54 }
55
56
57 if (action & A_DC_TIMER_START && timer_op_ok) {
58 crm_timer_start(election_trigger);
59 if (AM_I_DC) {
60
61 register_fsa_input(cause, I_ELECTION, NULL);
62 }
63
64 } else if (action & A_FINALIZE_TIMER_START) {
65 crm_timer_start(finalization_timer);
66
67 } else if (action & A_INTEGRATE_TIMER_START) {
68 crm_timer_start(integration_timer);
69
70
71
72 }
73 }
74
75 const char *
76 get_timer_desc(fsa_timer_t * timer)
77 {
78 if (timer == election_trigger) {
79 return "Election Trigger";
80
81 } else if (timer == shutdown_escalation_timer) {
82 return "Shutdown Escalation";
83
84 } else if (timer == integration_timer) {
85 return "Integration Timer";
86
87 } else if (timer == finalization_timer) {
88 return "Finalization Timer";
89
90 } else if (timer == transition_timer) {
91 return "New Transition Timer";
92
93 } else if (timer == wait_timer) {
94 return "Wait Timer";
95
96 } else if (timer == recheck_timer) {
97 return "PEngine Recheck Timer";
98
99 }
100 return "Unknown Timer";
101 }
102
103 gboolean
104 crm_timer_popped(gpointer data)
105 {
106 fsa_timer_t *timer = (fsa_timer_t *) data;
107
108 if (timer == wait_timer
109 || timer == recheck_timer
110 || timer == transition_timer || timer == finalization_timer || timer == election_trigger) {
111 crm_info("%s (%s) just popped (%dms)",
112 get_timer_desc(timer), fsa_input2string(timer->fsa_input), timer->period_ms);
113 timer->counter++;
114
115 } else {
116 crm_err("%s (%s) just popped in state %s! (%dms)",
117 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
118 fsa_state2string(fsa_state), timer->period_ms);
119 }
120
121 if (timer == election_trigger && election_trigger->counter > 5) {
122 crm_notice("We appear to be in an election loop, something may be wrong");
123 crm_write_blackbox(0, NULL);
124 election_trigger->counter = 0;
125 }
126
127 if (timer->repeat == FALSE) {
128 crm_timer_stop(timer);
129 }
130
131 if (timer->fsa_input == I_INTEGRATED) {
132 crm_info("Welcomed: %d, Integrated: %d",
133 crmd_join_phase_count(crm_join_welcomed),
134 crmd_join_phase_count(crm_join_integrated));
135 if (crmd_join_phase_count(crm_join_welcomed) == 0) {
136
137 register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, NULL, __FUNCTION__);
138
139 } else {
140 register_fsa_input_before(C_TIMER_POPPED, timer->fsa_input, NULL);
141 }
142
143 } else if (timer == recheck_timer && fsa_state != S_IDLE) {
144 crm_debug("Discarding %s event in state: %s",
145 fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
146
147 } else if (timer == finalization_timer && fsa_state != S_FINALIZE_JOIN) {
148 crm_debug("Discarding %s event in state: %s",
149 fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
150
151 } else if (timer->fsa_input != I_NULL) {
152 register_fsa_input(C_TIMER_POPPED, timer->fsa_input, NULL);
153 }
154
155 crm_trace("Triggering FSA: %s", __FUNCTION__);
156 mainloop_set_trigger(fsa_source);
157
158 return TRUE;
159 }
160
161 gboolean
162 is_timer_started(fsa_timer_t * timer)
163 {
164 if (timer->period_ms > 0) {
165 if (timer->source_id == 0) {
166 return FALSE;
167 } else {
168 return TRUE;
169 }
170 }
171 return FALSE;
172 }
173
174 gboolean
175 crm_timer_start(fsa_timer_t * timer)
176 {
177 const char *timer_desc = get_timer_desc(timer);
178
179 if (timer->source_id == 0 && timer->period_ms > 0) {
180 timer->source_id = g_timeout_add(timer->period_ms, timer->callback, (void *)timer);
181 CRM_ASSERT(timer->source_id != 0);
182 crm_debug("Started %s (%s:%dms), src=%d",
183 timer_desc, fsa_input2string(timer->fsa_input),
184 timer->period_ms, timer->source_id);
185
186 } else if (timer->period_ms < 0) {
187 crm_err("Tried to start %s (%s:%dms) with a -ve period",
188 timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms);
189
190 } else {
191 crm_debug("%s (%s:%dms) already running: src=%d",
192 timer_desc, fsa_input2string(timer->fsa_input),
193 timer->period_ms, timer->source_id);
194 return FALSE;
195 }
196 return TRUE;
197 }
198
199 gboolean
200 crm_timer_stop(fsa_timer_t * timer)
201 {
202 const char *timer_desc = get_timer_desc(timer);
203
204 if (timer == NULL) {
205 crm_err("Attempted to stop NULL timer");
206 return FALSE;
207
208 } else if (timer->source_id != 0) {
209 crm_trace("Stopping %s (%s:%dms), src=%d",
210 timer_desc, fsa_input2string(timer->fsa_input),
211 timer->period_ms, timer->source_id);
212 g_source_remove(timer->source_id);
213 timer->source_id = 0;
214
215 } else {
216 crm_trace("%s (%s:%dms) already stopped",
217 timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms);
218 return FALSE;
219 }
220 return TRUE;
221 }
222
223 const char *
224 fsa_input2string(enum crmd_fsa_input input)
225 {
226 const char *inputAsText = NULL;
227
228 switch (input) {
229 case I_NULL:
230 inputAsText = "I_NULL";
231 break;
232 case I_CIB_OP:
233 inputAsText = "I_CIB_OP (unused)";
234 break;
235 case I_CIB_UPDATE:
236 inputAsText = "I_CIB_UPDATE";
237 break;
238 case I_DC_TIMEOUT:
239 inputAsText = "I_DC_TIMEOUT";
240 break;
241 case I_ELECTION:
242 inputAsText = "I_ELECTION";
243 break;
244 case I_PE_CALC:
245 inputAsText = "I_PE_CALC";
246 break;
247 case I_RELEASE_DC:
248 inputAsText = "I_RELEASE_DC";
249 break;
250 case I_ELECTION_DC:
251 inputAsText = "I_ELECTION_DC";
252 break;
253 case I_ERROR:
254 inputAsText = "I_ERROR";
255 break;
256 case I_FAIL:
257 inputAsText = "I_FAIL";
258 break;
259 case I_INTEGRATED:
260 inputAsText = "I_INTEGRATED";
261 break;
262 case I_FINALIZED:
263 inputAsText = "I_FINALIZED";
264 break;
265 case I_NODE_JOIN:
266 inputAsText = "I_NODE_JOIN";
267 break;
268 case I_JOIN_OFFER:
269 inputAsText = "I_JOIN_OFFER";
270 break;
271 case I_JOIN_REQUEST:
272 inputAsText = "I_JOIN_REQUEST";
273 break;
274 case I_JOIN_RESULT:
275 inputAsText = "I_JOIN_RESULT";
276 break;
277 case I_NOT_DC:
278 inputAsText = "I_NOT_DC";
279 break;
280 case I_RECOVERED:
281 inputAsText = "I_RECOVERED";
282 break;
283 case I_RELEASE_FAIL:
284 inputAsText = "I_RELEASE_FAIL";
285 break;
286 case I_RELEASE_SUCCESS:
287 inputAsText = "I_RELEASE_SUCCESS";
288 break;
289 case I_RESTART:
290 inputAsText = "I_RESTART";
291 break;
292 case I_PE_SUCCESS:
293 inputAsText = "I_PE_SUCCESS";
294 break;
295 case I_ROUTER:
296 inputAsText = "I_ROUTER";
297 break;
298 case I_SHUTDOWN:
299 inputAsText = "I_SHUTDOWN";
300 break;
301 case I_STARTUP:
302 inputAsText = "I_STARTUP";
303 break;
304 case I_TE_SUCCESS:
305 inputAsText = "I_TE_SUCCESS";
306 break;
307 case I_STOP:
308 inputAsText = "I_STOP";
309 break;
310 case I_DC_HEARTBEAT:
311 inputAsText = "I_DC_HEARTBEAT";
312 break;
313 case I_WAIT_FOR_EVENT:
314 inputAsText = "I_WAIT_FOR_EVENT";
315 break;
316 case I_LRM_EVENT:
317 inputAsText = "I_LRM_EVENT";
318 break;
319 case I_PENDING:
320 inputAsText = "I_PENDING";
321 break;
322 case I_HALT:
323 inputAsText = "I_HALT";
324 break;
325 case I_TERMINATE:
326 inputAsText = "I_TERMINATE";
327 break;
328 case I_ILLEGAL:
329 inputAsText = "I_ILLEGAL";
330 break;
331 }
332
333 if (inputAsText == NULL) {
334 crm_err("Input %d is unknown", input);
335 inputAsText = "<UNKNOWN_INPUT>";
336 }
337
338 return inputAsText;
339 }
340
341 const char *
342 fsa_state2string(enum crmd_fsa_state state)
343 {
344 const char *stateAsText = NULL;
345
346 switch (state) {
347 case S_IDLE:
348 stateAsText = "S_IDLE";
349 break;
350 case S_ELECTION:
351 stateAsText = "S_ELECTION";
352 break;
353 case S_INTEGRATION:
354 stateAsText = "S_INTEGRATION";
355 break;
356 case S_FINALIZE_JOIN:
357 stateAsText = "S_FINALIZE_JOIN";
358 break;
359 case S_NOT_DC:
360 stateAsText = "S_NOT_DC";
361 break;
362 case S_POLICY_ENGINE:
363 stateAsText = "S_POLICY_ENGINE";
364 break;
365 case S_RECOVERY:
366 stateAsText = "S_RECOVERY";
367 break;
368 case S_RELEASE_DC:
369 stateAsText = "S_RELEASE_DC";
370 break;
371 case S_PENDING:
372 stateAsText = "S_PENDING";
373 break;
374 case S_STOPPING:
375 stateAsText = "S_STOPPING";
376 break;
377 case S_TERMINATE:
378 stateAsText = "S_TERMINATE";
379 break;
380 case S_TRANSITION_ENGINE:
381 stateAsText = "S_TRANSITION_ENGINE";
382 break;
383 case S_STARTING:
384 stateAsText = "S_STARTING";
385 break;
386 case S_HALT:
387 stateAsText = "S_HALT";
388 break;
389 case S_ILLEGAL:
390 stateAsText = "S_ILLEGAL";
391 break;
392 }
393
394 if (stateAsText == NULL) {
395 crm_err("State %d is unknown", state);
396 stateAsText = "<UNKNOWN_STATE>";
397 }
398
399 return stateAsText;
400 }
401
402 const char *
403 fsa_cause2string(enum crmd_fsa_cause cause)
404 {
405 const char *causeAsText = NULL;
406
407 switch (cause) {
408 case C_UNKNOWN:
409 causeAsText = "C_UNKNOWN";
410 break;
411 case C_STARTUP:
412 causeAsText = "C_STARTUP";
413 break;
414 case C_IPC_MESSAGE:
415 causeAsText = "C_IPC_MESSAGE";
416 break;
417 case C_HA_MESSAGE:
418 causeAsText = "C_HA_MESSAGE";
419 break;
420 case C_CCM_CALLBACK:
421 causeAsText = "C_CCM_CALLBACK";
422 break;
423 case C_TIMER_POPPED:
424 causeAsText = "C_TIMER_POPPED";
425 break;
426 case C_SHUTDOWN:
427 causeAsText = "C_SHUTDOWN";
428 break;
429 case C_HEARTBEAT_FAILED:
430 causeAsText = "C_HEARTBEAT_FAILED";
431 break;
432 case C_SUBSYSTEM_CONNECT:
433 causeAsText = "C_SUBSYSTEM_CONNECT";
434 break;
435 case C_LRM_OP_CALLBACK:
436 causeAsText = "C_LRM_OP_CALLBACK";
437 break;
438 case C_LRM_MONITOR_CALLBACK:
439 causeAsText = "C_LRM_MONITOR_CALLBACK";
440 break;
441 case C_CRMD_STATUS_CALLBACK:
442 causeAsText = "C_CRMD_STATUS_CALLBACK";
443 break;
444 case C_HA_DISCONNECT:
445 causeAsText = "C_HA_DISCONNECT";
446 break;
447 case C_FSA_INTERNAL:
448 causeAsText = "C_FSA_INTERNAL";
449 break;
450 case C_ILLEGAL:
451 causeAsText = "C_ILLEGAL";
452 break;
453 }
454
455 if (causeAsText == NULL) {
456 crm_err("Cause %d is unknown", cause);
457 causeAsText = "<UNKNOWN_CAUSE>";
458 }
459
460 return causeAsText;
461 }
462
463 const char *
464 fsa_action2string(long long action)
465 {
466 const char *actionAsText = NULL;
467
468 switch (action) {
469
470 case A_NOTHING:
471 actionAsText = "A_NOTHING";
472 break;
473 case A_ELECTION_START:
474 actionAsText = "A_ELECTION_START";
475 break;
476 case A_DC_JOIN_FINAL:
477 actionAsText = "A_DC_JOIN_FINAL";
478 break;
479 case A_READCONFIG:
480 actionAsText = "A_READCONFIG";
481 break;
482 case O_RELEASE:
483 actionAsText = "O_RELEASE";
484 break;
485 case A_STARTUP:
486 actionAsText = "A_STARTUP";
487 break;
488 case A_STARTED:
489 actionAsText = "A_STARTED";
490 break;
491 case A_HA_CONNECT:
492 actionAsText = "A_HA_CONNECT";
493 break;
494 case A_HA_DISCONNECT:
495 actionAsText = "A_HA_DISCONNECT";
496 break;
497 case A_LRM_CONNECT:
498 actionAsText = "A_LRM_CONNECT";
499 break;
500 case A_LRM_EVENT:
501 actionAsText = "A_LRM_EVENT";
502 break;
503 case A_LRM_INVOKE:
504 actionAsText = "A_LRM_INVOKE";
505 break;
506 case A_LRM_DISCONNECT:
507 actionAsText = "A_LRM_DISCONNECT";
508 break;
509 case O_LRM_RECONNECT:
510 actionAsText = "O_LRM_RECONNECT";
511 break;
512 case A_CL_JOIN_QUERY:
513 actionAsText = "A_CL_JOIN_QUERY";
514 break;
515 case A_DC_TIMER_STOP:
516 actionAsText = "A_DC_TIMER_STOP";
517 break;
518 case A_DC_TIMER_START:
519 actionAsText = "A_DC_TIMER_START";
520 break;
521 case A_INTEGRATE_TIMER_START:
522 actionAsText = "A_INTEGRATE_TIMER_START";
523 break;
524 case A_INTEGRATE_TIMER_STOP:
525 actionAsText = "A_INTEGRATE_TIMER_STOP";
526 break;
527 case A_FINALIZE_TIMER_START:
528 actionAsText = "A_FINALIZE_TIMER_START";
529 break;
530 case A_FINALIZE_TIMER_STOP:
531 actionAsText = "A_FINALIZE_TIMER_STOP";
532 break;
533 case A_ELECTION_COUNT:
534 actionAsText = "A_ELECTION_COUNT";
535 break;
536 case A_ELECTION_VOTE:
537 actionAsText = "A_ELECTION_VOTE";
538 break;
539 case A_ELECTION_CHECK:
540 actionAsText = "A_ELECTION_CHECK";
541 break;
542 case A_CL_JOIN_ANNOUNCE:
543 actionAsText = "A_CL_JOIN_ANNOUNCE";
544 break;
545 case A_CL_JOIN_REQUEST:
546 actionAsText = "A_CL_JOIN_REQUEST";
547 break;
548 case A_CL_JOIN_RESULT:
549 actionAsText = "A_CL_JOIN_RESULT";
550 break;
551 case A_DC_JOIN_OFFER_ALL:
552 actionAsText = "A_DC_JOIN_OFFER_ALL";
553 break;
554 case A_DC_JOIN_OFFER_ONE:
555 actionAsText = "A_DC_JOIN_OFFER_ONE";
556 break;
557 case A_DC_JOIN_PROCESS_REQ:
558 actionAsText = "A_DC_JOIN_PROCESS_REQ";
559 break;
560 case A_DC_JOIN_PROCESS_ACK:
561 actionAsText = "A_DC_JOIN_PROCESS_ACK";
562 break;
563 case A_DC_JOIN_FINALIZE:
564 actionAsText = "A_DC_JOIN_FINALIZE";
565 break;
566 case A_MSG_PROCESS:
567 actionAsText = "A_MSG_PROCESS";
568 break;
569 case A_MSG_ROUTE:
570 actionAsText = "A_MSG_ROUTE";
571 break;
572 case A_RECOVER:
573 actionAsText = "A_RECOVER";
574 break;
575 case A_DC_RELEASE:
576 actionAsText = "A_DC_RELEASE";
577 break;
578 case A_DC_RELEASED:
579 actionAsText = "A_DC_RELEASED";
580 break;
581 case A_DC_TAKEOVER:
582 actionAsText = "A_DC_TAKEOVER";
583 break;
584 case A_SHUTDOWN:
585 actionAsText = "A_SHUTDOWN";
586 break;
587 case A_SHUTDOWN_REQ:
588 actionAsText = "A_SHUTDOWN_REQ";
589 break;
590 case A_STOP:
591 actionAsText = "A_STOP ";
592 break;
593 case A_EXIT_0:
594 actionAsText = "A_EXIT_0";
595 break;
596 case A_EXIT_1:
597 actionAsText = "A_EXIT_1";
598 break;
599 case A_CCM_CONNECT:
600 actionAsText = "A_CCM_CONNECT";
601 break;
602 case A_CCM_DISCONNECT:
603 actionAsText = "A_CCM_DISCONNECT";
604 break;
605 case O_CIB_RESTART:
606 actionAsText = "O_CIB_RESTART";
607 break;
608 case A_CIB_START:
609 actionAsText = "A_CIB_START";
610 break;
611 case A_CIB_STOP:
612 actionAsText = "A_CIB_STOP";
613 break;
614 case A_TE_INVOKE:
615 actionAsText = "A_TE_INVOKE";
616 break;
617 case O_TE_RESTART:
618 actionAsText = "O_TE_RESTART";
619 break;
620 case A_TE_START:
621 actionAsText = "A_TE_START";
622 break;
623 case A_TE_STOP:
624 actionAsText = "A_TE_STOP";
625 break;
626 case A_TE_HALT:
627 actionAsText = "A_TE_HALT";
628 break;
629 case A_TE_CANCEL:
630 actionAsText = "A_TE_CANCEL";
631 break;
632 case A_PE_INVOKE:
633 actionAsText = "A_PE_INVOKE";
634 break;
635 case O_PE_RESTART:
636 actionAsText = "O_PE_RESTART";
637 break;
638 case A_PE_START:
639 actionAsText = "A_PE_START";
640 break;
641 case A_PE_STOP:
642 actionAsText = "A_PE_STOP";
643 break;
644 case A_NODE_BLOCK:
645 actionAsText = "A_NODE_BLOCK";
646 break;
647 case A_UPDATE_NODESTATUS:
648 actionAsText = "A_UPDATE_NODESTATUS";
649 break;
650 case A_LOG:
651 actionAsText = "A_LOG ";
652 break;
653 case A_ERROR:
654 actionAsText = "A_ERROR ";
655 break;
656 case A_WARN:
657 actionAsText = "A_WARN ";
658 break;
659
660 case A_DC_TIMER_START | A_CL_JOIN_QUERY:
661 actionAsText = "A_DC_TIMER_START|A_CL_JOIN_QUERY";
662 break;
663 }
664
665 if (actionAsText == NULL) {
666 crm_err("Action %.16llx is unknown", action);
667 actionAsText = "<UNKNOWN_ACTION>";
668 }
669
670 return actionAsText;
671 }
672
673 void
674 fsa_dump_inputs(int log_level, const char *text, long long input_register)
675 {
676 if (input_register == A_NOTHING) {
677 return;
678 }
679 if (text == NULL) {
680 text = "Input register contents:";
681 }
682
683 if (is_set(input_register, R_THE_DC)) {
684 crm_trace("%s %.16llx (R_THE_DC)", text, R_THE_DC);
685 }
686 if (is_set(input_register, R_STARTING)) {
687 crm_trace("%s %.16llx (R_STARTING)", text, R_STARTING);
688 }
689 if (is_set(input_register, R_SHUTDOWN)) {
690 crm_trace("%s %.16llx (R_SHUTDOWN)", text, R_SHUTDOWN);
691 }
692 if (is_set(input_register, R_STAYDOWN)) {
693 crm_trace("%s %.16llx (R_STAYDOWN)", text, R_STAYDOWN);
694 }
695 if (is_set(input_register, R_JOIN_OK)) {
696 crm_trace("%s %.16llx (R_JOIN_OK)", text, R_JOIN_OK);
697 }
698 if (is_set(input_register, R_READ_CONFIG)) {
699 crm_trace("%s %.16llx (R_READ_CONFIG)", text, R_READ_CONFIG);
700 }
701 if (is_set(input_register, R_INVOKE_PE)) {
702 crm_trace("%s %.16llx (R_INVOKE_PE)", text, R_INVOKE_PE);
703 }
704 if (is_set(input_register, R_CIB_CONNECTED)) {
705 crm_trace("%s %.16llx (R_CIB_CONNECTED)", text, R_CIB_CONNECTED);
706 }
707 if (is_set(input_register, R_PE_CONNECTED)) {
708 crm_trace("%s %.16llx (R_PE_CONNECTED)", text, R_PE_CONNECTED);
709 }
710 if (is_set(input_register, R_TE_CONNECTED)) {
711 crm_trace("%s %.16llx (R_TE_CONNECTED)", text, R_TE_CONNECTED);
712 }
713 if (is_set(input_register, R_LRM_CONNECTED)) {
714 crm_trace("%s %.16llx (R_LRM_CONNECTED)", text, R_LRM_CONNECTED);
715 }
716 if (is_set(input_register, R_CIB_REQUIRED)) {
717 crm_trace("%s %.16llx (R_CIB_REQUIRED)", text, R_CIB_REQUIRED);
718 }
719 if (is_set(input_register, R_PE_REQUIRED)) {
720 crm_trace("%s %.16llx (R_PE_REQUIRED)", text, R_PE_REQUIRED);
721 }
722 if (is_set(input_register, R_TE_REQUIRED)) {
723 crm_trace("%s %.16llx (R_TE_REQUIRED)", text, R_TE_REQUIRED);
724 }
725 if (is_set(input_register, R_REQ_PEND)) {
726 crm_trace("%s %.16llx (R_REQ_PEND)", text, R_REQ_PEND);
727 }
728 if (is_set(input_register, R_PE_PEND)) {
729 crm_trace("%s %.16llx (R_PE_PEND)", text, R_PE_PEND);
730 }
731 if (is_set(input_register, R_TE_PEND)) {
732 crm_trace("%s %.16llx (R_TE_PEND)", text, R_TE_PEND);
733 }
734 if (is_set(input_register, R_RESP_PEND)) {
735 crm_trace("%s %.16llx (R_RESP_PEND)", text, R_RESP_PEND);
736 }
737 if (is_set(input_register, R_CIB_DONE)) {
738 crm_trace("%s %.16llx (R_CIB_DONE)", text, R_CIB_DONE);
739 }
740 if (is_set(input_register, R_HAVE_CIB)) {
741 crm_trace("%s %.16llx (R_HAVE_CIB)", text, R_HAVE_CIB);
742 }
743 if (is_set(input_register, R_CIB_ASKED)) {
744 crm_trace("%s %.16llx (R_CIB_ASKED)", text, R_CIB_ASKED);
745 }
746 if (is_set(input_register, R_MEMBERSHIP)) {
747 crm_trace("%s %.16llx (R_MEMBERSHIP)", text, R_MEMBERSHIP);
748 }
749 if (is_set(input_register, R_PEER_DATA)) {
750 crm_trace("%s %.16llx (R_PEER_DATA)", text, R_PEER_DATA);
751 }
752 if (is_set(input_register, R_IN_RECOVERY)) {
753 crm_trace("%s %.16llx (R_IN_RECOVERY)", text, R_IN_RECOVERY);
754 }
755 }
756
757 void
758 fsa_dump_actions(long long action, const char *text)
759 {
760 if (is_set(action, A_READCONFIG)) {
761 crm_trace("Action %.16llx (A_READCONFIG) %s", A_READCONFIG, text);
762 }
763 if (is_set(action, A_STARTUP)) {
764 crm_trace("Action %.16llx (A_STARTUP) %s", A_STARTUP, text);
765 }
766 if (is_set(action, A_STARTED)) {
767 crm_trace("Action %.16llx (A_STARTED) %s", A_STARTED, text);
768 }
769 if (is_set(action, A_HA_CONNECT)) {
770 crm_trace("Action %.16llx (A_CONNECT) %s", A_HA_CONNECT, text);
771 }
772 if (is_set(action, A_HA_DISCONNECT)) {
773 crm_trace("Action %.16llx (A_DISCONNECT) %s", A_HA_DISCONNECT, text);
774 }
775 if (is_set(action, A_LRM_CONNECT)) {
776 crm_trace("Action %.16llx (A_LRM_CONNECT) %s", A_LRM_CONNECT, text);
777 }
778 if (is_set(action, A_LRM_EVENT)) {
779 crm_trace("Action %.16llx (A_LRM_EVENT) %s", A_LRM_EVENT, text);
780 }
781 if (is_set(action, A_LRM_INVOKE)) {
782 crm_trace("Action %.16llx (A_LRM_INVOKE) %s", A_LRM_INVOKE, text);
783 }
784 if (is_set(action, A_LRM_DISCONNECT)) {
785 crm_trace("Action %.16llx (A_LRM_DISCONNECT) %s", A_LRM_DISCONNECT, text);
786 }
787 if (is_set(action, A_DC_TIMER_STOP)) {
788 crm_trace("Action %.16llx (A_DC_TIMER_STOP) %s", A_DC_TIMER_STOP, text);
789 }
790 if (is_set(action, A_DC_TIMER_START)) {
791 crm_trace("Action %.16llx (A_DC_TIMER_START) %s", A_DC_TIMER_START, text);
792 }
793 if (is_set(action, A_INTEGRATE_TIMER_START)) {
794 crm_trace("Action %.16llx (A_INTEGRATE_TIMER_START) %s", A_INTEGRATE_TIMER_START, text);
795 }
796 if (is_set(action, A_INTEGRATE_TIMER_STOP)) {
797 crm_trace("Action %.16llx (A_INTEGRATE_TIMER_STOP) %s", A_INTEGRATE_TIMER_STOP, text);
798 }
799 if (is_set(action, A_FINALIZE_TIMER_START)) {
800 crm_trace("Action %.16llx (A_FINALIZE_TIMER_START) %s", A_FINALIZE_TIMER_START, text);
801 }
802 if (is_set(action, A_FINALIZE_TIMER_STOP)) {
803 crm_trace("Action %.16llx (A_FINALIZE_TIMER_STOP) %s", A_FINALIZE_TIMER_STOP, text);
804 }
805 if (is_set(action, A_ELECTION_COUNT)) {
806 crm_trace("Action %.16llx (A_ELECTION_COUNT) %s", A_ELECTION_COUNT, text);
807 }
808 if (is_set(action, A_ELECTION_VOTE)) {
809 crm_trace("Action %.16llx (A_ELECTION_VOTE) %s", A_ELECTION_VOTE, text);
810 }
811 if (is_set(action, A_ELECTION_CHECK)) {
812 crm_trace("Action %.16llx (A_ELECTION_CHECK) %s", A_ELECTION_CHECK, text);
813 }
814 if (is_set(action, A_CL_JOIN_ANNOUNCE)) {
815 crm_trace("Action %.16llx (A_CL_JOIN_ANNOUNCE) %s", A_CL_JOIN_ANNOUNCE, text);
816 }
817 if (is_set(action, A_CL_JOIN_REQUEST)) {
818 crm_trace("Action %.16llx (A_CL_JOIN_REQUEST) %s", A_CL_JOIN_REQUEST, text);
819 }
820 if (is_set(action, A_CL_JOIN_RESULT)) {
821 crm_trace("Action %.16llx (A_CL_JOIN_RESULT) %s", A_CL_JOIN_RESULT, text);
822 }
823 if (is_set(action, A_DC_JOIN_OFFER_ALL)) {
824 crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ALL) %s", A_DC_JOIN_OFFER_ALL, text);
825 }
826 if (is_set(action, A_DC_JOIN_OFFER_ONE)) {
827 crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ONE) %s", A_DC_JOIN_OFFER_ONE, text);
828 }
829 if (is_set(action, A_DC_JOIN_PROCESS_REQ)) {
830 crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_REQ) %s", A_DC_JOIN_PROCESS_REQ, text);
831 }
832 if (is_set(action, A_DC_JOIN_PROCESS_ACK)) {
833 crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_ACK) %s", A_DC_JOIN_PROCESS_ACK, text);
834 }
835 if (is_set(action, A_DC_JOIN_FINALIZE)) {
836 crm_trace("Action %.16llx (A_DC_JOIN_FINALIZE) %s", A_DC_JOIN_FINALIZE, text);
837 }
838 if (is_set(action, A_MSG_PROCESS)) {
839 crm_trace("Action %.16llx (A_MSG_PROCESS) %s", A_MSG_PROCESS, text);
840 }
841 if (is_set(action, A_MSG_ROUTE)) {
842 crm_trace("Action %.16llx (A_MSG_ROUTE) %s", A_MSG_ROUTE, text);
843 }
844 if (is_set(action, A_RECOVER)) {
845 crm_trace("Action %.16llx (A_RECOVER) %s", A_RECOVER, text);
846 }
847 if (is_set(action, A_DC_RELEASE)) {
848 crm_trace("Action %.16llx (A_DC_RELEASE) %s", A_DC_RELEASE, text);
849 }
850 if (is_set(action, A_DC_RELEASED)) {
851 crm_trace("Action %.16llx (A_DC_RELEASED) %s", A_DC_RELEASED, text);
852 }
853 if (is_set(action, A_DC_TAKEOVER)) {
854 crm_trace("Action %.16llx (A_DC_TAKEOVER) %s", A_DC_TAKEOVER, text);
855 }
856 if (is_set(action, A_SHUTDOWN)) {
857 crm_trace("Action %.16llx (A_SHUTDOWN) %s", A_SHUTDOWN, text);
858 }
859 if (is_set(action, A_SHUTDOWN_REQ)) {
860 crm_trace("Action %.16llx (A_SHUTDOWN_REQ) %s", A_SHUTDOWN_REQ, text);
861 }
862 if (is_set(action, A_STOP)) {
863 crm_trace("Action %.16llx (A_STOP ) %s", A_STOP, text);
864 }
865 if (is_set(action, A_EXIT_0)) {
866 crm_trace("Action %.16llx (A_EXIT_0) %s", A_EXIT_0, text);
867 }
868 if (is_set(action, A_EXIT_1)) {
869 crm_trace("Action %.16llx (A_EXIT_1) %s", A_EXIT_1, text);
870 }
871 if (is_set(action, A_CCM_CONNECT)) {
872 crm_trace("Action %.16llx (A_CCM_CONNECT) %s", A_CCM_CONNECT, text);
873 }
874 if (is_set(action, A_CCM_DISCONNECT)) {
875 crm_trace("Action %.16llx (A_CCM_DISCONNECT) %s", A_CCM_DISCONNECT, text);
876 }
877 if (is_set(action, A_CIB_START)) {
878 crm_trace("Action %.16llx (A_CIB_START) %s", A_CIB_START, text);
879 }
880 if (is_set(action, A_CIB_STOP)) {
881 crm_trace("Action %.16llx (A_CIB_STOP) %s", A_CIB_STOP, text);
882 }
883 if (is_set(action, A_TE_INVOKE)) {
884 crm_trace("Action %.16llx (A_TE_INVOKE) %s", A_TE_INVOKE, text);
885 }
886 if (is_set(action, A_TE_START)) {
887 crm_trace("Action %.16llx (A_TE_START) %s", A_TE_START, text);
888 }
889 if (is_set(action, A_TE_STOP)) {
890 crm_trace("Action %.16llx (A_TE_STOP) %s", A_TE_STOP, text);
891 }
892 if (is_set(action, A_TE_CANCEL)) {
893 crm_trace("Action %.16llx (A_TE_CANCEL) %s", A_TE_CANCEL, text);
894 }
895 if (is_set(action, A_PE_INVOKE)) {
896 crm_trace("Action %.16llx (A_PE_INVOKE) %s", A_PE_INVOKE, text);
897 }
898 if (is_set(action, A_PE_START)) {
899 crm_trace("Action %.16llx (A_PE_START) %s", A_PE_START, text);
900 }
901 if (is_set(action, A_PE_STOP)) {
902 crm_trace("Action %.16llx (A_PE_STOP) %s", A_PE_STOP, text);
903 }
904 if (is_set(action, A_NODE_BLOCK)) {
905 crm_trace("Action %.16llx (A_NODE_BLOCK) %s", A_NODE_BLOCK, text);
906 }
907 if (is_set(action, A_UPDATE_NODESTATUS)) {
908 crm_trace("Action %.16llx (A_UPDATE_NODESTATUS) %s", A_UPDATE_NODESTATUS, text);
909 }
910 if (is_set(action, A_LOG)) {
911 crm_trace("Action %.16llx (A_LOG ) %s", A_LOG, text);
912 }
913 if (is_set(action, A_ERROR)) {
914 crm_trace("Action %.16llx (A_ERROR ) %s", A_ERROR, text);
915 }
916 if (is_set(action, A_WARN)) {
917 crm_trace("Action %.16llx (A_WARN ) %s", A_WARN, text);
918 }
919 }
920
921 gboolean
922 update_dc(xmlNode * msg)
923 {
924 char *last_dc = fsa_our_dc;
925 const char *dc_version = NULL;
926 const char *welcome_from = NULL;
927
928 if (msg != NULL) {
929 gboolean invalid = FALSE;
930
931 dc_version = crm_element_value(msg, F_CRM_VERSION);
932 welcome_from = crm_element_value(msg, F_CRM_HOST_FROM);
933
934 CRM_CHECK(dc_version != NULL, return FALSE);
935 CRM_CHECK(welcome_from != NULL, return FALSE);
936
937 if (AM_I_DC && safe_str_neq(welcome_from, fsa_our_uname)) {
938 invalid = TRUE;
939
940 } else if (fsa_our_dc && safe_str_neq(welcome_from, fsa_our_dc)) {
941 invalid = TRUE;
942 }
943
944 if (invalid) {
945 CRM_CHECK(fsa_our_dc != NULL, crm_err("We have no DC"));
946 if (AM_I_DC) {
947 crm_err("Not updating DC to %s (%s): we are also a DC", welcome_from, dc_version);
948 } else {
949 crm_warn("New DC %s is not %s", welcome_from, fsa_our_dc);
950 }
951
952 register_fsa_action(A_CL_JOIN_QUERY | A_DC_TIMER_START);
953 return FALSE;
954 }
955 }
956
957 free(fsa_our_dc_version);
958 fsa_our_dc_version = NULL;
959
960 fsa_our_dc = NULL;
961
962 if (welcome_from != NULL) {
963 fsa_our_dc = strdup(welcome_from);
964 }
965 if (dc_version != NULL) {
966 fsa_our_dc_version = strdup(dc_version);
967 }
968
969 if (safe_str_eq(fsa_our_dc, last_dc)) {
970
971
972 } else if (fsa_our_dc != NULL) {
973 crm_node_t *dc_node = crm_get_peer(0, fsa_our_dc);
974
975 crm_info("Set DC to %s (%s)", crm_str(fsa_our_dc), crm_str(fsa_our_dc_version));
976 crm_update_peer_expected(__FUNCTION__, dc_node, CRMD_JOINSTATE_MEMBER);
977
978 } else if (last_dc != NULL) {
979 crm_info("Unset DC. Was %s", crm_str(last_dc));
980 }
981
982 free(last_dc);
983 return TRUE;
984 }
985
986 #define STATUS_PATH_MAX 512
987 static void
988 erase_xpath_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
989 {
990 char *xpath = user_data;
991
992 do_crm_log_unlikely(rc == 0 ? LOG_DEBUG : LOG_NOTICE,
993 "Deletion of \"%s\": %s (rc=%d)", xpath, pcmk_strerror(rc), rc);
994 }
995
996 #define XPATH_STATUS_TAG "//node_state[@uname='%s']/%s"
997
998 void
999 erase_status_tag(const char *uname, const char *tag, int options)
1000 {
1001 if (fsa_cib_conn && uname) {
1002 int call_id;
1003 char *xpath = crm_strdup_printf(XPATH_STATUS_TAG, uname, tag);
1004
1005 crm_info("Deleting %s status entries for %s " CRM_XS " xpath=%s",
1006 tag, uname, xpath);
1007 call_id = fsa_cib_conn->cmds->delete(fsa_cib_conn, xpath, NULL,
1008 cib_quorum_override | cib_xpath | options);
1009 fsa_register_cib_callback(call_id, FALSE, xpath, erase_xpath_callback);
1010
1011 }
1012 }
1013
1014 void crmd_peer_down(crm_node_t *peer, bool full)
1015 {
1016 if(full && peer->state == NULL) {
1017 crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0);
1018 crm_update_peer_proc(__FUNCTION__, peer, crm_proc_none, NULL);
1019 }
1020 crm_update_peer_join(__FUNCTION__, peer, crm_join_none);
1021 crm_update_peer_expected(__FUNCTION__, peer, CRMD_JOINSTATE_DOWN);
1022 }
1023
1024 #define MIN_CIB_OP_TIMEOUT (30)
1025
1026 unsigned int
1027 cib_op_timeout()
1028 {
1029 static int env_timeout = -1;
1030 unsigned int calculated_timeout = 0;
1031
1032 if (env_timeout == -1) {
1033 const char *env = getenv("PCMK_cib_timeout");
1034
1035 if (env) {
1036 env_timeout = crm_parse_int(env, "0");
1037 }
1038 env_timeout = QB_MAX(env_timeout, MIN_CIB_OP_TIMEOUT);
1039 crm_trace("Minimum CIB op timeout: %us (environment: %s)",
1040 env_timeout, (env? env : "none"));
1041 }
1042
1043 calculated_timeout = 1 + crm_active_peers();
1044 if (crm_remote_peer_cache) {
1045 calculated_timeout += g_hash_table_size(crm_remote_peer_cache);
1046 }
1047 calculated_timeout *= 10;
1048
1049 calculated_timeout = QB_MAX(calculated_timeout, env_timeout);
1050 crm_trace("Calculated timeout: %us", calculated_timeout);
1051
1052 if (fsa_cib_conn) {
1053 fsa_cib_conn->call_timeout = calculated_timeout;
1054 }
1055 return calculated_timeout;
1056 }