pacemaker 2.1.5-a3f44794f94
Scalable High-Availability cluster resource manager
pcmk_sched_group.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2022 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>
18
25static void
26expand_group_colocations(pe_resource_t *rsc)
27{
28 pe_resource_t *member = NULL;
29 bool any_unmanaged = false;
30 GList *item = NULL;
31
32 if (rsc->children == NULL) {
33 return;
34 }
35
36 // Treat "group with R" colocations as "first member with R"
37 member = (pe_resource_t *) rsc->children->data;
38 for (item = rsc->rsc_cons; item != NULL; item = item->next) {
39 pcmk__add_this_with(member, (pcmk__colocation_t *) (item->data));
40 }
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_colocation_dependents() will ensure that dependent resources
49 * in 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 (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 pcmk__add_this_with(member, constraint);
68 }
69 }
70 } else if (!pcmk_is_set(member->flags, pe_rsc_managed)) {
71 any_unmanaged = true;
72 }
73 }
74
75 g_list_free(rsc->rsc_cons);
76 rsc->rsc_cons = NULL;
77
78 // Treat "R with group" colocations as "R with last member"
79 member = pe__last_group_member(rsc);
80 for (item = rsc->rsc_cons_lhs; item != NULL; item = item->next) {
81 pcmk__add_with_this(member, (pcmk__colocation_t *) (item->data));
82 }
83 g_list_free(rsc->rsc_cons_lhs);
84 rsc->rsc_cons_lhs = NULL;
85}
86
98{
99 pe_node_t *first_assigned_node = NULL;
100 pe_resource_t *first_member = NULL;
101
102 CRM_ASSERT(rsc != NULL);
103
105 return rsc->allocated_to; // Assignment already done
106 }
108 pe_rsc_debug(rsc, "Assignment dependency loop detected involving %s",
109 rsc->id);
110 return NULL;
111 }
112
113 if (rsc->children == NULL) {
114 // No members to assign
116 return NULL;
117 }
118
120 first_member = (pe_resource_t *) rsc->children->data;
121 rsc->role = first_member->role;
122
123 expand_group_colocations(rsc);
124
126 rsc, __func__, rsc->allowed_nodes, rsc->cluster);
127
128 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
129 pe_resource_t *member = (pe_resource_t *) iter->data;
130 pe_node_t *node = NULL;
131
132 pe_rsc_trace(rsc, "Assigning group %s member %s",
133 rsc->id, member->id);
134 node = member->cmds->assign(member, prefer);
135 if (first_assigned_node == NULL) {
136 first_assigned_node = node;
137 }
138 }
139
140 pe__set_next_role(rsc, first_member->next_role, "first group member");
142
144 return NULL;
145 }
146 return first_assigned_node;
147}
148
158static pe_action_t *
159create_group_pseudo_op(pe_resource_t *group, const char *action)
160{
161 pe_action_t *op = custom_action(group, pcmk__op_key(group->id, action, 0),
162 action, NULL, TRUE, TRUE, group->cluster);
164 return op;
165}
166
173void
175{
176 CRM_ASSERT(rsc != NULL);
177
178 pe_rsc_trace(rsc, "Creating actions for group %s", rsc->id);
179
180 // Create actions for individual group members
181 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
182 pe_resource_t *member = (pe_resource_t *) iter->data;
183
184 member->cmds->create_actions(member);
185 }
186
187 // Create pseudo-actions for group itself to serve as ordering points
188 create_group_pseudo_op(rsc, RSC_START);
189 create_group_pseudo_op(rsc, RSC_STARTED);
190 create_group_pseudo_op(rsc, RSC_STOP);
191 create_group_pseudo_op(rsc, RSC_STOPPED);
192 if (crm_is_true(g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_PROMOTABLE))) {
193 create_group_pseudo_op(rsc, RSC_DEMOTE);
194 create_group_pseudo_op(rsc, RSC_DEMOTED);
195 create_group_pseudo_op(rsc, RSC_PROMOTE);
196 create_group_pseudo_op(rsc, RSC_PROMOTED);
197 }
198}
199
200// User data for member_internal_constraints()
201struct member_data {
202 // These could be derived from member but this avoids some function calls
203 bool ordered;
204 bool colocated;
205 bool promotable;
206
207 pe_resource_t *last_active;
208 pe_resource_t *previous_member;
209};
210
218static void
219member_internal_constraints(gpointer data, gpointer user_data)
220{
221 pe_resource_t *member = (pe_resource_t *) data;
222 struct member_data *member_data = (struct member_data *) user_data;
223
224 // For ordering demote vs demote or stop vs stop
225 uint32_t down_flags = pe_order_implies_first_printed;
226
227 // For ordering demote vs demoted or stop vs stopped
228 uint32_t post_down_flags = pe_order_implies_then_printed;
229
230 // Create the individual member's implicit constraints
231 member->cmds->internal_constraints(member);
232
233 if (member_data->previous_member == NULL) {
234 // This is first member
235 if (member_data->ordered) {
237 post_down_flags = pe_order_implies_then;
238 }
239
240 } else if (member_data->colocated) {
241 // Colocate this member with the previous one
242 pcmk__new_colocation("group:internal_colocation", NULL, INFINITY,
243 member, member_data->previous_member, NULL, NULL,
245 member->cluster);
246 }
247
248 if (member_data->promotable) {
249 // Demote group -> demote member -> group is demoted
251 member, RSC_DEMOTE, down_flags);
253 member->parent, RSC_DEMOTED,
254 post_down_flags);
255
256 // Promote group -> promote member -> group is promoted
258 member->parent, RSC_PROMOTED,
263 member, RSC_PROMOTE,
265 }
266
267 // Stop group -> stop member -> group is stopped
268 pcmk__order_stops(member->parent, member, down_flags);
270 post_down_flags);
271
272 // Start group -> start member -> group is started
278
279 if (!member_data->ordered) {
280 pcmk__order_starts(member->parent, member,
284 if (member_data->promotable) {
290 }
291
292 } else if (member_data->previous_member == NULL) {
293 pcmk__order_starts(member->parent, member, pe_order_none);
294 if (member_data->promotable) {
297 }
298
299 } else {
300 // Order this member relative to the previous one
301 pcmk__order_starts(member_data->previous_member, member,
303 pcmk__order_stops(member, member_data->previous_member,
305 if (member_data->promotable) {
306 pcmk__order_resource_actions(member_data->previous_member,
307 RSC_PROMOTE, member, RSC_PROMOTE,
311 member_data->previous_member,
313 }
314 }
315
316 // Make sure partially active groups shut down in sequence
317 if (member->running_on != NULL) {
318 if (member_data->ordered && (member_data->previous_member != NULL)
319 && (member_data->previous_member->running_on == NULL)
320 && (member_data->last_active != NULL)
321 && (member_data->last_active->running_on != NULL)) {
322 pcmk__order_stops(member, member_data->last_active, pe_order_optional);
323 }
324 member_data->last_active = member;
325 }
326
327 member_data->previous_member = member;
328}
329
336void
338{
339 struct member_data member_data = { false, };
340
341 CRM_ASSERT(rsc != NULL);
342
343 /* Order group pseudo-actions relative to each other for restarting:
344 * stop group -> group is stopped -> start group -> group is started
345 */
352
353 member_data.ordered = pe__group_flag_is_set(rsc, pe__group_ordered);
354 member_data.colocated = pe__group_flag_is_set(rsc, pe__group_colocated);
355 member_data.promotable = pcmk_is_set(uber_parent(rsc)->flags, pe_rsc_promotable);
356 g_list_foreach(rsc->children, member_internal_constraints, &member_data);
357}
358
371static void
372colocate_group_with(pe_resource_t *dependent, const pe_resource_t *primary,
373 const pcmk__colocation_t *colocation)
374{
375 pe_resource_t *member = NULL;
376
377 if (dependent->children == NULL) {
378 return;
379 }
380
381 pe_rsc_trace(primary, "Processing %s (group %s with %s) for dependent",
382 colocation->id, dependent->id, primary->id);
383
385 // Colocate first member (internal colocations will handle the rest)
386 member = (pe_resource_t *) dependent->children->data;
387 member->cmds->apply_coloc_score(member, primary, colocation, true);
388 return;
389 }
390
391 if (colocation->score >= INFINITY) {
392 pcmk__config_err("%s: Cannot perform mandatory colocation between "
393 "non-colocated group and %s",
394 dependent->id, primary->id);
395 return;
396 }
397
398 // Colocate each member individually
399 for (GList *iter = dependent->children; iter != NULL; iter = iter->next) {
400 member = (pe_resource_t *) iter->data;
401 member->cmds->apply_coloc_score(member, primary, colocation, true);
402 }
403}
404
417static void
418colocate_with_group(pe_resource_t *dependent, const pe_resource_t *primary,
419 const pcmk__colocation_t *colocation)
420{
421 pe_resource_t *member = NULL;
422
423 pe_rsc_trace(primary,
424 "Processing colocation %s (%s with group %s) for primary",
425 colocation->id, dependent->id, primary->id);
426
427 if (pcmk_is_set(primary->flags, pe_rsc_provisional)) {
428 return;
429 }
430
432
433 if (colocation->score >= INFINITY) {
434 /* For mandatory colocations, the entire group must be assignable
435 * (and in the specified role if any), so apply the colocation based
436 * on the last member.
437 */
438 member = pe__last_group_member(primary);
439 } else if (primary->children != NULL) {
440 /* For optional colocations, whether the group is partially or fully
441 * up doesn't matter, so apply the colocation based on the first
442 * member.
443 */
444 member = (pe_resource_t *) primary->children->data;
445 }
446 if (member == NULL) {
447 return; // Nothing to colocate with
448 }
449
450 member->cmds->apply_coloc_score(dependent, member, colocation, false);
451 return;
452 }
453
454 if (colocation->score >= INFINITY) {
455 pcmk__config_err("%s: Cannot perform mandatory colocation with"
456 " non-colocated group %s",
457 dependent->id, primary->id);
458 return;
459 }
460
461 // Colocate dependent with each member individually
462 for (GList *iter = primary->children; iter != NULL; iter = iter->next) {
463 member = (pe_resource_t *) iter->data;
464 member->cmds->apply_coloc_score(dependent, member, colocation, false);
465 }
466}
467
481void
483 const pe_resource_t *primary,
484 const pcmk__colocation_t *colocation,
485 bool for_dependent)
486{
487 CRM_ASSERT((dependent != NULL) && (primary != NULL)
488 && (colocation != NULL));
489
490 if (for_dependent) {
491 colocate_group_with(dependent, primary, colocation);
492
493 } else {
494 // Method should only be called for primitive dependents
495 CRM_ASSERT(dependent->variant == pe_native);
496
497 colocate_with_group(dependent, primary, colocation);
498 }
499}
500
512{
513 // Default flags for a group action
517
518 CRM_ASSERT(action != NULL);
519
520 // Update flags considering each member's own flags for same action
521 for (GList *iter = action->rsc->children; iter != NULL; iter = iter->next) {
522 pe_resource_t *member = (pe_resource_t *) iter->data;
523
524 // Check whether member has the same action
525 enum action_tasks task = get_complex_task(member, action->task, TRUE);
526 const char *task_s = task2text(task);
527 pe_action_t *member_action = find_first_action(member->actions, NULL,
528 task_s, node);
529
530 if (member_action != NULL) {
531 enum pe_action_flags member_flags;
532
533 member_flags = member->cmds->action_flags(member_action, node);
534
535 // Group action is mandatory if any member action is
537 && !pcmk_is_set(member_flags, pe_action_optional)) {
538 pe_rsc_trace(action->rsc, "%s is mandatory because %s is",
539 action->uuid, member_action->uuid);
540 pe__clear_raw_action_flags(flags, "group action",
543 }
544
545 // Group action is unrunnable if any member action is
546 if (!pcmk__str_eq(task_s, action->task, pcmk__str_none)
548 && !pcmk_is_set(member_flags, pe_action_runnable)) {
549
550 pe_rsc_trace(action->rsc, "%s is unrunnable because %s is",
551 action->uuid, member_action->uuid);
552 pe__clear_raw_action_flags(flags, "group action",
555 }
556
557 /* Group (pseudo-)actions other than stop or demote are unrunnable
558 * unless every member will do it.
559 */
560 } else if ((task != stop_rsc) && (task != action_demote)) {
561 pe_rsc_trace(action->rsc,
562 "%s is not runnable because %s will not %s",
563 action->uuid, member->id, task_s);
564 pe__clear_raw_action_flags(flags, "group action",
566 }
567 }
568
569 return flags;
570}
571
594uint32_t
596 const pe_node_t *node, uint32_t flags,
597 uint32_t filter, uint32_t type,
599{
600 uint32_t changed = pcmk__updated_none;
601
602 CRM_ASSERT((first != NULL) && (then != NULL) && (data_set != NULL));
603
604 // Group method can be called only for group action as "then" action
605 CRM_ASSERT(then->rsc != NULL);
606
607 // Update the actions for the group itself
608 changed |= pcmk__update_ordered_actions(first, then, node, flags, filter,
609 type, data_set);
610
611 // Update the actions for each group member
612 for (GList *iter = then->rsc->children; iter != NULL; iter = iter->next) {
613 pe_resource_t *member = (pe_resource_t *) iter->data;
614
615 pe_action_t *member_action = find_first_action(member->actions, NULL,
616 then->task, node);
617
618 if (member_action != NULL) {
619 changed |= member->cmds->update_ordered_actions(first,
620 member_action, node,
621 flags, filter, type,
622 data_set);
623 }
624 }
625 return changed;
626}
627
635void
637{
638 GList *node_list_orig = NULL;
639 GList *node_list_copy = NULL;
640 bool reset_scores = true;
641
642 CRM_ASSERT((rsc != NULL) && (location != NULL));
643
644 node_list_orig = location->node_list_rh;
645 node_list_copy = pcmk__copy_node_list(node_list_orig, true);
646 reset_scores = pe__group_flag_is_set(rsc, pe__group_colocated);
647
648 // Apply the constraint for the group itself (updates node scores)
649 pcmk__apply_location(rsc, location);
650
651 // Apply the constraint for each member
652 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
653 pe_resource_t *member = (pe_resource_t *) iter->data;
654
655 member->cmds->apply_location(member, location);
656
657 if (reset_scores) {
658 /* The first member of colocated groups needs to use the original
659 * node scores, but subsequent members should work on a copy, since
660 * the first member's scores already incorporate theirs.
661 */
662 reset_scores = false;
663 location->node_list_rh = node_list_copy;
664 }
665 }
666
667 location->node_list_rh = node_list_orig;
668 g_list_free_full(node_list_copy, free);
669}
670
671// Group implementation of resource_alloc_functions_t:colocated_resources()
672GList *
674 GList *colocated_rscs)
675{
676 pe_resource_t *member = NULL;
677
678 CRM_ASSERT(rsc != NULL);
679
680 if (orig_rsc == NULL) {
681 orig_rsc = rsc;
682 }
683
685 || pe_rsc_is_clone(rsc->parent)) {
686 /* This group has colocated members and/or is cloned -- either way,
687 * add every child's colocated resources to the list.
688 */
689 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
690 member = (pe_resource_t *) iter->data;
691 colocated_rscs = member->cmds->colocated_resources(member, orig_rsc,
692 colocated_rscs);
693 }
694
695 } else if (rsc->children != NULL) {
696 /* This group's members are not colocated, and the group is not cloned,
697 * so just add the first child's colocations to the list.
698 */
699 member = (pe_resource_t *) rsc->children->data;
700 colocated_rscs = member->cmds->colocated_resources(member, orig_rsc,
701 colocated_rscs);
702 }
703
704 // Now consider colocations where the group itself is specified
705 colocated_rscs = pcmk__colocated_resources(rsc, orig_rsc, colocated_rscs);
706
707 return colocated_rscs;
708}
709
710// Group implementation of resource_alloc_functions_t:add_utilization()
711void
713 const pe_resource_t *orig_rsc, GList *all_rscs,
714 GHashTable *utilization)
715{
716 pe_resource_t *member = NULL;
717
718 CRM_ASSERT((rsc != NULL) && (orig_rsc != NULL) && (utilization != NULL));
719
721 return;
722 }
723
724 pe_rsc_trace(orig_rsc, "%s: Adding group %s as colocated utilization",
725 orig_rsc->id, rsc->id);
727 || pe_rsc_is_clone(rsc->parent)) {
728 // Every group member will be on same node, so sum all members
729 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
730 member = (pe_resource_t *) iter->data;
731
733 && (g_list_find(all_rscs, member) == NULL)) {
734 member->cmds->add_utilization(member, orig_rsc, all_rscs,
735 utilization);
736 }
737 }
738
739 } else if (rsc->children != NULL) {
740 // Just add first member's utilization
741 member = (pe_resource_t *) rsc->children->data;
742 if ((member != NULL)
744 && (g_list_find(all_rscs, member) == NULL)) {
745
746 member->cmds->add_utilization(member, orig_rsc, all_rscs,
747 utilization);
748 }
749 }
750}
751
752// Group implementation of resource_alloc_functions_t:shutdown_lock()
753void
755{
756 CRM_ASSERT(rsc != NULL);
757
758 for (GList *iter = rsc->children; iter != NULL; iter = iter->next) {
759 pe_resource_t *member = (pe_resource_t *) iter->data;
760
761 member->cmds->shutdown_lock(member);
762 }
763}
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
Definition: operations.c:45
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:121
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:912
enum crm_ais_msg_types type
Definition: cpg.c:3
char data[0]
Definition: cpg.c:10
#define RSC_PROMOTE
Definition: crm.h:205
#define RSC_DEMOTE
Definition: crm.h:207
#define RSC_STARTED
Definition: crm.h:200
#define RSC_STOPPED
Definition: crm.h:203
#define RSC_START
Definition: crm.h:199
#define INFINITY
Definition: crm.h:99
#define RSC_STOP
Definition: crm.h:202
#define RSC_PROMOTED
Definition: crm.h:206
#define RSC_DEMOTED
Definition: crm.h:208
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)
#define pcmk__order_starts(rsc1, rsc2, flags)
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
G_GNUC_INTERNAL void pcmk__add_this_with(pe_resource_t *rsc, pcmk__colocation_t *colocation)
G_GNUC_INTERNAL GList * pcmk__colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
@ pcmk__updated_none
#define pcmk__order_stops(rsc1, rsc2, flags)
G_GNUC_INTERNAL void pcmk__apply_location(pe_resource_t *rsc, pe__location_t *constraint)
G_GNUC_INTERNAL void pcmk__add_with_this(pe_resource_t *rsc, pcmk__colocation_t *colocation)
G_GNUC_INTERNAL uint32_t pcmk__update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
#define pcmk__config_err(fmt...)
#define XML_RSC_ATTR_PROMOTABLE
Definition: msg_xml.h:232
pe_working_set_t * data_set
const char * action
Definition: pcmk_fence.c:30
void pcmk__group_shutdown_lock(pe_resource_t *rsc)
GList * pcmk__group_colocated_resources(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
void pcmk__group_internal_constraints(pe_resource_t *rsc)
void pcmk__group_create_actions(pe_resource_t *rsc)
void pcmk__group_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
enum pe_action_flags pcmk__group_action_flags(pe_action_t *action, const pe_node_t *node)
void pcmk__group_apply_location(pe_resource_t *rsc, pe__location_t *location)
uint32_t pcmk__group_update_ordered_actions(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
void pcmk__group_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
pe_node_t * pcmk__group_assign(pe_resource_t *rsc, const pe_node_t *prefer)
GList * pcmk__copy_node_list(const GList *list, bool reset)
#define pe_rsc_managed
Definition: pe_types.h:257
@ pe_order_implies_first_printed
Definition: pe_types.h:508
@ pe_order_restart
Definition: pe_types.h:503
@ pe_order_implies_then
Definition: pe_types.h:485
@ pe_order_none
Definition: pe_types.h:480
@ pe_order_implies_then_printed
Definition: pe_types.h:509
@ pe_order_optional
Definition: pe_types.h:481
@ pe_order_runnable_left
Definition: pe_types.h:491
#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:298
@ pe_action_optional
Definition: pe_types.h:301
@ pe_action_runnable
Definition: pe_types.h:300
@ pe_action_pseudo
Definition: pe_types.h:299
@ 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 pe__show_node_weights(level, rsc, text, nodes, data_set)
Definition: internal.h:394
#define pe__clear_raw_action_flags(action_flags, action_name, flags_to_clear)
Definition: internal.h:111
bool pe__group_flag_is_set(const pe_resource_t *group, uint32_t flags)
Definition: group.c:57
pe_resource_t * pe__last_group_member(const pe_resource_t *group)
Definition: group.c:37
@ pe__group_ordered
Definition: internal.h:37
@ pe__group_colocated
Definition: internal.h:38
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
Definition: pe_actions.c:940
pe_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pe_node_t *on_node)
Definition: pe_actions.c:1296
void pe__set_next_role(pe_resource_t *rsc, enum rsc_role_e role, const char *why)
Definition: complex.c:1120
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition: internal.h:80
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:46
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
Definition: pe_actions.c:1262
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:47
#define pe__set_resource_flags(resource, flags_to_set)
Definition: internal.h:74
#define pe__clear_action_flags(action, flags_to_clear)
Definition: internal.h:95
#define pe__set_order_flags(order_flags, flags_to_set)
Definition: internal.h:138
#define pe__set_action_flags(action, flags_to_set)
Definition: internal.h:86
#define CRM_ASSERT(expr)
Definition: results.h:42
@ pcmk__str_none
pe_resource_t * rsc
Definition: pe_types.h:406
char * uuid
Definition: pe_types.h:411
char * task
Definition: pe_types.h:410
GList * running_on
Definition: pe_types.h:373
GList * actions
Definition: pe_types.h:366
enum pe_obj_types variant
Definition: pe_types.h:338
GHashTable * meta
Definition: pe_types.h:380
GList * rsc_cons
Definition: pe_types.h:364
GList * rsc_cons_lhs
Definition: pe_types.h:363
GList * children
Definition: pe_types.h:384
pe_working_set_t * cluster
Definition: pe_types.h:335
char * id
Definition: pe_types.h:329
GHashTable * allowed_nodes
Definition: pe_types.h:375
pe_node_t * allocated_to
Definition: pe_types.h:370
unsigned long long flags
Definition: pe_types.h:355
pe_resource_t * parent
Definition: pe_types.h:336
resource_alloc_functions_t * cmds
Definition: pe_types.h:341
enum rsc_role_e next_role
Definition: pe_types.h:378
enum rsc_role_e role
Definition: pe_types.h:377
unsigned long long flags
Definition: pe_types.h:153
void(* apply_location)(pe_resource_t *rsc, pe__location_t *location)
uint32_t(* update_ordered_actions)(pe_action_t *first, pe_action_t *then, const pe_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pe_working_set_t *data_set)
void(* apply_coloc_score)(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
void(* add_utilization)(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void(* create_actions)(pe_resource_t *rsc)
enum pe_action_flags(* action_flags)(pe_action_t *action, const pe_node_t *node)
void(* shutdown_lock)(pe_resource_t *rsc)
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
void(* internal_constraints)(pe_resource_t *rsc)
pe_node_t *(* assign)(pe_resource_t *rsc, const pe_node_t *prefer)