pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_sched_clone.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-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 <crm/common/xml.h>
13#include <pacemaker-internal.h>
14
16
38 bool stop_if_fail)
39{
40 GList *colocations = NULL;
41
42 CRM_ASSERT(pcmk__is_clone(rsc));
43
45 return NULL; // Assignment has already been done
46 }
47
48 // Detect assignment loops
50 pcmk__rsc_debug(rsc, "Breaking assignment loop involving %s", rsc->id);
51 return NULL;
52 }
54
55 // If this clone is promotable, consider nodes' promotion scores
58 }
59
60 // If this clone is colocated with any other resources, assign those first
61 colocations = pcmk__this_with_colocations(rsc);
62 for (GList *iter = colocations; iter != NULL; iter = iter->next) {
63 pcmk__colocation_t *constraint = (pcmk__colocation_t *) iter->data;
64
65 pcmk__rsc_trace(rsc, "%s: Assigning colocation %s primary %s first",
66 rsc->id, constraint->id, constraint->primary->id);
67 constraint->primary->cmds->assign(constraint->primary, prefer,
68 stop_if_fail);
69 }
70 g_list_free(colocations);
71
72 // If any resources are colocated with this one, consider their preferences
73 colocations = pcmk__with_this_colocations(rsc);
74 g_list_foreach(colocations, pcmk__add_dependent_scores, rsc);
75 g_list_free(colocations);
76
79 rsc, __func__, rsc->allowed_nodes, rsc->cluster);
80
81 rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance);
84
87 }
88
90 pcmk__rsc_trace(rsc, "Assigned clone %s", rsc->id);
91 return NULL;
92}
93
100void
102{
103 CRM_ASSERT(pcmk__is_clone(rsc));
104
105 pcmk__rsc_trace(rsc, "Creating actions for clone %s", rsc->id);
109 }
110}
111
118void
120{
121 bool ordered = false;
122
123 CRM_ASSERT(pcmk__is_clone(rsc));
124
125 pcmk__rsc_trace(rsc, "Creating internal constraints for clone %s", rsc->id);
126
127 // Restart ordering: Stop -> stopped -> start -> started
137
138 // Demoted -> stop and started -> promote
141 rsc, PCMK_ACTION_STOP,
146 }
147
148 ordered = pe__clone_is_ordered(rsc);
149 if (ordered) {
150 /* Ordered clone instances must start and stop by instance number. The
151 * instances might have been previously shuffled for assignment or
152 * promotion purposes, so re-sort them.
153 */
154 rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance_number);
155 }
156 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
157 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
158
159 instance->cmds->internal_constraints(instance);
160
161 // Start clone -> start instance -> clone started
167
168 // Stop clone -> stop instance -> clone stopped
173
174 /* Instances of ordered clones must be started and stopped by instance
175 * number. Since only some instances may be starting or stopping, order
176 * each instance relative to every later instance.
177 */
178 if (ordered) {
179 for (GList *later = iter->next;
180 later != NULL; later = later->next) {
181 pcmk__order_starts(instance, (pcmk_resource_t *) later->data,
183 pcmk__order_stops((pcmk_resource_t *) later->data, instance,
185 }
186 }
187 }
190 }
191}
192
201static bool
202can_interleave(const pcmk__colocation_t *colocation)
203{
204 const pcmk_resource_t *dependent = colocation->dependent;
205
206 // Only colocations between clone or bundle resources use interleaving
207 if (dependent->variant <= pcmk_rsc_variant_group) {
208 return false;
209 }
210
211 // Only the dependent needs to be marked for interleaving
212 if (!crm_is_true(g_hash_table_lookup(dependent->meta,
214 return false;
215 }
216
217 /* @TODO Do we actually care about multiple primary instances sharing a
218 * dependent instance?
219 */
220 if (dependent->fns->max_per_node(dependent)
221 != colocation->primary->fns->max_per_node(colocation->primary)) {
222 pcmk__config_err("Cannot interleave %s and %s because they do not "
223 "support the same number of instances per node",
224 dependent->id, colocation->primary->id);
225 return false;
226 }
227
228 return true;
229}
230
246int
248 const pcmk_resource_t *primary,
249 const pcmk__colocation_t *colocation,
250 bool for_dependent)
251{
252 const GList *iter = NULL;
253 int priority_delta = 0;
254
255 /* This should never be called for the clone itself as a dependent. Instead,
256 * we add its colocation constraints to its instances and call the
257 * apply_coloc_score() method for the instances as dependents.
258 */
259 CRM_ASSERT(!for_dependent);
260
261 CRM_ASSERT((colocation != NULL) && pcmk__is_clone(primary)
262 && pcmk__is_primitive(dependent));
263
264 if (pcmk_is_set(primary->flags, pcmk_rsc_unassigned)) {
265 pcmk__rsc_trace(primary,
266 "Delaying processing colocation %s "
267 "because cloned primary %s is still provisional",
268 colocation->id, primary->id);
269 return 0;
270 }
271
272 pcmk__rsc_trace(primary, "Processing colocation %s (%s with clone %s @%s)",
273 colocation->id, dependent->id, primary->id,
274 pcmk_readable_score(colocation->score));
275
276 // Apply role-specific colocations
278 && (colocation->primary_role != pcmk_role_unknown)) {
279
280 if (pcmk_is_set(dependent->flags, pcmk_rsc_unassigned)) {
281 // We're assigning the dependent to a node
283 colocation);
284 return 0;
285 }
286
287 if (colocation->dependent_role == pcmk_role_promoted) {
288 // We're choosing a role for the dependent
290 dependent,
291 colocation);
292 }
293 }
294
295 // Apply interleaved colocations
296 if (can_interleave(colocation)) {
297 const pcmk_resource_t *primary_instance = NULL;
298
299 primary_instance = pcmk__find_compatible_instance(dependent, primary,
301 false);
302 if (primary_instance != NULL) {
303 pcmk__rsc_debug(primary, "Interleaving %s with %s",
304 dependent->id, primary_instance->id);
305
306 return dependent->cmds->apply_coloc_score(dependent,
307 primary_instance,
308 colocation, true);
309 }
310
311 if (colocation->score >= PCMK_SCORE_INFINITY) {
312 crm_notice("%s cannot run because it cannot interleave with "
313 "any instance of %s", dependent->id, primary->id);
314 pcmk__assign_resource(dependent, NULL, true, true);
315
316 } else {
317 pcmk__rsc_debug(primary,
318 "%s will not colocate with %s "
319 "because no instance can interleave with it",
320 dependent->id, primary->id);
321 }
322
323 return 0;
324 }
325
326 // Apply mandatory colocations
327 if (colocation->score >= PCMK_SCORE_INFINITY) {
328 GList *primary_nodes = NULL;
329
330 // Dependent can run only where primary will have unblocked instances
331 for (iter = primary->children; iter != NULL; iter = iter->next) {
332 const pcmk_resource_t *instance = iter->data;
333 pcmk_node_t *chosen = instance->fns->location(instance, NULL, 0);
334
335 if ((chosen != NULL)
336 && !is_set_recursive(instance, pcmk_rsc_blocked, TRUE)) {
337 pcmk__rsc_trace(primary, "Allowing %s: %s %d",
338 colocation->id, pcmk__node_name(chosen),
339 chosen->weight);
340 primary_nodes = g_list_prepend(primary_nodes, chosen);
341 }
342 }
343 pcmk__colocation_intersect_nodes(dependent, primary, colocation,
344 primary_nodes, false);
345 g_list_free(primary_nodes);
346 return 0;
347 }
348
349 // Apply optional colocations
350 for (iter = primary->children; iter != NULL; iter = iter->next) {
351 const pcmk_resource_t *instance = iter->data;
352 int instance_delta = instance->cmds->apply_coloc_score(dependent,
353 instance,
354 colocation,
355 false);
356
357 priority_delta = pcmk__add_scores(priority_delta, instance_delta);
358 }
359 return priority_delta;
360}
361
362// Clone implementation of pcmk_assignment_methods_t:with_this_colocations()
363void
365 const pcmk_resource_t *orig_rsc, GList **list)
366{
367 CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
368
369 pcmk__add_with_this_list(list, rsc->rsc_cons_lhs, orig_rsc);
370
371 if (rsc->parent != NULL) {
372 rsc->parent->cmds->with_this_colocations(rsc->parent, orig_rsc, list);
373 }
374}
375
376// Clone implementation of pcmk_assignment_methods_t:this_with_colocations()
377void
379 const pcmk_resource_t *orig_rsc, GList **list)
380{
381 CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
382
383 pcmk__add_this_with_list(list, rsc->rsc_cons, orig_rsc);
384
385 if (rsc->parent != NULL) {
386 rsc->parent->cmds->this_with_colocations(rsc->parent, orig_rsc, list);
387 }
388}
389
399uint32_t
401{
402 CRM_ASSERT((action != NULL) && pcmk__is_clone(action->rsc));
403
404 return pcmk__collective_action_flags(action, action->rsc->children, node);
405}
406
414void
416{
417 CRM_CHECK((location != NULL) && pcmk__is_clone(rsc), return);
418
419 pcmk__apply_location(rsc, location);
420
421 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
422 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
423
424 instance->cmds->apply_location(instance, location);
425 }
426}
427
428// GFunc wrapper for calling the action_flags() resource method
429static void
430call_action_flags(gpointer data, gpointer user_data)
431{
432 pcmk_resource_t *rsc = user_data;
433
434 rsc->cmds->action_flags((pcmk_action_t *) data, NULL);
435}
436
443void
445{
446 CRM_ASSERT(pcmk__is_clone(rsc));
447
448 g_list_foreach(rsc->actions, call_action_flags, rsc);
450
451 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
452 pcmk_resource_t *child_rsc = (pcmk_resource_t *) iter->data;
453
454 child_rsc->cmds->add_actions_to_graph(child_rsc);
455 }
456
459}
460
471static bool
472rsc_probed_on(const pcmk_resource_t *rsc, const pcmk_node_t *node)
473{
474 if (rsc->children != NULL) {
475 for (GList *child_iter = rsc->children; child_iter != NULL;
476 child_iter = child_iter->next) {
477
478 pcmk_resource_t *child = (pcmk_resource_t *) child_iter->data;
479
480 if (rsc_probed_on(child, node)) {
481 return true;
482 }
483 }
484 return false;
485 }
486
487 if (rsc->known_on != NULL) {
488 GHashTableIter iter;
489 pcmk_node_t *known_node = NULL;
490
491 g_hash_table_iter_init(&iter, rsc->known_on);
492 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &known_node)) {
493 if (pcmk__same_node(node, known_node)) {
494 return true;
495 }
496 }
497 }
498 return false;
499}
500
511static pcmk_resource_t *
512find_probed_instance_on(const pcmk_resource_t *clone, const pcmk_node_t *node)
513{
514 for (GList *iter = clone->children; iter != NULL; iter = iter->next) {
515 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
516
517 if (rsc_probed_on(instance, node)) {
518 return instance;
519 }
520 }
521 return NULL;
522}
523
531static bool
532probe_anonymous_clone(pcmk_resource_t *clone, pcmk_node_t *node)
533{
534 // Check whether we already probed an instance on this node
535 pcmk_resource_t *child = find_probed_instance_on(clone, node);
536
537 // Otherwise, check if we plan to start an instance on this node
538 for (GList *iter = clone->children; (iter != NULL) && (child == NULL);
539 iter = iter->next) {
540 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
541 const pcmk_node_t *instance_node = NULL;
542
543 instance_node = instance->fns->location(instance, NULL, 0);
544 if (pcmk__same_node(instance_node, node)) {
545 child = instance;
546 }
547 }
548
549 // Otherwise, use the first clone instance
550 if (child == NULL) {
551 child = clone->children->data;
552 }
553
554 // Anonymous clones only need to probe a single instance
555 return child->cmds->create_probe(child, node);
556}
557
567bool
569{
570 CRM_ASSERT((node != NULL) && pcmk__is_clone(rsc));
571
572 if (rsc->exclusive_discover) {
573 /* The clone is configured to be probed only where a location constraint
574 * exists with PCMK_XA_RESOURCE_DISCOVERY set to exclusive.
575 *
576 * This check is not strictly necessary here since the instance's
577 * create_probe() method would also check, but doing it here is more
578 * efficient (especially for unique clones with a large number of
579 * instances), and affects the CRM_meta_notify_available_uname variable
580 * passed with notify actions.
581 */
582 pcmk_node_t *allowed = g_hash_table_lookup(rsc->allowed_nodes,
583 node->details->id);
584
585 if ((allowed == NULL)
586 || (allowed->rsc_discover_mode != pcmk_probe_exclusive)) {
587 /* This node is not marked for resource discovery. Remove it from
588 * allowed_nodes so that notifications contain only nodes that the
589 * clone can possibly run on.
590 */
591 pcmk__rsc_trace(rsc,
592 "Skipping probe for %s on %s because resource has "
593 "exclusive discovery but is not allowed on node",
594 rsc->id, pcmk__node_name(node));
595 g_hash_table_remove(rsc->allowed_nodes, node->details->id);
596 return false;
597 }
598 }
599
600 rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance_number);
601 if (pcmk_is_set(rsc->flags, pcmk_rsc_unique)) {
602 return pcmk__probe_resource_list(rsc->children, node);
603 } else {
604 return probe_anonymous_clone(rsc, node);
605 }
606}
607
617void
619{
620 char *name = NULL;
621
622 CRM_ASSERT(pcmk__is_clone(rsc) && (xml != NULL));
623
625 crm_xml_add(xml, name, pcmk__flag_text(rsc->flags, pcmk_rsc_unique));
626 free(name);
627
629 crm_xml_add(xml, name, pcmk__flag_text(rsc->flags, pcmk_rsc_notify));
630 free(name);
631
634 free(name);
635
638 free(name);
639
641 int promoted_max = pe__clone_promoted_max(rsc);
642 int promoted_node_max = pe__clone_promoted_node_max(rsc);
643
645 crm_xml_add_int(xml, name, promoted_max);
646 free(name);
647
649 crm_xml_add_int(xml, name, promoted_node_max);
650 free(name);
651
652 /* @COMPAT Maintain backward compatibility with resource agents that
653 * expect the old names (deprecated since 2.0.0).
654 */
656 crm_xml_add_int(xml, name, promoted_max);
657 free(name);
658
660 crm_xml_add_int(xml, name, promoted_node_max);
661 free(name);
662 }
663}
664
665// Clone implementation of pcmk_assignment_methods_t:add_utilization()
666void
668 const pcmk_resource_t *orig_rsc, GList *all_rscs,
669 GHashTable *utilization)
670{
671 bool existing = false;
672 pcmk_resource_t *child = NULL;
673
674 CRM_ASSERT(pcmk__is_clone(rsc) && (orig_rsc != NULL)
675 && (utilization != NULL));
676
678 return;
679 }
680
681 // Look for any child already existing in the list
682 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
683 child = (pcmk_resource_t *) iter->data;
684 if (g_list_find(all_rscs, child)) {
685 existing = true; // Keep checking remaining children
686 } else {
687 // If this is a clone of a group, look for group's members
688 for (GList *member_iter = child->children; member_iter != NULL;
689 member_iter = member_iter->next) {
690
691 pcmk_resource_t *member = (pcmk_resource_t *) member_iter->data;
692
693 if (g_list_find(all_rscs, member) != NULL) {
694 // Add *child's* utilization, not group member's
695 child->cmds->add_utilization(child, orig_rsc, all_rscs,
696 utilization);
697 existing = true;
698 break;
699 }
700 }
701 }
702 }
703
704 if (!existing && (rsc->children != NULL)) {
705 // If nothing was found, still add first child's utilization
706 child = (pcmk_resource_t *) rsc->children->data;
707
708 child->cmds->add_utilization(child, orig_rsc, all_rscs, utilization);
709 }
710}
711
712// Clone implementation of pcmk_assignment_methods_t:shutdown_lock()
713void
715{
716 CRM_ASSERT(pcmk__is_clone(rsc));
717 return; // Clones currently don't support shutdown locks
718}
@ pcmk__ar_then_implies_first_graphed
If 'then' is required, 'first' must be added to the transition graph.
@ pcmk__ar_first_implies_then_graphed
If 'first' is required and runnable, 'then' must be in graph.
@ pcmk__ar_unrunnable_first_blocks
'then' is runnable (and migratable) only if 'first' is runnable
@ pcmk__ar_ordered
Actions are ordered (optionally, if no other flags are set)
#define PCMK_ACTION_STOP
Definition actions.h:75
#define PCMK_ACTION_RUNNING
Definition actions.h:71
#define PCMK_ACTION_PROMOTE
Definition actions.h:66
#define PCMK_ACTION_START
Definition actions.h:72
#define PCMK_ACTION_STOPPED
Definition actions.h:76
#define PCMK_ACTION_DEMOTED
Definition actions.h:50
const char * name
Definition cib.c:26
gboolean crm_is_true(const char *s)
Definition strings.c:488
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:98
char data[0]
Definition cpg.c:10
G_GNUC_INTERNAL void pcmk__add_this_with_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
#define pcmk__order_starts(rsc1, rsc2, flags)
G_GNUC_INTERNAL void pcmk__colocation_intersect_nodes(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, const GList *primary_nodes, bool merge_scores)
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
G_GNUC_INTERNAL void pcmk__assign_instances(pcmk_resource_t *collective, GList *instances, int max_total, int max_per_node)
G_GNUC_INTERNAL uint32_t pcmk__collective_action_flags(pcmk_action_t *action, const GList *instances, const pcmk_node_t *node)
G_GNUC_INTERNAL gint pcmk__cmp_instance_number(gconstpointer a, gconstpointer b)
G_GNUC_INTERNAL bool pcmk__assign_resource(pcmk_resource_t *rsc, pcmk_node_t *node, bool force, bool stop_if_fail)
G_GNUC_INTERNAL void pcmk__create_promotable_actions(pcmk_resource_t *clone)
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_compatible_instance(const pcmk_resource_t *match_rsc, const pcmk_resource_t *rsc, enum rsc_role_e role, bool current)
G_GNUC_INTERNAL GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
G_GNUC_INTERNAL gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
G_GNUC_INTERNAL void pcmk__order_promotable_instances(pcmk_resource_t *clone)
G_GNUC_INTERNAL void pcmk__add_with_this_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
G_GNUC_INTERNAL int pcmk__update_promotable_dependent_priority(const pcmk_resource_t *primary, pcmk_resource_t *dependent, const pcmk__colocation_t *colocation)
G_GNUC_INTERNAL bool pcmk__probe_resource_list(GList *rscs, pcmk_node_t *node)
G_GNUC_INTERNAL void pcmk__add_dependent_scores(gpointer data, gpointer user_data)
G_GNUC_INTERNAL GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__set_instance_roles(pcmk_resource_t *rsc)
#define pcmk__order_stops(rsc1, rsc2, flags)
G_GNUC_INTERNAL void pcmk__create_instance_actions(pcmk_resource_t *rsc, GList *instances)
G_GNUC_INTERNAL void pcmk__apply_location(pcmk_resource_t *rsc, pcmk__location_t *constraint)
G_GNUC_INTERNAL void pcmk__add_promotion_scores(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pcmk_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__update_dependent_with_promotable(const pcmk_resource_t *primary, pcmk_resource_t *dependent, const pcmk__colocation_t *colocation)
Update dependent for a colocation with a promotable clone.
#define crm_notice(fmt, args...)
Definition logging.h:395
#define CRM_CHECK(expr, failure_action)
Definition logging.h:245
#define pcmk__config_err(fmt...)
@ pcmk_probe_exclusive
Definition nodes.h:57
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:348
char * crm_meta_name(const char *field)
Get the environment variable equivalent of a meta-attribute name.
Definition nvpair.c:959
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:301
#define PCMK_META_CLONE_NODE_MAX
Definition options.h:84
#define PCMK_META_PROMOTED_MAX
Definition options.h:102
#define PCMK_META_CLONE_MAX
Definition options.h:82
#define PCMK_META_INTERLEAVE
Definition options.h:90
#define PCMK_META_NOTIFY
Definition options.h:97
#define PCMK_META_GLOBALLY_UNIQUE
Definition options.h:89
#define PCMK_META_PROMOTED_NODE_MAX
Definition options.h:103
#define PCMK__META_PROMOTED_MAX_LEGACY
#define PCMK__META_PROMOTED_NODE_MAX_LEGACY
const char * action
Definition pcmk_fence.c:30
void pcmk__clone_add_graph_meta(const pcmk_resource_t *rsc, xmlNode *xml)
void pcmk__clone_create_actions(pcmk_resource_t *rsc)
void pcmk__clone_internal_constraints(pcmk_resource_t *rsc)
uint32_t pcmk__clone_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
void pcmk__clone_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
int pcmk__clone_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
void pcmk__with_clone_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
void pcmk__clone_shutdown_lock(pcmk_resource_t *rsc)
pcmk_node_t * pcmk__clone_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
bool pcmk__clone_create_probe(pcmk_resource_t *rsc, pcmk_node_t *node)
void pcmk__clone_apply_location(pcmk_resource_t *rsc, pcmk__location_t *location)
void pcmk__clone_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
void pcmk__clone_add_actions_to_graph(pcmk_resource_t *rsc)
bool is_set_recursive(const pcmk_resource_t *rsc, long long flag, bool any)
Definition clone.c:588
void pe__create_clone_notifications(pcmk_resource_t *clone)
Definition clone.c:1470
int pe__clone_promoted_node_max(const pcmk_resource_t *clone)
Definition clone.c:114
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
Definition internal.h:176
int pe__clone_max(const pcmk_resource_t *clone)
Definition clone.c:63
bool pe__clone_is_ordered(const pcmk_resource_t *clone)
Definition clone.c:1344
int pe__clone_node_max(const pcmk_resource_t *clone)
Definition clone.c:80
int pe__clone_promoted_max(const pcmk_resource_t *clone)
Definition clone.c:97
void pe__free_clone_notification_data(pcmk_resource_t *clone)
Definition clone.c:1489
@ pcmk_rsc_variant_group
Definition resources.h:38
@ pcmk_rsc_promotable
Definition resources.h:106
@ pcmk_rsc_unassigned
Definition resources.h:109
@ pcmk_rsc_assigning
Definition resources.h:112
@ pcmk_rsc_unique
Definition resources.h:100
@ pcmk_rsc_notify
Definition resources.h:97
@ pcmk_rsc_blocked
Definition resources.h:91
#define CRM_ASSERT(expr)
Definition results.h:42
@ pcmk_role_unknown
Resource role is unknown.
Definition roles.h:35
@ pcmk_role_promoted
Promoted.
Definition roles.h:39
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
@ pcmk_sched_output_scores
Definition scheduler.h:173
#define pcmk__rsc_trace(rsc, fmt, args...)
#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
int pcmk__add_scores(int score1, int score2)
Definition scores.c:116
pcmk_resource_t * primary
pcmk_resource_t * dependent
Location constraint object.
int weight
Definition nodes.h:162
int rsc_discover_mode
Definition nodes.h:170
struct pe_node_shared_s * details
Definition nodes.h:167
const char * id
Definition nodes.h:72
pcmk_assignment_methods_t * cmds
Definition resources.h:413
GList * actions
Definition resources.h:444
enum pe_obj_types variant
Definition resources.h:410
GHashTable * meta
Definition resources.h:467
GList * rsc_cons
Definition resources.h:442
GList * rsc_cons_lhs
Definition resources.h:441
GList * children
Definition resources.h:471
pcmk_scheduler_t * cluster
Definition resources.h:408
gboolean exclusive_discover
Definition resources.h:432
pcmk_rsc_methods_t * fns
Definition resources.h:412
GHashTable * known_on
Definition resources.h:459
GHashTable * allowed_nodes
Definition resources.h:462
unsigned long long flags
Definition resources.h:428
pcmk_resource_t * parent
Definition resources.h:409
unsigned long long flags
Definition scheduler.h:211
void(* add_utilization)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void(* add_actions_to_graph)(pcmk_resource_t *rsc)
void(* this_with_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
int(* apply_coloc_score)(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
uint32_t(* action_flags)(pcmk_action_t *action, const pcmk_node_t *node)
bool(* create_probe)(pcmk_resource_t *rsc, pcmk_node_t *node)
void(* with_this_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
void(* internal_constraints)(pcmk_resource_t *rsc)
pcmk_node_t *(* assign)(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
void(* apply_location)(pcmk_resource_t *rsc, pcmk__location_t *location)
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
Definition resources.h:328
unsigned int(* max_per_node)(const pcmk_resource_t *rsc)
Definition resources.h:384
Wrappers for and extensions to libxml2.