pacemaker 2.1.7-2.1.7
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-2023 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/msg_xml.h>
13#include <pacemaker-internal.h>
14
16
38 bool stop_if_fail)
39{
40 GList *colocations = NULL;
41
42 CRM_ASSERT(pe_rsc_is_clone(rsc));
43
45 return NULL; // Assignment has already been done
46 }
47
48 // Detect assignment loops
50 pe_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 pe_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 pe_rsc_trace(rsc, "Assigned clone %s", rsc->id);
91 return NULL;
92}
93
100void
102{
103 CRM_ASSERT(pe_rsc_is_clone(rsc));
104
105 pe_rsc_trace(rsc, "Creating actions for clone %s", rsc->id);
109 }
110}
111
118void
120{
121 bool ordered = false;
122
123 CRM_ASSERT(pe_rsc_is_clone(rsc));
124
125 pe_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
244void
246 const pcmk_resource_t *primary,
247 const pcmk__colocation_t *colocation,
248 bool for_dependent)
249{
250 const GList *iter = NULL;
251
252 /* This should never be called for the clone itself as a dependent. Instead,
253 * we add its colocation constraints to its instances and call the
254 * apply_coloc_score() method for the instances as dependents.
255 */
256 CRM_ASSERT(!for_dependent);
257
258 CRM_ASSERT((colocation != NULL) && pe_rsc_is_clone(primary)
259 && (dependent != NULL)
260 && (dependent->variant == pcmk_rsc_variant_primitive));
261
262 if (pcmk_is_set(primary->flags, pcmk_rsc_unassigned)) {
263 pe_rsc_trace(primary,
264 "Delaying processing colocation %s "
265 "because cloned primary %s is still provisional",
266 colocation->id, primary->id);
267 return;
268 }
269
270 pe_rsc_trace(primary, "Processing colocation %s (%s with clone %s @%s)",
271 colocation->id, dependent->id, primary->id,
272 pcmk_readable_score(colocation->score));
273
274 // Apply role-specific colocations
276 && (colocation->primary_role != pcmk_role_unknown)) {
277
278 if (pcmk_is_set(dependent->flags, pcmk_rsc_unassigned)) {
279 // We're assigning the dependent to a node
281 colocation);
282 return;
283 }
284
285 if (colocation->dependent_role == pcmk_role_promoted) {
286 // We're choosing a role for the dependent
288 colocation);
289 return;
290 }
291 }
292
293 // Apply interleaved colocations
294 if (can_interleave(colocation)) {
295 const pcmk_resource_t *primary_instance = NULL;
296
297 primary_instance = pcmk__find_compatible_instance(dependent, primary,
299 false);
300 if (primary_instance != NULL) {
301 pe_rsc_debug(primary, "Interleaving %s with %s",
302 dependent->id, primary_instance->id);
303 dependent->cmds->apply_coloc_score(dependent, primary_instance,
304 colocation, true);
305
306 } else if (colocation->score >= INFINITY) {
307 crm_notice("%s cannot run because it cannot interleave with "
308 "any instance of %s", dependent->id, primary->id);
309 pcmk__assign_resource(dependent, NULL, true, true);
310
311 } else {
312 pe_rsc_debug(primary,
313 "%s will not colocate with %s "
314 "because no instance can interleave with it",
315 dependent->id, primary->id);
316 }
317
318 return;
319 }
320
321 // Apply mandatory colocations
322 if (colocation->score >= INFINITY) {
323 GList *primary_nodes = NULL;
324
325 // Dependent can run only where primary will have unblocked instances
326 for (iter = primary->children; iter != NULL; iter = iter->next) {
327 const pcmk_resource_t *instance = iter->data;
328 pcmk_node_t *chosen = instance->fns->location(instance, NULL, 0);
329
330 if ((chosen != NULL)
331 && !is_set_recursive(instance, pcmk_rsc_blocked, TRUE)) {
332 pe_rsc_trace(primary, "Allowing %s: %s %d",
333 colocation->id, pe__node_name(chosen),
334 chosen->weight);
335 primary_nodes = g_list_prepend(primary_nodes, chosen);
336 }
337 }
338 pcmk__colocation_intersect_nodes(dependent, primary, colocation,
339 primary_nodes, false);
340 g_list_free(primary_nodes);
341 return;
342 }
343
344 // Apply optional colocations
345 for (iter = primary->children; iter != NULL; iter = iter->next) {
346 const pcmk_resource_t *instance = iter->data;
347
348 instance->cmds->apply_coloc_score(dependent, instance, colocation,
349 false);
350 }
351}
352
353// Clone implementation of pcmk_assignment_methods_t:with_this_colocations()
354void
356 const pcmk_resource_t *orig_rsc, GList **list)
357{
358 CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
359
360 pcmk__add_with_this_list(list, rsc->rsc_cons_lhs, orig_rsc);
361
362 if (rsc->parent != NULL) {
363 rsc->parent->cmds->with_this_colocations(rsc->parent, orig_rsc, list);
364 }
365}
366
367// Clone implementation of pcmk_assignment_methods_t:this_with_colocations()
368void
370 const pcmk_resource_t *orig_rsc, GList **list)
371{
372 CRM_CHECK((rsc != NULL) && (orig_rsc != NULL) && (list != NULL), return);
373
374 pcmk__add_this_with_list(list, rsc->rsc_cons, orig_rsc);
375
376 if (rsc->parent != NULL) {
377 rsc->parent->cmds->this_with_colocations(rsc->parent, orig_rsc, list);
378 }
379}
380
390uint32_t
392{
393 CRM_ASSERT((action != NULL) && pe_rsc_is_clone(action->rsc));
394
395 return pcmk__collective_action_flags(action, action->rsc->children, node);
396}
397
405void
407{
408 CRM_CHECK((location != NULL) && pe_rsc_is_clone(rsc), return);
409
410 pcmk__apply_location(rsc, location);
411
412 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
413 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
414
415 instance->cmds->apply_location(instance, location);
416 }
417}
418
419// GFunc wrapper for calling the action_flags() resource method
420static void
421call_action_flags(gpointer data, gpointer user_data)
422{
423 pcmk_resource_t *rsc = user_data;
424
425 rsc->cmds->action_flags((pcmk_action_t *) data, NULL);
426}
427
434void
436{
437 CRM_ASSERT(pe_rsc_is_clone(rsc));
438
439 g_list_foreach(rsc->actions, call_action_flags, rsc);
441
442 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
443 pcmk_resource_t *child_rsc = (pcmk_resource_t *) iter->data;
444
445 child_rsc->cmds->add_actions_to_graph(child_rsc);
446 }
447
450}
451
462static bool
463rsc_probed_on(const pcmk_resource_t *rsc, const pcmk_node_t *node)
464{
465 if (rsc->children != NULL) {
466 for (GList *child_iter = rsc->children; child_iter != NULL;
467 child_iter = child_iter->next) {
468
469 pcmk_resource_t *child = (pcmk_resource_t *) child_iter->data;
470
471 if (rsc_probed_on(child, node)) {
472 return true;
473 }
474 }
475 return false;
476 }
477
478 if (rsc->known_on != NULL) {
479 GHashTableIter iter;
480 pcmk_node_t *known_node = NULL;
481
482 g_hash_table_iter_init(&iter, rsc->known_on);
483 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &known_node)) {
484 if (pe__same_node(node, known_node)) {
485 return true;
486 }
487 }
488 }
489 return false;
490}
491
502static pcmk_resource_t *
503find_probed_instance_on(const pcmk_resource_t *clone, const pcmk_node_t *node)
504{
505 for (GList *iter = clone->children; iter != NULL; iter = iter->next) {
506 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
507
508 if (rsc_probed_on(instance, node)) {
509 return instance;
510 }
511 }
512 return NULL;
513}
514
522static bool
523probe_anonymous_clone(pcmk_resource_t *clone, pcmk_node_t *node)
524{
525 // Check whether we already probed an instance on this node
526 pcmk_resource_t *child = find_probed_instance_on(clone, node);
527
528 // Otherwise, check if we plan to start an instance on this node
529 for (GList *iter = clone->children; (iter != NULL) && (child == NULL);
530 iter = iter->next) {
531 pcmk_resource_t *instance = (pcmk_resource_t *) iter->data;
532 const pcmk_node_t *instance_node = NULL;
533
534 instance_node = instance->fns->location(instance, NULL, 0);
535 if (pe__same_node(instance_node, node)) {
536 child = instance;
537 }
538 }
539
540 // Otherwise, use the first clone instance
541 if (child == NULL) {
542 child = clone->children->data;
543 }
544
545 // Anonymous clones only need to probe a single instance
546 return child->cmds->create_probe(child, node);
547}
548
558bool
560{
561 CRM_ASSERT((node != NULL) && pe_rsc_is_clone(rsc));
562
563 if (rsc->exclusive_discover) {
564 /* The clone is configured to be probed only where a location constraint
565 * exists with resource-discovery set to exclusive.
566 *
567 * This check is not strictly necessary here since the instance's
568 * create_probe() method would also check, but doing it here is more
569 * efficient (especially for unique clones with a large number of
570 * instances), and affects the CRM_meta_notify_available_uname variable
571 * passed with notify actions.
572 */
573 pcmk_node_t *allowed = g_hash_table_lookup(rsc->allowed_nodes,
574 node->details->id);
575
576 if ((allowed == NULL)
577 || (allowed->rsc_discover_mode != pcmk_probe_exclusive)) {
578 /* This node is not marked for resource discovery. Remove it from
579 * allowed_nodes so that notifications contain only nodes that the
580 * clone can possibly run on.
581 */
582 pe_rsc_trace(rsc,
583 "Skipping probe for %s on %s because resource has "
584 "exclusive discovery but is not allowed on node",
585 rsc->id, pe__node_name(node));
586 g_hash_table_remove(rsc->allowed_nodes, node->details->id);
587 return false;
588 }
589 }
590
591 rsc->children = g_list_sort(rsc->children, pcmk__cmp_instance_number);
592 if (pcmk_is_set(rsc->flags, pcmk_rsc_unique)) {
593 return pcmk__probe_resource_list(rsc->children, node);
594 } else {
595 return probe_anonymous_clone(rsc, node);
596 }
597}
598
608void
610{
611 char *name = NULL;
612
613 CRM_ASSERT(pe_rsc_is_clone(rsc) && (xml != NULL));
614
616 crm_xml_add(xml, name, pe__rsc_bool_str(rsc, pcmk_rsc_unique));
617 free(name);
618
620 crm_xml_add(xml, name, pe__rsc_bool_str(rsc, pcmk_rsc_notify));
621 free(name);
622
625 free(name);
626
629 free(name);
630
632 int promoted_max = pe__clone_promoted_max(rsc);
633 int promoted_node_max = pe__clone_promoted_node_max(rsc);
634
636 crm_xml_add_int(xml, name, promoted_max);
637 free(name);
638
640 crm_xml_add_int(xml, name, promoted_node_max);
641 free(name);
642
643 /* @COMPAT Maintain backward compatibility with resource agents that
644 * expect the old names (deprecated since 2.0.0).
645 */
647 crm_xml_add_int(xml, name, promoted_max);
648 free(name);
649
651 crm_xml_add_int(xml, name, promoted_node_max);
652 free(name);
653 }
654}
655
656// Clone implementation of pcmk_assignment_methods_t:add_utilization()
657void
659 const pcmk_resource_t *orig_rsc, GList *all_rscs,
660 GHashTable *utilization)
661{
662 bool existing = false;
663 pcmk_resource_t *child = NULL;
664
665 CRM_ASSERT(pe_rsc_is_clone(rsc) && (orig_rsc != NULL)
666 && (utilization != NULL));
667
669 return;
670 }
671
672 // Look for any child already existing in the list
673 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
674 child = (pcmk_resource_t *) iter->data;
675 if (g_list_find(all_rscs, child)) {
676 existing = true; // Keep checking remaining children
677 } else {
678 // If this is a clone of a group, look for group's members
679 for (GList *member_iter = child->children; member_iter != NULL;
680 member_iter = member_iter->next) {
681
682 pcmk_resource_t *member = (pcmk_resource_t *) member_iter->data;
683
684 if (g_list_find(all_rscs, member) != NULL) {
685 // Add *child's* utilization, not group member's
686 child->cmds->add_utilization(child, orig_rsc, all_rscs,
687 utilization);
688 existing = true;
689 break;
690 }
691 }
692 }
693 }
694
695 if (!existing && (rsc->children != NULL)) {
696 // If nothing was found, still add first child's utilization
697 child = (pcmk_resource_t *) rsc->children->data;
698
699 child->cmds->add_utilization(child, orig_rsc, all_rscs, utilization);
700 }
701}
702
703// Clone implementation of pcmk_assignment_methods_t:shutdown_lock()
704void
706{
707 CRM_ASSERT(pe_rsc_is_clone(rsc));
708 return; // Clones currently don't support shutdown locks
709}
@ 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:74
#define PCMK_ACTION_RUNNING
Definition actions.h:70
#define PCMK_ACTION_PROMOTE
Definition actions.h:65
#define PCMK_ACTION_START
Definition actions.h:71
#define PCMK_ACTION_STOPPED
Definition actions.h:75
#define PCMK_ACTION_DEMOTED
Definition actions.h:50
const char * name
Definition cib.c:26
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition scores.c:86
char * crm_meta_name(const char *field)
Definition utils.c:468
gboolean crm_is_true(const char *s)
Definition strings.c:416
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:99
char data[0]
Definition cpg.c:10
#define INFINITY
Definition crm.h:98
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 void pcmk__apply_location(pcmk_resource_t *rsc, pe__location_t *constraint)
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 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__update_promotable_dependent_priority(const pcmk_resource_t *primary, pcmk_resource_t *dependent, const pcmk__colocation_t *colocation)
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__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:381
#define CRM_CHECK(expr, failure_action)
Definition logging.h:238
#define pcmk__config_err(fmt...)
#define PCMK_META_CLONE_NODE_MAX
Definition msg_xml.h:66
#define XML_RSC_ATTR_NOTIFY
Definition msg_xml.h:251
#define PCMK_META_PROMOTED_MAX
Definition msg_xml.h:70
#define PCMK_META_CLONE_MAX
Definition msg_xml.h:64
#define PCMK_XA_PROMOTED_NODE_MAX_LEGACY
Definition msg_xml.h:57
#define XML_RSC_ATTR_UNIQUE
Definition msg_xml.h:250
#define XML_RSC_ATTR_INTERLEAVE
Definition msg_xml.h:245
#define PCMK_META_PROMOTED_NODE_MAX
Definition msg_xml.h:71
#define PCMK_XA_PROMOTED_MAX_LEGACY
Definition msg_xml.h:56
@ pcmk_probe_exclusive
Never probe resource on node.
Definition nodes.h:51
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:349
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:302
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)
void pcmk__clone_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
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)
void pcmk__clone_apply_location(pcmk_resource_t *rsc, pe__location_t *location)
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_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:558
void pe__create_clone_notifications(pcmk_resource_t *clone)
Definition clone.c:1426
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:341
int pe__clone_max(const pcmk_resource_t *clone)
Definition clone.c:63
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition internal.h:70
#define pe_rsc_debug(rsc, fmt, args...)
Definition internal.h:36
bool pe__clone_is_ordered(const pcmk_resource_t *clone)
Definition clone.c:1300
#define pe_rsc_trace(rsc, fmt, args...)
Definition internal.h:37
#define pe__set_resource_flags(resource, flags_to_set)
Definition internal.h:64
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:1445
@ pcmk_rsc_variant_group
Group resource.
Definition resources.h:35
@ pcmk_rsc_variant_primitive
Primitive resource.
Definition resources.h:34
@ pcmk_rsc_promotable
Whether resource can be promoted and demoted.
Definition resources.h:124
@ pcmk_rsc_unassigned
Whether resource has not yet been assigned to a node.
Definition resources.h:127
@ pcmk_rsc_assigning
Whether resource is in the process of being assigned to a node.
Definition resources.h:130
@ pcmk_rsc_unique
Whether resource is not an anonymous clone instance.
Definition resources.h:118
@ pcmk_rsc_notify
Whether resource has clone notifications enabled.
Definition resources.h:115
@ pcmk_rsc_blocked
Whether resource is blocked from further action.
Definition resources.h:109
#define CRM_ASSERT(expr)
Definition results.h:42
@ pcmk_role_unknown
Resource role is unknown.
Definition roles.h:28
@ pcmk_role_promoted
Promoted.
Definition roles.h:32
@ pcmk_sched_output_scores
Whether node scores should be output instead of logged.
Definition scheduler.h:158
pcmk_resource_t * primary
pcmk_resource_t * dependent
Implementation of pcmk_action_t.
Definition actions.h:390
Implementation of pcmk_node_t.
Definition nodes.h:130
int weight
Node score for a given resource.
Definition nodes.h:131
int rsc_discover_mode
Probe mode (enum pe_discover_e)
Definition nodes.h:137
struct pe_node_shared_s * details
Basic node information.
Definition nodes.h:134
const char * id
Node ID at the cluster layer.
Definition nodes.h:67
Implementation of pcmk_resource_t.
Definition resources.h:399
pcmk_assignment_methods_t * cmds
Resource assignment methods.
Definition resources.h:417
GList * actions
Definition resources.h:447
enum pe_obj_types variant
Resource variant.
Definition resources.h:414
GHashTable * meta
Resource's meta-attributes.
Definition resources.h:471
GList * rsc_cons
Definition resources.h:445
GList * rsc_cons_lhs
Definition resources.h:444
GList * children
Resource's child resources, if any.
Definition resources.h:475
pcmk_scheduler_t * cluster
Cluster that resource is part of.
Definition resources.h:412
gboolean exclusive_discover
Whether exclusive probing is enabled.
Definition resources.h:433
pcmk_rsc_methods_t * fns
Resource object methods.
Definition resources.h:416
GHashTable * known_on
Nodes where resource has been probed (key is node ID, not name)
Definition resources.h:463
char * id
Resource ID in configuration.
Definition resources.h:400
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
Definition resources.h:466
unsigned long long flags
Group of enum pcmk_rsc_flags.
Definition resources.h:429
pcmk_resource_t * parent
Resource's parent resource, if any.
Definition resources.h:413
unsigned long long flags
Group of enum pcmk_scheduler_flags.
Definition scheduler.h:183
void(* apply_location)(pcmk_resource_t *rsc, pe__location_t *location)
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)
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_coloc_score)(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
Definition resources.h:339
unsigned int(* max_per_node)(const pcmk_resource_t *rsc)
Get maximum resource instances per node.
Definition resources.h:395