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 = pcmk__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 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, 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 abort_transition(INFINITY, tg_stop, "Peer Halt", NULL);
136 if (transition_graph->complete == FALSE) {
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 == FALSE) {
155 crm_info("Another transition is already active");
156 abort_transition(INFINITY, tg_restart, "Transition Active", NULL);
157 return;
158 }
159
160 if (fsa_pe_ref == NULL || !pcmk__str_eq(fsa_pe_ref, ref, pcmk__str_casei)) {
161 crm_info("Transition is redundant: %s vs. %s", crm_str(fsa_pe_ref), crm_str(ref));
162 abort_transition(INFINITY, tg_restart, "Transition Redundant", NULL);
163 }
164
165 graph_data = input->xml;
166
167 if (graph_data == NULL && graph_file != NULL) {
168 graph_data = filename2xml(graph_file);
169 }
170
171 if (is_timer_started(transition_timer)) {
172 crm_debug("The transitioner wait for a transition timer");
173 return;
174 }
175
176 CRM_CHECK(graph_data != NULL,
177 crm_err("Input raised by %s is invalid", msg_data->origin);
178 crm_log_xml_err(input->msg, "Bad command");
179 return);
180
181 pcmk__free_graph(transition_graph);
182 transition_graph = pcmk__unpack_graph(graph_data, graph_input);
183 if (transition_graph == NULL) {
184 CRM_CHECK(transition_graph != NULL,);
185 transition_graph = create_blank_graph();
186 return;
187 }
188 crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref,
189 graph_input);
190
191 te_reset_job_counts();
192 value = crm_element_value(graph_data, "failed-stop-offset");
193 if (value) {
194 free(failed_stop_offset);
195 failed_stop_offset = strdup(value);
196 }
197
198 value = crm_element_value(graph_data, "failed-start-offset");
199 if (value) {
200 free(failed_start_offset);
201 failed_start_offset = strdup(value);
202 }
203
204 if ((crm_element_value_epoch(graph_data, "recheck-by", &recheck_by)
205 != pcmk_ok) || (recheck_by < 0)) {
206 recheck_by = 0;
207 }
208
209 trigger_graph();
210 pcmk__log_graph(LOG_TRACE, transition_graph);
211
212 if (graph_data != input->xml) {
213 free_xml(graph_data);
214 }
215 }
216 }