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 crm_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 crm_graph_t *
26 create_blank_graph(void)
27 {
28 crm_graph_t *a_graph = unpack_graph(NULL, NULL);
29
30 a_graph->complete = TRUE;
31 a_graph->abort_reason = "DC Takeover";
32 a_graph->completion_action = tg_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 destroy_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 set_graph_functions(&te_graph_fns);
100
101 if (transition_graph) {
102 destroy_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, tg_restart, "Peer Cancelled", NULL);
130 if (transition_graph->complete == FALSE) {
131 crmd_fsa_stall(FALSE);
132 }
133
134 } else if (action & A_TE_HALT) {
135 crm_debug("Halting the transition: %s", transition_graph->complete ? "inactive" : "active");
136 abort_transition(INFINITY, tg_stop, "Peer Halt", NULL);
137 if (transition_graph->complete == FALSE) {
138 crmd_fsa_stall(FALSE);
139 }
140
141 } else if (action & A_TE_INVOKE) {
142 const char *value = NULL;
143 xmlNode *graph_data = NULL;
144 ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
145 const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE);
146 const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH);
147 const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT);
148
149 if (graph_file == NULL && input->xml == NULL) {
150 crm_log_xml_err(input->msg, "Bad command");
151 register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
152 return;
153 }
154
155 if (transition_graph->complete == FALSE) {
156 crm_info("Another transition is already active");
157 abort_transition(INFINITY, tg_restart, "Transition Active", NULL);
158 return;
159 }
160
161 if (fsa_pe_ref == NULL || !pcmk__str_eq(fsa_pe_ref, ref, pcmk__str_casei)) {
162 crm_info("Transition is redundant: %s vs. %s", crm_str(fsa_pe_ref), crm_str(ref));
163 abort_transition(INFINITY, tg_restart, "Transition Redundant", NULL);
164 }
165
166 graph_data = input->xml;
167
168 if (graph_data == NULL && graph_file != NULL) {
169 graph_data = filename2xml(graph_file);
170 }
171
172 if (is_timer_started(transition_timer)) {
173 crm_debug("The transitioner wait for a transition timer");
174 return;
175 }
176
177 CRM_CHECK(graph_data != NULL,
178 crm_err("Input raised by %s is invalid", msg_data->origin);
179 crm_log_xml_err(input->msg, "Bad command");
180 return);
181
182 destroy_graph(transition_graph);
183 transition_graph = unpack_graph(graph_data, graph_input);
184 if (transition_graph == NULL) {
185 CRM_CHECK(transition_graph != NULL,);
186 transition_graph = create_blank_graph();
187 return;
188 }
189 crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
190 graph_input);
191
192 te_reset_job_counts();
193 value = crm_element_value(graph_data, "failed-stop-offset");
194 if (value) {
195 free(failed_stop_offset);
196 failed_stop_offset = strdup(value);
197 }
198
199 value = crm_element_value(graph_data, "failed-start-offset");
200 if (value) {
201 free(failed_start_offset);
202 failed_start_offset = strdup(value);
203 }
204
205 if ((crm_element_value_epoch(graph_data, "recheck-by", &recheck_by)
206 != pcmk_ok) || (recheck_by < 0)) {
207 recheck_by = 0;
208 }
209
210 trigger_graph();
211 print_graph(LOG_TRACE, transition_graph);
212
213 if (graph_data != input->xml) {
214 free_xml(graph_data);
215 }
216 }
217 }