pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_sched_resource.c
Go to the documentation of this file.
1/*
2 * Copyright 2014-2024 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
12#include <stdlib.h>
13#include <string.h>
14#include <crm/common/xml.h>
15#include <pacemaker-internal.h>
16
18
19// Resource assignment methods by resource variant
20static pcmk_assignment_methods_t assignment_methods[] = {
21 {
39 },
40 {
58 },
59 {
77 },
78 {
96 }
97};
98
110bool
112 const xmlNode *rsc_entry, bool active_on_node)
113{
114 bool changed = false;
115 const char *attr_list[] = {
119 };
120
121 for (int i = 0; i < PCMK__NELEM(attr_list); i++) {
122 const char *value = crm_element_value(rsc->xml, attr_list[i]);
123 const char *old_value = crm_element_value(rsc_entry, attr_list[i]);
124
125 if (!pcmk__str_eq(value, old_value, pcmk__str_none)) {
126 changed = true;
127 trigger_unfencing(rsc, node, "Device definition changed", NULL,
128 rsc->cluster);
129 if (active_on_node) {
130 crm_notice("Forcing restart of %s on %s "
131 "because %s changed from '%s' to '%s'",
132 rsc->id, pcmk__node_name(node), attr_list[i],
133 pcmk__s(old_value, ""), pcmk__s(value, ""));
134 }
135 }
136 }
137 if (changed && active_on_node) {
138 // Make sure the resource is restarted
139 custom_action(rsc, stop_key(rsc), PCMK_ACTION_STOP, node, FALSE,
140 rsc->cluster);
142 }
143 return changed;
144}
145
156static GList *
157add_rsc_if_matching(GList *result, pcmk_resource_t *rsc, const char *id)
158{
159 if ((strcmp(rsc->id, id) == 0)
160 || ((rsc->clone_name != NULL) && (strcmp(rsc->clone_name, id) == 0))) {
161 result = g_list_prepend(result, rsc);
162 }
163 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
164 pcmk_resource_t *child = (pcmk_resource_t *) iter->data;
165
166 result = add_rsc_if_matching(result, child, id);
167 }
168 return result;
169}
170
182GList *
184{
185 GList *result = NULL;
186
187 CRM_CHECK((id != NULL) && (scheduler != NULL), return NULL);
188 for (GList *iter = scheduler->resources; iter != NULL; iter = iter->next) {
189 result = add_rsc_if_matching(result, (pcmk_resource_t *) iter->data,
190 id);
191 }
192 return result;
193}
194
202static void
203set_assignment_methods_for_rsc(gpointer data, gpointer user_data)
204{
205 pcmk_resource_t *rsc = data;
206
207 rsc->cmds = &assignment_methods[rsc->variant];
208 g_list_foreach(rsc->children, set_assignment_methods_for_rsc, NULL);
209}
210
217void
219{
220 g_list_foreach(scheduler->resources, set_assignment_methods_for_rsc, NULL);
221}
222
233static inline void
234add_colocated_resources(const pcmk_resource_t *rsc,
235 const pcmk_resource_t *orig_rsc, GList **list)
236{
237 *list = rsc->cmds->colocated_resources(rsc, orig_rsc, *list);
238}
239
240// Shared implementation of pcmk_assignment_methods_t:colocated_resources()
241GList *
243 const pcmk_resource_t *orig_rsc,
244 GList *colocated_rscs)
245{
246 const GList *iter = NULL;
247 GList *colocations = NULL;
248
249 if (orig_rsc == NULL) {
250 orig_rsc = rsc;
251 }
252
253 if ((rsc == NULL) || (g_list_find(colocated_rscs, rsc) != NULL)) {
254 return colocated_rscs;
255 }
256
257 pcmk__rsc_trace(orig_rsc, "%s is in colocation chain with %s",
258 rsc->id, orig_rsc->id);
259 colocated_rscs = g_list_prepend(colocated_rscs, (gpointer) rsc);
260
261 // Follow colocations where this resource is the dependent resource
262 colocations = pcmk__this_with_colocations(rsc);
263 for (iter = colocations; iter != NULL; iter = iter->next) {
264 const pcmk__colocation_t *constraint = iter->data;
265 const pcmk_resource_t *primary = constraint->primary;
266
267 if (primary == orig_rsc) {
268 continue; // Break colocation loop
269 }
270
271 if ((constraint->score == PCMK_SCORE_INFINITY) &&
272 (pcmk__colocation_affects(rsc, primary, constraint,
274 add_colocated_resources(primary, orig_rsc, &colocated_rscs);
275 }
276 }
277 g_list_free(colocations);
278
279 // Follow colocations where this resource is the primary resource
280 colocations = pcmk__with_this_colocations(rsc);
281 for (iter = colocations; iter != NULL; iter = iter->next) {
282 const pcmk__colocation_t *constraint = iter->data;
283 const pcmk_resource_t *dependent = constraint->dependent;
284
285 if (dependent == orig_rsc) {
286 continue; // Break colocation loop
287 }
288
289 if (pcmk__is_clone(rsc) && !pcmk__is_clone(dependent)) {
290 continue; // We can't be sure whether dependent will be colocated
291 }
292
293 if ((constraint->score == PCMK_SCORE_INFINITY) &&
294 (pcmk__colocation_affects(dependent, rsc, constraint,
296 add_colocated_resources(dependent, orig_rsc, &colocated_rscs);
297 }
298 }
299 g_list_free(colocations);
300
301 return colocated_rscs;
302}
303
304// No-op function for variants that don't need to implement add_graph_meta()
305void
307{
308}
309
316void
318{
319 pcmk_node_t *next = NULL;
320 pcmk_node_t *current = NULL;
321 pcmk__output_t *out = NULL;
322
323 CRM_ASSERT(rsc != NULL);
324
325 out = rsc->cluster->priv;
326 if (rsc->children != NULL) {
327 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
328 pcmk_resource_t *child = (pcmk_resource_t *) iter->data;
329
330 child->cmds->output_actions(child);
331 }
332 return;
333 }
334
335 next = rsc->allocated_to;
336 if (rsc->running_on) {
337 current = pcmk__current_node(rsc);
338 if (rsc->role == pcmk_role_stopped) {
339 /* This can occur when resources are being recovered because
340 * the current role can change in pcmk__primitive_create_actions()
341 */
342 rsc->role = pcmk_role_started;
343 }
344 }
345
346 if ((current == NULL) && pcmk_is_set(rsc->flags, pcmk_rsc_removed)) {
347 /* Don't log stopped orphans */
348 return;
349 }
350
351 out->message(out, "rsc-action", rsc, current, next);
352}
353
361static inline void
362add_assigned_resource(pcmk_node_t *node, pcmk_resource_t *rsc)
363{
364 node->details->allocated_rsc = g_list_prepend(node->details->allocated_rsc,
365 rsc);
366}
367
403bool
405 bool stop_if_fail)
406{
407 bool changed = false;
408
409 CRM_ASSERT(rsc != NULL);
410
411 if (rsc->children != NULL) {
412 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
413 pcmk_resource_t *child_rsc = iter->data;
414
415 changed |= pcmk__assign_resource(child_rsc, node, force,
416 stop_if_fail);
417 }
418 return changed;
419 }
420
421 // Assigning a primitive
422
423 if (!force && (node != NULL)
424 && ((node->weight < 0)
425 // Allow graph to assume that guest node connections will come up
426 || (!pcmk__node_available(node, true, false)
427 && !pcmk__is_guest_or_bundle_node(node)))) {
428
429 pcmk__rsc_debug(rsc,
430 "All nodes for resource %s are unavailable, unclean or "
431 "shutting down (%s can%s run resources, with score %s)",
432 rsc->id, pcmk__node_name(node),
433 (pcmk__node_available(node, true, false)? "" : "not"),
435
436 if (stop_if_fail) {
437 pe__set_next_role(rsc, pcmk_role_stopped, "node availability");
438 }
439 node = NULL;
440 }
441
442 if (rsc->allocated_to != NULL) {
443 changed = !pcmk__same_node(rsc->allocated_to, node);
444 } else {
445 changed = (node != NULL);
446 }
449
450 if (node == NULL) {
451 char *rc_stopped = NULL;
452
453 pcmk__rsc_debug(rsc, "Could not assign %s to a node", rsc->id);
454
455 if (!stop_if_fail) {
456 return changed;
457 }
458 pe__set_next_role(rsc, pcmk_role_stopped, "unable to assign");
459
460 for (GList *iter = rsc->actions; iter != NULL; iter = iter->next) {
461 pcmk_action_t *op = (pcmk_action_t *) iter->data;
462
463 pcmk__rsc_debug(rsc, "Updating %s for %s assignment failure",
464 op->uuid, rsc->id);
465
466 if (pcmk__str_eq(op->task, PCMK_ACTION_STOP, pcmk__str_none)) {
468
469 } else if (pcmk__str_eq(op->task, PCMK_ACTION_START,
472
473 } else {
474 // Cancel recurring actions, unless for stopped state
475 const char *interval_ms_s = NULL;
476 const char *target_rc_s = NULL;
477
478 interval_ms_s = g_hash_table_lookup(op->meta,
480 target_rc_s = g_hash_table_lookup(op->meta,
482 if (rc_stopped == NULL) {
483 rc_stopped = pcmk__itoa(PCMK_OCF_NOT_RUNNING);
484 }
485
486 if (!pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches)
487 && !pcmk__str_eq(rc_stopped, target_rc_s, pcmk__str_none)) {
488
490 }
491 }
492 }
493 free(rc_stopped);
494 return changed;
495 }
496
497 pcmk__rsc_debug(rsc, "Assigning %s to %s", rsc->id, pcmk__node_name(node));
498 rsc->allocated_to = pe__copy_node(node);
499
500 add_assigned_resource(node, rsc);
501 node->details->num_resources++;
502 node->count++;
504
506 pcmk__output_t *out = rsc->cluster->priv;
507
508 out->message(out, "resource-util", rsc, node, __func__);
509 }
510 return changed;
511}
512
524void
526{
527 pcmk_node_t *old = rsc->allocated_to;
528
529 if (old == NULL) {
530 crm_info("Unassigning %s", rsc->id);
531 } else {
532 crm_info("Unassigning %s from %s", rsc->id, pcmk__node_name(old));
533 }
534
536
537 if (rsc->children == NULL) {
538 if (old == NULL) {
539 return;
540 }
541 rsc->allocated_to = NULL;
542
543 /* We're going to free the pcmk_node_t, but its details member is shared
544 * and will remain, so update that appropriately first.
545 */
546 old->details->allocated_rsc = g_list_remove(old->details->allocated_rsc,
547 rsc);
548 old->details->num_resources--;
550 free(old);
551 return;
552 }
553
554 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
556 }
557}
558
570bool
572 pcmk_resource_t **failed)
573{
574 int fail_count, remaining_tries;
575 pcmk_resource_t *rsc_to_ban = rsc;
576
577 // Migration threshold of 0 means never force away
578 if (rsc->migration_threshold == 0) {
579 return false;
580 }
581
582 // If we're ignoring failures, also ignore the migration threshold
584 return false;
585 }
586
587 // If there are no failures, there's no need to force away
588 fail_count = pe_get_failcount(node, rsc, NULL,
590 if (fail_count <= 0) {
591 return false;
592 }
593
594 // If failed resource is anonymous clone instance, we'll force clone away
595 if (!pcmk_is_set(rsc->flags, pcmk_rsc_unique)) {
596 rsc_to_ban = uber_parent(rsc);
597 }
598
599 // How many more times recovery will be tried on this node
600 remaining_tries = rsc->migration_threshold - fail_count;
601
602 if (remaining_tries <= 0) {
603 pcmk__sched_warn("%s cannot run on %s due to reaching migration "
604 "threshold (clean up resource to allow again)"
605 CRM_XS " failures=%d "
607 rsc_to_ban->id, pcmk__node_name(node), fail_count,
609 if (failed != NULL) {
610 *failed = rsc_to_ban;
611 }
612 return true;
613 }
614
615 crm_info("%s can fail %d more time%s on "
616 "%s before reaching migration threshold (%d)",
617 rsc_to_ban->id, remaining_tries, pcmk__plural_s(remaining_tries),
618 pcmk__node_name(node), rsc->migration_threshold);
619 return false;
620}
621
631static int
632get_node_score(const pcmk_node_t *node, GHashTable *nodes)
633{
634 pcmk_node_t *found_node = NULL;
635
636 if ((node != NULL) && (nodes != NULL)) {
637 found_node = g_hash_table_lookup(nodes, node->details->id);
638 }
639 return (found_node == NULL)? -PCMK_SCORE_INFINITY : found_node->weight;
640}
641
653static gint
654cmp_resources(gconstpointer a, gconstpointer b, gpointer data)
655{
656 /* GLib insists that this function require gconstpointer arguments, but we
657 * make a small, temporary change to each argument (setting the
658 * pe_rsc_merging flag) during comparison
659 */
660 pcmk_resource_t *resource1 = (pcmk_resource_t *) a;
661 pcmk_resource_t *resource2 = (pcmk_resource_t *) b;
662 const GList *nodes = data;
663
664 int rc = 0;
665 int r1_score = -PCMK_SCORE_INFINITY;
666 int r2_score = -PCMK_SCORE_INFINITY;
667 pcmk_node_t *r1_node = NULL;
668 pcmk_node_t *r2_node = NULL;
669 GHashTable *r1_nodes = NULL;
670 GHashTable *r2_nodes = NULL;
671 const char *reason = NULL;
672
673 // Resources with highest priority should be assigned first
674 reason = "priority";
675 r1_score = resource1->priority;
676 r2_score = resource2->priority;
677 if (r1_score > r2_score) {
678 rc = -1;
679 goto done;
680 }
681 if (r1_score < r2_score) {
682 rc = 1;
683 goto done;
684 }
685
686 // We need nodes to make any other useful comparisons
687 reason = "no node list";
688 if (nodes == NULL) {
689 goto done;
690 }
691
692 // Calculate and log node scores
693 resource1->cmds->add_colocated_node_scores(resource1, NULL, resource1->id,
694 &r1_nodes, NULL, 1,
696 resource2->cmds->add_colocated_node_scores(resource2, NULL, resource2->id,
697 &r2_nodes, NULL, 1,
699 pe__show_node_scores(true, NULL, resource1->id, r1_nodes,
700 resource1->cluster);
701 pe__show_node_scores(true, NULL, resource2->id, r2_nodes,
702 resource2->cluster);
703
704 // The resource with highest score on its current node goes first
705 reason = "current location";
706 if (resource1->running_on != NULL) {
707 r1_node = pcmk__current_node(resource1);
708 }
709 if (resource2->running_on != NULL) {
710 r2_node = pcmk__current_node(resource2);
711 }
712 r1_score = get_node_score(r1_node, r1_nodes);
713 r2_score = get_node_score(r2_node, r2_nodes);
714 if (r1_score > r2_score) {
715 rc = -1;
716 goto done;
717 }
718 if (r1_score < r2_score) {
719 rc = 1;
720 goto done;
721 }
722
723 // Otherwise a higher score on any node will do
724 reason = "score";
725 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
726 const pcmk_node_t *node = (const pcmk_node_t *) iter->data;
727
728 r1_score = get_node_score(node, r1_nodes);
729 r2_score = get_node_score(node, r2_nodes);
730 if (r1_score > r2_score) {
731 rc = -1;
732 goto done;
733 }
734 if (r1_score < r2_score) {
735 rc = 1;
736 goto done;
737 }
738 }
739
740done:
741 crm_trace("%s (%d)%s%s %c %s (%d)%s%s: %s",
742 resource1->id, r1_score,
743 ((r1_node == NULL)? "" : " on "),
744 ((r1_node == NULL)? "" : r1_node->details->id),
745 ((rc < 0)? '>' : ((rc > 0)? '<' : '=')),
746 resource2->id, r2_score,
747 ((r2_node == NULL)? "" : " on "),
748 ((r2_node == NULL)? "" : r2_node->details->id),
749 reason);
750 if (r1_nodes != NULL) {
751 g_hash_table_destroy(r1_nodes);
752 }
753 if (r2_nodes != NULL) {
754 g_hash_table_destroy(r2_nodes);
755 }
756 return rc;
757}
758
765void
767{
768 GList *nodes = g_list_copy(scheduler->nodes);
769
770 nodes = pcmk__sort_nodes(nodes, NULL);
771 scheduler->resources = g_list_sort_with_data(scheduler->resources,
772 cmp_resources, nodes);
773 g_list_free(nodes);
774}
#define PCMK_ACTION_STOP
Definition actions.h:75
#define PCMK_ACTION_START
Definition actions.h:72
@ pcmk_action_runnable
Definition actions.h:207
@ pcmk_action_optional
Definition actions.h:210
#define pcmk__clear_action_flags(action, flags_to_clear)
#define PCMK__NELEM(a)
Definition internal.h:48
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:98
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
Definition complex.c:1007
char data[0]
Definition cpg.c:10
uint32_t id
Definition cpg.c:0
@ pcmk__fc_effective
@ pcmk__fc_fillers
G_GNUC_INTERNAL void pcmk__consume_node_capacity(GHashTable *current_utilization, const pcmk_resource_t *rsc)
G_GNUC_INTERNAL enum pcmk__coloc_affects pcmk__colocation_affects(const pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool preview)
G_GNUC_INTERNAL void pcmk__primitive_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL void pcmk__bundle_shutdown_lock(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__primitive_shutdown_lock(pcmk_resource_t *rsc)
G_GNUC_INTERNAL bool pcmk__clone_create_probe(pcmk_resource_t *rsc, pcmk_node_t *node)
@ pcmk__coloc_select_this_with
G_GNUC_INTERNAL GList * pcmk__group_colocated_resources(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
G_GNUC_INTERNAL int pcmk__primitive_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL uint32_t pcmk__group_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
G_GNUC_INTERNAL void pcmk__group_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__primitive_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__output_bundle_actions(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__with_primitive_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__primitive_create_actions(pcmk_resource_t *rsc)
G_GNUC_INTERNAL pcmk_node_t * pcmk__bundle_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__clone_internal_constraints(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__bundle_apply_location(pcmk_resource_t *rsc, pcmk__location_t *constraint)
G_GNUC_INTERNAL uint32_t pcmk__primitive_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
G_GNUC_INTERNAL int pcmk__group_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__bundle_create_actions(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__bundle_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL int pcmk__bundle_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL uint32_t pcmk__update_ordered_actions(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL uint32_t pcmk__group_update_ordered_actions(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL pcmk_node_t * pcmk__group_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__clone_create_actions(pcmk_resource_t *rsc)
@ pcmk__coloc_affects_location
G_GNUC_INTERNAL void pcmk__group_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL void pcmk__clone_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL uint32_t pcmk__clone_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
G_GNUC_INTERNAL GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__bundle_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
G_GNUC_INTERNAL pcmk_node_t * pcmk__primitive_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__with_clone_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__clone_add_graph_meta(const pcmk_resource_t *rsc, xmlNode *xml)
G_GNUC_INTERNAL void pcmk__primitive_add_graph_meta(const pcmk_resource_t *rsc, xmlNode *xml)
G_GNUC_INTERNAL uint32_t pcmk__instance_update_ordered_actions(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL void pcmk__clone_apply_location(pcmk_resource_t *rsc, pcmk__location_t *constraint)
G_GNUC_INTERNAL void pcmk__clone_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pcmk_node_t *active_node)
G_GNUC_INTERNAL void pcmk__group_create_actions(pcmk_resource_t *rsc)
G_GNUC_INTERNAL pcmk_node_t * pcmk__clone_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__clone_add_actions_to_graph(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__bundle_internal_constraints(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__bundle_add_actions_to_graph(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__primitive_internal_constraints(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_colocated_node_scores(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
G_GNUC_INTERNAL void pcmk__with_bundle_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__group_apply_location(pcmk_resource_t *rsc, pcmk__location_t *location)
G_GNUC_INTERNAL void pcmk__group_internal_constraints(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__with_group_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
G_GNUC_INTERNAL void pcmk__clone_shutdown_lock(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__group_shutdown_lock(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__apply_location(pcmk_resource_t *rsc, pcmk__location_t *constraint)
G_GNUC_INTERNAL bool pcmk__bundle_create_probe(pcmk_resource_t *rsc, pcmk_node_t *node)
G_GNUC_INTERNAL int pcmk__clone_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL void pcmk__release_node_capacity(GHashTable *current_utilization, const pcmk_resource_t *rsc)
G_GNUC_INTERNAL bool pcmk__node_available(const pcmk_node_t *node, bool consider_score, bool consider_guest)
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pcmk_resource_t *rsc)
G_GNUC_INTERNAL bool pcmk__probe_rsc_on_node(pcmk_resource_t *rsc, pcmk_node_t *node)
G_GNUC_INTERNAL void pcmk__group_add_colocated_node_scores(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
G_GNUC_INTERNAL uint32_t pcmk__bundle_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
#define crm_info(fmt, args...)
Definition logging.h:397
#define CRM_XS
Definition logging.h:56
#define crm_notice(fmt, args...)
Definition logging.h:395
#define CRM_CHECK(expr, failure_action)
Definition logging.h:245
#define crm_trace(fmt, args...)
Definition logging.h:402
pcmk_scheduler_t * scheduler
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition nvpair.c:446
#define PCMK_META_INTERVAL
Definition options.h:91
#define PCMK_META_MIGRATION_THRESHOLD
Definition options.h:95
#define PCMK__META_OP_TARGET_RC
pcmk__action_result_t result
Definition pcmk_fence.c:35
GList * pcmk__rscs_matching_id(const char *id, const pcmk_scheduler_t *scheduler)
GList * pcmk__colocated_resources(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
bool pcmk__threshold_reached(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_resource_t **failed)
bool pcmk__assign_resource(pcmk_resource_t *rsc, pcmk_node_t *node, bool force, bool stop_if_fail)
bool pcmk__rsc_agent_changed(pcmk_resource_t *rsc, pcmk_node_t *node, const xmlNode *rsc_entry, bool active_on_node)
void pcmk__output_resource_actions(pcmk_resource_t *rsc)
void pcmk__sort_resources(pcmk_scheduler_t *scheduler)
void pcmk__unassign_resource(pcmk_resource_t *rsc)
void pcmk__noop_add_graph_meta(const pcmk_resource_t *rsc, xmlNode *xml)
void pcmk__set_assignment_methods(pcmk_scheduler_t *scheduler)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
Definition utils.c:89
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
Definition internal.h:176
#define stop_key(rsc)
Definition internal.h:213
int pe_get_failcount(const pcmk_node_t *node, pcmk_resource_t *rsc, time_t *last_failure, uint32_t flags, const xmlNode *xml_op)
Definition failcounts.c:361
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition complex.c:1253
pcmk_action_t * custom_action(pcmk_resource_t *rsc, char *key, const char *task, const pcmk_node_t *on_node, gboolean optional, pcmk_scheduler_t *scheduler)
Create or update an action object.
void trigger_unfencing(pcmk_resource_t *rsc, pcmk_node_t *node, const char *reason, pcmk_action_t *dependency, pcmk_scheduler_t *scheduler)
Definition utils.c:591
@ pcmk_rsc_unassigned
Definition resources.h:109
@ pcmk_rsc_unique
Definition resources.h:100
@ pcmk_rsc_removed
Definition resources.h:85
@ pcmk_rsc_start_pending
Definition resources.h:142
@ pcmk_rsc_ignore_failure
Definition resources.h:160
#define CRM_ASSERT(expr)
Definition results.h:42
@ PCMK_OCF_NOT_RUNNING
Service safely stopped.
Definition results.h:190
@ pcmk_role_started
Started.
Definition roles.h:37
@ pcmk_role_stopped
Stopped.
Definition roles.h:36
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
@ pcmk_sched_show_utilization
Definition scheduler.h:176
#define pcmk__rsc_trace(rsc, fmt, args...)
#define pcmk__sched_warn(fmt...)
#define pcmk__rsc_debug(rsc, fmt, args...)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition scores.c:86
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
Definition scores.h:24
#define pcmk__plural_s(i)
@ pcmk__str_none
@ pcmk__str_null_matches
pcmk_resource_t * primary
pcmk_resource_t * dependent
This structure contains everything that makes up a single output formatter.
int(* message)(pcmk__output_t *out, const char *message_id,...)
char * uuid
Definition actions.h:344
char * task
Definition actions.h:343
GHashTable * meta
Definition actions.h:354
int weight
Definition nodes.h:162
int count
Definition nodes.h:164
struct pe_node_shared_s * details
Definition nodes.h:167
int num_resources
Definition nodes.h:132
const char * id
Definition nodes.h:72
GHashTable * utilization
Definition nodes.h:143
GList * allocated_rsc
Definition nodes.h:141
pcmk_assignment_methods_t * cmds
Definition resources.h:413
GList * running_on
Definition resources.h:456
GList * actions
Definition resources.h:444
enum pe_obj_types variant
Definition resources.h:410
GList * children
Definition resources.h:471
pcmk_scheduler_t * cluster
Definition resources.h:408
int migration_threshold
Definition resources.h:422
char * clone_name
Definition resources.h:397
pcmk_node_t * allocated_to
Definition resources.h:447
xmlNode * xml
Definition resources.h:400
unsigned long long flags
Definition resources.h:428
enum rsc_role_e role
Definition resources.h:464
GList * resources
Definition scheduler.h:231
unsigned long long flags
Definition scheduler.h:211
GList *(* colocated_resources)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
void(* output_actions)(pcmk_resource_t *rsc)
void(* add_colocated_node_scores)(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
Wrappers for and extensions to libxml2.
#define PCMK_XA_CLASS
Definition xml_names.h:241
#define PCMK_XA_PROVIDER
Definition xml_names.h:359
#define PCMK_XA_TYPE
Definition xml_names.h:425