This source file includes following definitions.
- create_blank_graph
- do_te_control
- do_te_invoke
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <crm/crm.h>
13 #include <crm/msg_xml.h>
14 #include <crm/common/xml.h>
15
16 #include <pacemaker-controld.h>
17
18 static pcmk__graph_t *
19 create_blank_graph(void)
20 {
21 pcmk__graph_t *a_graph = pcmk__unpack_graph(NULL, NULL);
22
23 a_graph->complete = true;
24 a_graph->abort_reason = "DC Takeover";
25 a_graph->completion_action = pcmk__graph_restart;
26 return a_graph;
27 }
28
29
30 void
31 do_te_control(long long action,
32 enum crmd_fsa_cause cause,
33 enum crmd_fsa_state cur_state,
34 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
35 {
36 cib_t *cib_conn = controld_globals.cib_conn;
37 gboolean init_ok = TRUE;
38
39 if (pcmk_is_set(action, A_TE_STOP)) {
40 pcmk__free_graph(controld_globals.transition_graph);
41 controld_globals.transition_graph = NULL;
42
43 if (cib_conn != NULL) {
44 cib_conn->cmds->del_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY,
45 te_update_diff);
46 }
47
48 controld_clear_fsa_input_flags(R_TE_CONNECTED);
49 crm_info("Transitioner is now inactive");
50 }
51
52 if ((action & A_TE_START) == 0) {
53 return;
54
55 } else if (pcmk_is_set(controld_globals.fsa_input_register,
56 R_TE_CONNECTED)) {
57 crm_debug("The transitioner is already active");
58 return;
59
60 } else if ((action & A_TE_START) && cur_state == S_STOPPING) {
61 crm_info("Ignoring request to start the transitioner while shutting down");
62 return;
63 }
64
65 if (controld_globals.te_uuid == NULL) {
66 controld_globals.te_uuid = crm_generate_uuid();
67 crm_info("Registering TE UUID: %s", controld_globals.te_uuid);
68 }
69
70 if (cib_conn == NULL) {
71 crm_err("Could not set CIB callbacks");
72 init_ok = FALSE;
73
74 } else {
75 if (cib_conn->cmds->add_notify_callback(cib_conn, T_CIB_DIFF_NOTIFY,
76 te_update_diff) != pcmk_ok) {
77 crm_err("Could not set CIB notification callback");
78 init_ok = FALSE;
79 }
80 }
81
82 if (init_ok) {
83 controld_register_graph_functions();
84 pcmk__free_graph(controld_globals.transition_graph);
85
86
87 crm_debug("Transitioner is now active");
88 controld_globals.transition_graph = create_blank_graph();
89 controld_set_fsa_input_flags(R_TE_CONNECTED);
90 }
91 }
92
93
94 void
95 do_te_invoke(long long action,
96 enum crmd_fsa_cause cause,
97 enum crmd_fsa_state cur_state,
98 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
99 {
100
101 if (!AM_I_DC
102 || ((controld_globals.fsa_state != S_TRANSITION_ENGINE)
103 && pcmk_is_set(action, A_TE_INVOKE))) {
104 crm_notice("No need to invoke the TE (%s) in state %s",
105 fsa_action2string(action),
106 fsa_state2string(controld_globals.fsa_state));
107 return;
108 }
109
110 if (action & A_TE_CANCEL) {
111 crm_debug("Cancelling the transition: %sactive",
112 controld_globals.transition_graph->complete? "in" : "");
113 abort_transition(INFINITY, pcmk__graph_restart, "Peer Cancelled", NULL);
114 if (!controld_globals.transition_graph->complete) {
115 crmd_fsa_stall(FALSE);
116 }
117
118 } else if (action & A_TE_HALT) {
119 abort_transition(INFINITY, pcmk__graph_wait, "Peer Halt", NULL);
120 if (!controld_globals.transition_graph->complete) {
121 crmd_fsa_stall(FALSE);
122 }
123
124 } else if (action & A_TE_INVOKE) {
125 ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
126 xmlNode *graph_data = input->xml;
127 const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
128 const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
129 const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
130
131 if (graph_file == NULL && graph_data == NULL) {
132 crm_log_xml_err(input->msg, "Bad command");
133 register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
134 return;
135 }
136
137 if (!controld_globals.transition_graph->complete) {
138 crm_info("Another transition is already active");
139 abort_transition(INFINITY, pcmk__graph_restart, "Transition Active",
140 NULL);
141 return;
142 }
143
144 if ((controld_globals.fsa_pe_ref == NULL)
145 || !pcmk__str_eq(controld_globals.fsa_pe_ref, ref,
146 pcmk__str_none)) {
147 crm_info("Transition is redundant: %s expected but %s received",
148 pcmk__s(controld_globals.fsa_pe_ref, "no reference"),
149 pcmk__s(ref, "no reference"));
150 abort_transition(INFINITY, pcmk__graph_restart,
151 "Transition Redundant", NULL);
152 }
153
154 if (graph_data == NULL && graph_file != NULL) {
155 graph_data = filename2xml(graph_file);
156 }
157
158 if (controld_is_started_transition_timer()) {
159 crm_debug("The transitioner wait for a transition timer");
160 return;
161 }
162
163 CRM_CHECK(graph_data != NULL,
164 crm_err("Input raised by %s is invalid", msg_data->origin);
165 crm_log_xml_err(input->msg, "Bad command");
166 return);
167
168 pcmk__free_graph(controld_globals.transition_graph);
169 controld_globals.transition_graph = pcmk__unpack_graph(graph_data,
170 graph_input);
171 CRM_CHECK(controld_globals.transition_graph != NULL,
172 controld_globals.transition_graph = create_blank_graph();
173 return);
174 crm_info("Processing graph %d (ref=%s) derived from %s",
175 controld_globals.transition_graph->id, ref, graph_input);
176
177 te_reset_job_counts();
178
179 trigger_graph();
180 pcmk__log_graph(LOG_TRACE, controld_globals.transition_graph);
181
182 if (graph_data != input->xml) {
183 free_xml(graph_data);
184 }
185 }
186 }