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