pacemaker 2.1.1-77db578727
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_sched_utils.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2021 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU General Public License version 2
7 * or later (GPLv2+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11#include <crm/msg_xml.h>
12#include <crm/lrmd.h> // lrmd_event_data_t
14#include <pacemaker-internal.h>
15
17rsc2node_new(const char *id, pe_resource_t *rsc,
18 int node_weight, const char *discover_mode,
19 pe_node_t *foo_node, pe_working_set_t *data_set)
20{
21 pe__location_t *new_con = NULL;
22
23 if (rsc == NULL || id == NULL) {
24 pe_err("Invalid constraint %s for rsc=%p", crm_str(id), rsc);
25 return NULL;
26
27 } else if (foo_node == NULL) {
28 CRM_CHECK(node_weight == 0, return NULL);
29 }
30
31 new_con = calloc(1, sizeof(pe__location_t));
32 if (new_con != NULL) {
33 new_con->id = strdup(id);
34 new_con->rsc_lh = rsc;
35 new_con->node_list_rh = NULL;
37
38
39 if (pcmk__str_eq(discover_mode, "always", pcmk__str_null_matches | pcmk__str_casei)) {
41 } else if (pcmk__str_eq(discover_mode, "never", pcmk__str_casei)) {
43 } else if (pcmk__str_eq(discover_mode, "exclusive", pcmk__str_casei)) {
45 rsc->exclusive_discover = TRUE;
46 } else {
47 pe_err("Invalid %s value %s in location constraint", XML_LOCATION_ATTR_DISCOVERY, discover_mode);
48 }
49
50 if (foo_node != NULL) {
51 pe_node_t *copy = pe__copy_node(foo_node);
52
53 copy->weight = node_weight;
54 new_con->node_list_rh = g_list_prepend(NULL, copy);
55 }
56
57 data_set->placement_constraints = g_list_prepend(data_set->placement_constraints, new_con);
58 rsc->rsc_location = g_list_prepend(rsc->rsc_location, new_con);
59 }
60
61 return new_con;
62}
63
64gboolean
66{
67 if (node == NULL) {
68 return FALSE;
69 }
70#if 0
71 if (node->weight < 0) {
72 return FALSE;
73 }
74#endif
75
76 if (node->details->online == FALSE
77 || node->details->shutdown || node->details->unclean
78 || node->details->standby || node->details->maintenance) {
79 crm_trace("%s: online=%d, unclean=%d, standby=%d, maintenance=%d",
80 node->details->uname, node->details->online,
81 node->details->unclean, node->details->standby, node->details->maintenance);
82 return FALSE;
83 }
84 return TRUE;
85}
86
95GHashTable *
96pcmk__copy_node_table(GHashTable *nodes)
97{
98 GHashTable *new_table = NULL;
99 GHashTableIter iter;
100 pe_node_t *node = NULL;
101
102 if (nodes == NULL) {
103 return NULL;
104 }
105 new_table = pcmk__strkey_table(NULL, free);
106 g_hash_table_iter_init(&iter, nodes);
107 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
108 pe_node_t *new_node = pe__copy_node(node);
109
110 g_hash_table_insert(new_table, (gpointer) new_node->details->id,
111 new_node);
112 }
113 return new_table;
114}
115
125GList *
126pcmk__copy_node_list(const GList *list, bool reset)
127{
128 GList *result = NULL;
129
130 for (const GList *gIter = list; gIter != NULL; gIter = gIter->next) {
131 pe_node_t *new_node = NULL;
132 pe_node_t *this_node = (pe_node_t *) gIter->data;
133
134 new_node = pe__copy_node(this_node);
135 if (reset) {
136 new_node->weight = 0;
137 }
138 result = g_list_prepend(result, new_node);
139 }
140 return result;
141}
142
143struct node_weight_s {
144 pe_node_t *active;
145 pe_working_set_t *data_set;
146};
147
148/* return -1 if 'a' is more preferred
149 * return 1 if 'b' is more preferred
150 */
151
152static gint
153sort_node_weight(gconstpointer a, gconstpointer b, gpointer data)
154{
155 const pe_node_t *node1 = (const pe_node_t *)a;
156 const pe_node_t *node2 = (const pe_node_t *)b;
157 struct node_weight_s *nw = data;
158
159 int node1_weight = 0;
160 int node2_weight = 0;
161
162 int result = 0;
163
164 if (a == NULL) {
165 return 1;
166 }
167 if (b == NULL) {
168 return -1;
169 }
170
171 node1_weight = node1->weight;
172 node2_weight = node2->weight;
173
174 if (can_run_resources(node1) == FALSE) {
175 node1_weight = -INFINITY;
176 }
177 if (can_run_resources(node2) == FALSE) {
178 node2_weight = -INFINITY;
179 }
180
181 if (node1_weight > node2_weight) {
182 crm_trace("%s (%d) > %s (%d) : weight",
183 node1->details->uname, node1_weight, node2->details->uname, node2_weight);
184 return -1;
185 }
186
187 if (node1_weight < node2_weight) {
188 crm_trace("%s (%d) < %s (%d) : weight",
189 node1->details->uname, node1_weight, node2->details->uname, node2_weight);
190 return 1;
191 }
192
193 crm_trace("%s (%d) == %s (%d) : weight",
194 node1->details->uname, node1_weight, node2->details->uname, node2_weight);
195
196 if (pcmk__str_eq(nw->data_set->placement_strategy, "minimal", pcmk__str_casei)) {
197 goto equal;
198 }
199
200 if (pcmk__str_eq(nw->data_set->placement_strategy, "balanced", pcmk__str_casei)) {
201 result = compare_capacity(node1, node2);
202 if (result < 0) {
203 crm_trace("%s > %s : capacity (%d)",
204 node1->details->uname, node2->details->uname, result);
205 return -1;
206 } else if (result > 0) {
207 crm_trace("%s < %s : capacity (%d)",
208 node1->details->uname, node2->details->uname, result);
209 return 1;
210 }
211 }
212
213 /* now try to balance resources across the cluster */
214 if (node1->details->num_resources < node2->details->num_resources) {
215 crm_trace("%s (%d) > %s (%d) : resources",
216 node1->details->uname, node1->details->num_resources,
217 node2->details->uname, node2->details->num_resources);
218 return -1;
219
220 } else if (node1->details->num_resources > node2->details->num_resources) {
221 crm_trace("%s (%d) < %s (%d) : resources",
222 node1->details->uname, node1->details->num_resources,
223 node2->details->uname, node2->details->num_resources);
224 return 1;
225 }
226
227 if (nw->active && nw->active->details == node1->details) {
228 crm_trace("%s (%d) > %s (%d) : active",
229 node1->details->uname, node1->details->num_resources,
230 node2->details->uname, node2->details->num_resources);
231 return -1;
232 } else if (nw->active && nw->active->details == node2->details) {
233 crm_trace("%s (%d) < %s (%d) : active",
234 node1->details->uname, node1->details->num_resources,
235 node2->details->uname, node2->details->num_resources);
236 return 1;
237 }
238 equal:
239 crm_trace("%s = %s", node1->details->uname, node2->details->uname);
240 return strcmp(node1->details->uname, node2->details->uname);
241}
242
243GList *
244sort_nodes_by_weight(GList *nodes, pe_node_t *active_node,
245 pe_working_set_t *data_set)
246{
247 struct node_weight_s nw = { active_node, data_set };
248
249 return g_list_sort_with_data(nodes, sort_node_weight, &nw);
250}
251
252void
254{
255 if (rsc->allocated_to) {
256 pe_node_t *old = rsc->allocated_to;
257
258 crm_info("Deallocating %s from %s", rsc->id, old->details->uname);
260 rsc->allocated_to = NULL;
261
262 old->details->allocated_rsc = g_list_remove(old->details->allocated_rsc, rsc);
263 old->details->num_resources--;
264 /* old->count--; */
266 free(old);
267 }
268}
269
270gboolean
271native_assign_node(pe_resource_t *rsc, pe_node_t *chosen, gboolean force)
272{
273 pcmk__output_t *out = rsc->cluster->priv;
274
276
277 if (force == FALSE && chosen != NULL) {
278 bool unset = FALSE;
279
280 if(chosen->weight < 0) {
281 unset = TRUE;
282
283 // Allow the graph to assume that the remote resource will come up
284 } else if (!can_run_resources(chosen) && !pe__is_guest_node(chosen)) {
285 unset = TRUE;
286 }
287
288 if(unset) {
289 crm_debug("All nodes for resource %s are unavailable"
290 ", unclean or shutting down (%s: %d, %d)",
291 rsc->id, chosen->details->uname, can_run_resources(chosen), chosen->weight);
292 pe__set_next_role(rsc, RSC_ROLE_STOPPED, "node availability");
293 chosen = NULL;
294 }
295 }
296
297 /* todo: update the old node for each resource to reflect its
298 * new resource count
299 */
300
303
304 if (chosen == NULL) {
305 GList *gIter = NULL;
306 char *rc_inactive = pcmk__itoa(PCMK_OCF_NOT_RUNNING);
307
308 crm_debug("Could not allocate a node for %s", rsc->id);
309 pe__set_next_role(rsc, RSC_ROLE_STOPPED, "unable to allocate");
310
311 for (gIter = rsc->actions; gIter != NULL; gIter = gIter->next) {
312 pe_action_t *op = (pe_action_t *) gIter->data;
313 const char *interval_ms_s = g_hash_table_lookup(op->meta, XML_LRM_ATTR_INTERVAL_MS);
314
315 crm_debug("Processing %s", op->uuid);
316 if(pcmk__str_eq(RSC_STOP, op->task, pcmk__str_casei)) {
318
319 } else if(pcmk__str_eq(RSC_START, op->task, pcmk__str_casei)) {
321 //pe__set_resource_flags(rsc, pe_rsc_block);
322
323 } else if (interval_ms_s && !pcmk__str_eq(interval_ms_s, "0", pcmk__str_casei)) {
324 if(pcmk__str_eq(rc_inactive, g_hash_table_lookup(op->meta, XML_ATTR_TE_TARGET_RC), pcmk__str_casei)) {
325 /* This is a recurring monitor for the stopped state, leave it alone */
326
327 } else {
328 /* Normal monitor operation, cancel it */
330 }
331 }
332 }
333
334 free(rc_inactive);
335 return FALSE;
336 }
337
338 crm_debug("Assigning %s to %s", chosen->details->uname, rsc->id);
339 rsc->allocated_to = pe__copy_node(chosen);
340
341 chosen->details->allocated_rsc = g_list_prepend(chosen->details->allocated_rsc, rsc);
342 chosen->details->num_resources++;
343 chosen->count++;
345
347 out->message(out, "resource-util", rsc, chosen, __func__);
348 }
349
350 return TRUE;
351}
352
353void
354log_action(unsigned int log_level, const char *pre_text, pe_action_t * action, gboolean details)
355{
356 const char *node_uname = NULL;
357 const char *node_uuid = NULL;
358 const char *desc = NULL;
359
360 if (action == NULL) {
361 crm_trace("%s%s: <NULL>", pre_text == NULL ? "" : pre_text, pre_text == NULL ? "" : ": ");
362 return;
363 }
364
365 if (pcmk_is_set(action->flags, pe_action_pseudo)) {
366 node_uname = NULL;
367 node_uuid = NULL;
368
369 } else if (action->node != NULL) {
370 node_uname = action->node->details->uname;
371 node_uuid = action->node->details->id;
372 } else {
373 node_uname = "<none>";
374 node_uuid = NULL;
375 }
376
377 switch (text2task(action->task)) {
378 case stonith_node:
379 case shutdown_crm:
380 if (pcmk_is_set(action->flags, pe_action_pseudo)) {
381 desc = "Pseudo ";
382 } else if (pcmk_is_set(action->flags, pe_action_optional)) {
383 desc = "Optional ";
384 } else if (!pcmk_is_set(action->flags, pe_action_runnable)) {
385 desc = "!!Non-Startable!! ";
386 } else if (pcmk_is_set(action->flags, pe_action_processed)) {
387 desc = "";
388 } else {
389 desc = "(Provisional) ";
390 }
391 crm_trace("%s%s%sAction %d: %s%s%s%s%s%s",
392 ((pre_text == NULL)? "" : pre_text),
393 ((pre_text == NULL)? "" : ": "),
394 desc, action->id, action->uuid,
395 (node_uname? "\ton " : ""), (node_uname? node_uname : ""),
396 (node_uuid? "\t\t(" : ""), (node_uuid? node_uuid : ""),
397 (node_uuid? ")" : ""));
398 break;
399 default:
401 desc = "Optional ";
402 } else if (pcmk_is_set(action->flags, pe_action_pseudo)) {
403 desc = "Pseudo ";
404 } else if (!pcmk_is_set(action->flags, pe_action_runnable)) {
405 desc = "!!Non-Startable!! ";
406 } else if (pcmk_is_set(action->flags, pe_action_processed)) {
407 desc = "";
408 } else {
409 desc = "(Provisional) ";
410 }
411 crm_trace("%s%s%sAction %d: %s %s%s%s%s%s%s",
412 ((pre_text == NULL)? "" : pre_text),
413 ((pre_text == NULL)? "" : ": "),
414 desc, action->id, action->uuid,
415 (action->rsc? action->rsc->id : "<none>"),
416 (node_uname? "\ton " : ""), (node_uname? node_uname : ""),
417 (node_uuid? "\t\t(" : ""), (node_uuid? node_uuid : ""),
418 (node_uuid? ")" : ""));
419 break;
420 }
421
422 if (details) {
423 GList *gIter = NULL;
424
425 crm_trace("\t\t====== Preceding Actions");
426
427 gIter = action->actions_before;
428 for (; gIter != NULL; gIter = gIter->next) {
429 pe_action_wrapper_t *other = (pe_action_wrapper_t *) gIter->data;
430
431 log_action(log_level + 1, "\t\t", other->action, FALSE);
432 }
433
434 crm_trace("\t\t====== Subsequent Actions");
435
436 gIter = action->actions_after;
437 for (; gIter != NULL; gIter = gIter->next) {
438 pe_action_wrapper_t *other = (pe_action_wrapper_t *) gIter->data;
439
440 log_action(log_level + 1, "\t\t", other->action, FALSE);
441 }
442
443 crm_trace("\t\t====== End");
444
445 } else {
446 crm_trace("\t\t(before=%d, after=%d)",
447 g_list_length(action->actions_before), g_list_length(action->actions_after));
448 }
449}
450
451gboolean
452can_run_any(GHashTable * nodes)
453{
454 GHashTableIter iter;
455 pe_node_t *node = NULL;
456
457 if (nodes == NULL) {
458 return FALSE;
459 }
460
461 g_hash_table_iter_init(&iter, nodes);
462 while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
463 if (can_run_resources(node) && node->weight >= 0) {
464 return TRUE;
465 }
466 }
467
468 return FALSE;
469}
470
472create_pseudo_resource_op(pe_resource_t * rsc, const char *task, bool optional, bool runnable, pe_working_set_t *data_set)
473{
474 pe_action_t *action = custom_action(rsc, pcmk__op_key(rsc->id, task, 0),
475 task, NULL, optional, TRUE, data_set);
476
478 if(runnable) {
480 }
481 return action;
482}
483
497pe_cancel_op(pe_resource_t *rsc, const char *task, guint interval_ms,
498 pe_node_t *node, pe_working_set_t *data_set)
499{
500 pe_action_t *cancel_op;
501 char *interval_ms_s = crm_strdup_printf("%u", interval_ms);
502
503 // @TODO dangerous if possible to schedule another action with this key
504 char *key = pcmk__op_key(rsc->id, task, interval_ms);
505
506 cancel_op = custom_action(rsc, key, RSC_CANCEL, node, FALSE, TRUE,
507 data_set);
508
509 free(cancel_op->task);
510 cancel_op->task = strdup(RSC_CANCEL);
511
512 free(cancel_op->cancel_task);
513 cancel_op->cancel_task = strdup(task);
514
515 add_hash_param(cancel_op->meta, XML_LRM_ATTR_TASK, task);
516 add_hash_param(cancel_op->meta, XML_LRM_ATTR_INTERVAL_MS, interval_ms_s);
517 free(interval_ms_s);
518
519 return cancel_op;
520}
521
533{
534 char *shutdown_id = crm_strdup_printf("%s-%s", CRM_OP_SHUTDOWN,
535 node->details->uname);
536
537 pe_action_t *shutdown_op = custom_action(NULL, shutdown_id, CRM_OP_SHUTDOWN,
538 node, FALSE, TRUE, data_set);
539
540 crm_notice("Scheduling shutdown of node %s", node->details->uname);
541 shutdown_constraints(node, shutdown_op, data_set);
543 return shutdown_op;
544}
545
546static char *
547generate_transition_magic(const char *transition_key, int op_status, int op_rc)
548{
549 CRM_CHECK(transition_key != NULL, return NULL);
550 return crm_strdup_printf("%d:%d;%s", op_status, op_rc, transition_key);
551}
552
553static void
554append_digest(lrmd_event_data_t *op, xmlNode *update, const char *version,
555 const char *magic, int level)
556{
557 /* this will enable us to later determine that the
558 * resource's parameters have changed and we should force
559 * a restart
560 */
561 char *digest = NULL;
562 xmlNode *args_xml = NULL;
563
564 if (op->params == NULL) {
565 return;
566 }
567
568 args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
569 g_hash_table_foreach(op->params, hash2field, args_xml);
571 digest = calculate_operation_digest(args_xml, version);
572
573#if 0
574 if (level < get_crm_log_level()
575 && op->interval_ms == 0 && pcmk__str_eq(op->op_type, CRMD_ACTION_START, pcmk__str_none)) {
576 char *digest_source = dump_xml_unformatted(args_xml);
577
578 do_crm_log(level, "Calculated digest %s for %s (%s). Source: %s\n",
579 digest, ID(update), magic, digest_source);
580 free(digest_source);
581 }
582#endif
583 crm_xml_add(update, XML_LRM_ATTR_OP_DIGEST, digest);
584
585 free_xml(args_xml);
586 free(digest);
587}
588
589#define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
590
605xmlNode *
607 const char *caller_version, int target_rc,
608 const char *node, const char *origin, int level)
609{
610 char *key = NULL;
611 char *magic = NULL;
612 char *op_id = NULL;
613 char *op_id_additional = NULL;
614 char *local_user_data = NULL;
615 const char *exit_reason = NULL;
616
617 xmlNode *xml_op = NULL;
618 const char *task = NULL;
619
620 CRM_CHECK(op != NULL, return NULL);
621 do_crm_log(level, "%s: Updating resource %s after %s op %s (interval=%u)",
622 origin, op->rsc_id, op->op_type, services_lrm_status_str(op->op_status),
623 op->interval_ms);
624
625 crm_trace("DC version: %s", caller_version);
626
627 task = op->op_type;
628
629 /* Record a successful agent reload as a start, and a failed one as a
630 * monitor, to make life easier for the scheduler when determining the
631 * current state.
632 *
633 * @COMPAT We should check "reload" here only if the operation was for a
634 * pre-OCF-1.1 resource agent, but we don't know that here, and we should
635 * only ever get results for actions scheduled by us, so we can reasonably
636 * assume any "reload" is actually a pre-1.1 agent reload.
637 */
639 NULL)) {
640 if (op->op_status == PCMK_LRM_OP_DONE) {
641 task = CRMD_ACTION_START;
642 } else {
643 task = CRMD_ACTION_STATUS;
644 }
645 }
646
647 key = pcmk__op_key(op->rsc_id, task, op->interval_ms);
648 if (pcmk__str_eq(task, CRMD_ACTION_NOTIFY, pcmk__str_none)) {
649 const char *n_type = crm_meta_value(op->params, "notify_type");
650 const char *n_task = crm_meta_value(op->params, "notify_operation");
651
652 CRM_LOG_ASSERT(n_type != NULL);
653 CRM_LOG_ASSERT(n_task != NULL);
654 op_id = pcmk__notify_key(op->rsc_id, n_type, n_task);
655
656 if (op->op_status != PCMK_LRM_OP_PENDING) {
657 /* Ignore notify errors.
658 *
659 * @TODO It might be better to keep the correct result here, and
660 * ignore it in process_graph_event().
661 */
663 op->rc = 0;
664 }
665
666 } else if (did_rsc_op_fail(op, target_rc)) {
667 op_id = pcmk__op_key(op->rsc_id, "last_failure", 0);
668 if (op->interval_ms == 0) {
669 // Ensure 'last' gets updated, in case record-pending is true
670 op_id_additional = pcmk__op_key(op->rsc_id, "last", 0);
671 }
672 exit_reason = op->exit_reason;
673
674 } else if (op->interval_ms > 0) {
675 op_id = strdup(key);
676
677 } else {
678 op_id = pcmk__op_key(op->rsc_id, "last", 0);
679 }
680
681 again:
682 xml_op = pcmk__xe_match(parent, XML_LRM_TAG_RSC_OP, XML_ATTR_ID, op_id);
683 if (xml_op == NULL) {
684 xml_op = create_xml_node(parent, XML_LRM_TAG_RSC_OP);
685 }
686
687 if (op->user_data == NULL) {
688 crm_debug("Generating fake transition key for: " PCMK__OP_FMT
689 " %d from %s", op->rsc_id, op->op_type, op->interval_ms,
690 op->call_id, origin);
691 local_user_data = pcmk__transition_key(-1, op->call_id, target_rc,
692 FAKE_TE_ID);
693 op->user_data = local_user_data;
694 }
695
696 if(magic == NULL) {
697 magic = generate_transition_magic(op->user_data, op->op_status, op->rc);
698 }
699
700 crm_xml_add(xml_op, XML_ATTR_ID, op_id);
702 crm_xml_add(xml_op, XML_LRM_ATTR_TASK, task);
703 crm_xml_add(xml_op, XML_ATTR_ORIGIN, origin);
704 crm_xml_add(xml_op, XML_ATTR_CRM_VERSION, caller_version);
707 crm_xml_add(xml_op, XML_LRM_ATTR_EXIT_REASON, exit_reason == NULL ? "" : exit_reason);
708 crm_xml_add(xml_op, XML_LRM_ATTR_TARGET, node); /* For context during triage */
709
711 crm_xml_add_int(xml_op, XML_LRM_ATTR_RC, op->rc);
714
715 if (compare_version("2.1", caller_version) <= 0) {
716 if (op->t_run || op->t_rcchange || op->exec_time || op->queue_time) {
717 crm_trace("Timing data (" PCMK__OP_FMT
718 "): last=%u change=%u exec=%u queue=%u",
719 op->rsc_id, op->op_type, op->interval_ms,
720 op->t_run, op->t_rcchange, op->exec_time, op->queue_time);
721
722 if ((op->interval_ms != 0) && (op->t_rcchange != 0)) {
723 // Recurring ops may have changed rc after initial run
725 (long long) op->t_rcchange);
726 } else {
728 (long long) op->t_run);
729 }
730
733 }
734 }
735
737 /*
738 * Record migrate_source and migrate_target always for migrate ops.
739 */
740 const char *name = XML_LRM_ATTR_MIGRATE_SOURCE;
741
742 crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
743
745 crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
746 }
747
748 append_digest(op, xml_op, caller_version, magic, LOG_DEBUG);
749
750 if (op_id_additional) {
751 free(op_id);
752 op_id = op_id_additional;
753 op_id_additional = NULL;
754 goto again;
755 }
756
757 if (local_user_data) {
758 free(local_user_data);
759 op->user_data = NULL;
760 }
761 free(magic);
762 free(op_id);
763 free(key);
764 return xml_op;
765}
766
769{
770 int rc = pcmk_rc_ok;
771 pcmk__output_t *out = NULL;
772 const char* argv[] = { "", NULL };
773 pcmk__supported_format_t formats[] = {
775 { NULL, NULL, NULL }
776 };
777
778 pcmk__register_formats(NULL, formats);
779 rc = pcmk__output_new(&out, "log", NULL, (char**)argv);
780 if ((rc != pcmk_rc_ok) || (out == NULL)) {
781 crm_err("Can't log resource details due to internal error: %s\n",
782 pcmk_rc_str(rc));
783 return NULL;
784 }
785
788 return out;
789}
void pcmk__filter_op_for_digest(xmlNode *param_set)
Definition operations.c:390
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Definition operations.c:229
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
Definition operations.c:45
char * pcmk__transition_key(int transition_id, int action_id, int target_rc, const char *node)
Definition operations.c:296
#define PCMK__OP_FMT
Definition internal.h:168
uint32_t version
Definition remote.c:1
const char * crm_meta_value(GHashTable *hash, const char *field)
Definition utils.c:533
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc)
Definition operations.c:437
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
int compare_version(const char *version1, const char *version2)
Definition utils.c:232
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:114
enum action_tasks text2task(const char *task)
Definition common.c:354
@ shutdown_crm
Definition common.h:75
@ stonith_node
Definition common.h:76
@ RSC_ROLE_STOPPED
Definition common.h:94
@ RSC_ROLE_UNKNOWN
Definition common.h:93
char data[0]
Definition cpg.c:10
#define CRMD_ACTION_NOTIFY
Definition crm.h:187
#define CRM_OP_SHUTDOWN
Definition crm.h:144
#define CRMD_ACTION_RELOAD_AGENT
Definition crm.h:172
#define CRMD_ACTION_MIGRATED
Definition crm.h:174
#define CRMD_ACTION_STATUS
Definition crm.h:190
#define RSC_START
Definition crm.h:201
#define CRMD_ACTION_RELOAD
Definition crm.h:171
#define INFINITY
Definition crm.h:99
#define RSC_STOP
Definition crm.h:204
#define CRMD_ACTION_MIGRATE
Definition crm.h:173
#define CRMD_ACTION_START
Definition crm.h:176
#define RSC_CANCEL
Definition crm.h:196
unsigned int get_crm_log_level(void)
Definition logging.c:992
#define crm_str(x)
Definition logging.h:376
#define crm_info(fmt, args...)
Definition logging.h:353
#define do_crm_log(level, fmt, args...)
Log a message.
Definition logging.h:159
#define CRM_LOG_ASSERT(expr)
Definition logging.h:202
#define crm_notice(fmt, args...)
Definition logging.h:352
#define CRM_CHECK(expr, failure_action)
Definition logging.h:218
#define crm_debug(fmt, args...)
Definition logging.h:355
#define crm_err(fmt, args...)
Definition logging.h:350
#define crm_trace(fmt, args...)
Definition logging.h:356
Resource agent executor.
#define XML_LOCATION_ATTR_DISCOVERY
Definition msg_xml.h:352
#define XML_LRM_TAG_RSC_OP
Definition msg_xml.h:265
#define ID(x)
Definition msg_xml.h:456
#define XML_ATTR_TRANSITION_KEY
Definition msg_xml.h:399
#define XML_ATTR_CRM_VERSION
Definition msg_xml.h:112
#define XML_BOOLEAN_TRUE
Definition msg_xml.h:140
#define XML_ATTR_TE_NOWAIT
Definition msg_xml.h:401
#define XML_LRM_ATTR_OP_DIGEST
Definition msg_xml.h:310
#define XML_LRM_ATTR_MIGRATE_SOURCE
Definition msg_xml.h:322
#define XML_LRM_ATTR_TASK_KEY
Definition msg_xml.h:298
#define XML_LRM_ATTR_OPSTATUS
Definition msg_xml.h:307
#define XML_ATTR_ID
Definition msg_xml.h:129
#define XML_ATTR_TRANSITION_MAGIC
Definition msg_xml.h:398
#define XML_RSC_OP_T_EXEC
Definition msg_xml.h:319
#define XML_LRM_ATTR_EXIT_REASON
Definition msg_xml.h:315
#define XML_ATTR_ORIGIN
Definition msg_xml.h:124
#define XML_LRM_ATTR_TASK
Definition msg_xml.h:297
#define XML_LRM_ATTR_MIGRATE_TARGET
Definition msg_xml.h:323
#define XML_LRM_ATTR_TARGET
Definition msg_xml.h:299
#define XML_RSC_OP_LAST_CHANGE
Definition msg_xml.h:317
#define XML_LRM_ATTR_CALLID
Definition msg_xml.h:309
#define XML_LRM_ATTR_RC
Definition msg_xml.h:308
#define XML_RSC_OP_T_QUEUE
Definition msg_xml.h:320
#define XML_TAG_PARAMS
Definition msg_xml.h:209
#define XML_ATTR_TE_TARGET_RC
Definition msg_xml.h:402
#define XML_LRM_ATTR_INTERVAL_MS
Definition msg_xml.h:295
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
Definition nvpair.c:786
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition nvpair.c:432
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
Definition nvpair.c:482
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition nvpair.c:324
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value.
Definition nvpair.c:454
#define PCMK__SUPPORTED_FORMAT_LOG
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename, char **argv)
Definition output.c:31
void pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *table)
Definition output.c:99
char * name
Definition pcmk_fence.c:31
const char * action
Definition pcmk_fence.c:30
int rc
Definition pcmk_fence.c:35
pcmk__output_t * pcmk__new_logger(void)
GHashTable * pcmk__copy_node_table(GHashTable *nodes)
gboolean can_run_resources(const pe_node_t *node)
GList * pcmk__copy_node_list(const GList *list, bool reset)
void native_deallocate(pe_resource_t *rsc)
pe__location_t * rsc2node_new(const char *id, pe_resource_t *rsc, int node_weight, const char *discover_mode, pe_node_t *foo_node, pe_working_set_t *data_set)
pe_action_t * pe_cancel_op(pe_resource_t *rsc, const char *task, guint interval_ms, pe_node_t *node, pe_working_set_t *data_set)
gboolean can_run_any(GHashTable *nodes)
xmlNode * pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *op, const char *caller_version, int target_rc, const char *node, const char *origin, int level)
void log_action(unsigned int log_level, const char *pre_text, pe_action_t *action, gboolean details)
pe_action_t * create_pseudo_resource_op(pe_resource_t *rsc, const char *task, bool optional, bool runnable, pe_working_set_t *data_set)
pe_action_t * sched_shutdown_op(pe_node_t *node, pe_working_set_t *data_set)
GList * sort_nodes_by_weight(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
#define FAKE_TE_ID
gboolean native_assign_node(pe_resource_t *rsc, pe_node_t *chosen, gboolean force)
void pcmk__register_lib_messages(pcmk__output_t *out)
int compare_capacity(const pe_node_t *node1, const pe_node_t *node2)
void calculate_utilization(GHashTable *current_utilization, GHashTable *utilization, gboolean plus)
gboolean shutdown_constraints(pe_node_t *node, pe_action_t *shutdown_op, pe_working_set_t *data_set)
#define pe_rsc_provisional
Definition pe_types.h:258
@ pe_discover_exclusive
Definition pe_types.h:480
@ pe_discover_always
Definition pe_types.h:478
@ pe_discover_never
Definition pe_types.h:479
@ pe_action_optional
Definition pe_types.h:294
@ pe_action_processed
Definition pe_types.h:302
@ pe_action_runnable
Definition pe_types.h:293
@ pe_action_pseudo
Definition pe_types.h:292
@ pe_native
Definition pe_types.h:37
#define pe_flag_show_utilization
Definition pe_types.h:134
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Definition utils.c:415
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition complex.c:1116
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition internal.h:53
void pe__register_messages(pcmk__output_t *out)
Definition pe_output.c:2732
#define pe__set_resource_flags(resource, flags_to_set)
Definition internal.h:47
#define pe__clear_action_flags(action, flags_to_clear)
Definition internal.h:68
pe_node_t * pe__copy_node(const pe_node_t *this_node)
Definition utils.c:142
#define pe_err(fmt...)
Definition internal.h:22
#define pe__set_action_flags(action, flags_to_set)
Definition internal.h:59
void add_hash_param(GHashTable *hash, const char *name, const char *value)
Definition common.c:579
bool pe__is_guest_node(const pe_node_t *node)
Definition remote.c:33
#define CRM_ASSERT(expr)
Definition results.h:42
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:420
@ PCMK_OCF_NOT_RUNNING
Definition results.h:158
@ pcmk_rc_ok
Definition results.h:142
op_status
Definition services.h:86
@ PCMK_LRM_OP_DONE
Definition services.h:89
@ PCMK_LRM_OP_PENDING
Definition services.h:88
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition strings.c:610
@ pcmk__str_none
@ pcmk__str_null_matches
@ pcmk__str_casei
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition strings.c:979
const char * op_type
Definition lrmd.h:205
unsigned int t_run
Definition lrmd.h:227
unsigned int t_rcchange
Definition lrmd.h:229
const char * exit_reason
Definition lrmd.h:248
const char * user_data
Definition lrmd.h:207
unsigned int exec_time
Definition lrmd.h:231
enum ocf_exitcode rc
Definition lrmd.h:221
unsigned int queue_time
Definition lrmd.h:233
void * params
Definition lrmd.h:240
guint interval_ms
Definition lrmd.h:214
const char * rsc_id
Definition lrmd.h:203
This structure contains everything that makes up a single output formatter.
int(* message)(pcmk__output_t *out, const char *message_id,...)
enum pe_discover_e discover_mode
Definition internal.h:172
pe_resource_t * rsc_lh
Definition internal.h:170
enum rsc_role_e role_filter
Definition internal.h:171
char * uuid
Definition pe_types.h:416
char * task
Definition pe_types.h:415
GHashTable * meta
Definition pe_types.h:425
char * cancel_task
Definition pe_types.h:417
pe_action_t * action
Definition pe_types.h:535
int weight
Definition pe_types.h:241
int count
Definition pe_types.h:243
struct pe_node_shared_s * details
Definition pe_types.h:244
gboolean shutdown
Definition pe_types.h:219
const char * id
Definition pe_types.h:208
gboolean online
Definition pe_types.h:213
const char * uname
Definition pe_types.h:209
gboolean standby
Definition pe_types.h:214
GHashTable * utilization
Definition pe_types.h:235
GList * allocated_rsc
Definition pe_types.h:232
gboolean unclean
Definition pe_types.h:217
gboolean maintenance
Definition pe_types.h:222
GList * actions
Definition pe_types.h:360
GList * rsc_location
Definition pe_types.h:359
enum pe_obj_types variant
Definition pe_types.h:331
gboolean exclusive_discover
Definition pe_types.h:353
pe_working_set_t * cluster
Definition pe_types.h:328
GHashTable * utilization
Definition pe_types.h:376
pe_node_t * allocated_to
Definition pe_types.h:364
unsigned long long flags
Definition pe_types.h:146
GList * placement_constraints
Definition pe_types.h:159
char * dump_xml_unformatted(xmlNode *msg)
Definition xml.c:2017
void free_xml(xmlNode *child)
Definition xml.c:823
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition xml.c:696
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition digest.c:170
xmlNode * pcmk__xe_match(xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition xml.c:496