pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
pcmk_sched_group.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2021 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU General Public License version 2
7 * or later (GPLv2+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <stdbool.h>
13
14#include <crm/msg_xml.h>
15
16#include <pacemaker-internal.h>
17
19
20#define VARIANT_GROUP 1
21#include <lib/pengine/variant.h>
22
29static void
30expand_group_colocations(pe_resource_t *rsc)
31{
32 group_variant_data_t *group_data = NULL;
33 pe_resource_t *member = NULL;
34 bool any_unmanaged = false;
35
36 get_group_variant_data(group_data, rsc);
37
38 // Treat "group with R" colocations as "first member with R"
39 member = group_data->first_child;
40 member->rsc_cons = g_list_concat(member->rsc_cons, rsc->rsc_cons);
41
42
43 /* The above works for the whole group because each group member is
44 * colocated with the previous one.
45 *
46 * However, there is a special case when a group has a mandatory colocation
47 * with a resource that can't start. In that case,
48 * pcmk__block_colocated_starts() will ensure that dependent resources in
49 * mandatory colocations (i.e. the first member for groups) can't start
50 * either. But if any group member is unmanaged and already started, the
51 * internal group colocations are no longer sufficient to make that apply to
52 * later members.
53 *
54 * To handle that case, add mandatory colocations to each member after the
55 * first.
56 */
57 any_unmanaged = !pcmk_is_set(member->flags, pe_rsc_managed);
58 for (GList *item = rsc->children->next; item != NULL; item = item->next) {
59 member = item->data;
60 if (any_unmanaged) {
61 for (GList *cons_iter = rsc->rsc_cons; cons_iter != NULL;
62 cons_iter = cons_iter->next) {
63
64 pcmk__colocation_t *constraint = (pcmk__colocation_t *) cons_iter->data;
65
66 if (constraint->score == INFINITY) {
67 member->rsc_cons = g_list_prepend(member->rsc_cons, constraint);
68 }
69 }
70 } else if (!pcmk_is_set(member->flags, pe_rsc_managed)) {
71 any_unmanaged = true;
72 }
73 }
74
75 rsc->rsc_cons = NULL;
76
77 // Treat "R with group" colocations as "R with last member"
78 member = group_data->last_child;
79 member->rsc_cons_lhs = g_list_concat(member->rsc_cons_lhs,
80 rsc->rsc_cons_lhs);
81 rsc->rsc_cons_lhs = NULL;
82}
83
87{
88 pe_node_t *node = NULL;
89 pe_node_t *group_node = NULL;
90 GList *gIter = NULL;
91 group_variant_data_t *group_data = NULL;
92
93 get_group_variant_data(group_data, rsc);
94
96 return rsc->allocated_to;
97 }
99 pe_rsc_debug(rsc, "Dependency loop detected involving %s", rsc->id);
100 return NULL;
101 }
102
103 if (group_data->first_child == NULL) {
104 // Nothing to allocate
106 return NULL;
107 }
108
110 rsc->role = group_data->first_child->role;
111
112 expand_group_colocations(rsc);
113
115 rsc, __func__, rsc->allowed_nodes, data_set);
116
117 gIter = rsc->children;
118 for (; gIter != NULL; gIter = gIter->next) {
119 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
120
121 pe_rsc_trace(rsc, "Allocating group %s member %s",
122 rsc->id, child_rsc->id);
123 node = child_rsc->cmds->allocate(child_rsc, prefer, data_set);
124 if (group_node == NULL) {
125 group_node = node;
126 }
127 }
128
129 pe__set_next_role(rsc, group_data->first_child->next_role,
130 "first group member");
132
133 if (group_data->colocated) {
134 return group_node;
135 }
136 return NULL;
137}
138
140
141void
143{
144 pe_action_t *op = NULL;
145 const char *value = NULL;
146 GList *gIter = rsc->children;
147
148 pe_rsc_trace(rsc, "Creating actions for %s", rsc->id);
149
150 for (; gIter != NULL; gIter = gIter->next) {
151 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
152
153 child_rsc->cmds->create_actions(child_rsc, data_set);
154 group_update_pseudo_status(rsc, child_rsc);
155 }
156
157 op = start_action(rsc, NULL, TRUE /* !group_data->child_starting */ );
159
160 op = custom_action(rsc, started_key(rsc),
161 RSC_STARTED, NULL, TRUE /* !group_data->child_starting */ , TRUE, data_set);
163
164 op = stop_action(rsc, NULL, TRUE /* !group_data->child_stopping */ );
166
167 op = custom_action(rsc, stopped_key(rsc),
168 RSC_STOPPED, NULL, TRUE /* !group_data->child_stopping */ , TRUE, data_set);
170
171 value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_PROMOTABLE);
172 if (crm_is_true(value)) {
173 op = custom_action(rsc, demote_key(rsc), RSC_DEMOTE, NULL, TRUE, TRUE, data_set);
175
176 op = custom_action(rsc, demoted_key(rsc), RSC_DEMOTED, NULL, TRUE, TRUE, data_set);
178
179 op = custom_action(rsc, promote_key(rsc), RSC_PROMOTE, NULL, TRUE, TRUE, data_set);
181
182 op = custom_action(rsc, promoted_key(rsc), RSC_PROMOTED, NULL, TRUE, TRUE, data_set);
184 }
185}
186
187void
189{
190 GList *gIter = child->actions;
191 group_variant_data_t *group_data = NULL;
192
193 get_group_variant_data(group_data, parent);
194
195 if (group_data->ordered == FALSE) {
196 /* If this group is not ordered, then leave the meta-actions as optional */
197 return;
198 }
199
200 if (group_data->child_stopping && group_data->child_starting) {
201 return;
202 }
203
204 for (; gIter != NULL; gIter = gIter->next) {
205 pe_action_t *action = (pe_action_t *) gIter->data;
206
208 continue;
209 }
210 if (pcmk__str_eq(RSC_STOP, action->task, pcmk__str_casei)
212
213 group_data->child_stopping = TRUE;
214 pe_rsc_trace(action->rsc, "Based on %s the group is stopping", action->uuid);
215
216 } else if (pcmk__str_eq(RSC_START, action->task, pcmk__str_casei)
218 group_data->child_starting = TRUE;
219 pe_rsc_trace(action->rsc, "Based on %s the group is starting", action->uuid);
220 }
221 }
222}
223
224void
226{
227 GList *gIter = rsc->children;
228 pe_resource_t *last_rsc = NULL;
229 pe_resource_t *last_active = NULL;
230 pe_resource_t *top = uber_parent(rsc);
231 group_variant_data_t *group_data = NULL;
232
233 get_group_variant_data(group_data, rsc);
234
241
242 for (; gIter != NULL; gIter = gIter->next) {
243 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
244 int stop = pe_order_none;
245 int stopped = pe_order_implies_then_printed;
247 int started =
249
250 child_rsc->cmds->internal_constraints(child_rsc, data_set);
251
252 if (last_rsc == NULL) {
253 if (group_data->ordered) {
255 stopped = pe_order_implies_then;
256 }
257
258 } else if (group_data->colocated) {
259 pcmk__new_colocation("group:internal_colocation", NULL, INFINITY,
260 child_rsc, last_rsc, NULL, NULL,
261 pcmk_is_set(child_rsc->flags, pe_rsc_critical),
262 data_set);
263 }
264
268 data_set);
269
271 RSC_DEMOTED, stopped, data_set);
272
274 RSC_PROMOTED, started, data_set);
275
279 data_set);
280
281 }
282
284 data_set);
285 pcmk__order_stops(rsc, child_rsc,
287
289 stopped, data_set);
291 started, data_set);
292
293 if (group_data->ordered == FALSE) {
294 pcmk__order_starts(rsc, child_rsc,
300 data_set);
301 }
302
303 } else if (last_rsc != NULL) {
304 pcmk__order_starts(last_rsc, child_rsc, start, data_set);
305 pcmk__order_stops(child_rsc, last_rsc,
307
309 pcmk__order_resource_actions(last_rsc, RSC_PROMOTE, child_rsc,
310 RSC_PROMOTE, start, data_set);
311 pcmk__order_resource_actions(child_rsc, RSC_DEMOTE, last_rsc,
313 data_set);
314 }
315
316 } else {
317 pcmk__order_starts(rsc, child_rsc, pe_order_none, data_set);
321 data_set);
322 }
323 }
324
325 /* Look for partially active groups
326 * Make sure they still shut down in sequence
327 */
328 if (child_rsc->running_on) {
329 if (group_data->ordered
330 && last_rsc
331 && last_rsc->running_on == NULL && last_active && last_active->running_on) {
332 pcmk__order_stops(child_rsc, last_active, pe_order_optional,
333 data_set);
334 }
335 last_active = child_rsc;
336 }
337
338 last_rsc = child_rsc;
339 }
340
341 if (group_data->ordered && last_rsc != NULL) {
342 int stop_stop_flags = pe_order_implies_then;
343 int stop_stopped_flags = pe_order_optional;
344
345 pcmk__order_stops(rsc, last_rsc, stop_stop_flags, data_set);
347 stop_stopped_flags, data_set);
348
351 stop_stop_flags, data_set);
353 stop_stopped_flags, data_set);
354 }
355 }
356}
357
358void
360 pcmk__colocation_t *constraint,
362{
363 GList *gIter = NULL;
364 group_variant_data_t *group_data = NULL;
365
366 if (dependent == NULL) {
367 pe_err("dependent was NULL for %s", constraint->id);
368 return;
369
370 } else if (primary == NULL) {
371 pe_err("primary was NULL for %s", constraint->id);
372 return;
373 }
374
375 gIter = dependent->children;
376 pe_rsc_trace(dependent, "Processing constraints from %s", dependent->id);
377
378 get_group_variant_data(group_data, dependent);
379
380 if (group_data->colocated) {
381 group_data->first_child->cmds->rsc_colocation_lh(group_data->first_child,
382 primary, constraint,
383 data_set);
384 return;
385
386 } else if (constraint->score >= INFINITY) {
387 pcmk__config_err("%s: Cannot perform mandatory colocation "
388 "between non-colocated group and %s",
389 dependent->id, primary->id);
390 return;
391 }
392
393 for (; gIter != NULL; gIter = gIter->next) {
394 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
395
396 child_rsc->cmds->rsc_colocation_lh(child_rsc, primary, constraint,
397 data_set);
398 }
399}
400
401void
403 pcmk__colocation_t *constraint,
405{
406 GList *gIter = primary->children;
407 group_variant_data_t *group_data = NULL;
408
409 get_group_variant_data(group_data, primary);
410 CRM_CHECK(dependent->variant == pe_native, return);
411
412 pe_rsc_trace(primary, "Processing RH %s of constraint %s (LH is %s)",
413 primary->id, constraint->id, dependent->id);
414
415 if (pcmk_is_set(primary->flags, pe_rsc_provisional)) {
416 return;
417
418 } else if (group_data->colocated && group_data->first_child) {
419 if (constraint->score >= INFINITY) {
420 /* Ensure RHS is _fully_ up before can start LHS */
421 group_data->last_child->cmds->rsc_colocation_rh(dependent,
422 group_data->last_child,
423 constraint,
424 data_set);
425 } else {
426 /* A partially active RHS is fine */
427 group_data->first_child->cmds->rsc_colocation_rh(dependent,
428 group_data->first_child,
429 constraint,
430 data_set);
431 }
432
433 return;
434
435 } else if (constraint->score >= INFINITY) {
436 pcmk__config_err("%s: Cannot perform mandatory colocation with"
437 " non-colocated group %s", dependent->id, primary->id);
438 return;
439 }
440
441 for (; gIter != NULL; gIter = gIter->next) {
442 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
443
444 child_rsc->cmds->rsc_colocation_rh(dependent, child_rsc, constraint,
445 data_set);
446 }
447}
448
451{
452 GList *gIter = NULL;
454
455 for (gIter = action->rsc->children; gIter != NULL; gIter = gIter->next) {
456 pe_resource_t *child = (pe_resource_t *) gIter->data;
457 enum action_tasks task = get_complex_task(child, action->task, TRUE);
458 const char *task_s = task2text(task);
459 pe_action_t *child_action = find_first_action(child->actions, NULL, task_s, node);
460
461 if (child_action) {
462 enum pe_action_flags child_flags = child->cmds->action_flags(child_action, node);
463
465 && !pcmk_is_set(child_flags, pe_action_optional)) {
466 pe_rsc_trace(action->rsc, "%s is mandatory because of %s", action->uuid,
467 child_action->uuid);
468 pe__clear_raw_action_flags(flags, "group action",
471 }
472 if (!pcmk__str_eq(task_s, action->task, pcmk__str_casei)
474 && !pcmk_is_set(child_flags, pe_action_runnable)) {
475
476 pe_rsc_trace(action->rsc, "%s is not runnable because of %s", action->uuid,
477 child_action->uuid);
478 pe__clear_raw_action_flags(flags, "group action",
481 }
482
483 } else if (task != stop_rsc && task != action_demote) {
484 pe_rsc_trace(action->rsc, "%s is not runnable because of %s (not found in %s)",
485 action->uuid, task_s, child->id);
486 pe__clear_raw_action_flags(flags, "group action",
488 }
489 }
490
491 return flags;
492}
493
496 enum pe_action_flags flags, enum pe_action_flags filter,
498{
499 GList *gIter = then->rsc->children;
500 enum pe_graph_flags changed = pe_graph_none;
501
502 CRM_ASSERT(then->rsc != NULL);
503 changed |= native_update_actions(first, then, node, flags, filter, type,
504 data_set);
505
506 for (; gIter != NULL; gIter = gIter->next) {
507 pe_resource_t *child = (pe_resource_t *) gIter->data;
508 pe_action_t *child_action = find_first_action(child->actions, NULL, then->task, node);
509
510 if (child_action) {
511 changed |= child->cmds->update_actions(first, child_action, node,
512 flags, filter, type,
513 data_set);
514 }
515 }
516
517 return changed;
518}
519
520void
522{
523 GList *gIter = rsc->children;
524 GList *saved = constraint->node_list_rh;
525 GList *zero = pcmk__copy_node_list(constraint->node_list_rh, true);
526 gboolean reset_scores = TRUE;
527 group_variant_data_t *group_data = NULL;
528
529 get_group_variant_data(group_data, rsc);
530
531 pe_rsc_debug(rsc, "Processing rsc_location %s for %s", constraint->id, rsc->id);
532
533 pcmk__apply_location(constraint, rsc);
534
535 for (; gIter != NULL; gIter = gIter->next) {
536 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
537
538 child_rsc->cmds->rsc_location(child_rsc, constraint);
539 if (group_data->colocated && reset_scores) {
540 reset_scores = FALSE;
541 constraint->node_list_rh = zero;
542 }
543 }
544
545 constraint->node_list_rh = saved;
546 g_list_free_full(zero, free);
547}
548
549void
551{
552 CRM_CHECK(rsc != NULL, return);
553
554 pe_rsc_trace(rsc, "Processing actions from %s", rsc->id);
556
557 for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
558 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
559
560 child_rsc->cmds->expand(child_rsc, data_set);
561 }
562}
563
564GHashTable *
565pcmk__group_merge_weights(pe_resource_t *rsc, const char *primary_id,
566 GHashTable *nodes, const char *attr, float factor,
567 uint32_t flags)
568{
569 GList *gIter = rsc->rsc_cons_lhs;
570 group_variant_data_t *group_data = NULL;
571
572 get_group_variant_data(group_data, rsc);
573
574 if (pcmk_is_set(rsc->flags, pe_rsc_merging)) {
575 pe_rsc_info(rsc, "Breaking dependency loop with %s at %s",
576 rsc->id, primary_id);
577 return nodes;
578 }
579
581
582 nodes = group_data->first_child->cmds->merge_weights(group_data->first_child,
583 primary_id, nodes,
584 attr, factor, flags);
585
586 for (; gIter != NULL; gIter = gIter->next) {
587 pcmk__colocation_t *constraint = (pcmk__colocation_t *) gIter->data;
588
589 nodes = pcmk__native_merge_weights(constraint->dependent, rsc->id,
590 nodes, constraint->node_attribute,
591 constraint->score / (float) INFINITY,
592 flags);
593 }
594
596 return nodes;
597}
598
599void
600group_append_meta(pe_resource_t * rsc, xmlNode * xml)
601{
602}
603
604// Group implementation of resource_alloc_functions_t:colocated_resources()
605GList *
607 GList *colocated_rscs)
608{
609 pe_resource_t *child_rsc = NULL;
610 group_variant_data_t *group_data = NULL;
611
612 get_group_variant_data(group_data, rsc);
613
614 if (orig_rsc == NULL) {
615 orig_rsc = rsc;
616 }
617
618 if (group_data->colocated || pe_rsc_is_clone(rsc->parent)) {
619 /* This group has colocated members and/or is cloned -- either way,
620 * add every child's colocated resources to the list.
621 */
622 for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
623 child_rsc = (pe_resource_t *) gIter->data;
624 colocated_rscs = child_rsc->cmds->colocated_resources(child_rsc,
625 orig_rsc,
626 colocated_rscs);
627 }
628
629 } else if (group_data->first_child != NULL) {
630 /* This group's members are not colocated, and the group is not cloned,
631 * so just add the first child's colocations to the list.
632 */
633 child_rsc = group_data->first_child;
634 colocated_rscs = child_rsc->cmds->colocated_resources(child_rsc,
635 orig_rsc,
636 colocated_rscs);
637 }
638
639 // Now consider colocations where the group itself is specified
640 colocated_rscs = pcmk__colocated_resources(rsc, orig_rsc, colocated_rscs);
641
642 return colocated_rscs;
643}
644
645// Group implementation of resource_alloc_functions_t:add_utilization()
646void
648 GList *all_rscs, GHashTable *utilization)
649{
650 group_variant_data_t *group_data = NULL;
651 pe_resource_t *child = NULL;
652
654 return;
655 }
656
657 pe_rsc_trace(orig_rsc, "%s: Adding group %s as colocated utilization",
658 orig_rsc->id, rsc->id);
659 get_group_variant_data(group_data, rsc);
660 if (group_data->colocated || pe_rsc_is_clone(rsc->parent)) {
661 // Every group member will be on same node, so sum all members
662 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
663 child = (pe_resource_t *) iter->data;
664
666 && (g_list_find(all_rscs, child) == NULL)) {
667 child->cmds->add_utilization(child, orig_rsc, all_rscs,
668 utilization);
669 }
670 }
671
672 } else {
673 // Just add first child's utilization
674 child = group_data->first_child;
675 if ((child != NULL)
677 && (g_list_find(all_rscs, child) == NULL)) {
678
679 child->cmds->add_utilization(child, orig_rsc, all_rscs,
680 utilization);
681 }
682 }
683}
684
685// Group implementation of resource_alloc_functions_t:shutdown_lock()
686void
688{
689 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
690 pe_resource_t *child = (pe_resource_t *) iter->data;
691
692 child->cmds->shutdown_lock(child);
693 }
694}
const char * parent
Definition: cib.c:25
uint64_t flags
Definition: remote.c:3
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:122
const char * task2text(enum action_tasks task)
Definition: common.c:401
action_tasks
Definition: common.h:61
@ action_demote
Definition: common.h:72
@ stop_rsc
Definition: common.h:64
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:913
enum crm_ais_msg_types type
Definition: cpg.c:3
#define RSC_PROMOTE
Definition: crm.h:207
#define RSC_DEMOTE
Definition: crm.h:209
#define RSC_STARTED
Definition: crm.h:202
#define RSC_STOPPED
Definition: crm.h:205
#define RSC_START
Definition: crm.h:201
#define INFINITY
Definition: crm.h:99
#define RSC_STOP
Definition: crm.h:204
#define RSC_PROMOTED
Definition: crm.h:208
#define RSC_DEMOTED
Definition: crm.h:210
G_GNUC_INTERNAL void pcmk__new_colocation(const char *id, const char *node_attr, int score, pe_resource_t *dependent, pe_resource_t *primary, const char *dependent_role, const char *primary_role, bool influence, pe_working_set_t *data_set)
G_GNUC_INTERNAL void pcmk__apply_location(pe__location_t *constraint, pe_resource_t *rsc)
#define pcmk__order_resource_actions(lh_rsc, lh_task, rh_rsc, rh_task, flags, data_set)
#define pcmk__order_stops(rsc1, rsc2, type, data_set)
G_GNUC_INTERNAL GList * pcmk__colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
#define pcmk__order_starts(rsc1, rsc2, type, data_set)
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
#define pcmk__config_err(fmt...)
#define XML_RSC_ATTR_PROMOTABLE
Definition: msg_xml.h:235
pe_working_set_t * data_set
const char * action
Definition: pcmk_fence.c:29
void pcmk__group_shutdown_lock(pe_resource_t *rsc)
void pcmk__group_add_utilization(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void group_rsc_colocation_rh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
void group_create_actions(pe_resource_t *rsc, pe_working_set_t *data_set)
void group_rsc_colocation_lh(pe_resource_t *dependent, pe_resource_t *primary, pcmk__colocation_t *constraint, pe_working_set_t *data_set)
GList * pcmk__group_colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
enum pe_action_flags group_action_flags(pe_action_t *action, pe_node_t *node)
void group_internal_constraints(pe_resource_t *rsc, pe_working_set_t *data_set)
void group_update_pseudo_status(pe_resource_t *parent, pe_resource_t *child)
GHashTable * pcmk__group_merge_weights(pe_resource_t *rsc, const char *primary_id, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
pe_node_t * pcmk__group_allocate(pe_resource_t *rsc, pe_node_t *prefer, pe_working_set_t *data_set)
void group_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
void group_append_meta(pe_resource_t *rsc, xmlNode *xml)
enum pe_graph_flags group_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
void group_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
void native_expand(pe_resource_t *rsc, pe_working_set_t *data_set)
GHashTable * pcmk__native_merge_weights(pe_resource_t *rsc, const char *rhs, GHashTable *nodes, const char *attr, float factor, uint32_t flags)
enum pe_graph_flags native_update_actions(pe_action_t *first, pe_action_t *then, pe_node_t *node, enum pe_action_flags flags, enum pe_action_flags filter, enum pe_ordering type, pe_working_set_t *data_set)
GList * pcmk__copy_node_list(const GList *list, bool reset)
pe_graph_flags
Definition: pe_types.h:297
@ pe_graph_none
Definition: pe_types.h:298
#define pe_rsc_managed
Definition: pe_types.h:257
pe_ordering
Definition: pe_types.h:497
@ pe_order_implies_first_printed
Definition: pe_types.h:526
@ pe_order_restart
Definition: pe_types.h:521
@ pe_order_implies_then
Definition: pe_types.h:503
@ pe_order_none
Definition: pe_types.h:498
@ pe_order_implies_then_printed
Definition: pe_types.h:527
@ pe_order_optional
Definition: pe_types.h:499
@ pe_order_runnable_left
Definition: pe_types.h:509
#define pe_rsc_provisional
Definition: pe_types.h:266
#define pe_rsc_allocating
Definition: pe_types.h:267
#define pe_flag_show_scores
Definition: pe_types.h:134
pe_action_flags
Definition: pe_types.h:305
@ pe_action_optional
Definition: pe_types.h:308
@ pe_action_runnable
Definition: pe_types.h:307
@ pe_action_pseudo
Definition: pe_types.h:306
#define pe_rsc_merging
Definition: pe_types.h:268
@ pe_native
Definition: pe_types.h:38
#define pe_rsc_promotable
Definition: pe_types.h:264
#define pe_rsc_critical
Definition: pe_types.h:274
#define demote_key(rsc)
Definition: internal.h:404
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
Definition: internal.h:355
#define demoted_key(rsc)
Definition: internal.h:409
#define pe__clear_raw_action_flags(action_flags, action_name, flags_to_clear)
Definition: internal.h:86
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
Definition: utils.c:730
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
Definition: utils.c:1541
#define promoted_key(rsc)
Definition: internal.h:399
#define start_action(rsc, node, optional)
Definition: internal.h:385
#define started_key(rsc)
Definition: internal.h:389
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition: complex.c:1126
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:55
#define stopped_key(rsc)
Definition: internal.h:373
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:21
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
Definition: utils.c:1518
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:22
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:49
#define stop_action(rsc, node, optional)
Definition: internal.h:379
#define promote_key(rsc)
Definition: internal.h:394
#define pe_rsc_info(rsc, fmt, args...)
Definition: internal.h:20
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:70
#define pe__set_order_flags(order_flags, flags_to_set)
Definition: internal.h:113
#define pe_err(fmt...)
Definition: internal.h:24
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:61
#define CRM_ASSERT(expr)
Definition: results.h:42
@ pcmk__str_casei
const char * node_attribute
pe_resource_t * dependent
pe_resource_t * rsc
Definition: pe_types.h:424
char * uuid
Definition: pe_types.h:429
char * task
Definition: pe_types.h:428
GList * running_on
Definition: pe_types.h:380
GList * actions
Definition: pe_types.h:373
enum pe_obj_types variant
Definition: pe_types.h:345
GHashTable * meta
Definition: pe_types.h:387
GList * rsc_cons
Definition: pe_types.h:371
GList * rsc_cons_lhs
Definition: pe_types.h:370
GList * children
Definition: pe_types.h:391
char * id
Definition: pe_types.h:336
GHashTable * allowed_nodes
Definition: pe_types.h:382
pe_node_t * allocated_to
Definition: pe_types.h:377
unsigned long long flags
Definition: pe_types.h:362
pe_resource_t * parent
Definition: pe_types.h:343
resource_alloc_functions_t * cmds
Definition: pe_types.h:348
enum rsc_role_e next_role
Definition: pe_types.h:385
enum rsc_role_e role
Definition: pe_types.h:384
unsigned long long flags
Definition: pe_types.h:153
void(* add_utilization)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void(* rsc_location)(pe_resource_t *, pe__location_t *)
void(* rsc_colocation_lh)(pe_resource_t *, pe_resource_t *, pcmk__colocation_t *, pe_working_set_t *)
void(* rsc_colocation_rh)(pe_resource_t *, pe_resource_t *, pcmk__colocation_t *, pe_working_set_t *)
void(* expand)(pe_resource_t *, pe_working_set_t *)
pe_node_t *(* allocate)(pe_resource_t *, pe_node_t *, pe_working_set_t *)
void(* shutdown_lock)(pe_resource_t *rsc)
void(* create_actions)(pe_resource_t *, pe_working_set_t *)
void(* internal_constraints)(pe_resource_t *, pe_working_set_t *)
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
enum pe_action_flags(* action_flags)(pe_action_t *, pe_node_t *)
enum pe_graph_flags(* update_actions)(pe_action_t *, pe_action_t *, pe_node_t *, enum pe_action_flags, enum pe_action_flags, enum pe_ordering, pe_working_set_t *data_set)