This source file includes following definitions.
- shutdown_lock_cleared
- te_update_diff_v1
- process_lrm_resource_diff
- process_resource_updates
- extract_node_uuid
- abort_unless_down
- process_op_deletion
- process_delete_diff
- process_node_state_diff
- process_status_diff
- process_cib_diff
- te_update_diff_element_v2
- te_update_diff_v2
- te_update_diff
- process_te_message
- cib_action_updated
- action_timer_callback
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/stat.h>
13
14 #include <crm/crm.h>
15 #include <crm/common/xml.h>
16 #include <crm/common/xml_internal.h>
17
18 #include <pacemaker-controld.h>
19
20 void te_update_confirm(const char *event, xmlNode * msg);
21
22 #define RSC_OP_PREFIX "//" PCMK__XE_DIFF_ADDED "//" PCMK_XE_CIB \
23 "//" PCMK__XE_LRM_RSC_OP "[@" PCMK_XA_ID "='"
24
25
26 static bool
27 shutdown_lock_cleared(xmlNode *lrm_resource)
28 {
29 time_t shutdown_lock = 0;
30
31 return (crm_element_value_epoch(lrm_resource, PCMK_OPT_SHUTDOWN_LOCK,
32 &shutdown_lock) == pcmk_ok)
33 && (shutdown_lock == 0);
34 }
35
36 static void
37 te_update_diff_v1(const char *event, xmlNode *diff)
38 {
39 int lpc, max;
40 xmlXPathObject *xpathObj = NULL;
41 GString *rsc_op_xpath = NULL;
42
43 CRM_CHECK(diff != NULL, return);
44
45 pcmk__output_set_log_level(controld_globals.logger_out, LOG_TRACE);
46 controld_globals.logger_out->message(controld_globals.logger_out,
47 "xml-patchset", diff);
48
49 if (cib__config_changed_v1(NULL, NULL, &diff)) {
50 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
51 "Non-status change", diff);
52 goto bail;
53 }
54
55
56 xpathObj =
57 xpath_search(diff,
58 "//" PCMK__XE_CIB_UPDATE_RESULT
59 "//" PCMK__XE_DIFF_ADDED
60 "//" PCMK_XE_TICKETS);
61 if (numXpathResults(xpathObj) > 0) {
62 xmlNode *aborted = getXpathResult(xpathObj, 0);
63
64 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
65 "Ticket attribute: update", aborted);
66 goto bail;
67
68 }
69 freeXpathObject(xpathObj);
70
71
72 xpathObj =
73 xpath_search(diff,
74 "//" PCMK__XE_CIB_UPDATE_RESULT
75 "//" PCMK__XE_DIFF_REMOVED
76 "//" PCMK_XE_TICKETS);
77 if (numXpathResults(xpathObj) > 0) {
78 xmlNode *aborted = getXpathResult(xpathObj, 0);
79
80 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
81 "Ticket attribute: removal", aborted);
82 goto bail;
83 }
84 freeXpathObject(xpathObj);
85
86
87 xpathObj =
88 xpath_search(diff,
89 "//" PCMK__XE_CIB_UPDATE_RESULT
90 "//" PCMK__XE_DIFF_REMOVED
91 "//" PCMK__XE_TRANSIENT_ATTRIBUTES);
92 if (numXpathResults(xpathObj) > 0) {
93 xmlNode *aborted = getXpathResult(xpathObj, 0);
94
95 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
96 "Transient attribute: removal", aborted);
97 goto bail;
98
99 }
100 freeXpathObject(xpathObj);
101
102
103 xpathObj = xpath_search(diff,
104 "//" PCMK__XE_CIB_UPDATE_RESULT
105 "//" PCMK__XE_DIFF_ADDED
106 "//" PCMK__XE_LRM_RESOURCE);
107 max = numXpathResults(xpathObj);
108
109
110
111
112
113
114
115
116
117
118
119 if ((controld_globals.transition_graph->pending == 0) && (max > 1)) {
120 crm_debug("Ignoring resource operation updates due to history refresh of %d resources",
121 max);
122 crm_log_xml_trace(diff, "lrm-refresh");
123 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
124 "History refresh", NULL);
125 goto bail;
126 }
127
128 if (max == 1) {
129 xmlNode *lrm_resource = getXpathResult(xpathObj, 0);
130
131 if (shutdown_lock_cleared(lrm_resource)) {
132
133 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
134 "Shutdown lock cleared", lrm_resource);
135
136 }
137 }
138 freeXpathObject(xpathObj);
139
140
141 xpathObj =
142 xpath_search(diff,
143 "//" PCMK__XE_CIB_UPDATE_RESULT
144 "//" PCMK__XE_DIFF_ADDED
145 "//" PCMK__XE_LRM_RSC_OP);
146 max = numXpathResults(xpathObj);
147 if (max > 0) {
148 int lpc = 0;
149
150 for (lpc = 0; lpc < max; lpc++) {
151 xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
152 const char *node = get_node_id(rsc_op);
153
154 process_graph_event(rsc_op, node);
155 }
156 }
157 freeXpathObject(xpathObj);
158
159
160 xpathObj = xpath_search(diff,
161 "//" PCMK__XE_DIFF_REMOVED
162 "//" PCMK__XE_LRM_RSC_OP);
163 max = numXpathResults(xpathObj);
164 for (lpc = 0; lpc < max; lpc++) {
165 const char *op_id = NULL;
166 xmlXPathObject *op_match = NULL;
167 xmlNode *match = getXpathResult(xpathObj, lpc);
168
169 CRM_LOG_ASSERT(match != NULL);
170 if(match == NULL) { continue; };
171
172 op_id = pcmk__xe_id(match);
173
174 if (rsc_op_xpath == NULL) {
175 rsc_op_xpath = g_string_new(RSC_OP_PREFIX);
176 } else {
177 g_string_truncate(rsc_op_xpath, sizeof(RSC_OP_PREFIX) - 1);
178 }
179 pcmk__g_strcat(rsc_op_xpath, op_id, "']", NULL);
180
181 op_match = xpath_search(diff, (const char *) rsc_op_xpath->str);
182 if (numXpathResults(op_match) == 0) {
183
184 const char *node = get_node_id(match);
185 pcmk__graph_action_t *cancelled = get_cancel_action(op_id, node);
186
187 if (cancelled == NULL) {
188 crm_debug("No match for deleted action %s (%s on %s)",
189 (const char *) rsc_op_xpath->str, op_id, node);
190 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
191 "Resource op removal", match);
192 freeXpathObject(op_match);
193 goto bail;
194
195 } else {
196 crm_debug("Deleted " PCMK__XE_LRM_RSC_OP " %s on %s was for "
197 "graph event %d",
198 op_id, node, cancelled->id);
199 }
200 }
201
202 freeXpathObject(op_match);
203 }
204
205 bail:
206 freeXpathObject(xpathObj);
207 if (rsc_op_xpath != NULL) {
208 g_string_free(rsc_op_xpath, TRUE);
209 }
210 }
211
212 static void
213 process_lrm_resource_diff(xmlNode *lrm_resource, const char *node)
214 {
215 for (xmlNode *rsc_op = pcmk__xe_first_child(lrm_resource, NULL, NULL, NULL);
216 rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) {
217 process_graph_event(rsc_op, node);
218 }
219 if (shutdown_lock_cleared(lrm_resource)) {
220
221 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
222 "Shutdown lock cleared", lrm_resource);
223 }
224 }
225
226 static void
227 process_resource_updates(const char *node, xmlNode *xml, xmlNode *change,
228 const char *op, const char *xpath)
229 {
230 xmlNode *rsc = NULL;
231
232 if (xml == NULL) {
233 return;
234 }
235
236 if (pcmk__xe_is(xml, PCMK__XE_LRM)) {
237 xml = pcmk__xe_first_child(xml, PCMK__XE_LRM_RESOURCES, NULL, NULL);
238 CRM_CHECK(xml != NULL, return);
239 }
240
241 CRM_CHECK(pcmk__xe_is(xml, PCMK__XE_LRM_RESOURCES), return);
242
243
244
245
246
247
248
249
250
251
252
253
254
255 if ((controld_globals.transition_graph->pending == 0)
256 && (xml->children != NULL) && (xml->children->next != NULL)) {
257
258 crm_log_xml_trace(change, "lrm-refresh");
259 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
260 "History refresh", NULL);
261 return;
262 }
263
264 for (rsc = pcmk__xe_first_child(xml, NULL, NULL, NULL); rsc != NULL;
265 rsc = pcmk__xe_next(rsc)) {
266 crm_trace("Processing %s", pcmk__xe_id(rsc));
267 process_lrm_resource_diff(rsc, node);
268 }
269 }
270
271 static char *extract_node_uuid(const char *xpath)
272 {
273 char *mutable_path = pcmk__str_copy(xpath);
274 char *node_uuid = NULL;
275 char *search = NULL;
276 char *match = NULL;
277
278 match = strstr(mutable_path, PCMK__XE_NODE_STATE "[@" PCMK_XA_ID "=\'");
279 if (match == NULL) {
280 free(mutable_path);
281 return NULL;
282 }
283 match += strlen(PCMK__XE_NODE_STATE "[@" PCMK_XA_ID "=\'");
284
285 search = strchr(match, '\'');
286 if (search == NULL) {
287 free(mutable_path);
288 return NULL;
289 }
290 search[0] = 0;
291
292 node_uuid = pcmk__str_copy(match);
293 free(mutable_path);
294 return node_uuid;
295 }
296
297 static void
298 abort_unless_down(const char *xpath, const char *op, xmlNode *change,
299 const char *reason)
300 {
301 char *node_uuid = NULL;
302 pcmk__graph_action_t *down = NULL;
303
304 if (!pcmk__str_eq(op, PCMK_VALUE_DELETE, pcmk__str_none)) {
305 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart, reason,
306 change);
307 return;
308 }
309
310 node_uuid = extract_node_uuid(xpath);
311 if(node_uuid == NULL) {
312 crm_err("Could not extract node ID from %s", xpath);
313 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart, reason,
314 change);
315 return;
316 }
317
318 down = match_down_event(node_uuid);
319 if (down == NULL) {
320 crm_trace("Not expecting %s to be down (%s)", node_uuid, xpath);
321 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart, reason,
322 change);
323 } else {
324 crm_trace("Expecting changes to %s (%s)", node_uuid, xpath);
325 }
326 free(node_uuid);
327 }
328
329 static void
330 process_op_deletion(const char *xpath, xmlNode *change)
331 {
332 char *mutable_key = pcmk__str_copy(xpath);
333 char *key;
334 char *node_uuid;
335
336
337 key = strrchr(mutable_key, '\'');
338 if (key != NULL) {
339 *key = '\0';
340 key = strrchr(mutable_key, '\'');
341 }
342 if (key == NULL) {
343 crm_warn("Ignoring malformed CIB update (resource deletion of %s)",
344 xpath);
345 free(mutable_key);
346 return;
347 }
348 ++key;
349
350 node_uuid = extract_node_uuid(xpath);
351 if (confirm_cancel_action(key, node_uuid) == FALSE) {
352 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
353 "Resource operation removal", change);
354 }
355 free(mutable_key);
356 free(node_uuid);
357 }
358
359 static void
360 process_delete_diff(const char *xpath, const char *op, xmlNode *change)
361 {
362 if (strstr(xpath, "/" PCMK__XE_LRM_RSC_OP "[")) {
363 process_op_deletion(xpath, change);
364
365 } else if (strstr(xpath, "/" PCMK__XE_LRM "[")) {
366 abort_unless_down(xpath, op, change, "Resource state removal");
367
368 } else if (strstr(xpath, "/" PCMK__XE_NODE_STATE "[")) {
369 abort_unless_down(xpath, op, change, "Node state removal");
370
371 } else {
372 crm_trace("Ignoring delete of %s", xpath);
373 }
374 }
375
376 static void
377 process_node_state_diff(xmlNode *state, xmlNode *change, const char *op,
378 const char *xpath)
379 {
380 xmlNode *lrm = pcmk__xe_first_child(state, PCMK__XE_LRM, NULL, NULL);
381
382 process_resource_updates(pcmk__xe_id(state), lrm, change, op, xpath);
383 }
384
385 static void
386 process_status_diff(xmlNode *status, xmlNode *change, const char *op,
387 const char *xpath)
388 {
389 for (xmlNode *state = pcmk__xe_first_child(status, NULL, NULL, NULL);
390 state != NULL; state = pcmk__xe_next(state)) {
391
392 process_node_state_diff(state, change, op, xpath);
393 }
394 }
395
396 static void
397 process_cib_diff(xmlNode *cib, xmlNode *change, const char *op,
398 const char *xpath)
399 {
400 xmlNode *status = pcmk__xe_first_child(cib, PCMK_XE_STATUS, NULL, NULL);
401 xmlNode *config = pcmk__xe_first_child(cib, PCMK_XE_CONFIGURATION, NULL,
402 NULL);
403
404 if (status) {
405 process_status_diff(status, change, op, xpath);
406 }
407 if (config) {
408 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
409 "Non-status-only change", change);
410 }
411 }
412
413 static int
414 te_update_diff_element_v2(xmlNode *change, void *userdata)
415 {
416 xmlNode *match = NULL;
417 const char *name = NULL;
418 const char *xpath = crm_element_value(change, PCMK_XA_PATH);
419
420
421 const char *op = crm_element_value(change, PCMK_XA_OPERATION);
422
423
424 if (op == NULL) {
425 return pcmk_rc_ok;
426
427 } else if (xpath == NULL) {
428 crm_trace("Ignoring %s change for version field", op);
429 return pcmk_rc_ok;
430
431 } else if ((strcmp(op, PCMK_VALUE_MOVE) == 0)
432 && (strstr(xpath,
433 "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION
434 "/" PCMK_XE_RESOURCES) == NULL)) {
435
436
437
438 crm_trace("Ignoring move change at %s", xpath);
439 return pcmk_rc_ok;
440 }
441
442
443 if (strcmp(op, PCMK_VALUE_CREATE) == 0) {
444 match = change->children;
445
446 } else if (strcmp(op, PCMK_VALUE_MODIFY) == 0) {
447 match = pcmk__xe_first_child(change, PCMK_XE_CHANGE_RESULT, NULL, NULL);
448 if(match) {
449 match = match->children;
450 }
451
452 } else if (!pcmk__str_any_of(op,
453 PCMK_VALUE_DELETE, PCMK_VALUE_MOVE,
454 NULL)) {
455 crm_warn("Ignoring malformed CIB update (%s operation on %s is unrecognized)",
456 op, xpath);
457 return pcmk_rc_ok;
458 }
459
460 if (match) {
461 if (match->type == XML_COMMENT_NODE) {
462 crm_trace("Ignoring %s operation for comment at %s", op, xpath);
463 return pcmk_rc_ok;
464 }
465 name = (const char *)match->name;
466 }
467
468 crm_trace("Handling %s operation for %s%s%s",
469 op, (xpath? xpath : "CIB"),
470 (name? " matched by " : ""), (name? name : ""));
471
472 if (strstr(xpath, "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION)) {
473 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
474 "Configuration change", change);
475 return pcmk_rc_cib_modified;
476
477 } else if (strstr(xpath, "/" PCMK_XE_TICKETS)
478 || pcmk__str_eq(name, PCMK_XE_TICKETS, pcmk__str_none)) {
479 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
480 "Ticket attribute change", change);
481 return pcmk_rc_cib_modified;
482
483 } else if (strstr(xpath, "/" PCMK__XE_TRANSIENT_ATTRIBUTES "[")
484 || pcmk__str_eq(name, PCMK__XE_TRANSIENT_ATTRIBUTES,
485 pcmk__str_none)) {
486 abort_unless_down(xpath, op, change, "Transient attribute change");
487 return pcmk_rc_cib_modified;
488
489 } else if (strcmp(op, PCMK_VALUE_DELETE) == 0) {
490 process_delete_diff(xpath, op, change);
491
492 } else if (name == NULL) {
493 crm_warn("Ignoring malformed CIB update (%s at %s has no result)",
494 op, xpath);
495
496 } else if (strcmp(name, PCMK_XE_CIB) == 0) {
497 process_cib_diff(match, change, op, xpath);
498
499 } else if (strcmp(name, PCMK_XE_STATUS) == 0) {
500 process_status_diff(match, change, op, xpath);
501
502 } else if (strcmp(name, PCMK__XE_NODE_STATE) == 0) {
503 process_node_state_diff(match, change, op, xpath);
504
505 } else if (strcmp(name, PCMK__XE_LRM) == 0) {
506 process_resource_updates(pcmk__xe_id(match), match, change, op,
507 xpath);
508
509 } else if (strcmp(name, PCMK__XE_LRM_RESOURCES) == 0) {
510 char *local_node = pcmk__xpath_node_id(xpath, PCMK__XE_LRM);
511
512 process_resource_updates(local_node, match, change, op, xpath);
513 free(local_node);
514
515 } else if (strcmp(name, PCMK__XE_LRM_RESOURCE) == 0) {
516 char *local_node = pcmk__xpath_node_id(xpath, PCMK__XE_LRM);
517
518 process_lrm_resource_diff(match, local_node);
519 free(local_node);
520
521 } else if (strcmp(name, PCMK__XE_LRM_RSC_OP) == 0) {
522 char *local_node = pcmk__xpath_node_id(xpath, PCMK__XE_LRM);
523
524 process_graph_event(match, local_node);
525 free(local_node);
526
527 } else {
528 crm_warn("Ignoring malformed CIB update (%s at %s has unrecognized result %s)",
529 op, xpath, name);
530 }
531
532 return pcmk_rc_ok;
533 }
534
535 static void
536 te_update_diff_v2(xmlNode *diff)
537 {
538 crm_log_xml_trace(diff, "Patch:Raw");
539 pcmk__xe_foreach_child(diff, NULL, te_update_diff_element_v2, NULL);
540 }
541
542 void
543 te_update_diff(const char *event, xmlNode * msg)
544 {
545 xmlNode *wrapper = NULL;
546 xmlNode *diff = NULL;
547 const char *op = NULL;
548 int rc = -EINVAL;
549 int format = 1;
550 int p_add[] = { 0, 0, 0 };
551 int p_del[] = { 0, 0, 0 };
552
553 CRM_CHECK(msg != NULL, return);
554 crm_element_value_int(msg, PCMK__XA_CIB_RC, &rc);
555
556 if (controld_globals.transition_graph == NULL) {
557 crm_trace("No graph");
558 return;
559
560 } else if (rc < pcmk_ok) {
561 crm_trace("Filter rc=%d (%s)", rc, pcmk_strerror(rc));
562 return;
563
564 } else if (controld_globals.transition_graph->complete
565 && (controld_globals.fsa_state != S_IDLE)
566 && (controld_globals.fsa_state != S_TRANSITION_ENGINE)
567 && (controld_globals.fsa_state != S_POLICY_ENGINE)) {
568 crm_trace("Filter state=%s (complete)",
569 fsa_state2string(controld_globals.fsa_state));
570 return;
571 }
572
573 op = crm_element_value(msg, PCMK__XA_CIB_OP);
574
575 wrapper = pcmk__xe_first_child(msg, PCMK__XE_CIB_UPDATE_RESULT, NULL, NULL);
576 diff = pcmk__xe_first_child(wrapper, NULL, NULL, NULL);
577
578 xml_patch_versions(diff, p_add, p_del);
579 crm_debug("Processing (%s) diff: %d.%d.%d -> %d.%d.%d (%s)", op,
580 p_del[0], p_del[1], p_del[2], p_add[0], p_add[1], p_add[2],
581 fsa_state2string(controld_globals.fsa_state));
582
583 crm_element_value_int(diff, PCMK_XA_FORMAT, &format);
584 switch (format) {
585 case 1:
586 te_update_diff_v1(event, diff);
587 break;
588 case 2:
589 te_update_diff_v2(diff);
590 break;
591 default:
592 crm_warn("Ignoring malformed CIB update (unknown patch format %d)",
593 format);
594 }
595 controld_remove_all_outside_events();
596 }
597
598 void
599 process_te_message(xmlNode * msg, xmlNode * xml_data)
600 {
601 const char *value = NULL;
602 xmlXPathObject *xpathObj = NULL;
603 int nmatches = 0;
604
605 CRM_CHECK(msg != NULL, return);
606
607
608 value = crm_element_value(msg, PCMK__XA_CRM_SYS_TO);
609 if (pcmk__str_empty(value)
610 || !pcmk__str_eq(value, CRM_SYSTEM_TENGINE, pcmk__str_none)) {
611 crm_info("Received invalid transition request: subsystem '%s' not '"
612 CRM_SYSTEM_TENGINE "'", pcmk__s(value, ""));
613 return;
614 }
615
616
617 value = crm_element_value(msg, PCMK__XA_CRM_TASK);
618 if (!pcmk__str_eq(value, CRM_OP_INVOKE_LRM, pcmk__str_none)) {
619 crm_info("Received invalid transition request: command '%s' not '"
620 CRM_OP_INVOKE_LRM "'", pcmk__s(value, ""));
621 return;
622 }
623
624
625 value = crm_element_value(msg, PCMK__XA_CRM_SYS_FROM);
626 if (!pcmk__str_eq(value, CRM_SYSTEM_LRMD, pcmk__str_none)) {
627 crm_info("Received invalid transition request: from '%s' not '"
628 CRM_SYSTEM_LRMD "'", pcmk__s(value, ""));
629 return;
630 }
631
632 crm_debug("Processing transition request with ref='%s' origin='%s'",
633 pcmk__s(crm_element_value(msg, PCMK_XA_REFERENCE), ""),
634 pcmk__s(crm_element_value(msg, PCMK__XA_SRC), ""));
635
636 xpathObj = xpath_search(xml_data, "//" PCMK__XE_LRM_RSC_OP);
637 nmatches = numXpathResults(xpathObj);
638 if (nmatches == 0) {
639 crm_err("Received transition request with no results (bug?)");
640 } else {
641 for (int lpc = 0; lpc < nmatches; lpc++) {
642 xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
643 const char *node = get_node_id(rsc_op);
644
645 process_graph_event(rsc_op, node);
646 }
647 }
648 freeXpathObject(xpathObj);
649 }
650
651 void
652 cib_action_updated(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
653 {
654 if (rc < pcmk_ok) {
655 crm_err("Update %d FAILED: %s", call_id, pcmk_strerror(rc));
656 }
657 }
658
659
660
661
662
663
664
665
666 gboolean
667 action_timer_callback(gpointer data)
668 {
669 pcmk__graph_action_t *action = (pcmk__graph_action_t *) data;
670 const char *task = NULL;
671 const char *on_node = NULL;
672 const char *via_node = NULL;
673
674 CRM_CHECK(data != NULL, return FALSE);
675
676 stop_te_timer(action);
677
678 task = crm_element_value(action->xml, PCMK_XA_OPERATION);
679 on_node = crm_element_value(action->xml, PCMK__META_ON_NODE);
680 via_node = crm_element_value(action->xml, PCMK__XA_ROUTER_NODE);
681
682 if (controld_globals.transition_graph->complete) {
683 crm_notice("Node %s did not send %s result (via %s) within %dms "
684 "(ignoring because transition not in progress)",
685 (on_node? on_node : ""), (task? task : "unknown action"),
686 (via_node? via_node : "controller"), action->timeout);
687 } else {
688
689
690 crm_err("Node %s did not send %s result (via %s) within %dms "
691 "(action timeout plus " PCMK_OPT_CLUSTER_DELAY ")",
692 (on_node? on_node : ""), (task? task : "unknown action"),
693 (via_node? via_node : "controller"),
694 (action->timeout
695 + controld_globals.transition_graph->network_delay));
696 pcmk__log_graph_action(LOG_ERR, action);
697
698 pcmk__set_graph_action_flags(action, pcmk__graph_action_failed);
699
700 te_action_confirmed(action, controld_globals.transition_graph);
701 abort_transition(PCMK_SCORE_INFINITY, pcmk__graph_restart,
702 "Action lost", NULL);
703
704
705 if ((action->type == pcmk__rsc_graph_action)
706 && controld_action_is_recordable(task)) {
707 controld_record_action_timeout(action);
708 }
709 }
710
711 return FALSE;
712 }