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