This source file includes following definitions.
- crmd_ha_msg_filter
- node_alive
- peer_update_callback
- crmd_cib_connection_destroy
- crm_fsa_trigger
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13 #include <string.h>
14
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <crm/common/xml.h>
18 #include <crm/cluster.h>
19 #include <crm/cib.h>
20
21 #include <pacemaker-controld.h>
22
23
24 extern gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source);
25
26 void
27 crmd_ha_msg_filter(xmlNode * msg)
28 {
29 if (AM_I_DC) {
30 const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM);
31
32 if (pcmk__str_eq(sys_from, CRM_SYSTEM_DC, pcmk__str_casei)) {
33 const char *from = crm_element_value(msg, F_ORIG);
34
35 if (!pcmk__str_eq(from, fsa_our_uname, pcmk__str_casei)) {
36 int level = LOG_INFO;
37 const char *op = crm_element_value(msg, F_CRM_TASK);
38
39
40 if (fsa_state != S_ELECTION) {
41 ha_msg_input_t new_input;
42
43 level = LOG_WARNING;
44 new_input.msg = msg;
45 register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, &new_input,
46 __func__);
47 }
48
49 do_crm_log(level, "Another DC detected: %s (op=%s)", from, op);
50 goto done;
51 }
52 }
53
54 } else {
55 const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
56
57 if (pcmk__str_eq(sys_to, CRM_SYSTEM_DC, pcmk__str_casei)) {
58 return;
59 }
60 }
61
62
63 route_message(C_HA_MESSAGE, msg);
64
65 done:
66 trigger_fsa();
67 }
68
69
70
71
72
73
74
75
76
77
78
79 static int
80 node_alive(const crm_node_t *node)
81 {
82 if (pcmk_is_set(node->flags, crm_remote_node)) {
83
84 return pcmk__str_eq(node->state, CRM_NODE_MEMBER, pcmk__str_casei) ? 1: -1;
85
86 } else if (crm_is_peer_active(node)) {
87
88 return 1;
89
90 } else if (!pcmk_is_set(node->processes, crm_get_cluster_proc())
91 && !pcmk__str_eq(node->state, CRM_NODE_MEMBER, pcmk__str_casei)) {
92
93 return -1;
94 }
95
96
97 return 0;
98 }
99
100 #define state_text(state) ((state)? (const char *)(state) : "in unknown state")
101
102 bool controld_dc_left = false;
103
104 void
105 peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data)
106 {
107 uint32_t old = 0;
108 bool appeared = FALSE;
109 bool is_remote = pcmk_is_set(node->flags, crm_remote_node);
110
111
112
113
114
115 if (!is_remote) {
116 controld_set_fsa_input_flags(R_PEER_DATA);
117 }
118
119 if (type == crm_status_processes
120 && pcmk_is_set(node->processes, crm_get_cluster_proc())
121 && !AM_I_DC
122 && !is_remote) {
123
124
125
126
127 xmlNode *query = create_request(CRM_OP_HELLO, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);
128
129 crm_debug("Sending hello to node %u so that it learns our node name", node->id);
130 send_cluster_message(node, crm_msg_crmd, query, FALSE);
131
132 free_xml(query);
133 }
134
135 if (node->uname == NULL) {
136 return;
137 }
138
139 switch (type) {
140 case crm_status_uname:
141
142 crm_info("%s node %s is now %s",
143 (is_remote? "Remote" : "Cluster"),
144 node->uname, state_text(node->state));
145 return;
146
147 case crm_status_nstate:
148
149
150
151 CRM_CHECK(!pcmk__str_eq(data, node->state, pcmk__str_casei),
152 return);
153
154 crm_info("%s node %s is now %s (was %s)",
155 (is_remote? "Remote" : "Cluster"),
156 node->uname, state_text(node->state), state_text(data));
157
158 if (pcmk__str_eq(CRM_NODE_MEMBER, node->state, pcmk__str_casei)) {
159 appeared = TRUE;
160 if (!is_remote) {
161 remove_stonith_cleanup(node->uname);
162 }
163 } else {
164 controld_remove_voter(node->uname);
165 }
166
167 crmd_alert_node_event(node);
168 break;
169
170 case crm_status_processes:
171 CRM_CHECK(data != NULL, return);
172 old = *(const uint32_t *)data;
173 appeared = pcmk_is_set(node->processes, crm_get_cluster_proc());
174
175 crm_info("Node %s is %s a peer " CRM_XS " DC=%s old=%#07x new=%#07x",
176 node->uname, (appeared? "now" : "no longer"),
177 (AM_I_DC? "true" : (fsa_our_dc? fsa_our_dc : "<none>")),
178 old, node->processes);
179
180 if (!pcmk_is_set((node->processes ^ old), crm_get_cluster_proc())) {
181
182
183
184 crm_trace("Process flag %#7x did not change from %#7x to %#7x",
185 crm_get_cluster_proc(), old, node->processes);
186 return;
187
188 }
189
190 if (!appeared) {
191 controld_remove_voter(node->uname);
192 }
193
194 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
195 crm_trace("Ignoring peer status change because not connected to CIB");
196 return;
197
198 } else if (fsa_state == S_STOPPING) {
199 crm_trace("Ignoring peer status change because stopping");
200 return;
201 }
202
203 if (pcmk__str_eq(node->uname, fsa_our_uname, pcmk__str_casei) && !appeared) {
204
205 crm_notice("Our peer connection failed");
206 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ERROR, NULL);
207
208 } else if (pcmk__str_eq(node->uname, fsa_our_dc, pcmk__str_casei) && crm_is_peer_active(node) == FALSE) {
209
210 crm_notice("Our peer on the DC (%s) is dead", fsa_our_dc);
211 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ELECTION, NULL);
212
213
214
215
216
217
218
219
220
221 if (compare_version(fsa_our_dc_version, "3.0.9") > 0) {
222 controld_delete_node_state(node->uname,
223 controld_section_attrs,
224 cib_scope_local);
225 }
226
227 } else if (AM_I_DC || controld_dc_left || (fsa_our_dc == NULL)) {
228
229
230
231
232 if (appeared) {
233 te_trigger_stonith_history_sync(FALSE);
234 } else {
235 controld_delete_node_state(node->uname,
236 controld_section_attrs,
237 cib_scope_local);
238 }
239 }
240 break;
241 }
242
243 if (AM_I_DC) {
244 xmlNode *update = NULL;
245 int flags = node_update_peer;
246 int alive = node_alive(node);
247 pcmk__graph_action_t *down = match_down_event(node->uuid);
248
249 crm_trace("Alive=%d, appeared=%d, down=%d",
250 alive, appeared, (down? down->id : -1));
251
252 if (appeared && (alive > 0) && !is_remote) {
253 register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL);
254 }
255
256 if (down) {
257 const char *task = crm_element_value(down->xml, XML_LRM_ATTR_TASK);
258
259 if (pcmk__str_eq(task, CRM_OP_FENCE, pcmk__str_casei)) {
260
261
262 crm_trace("Updating CIB %s fencer reported fencing of %s complete",
263 (pcmk_is_set(down->flags, pcmk__graph_action_confirmed)? "after" : "before"), node->uname);
264
265 } else if (!appeared && pcmk__str_eq(task, CRM_OP_SHUTDOWN, pcmk__str_casei)) {
266
267
268 if (!is_remote) {
269 flags |= node_update_join | node_update_expected;
270 crmd_peer_down(node, FALSE);
271 check_join_state(fsa_state, __func__);
272 }
273 if (alive >= 0) {
274 crm_info("%s of peer %s is in progress " CRM_XS " action=%d",
275 task, node->uname, down->id);
276 } else {
277 crm_notice("%s of peer %s is complete " CRM_XS " action=%d",
278 task, node->uname, down->id);
279 pcmk__update_graph(transition_graph, down);
280 trigger_graph();
281 }
282
283 } else {
284 crm_trace("Node %s is %s, was expected to %s (op %d)",
285 node->uname,
286 ((alive > 0)? "alive" :
287 ((alive < 0)? "dead" : "partially alive")),
288 task, down->id);
289 }
290
291 } else if (appeared == FALSE) {
292 if (transition_graph == NULL || transition_graph->id == -1) {
293 crm_info("Stonith/shutdown of node %s is unknown to the "
294 "current DC", node->uname);
295 } else {
296 crm_warn("Stonith/shutdown of node %s was not expected",
297 node->uname);
298 }
299 if (!is_remote) {
300 crm_update_peer_join(__func__, node, crm_join_none);
301 check_join_state(fsa_state, __func__);
302 }
303 abort_transition(INFINITY, pcmk__graph_restart, "Node failure",
304 NULL);
305 fail_incompletable_actions(transition_graph, node->uuid);
306
307 } else {
308 crm_trace("Node %s came up, was not expected to be down",
309 node->uname);
310 }
311
312 if (is_remote) {
313
314
315
316 flags |= node_update_cluster;
317
318
319 if (appeared) {
320 abort_transition(INFINITY, pcmk__graph_restart,
321 "Pacemaker Remote node integrated", NULL);
322 }
323 }
324
325
326 update = create_node_state_update(node, flags, NULL, __func__);
327 if (update == NULL) {
328 crm_debug("Node state update not yet possible for %s", node->uname);
329 } else {
330 fsa_cib_anon_update(XML_CIB_TAG_STATUS, update);
331 }
332 free_xml(update);
333 }
334
335 trigger_fsa();
336 }
337
338 void
339 crmd_cib_connection_destroy(gpointer user_data)
340 {
341 CRM_LOG_ASSERT(user_data == fsa_cib_conn);
342
343 crm_trace("Invoked");
344 trigger_fsa();
345 fsa_cib_conn->state = cib_disconnected;
346
347 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
348 crm_info("Connection to the CIB manager terminated");
349 return;
350 }
351
352
353 crm_crit("Lost connection to the CIB manager, shutting down");
354 register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
355 controld_clear_fsa_input_flags(R_CIB_CONNECTED);
356
357 return;
358 }
359
360 gboolean
361 crm_fsa_trigger(gpointer user_data)
362 {
363 crm_trace("Invoked (queue len: %d)", g_list_length(fsa_message_queue));
364 s_crmd_fsa(C_FSA_INTERNAL);
365 crm_trace("Exited (queue len: %d)", g_list_length(fsa_message_queue));
366 return TRUE;
367 }