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