This source file includes following definitions.
- global_cib_callback
- 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 extern pcmk__graph_functions_t te_graph_fns;
19
20 static void
21 global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output)
22 {
23 }
24
25 static pcmk__graph_t *
26 create_blank_graph(void)
27 {
28 pcmk__graph_t *a_graph = pcmk__unpack_graph(NULL, NULL);
29
30 a_graph->complete = true;
31 a_graph->abort_reason = "DC Takeover";
32 a_graph->completion_action = pcmk__graph_restart;
33 return a_graph;
34 }
35
36
37 void
38 do_te_control(long long action,
39 enum crmd_fsa_cause cause,
40 enum crmd_fsa_state cur_state,
41 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
42 {
43 gboolean init_ok = TRUE;
44
45 if (action & A_TE_STOP) {
46 if (transition_graph) {
47 pcmk__free_graph(transition_graph);
48 transition_graph = NULL;
49 }
50
51 if (fsa_cib_conn) {
52 fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY,
53 te_update_diff);
54 }
55
56 controld_clear_fsa_input_flags(R_TE_CONNECTED);
57 crm_info("Transitioner is now inactive");
58 }
59
60 if ((action & A_TE_START) == 0) {
61 return;
62
63 } else if (pcmk_is_set(fsa_input_register, R_TE_CONNECTED)) {
64 crm_debug("The transitioner is already active");
65 return;
66
67 } else if ((action & A_TE_START) && cur_state == S_STOPPING) {
68 crm_info("Ignoring request to start the transitioner while shutting down");
69 return;
70 }
71
72 if (te_uuid == NULL) {
73 te_uuid = crm_generate_uuid();
74 crm_info("Registering TE UUID: %s", te_uuid);
75 }
76
77 if (fsa_cib_conn == NULL) {
78 crm_err("Could not set CIB callbacks");
79 init_ok = FALSE;
80
81 } else {
82
83 if (fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn,
84 T_CIB_DIFF_NOTIFY, te_update_diff) != pcmk_ok) {
85
86 crm_err("Could not set CIB notification callback");
87 init_ok = FALSE;
88 }
89
90 if (fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn,
91 global_cib_callback) != pcmk_ok) {
92
93 crm_err("Could not set CIB global callback");
94 init_ok = FALSE;
95 }
96 }
97
98 if (init_ok) {
99 pcmk__set_graph_functions(&te_graph_fns);
100
101 if (transition_graph) {
102 pcmk__free_graph(transition_graph);
103 }
104
105
106 crm_debug("Transitioner is now active");
107 transition_graph = create_blank_graph();
108 controld_set_fsa_input_flags(R_TE_CONNECTED);
109 }
110 }
111
112
113 void
114 do_te_invoke(long long action,
115 enum crmd_fsa_cause cause,
116 enum crmd_fsa_state cur_state,
117 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
118 {
119
120 if (AM_I_DC == FALSE || (fsa_state != S_TRANSITION_ENGINE && (action & A_TE_INVOKE))) {
121 crm_notice("No need to invoke the TE (%s) in state %s",
122 fsa_action2string(action), fsa_state2string(fsa_state));
123 return;
124 }
125
126 if (action & A_TE_CANCEL) {
127 crm_debug("Cancelling the transition: %s",
128 transition_graph->complete ? "inactive" : "active");
129 abort_transition(INFINITY, pcmk__graph_restart, "Peer Cancelled", NULL);
130 if (!transition_graph->complete) {
131 crmd_fsa_stall(FALSE);
132 }
133
134 } else if (action & A_TE_HALT) {
135 abort_transition(INFINITY, pcmk__graph_wait, "Peer Halt", NULL);
136 if (!transition_graph->complete) {
137 crmd_fsa_stall(FALSE);
138 }
139
140 } else if (action & A_TE_INVOKE) {
141 const char *value = NULL;
142 xmlNode *graph_data = NULL;
143 ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
144 const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
145 const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
146 const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
147
148 if (graph_file == NULL && input->xml == NULL) {
149 crm_log_xml_err(input->msg, "Bad command");
150 register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
151 return;
152 }
153
154 if (!transition_graph->complete) {
155 crm_info("Another transition is already active");
156 abort_transition(INFINITY, pcmk__graph_restart, "Transition Active",
157 NULL);
158 return;
159 }
160
161 if ((fsa_pe_ref == NULL)
162 || !pcmk__str_eq(fsa_pe_ref, ref, pcmk__str_none)) {
163 crm_info("Transition is redundant: %s expected but %s received",
164 pcmk__s(fsa_pe_ref, "no reference"),
165 pcmk__s(ref, "no reference"));
166 abort_transition(INFINITY, pcmk__graph_restart,
167 "Transition Redundant", NULL);
168 }
169
170 graph_data = input->xml;
171
172 if (graph_data == NULL && graph_file != NULL) {
173 graph_data = filename2xml(graph_file);
174 }
175
176 if (is_timer_started(transition_timer)) {
177 crm_debug("The transitioner wait for a transition timer");
178 return;
179 }
180
181 CRM_CHECK(graph_data != NULL,
182 crm_err("Input raised by %s is invalid", msg_data->origin);
183 crm_log_xml_err(input->msg, "Bad command");
184 return);
185
186 pcmk__free_graph(transition_graph);
187 transition_graph = pcmk__unpack_graph(graph_data, graph_input);
188 CRM_CHECK(transition_graph != NULL,
189 transition_graph = create_blank_graph(); return);
190 crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
191 graph_input);
192
193 te_reset_job_counts();
194 value = crm_element_value(graph_data, "failed-stop-offset");
195 if (value) {
196 free(failed_stop_offset);
197 failed_stop_offset = strdup(value);
198 }
199
200 value = crm_element_value(graph_data, "failed-start-offset");
201 if (value) {
202 free(failed_start_offset);
203 failed_start_offset = strdup(value);
204 }
205
206 if ((crm_element_value_epoch(graph_data, "recheck-by", &recheck_by)
207 != pcmk_ok) || (recheck_by < 0)) {
208 recheck_by = 0;
209 }
210
211 trigger_graph();
212 pcmk__log_graph(LOG_TRACE, transition_graph);
213
214 if (graph_data != input->xml) {
215 free_xml(graph_data);
216 }
217 }
218 }