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 }
175
176 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
177 crm_trace("Ignoring peer status change because not connected to CIB");
178 return;
179
180 } else if (fsa_state == S_STOPPING) {
181 crm_trace("Ignoring peer status change because stopping");
182 return;
183 }
184
185 if (pcmk__str_eq(node->uname, fsa_our_uname, pcmk__str_casei) && !appeared) {
186
187 crm_notice("Our peer connection failed");
188 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ERROR, NULL);
189
190 } else if (pcmk__str_eq(node->uname, fsa_our_dc, pcmk__str_casei) && crm_is_peer_active(node) == FALSE) {
191
192 crm_notice("Our peer on the DC (%s) is dead", fsa_our_dc);
193 register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ELECTION, NULL);
194
195
196
197
198
199
200
201
202
203 if (compare_version(fsa_our_dc_version, "3.0.9") > 0) {
204 controld_delete_node_state(node->uname,
205 controld_section_attrs,
206 cib_scope_local);
207 }
208
209 } else if (AM_I_DC || (fsa_our_dc == NULL)) {
210
211
212
213
214 if (appeared) {
215 te_trigger_stonith_history_sync(FALSE);
216 } else {
217 controld_delete_node_state(node->uname,
218 controld_section_attrs,
219 cib_scope_local);
220 }
221 }
222 break;
223 }
224
225 if (AM_I_DC) {
226 xmlNode *update = NULL;
227 int flags = node_update_peer;
228 int alive = node_alive(node);
229 crm_action_t *down = match_down_event(node->uuid);
230
231 crm_trace("Alive=%d, appeared=%d, down=%d",
232 alive, appeared, (down? down->id : -1));
233
234 if (appeared && (alive > 0) && !is_remote) {
235 register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL);
236 }
237
238 if (down) {
239 const char *task = crm_element_value(down->xml, XML_LRM_ATTR_TASK);
240
241 if (pcmk__str_eq(task, CRM_OP_FENCE, pcmk__str_casei)) {
242
243
244 crm_trace("Updating CIB %s fencer reported fencing of %s complete",
245 (down->confirmed? "after" : "before"), node->uname);
246
247 } else if (!appeared && pcmk__str_eq(task, CRM_OP_SHUTDOWN, pcmk__str_casei)) {
248
249
250 if (!is_remote) {
251 flags |= node_update_join | node_update_expected;
252 crmd_peer_down(node, FALSE);
253 check_join_state(fsa_state, __func__);
254 }
255 if (alive >= 0) {
256 crm_info("%s of peer %s is in progress " CRM_XS " action=%d",
257 task, node->uname, down->id);
258 } else {
259 crm_notice("%s of peer %s is complete " CRM_XS " action=%d",
260 task, node->uname, down->id);
261 update_graph(transition_graph, down);
262 trigger_graph();
263 }
264
265 } else {
266 crm_trace("Node %s is %s, was expected to %s (op %d)",
267 node->uname,
268 ((alive > 0)? "alive" :
269 ((alive < 0)? "dead" : "partially alive")),
270 task, down->id);
271 }
272
273 } else if (appeared == FALSE) {
274 crm_warn("Stonith/shutdown of node %s was not expected",
275 node->uname);
276 if (!is_remote) {
277 crm_update_peer_join(__func__, node, crm_join_none);
278 check_join_state(fsa_state, __func__);
279 }
280 abort_transition(INFINITY, tg_restart, "Node failure", NULL);
281 fail_incompletable_actions(transition_graph, node->uuid);
282
283 } else {
284 crm_trace("Node %s came up, was not expected to be down",
285 node->uname);
286 }
287
288 if (is_remote) {
289
290
291
292 flags |= node_update_cluster;
293
294
295 if (appeared) {
296 abort_transition(INFINITY, tg_restart,
297 "pacemaker_remote node integrated", NULL);
298 }
299 }
300
301
302 update = create_node_state_update(node, flags, NULL, __func__);
303 if (update == NULL) {
304 crm_debug("Node state update not yet possible for %s", node->uname);
305 } else {
306 fsa_cib_anon_update(XML_CIB_TAG_STATUS, update);
307 }
308 free_xml(update);
309 }
310
311 trigger_fsa();
312 }
313
314 void
315 crmd_cib_connection_destroy(gpointer user_data)
316 {
317 CRM_CHECK(user_data == fsa_cib_conn,;);
318
319 crm_trace("Invoked");
320 trigger_fsa();
321 fsa_cib_conn->state = cib_disconnected;
322
323 if (!pcmk_is_set(fsa_input_register, R_CIB_CONNECTED)) {
324 crm_info("Connection to the CIB manager terminated");
325 return;
326 }
327
328
329 crm_crit("Lost connection to the CIB manager, shutting down");
330 register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
331 controld_clear_fsa_input_flags(R_CIB_CONNECTED);
332
333 return;
334 }
335
336 gboolean
337 crm_fsa_trigger(gpointer user_data)
338 {
339 crm_trace("Invoked (queue len: %d)", g_list_length(fsa_message_queue));
340 s_crmd_fsa(C_FSA_INTERNAL);
341 crm_trace("Exited (queue len: %d)", g_list_length(fsa_message_queue));
342 return TRUE;
343 }