pacemaker 3.0.1-16e74fc4da
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->priv->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->priv->scheduler);
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->priv->scheduler);
142 }
143 return changed;
144}
145
156static GList *
157add_rsc_if_matching(GList *result, pcmk_resource_t *rsc, const char *id)
158{
159 if (pcmk__str_eq(id, rsc->id, pcmk__str_none)
160 || pcmk__str_eq(id, rsc->priv->history_id, pcmk__str_none)) {
161 result = g_list_prepend(result, rsc);
162 }
163
164 for (GList *iter = rsc->priv->children;
165 iter != NULL; iter = iter->next) {
166
167 pcmk_resource_t *child = (pcmk_resource_t *) iter->data;
168
169 result = add_rsc_if_matching(result, child, id);
170 }
171 return result;
172}
173
185GList *
187{
188 GList *result = NULL;
189
190 CRM_CHECK((id != NULL) && (scheduler != NULL), return NULL);
191
192 for (GList *iter = scheduler->priv->resources;
193 iter != NULL; iter = iter->next) {
194
195 result = add_rsc_if_matching(result, (pcmk_resource_t *) iter->data,
196 id);
197 }
198 return result;
199}
200
208static void
209set_assignment_methods_for_rsc(gpointer data, gpointer user_data)
210{
211 pcmk_resource_t *rsc = data;
212
213 rsc->priv->cmds = &assignment_methods[rsc->priv->variant];
214 g_list_foreach(rsc->priv->children, set_assignment_methods_for_rsc,
215 NULL);
216}
217
224void
226{
227 g_list_foreach(scheduler->priv->resources, set_assignment_methods_for_rsc,
228 NULL);
229}
230
241static inline void
242add_colocated_resources(const pcmk_resource_t *rsc,
243 const pcmk_resource_t *orig_rsc, GList **list)
244{
245 *list = rsc->priv->cmds->colocated_resources(rsc, orig_rsc, *list);
246}
247
248// Shared implementation of pcmk__assignment_methods_t:colocated_resources()
249GList *
251 const pcmk_resource_t *orig_rsc,
252 GList *colocated_rscs)
253{
254 const GList *iter = NULL;
255 GList *colocations = NULL;
256
257 if (orig_rsc == NULL) {
258 orig_rsc = rsc;
259 }
260
261 if ((rsc == NULL) || (g_list_find(colocated_rscs, rsc) != NULL)) {
262 return colocated_rscs;
263 }
264
265 pcmk__rsc_trace(orig_rsc, "%s is in colocation chain with %s",
266 rsc->id, orig_rsc->id);
267 colocated_rscs = g_list_prepend(colocated_rscs, (gpointer) rsc);
268
269 // Follow colocations where this resource is the dependent resource
270 colocations = pcmk__this_with_colocations(rsc);
271 for (iter = colocations; iter != NULL; iter = iter->next) {
272 const pcmk__colocation_t *constraint = iter->data;
273 const pcmk_resource_t *primary = constraint->primary;
274
275 if (primary == orig_rsc) {
276 continue; // Break colocation loop
277 }
278
279 if ((constraint->score == PCMK_SCORE_INFINITY) &&
280 (pcmk__colocation_affects(rsc, primary, constraint,
282 add_colocated_resources(primary, orig_rsc, &colocated_rscs);
283 }
284 }
285 g_list_free(colocations);
286
287 // Follow colocations where this resource is the primary resource
288 colocations = pcmk__with_this_colocations(rsc);
289 for (iter = colocations; iter != NULL; iter = iter->next) {
290 const pcmk__colocation_t *constraint = iter->data;
291 const pcmk_resource_t *dependent = constraint->dependent;
292
293 if (dependent == orig_rsc) {
294 continue; // Break colocation loop
295 }
296
297 if (pcmk__is_clone(rsc) && !pcmk__is_clone(dependent)) {
298 continue; // We can't be sure whether dependent will be colocated
299 }
300
301 if ((constraint->score == PCMK_SCORE_INFINITY) &&
302 (pcmk__colocation_affects(dependent, rsc, constraint,
304 add_colocated_resources(dependent, orig_rsc, &colocated_rscs);
305 }
306 }
307 g_list_free(colocations);
308
309 return colocated_rscs;
310}
311
312// No-op function for variants that don't need to implement add_graph_meta()
313void
315{
316}
317
324void
326{
327 pcmk_node_t *next = NULL;
328 pcmk_node_t *current = NULL;
329 pcmk__output_t *out = NULL;
330
331 pcmk__assert(rsc != NULL);
332
333 out = rsc->priv->scheduler->priv->out;
334 if (rsc->priv->children != NULL) {
335
336 for (GList *iter = rsc->priv->children;
337 iter != NULL; iter = iter->next) {
338
339 pcmk_resource_t *child = (pcmk_resource_t *) iter->data;
340
341 child->priv->cmds->output_actions(child);
342 }
343 return;
344 }
345
346 next = rsc->priv->assigned_node;
347 if (rsc->priv->active_nodes != NULL) {
348 current = pcmk__current_node(rsc);
349 if (rsc->priv->orig_role == pcmk_role_stopped) {
350 /* This can occur when resources are being recovered because
351 * the current role can change in pcmk__primitive_create_actions()
352 */
354 }
355 }
356
357 if ((current == NULL) && pcmk_is_set(rsc->flags, pcmk__rsc_removed)) {
358 /* Don't log stopped orphans */
359 return;
360 }
361
362 out->message(out, "rsc-action", rsc, current, next);
363}
364
372static inline void
373add_assigned_resource(pcmk_node_t *node, pcmk_resource_t *rsc)
374{
375 node->priv->assigned_resources =
376 g_list_prepend(node->priv->assigned_resources, rsc);
377}
378
414bool
416 bool stop_if_fail)
417{
418 bool changed = false;
420
421 pcmk__assert(rsc != NULL);
422 scheduler = rsc->priv->scheduler;
423
424 if (rsc->priv->children != NULL) {
425
426 for (GList *iter = rsc->priv->children;
427 iter != NULL; iter = iter->next) {
428
429 pcmk_resource_t *child_rsc = iter->data;
430
431 changed |= pcmk__assign_resource(child_rsc, node, force,
432 stop_if_fail);
433 }
434 return changed;
435 }
436
437 // Assigning a primitive
438
439 if (!force && (node != NULL)
440 && ((node->assign->score < 0)
441 // Allow graph to assume that guest node connections will come up
442 || (!pcmk__node_available(node, true, false)
443 && !pcmk__is_guest_or_bundle_node(node)))) {
444
445 pcmk__rsc_debug(rsc,
446 "All nodes for resource %s are unavailable, unclean or "
447 "shutting down (%s can%s run resources, with score %s)",
448 rsc->id, pcmk__node_name(node),
449 (pcmk__node_available(node, true, false)? "" : "not"),
451
452 if (stop_if_fail) {
453 pe__set_next_role(rsc, pcmk_role_stopped, "node availability");
454 }
455 node = NULL;
456 }
457
458 if (rsc->priv->assigned_node != NULL) {
459 changed = !pcmk__same_node(rsc->priv->assigned_node, node);
460 } else {
461 changed = (node != NULL);
462 }
465
466 if (node == NULL) {
467 char *rc_stopped = NULL;
468
469 pcmk__rsc_debug(rsc, "Could not assign %s to a node", rsc->id);
470
471 if (!stop_if_fail) {
472 return changed;
473 }
474 pe__set_next_role(rsc, pcmk_role_stopped, "unable to assign");
475
476 for (GList *iter = rsc->priv->actions;
477 iter != NULL; iter = iter->next) {
478
479 pcmk_action_t *op = (pcmk_action_t *) iter->data;
480
481 pcmk__rsc_debug(rsc, "Updating %s for %s assignment failure",
482 op->uuid, rsc->id);
483
484 if (pcmk__str_eq(op->task, PCMK_ACTION_STOP, pcmk__str_none)) {
486
487 } else if (pcmk__str_eq(op->task, PCMK_ACTION_START,
490
491 } else {
492 // Cancel recurring actions, unless for stopped state
493 const char *interval_ms_s = NULL;
494 const char *target_rc_s = NULL;
495
496 interval_ms_s = g_hash_table_lookup(op->meta,
498 target_rc_s = g_hash_table_lookup(op->meta,
500 if (rc_stopped == NULL) {
501 rc_stopped = pcmk__itoa(PCMK_OCF_NOT_RUNNING);
502 }
503
504 if (!pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches)
505 && !pcmk__str_eq(rc_stopped, target_rc_s, pcmk__str_none)) {
506
508 }
509 }
510 }
511 free(rc_stopped);
512 return changed;
513 }
514
515 pcmk__rsc_debug(rsc, "Assigning %s to %s", rsc->id, pcmk__node_name(node));
516 rsc->priv->assigned_node = pe__copy_node(node);
517
518 add_assigned_resource(node, rsc);
519 node->priv->num_resources++;
520 node->assign->count++;
522
525
526 out->message(out, "resource-util", rsc, node, __func__);
527 }
528 return changed;
529}
530
542void
544{
545 pcmk_node_t *old = rsc->priv->assigned_node;
546
547 if (old == NULL) {
548 crm_info("Unassigning %s", rsc->id);
549 } else {
550 crm_info("Unassigning %s from %s", rsc->id, pcmk__node_name(old));
551 }
552
554
555 if (rsc->priv->children == NULL) {
556 if (old == NULL) {
557 return;
558 }
559 rsc->priv->assigned_node = NULL;
560
561 /* We're going to free the pcmk_node_t copy, but its priv member is
562 * shared and will remain, so update that appropriately first.
563 */
565 g_list_remove(old->priv->assigned_resources, rsc);
566 old->priv->num_resources--;
569 return;
570 }
571
572 for (GList *iter = rsc->priv->children;
573 iter != NULL; iter = iter->next) {
574
576 }
577}
578
590bool
592 pcmk_resource_t **failed)
593{
594 int fail_count, remaining_tries;
595 pcmk_resource_t *rsc_to_ban = rsc;
596
597 // Migration threshold of 0 means never force away
598 if (rsc->priv->ban_after_failures == 0) {
599 return false;
600 }
601
602 // If we're ignoring failures, also ignore the migration threshold
604 return false;
605 }
606
607 // If there are no failures, there's no need to force away
608 fail_count = pe_get_failcount(node, rsc, NULL,
610 if (fail_count <= 0) {
611 return false;
612 }
613
614 // If failed resource is anonymous clone instance, we'll force clone away
615 if (!pcmk_is_set(rsc->flags, pcmk__rsc_unique)) {
616 rsc_to_ban = uber_parent(rsc);
617 }
618
619 // How many more times recovery will be tried on this node
620 remaining_tries = rsc->priv->ban_after_failures - fail_count;
621
622 if (remaining_tries <= 0) {
624 "%s cannot run on %s due to reaching migration "
625 "threshold (clean up resource to allow again) "
626 QB_XS " failures=%d "
628 rsc_to_ban->id, pcmk__node_name(node), fail_count,
630 if (failed != NULL) {
631 *failed = rsc_to_ban;
632 }
633 return true;
634 }
635
636 crm_info("%s can fail %d more time%s on "
637 "%s before reaching migration threshold (%d)",
638 rsc_to_ban->id, remaining_tries, pcmk__plural_s(remaining_tries),
639 pcmk__node_name(node), rsc->priv->ban_after_failures);
640 return false;
641}
642
652static int
653get_node_score(const pcmk_node_t *node, GHashTable *nodes)
654{
655 pcmk_node_t *found_node = NULL;
656
657 if ((node != NULL) && (nodes != NULL)) {
658 found_node = g_hash_table_lookup(nodes, node->priv->id);
659 }
660 if (found_node == NULL) {
661 return -PCMK_SCORE_INFINITY;
662 }
663 return found_node->assign->score;
664}
665
677static gint
678cmp_resources(gconstpointer a, gconstpointer b, gpointer data)
679{
680 /* GLib insists that this function require gconstpointer arguments, but we
681 * make a small, temporary change to each argument (setting the
682 * pe_rsc_merging flag) during comparison
683 */
684 pcmk_resource_t *resource1 = (pcmk_resource_t *) a;
685 pcmk_resource_t *resource2 = (pcmk_resource_t *) b;
686 const GList *nodes = data;
687
688 int rc = 0;
689 int r1_score = -PCMK_SCORE_INFINITY;
690 int r2_score = -PCMK_SCORE_INFINITY;
691 pcmk_node_t *r1_node = NULL;
692 pcmk_node_t *r2_node = NULL;
693 GHashTable *r1_nodes = NULL;
694 GHashTable *r2_nodes = NULL;
695 const char *reason = NULL;
696
697 // Resources with highest priority should be assigned first
698 reason = "priority";
699 r1_score = resource1->priv->priority;
700 r2_score = resource2->priv->priority;
701 if (r1_score > r2_score) {
702 rc = -1;
703 goto done;
704 }
705 if (r1_score < r2_score) {
706 rc = 1;
707 goto done;
708 }
709
710 // We need nodes to make any other useful comparisons
711 reason = "no node list";
712 if (nodes == NULL) {
713 goto done;
714 }
715
716 // Calculate and log node scores
717 resource1->priv->cmds->add_colocated_node_scores(resource1, NULL,
718 resource1->id,
719 &r1_nodes, NULL, 1,
721 resource2->priv->cmds->add_colocated_node_scores(resource2, NULL,
722 resource2->id,
723 &r2_nodes, NULL, 1,
725 pe__show_node_scores(true, NULL, resource1->id, r1_nodes,
726 resource1->priv->scheduler);
727 pe__show_node_scores(true, NULL, resource2->id, r2_nodes,
728 resource2->priv->scheduler);
729
730 // The resource with highest score on its current node goes first
731 reason = "current location";
732 if (resource1->priv->active_nodes != NULL) {
733 r1_node = pcmk__current_node(resource1);
734 }
735 if (resource2->priv->active_nodes != NULL) {
736 r2_node = pcmk__current_node(resource2);
737 }
738 r1_score = get_node_score(r1_node, r1_nodes);
739 r2_score = get_node_score(r2_node, r2_nodes);
740 if (r1_score > r2_score) {
741 rc = -1;
742 goto done;
743 }
744 if (r1_score < r2_score) {
745 rc = 1;
746 goto done;
747 }
748
749 // Otherwise a higher score on any node will do
750 reason = "score";
751 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
752 const pcmk_node_t *node = (const pcmk_node_t *) iter->data;
753
754 r1_score = get_node_score(node, r1_nodes);
755 r2_score = get_node_score(node, r2_nodes);
756 if (r1_score > r2_score) {
757 rc = -1;
758 goto done;
759 }
760 if (r1_score < r2_score) {
761 rc = 1;
762 goto done;
763 }
764 }
765
766done:
767 crm_trace("%s (%d)%s%s %c %s (%d)%s%s: %s",
768 resource1->id, r1_score,
769 ((r1_node == NULL)? "" : " on "),
770 ((r1_node == NULL)? "" : r1_node->priv->id),
771 ((rc < 0)? '>' : ((rc > 0)? '<' : '=')),
772 resource2->id, r2_score,
773 ((r2_node == NULL)? "" : " on "),
774 ((r2_node == NULL)? "" : r2_node->priv->id),
775 reason);
776 if (r1_nodes != NULL) {
777 g_hash_table_destroy(r1_nodes);
778 }
779 if (r2_nodes != NULL) {
780 g_hash_table_destroy(r2_nodes);
781 }
782 return rc;
783}
784
791void
793{
794 GList *nodes = g_list_copy(scheduler->nodes);
795
796 nodes = pcmk__sort_nodes(nodes, NULL);
798 g_list_sort_with_data(scheduler->priv->resources, cmp_resources, nodes);
799 g_list_free(nodes);
800}
#define PCMK_ACTION_STOP
Definition actions.h:66
#define PCMK_ACTION_START
Definition actions.h:63
@ pcmk__action_runnable
@ pcmk__action_optional
#define pcmk__clear_action_flags(action, flags_to_clear)
#define PCMK__NELEM(a)
Definition internal.h:50
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:80
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
Definition complex.c:999
char data[0]
Definition cpg.c:10
@ pcmk__fc_launched
@ pcmk__fc_effective
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:365
#define crm_notice(fmt, args...)
Definition logging.h:363
#define CRM_CHECK(expr, failure_action)
Definition logging.h:213
#define crm_trace(fmt, args...)
Definition logging.h:370
pcmk_scheduler_t * scheduler
void pcmk__free_node_copy(void *data)
Definition nodes.c:64
#define PCMK_META_INTERVAL
Definition options.h:92
#define PCMK_META_MIGRATION_THRESHOLD
Definition options.h:96
#define PCMK__META_OP_TARGET_RC
pcmk__action_result_t result
Definition pcmk_fence.c:37
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:124
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
Definition internal.h:158
#define stop_key(rsc)
Definition internal.h:190
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:367
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition complex.c:1247
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:628
@ pcmk__rsc_unassigned
@ pcmk__rsc_unique
@ pcmk__rsc_removed
@ pcmk__rsc_ignore_failure
@ pcmk__rsc_start_pending
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
@ PCMK_OCF_NOT_RUNNING
Service safely stopped.
Definition results.h:186
#define pcmk__assert(expr)
@ pcmk_role_started
Started.
Definition roles.h:37
@ pcmk_role_stopped
Stopped.
Definition roles.h:36
#define pcmk__rsc_trace(rsc, fmt, args...)
#define pcmk__rsc_debug(rsc, fmt, args...)
#define pcmk__sched_warn(scheduler, fmt...)
@ pcmk__sched_show_utilization
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition scores.c:102
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
Definition scores.h:26
#define pcmk__plural_s(i)
@ pcmk__str_none
@ pcmk__str_null_matches
GHashTable * meta
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)
GList *(* colocated_resources)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
void(* output_actions)(pcmk_resource_t *rsc)
pcmk_resource_t * primary
pcmk_resource_t * dependent
GHashTable * utilization
This structure contains everything that makes up a single output formatter.
int(* message)(pcmk__output_t *out, const char *message_id,...)
pcmk_scheduler_t * scheduler
enum pcmk__rsc_variant variant
const pcmk__assignment_methods_t * cmds
unsigned long long flags
Definition resources.h:69
pcmk__resource_private_t * priv
Definition resources.h:61
pcmk__scheduler_private_t * priv
Definition scheduler.h:99
GList * nodes
Definition scheduler.h:97
uint64_t flags
Definition scheduler.h:89
pcmk__node_private_t * priv
Definition nodes.h:85
struct pcmk__node_assignment * assign
Definition nodes.h:79
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define PCMK_XA_CLASS
Definition xml_names.h:246
#define PCMK_XA_PROVIDER
Definition xml_names.h:364
#define PCMK_XA_TYPE
Definition xml_names.h:430