This source file includes following definitions.
- lrm_connection_destroy
- make_stop_id
- copy_instance_keys
- copy_meta_keys
- history_remove_recurring_op
- history_free_recurring_ops
- history_free
- update_history_cache
- send_task_ok_ack
- op_node_name
- lrm_op_callback
- try_local_executor_connect
- do_lrm_control
- lrm_state_verify_stopped
- build_parameter_list
- append_restart_list
- append_secure_list
- build_operation_update
- is_rsc_active
- build_active_RAs
- do_lrm_query_internal
- controld_query_executor_state
- controld_rc2event
- controld_trigger_delete_refresh
- notify_deleted
- lrm_remove_deleted_rsc
- lrm_remove_deleted_op
- delete_rsc_entry
- erase_lrm_history_by_op
- erase_lrm_history_by_id
- last_failed_matches_op
- lrm_clear_last_failure
- cancel_op
- cancel_action_by_key
- cancel_op_key
- get_lrm_resource
- delete_resource
- get_fake_call_id
- fake_op_status
- force_reprobe
- synthesize_lrmd_failure
- lrm_op_target
- fail_lrm_resource
- handle_refresh_op
- handle_query_op
- handle_reprobe_op
- do_lrm_cancel
- do_lrm_delete
- do_lrm_invoke
- resolve_versioned_parameters
- construct_op
- controld_ack_event_directly
- verify_stopped
- stop_recurring_action_by_rsc
- stop_recurring_actions
- record_pending_op
- do_lrm_rsc_op
- cib_rsc_callback
- should_preserve_lock
- do_update_resource
- do_lrm_event
- unescape_newlines
- did_lrm_rsc_op_fail
- log_executor_event
- process_lrm_event
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <regex.h>
13 #include <sys/param.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16
17 #include <crm/crm.h>
18 #include <crm/lrmd.h>
19 #include <crm/services.h>
20 #include <crm/msg_xml.h>
21 #include <crm/common/xml.h>
22 #include <crm/pengine/rules.h>
23 #include <crm/lrmd_internal.h>
24
25 #include <pacemaker-internal.h>
26 #include <pacemaker-controld.h>
27
28 #define START_DELAY_THRESHOLD 5 * 60 * 1000
29 #define MAX_LRM_REG_FAILS 30
30
31 struct delete_event_s {
32 int rc;
33 const char *rsc;
34 lrm_state_t *lrm_state;
35 };
36
37 static gboolean is_rsc_active(lrm_state_t * lrm_state, const char *rsc_id);
38 static gboolean build_active_RAs(lrm_state_t * lrm_state, xmlNode * rsc_list);
39 static gboolean stop_recurring_actions(gpointer key, gpointer value, gpointer user_data);
40
41 static lrmd_event_data_t *construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op,
42 const char *rsc_id, const char *operation);
43 static void do_lrm_rsc_op(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc,
44 const char *operation, xmlNode *msg);
45
46 static gboolean lrm_state_verify_stopped(lrm_state_t * lrm_state, enum crmd_fsa_state cur_state,
47 int log_level);
48 static int do_update_resource(const char *node_name, lrmd_rsc_info_t *rsc,
49 lrmd_event_data_t *op, time_t lock_time);
50
51 static void
52 lrm_connection_destroy(void)
53 {
54 if (pcmk_is_set(fsa_input_register, R_LRM_CONNECTED)) {
55 crm_crit("Connection to executor failed");
56 register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL);
57 controld_clear_fsa_input_flags(R_LRM_CONNECTED);
58
59 } else {
60 crm_info("Disconnected from executor");
61 }
62
63 }
64
65 static char *
66 make_stop_id(const char *rsc, int call_id)
67 {
68 return crm_strdup_printf("%s:%d", rsc, call_id);
69 }
70
71 static void
72 copy_instance_keys(gpointer key, gpointer value, gpointer user_data)
73 {
74 if (strstr(key, CRM_META "_") == NULL) {
75 g_hash_table_replace(user_data, strdup((const char *)key), strdup((const char *)value));
76 }
77 }
78
79 static void
80 copy_meta_keys(gpointer key, gpointer value, gpointer user_data)
81 {
82 if (strstr(key, CRM_META "_") != NULL) {
83 g_hash_table_replace(user_data, strdup((const char *)key), strdup((const char *)value));
84 }
85 }
86
87
88
89
90
91
92
93
94
95
96 static gboolean
97 history_remove_recurring_op(rsc_history_t *history, const lrmd_event_data_t *op)
98 {
99 GList *iter;
100
101 for (iter = history->recurring_op_list; iter != NULL; iter = iter->next) {
102 lrmd_event_data_t *existing = iter->data;
103
104 if ((op->interval_ms == existing->interval_ms)
105 && pcmk__str_eq(op->rsc_id, existing->rsc_id, pcmk__str_none)
106 && pcmk__str_eq(op->op_type, existing->op_type, pcmk__str_casei)) {
107
108 history->recurring_op_list = g_list_delete_link(history->recurring_op_list, iter);
109 lrmd_free_event(existing);
110 return TRUE;
111 }
112 }
113 return FALSE;
114 }
115
116
117
118
119
120
121
122 static void
123 history_free_recurring_ops(rsc_history_t *history)
124 {
125 GList *iter;
126
127 for (iter = history->recurring_op_list; iter != NULL; iter = iter->next) {
128 lrmd_free_event(iter->data);
129 }
130 g_list_free(history->recurring_op_list);
131 history->recurring_op_list = NULL;
132 }
133
134
135
136
137
138
139
140 void
141 history_free(gpointer data)
142 {
143 rsc_history_t *history = (rsc_history_t*)data;
144
145 if (history->stop_params) {
146 g_hash_table_destroy(history->stop_params);
147 }
148
149
150 free(history->rsc.type);
151 free(history->rsc.standard);
152 free(history->rsc.provider);
153
154 lrmd_free_event(history->failed);
155 lrmd_free_event(history->last);
156 free(history->id);
157 history_free_recurring_ops(history);
158 free(history);
159 }
160
161 static void
162 update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op)
163 {
164 int target_rc = 0;
165 rsc_history_t *entry = NULL;
166
167 if (op->rsc_deleted) {
168 crm_debug("Purged history for '%s' after %s", op->rsc_id, op->op_type);
169 controld_delete_resource_history(op->rsc_id, lrm_state->node_name,
170 NULL, crmd_cib_smart_opt());
171 return;
172 }
173
174 if (pcmk__str_eq(op->op_type, RSC_NOTIFY, pcmk__str_casei)) {
175 return;
176 }
177
178 crm_debug("Updating history for '%s' with %s op", op->rsc_id, op->op_type);
179
180 entry = g_hash_table_lookup(lrm_state->resource_history, op->rsc_id);
181 if (entry == NULL && rsc) {
182 entry = calloc(1, sizeof(rsc_history_t));
183 entry->id = strdup(op->rsc_id);
184 g_hash_table_insert(lrm_state->resource_history, entry->id, entry);
185
186 entry->rsc.id = entry->id;
187 entry->rsc.type = strdup(rsc->type);
188 entry->rsc.standard = strdup(rsc->standard);
189 if (rsc->provider) {
190 entry->rsc.provider = strdup(rsc->provider);
191 } else {
192 entry->rsc.provider = NULL;
193 }
194
195 } else if (entry == NULL) {
196 crm_info("Resource %s no longer exists, not updating cache", op->rsc_id);
197 return;
198 }
199
200 entry->last_callid = op->call_id;
201 target_rc = rsc_op_expected_rc(op);
202 if (op->op_status == PCMK_EXEC_CANCELLED) {
203 if (op->interval_ms > 0) {
204 crm_trace("Removing cancelled recurring op: " PCMK__OP_FMT,
205 op->rsc_id, op->op_type, op->interval_ms);
206 history_remove_recurring_op(entry, op);
207 return;
208 } else {
209 crm_trace("Skipping " PCMK__OP_FMT " rc=%d, status=%d",
210 op->rsc_id, op->op_type, op->interval_ms, op->rc,
211 op->op_status);
212 }
213
214 } else if (did_rsc_op_fail(op, target_rc)) {
215
216
217
218 if (entry->failed) {
219 lrmd_free_event(entry->failed);
220 }
221 entry->failed = lrmd_copy_event(op);
222
223 } else if (op->interval_ms == 0) {
224 if (entry->last) {
225 lrmd_free_event(entry->last);
226 }
227 entry->last = lrmd_copy_event(op);
228
229 if (op->params && pcmk__strcase_any_of(op->op_type, CRMD_ACTION_START,
230 CRMD_ACTION_RELOAD,
231 CRMD_ACTION_RELOAD_AGENT,
232 CRMD_ACTION_STATUS, NULL)) {
233 if (entry->stop_params) {
234 g_hash_table_destroy(entry->stop_params);
235 }
236 entry->stop_params = pcmk__strkey_table(free, free);
237
238 g_hash_table_foreach(op->params, copy_instance_keys, entry->stop_params);
239 }
240 }
241
242 if (op->interval_ms > 0) {
243
244 history_remove_recurring_op(entry, op);
245
246 crm_trace("Adding recurring op: " PCMK__OP_FMT,
247 op->rsc_id, op->op_type, op->interval_ms);
248 entry->recurring_op_list = g_list_prepend(entry->recurring_op_list, lrmd_copy_event(op));
249
250 } else if (entry->recurring_op_list && !pcmk__str_eq(op->op_type, RSC_STATUS, pcmk__str_casei)) {
251 crm_trace("Dropping %d recurring ops because of: " PCMK__OP_FMT,
252 g_list_length(entry->recurring_op_list), op->rsc_id,
253 op->op_type, op->interval_ms);
254 history_free_recurring_ops(entry);
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270 static void
271 send_task_ok_ack(lrm_state_t *lrm_state, ha_msg_input_t *input,
272 const char *rsc_id, lrmd_rsc_info_t *rsc, const char *task,
273 const char *ack_host, const char *ack_sys)
274 {
275 lrmd_event_data_t *op = construct_op(lrm_state, input->xml, rsc_id, task);
276
277 lrmd__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
278 controld_ack_event_directly(ack_host, ack_sys, rsc, op, rsc_id);
279 lrmd_free_event(op);
280 }
281
282 static inline const char *
283 op_node_name(lrmd_event_data_t *op)
284 {
285 return op->remote_nodename? op->remote_nodename : fsa_our_uname;
286 }
287
288 void
289 lrm_op_callback(lrmd_event_data_t * op)
290 {
291 CRM_CHECK(op != NULL, return);
292 switch (op->type) {
293 case lrmd_event_disconnect:
294 if (op->remote_nodename == NULL) {
295
296
297
298 lrm_connection_destroy();
299 }
300 break;
301
302 case lrmd_event_exec_complete:
303 {
304 lrm_state_t *lrm_state = lrm_state_find(op_node_name(op));
305
306 CRM_ASSERT(lrm_state != NULL);
307 process_lrm_event(lrm_state, op, NULL, NULL);
308 }
309 break;
310
311 default:
312 break;
313 }
314 }
315
316 static void
317 try_local_executor_connect(long long action, fsa_data_t *msg_data,
318 lrm_state_t *lrm_state)
319 {
320 int rc = pcmk_rc_ok;
321
322 crm_debug("Connecting to the local executor");
323
324
325 rc = controld_connect_local_executor(lrm_state);
326 if (rc == pcmk_rc_ok) {
327 controld_set_fsa_input_flags(R_LRM_CONNECTED);
328 crm_info("Connection to the local executor established");
329 return;
330 }
331
332
333 if (lrm_state->num_lrm_register_fails < MAX_LRM_REG_FAILS) {
334 crm_warn("Failed to connect to the local executor %d time%s "
335 "(%d max): %s", lrm_state->num_lrm_register_fails,
336 pcmk__plural_s(lrm_state->num_lrm_register_fails),
337 MAX_LRM_REG_FAILS, pcmk_rc_str(rc));
338 controld_start_timer(wait_timer);
339 crmd_fsa_stall(FALSE);
340 return;
341 }
342
343
344 crm_err("Failed to connect to the executor the max allowed "
345 "%d time%s: %s", lrm_state->num_lrm_register_fails,
346 pcmk__plural_s(lrm_state->num_lrm_register_fails),
347 pcmk_rc_str(rc));
348 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
349 }
350
351
352 void
353 do_lrm_control(long long action,
354 enum crmd_fsa_cause cause,
355 enum crmd_fsa_state cur_state,
356 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
357 {
358
359
360
361
362
363 lrm_state_t *lrm_state = NULL;
364
365 if(fsa_our_uname == NULL) {
366 return;
367 }
368 lrm_state = lrm_state_find_or_create(fsa_our_uname);
369 if (lrm_state == NULL) {
370 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
371 return;
372 }
373
374 if (action & A_LRM_DISCONNECT) {
375 if (lrm_state_verify_stopped(lrm_state, cur_state, LOG_INFO) == FALSE) {
376 if (action == A_LRM_DISCONNECT) {
377 crmd_fsa_stall(FALSE);
378 return;
379 }
380 }
381
382 controld_clear_fsa_input_flags(R_LRM_CONNECTED);
383 crm_info("Disconnecting from the executor");
384 lrm_state_disconnect(lrm_state);
385 lrm_state_reset_tables(lrm_state, FALSE);
386 crm_notice("Disconnected from the executor");
387 }
388
389 if (action & A_LRM_CONNECT) {
390 try_local_executor_connect(action, msg_data, lrm_state);
391 }
392
393 if (action & ~(A_LRM_CONNECT | A_LRM_DISCONNECT)) {
394 crm_err("Unexpected action %s in %s", fsa_action2string(action),
395 __func__);
396 }
397 }
398
399 static gboolean
400 lrm_state_verify_stopped(lrm_state_t * lrm_state, enum crmd_fsa_state cur_state, int log_level)
401 {
402 int counter = 0;
403 gboolean rc = TRUE;
404 const char *when = "lrm disconnect";
405
406 GHashTableIter gIter;
407 const char *key = NULL;
408 rsc_history_t *entry = NULL;
409 active_op_t *pending = NULL;
410
411 crm_debug("Checking for active resources before exit");
412
413 if (cur_state == S_TERMINATE) {
414 log_level = LOG_ERR;
415 when = "shutdown";
416
417 } else if (pcmk_is_set(fsa_input_register, R_SHUTDOWN)) {
418 when = "shutdown... waiting";
419 }
420
421 if (lrm_state->pending_ops && lrm_state_is_connected(lrm_state) == TRUE) {
422 guint removed = g_hash_table_foreach_remove(
423 lrm_state->pending_ops, stop_recurring_actions, lrm_state);
424 guint nremaining = g_hash_table_size(lrm_state->pending_ops);
425
426 if (removed || nremaining) {
427 crm_notice("Stopped %u recurring operation%s at %s (%u remaining)",
428 removed, pcmk__plural_s(removed), when, nremaining);
429 }
430 }
431
432 if (lrm_state->pending_ops) {
433 g_hash_table_iter_init(&gIter, lrm_state->pending_ops);
434 while (g_hash_table_iter_next(&gIter, NULL, (void **)&pending)) {
435
436 if (pending->interval_ms == 0) {
437 counter++;
438 }
439 }
440 }
441
442 if (counter > 0) {
443 do_crm_log(log_level, "%d pending executor operation%s at %s",
444 counter, pcmk__plural_s(counter), when);
445
446 if ((cur_state == S_TERMINATE)
447 || !pcmk_is_set(fsa_input_register, R_SENT_RSC_STOP)) {
448 g_hash_table_iter_init(&gIter, lrm_state->pending_ops);
449 while (g_hash_table_iter_next(&gIter, (gpointer*)&key, (gpointer*)&pending)) {
450 do_crm_log(log_level, "Pending action: %s (%s)", key, pending->op_key);
451 }
452
453 } else {
454 rc = FALSE;
455 }
456 return rc;
457 }
458
459 if (lrm_state->resource_history == NULL) {
460 return rc;
461 }
462
463 if (pcmk_is_set(fsa_input_register, R_SHUTDOWN)) {
464
465 when = "shutdown";
466 }
467
468 counter = 0;
469 g_hash_table_iter_init(&gIter, lrm_state->resource_history);
470 while (g_hash_table_iter_next(&gIter, NULL, (gpointer*)&entry)) {
471 if (is_rsc_active(lrm_state, entry->id) == FALSE) {
472 continue;
473 }
474
475 counter++;
476 if (log_level == LOG_ERR) {
477 crm_info("Found %s active at %s", entry->id, when);
478 } else {
479 crm_trace("Found %s active at %s", entry->id, when);
480 }
481 if (lrm_state->pending_ops) {
482 GHashTableIter hIter;
483
484 g_hash_table_iter_init(&hIter, lrm_state->pending_ops);
485 while (g_hash_table_iter_next(&hIter, (gpointer*)&key, (gpointer*)&pending)) {
486 if (pcmk__str_eq(entry->id, pending->rsc_id, pcmk__str_none)) {
487 crm_notice("%sction %s (%s) incomplete at %s",
488 pending->interval_ms == 0 ? "A" : "Recurring a",
489 key, pending->op_key, when);
490 }
491 }
492 }
493 }
494
495 if (counter) {
496 crm_err("%d resource%s active at %s",
497 counter, (counter == 1)? " was" : "s were", when);
498 }
499
500 return rc;
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522 static char *
523 build_parameter_list(const lrmd_event_data_t *op,
524 const struct ra_metadata_s *metadata,
525 enum ra_param_flags_e param_type, xmlNode **result)
526 {
527 char *list = NULL;
528 size_t len = 0;
529
530 *result = create_xml_node(NULL, XML_TAG_PARAMS);
531
532 for (GList *iter = metadata->ra_params; iter != NULL; iter = iter->next) {
533 struct ra_param_s *param = (struct ra_param_s *) iter->data;
534
535 bool accept_for_list = false;
536 bool accept_for_xml = false;
537
538 switch (param_type) {
539 case ra_param_reloadable:
540 accept_for_list = !pcmk_is_set(param->rap_flags, param_type);
541 accept_for_xml = accept_for_list;
542 break;
543
544 case ra_param_unique:
545 accept_for_list = pcmk_is_set(param->rap_flags, param_type);
546 accept_for_xml = accept_for_list;
547 break;
548
549 case ra_param_private:
550 accept_for_list = pcmk_is_set(param->rap_flags, param_type);
551 accept_for_xml = !accept_for_list;
552 break;
553 }
554
555 if (accept_for_list) {
556 crm_trace("Attr %s is %s", param->rap_name, ra_param_flag2text(param_type));
557
558 if (list == NULL) {
559
560 pcmk__add_word(&list, &len, " ");
561 }
562 pcmk__add_word(&list, &len, param->rap_name);
563
564 } else {
565 crm_trace("Rejecting %s for %s", param->rap_name, ra_param_flag2text(param_type));
566 }
567
568 if (accept_for_xml) {
569 const char *v = g_hash_table_lookup(op->params, param->rap_name);
570
571 if (v != NULL) {
572 crm_trace("Adding attr %s=%s to the xml result", param->rap_name, v);
573 crm_xml_add(*result, param->rap_name, v);
574 }
575 }
576 }
577
578 if (list != NULL) {
579
580 pcmk__add_word(&list, &len, " ");
581 }
582 return list;
583 }
584
585 static void
586 append_restart_list(lrmd_event_data_t *op, struct ra_metadata_s *metadata,
587 xmlNode *update, const char *version)
588 {
589 char *list = NULL;
590 char *digest = NULL;
591 xmlNode *restart = NULL;
592
593 CRM_LOG_ASSERT(op->params != NULL);
594
595 if (op->interval_ms > 0) {
596
597 return;
598 }
599
600 if (pcmk_is_set(metadata->ra_flags, ra_supports_reload_agent)) {
601
602 list = build_parameter_list(op, metadata, ra_param_reloadable,
603 &restart);
604
605 } else if (pcmk_is_set(metadata->ra_flags, ra_supports_legacy_reload)) {
606
607
608
609
610
611
612 list = build_parameter_list(op, metadata, ra_param_unique, &restart);
613
614 } else {
615
616 return;
617 }
618
619 digest = calculate_operation_digest(restart, version);
620
621
622 crm_xml_add(update, XML_LRM_ATTR_OP_RESTART, list? list: "");
623 crm_xml_add(update, XML_LRM_ATTR_RESTART_DIGEST, digest);
624
625 crm_trace("%s: %s, %s", op->rsc_id, digest, list);
626 crm_log_xml_trace(restart, "restart digest source");
627
628 free_xml(restart);
629 free(digest);
630 free(list);
631 }
632
633 static void
634 append_secure_list(lrmd_event_data_t *op, struct ra_metadata_s *metadata,
635 xmlNode *update, const char *version)
636 {
637 char *list = NULL;
638 char *digest = NULL;
639 xmlNode *secure = NULL;
640
641 CRM_LOG_ASSERT(op->params != NULL);
642
643
644
645
646
647
648 list = build_parameter_list(op, metadata, ra_param_private, &secure);
649
650 if (list != NULL) {
651 digest = calculate_operation_digest(secure, version);
652 crm_xml_add(update, XML_LRM_ATTR_OP_SECURE, list);
653 crm_xml_add(update, XML_LRM_ATTR_SECURE_DIGEST, digest);
654
655 crm_trace("%s: %s, %s", op->rsc_id, digest, list);
656 crm_log_xml_trace(secure, "secure digest source");
657 } else {
658 crm_trace("%s: no secure parameters", op->rsc_id);
659 }
660
661 free_xml(secure);
662 free(digest);
663 free(list);
664 }
665
666 static gboolean
667 build_operation_update(xmlNode * parent, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op,
668 const char *node_name, const char *src)
669 {
670 int target_rc = 0;
671 xmlNode *xml_op = NULL;
672 struct ra_metadata_s *metadata = NULL;
673 const char *caller_version = NULL;
674 lrm_state_t *lrm_state = NULL;
675 uint32_t metadata_source = controld_metadata_from_agent;
676
677 if (op == NULL) {
678 return FALSE;
679 }
680
681 target_rc = rsc_op_expected_rc(op);
682
683
684
685
686
687
688
689 caller_version = g_hash_table_lookup(op->params, XML_ATTR_CRM_VERSION);
690 CRM_LOG_ASSERT(caller_version != NULL);
691
692 if(caller_version == NULL) {
693 caller_version = CRM_FEATURE_SET;
694 }
695
696 crm_trace("Building %s operation update with originator version: %s", op->rsc_id, caller_version);
697 xml_op = pcmk__create_history_xml(parent, op, caller_version, target_rc,
698 fsa_our_uname, src, LOG_DEBUG);
699 if (xml_op == NULL) {
700 return TRUE;
701 }
702
703 if ((rsc == NULL) || (op->params == NULL)
704 || !crm_op_needs_metadata(rsc->standard, op->op_type)) {
705
706 crm_trace("No digests needed for %s action on %s (params=%p rsc=%p)",
707 op->op_type, op->rsc_id, op->params, rsc);
708 return TRUE;
709 }
710
711 lrm_state = lrm_state_find(node_name);
712 if (lrm_state == NULL) {
713 crm_warn("Cannot calculate digests for operation " PCMK__OP_FMT
714 " because we have no connection to executor for %s",
715 op->rsc_id, op->op_type, op->interval_ms, node_name);
716 return TRUE;
717 }
718
719
720
721
722
723
724
725
726
727 if ((op->op_status != PCMK_EXEC_DONE) || (op->rc != target_rc)
728 || !pcmk__str_eq(op->op_type, CRMD_ACTION_START, pcmk__str_none)) {
729 metadata_source |= controld_metadata_from_cache;
730 }
731 metadata = controld_get_rsc_metadata(lrm_state, rsc, metadata_source);
732 if (metadata == NULL) {
733 return TRUE;
734 }
735
736 #if ENABLE_VERSIONED_ATTRS
737 crm_xml_add(xml_op, XML_ATTR_RA_VERSION, metadata->ra_version);
738 #endif
739
740 crm_trace("Including additional digests for %s:%s:%s",
741 rsc->standard, rsc->provider, rsc->type);
742 append_restart_list(op, metadata, xml_op, caller_version);
743 append_secure_list(op, metadata, xml_op, caller_version);
744
745 return TRUE;
746 }
747
748 static gboolean
749 is_rsc_active(lrm_state_t * lrm_state, const char *rsc_id)
750 {
751 rsc_history_t *entry = NULL;
752
753 entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id);
754 if (entry == NULL || entry->last == NULL) {
755 return FALSE;
756 }
757
758 crm_trace("Processing %s: %s.%d=%d", rsc_id, entry->last->op_type,
759 entry->last->interval_ms, entry->last->rc);
760 if (entry->last->rc == PCMK_OCF_OK && pcmk__str_eq(entry->last->op_type, CRMD_ACTION_STOP, pcmk__str_casei)) {
761 return FALSE;
762
763 } else if (entry->last->rc == PCMK_OCF_OK
764 && pcmk__str_eq(entry->last->op_type, CRMD_ACTION_MIGRATE, pcmk__str_casei)) {
765
766 return FALSE;
767
768 } else if (entry->last->rc == PCMK_OCF_NOT_RUNNING) {
769 return FALSE;
770
771 } else if ((entry->last->interval_ms == 0)
772 && (entry->last->rc == PCMK_OCF_NOT_CONFIGURED)) {
773
774 return FALSE;
775 }
776
777 return TRUE;
778 }
779
780 static gboolean
781 build_active_RAs(lrm_state_t * lrm_state, xmlNode * rsc_list)
782 {
783 GHashTableIter iter;
784 rsc_history_t *entry = NULL;
785
786 g_hash_table_iter_init(&iter, lrm_state->resource_history);
787 while (g_hash_table_iter_next(&iter, NULL, (void **)&entry)) {
788
789 GList *gIter = NULL;
790 xmlNode *xml_rsc = create_xml_node(rsc_list, XML_LRM_TAG_RESOURCE);
791
792 crm_xml_add(xml_rsc, XML_ATTR_ID, entry->id);
793 crm_xml_add(xml_rsc, XML_ATTR_TYPE, entry->rsc.type);
794 crm_xml_add(xml_rsc, XML_AGENT_ATTR_CLASS, entry->rsc.standard);
795 crm_xml_add(xml_rsc, XML_AGENT_ATTR_PROVIDER, entry->rsc.provider);
796
797 if (entry->last && entry->last->params) {
798 const char *container = g_hash_table_lookup(entry->last->params, CRM_META"_"XML_RSC_ATTR_CONTAINER);
799 if (container) {
800 crm_trace("Resource %s is a part of container resource %s", entry->id, container);
801 crm_xml_add(xml_rsc, XML_RSC_ATTR_CONTAINER, container);
802 }
803 }
804 build_operation_update(xml_rsc, &(entry->rsc), entry->failed, lrm_state->node_name,
805 __func__);
806 build_operation_update(xml_rsc, &(entry->rsc), entry->last, lrm_state->node_name,
807 __func__);
808 for (gIter = entry->recurring_op_list; gIter != NULL; gIter = gIter->next) {
809 build_operation_update(xml_rsc, &(entry->rsc), gIter->data, lrm_state->node_name,
810 __func__);
811 }
812 }
813
814 return FALSE;
815 }
816
817 static xmlNode *
818 do_lrm_query_internal(lrm_state_t *lrm_state, int update_flags)
819 {
820 xmlNode *xml_state = NULL;
821 xmlNode *xml_data = NULL;
822 xmlNode *rsc_list = NULL;
823 crm_node_t *peer = NULL;
824
825 peer = crm_get_peer_full(0, lrm_state->node_name, CRM_GET_PEER_ANY);
826 CRM_CHECK(peer != NULL, return NULL);
827
828 xml_state = create_node_state_update(peer, update_flags, NULL,
829 __func__);
830 if (xml_state == NULL) {
831 return NULL;
832 }
833
834 xml_data = create_xml_node(xml_state, XML_CIB_TAG_LRM);
835 crm_xml_add(xml_data, XML_ATTR_ID, peer->uuid);
836 rsc_list = create_xml_node(xml_data, XML_LRM_TAG_RESOURCES);
837
838
839 build_active_RAs(lrm_state, rsc_list);
840
841 crm_log_xml_trace(xml_state, "Current executor state");
842
843 return xml_state;
844 }
845
846 xmlNode *
847 controld_query_executor_state(const char *node_name)
848 {
849 lrm_state_t *lrm_state = lrm_state_find(node_name);
850
851 if (!lrm_state) {
852 crm_err("Could not find executor state for node %s", node_name);
853 return NULL;
854 }
855 return do_lrm_query_internal(lrm_state,
856 node_update_cluster|node_update_peer);
857 }
858
859
860
861
862
863
864
865
866 void
867 controld_rc2event(lrmd_event_data_t *event, int rc)
868 {
869
870
871
872 switch (rc) {
873 case pcmk_rc_ok:
874 lrmd__set_result(event, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
875 break;
876 case EACCES:
877 lrmd__set_result(event, PCMK_OCF_INSUFFICIENT_PRIV,
878 PCMK_EXEC_ERROR, NULL);
879 break;
880 default:
881 lrmd__set_result(event, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_ERROR,
882 NULL);
883 break;
884 }
885 }
886
887
888
889
890
891
892
893
894
895
896
897
898 void
899 controld_trigger_delete_refresh(const char *from_sys, const char *rsc_id)
900 {
901 if (!pcmk__str_eq(from_sys, CRM_SYSTEM_TENGINE, pcmk__str_casei)) {
902 char *now_s = crm_strdup_printf("%lld", (long long) time(NULL));
903
904 crm_debug("Triggering a refresh after %s cleaned %s", from_sys, rsc_id);
905 update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
906 NULL, NULL, NULL, NULL, "last-lrm-refresh", now_s,
907 FALSE, NULL, NULL);
908 free(now_s);
909 }
910 }
911
912 static void
913 notify_deleted(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id, int rc)
914 {
915 lrmd_event_data_t *op = NULL;
916 const char *from_sys = crm_element_value(input->msg, F_CRM_SYS_FROM);
917 const char *from_host = crm_element_value(input->msg, F_CRM_HOST_FROM);
918
919 crm_info("Notifying %s on %s that %s was%s deleted",
920 from_sys, (from_host? from_host : "localhost"), rsc_id,
921 ((rc == pcmk_ok)? "" : " not"));
922 op = construct_op(lrm_state, input->xml, rsc_id, CRMD_ACTION_DELETE);
923 controld_rc2event(op, pcmk_legacy2rc(rc));
924 controld_ack_event_directly(from_host, from_sys, NULL, op, rsc_id);
925 lrmd_free_event(op);
926 controld_trigger_delete_refresh(from_sys, rsc_id);
927 }
928
929 static gboolean
930 lrm_remove_deleted_rsc(gpointer key, gpointer value, gpointer user_data)
931 {
932 struct delete_event_s *event = user_data;
933 struct pending_deletion_op_s *op = value;
934
935 if (pcmk__str_eq(event->rsc, op->rsc, pcmk__str_none)) {
936 notify_deleted(event->lrm_state, op->input, event->rsc, event->rc);
937 return TRUE;
938 }
939 return FALSE;
940 }
941
942 static gboolean
943 lrm_remove_deleted_op(gpointer key, gpointer value, gpointer user_data)
944 {
945 const char *rsc = user_data;
946 active_op_t *pending = value;
947
948 if (pcmk__str_eq(rsc, pending->rsc_id, pcmk__str_none)) {
949 crm_info("Removing op %s:%d for deleted resource %s",
950 pending->op_key, pending->call_id, rsc);
951 return TRUE;
952 }
953 return FALSE;
954 }
955
956 static void
957 delete_rsc_entry(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id,
958 GHashTableIter * rsc_gIter, int rc, const char *user_name)
959 {
960 struct delete_event_s event;
961
962 CRM_CHECK(rsc_id != NULL, return);
963
964 if (rc == pcmk_ok) {
965 char *rsc_id_copy = strdup(rsc_id);
966
967 if (rsc_gIter) {
968 g_hash_table_iter_remove(rsc_gIter);
969 } else {
970 g_hash_table_remove(lrm_state->resource_history, rsc_id_copy);
971 }
972 controld_delete_resource_history(rsc_id_copy, lrm_state->node_name,
973 user_name, crmd_cib_smart_opt());
974 g_hash_table_foreach_remove(lrm_state->pending_ops, lrm_remove_deleted_op, rsc_id_copy);
975 free(rsc_id_copy);
976 }
977
978 if (input) {
979 notify_deleted(lrm_state, input, rsc_id, rc);
980 }
981
982 event.rc = rc;
983 event.rsc = rsc_id;
984 event.lrm_state = lrm_state;
985 g_hash_table_foreach_remove(lrm_state->deletion_ops, lrm_remove_deleted_rsc, &event);
986 }
987
988
989
990
991
992
993
994
995 static void
996 erase_lrm_history_by_op(lrm_state_t *lrm_state, lrmd_event_data_t *op)
997 {
998 xmlNode *xml_top = NULL;
999
1000 CRM_CHECK(op != NULL, return);
1001
1002 xml_top = create_xml_node(NULL, XML_LRM_TAG_RSC_OP);
1003 crm_xml_add_int(xml_top, XML_LRM_ATTR_CALLID, op->call_id);
1004 crm_xml_add(xml_top, XML_ATTR_TRANSITION_KEY, op->user_data);
1005
1006 if (op->interval_ms > 0) {
1007 char *op_id = pcmk__op_key(op->rsc_id, op->op_type, op->interval_ms);
1008
1009
1010 crm_xml_add(xml_top, XML_ATTR_ID, op_id);
1011 free(op_id);
1012 }
1013
1014 crm_debug("Erasing resource operation history for " PCMK__OP_FMT " (call=%d)",
1015 op->rsc_id, op->op_type, op->interval_ms, op->call_id);
1016
1017 fsa_cib_conn->cmds->remove(fsa_cib_conn, XML_CIB_TAG_STATUS, xml_top,
1018 cib_quorum_override);
1019
1020 crm_log_xml_trace(xml_top, "op:cancel");
1021 free_xml(xml_top);
1022 }
1023
1024
1025 #define XPATH_HISTORY \
1026 "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS \
1027 "/" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" \
1028 "/" XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES \
1029 "/" XML_LRM_TAG_RESOURCE "[@" XML_ATTR_ID "='%s']" \
1030 "/" XML_LRM_TAG_RSC_OP
1031
1032
1033 #define XPATH_HISTORY_ID XPATH_HISTORY \
1034 "[@" XML_ATTR_ID "='%s']"
1035
1036
1037 #define XPATH_HISTORY_CALL XPATH_HISTORY \
1038 "[@" XML_ATTR_ID "='%s' and @" XML_LRM_ATTR_CALLID "='%d']"
1039
1040
1041 #define XPATH_HISTORY_ORIG XPATH_HISTORY \
1042 "[@" XML_ATTR_ID "='%s' and @" XML_LRM_ATTR_TASK_KEY "='%s']"
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054 static void
1055 erase_lrm_history_by_id(lrm_state_t *lrm_state, const char *rsc_id,
1056 const char *key, const char *orig_op, int call_id)
1057 {
1058 char *op_xpath = NULL;
1059
1060 CRM_CHECK((rsc_id != NULL) && (key != NULL), return);
1061
1062 if (call_id > 0) {
1063 op_xpath = crm_strdup_printf(XPATH_HISTORY_CALL,
1064 lrm_state->node_name, rsc_id, key,
1065 call_id);
1066
1067 } else if (orig_op) {
1068 op_xpath = crm_strdup_printf(XPATH_HISTORY_ORIG,
1069 lrm_state->node_name, rsc_id, key,
1070 orig_op);
1071 } else {
1072 op_xpath = crm_strdup_printf(XPATH_HISTORY_ID,
1073 lrm_state->node_name, rsc_id, key);
1074 }
1075
1076 crm_debug("Erasing resource operation history for %s on %s (call=%d)",
1077 key, rsc_id, call_id);
1078 fsa_cib_conn->cmds->remove(fsa_cib_conn, op_xpath, NULL,
1079 cib_quorum_override | cib_xpath);
1080 free(op_xpath);
1081 }
1082
1083 static inline gboolean
1084 last_failed_matches_op(rsc_history_t *entry, const char *op, guint interval_ms)
1085 {
1086 if (entry == NULL) {
1087 return FALSE;
1088 }
1089 if (op == NULL) {
1090 return TRUE;
1091 }
1092 return (pcmk__str_eq(op, entry->failed->op_type, pcmk__str_casei)
1093 && (interval_ms == entry->failed->interval_ms));
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 void
1110 lrm_clear_last_failure(const char *rsc_id, const char *node_name,
1111 const char *operation, guint interval_ms)
1112 {
1113 char *op_key = NULL;
1114 char *orig_op_key = NULL;
1115 lrm_state_t *lrm_state = NULL;
1116
1117 lrm_state = lrm_state_find(node_name);
1118 if (lrm_state == NULL) {
1119 return;
1120 }
1121
1122
1123 op_key = pcmk__op_key(rsc_id, "last_failure", 0);
1124 if (operation) {
1125 orig_op_key = pcmk__op_key(rsc_id, operation, interval_ms);
1126 }
1127 erase_lrm_history_by_id(lrm_state, rsc_id, op_key, orig_op_key, 0);
1128 free(op_key);
1129 free(orig_op_key);
1130
1131
1132 if (lrm_state->resource_history) {
1133 rsc_history_t *entry = g_hash_table_lookup(lrm_state->resource_history,
1134 rsc_id);
1135
1136 if (last_failed_matches_op(entry, operation, interval_ms)) {
1137 lrmd_free_event(entry->failed);
1138 entry->failed = NULL;
1139 }
1140 }
1141 }
1142
1143
1144 static gboolean
1145 cancel_op(lrm_state_t * lrm_state, const char *rsc_id, const char *key, int op, gboolean remove)
1146 {
1147 int rc = pcmk_ok;
1148 char *local_key = NULL;
1149 active_op_t *pending = NULL;
1150
1151 CRM_CHECK(op != 0, return FALSE);
1152 CRM_CHECK(rsc_id != NULL, return FALSE);
1153 if (key == NULL) {
1154 local_key = make_stop_id(rsc_id, op);
1155 key = local_key;
1156 }
1157 pending = g_hash_table_lookup(lrm_state->pending_ops, key);
1158
1159 if (pending) {
1160 if (remove && !pcmk_is_set(pending->flags, active_op_remove)) {
1161 controld_set_active_op_flags(pending, active_op_remove);
1162 crm_debug("Scheduling %s for removal", key);
1163 }
1164
1165 if (pcmk_is_set(pending->flags, active_op_cancelled)) {
1166 crm_debug("Operation %s already cancelled", key);
1167 free(local_key);
1168 return FALSE;
1169 }
1170 controld_set_active_op_flags(pending, active_op_cancelled);
1171
1172 } else {
1173 crm_info("No pending op found for %s", key);
1174 free(local_key);
1175 return FALSE;
1176 }
1177
1178 crm_debug("Cancelling op %d for %s (%s)", op, rsc_id, key);
1179 rc = lrm_state_cancel(lrm_state, pending->rsc_id, pending->op_type,
1180 pending->interval_ms);
1181 if (rc == pcmk_ok) {
1182 crm_debug("Op %d for %s (%s): cancelled", op, rsc_id, key);
1183 free(local_key);
1184 return TRUE;
1185 }
1186
1187 crm_debug("Op %d for %s (%s): Nothing to cancel", op, rsc_id, key);
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197 free(local_key);
1198 return FALSE;
1199 }
1200
1201 struct cancel_data {
1202 gboolean done;
1203 gboolean remove;
1204 const char *key;
1205 lrmd_rsc_info_t *rsc;
1206 lrm_state_t *lrm_state;
1207 };
1208
1209 static gboolean
1210 cancel_action_by_key(gpointer key, gpointer value, gpointer user_data)
1211 {
1212 gboolean remove = FALSE;
1213 struct cancel_data *data = user_data;
1214 active_op_t *op = value;
1215
1216 if (pcmk__str_eq(op->op_key, data->key, pcmk__str_none)) {
1217 data->done = TRUE;
1218 remove = !cancel_op(data->lrm_state, data->rsc->id, key, op->call_id, data->remove);
1219 }
1220 return remove;
1221 }
1222
1223 static gboolean
1224 cancel_op_key(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *key, gboolean remove)
1225 {
1226 guint removed = 0;
1227 struct cancel_data data;
1228
1229 CRM_CHECK(rsc != NULL, return FALSE);
1230 CRM_CHECK(key != NULL, return FALSE);
1231
1232 data.key = key;
1233 data.rsc = rsc;
1234 data.done = FALSE;
1235 data.remove = remove;
1236 data.lrm_state = lrm_state;
1237
1238 removed = g_hash_table_foreach_remove(lrm_state->pending_ops, cancel_action_by_key, &data);
1239 crm_trace("Removed %u op cache entries, new size: %u",
1240 removed, g_hash_table_size(lrm_state->pending_ops));
1241 return data.done;
1242 }
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 static int
1262 get_lrm_resource(lrm_state_t *lrm_state, xmlNode *rsc_xml, gboolean do_create,
1263 lrmd_rsc_info_t **rsc_info)
1264 {
1265 const char *id = ID(rsc_xml);
1266
1267 CRM_CHECK(lrm_state && rsc_xml && rsc_info, return -EINVAL);
1268 CRM_CHECK(id, return -EINVAL);
1269
1270 if (lrm_state_is_connected(lrm_state) == FALSE) {
1271 return -ENOTCONN;
1272 }
1273
1274 crm_trace("Retrieving resource information for %s from the executor", id);
1275 *rsc_info = lrm_state_get_rsc_info(lrm_state, id, 0);
1276
1277
1278 if (!*rsc_info) {
1279 const char *long_id = crm_element_value(rsc_xml, XML_ATTR_ID_LONG);
1280
1281 if (long_id) {
1282 *rsc_info = lrm_state_get_rsc_info(lrm_state, long_id, 0);
1283 }
1284 }
1285
1286 if ((*rsc_info == NULL) && do_create) {
1287 const char *class = crm_element_value(rsc_xml, XML_AGENT_ATTR_CLASS);
1288 const char *provider = crm_element_value(rsc_xml, XML_AGENT_ATTR_PROVIDER);
1289 const char *type = crm_element_value(rsc_xml, XML_ATTR_TYPE);
1290 int rc;
1291
1292 crm_trace("Registering resource %s with the executor", id);
1293 rc = lrm_state_register_rsc(lrm_state, id, class, provider, type,
1294 lrmd_opt_drop_recurring);
1295 if (rc != pcmk_ok) {
1296 fsa_data_t *msg_data = NULL;
1297
1298 crm_err("Could not register resource %s with the executor on %s: %s "
1299 CRM_XS " rc=%d",
1300 id, lrm_state->node_name, pcmk_strerror(rc), rc);
1301
1302
1303
1304
1305
1306 if (lrm_state_is_local(lrm_state) == TRUE) {
1307 register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
1308 }
1309 return rc;
1310 }
1311
1312 *rsc_info = lrm_state_get_rsc_info(lrm_state, id, 0);
1313 }
1314 return *rsc_info? pcmk_ok : -ENODEV;
1315 }
1316
1317 static void
1318 delete_resource(lrm_state_t * lrm_state,
1319 const char *id,
1320 lrmd_rsc_info_t * rsc,
1321 GHashTableIter * gIter,
1322 const char *sys,
1323 const char *user,
1324 ha_msg_input_t * request,
1325 gboolean unregister)
1326 {
1327 int rc = pcmk_ok;
1328
1329 crm_info("Removing resource %s from executor for %s%s%s",
1330 id, sys, (user? " as " : ""), (user? user : ""));
1331
1332 if (rsc && unregister) {
1333 rc = lrm_state_unregister_rsc(lrm_state, id, 0);
1334 }
1335
1336 if (rc == pcmk_ok) {
1337 crm_trace("Resource %s deleted from executor", id);
1338 } else if (rc == -EINPROGRESS) {
1339 crm_info("Deletion of resource '%s' from executor is pending", id);
1340 if (request) {
1341 struct pending_deletion_op_s *op = NULL;
1342 char *ref = crm_element_value_copy(request->msg, XML_ATTR_REFERENCE);
1343
1344 op = calloc(1, sizeof(struct pending_deletion_op_s));
1345 op->rsc = strdup(rsc->id);
1346 op->input = copy_ha_msg_input(request);
1347 g_hash_table_insert(lrm_state->deletion_ops, ref, op);
1348 }
1349 return;
1350 } else {
1351 crm_warn("Could not delete '%s' from executor for %s%s%s: %s "
1352 CRM_XS " rc=%d", id, sys, (user? " as " : ""),
1353 (user? user : ""), pcmk_strerror(rc), rc);
1354 }
1355
1356 delete_rsc_entry(lrm_state, request, id, gIter, rc, user);
1357 }
1358
1359 static int
1360 get_fake_call_id(lrm_state_t *lrm_state, const char *rsc_id)
1361 {
1362 int call_id = 999999999;
1363 rsc_history_t *entry = NULL;
1364
1365 if(lrm_state) {
1366 entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id);
1367 }
1368
1369
1370
1371
1372 if (entry) {
1373 call_id = entry->last_callid + 1;
1374 }
1375
1376 if (call_id < 0) {
1377 call_id = 1;
1378 }
1379 return call_id;
1380 }
1381
1382 static void
1383 fake_op_status(lrm_state_t *lrm_state, lrmd_event_data_t *op, int op_status,
1384 enum ocf_exitcode op_exitcode, const char *exit_reason)
1385 {
1386 op->call_id = get_fake_call_id(lrm_state, op->rsc_id);
1387 op->t_run = time(NULL);
1388 op->t_rcchange = op->t_run;
1389 lrmd__set_result(op, op_exitcode, op_status, exit_reason);
1390 }
1391
1392 static void
1393 force_reprobe(lrm_state_t *lrm_state, const char *from_sys,
1394 const char *from_host, const char *user_name,
1395 gboolean is_remote_node)
1396 {
1397 GHashTableIter gIter;
1398 rsc_history_t *entry = NULL;
1399
1400 crm_info("Clearing resource history on node %s", lrm_state->node_name);
1401 g_hash_table_iter_init(&gIter, lrm_state->resource_history);
1402 while (g_hash_table_iter_next(&gIter, NULL, (void **)&entry)) {
1403
1404
1405
1406 gboolean unregister = TRUE;
1407
1408 if (is_remote_lrmd_ra(NULL, NULL, entry->id)) {
1409 lrm_state_t *remote_lrm_state = lrm_state_find(entry->id);
1410 if (remote_lrm_state) {
1411
1412
1413 force_reprobe(remote_lrm_state, from_sys, from_host, user_name, TRUE);
1414 }
1415 unregister = FALSE;
1416 }
1417
1418 delete_resource(lrm_state, entry->id, &entry->rsc, &gIter, from_sys,
1419 user_name, NULL, unregister);
1420 }
1421
1422
1423 controld_delete_node_state(lrm_state->node_name, controld_section_lrm,
1424 cib_scope_local);
1425
1426
1427
1428
1429 update_attrd(lrm_state->node_name, CRM_OP_PROBED, NULL, user_name, is_remote_node);
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446 static void
1447 synthesize_lrmd_failure(lrm_state_t *lrm_state, xmlNode *action,
1448 int op_status, enum ocf_exitcode rc,
1449 const char *exit_reason)
1450 {
1451 lrmd_event_data_t *op = NULL;
1452 const char *operation = crm_element_value(action, XML_LRM_ATTR_TASK);
1453 const char *target_node = crm_element_value(action, XML_LRM_ATTR_TARGET);
1454 xmlNode *xml_rsc = find_xml_node(action, XML_CIB_TAG_RESOURCE, TRUE);
1455
1456 if ((xml_rsc == NULL) || (ID(xml_rsc) == NULL)) {
1457
1458 crm_info("Can't fake %s failure (%d) on %s without resource configuration",
1459 crm_element_value(action, XML_LRM_ATTR_TASK_KEY), rc,
1460 target_node);
1461 return;
1462
1463 } else if(operation == NULL) {
1464
1465 crm_info("Can't fake %s failure (%d) on %s without operation",
1466 ID(xml_rsc), rc, target_node);
1467 return;
1468 }
1469
1470 op = construct_op(lrm_state, action, ID(xml_rsc), operation);
1471
1472 if (pcmk__str_eq(operation, RSC_NOTIFY, pcmk__str_casei)) {
1473 fake_op_status(lrm_state, op, PCMK_EXEC_DONE, PCMK_OCF_OK, NULL);
1474 } else {
1475 fake_op_status(lrm_state, op, op_status, rc, exit_reason);
1476 }
1477
1478 crm_info("Faking " PCMK__OP_FMT " result (%d) on %s",
1479 op->rsc_id, op->op_type, op->interval_ms, op->rc, target_node);
1480
1481
1482 process_lrm_event(lrm_state, op, NULL, action);
1483 lrmd_free_event(op);
1484 }
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494 static const char *
1495 lrm_op_target(xmlNode *xml)
1496 {
1497 const char *target = NULL;
1498
1499 if (xml) {
1500 target = crm_element_value(xml, XML_LRM_ATTR_TARGET);
1501 }
1502 if (target == NULL) {
1503 target = fsa_our_uname;
1504 }
1505 return target;
1506 }
1507
1508 static void
1509 fail_lrm_resource(xmlNode *xml, lrm_state_t *lrm_state, const char *user_name,
1510 const char *from_host, const char *from_sys)
1511 {
1512 lrmd_event_data_t *op = NULL;
1513 lrmd_rsc_info_t *rsc = NULL;
1514 xmlNode *xml_rsc = find_xml_node(xml, XML_CIB_TAG_RESOURCE, TRUE);
1515
1516 CRM_CHECK(xml_rsc != NULL, return);
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 op = construct_op(lrm_state, xml, ID(xml_rsc), "asyncmon");
1527
1528 free((char*) op->user_data);
1529 op->user_data = NULL;
1530 op->interval_ms = 0;
1531
1532 if (user_name && !pcmk__is_privileged(user_name)) {
1533 crm_err("%s does not have permission to fail %s", user_name, ID(xml_rsc));
1534 fake_op_status(lrm_state, op, PCMK_EXEC_ERROR,
1535 PCMK_OCF_INSUFFICIENT_PRIV,
1536 "Unprivileged user cannot fail resources");
1537 controld_ack_event_directly(from_host, from_sys, NULL, op, ID(xml_rsc));
1538 lrmd_free_event(op);
1539 return;
1540 }
1541
1542
1543 if (get_lrm_resource(lrm_state, xml_rsc, TRUE, &rsc) == pcmk_ok) {
1544 crm_info("Failing resource %s...", rsc->id);
1545 fake_op_status(lrm_state, op, PCMK_EXEC_DONE, PCMK_OCF_UNKNOWN_ERROR,
1546 "Simulated failure");
1547 process_lrm_event(lrm_state, op, NULL, xml);
1548 op->rc = PCMK_OCF_OK;
1549 lrmd_free_rsc_info(rsc);
1550
1551 } else {
1552 crm_info("Cannot find/create resource in order to fail it...");
1553 crm_log_xml_warn(xml, "bad input");
1554 fake_op_status(lrm_state, op, PCMK_EXEC_ERROR, PCMK_OCF_UNKNOWN_ERROR,
1555 "Cannot fail unknown resource");
1556 }
1557
1558 controld_ack_event_directly(from_host, from_sys, NULL, op, ID(xml_rsc));
1559 lrmd_free_event(op);
1560 }
1561
1562 static void
1563 handle_refresh_op(lrm_state_t *lrm_state, const char *user_name,
1564 const char *from_host, const char *from_sys)
1565 {
1566 int rc = pcmk_ok;
1567 xmlNode *fragment = do_lrm_query_internal(lrm_state, node_update_all);
1568
1569 fsa_cib_update(XML_CIB_TAG_STATUS, fragment, cib_quorum_override, rc, user_name);
1570 crm_info("Forced a local resource history refresh: call=%d", rc);
1571
1572 if (!pcmk__str_eq(CRM_SYSTEM_CRMD, from_sys, pcmk__str_casei)) {
1573 xmlNode *reply = create_request(CRM_OP_INVOKE_LRM, fragment, from_host,
1574 from_sys, CRM_SYSTEM_LRMD,
1575 fsa_our_uuid);
1576
1577 crm_debug("ACK'ing refresh from %s (%s)", from_sys, from_host);
1578
1579 if (relay_message(reply, TRUE) == FALSE) {
1580 crm_log_xml_err(reply, "Unable to route reply");
1581 }
1582 free_xml(reply);
1583 }
1584
1585 free_xml(fragment);
1586 }
1587
1588 static void
1589 handle_query_op(xmlNode *msg, lrm_state_t *lrm_state)
1590 {
1591 xmlNode *data = do_lrm_query_internal(lrm_state, node_update_all);
1592 xmlNode *reply = create_reply(msg, data);
1593
1594 if (relay_message(reply, TRUE) == FALSE) {
1595 crm_err("Unable to route reply");
1596 crm_log_xml_err(reply, "reply");
1597 }
1598 free_xml(reply);
1599 free_xml(data);
1600 }
1601
1602 static void
1603 handle_reprobe_op(lrm_state_t *lrm_state, const char *from_sys,
1604 const char *from_host, const char *user_name,
1605 gboolean is_remote_node)
1606 {
1607 crm_notice("Forcing the status of all resources to be redetected");
1608 force_reprobe(lrm_state, from_sys, from_host, user_name, is_remote_node);
1609
1610 if (!pcmk__strcase_any_of(from_sys, CRM_SYSTEM_PENGINE, CRM_SYSTEM_TENGINE, NULL)) {
1611
1612 xmlNode *reply = create_request(CRM_OP_INVOKE_LRM, NULL, from_host,
1613 from_sys, CRM_SYSTEM_LRMD,
1614 fsa_our_uuid);
1615
1616 crm_debug("ACK'ing re-probe from %s (%s)", from_sys, from_host);
1617
1618 if (relay_message(reply, TRUE) == FALSE) {
1619 crm_log_xml_err(reply, "Unable to route reply");
1620 }
1621 free_xml(reply);
1622 }
1623 }
1624
1625 static bool do_lrm_cancel(ha_msg_input_t *input, lrm_state_t *lrm_state,
1626 lrmd_rsc_info_t *rsc, const char *from_host, const char *from_sys)
1627 {
1628 char *op_key = NULL;
1629 char *meta_key = NULL;
1630 int call = 0;
1631 const char *call_id = NULL;
1632 const char *op_task = NULL;
1633 guint interval_ms = 0;
1634 gboolean in_progress = FALSE;
1635 xmlNode *params = find_xml_node(input->xml, XML_TAG_ATTRS, TRUE);
1636
1637 CRM_CHECK(params != NULL, return FALSE);
1638
1639 meta_key = crm_meta_name(XML_LRM_ATTR_TASK);
1640 op_task = crm_element_value(params, meta_key);
1641 free(meta_key);
1642 CRM_CHECK(op_task != NULL, return FALSE);
1643
1644 meta_key = crm_meta_name(XML_LRM_ATTR_INTERVAL_MS);
1645 if (crm_element_value_ms(params, meta_key, &interval_ms) != pcmk_ok) {
1646 free(meta_key);
1647 return FALSE;
1648 }
1649 free(meta_key);
1650
1651 op_key = pcmk__op_key(rsc->id, op_task, interval_ms);
1652
1653 meta_key = crm_meta_name(XML_LRM_ATTR_CALLID);
1654 call_id = crm_element_value(params, meta_key);
1655 free(meta_key);
1656
1657 crm_debug("Scheduler requested op %s (call=%s) be cancelled",
1658 op_key, (call_id? call_id : "NA"));
1659 pcmk__scan_min_int(call_id, &call, 0);
1660 if (call == 0) {
1661
1662 in_progress = cancel_op_key(lrm_state, rsc, op_key, TRUE);
1663
1664 } else {
1665
1666 in_progress = cancel_op(lrm_state, rsc->id, NULL, call, TRUE);
1667 }
1668
1669
1670 if (!in_progress || is_remote_lrmd_ra(NULL, NULL, rsc->id)) {
1671 char *op_id = make_stop_id(rsc->id, call);
1672
1673 if (is_remote_lrmd_ra(NULL, NULL, rsc->id) == FALSE) {
1674 crm_info("Nothing known about operation %d for %s", call, op_key);
1675 }
1676 erase_lrm_history_by_id(lrm_state, rsc->id, op_key, NULL, call);
1677 send_task_ok_ack(lrm_state, input, rsc->id, rsc, op_task,
1678 from_host, from_sys);
1679
1680
1681 g_hash_table_remove(lrm_state->pending_ops, op_id);
1682 free(op_id);
1683
1684 } else {
1685
1686
1687
1688
1689
1690
1691
1692 const char *peer_version = crm_element_value(params, XML_ATTR_CRM_VERSION);
1693
1694 if (compare_version(peer_version, "3.0.8") <= 0) {
1695 crm_info("Sending compatibility ack for %s cancellation to %s (CRM version %s)",
1696 op_key, from_host, peer_version);
1697 send_task_ok_ack(lrm_state, input, rsc->id, rsc, op_task,
1698 from_host, from_sys);
1699 }
1700 }
1701
1702 free(op_key);
1703 return TRUE;
1704 }
1705
1706 static void
1707 do_lrm_delete(ha_msg_input_t *input, lrm_state_t *lrm_state,
1708 lrmd_rsc_info_t *rsc, const char *from_sys, const char *from_host,
1709 bool crm_rsc_delete, const char *user_name)
1710 {
1711 gboolean unregister = TRUE;
1712 int cib_rc = controld_delete_resource_history(rsc->id, lrm_state->node_name,
1713 user_name,
1714 cib_dryrun|cib_sync_call);
1715
1716 if (cib_rc != pcmk_rc_ok) {
1717 lrmd_event_data_t *op = NULL;
1718
1719 op = construct_op(lrm_state, input->xml, rsc->id, CRMD_ACTION_DELETE);
1720
1721
1722
1723
1724 lrmd__set_result(op, pcmk_rc2ocf(cib_rc), PCMK_EXEC_ERROR, NULL);
1725 controld_ack_event_directly(from_host, from_sys, NULL, op, rsc->id);
1726 lrmd_free_event(op);
1727 return;
1728 }
1729
1730 if (crm_rsc_delete && is_remote_lrmd_ra(NULL, NULL, rsc->id)) {
1731 unregister = FALSE;
1732 }
1733
1734 delete_resource(lrm_state, rsc->id, rsc, NULL, from_sys,
1735 user_name, input, unregister);
1736 }
1737
1738
1739 void
1740 do_lrm_invoke(long long action,
1741 enum crmd_fsa_cause cause,
1742 enum crmd_fsa_state cur_state,
1743 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
1744 {
1745 lrm_state_t *lrm_state = NULL;
1746 const char *crm_op = NULL;
1747 const char *from_sys = NULL;
1748 const char *from_host = NULL;
1749 const char *operation = NULL;
1750 ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg);
1751 const char *user_name = NULL;
1752 const char *target_node = NULL;
1753 gboolean is_remote_node = FALSE;
1754 bool crm_rsc_delete = FALSE;
1755
1756 target_node = lrm_op_target(input->xml);
1757 is_remote_node = !pcmk__str_eq(target_node, fsa_our_uname,
1758 pcmk__str_casei);
1759
1760 lrm_state = lrm_state_find(target_node);
1761 if ((lrm_state == NULL) && is_remote_node) {
1762 crm_err("Failing action because local node has never had connection to remote node %s",
1763 target_node);
1764 synthesize_lrmd_failure(NULL, input->xml, PCMK_EXEC_NOT_CONNECTED,
1765 PCMK_OCF_UNKNOWN_ERROR,
1766 "Local node has no connection to remote");
1767 return;
1768 }
1769 CRM_ASSERT(lrm_state != NULL);
1770
1771 user_name = pcmk__update_acl_user(input->msg, F_CRM_USER, NULL);
1772 crm_op = crm_element_value(input->msg, F_CRM_TASK);
1773 from_sys = crm_element_value(input->msg, F_CRM_SYS_FROM);
1774 if (!pcmk__str_eq(from_sys, CRM_SYSTEM_TENGINE, pcmk__str_casei)) {
1775 from_host = crm_element_value(input->msg, F_CRM_HOST_FROM);
1776 }
1777 crm_trace("Executor %s command from %s as user %s",
1778 crm_op, from_sys, user_name);
1779
1780 if (pcmk__str_eq(crm_op, CRM_OP_LRM_DELETE, pcmk__str_casei)) {
1781 if (!pcmk__str_eq(from_sys, CRM_SYSTEM_TENGINE, pcmk__str_casei)) {
1782 crm_rsc_delete = TRUE;
1783 }
1784 operation = CRMD_ACTION_DELETE;
1785
1786 } else if (pcmk__str_eq(crm_op, CRM_OP_LRM_FAIL, pcmk__str_casei)) {
1787 fail_lrm_resource(input->xml, lrm_state, user_name, from_host,
1788 from_sys);
1789 return;
1790
1791 } else if (input->xml != NULL) {
1792 operation = crm_element_value(input->xml, XML_LRM_ATTR_TASK);
1793 }
1794
1795 if (pcmk__str_eq(crm_op, CRM_OP_LRM_REFRESH, pcmk__str_casei)) {
1796 handle_refresh_op(lrm_state, user_name, from_host, from_sys);
1797
1798 } else if (pcmk__str_eq(crm_op, CRM_OP_LRM_QUERY, pcmk__str_casei)) {
1799 handle_query_op(input->msg, lrm_state);
1800
1801 } else if (pcmk__str_eq(operation, CRM_OP_PROBED, pcmk__str_casei)) {
1802 update_attrd(lrm_state->node_name, CRM_OP_PROBED, XML_BOOLEAN_TRUE,
1803 user_name, is_remote_node);
1804
1805 } else if (pcmk__str_eq(crm_op, CRM_OP_REPROBE, pcmk__str_casei)
1806 || pcmk__str_eq(operation, CRM_OP_REPROBE, pcmk__str_casei)) {
1807 handle_reprobe_op(lrm_state, from_sys, from_host, user_name,
1808 is_remote_node);
1809
1810 } else if (operation != NULL) {
1811 lrmd_rsc_info_t *rsc = NULL;
1812 xmlNode *xml_rsc = find_xml_node(input->xml, XML_CIB_TAG_RESOURCE, TRUE);
1813 gboolean create_rsc = !pcmk__str_eq(operation, CRMD_ACTION_DELETE,
1814 pcmk__str_casei);
1815 int rc;
1816
1817
1818 CRM_CHECK(xml_rsc && ID(xml_rsc), return);
1819
1820 rc = get_lrm_resource(lrm_state, xml_rsc, create_rsc, &rsc);
1821 if (rc == -ENOTCONN) {
1822 synthesize_lrmd_failure(lrm_state, input->xml,
1823 PCMK_EXEC_NOT_CONNECTED,
1824 PCMK_OCF_UNKNOWN_ERROR,
1825 "Not connected to remote executor");
1826 return;
1827
1828 } else if ((rc < 0) && !create_rsc) {
1829
1830
1831
1832 crm_notice("Not registering resource '%s' for a %s event "
1833 CRM_XS " get-rc=%d (%s) transition-key=%s",
1834 ID(xml_rsc), operation,
1835 rc, pcmk_strerror(rc), ID(input->xml));
1836 delete_rsc_entry(lrm_state, input, ID(xml_rsc), NULL, pcmk_ok,
1837 user_name);
1838 return;
1839
1840 } else if (rc == -EINVAL) {
1841
1842 crm_err("Invalid resource definition for %s", ID(xml_rsc));
1843 crm_log_xml_warn(input->msg, "invalid resource");
1844 synthesize_lrmd_failure(lrm_state, input->xml, PCMK_EXEC_ERROR,
1845 PCMK_OCF_NOT_CONFIGURED,
1846 "Invalid resource definition");
1847 return;
1848
1849 } else if (rc < 0) {
1850
1851 crm_err("Could not register resource '%s' with executor: %s "
1852 CRM_XS " rc=%d",
1853 ID(xml_rsc), pcmk_strerror(rc), rc);
1854 crm_log_xml_warn(input->msg, "failed registration");
1855 synthesize_lrmd_failure(lrm_state, input->xml, PCMK_EXEC_ERROR,
1856 PCMK_OCF_INVALID_PARAM,
1857 "Could not register resource with executor");
1858 return;
1859 }
1860
1861 if (pcmk__str_eq(operation, CRMD_ACTION_CANCEL, pcmk__str_casei)) {
1862 if (!do_lrm_cancel(input, lrm_state, rsc, from_host, from_sys)) {
1863 crm_log_xml_warn(input->xml, "Bad command");
1864 }
1865
1866 } else if (pcmk__str_eq(operation, CRMD_ACTION_DELETE, pcmk__str_casei)) {
1867 do_lrm_delete(input, lrm_state, rsc, from_sys, from_host,
1868 crm_rsc_delete, user_name);
1869
1870 } else if (pcmk__str_any_of(operation, CRMD_ACTION_RELOAD,
1871 CRMD_ACTION_RELOAD_AGENT, NULL)) {
1872
1873
1874
1875
1876
1877 struct ra_metadata_s *md = NULL;
1878 const char *reload_name = CRMD_ACTION_RELOAD_AGENT;
1879
1880 md = controld_get_rsc_metadata(lrm_state, rsc,
1881 controld_metadata_from_cache);
1882 if ((md != NULL)
1883 && pcmk_is_set(md->ra_flags, ra_supports_legacy_reload)) {
1884 reload_name = CRMD_ACTION_RELOAD;
1885 }
1886 do_lrm_rsc_op(lrm_state, rsc, reload_name, input->xml);
1887
1888 } else {
1889 do_lrm_rsc_op(lrm_state, rsc, operation, input->xml);
1890 }
1891
1892 lrmd_free_rsc_info(rsc);
1893
1894 } else {
1895 crm_err("Cannot perform operation %s of unknown type", crm_str(crm_op));
1896 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
1897 }
1898 }
1899
1900 #if ENABLE_VERSIONED_ATTRS
1901 static void
1902 resolve_versioned_parameters(lrm_state_t *lrm_state, const char *rsc_id,
1903 const xmlNode *rsc_op, GHashTable *params)
1904 {
1905
1906
1907 lrmd_rsc_info_t *rsc = lrm_state_get_rsc_info(lrm_state, rsc_id, 0);
1908 struct ra_metadata_s *metadata;
1909
1910 metadata = controld_get_rsc_metadata(lrm_state, rsc,
1911 controld_metadata_from_cache);
1912 if (metadata) {
1913 xmlNode *versioned_attrs = NULL;
1914 GHashTable *hash = NULL;
1915 char *key = NULL;
1916 char *value = NULL;
1917 GHashTableIter iter;
1918
1919 versioned_attrs = first_named_child(rsc_op, XML_TAG_OP_VER_ATTRS);
1920 hash = pe_unpack_versioned_parameters(versioned_attrs, metadata->ra_version);
1921 g_hash_table_iter_init(&iter, hash);
1922 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
1923 g_hash_table_iter_steal(&iter);
1924 g_hash_table_replace(params, key, value);
1925 }
1926 g_hash_table_destroy(hash);
1927
1928 versioned_attrs = first_named_child(rsc_op, XML_TAG_OP_VER_META);
1929 hash = pe_unpack_versioned_parameters(versioned_attrs, metadata->ra_version);
1930 g_hash_table_iter_init(&iter, hash);
1931 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
1932 g_hash_table_replace(params, crm_meta_name(key), strdup(value));
1933
1934 if (pcmk__str_eq(key, XML_ATTR_TIMEOUT, pcmk__str_casei)) {
1935 pcmk__scan_min_int(value, &op->timeout, 0);
1936 } else if (pcmk__str_eq(key, XML_OP_ATTR_START_DELAY, pcmk__str_casei)) {
1937 pcmk__scan_min_int(value, &op->start_delay, 0);
1938 }
1939 }
1940 g_hash_table_destroy(hash);
1941
1942 versioned_attrs = first_named_child(rsc_op, XML_TAG_RSC_VER_ATTRS);
1943 hash = pe_unpack_versioned_parameters(versioned_attrs, metadata->ra_version);
1944 g_hash_table_iter_init(&iter, hash);
1945 while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) {
1946 g_hash_table_iter_steal(&iter);
1947 g_hash_table_replace(params, key, value);
1948 }
1949 g_hash_table_destroy(hash);
1950 }
1951
1952 lrmd_free_rsc_info(rsc);
1953 }
1954 #endif
1955
1956 static lrmd_event_data_t *
1957 construct_op(lrm_state_t *lrm_state, xmlNode *rsc_op, const char *rsc_id,
1958 const char *operation)
1959 {
1960 lrmd_event_data_t *op = NULL;
1961 const char *op_delay = NULL;
1962 const char *op_timeout = NULL;
1963 GHashTable *params = NULL;
1964
1965 xmlNode *primitive = NULL;
1966 const char *class = NULL;
1967
1968 const char *transition = NULL;
1969
1970 CRM_ASSERT(rsc_id && operation);
1971
1972 op = lrmd_new_event(rsc_id, operation, 0);
1973 op->type = lrmd_event_exec_complete;
1974 op->timeout = 0;
1975 op->start_delay = 0;
1976 lrmd__set_result(op, PCMK_OCF_UNKNOWN, PCMK_EXEC_PENDING, NULL);
1977
1978 if (rsc_op == NULL) {
1979 CRM_LOG_ASSERT(pcmk__str_eq(CRMD_ACTION_STOP, operation, pcmk__str_casei));
1980 op->user_data = NULL;
1981
1982
1983
1984
1985
1986 op->params = pcmk__strkey_table(free, free);
1987
1988 g_hash_table_insert(op->params, strdup(XML_ATTR_CRM_VERSION), strdup(CRM_FEATURE_SET));
1989
1990 crm_trace("Constructed %s op for %s", operation, rsc_id);
1991 return op;
1992 }
1993
1994 params = xml2list(rsc_op);
1995 g_hash_table_remove(params, CRM_META "_op_target_rc");
1996
1997 op_delay = crm_meta_value(params, XML_OP_ATTR_START_DELAY);
1998 pcmk__scan_min_int(op_delay, &op->start_delay, 0);
1999
2000 op_timeout = crm_meta_value(params, XML_ATTR_TIMEOUT);
2001 pcmk__scan_min_int(op_timeout, &op->timeout, 0);
2002
2003 if (pcmk__guint_from_hash(params, CRM_META "_" XML_LRM_ATTR_INTERVAL_MS, 0,
2004 &(op->interval_ms)) != pcmk_rc_ok) {
2005 op->interval_ms = 0;
2006 }
2007
2008
2009
2010 primitive = find_xml_node(rsc_op, XML_CIB_TAG_RESOURCE, FALSE);
2011 class = crm_element_value(primitive, XML_AGENT_ATTR_CLASS);
2012
2013 if (pcmk_is_set(pcmk_get_ra_caps(class), pcmk_ra_cap_fence_params)
2014 && pcmk__str_eq(operation, CRMD_ACTION_STATUS, pcmk__str_casei)
2015 && (op->interval_ms > 0)) {
2016
2017 op_timeout = g_hash_table_lookup(params, "pcmk_monitor_timeout");
2018 if (op_timeout != NULL) {
2019 op->timeout = crm_get_msec(op_timeout);
2020 }
2021 }
2022
2023 #if ENABLE_VERSIONED_ATTRS
2024 if (lrm_state && !is_remote_lrmd_ra(NULL, NULL, rsc_id)
2025 && !pcmk__strcase_any_of(op_type, CRMD_ACTION_METADATA, CRMD_ACTION_DELETE,
2026 NULL)) {
2027 resolve_versioned_parameters(lrm_state, rsc_id, rsc_op, params);
2028 }
2029 #endif
2030
2031 if (!pcmk__str_eq(operation, RSC_STOP, pcmk__str_casei)) {
2032 op->params = params;
2033
2034 } else {
2035 rsc_history_t *entry = NULL;
2036
2037 if (lrm_state) {
2038 entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id);
2039 }
2040
2041
2042
2043 if (!entry || !entry->stop_params) {
2044 op->params = params;
2045 } else {
2046
2047
2048 op->params = pcmk__strkey_table(free, free);
2049
2050 g_hash_table_foreach(params, copy_meta_keys, op->params);
2051 g_hash_table_foreach(entry->stop_params, copy_instance_keys, op->params);
2052 g_hash_table_destroy(params);
2053 params = NULL;
2054 }
2055 }
2056
2057
2058 if (op->timeout <= 0) {
2059 op->timeout = op->interval_ms;
2060 }
2061 if (op->start_delay < 0) {
2062 op->start_delay = 0;
2063 }
2064
2065 transition = crm_element_value(rsc_op, XML_ATTR_TRANSITION_KEY);
2066 CRM_CHECK(transition != NULL, return op);
2067
2068 op->user_data = strdup(transition);
2069
2070 if (op->interval_ms != 0) {
2071 if (pcmk__strcase_any_of(operation, CRMD_ACTION_START, CRMD_ACTION_STOP, NULL)) {
2072 crm_err("Start and Stop actions cannot have an interval: %u",
2073 op->interval_ms);
2074 op->interval_ms = 0;
2075 }
2076 }
2077
2078 crm_trace("Constructed %s op for %s: interval=%u",
2079 operation, rsc_id, op->interval_ms);
2080
2081 return op;
2082 }
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097 void
2098 controld_ack_event_directly(const char *to_host, const char *to_sys,
2099 lrmd_rsc_info_t *rsc, lrmd_event_data_t *op,
2100 const char *rsc_id)
2101 {
2102 xmlNode *reply = NULL;
2103 xmlNode *update, *iter;
2104 crm_node_t *peer = NULL;
2105
2106 CRM_CHECK(op != NULL, return);
2107 if (op->rsc_id == NULL) {
2108 CRM_ASSERT(rsc_id != NULL);
2109 op->rsc_id = strdup(rsc_id);
2110 }
2111 if (to_sys == NULL) {
2112 to_sys = CRM_SYSTEM_TENGINE;
2113 }
2114
2115 peer = crm_get_peer(0, fsa_our_uname);
2116 update = create_node_state_update(peer, node_update_none, NULL,
2117 __func__);
2118
2119 iter = create_xml_node(update, XML_CIB_TAG_LRM);
2120 crm_xml_add(iter, XML_ATTR_ID, fsa_our_uuid);
2121 iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES);
2122 iter = create_xml_node(iter, XML_LRM_TAG_RESOURCE);
2123
2124 crm_xml_add(iter, XML_ATTR_ID, op->rsc_id);
2125
2126 build_operation_update(iter, rsc, op, fsa_our_uname, __func__);
2127 reply = create_request(CRM_OP_INVOKE_LRM, update, to_host, to_sys, CRM_SYSTEM_LRMD, NULL);
2128
2129 crm_log_xml_trace(update, "[direct ACK]");
2130
2131 crm_debug("ACK'ing resource op " PCMK__OP_FMT " from %s: %s",
2132 op->rsc_id, op->op_type, op->interval_ms, op->user_data,
2133 crm_element_value(reply, XML_ATTR_REFERENCE));
2134
2135 if (relay_message(reply, TRUE) == FALSE) {
2136 crm_log_xml_err(reply, "Unable to route reply");
2137 }
2138
2139 free_xml(update);
2140 free_xml(reply);
2141 }
2142
2143 gboolean
2144 verify_stopped(enum crmd_fsa_state cur_state, int log_level)
2145 {
2146 gboolean res = TRUE;
2147 GList *lrm_state_list = lrm_state_get_list();
2148 GList *state_entry;
2149
2150 for (state_entry = lrm_state_list; state_entry != NULL; state_entry = state_entry->next) {
2151 lrm_state_t *lrm_state = state_entry->data;
2152
2153 if (!lrm_state_verify_stopped(lrm_state, cur_state, log_level)) {
2154
2155 res = FALSE;
2156 }
2157 }
2158
2159 controld_set_fsa_input_flags(R_SENT_RSC_STOP);
2160 g_list_free(lrm_state_list); lrm_state_list = NULL;
2161 return res;
2162 }
2163
2164 struct stop_recurring_action_s {
2165 lrmd_rsc_info_t *rsc;
2166 lrm_state_t *lrm_state;
2167 };
2168
2169 static gboolean
2170 stop_recurring_action_by_rsc(gpointer key, gpointer value, gpointer user_data)
2171 {
2172 gboolean remove = FALSE;
2173 struct stop_recurring_action_s *event = user_data;
2174 active_op_t *op = value;
2175
2176 if ((op->interval_ms != 0)
2177 && pcmk__str_eq(op->rsc_id, event->rsc->id, pcmk__str_none)) {
2178
2179 crm_debug("Cancelling op %d for %s (%s)", op->call_id, op->rsc_id, (char*)key);
2180 remove = !cancel_op(event->lrm_state, event->rsc->id, key, op->call_id, FALSE);
2181 }
2182
2183 return remove;
2184 }
2185
2186 static gboolean
2187 stop_recurring_actions(gpointer key, gpointer value, gpointer user_data)
2188 {
2189 gboolean remove = FALSE;
2190 lrm_state_t *lrm_state = user_data;
2191 active_op_t *op = value;
2192
2193 if (op->interval_ms != 0) {
2194 crm_info("Cancelling op %d for %s (%s)", op->call_id, op->rsc_id,
2195 (const char *) key);
2196 remove = !cancel_op(lrm_state, op->rsc_id, key, op->call_id, FALSE);
2197 }
2198
2199 return remove;
2200 }
2201
2202 static void
2203 record_pending_op(const char *node_name, lrmd_rsc_info_t *rsc, lrmd_event_data_t *op)
2204 {
2205 const char *record_pending = NULL;
2206
2207 CRM_CHECK(node_name != NULL, return);
2208 CRM_CHECK(rsc != NULL, return);
2209 CRM_CHECK(op != NULL, return);
2210
2211
2212 if ((op->op_type == NULL) || (op->params == NULL)
2213 || !controld_action_is_recordable(op->op_type)) {
2214 return;
2215 }
2216
2217
2218 record_pending = crm_meta_value(op->params, XML_OP_ATTR_PENDING);
2219 if (record_pending && !crm_is_true(record_pending)) {
2220 return;
2221 }
2222
2223 op->call_id = -1;
2224 lrmd__set_result(op, PCMK_OCF_UNKNOWN, PCMK_EXEC_PENDING, NULL);
2225
2226 op->t_run = time(NULL);
2227 op->t_rcchange = op->t_run;
2228
2229
2230 crm_debug("Recording pending op " PCMK__OP_FMT " on %s in the CIB",
2231 op->rsc_id, op->op_type, op->interval_ms, node_name);
2232
2233 do_update_resource(node_name, rsc, op, 0);
2234 }
2235
2236 static void
2237 do_lrm_rsc_op(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc,
2238 const char *operation, xmlNode *msg)
2239 {
2240 int rc;
2241 int call_id = 0;
2242 char *op_id = NULL;
2243 lrmd_event_data_t *op = NULL;
2244 lrmd_key_value_t *params = NULL;
2245 fsa_data_t *msg_data = NULL;
2246 const char *transition = NULL;
2247 gboolean stop_recurring = FALSE;
2248 const char *nack_reason = NULL;
2249
2250 CRM_CHECK(rsc != NULL, return);
2251 CRM_CHECK(operation != NULL, return);
2252
2253 if (msg != NULL) {
2254 transition = crm_element_value(msg, XML_ATTR_TRANSITION_KEY);
2255 if (transition == NULL) {
2256 crm_log_xml_err(msg, "Missing transition number");
2257 }
2258 }
2259
2260 op = construct_op(lrm_state, msg, rsc->id, operation);
2261 CRM_CHECK(op != NULL, return);
2262
2263 if (is_remote_lrmd_ra(NULL, NULL, rsc->id)
2264 && (op->interval_ms == 0)
2265 && strcmp(operation, CRMD_ACTION_MIGRATE) == 0) {
2266
2267
2268
2269
2270
2271 stop_recurring = FALSE;
2272
2273 } else if ((op->interval_ms == 0)
2274 && strcmp(operation, CRMD_ACTION_STATUS) != 0
2275 && strcmp(operation, CRMD_ACTION_NOTIFY) != 0) {
2276
2277
2278 stop_recurring = TRUE;
2279 }
2280
2281 if (stop_recurring == TRUE) {
2282 guint removed = 0;
2283 struct stop_recurring_action_s data;
2284
2285 data.rsc = rsc;
2286 data.lrm_state = lrm_state;
2287 removed = g_hash_table_foreach_remove(
2288 lrm_state->pending_ops, stop_recurring_action_by_rsc, &data);
2289
2290 if (removed) {
2291 crm_debug("Stopped %u recurring operation%s in preparation for "
2292 PCMK__OP_FMT, removed, pcmk__plural_s(removed),
2293 rsc->id, operation, op->interval_ms);
2294 }
2295 }
2296
2297
2298 crm_notice("Requesting local execution of %s operation for %s on %s "
2299 CRM_XS " transition_key=%s op_key=" PCMK__OP_FMT,
2300 crm_action_str(op->op_type, op->interval_ms), rsc->id, lrm_state->node_name,
2301 transition, rsc->id, operation, op->interval_ms);
2302
2303 if (pcmk_is_set(fsa_input_register, R_SHUTDOWN)
2304 && pcmk__str_eq(operation, RSC_START, pcmk__str_casei)) {
2305
2306 register_fsa_input(C_SHUTDOWN, I_SHUTDOWN, NULL);
2307 nack_reason = "Not attempting start due to shutdown in progress";
2308
2309 } else if (fsa_state != S_NOT_DC
2310 && fsa_state != S_POLICY_ENGINE
2311 && fsa_state != S_TRANSITION_ENGINE
2312 && !pcmk__str_eq(operation, CRMD_ACTION_STOP, pcmk__str_casei)) {
2313 nack_reason = "Controller cannot attempt actions at this time";
2314 }
2315
2316 if (nack_reason != NULL) {
2317 crm_notice("Discarding attempt to perform action %s on %s in state %s (shutdown=%s)",
2318 operation, rsc->id, fsa_state2string(fsa_state),
2319 pcmk__btoa(pcmk_is_set(fsa_input_register, R_SHUTDOWN)));
2320
2321 lrmd__set_result(op, PCMK_OCF_UNKNOWN_ERROR, PCMK_EXEC_INVALID,
2322 nack_reason);
2323 controld_ack_event_directly(NULL, NULL, rsc, op, rsc->id);
2324 lrmd_free_event(op);
2325 free(op_id);
2326 return;
2327 }
2328
2329 record_pending_op(lrm_state->node_name, rsc, op);
2330
2331 op_id = pcmk__op_key(rsc->id, op->op_type, op->interval_ms);
2332
2333 if (op->interval_ms > 0) {
2334
2335 cancel_op_key(lrm_state, rsc, op_id, FALSE);
2336 }
2337
2338 if (op->params) {
2339 char *key = NULL;
2340 char *value = NULL;
2341 GHashTableIter iter;
2342
2343 g_hash_table_iter_init(&iter, op->params);
2344 while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value)) {
2345 params = lrmd_key_value_add(params, key, value);
2346 }
2347 }
2348
2349 rc = controld_execute_resource_agent(lrm_state, rsc->id, op->op_type,
2350 op->user_data, op->interval_ms,
2351 op->timeout, op->start_delay, params,
2352 &call_id);
2353 if (rc == pcmk_rc_ok) {
2354
2355
2356
2357 char *call_id_s = make_stop_id(rsc->id, call_id);
2358 active_op_t *pending = NULL;
2359
2360 pending = calloc(1, sizeof(active_op_t));
2361 crm_trace("Recording pending op: %d - %s %s", call_id, op_id, call_id_s);
2362
2363 pending->call_id = call_id;
2364 pending->interval_ms = op->interval_ms;
2365 pending->op_type = strdup(operation);
2366 pending->op_key = strdup(op_id);
2367 pending->rsc_id = strdup(rsc->id);
2368 pending->start_time = time(NULL);
2369 pending->user_data = op->user_data? strdup(op->user_data) : NULL;
2370 if (crm_element_value_epoch(msg, XML_CONFIG_ATTR_SHUTDOWN_LOCK,
2371 &(pending->lock_time)) != pcmk_ok) {
2372 pending->lock_time = 0;
2373 }
2374 g_hash_table_replace(lrm_state->pending_ops, call_id_s, pending);
2375
2376 if ((op->interval_ms > 0)
2377 && (op->start_delay > START_DELAY_THRESHOLD)) {
2378 int target_rc = PCMK_OCF_OK;
2379
2380 crm_info("Faking confirmation of %s: execution postponed for over 5 minutes", op_id);
2381 decode_transition_key(op->user_data, NULL, NULL, NULL, &target_rc);
2382 lrmd__set_result(op, target_rc, PCMK_EXEC_DONE, NULL);
2383 controld_ack_event_directly(NULL, NULL, rsc, op, rsc->id);
2384 }
2385
2386 pending->params = op->params;
2387 op->params = NULL;
2388
2389 } else if (lrm_state_is_local(lrm_state)) {
2390 crm_err("Could not initiate %s action for resource %s locally: %s "
2391 CRM_XS " rc=%d", operation, rsc->id, pcmk_rc_str(rc), rc);
2392 fake_op_status(lrm_state, op, PCMK_EXEC_NOT_CONNECTED,
2393 PCMK_OCF_UNKNOWN_ERROR, pcmk_rc_str(rc));
2394 process_lrm_event(lrm_state, op, NULL, NULL);
2395 register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL);
2396
2397 } else {
2398 crm_err("Could not initiate %s action for resource %s remotely on %s: "
2399 "%s " CRM_XS " rc=%d",
2400 operation, rsc->id, lrm_state->node_name, pcmk_rc_str(rc), rc);
2401 fake_op_status(lrm_state, op, PCMK_EXEC_NOT_CONNECTED,
2402 PCMK_OCF_UNKNOWN_ERROR, pcmk_rc_str(rc));
2403 process_lrm_event(lrm_state, op, NULL, NULL);
2404 }
2405
2406 free(op_id);
2407 lrmd_free_event(op);
2408 }
2409
2410 int last_resource_update = 0;
2411
2412 static void
2413 cib_rsc_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
2414 {
2415 switch (rc) {
2416 case pcmk_ok:
2417 case -pcmk_err_diff_failed:
2418 case -pcmk_err_diff_resync:
2419 crm_trace("Resource update %d complete: rc=%d", call_id, rc);
2420 break;
2421 default:
2422 crm_warn("Resource update %d failed: (rc=%d) %s", call_id, rc, pcmk_strerror(rc));
2423 }
2424
2425 if (call_id == last_resource_update) {
2426 last_resource_update = 0;
2427 trigger_fsa();
2428 }
2429 }
2430
2431
2432
2433
2434
2435 static bool
2436 should_preserve_lock(lrmd_event_data_t *op)
2437 {
2438 if (!controld_shutdown_lock_enabled) {
2439 return false;
2440 }
2441 if (!strcmp(op->op_type, RSC_STOP) && (op->rc == PCMK_OCF_OK)) {
2442 return true;
2443 }
2444 if (!strcmp(op->op_type, RSC_STATUS) && (op->rc == PCMK_OCF_NOT_RUNNING)) {
2445 return true;
2446 }
2447 return false;
2448 }
2449
2450 static int
2451 do_update_resource(const char *node_name, lrmd_rsc_info_t *rsc,
2452 lrmd_event_data_t *op, time_t lock_time)
2453 {
2454
2455
2456
2457
2458
2459
2460
2461
2462 int rc = pcmk_ok;
2463 xmlNode *update, *iter = NULL;
2464 int call_opt = crmd_cib_smart_opt();
2465 const char *uuid = NULL;
2466
2467 CRM_CHECK(op != NULL, return 0);
2468
2469 iter = create_xml_node(iter, XML_CIB_TAG_STATUS);
2470 update = iter;
2471 iter = create_xml_node(iter, XML_CIB_TAG_STATE);
2472
2473 if (pcmk__str_eq(node_name, fsa_our_uname, pcmk__str_casei)) {
2474 uuid = fsa_our_uuid;
2475
2476 } else {
2477
2478 uuid = node_name;
2479 crm_xml_add(iter, XML_NODE_IS_REMOTE, "true");
2480 }
2481
2482 CRM_LOG_ASSERT(uuid != NULL);
2483 if(uuid == NULL) {
2484 rc = -EINVAL;
2485 goto done;
2486 }
2487
2488 crm_xml_add(iter, XML_ATTR_UUID, uuid);
2489 crm_xml_add(iter, XML_ATTR_UNAME, node_name);
2490 crm_xml_add(iter, XML_ATTR_ORIGIN, __func__);
2491
2492 iter = create_xml_node(iter, XML_CIB_TAG_LRM);
2493 crm_xml_add(iter, XML_ATTR_ID, uuid);
2494
2495 iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES);
2496 iter = create_xml_node(iter, XML_LRM_TAG_RESOURCE);
2497 crm_xml_add(iter, XML_ATTR_ID, op->rsc_id);
2498
2499 build_operation_update(iter, rsc, op, node_name, __func__);
2500
2501 if (rsc) {
2502 const char *container = NULL;
2503
2504 crm_xml_add(iter, XML_ATTR_TYPE, rsc->type);
2505 crm_xml_add(iter, XML_AGENT_ATTR_CLASS, rsc->standard);
2506 crm_xml_add(iter, XML_AGENT_ATTR_PROVIDER, rsc->provider);
2507 if (lock_time != 0) {
2508
2509
2510
2511 if (!should_preserve_lock(op)) {
2512 lock_time = 0;
2513 }
2514 crm_xml_add_ll(iter, XML_CONFIG_ATTR_SHUTDOWN_LOCK,
2515 (long long) lock_time);
2516 }
2517
2518 if (op->params) {
2519 container = g_hash_table_lookup(op->params, CRM_META"_"XML_RSC_ATTR_CONTAINER);
2520 }
2521 if (container) {
2522 crm_trace("Resource %s is a part of container resource %s", op->rsc_id, container);
2523 crm_xml_add(iter, XML_RSC_ATTR_CONTAINER, container);
2524 }
2525
2526 } else {
2527 crm_warn("Resource %s no longer exists in the executor", op->rsc_id);
2528 controld_ack_event_directly(NULL, NULL, rsc, op, op->rsc_id);
2529 goto cleanup;
2530 }
2531
2532 crm_log_xml_trace(update, __func__);
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551 fsa_cib_update(XML_CIB_TAG_STATUS, update, call_opt, rc, NULL);
2552
2553 if (rc > 0) {
2554 last_resource_update = rc;
2555 }
2556 done:
2557
2558 crm_trace("Sent resource state update message: %d for %s=%u on %s",
2559 rc, op->op_type, op->interval_ms, op->rsc_id);
2560 fsa_register_cib_callback(rc, FALSE, NULL, cib_rsc_callback);
2561
2562 cleanup:
2563 free_xml(update);
2564 return rc;
2565 }
2566
2567 void
2568 do_lrm_event(long long action,
2569 enum crmd_fsa_cause cause,
2570 enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data)
2571 {
2572 CRM_CHECK(FALSE, return);
2573 }
2574
2575 static char *
2576 unescape_newlines(const char *string)
2577 {
2578 char *pch = NULL;
2579 char *ret = NULL;
2580 static const char *escaped_newline = "\\n";
2581
2582 if (!string) {
2583 return NULL;
2584 }
2585
2586 ret = strdup(string);
2587 pch = strstr(ret, escaped_newline);
2588 while (pch != NULL) {
2589
2590
2591
2592 pch[0] = '\n';
2593 pch[1] = ' ';
2594 pch = strstr(pch, escaped_newline);
2595 }
2596
2597 return ret;
2598 }
2599
2600 static bool
2601 did_lrm_rsc_op_fail(lrm_state_t *lrm_state, const char * rsc_id,
2602 const char * op_type, guint interval_ms)
2603 {
2604 rsc_history_t *entry = NULL;
2605
2606 CRM_CHECK(lrm_state != NULL, return FALSE);
2607 CRM_CHECK(rsc_id != NULL, return FALSE);
2608 CRM_CHECK(op_type != NULL, return FALSE);
2609
2610 entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id);
2611 if (entry == NULL || entry->failed == NULL) {
2612 return FALSE;
2613 }
2614
2615 if (pcmk__str_eq(entry->failed->rsc_id, rsc_id, pcmk__str_none)
2616 && pcmk__str_eq(entry->failed->op_type, op_type, pcmk__str_casei)
2617 && entry->failed->interval_ms == interval_ms) {
2618 return TRUE;
2619 }
2620
2621 return FALSE;
2622 }
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634 static void
2635 log_executor_event(lrmd_event_data_t *op, const char *op_key,
2636 const char *node_name, int update_id, gboolean confirmed)
2637 {
2638 int log_level = LOG_ERR;
2639 GString *str = g_string_sized_new(100);
2640
2641 g_string_printf(str, "Result of %s operation for %s",
2642 crm_action_str(op->op_type, op->interval_ms), op->rsc_id);
2643
2644 if (node_name != NULL) {
2645 g_string_append_printf(str, " on %s", node_name);
2646 }
2647
2648 switch (op->op_status) {
2649 case PCMK_EXEC_DONE:
2650 log_level = LOG_NOTICE;
2651 g_string_append_printf(str, ": %s",
2652 services_ocf_exitcode_str(op->rc));
2653 break;
2654
2655 case PCMK_EXEC_TIMEOUT:
2656 g_string_append_printf(str, ": %s after %s",
2657 pcmk_exec_status_str(op->op_status),
2658 pcmk__readable_interval(op->timeout));
2659 break;
2660
2661 case PCMK_EXEC_CANCELLED:
2662 log_level = LOG_INFO;
2663
2664 default:
2665 g_string_append_printf(str, ": %s",
2666 pcmk_exec_status_str(op->op_status));
2667 }
2668
2669 if ((op->exit_reason != NULL)
2670 && ((op->op_status != PCMK_EXEC_DONE) || (op->rc != PCMK_OCF_OK))) {
2671 g_string_append_printf(str, " (%s)", op->exit_reason);
2672 }
2673
2674 g_string_append(str, " " CRM_XS);
2675 if (update_id != 0) {
2676 g_string_append_printf(str, " CIB update %d,", update_id);
2677 }
2678 g_string_append_printf(str, " graph action %sconfirmed; call=%d key=%s",
2679 (confirmed? "" : "un"), op->call_id, op_key);
2680 if (op->op_status == PCMK_EXEC_DONE) {
2681 g_string_append_printf(str, " rc=%d", op->rc);
2682 }
2683
2684 do_crm_log(log_level, "%s", str->str);
2685 g_string_free(str, TRUE);
2686
2687 if (op->output != NULL) {
2688 char *prefix = crm_strdup_printf("%s-" PCMK__OP_FMT ":%d", node_name,
2689 op->rsc_id, op->op_type,
2690 op->interval_ms, op->call_id);
2691
2692 if (op->rc) {
2693 crm_log_output(LOG_NOTICE, prefix, op->output);
2694 } else {
2695 crm_log_output(LOG_DEBUG, prefix, op->output);
2696 }
2697 free(prefix);
2698 }
2699 }
2700
2701 void
2702 process_lrm_event(lrm_state_t *lrm_state, lrmd_event_data_t *op,
2703 active_op_t *pending, xmlNode *action_xml)
2704 {
2705 char *op_id = NULL;
2706 char *op_key = NULL;
2707
2708 int update_id = 0;
2709 gboolean remove = FALSE;
2710 gboolean removed = FALSE;
2711 bool need_direct_ack = FALSE;
2712 lrmd_rsc_info_t *rsc = NULL;
2713 const char *node_name = NULL;
2714
2715 CRM_CHECK(op != NULL, return);
2716 CRM_CHECK(op->rsc_id != NULL, return);
2717
2718
2719 if (compare_version(fsa_our_dc_version, "3.2.0") < 0) {
2720 switch (op->op_status) {
2721 case PCMK_EXEC_NOT_CONNECTED:
2722 lrmd__set_result(op, PCMK_OCF_CONNECTION_DIED,
2723 PCMK_EXEC_ERROR, op->exit_reason);
2724 break;
2725 case PCMK_EXEC_INVALID:
2726 lrmd__set_result(op, CRM_DIRECT_NACK_RC, PCMK_EXEC_ERROR,
2727 op->exit_reason);
2728 break;
2729 default:
2730 break;
2731 }
2732 }
2733
2734 op_id = make_stop_id(op->rsc_id, op->call_id);
2735 op_key = pcmk__op_key(op->rsc_id, op->op_type, op->interval_ms);
2736
2737
2738 if (lrm_state) {
2739 rsc = lrm_state_get_rsc_info(lrm_state, op->rsc_id, 0);
2740 }
2741 if ((rsc == NULL) && action_xml) {
2742 xmlNode *xml = find_xml_node(action_xml, XML_CIB_TAG_RESOURCE, TRUE);
2743
2744 const char *standard = crm_element_value(xml, XML_AGENT_ATTR_CLASS);
2745 const char *provider = crm_element_value(xml, XML_AGENT_ATTR_PROVIDER);
2746 const char *type = crm_element_value(xml, XML_ATTR_TYPE);
2747
2748 if (standard && type) {
2749 crm_info("%s agent information not cached, using %s%s%s:%s from action XML",
2750 op->rsc_id, standard,
2751 (provider? ":" : ""), (provider? provider : ""), type);
2752 rsc = lrmd_new_rsc_info(op->rsc_id, standard, provider, type);
2753 } else {
2754 crm_err("Can't process %s result because %s agent information not cached or in XML",
2755 op_key, op->rsc_id);
2756 }
2757 }
2758
2759
2760 if (lrm_state) {
2761 node_name = lrm_state->node_name;
2762 } else if (action_xml) {
2763 node_name = crm_element_value(action_xml, XML_LRM_ATTR_TARGET);
2764 }
2765
2766 if(pending == NULL) {
2767 remove = TRUE;
2768 if (lrm_state) {
2769 pending = g_hash_table_lookup(lrm_state->pending_ops, op_id);
2770 }
2771 }
2772
2773 if (op->op_status == PCMK_EXEC_ERROR) {
2774 switch(op->rc) {
2775 case PCMK_OCF_NOT_RUNNING:
2776 case PCMK_OCF_RUNNING_PROMOTED:
2777 case PCMK_OCF_DEGRADED:
2778 case PCMK_OCF_DEGRADED_PROMOTED:
2779
2780 op->op_status = PCMK_EXEC_DONE;
2781 break;
2782 default:
2783
2784 break;
2785 }
2786 }
2787
2788 if (op->op_status != PCMK_EXEC_CANCELLED) {
2789
2790
2791
2792
2793 need_direct_ack = TRUE;
2794
2795 if (controld_action_is_recordable(op->op_type)) {
2796 if (node_name && rsc) {
2797
2798 update_id = do_update_resource(node_name, rsc, op,
2799 pending? pending->lock_time : 0);
2800 need_direct_ack = FALSE;
2801
2802 } else if (op->rsc_deleted) {
2803
2804
2805
2806
2807 crm_notice("Not recording %s result in CIB because "
2808 "resource information was removed since it was initiated",
2809 op_key);
2810 } else {
2811
2812
2813
2814
2815 crm_err("Unable to record %s result in CIB: %s", op_key,
2816 (node_name? "No resource information" : "No node name"));
2817 }
2818 }
2819
2820 } else if (op->interval_ms == 0) {
2821
2822
2823
2824
2825 need_direct_ack = TRUE;
2826
2827 } else if (pending == NULL) {
2828
2829
2830
2831
2832 } else if (op->user_data == NULL) {
2833
2834
2835
2836 crm_err("Recurring operation %s was cancelled without transition information",
2837 op_key);
2838
2839 } else if (pcmk_is_set(pending->flags, active_op_remove)) {
2840
2841
2842
2843 if (lrm_state) {
2844 erase_lrm_history_by_op(lrm_state, op);
2845 }
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856 if (did_lrm_rsc_op_fail(lrm_state, pending->rsc_id,
2857 pending->op_type, pending->interval_ms)) {
2858 need_direct_ack = TRUE;
2859 }
2860
2861 } else if (op->rsc_deleted) {
2862
2863
2864
2865
2866 crm_debug("Recurring op %s was cancelled due to resource deletion",
2867 op_key);
2868 need_direct_ack = TRUE;
2869
2870 } else {
2871
2872
2873
2874
2875 }
2876
2877 if (need_direct_ack) {
2878 controld_ack_event_directly(NULL, NULL, NULL, op, op->rsc_id);
2879 }
2880
2881 if(remove == FALSE) {
2882
2883 removed = TRUE;
2884
2885 } else if (lrm_state && ((op->interval_ms == 0)
2886 || (op->op_status == PCMK_EXEC_CANCELLED))) {
2887
2888 gboolean found = g_hash_table_remove(lrm_state->pending_ops, op_id);
2889
2890 if (op->interval_ms != 0) {
2891 removed = TRUE;
2892 } else if (found) {
2893 removed = TRUE;
2894 crm_trace("Op %s (call=%d, stop-id=%s, remaining=%u): Confirmed",
2895 op_key, op->call_id, op_id,
2896 g_hash_table_size(lrm_state->pending_ops));
2897 }
2898 }
2899
2900 log_executor_event(op, op_key, node_name, update_id, removed);
2901
2902 if (lrm_state) {
2903 if (!pcmk__str_eq(op->op_type, RSC_METADATA, pcmk__str_casei)) {
2904 crmd_alert_resource_op(lrm_state->node_name, op);
2905 } else if (rsc && (op->rc == PCMK_OCF_OK)) {
2906 char *metadata = unescape_newlines(op->output);
2907
2908 metadata_cache_update(lrm_state->metadata_cache, rsc, metadata);
2909 free(metadata);
2910 }
2911 }
2912
2913 if (op->rsc_deleted) {
2914 crm_info("Deletion of resource '%s' complete after %s", op->rsc_id, op_key);
2915 if (lrm_state) {
2916 delete_rsc_entry(lrm_state, NULL, op->rsc_id, NULL, pcmk_ok, NULL);
2917 }
2918 }
2919
2920
2921
2922
2923 mainloop_set_trigger(fsa_source);
2924 if (lrm_state && rsc) {
2925 update_history_cache(lrm_state, rsc, op);
2926 }
2927
2928 lrmd_free_rsc_info(rsc);
2929 free(op_key);
2930 free(op_id);
2931 }