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