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 void
103 peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data)
104 {
105 uint32_t old = 0;
106 bool appeared = FALSE;
107 bool is_remote = pcmk_is_set(node->flags, crm_remote_node);
108
109
110
111
112
113 if (!is_remote) {
114 controld_set_fsa_input_flags(R_PEER_DATA);
115 }
116
117 if (node->uname == NULL) {
118 return;
119 }
120
121 switch (type) {
122 case crm_status_uname:
123
124 crm_info("%s node %s is now %s",
125 (is_remote? "Remote" : "Cluster"),
126 node->uname, state_text(node->state));
127 return;
128
129 case crm_status_nstate:
130
131
132
133 CRM_CHECK(!pcmk__str_eq(data, node->state, pcmk__str_casei),
134 return);
135
136 crm_info("%s node %s is now %s (was %s)",
137 (is_remote? "Remote" : "Cluster"),
138 node->uname, state_text(node->state), state_text(data));
139
140 if (pcmk__str_eq(CRM_NODE_MEMBER, node->state, pcmk__str_casei)) {
141 appeared = TRUE;
142 if (!is_remote) {
143 remove_stonith_cleanup(node->uname);
144 }
145 } else {
146 controld_remove_voter(node->uname);
147 }
148
149 crmd_alert_node_event(node);
150 break;
151
152 case crm_status_processes:
153 CRM_CHECK(data != NULL, return);
154 old = *(const uint32_t *)data;
155 appeared = pcmk_is_set(node->processes, crm_get_cluster_proc());
156
157 crm_info("Node %s is %s a peer " CRM_XS " DC=%s old=0x%07x new=0x%07x",
158 node->uname, (appeared? "now" : "no longer"),
159 (AM_I_DC? "true" : (fsa_our_dc? fsa_our_dc : "<none>")),
160 old, node->processes);
161
162 if (!pcmk_is_set((node->processes ^ old), crm_get_cluster_proc())) {
163
164
165
166 crm_trace("Process flag 0x%7x did not change from 0x%7x to 0x%7x",
167 crm_get_cluster_proc(), old, node->processes);
168 return;
169
170 }
171
172 if (!appeared) {
173 controld_remove_voter(node->uname);
174 } else if (!AM_I_DC && !is_remote) {
175
176
177
178
179 xmlNode *query = create_request(CRM_OP_HELLO, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL);
180
181 crm_debug("Broadcasting our uname because of node %u", node->id);
182 send_cluster_message(node, crm_msg_crmd, query, FALSE);
183
184 free_xml(query);
185 }
186
187 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
188 crm_trace("Ignoring peer status change because not connected to CIB");
189 return;
190
191 } else if (fsa_state == S_STOPPING) {
192 crm_trace("Ignoring peer status change because stopping");
193 return;
194 }
195
196 if (pcmk__str_eq(node->uname, fsa_our_uname, pcmk__str_casei) && !appeared) {
197
198 crm_notice("Our peer connection failed");
199 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ERROR, NULL);
200
201 } else if (pcmk__str_eq(node->uname, fsa_our_dc, pcmk__str_casei) && crm_is_peer_active(node) == FALSE) {
202
203 crm_notice("Our peer on the DC (%s) is dead", fsa_our_dc);
204 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ELECTION, NULL);
205
206
207
208
209
210
211
212
213
214 if (compare_version(fsa_our_dc_version, "3.0.9") > 0) {
215 controld_delete_node_state(node->uname,
216 controld_section_attrs,
217 cib_scope_local);
218 }
219
220 } else if (AM_I_DC || (fsa_our_dc == NULL)) {
221
222
223
224
225 if (appeared) {
226 te_trigger_stonith_history_sync(FALSE);
227 } else {
228 controld_delete_node_state(node->uname,
229 controld_section_attrs,
230 cib_scope_local);
231 }
232 }
233 break;
234 }
235
236 if (AM_I_DC) {
237 xmlNode *update = NULL;
238 int flags = node_update_peer;
239 int alive = node_alive(node);
240 crm_action_t *down = match_down_event(node->uuid);
241
242 crm_trace("Alive=%d, appeared=%d, down=%d",
243 alive, appeared, (down? down->id : -1));
244
245 if (appeared && (alive > 0) && !is_remote) {
246 register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL);
247 }
248
249 if (down) {
250 const char *task = crm_element_value(down->xml, XML_LRM_ATTR_TASK);
251
252 if (pcmk__str_eq(task, CRM_OP_FENCE, pcmk__str_casei)) {
253
254
255 crm_trace("Updating CIB %s fencer reported fencing of %s complete",
256 (down->confirmed? "after" : "before"), node->uname);
257
258 } else if (!appeared && pcmk__str_eq(task, CRM_OP_SHUTDOWN, pcmk__str_casei)) {
259
260
261 if (!is_remote) {
262 flags |= node_update_join | node_update_expected;
263 crmd_peer_down(node, FALSE);
264 check_join_state(fsa_state, __func__);
265 }
266 if (alive >= 0) {
267 crm_info("%s of peer %s is in progress " CRM_XS " action=%d",
268 task, node->uname, down->id);
269 } else {
270 crm_notice("%s of peer %s is complete " CRM_XS " action=%d",
271 task, node->uname, down->id);
272 update_graph(transition_graph, down);
273 trigger_graph();
274 }
275
276 } else {
277 crm_trace("Node %s is %s, was expected to %s (op %d)",
278 node->uname,
279 ((alive > 0)? "alive" :
280 ((alive < 0)? "dead" : "partially alive")),
281 task, down->id);
282 }
283
284 } else if (appeared == FALSE) {
285 crm_warn("Stonith/shutdown of node %s was not expected",
286 node->uname);
287 if (!is_remote) {
288 crm_update_peer_join(__func__, node, crm_join_none);
289 check_join_state(fsa_state, __func__);
290 }
291 abort_transition(INFINITY, tg_restart, "Node failure", NULL);
292 fail_incompletable_actions(transition_graph, node->uuid);
293
294 } else {
295 crm_trace("Node %s came up, was not expected to be down",
296 node->uname);
297 }
298
299 if (is_remote) {
300
301
302
303 flags |= node_update_cluster;
304
305
306 if (appeared) {
307 abort_transition(INFINITY, tg_restart,
308 "pacemaker_remote node integrated", NULL);
309 }
310 }
311
312
313 update = create_node_state_update(node, flags, NULL, __func__);
314 if (update == NULL) {
315 crm_debug("Node state update not yet possible for %s", node->uname);
316 } else {
317 fsa_cib_anon_update(XML_CIB_TAG_STATUS, update);
318 }
319 free_xml(update);
320 }
321
322 trigger_fsa();
323 }
324
325 void
326 crmd_cib_connection_destroy(gpointer user_data)
327 {
328 CRM_CHECK(user_data == fsa_cib_conn,;);
329
330 crm_trace("Invoked");
331 trigger_fsa();
332 fsa_cib_conn->state = cib_disconnected;
333
334 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
335 crm_info("Connection to the CIB manager terminated");
336 return;
337 }
338
339
340 crm_crit("Lost connection to the CIB manager, shutting down");
341 register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
342 controld_clear_fsa_input_flags(R_CIB_CONNECTED);
343
344 return;
345 }
346
347 gboolean
348 crm_fsa_trigger(gpointer user_data)
349 {
350 crm_trace("Invoked (queue len: %d)", g_list_length(fsa_message_queue));
351 s_crmd_fsa(C_FSA_INTERNAL);
352 crm_trace("Exited (queue len: %d)", g_list_length(fsa_message_queue));
353 return TRUE;
354 }