37 instance->
id, pe__node_name(node));
43 "%s cannot run on %s: node cannot run resources",
44 instance->
id, pe__node_name(node));
49 if (allowed_node == NULL) {
50 crm_warn(
"%s cannot run on %s: node not allowed",
51 instance->
id, pe__node_name(node));
55 if (allowed_node->
weight < 0) {
56 pe_rsc_trace(instance,
"%s cannot run on %s: parent score is %s there",
57 instance->
id, pe__node_name(node),
62 if (allowed_node->
count >= max_per_node) {
64 "%s cannot run on %s: node already has %d instance%s",
65 instance->
id, pe__node_name(node), max_per_node,
70 pe_rsc_trace(instance,
"%s can run on %s (%d already running)",
71 instance->
id, pe__node_name(node), allowed_node->
count);
83 ban_unavailable_allowed_nodes(
pcmk_resource_t *instance,
int max_per_node)
90 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
91 if (!can_run_instance(instance, node, max_per_node)) {
92 pe_rsc_trace(instance,
"Banning %s from unavailable node %s",
93 instance->
id, pe__node_name(node));
95 for (GList *child_iter = instance->
children;
96 child_iter != NULL; child_iter = child_iter->next) {
102 if (child_node != NULL) {
104 "Banning %s child %s " 105 "from unavailable node %s",
106 instance->
id, child->
id,
107 pe__node_name(node));
132 g_hash_table_insert(table, (gpointer) node->
details->
id, node);
144 apply_parent_colocations(
const pcmk_resource_t *rsc, GHashTable **nodes)
148 for (
const GList *iter = colocations; iter != NULL; iter = iter->next) {
157 g_list_free(colocations);
160 for (
const GList *iter = colocations; iter != NULL; iter = iter->next) {
165 if (!pcmk__colocation_has_influence(colocation, rsc)) {
172 g_list_free(colocations);
197 pcmk_node_t *current_node1 = pe__current_node(instance1);
198 pcmk_node_t *current_node2 = pe__current_node(instance2);
199 GHashTable *colocated_scores1 = NULL;
200 GHashTable *colocated_scores2 = NULL;
203 && (instance2 != NULL) && (instance2->
parent != NULL)
204 && (current_node1 != NULL) && (current_node2 != NULL));
207 colocated_scores1 = new_node_table(current_node1);
208 colocated_scores2 = new_node_table(current_node2);
211 apply_parent_colocations(instance1, &colocated_scores1);
212 apply_parent_colocations(instance2, &colocated_scores2);
215 node1 = g_hash_table_lookup(colocated_scores1, current_node1->
details->
id);
216 node2 = g_hash_table_lookup(colocated_scores2, current_node2->
details->
id);
220 crm_trace(
"Assign %s (%d on %s) after %s (%d on %s)",
226 crm_trace(
"Assign %s (%d on %s) before %s (%d on %s)",
232 g_hash_table_destroy(colocated_scores1);
233 g_hash_table_destroy(colocated_scores2);
251 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
273 (*node)->details->id);
275 if ((allowed == NULL) || (allowed->
weight < 0)) {
276 pe_rsc_trace(rsc,
"%s: current location (%s) is unavailable",
277 rsc->
id, pe__node_name(*node));
304 CRM_ASSERT((instance1 != NULL) && (instance2 != NULL));
307 div1 = strrchr(instance1->
id,
':');
309 div1 = strrchr(instance1->
id,
'-');
311 div2 = strrchr(instance2->
id,
':');
313 div2 = strrchr(instance2->
id,
'-');
317 return (gint) (strtol(div1 + 1, NULL, 10) - strtol(div2 + 1, NULL, 10));
351 unsigned int nnodes1 = 0;
352 unsigned int nnodes2 = 0;
360 CRM_ASSERT((instance1 != NULL) && (instance2 != NULL));
368 if ((nnodes1 > 0) && (nnodes2 > 0)) {
369 if (nnodes1 < nnodes2) {
370 crm_trace(
"Assign %s (active on %d) before %s (active on %d): " 371 "less multiply active",
372 instance1->
id, nnodes1, instance2->
id, nnodes2);
375 }
else if (nnodes1 > nnodes2) {
376 crm_trace(
"Assign %s (active on %d) after %s (active on %d): " 377 "more multiply active",
378 instance1->
id, nnodes1, instance2->
id, nnodes2);
386 can1 = node_is_allowed(instance1, &
node1);
387 can2 = node_is_allowed(instance2, &
node2);
389 crm_trace(
"Assign %s before %s: not active on a disallowed node",
390 instance1->
id, instance2->
id);
393 }
else if (!can1 && can2) {
394 crm_trace(
"Assign %s after %s: active on a disallowed node",
395 instance1->
id, instance2->
id);
401 crm_trace(
"Assign %s before %s: priority (%d > %d)",
402 instance1->
id, instance2->
id,
407 crm_trace(
"Assign %s after %s: priority (%d < %d)",
408 instance1->
id, instance2->
id,
415 crm_trace(
"No assignment preference for %s vs. %s: inactive",
416 instance1->
id, instance2->
id);
419 }
else if (
node1 == NULL) {
420 crm_trace(
"Assign %s after %s: active", instance1->
id, instance2->
id);
423 }
else if (
node2 == NULL) {
424 crm_trace(
"Assign %s before %s: active", instance1->
id, instance2->
id);
432 crm_trace(
"Assign %s before %s: current node can run resources",
433 instance1->
id, instance2->
id);
436 }
else if (!can1 && can2) {
437 crm_trace(
"Assign %s after %s: current node can't run resources",
438 instance1->
id, instance2->
id);
446 crm_trace(
"No assignment preference for %s vs. %s: " 447 "parent not allowed on either instance's current node",
448 instance1->
id, instance2->
id);
451 }
else if (
node1 == NULL) {
452 crm_trace(
"Assign %s after %s: parent not allowed on current node",
453 instance1->
id, instance2->
id);
456 }
else if (
node2 == NULL) {
457 crm_trace(
"Assign %s before %s: parent allowed on current node",
458 instance1->
id, instance2->
id);
464 crm_trace(
"Assign %s before %s: fewer active instances on current node",
465 instance1->
id, instance2->
id);
469 crm_trace(
"Assign %s after %s: more active instances on current node",
470 instance1->
id, instance2->
id);
475 can1 = did_fail(instance1);
476 can2 = did_fail(instance2);
478 crm_trace(
"Assign %s before %s: not failed",
479 instance1->
id, instance2->
id);
481 }
else if (can1 && !can2) {
483 instance1->
id, instance2->
id);
488 rc = cmp_instance_by_colocation(instance1, instance2);
496 crm_trace(
"Assign %s before %s: instance number",
497 instance1->
id, instance2->
id);
499 crm_trace(
"Assign %s after %s: instance number",
500 instance1->
id, instance2->
id);
502 crm_trace(
"No assignment preference for %s vs. %s",
503 instance1->
id, instance2->
id);
525 if (assigned_to == NULL) {
530 if (allowed == NULL) {
560 pe_rsc_trace(instance,
"Assigning %s (preferring %s)", instance->
id,
561 ((prefer == NULL)?
"no node" : prefer->
details->
uname));
565 "Assignment loop detected involving %s colocations",
569 ban_unavailable_allowed_nodes(instance, max_per_node);
572 chosen = instance->
cmds->
assign(instance, prefer, (prefer == NULL));
573 increment_parent_count(instance, chosen);
599 GHashTable *allowed_orig = NULL;
600 GHashTable *allowed_orig_parent =
parent->allowed_nodes;
603 pe_rsc_trace(instance,
"Trying to assign %s to its current node %s",
604 instance->
id, pe__node_name(current));
610 "Not assigning %s to current node %s: unavailable",
611 instance->
id, pe__node_name(current));
638 while (reserved < available) {
639 chosen = assign_instance(instance, current, max_per_node);
641 if (pe__same_node(chosen, current)) {
647 pe_rsc_debug(instance,
"Rolling back node scores for %s", instance->
id);
650 if (chosen == NULL) {
653 "Not assigning %s to current node %s: unavailable",
654 instance->
id, pe__node_name(current));
661 "Not assigning %s to current node %s: %s is better",
662 instance->
id, pe__node_name(current),
663 pe__node_name(chosen));
666 if (++reserved >= available) {
668 "Not assigning %s to current node %s: " 669 "other assignments are more important",
670 instance->
id, pe__node_name(current));
674 "Reserved an instance of %s for %s. Retrying " 675 "assignment of %s to %s",
676 rsc->
id, pe__node_name(chosen), instance->
id,
677 pe__node_name(current));
685 g_hash_table_destroy(allowed_orig);
688 g_hash_table_destroy(
parent->allowed_nodes);
689 parent->allowed_nodes = allowed_orig_parent;
691 if (chosen == NULL) {
695 pe_rsc_trace(instance,
"Assigned %s to current node %s",
696 instance->
id, pe__node_name(current));
697 increment_parent_count(instance, chosen);
712 unsigned int available_nodes = 0;
717 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
723 return available_nodes;
749 node = pe__current_node(instance);
751 pe_rsc_trace(instance,
"Not assigning %s to %s early (unavailable)",
752 instance->
id, pe__node_name(node));
758 if ((parent_node != NULL) && (parent_node->
count >= optimal_per_node)) {
760 "Not assigning %s to %s early " 761 "(optimal instances already assigned)",
762 instance->
id, pe__node_name(node));
780 int max_total,
int max_per_node)
783 unsigned int available_nodes = reset_allowed_node_counts(collective);
785 int optimal_per_node = 0;
791 if (available_nodes > 0) {
792 optimal_per_node = max_total / available_nodes;
794 if (optimal_per_node < 1) {
795 optimal_per_node = 1;
799 "Assigning up to %d %s instance%s to up to %u node%s " 800 "(at most %d per host, %d optimal)",
803 max_per_node, optimal_per_node);
806 for (iter = instances; (iter != NULL) && (assigned < max_total);
808 int available = max_total - assigned;
810 instance = iter->data;
815 current = preferred_node(instance, optimal_per_node);
816 if ((current != NULL)
817 && assign_instance_early(collective, instance, current,
818 max_per_node, available)) {
823 pe_rsc_trace(collective,
"Assigned %d of %d instance%s to current node",
826 for (iter = instances; iter != NULL; iter = iter->next) {
834 current = pe__current_node(instance);
836 const char *unmanaged =
"";
839 unmanaged =
"Unmanaged resource ";
841 crm_notice(
"%s%s is running on %s which is no longer allowed",
842 unmanaged, instance->
id, pe__node_name(current));
846 if (assigned >= max_total) {
848 "Not assigning %s because maximum %d instances " 850 instance->
id, max_total);
852 "collective_limit_reached", collective->
cluster);
854 }
else if (assign_instance(instance, NULL, max_per_node) != NULL) {
859 pe_rsc_debug(collective,
"Assigned %d of %d possible instance%s of %s",
891 const GList *iter = NULL;
902 (iter != NULL) && !pcmk_all_flags_set(*state,
instance_all);
929 pe_rsc_trace(instance,
"Instance is starting due to %s",
933 pe_rsc_trace(instance,
"%s doesn't affect %s state (%s)",
935 (optional?
"optional" :
"unrunnable"));
947 pe_rsc_trace(instance,
"Instance is stopping due to %s",
951 pe_rsc_trace(instance,
"%s doesn't affect %s state (%s)",
953 (optional?
"optional" :
"unrunnable"));
983 pe_rsc_trace(collective,
"Creating collective instance actions for %s",
987 for (GList *iter = instances; iter != NULL; iter = iter->next) {
991 check_instance_state(instance, &state);
1035 static inline GList *
1079 CRM_CHECK((instance != NULL) && (node != NULL),
return false);
1082 && (role != instance->
fns->
state(instance, current))) {
1084 "%s is not a compatible instance (role is not %s)",
1091 instance_node = instance->
fns->
location(instance, NULL, current);
1094 if (instance_node == NULL) {
1096 "%s is not a compatible instance (not assigned to a node)",
1101 if (!pe__same_node(instance_node, node)) {
1103 "%s is not a compatible instance (assigned to %s not %s)",
1104 instance->
id, pe__node_name(instance_node),
1105 pe__node_name(node));
1131 GList *instances = NULL;
1133 instances = get_instance_list(rsc);
1134 for (GList *iter = instances; iter != NULL; iter = iter->next) {
1139 "Found %s %s instance %s compatible with %s on %s",
1141 rsc->
id, instance->
id, match_rsc->
id,
1142 pe__node_name(node));
1143 free_instance_list(rsc, instances);
1147 free_instance_list(rsc, instances);
1149 pe_rsc_trace(match_rsc,
"No %s %s instance found compatible with %s on %s",
1151 rsc->
id, match_rsc->
id, pe__node_name(node));
1174 GList *nodes = NULL;
1178 node = match_rsc->
fns->
location(match_rsc, NULL, current);
1180 return find_compatible_instance_on_node(match_rsc, rsc, node, role,
1187 for (GList *iter = nodes; (iter != NULL) && (instance == NULL);
1188 iter = iter->next) {
1189 instance = find_compatible_instance_on_node(match_rsc, rsc,
1194 if (instance == NULL) {
1195 pe_rsc_debug(rsc,
"No %s instance found compatible with %s",
1196 rsc->
id, match_rsc->
id);
1222 "%s has no instance to order before stopping " 1224 first->
rsc->
id, then_instance->
id);
1232 "Inhibiting %s from being active " 1233 "because there is no %s instance to interleave",
1234 then_instance->
id, first->
rsc->
id);
1295 if (matching_action != NULL) {
1296 return matching_action;
1302 crm_trace(
"No %s action found for %s%s",
1307 crm_err(
"No %s action found for %s to interleave (bug?)",
1308 action_name, instance->
id);
1332 char *action_type = NULL;
1333 const char *action_name =
action->task;
1341 action_name = strstr(action_type,
"_notify_");
1344 action_name += strlen(
"_notify_");
1376 GList *instances = NULL;
1378 const char *orig_first_task = orig_action_name(first);
1386 instances = get_instance_list(then->
rsc);
1387 for (GList *iter = instances; iter != NULL; iter = iter->next) {
1400 if (first_instance == NULL) {
1401 if (unassign_if_mandatory(first, then, then_instance,
type,
1408 first_action = find_instance_action(first, first_instance,
1409 orig_first_task, node,
true);
1410 if (first_action == NULL) {
1414 then_action = find_instance_action(then, then_instance, then->
task,
1416 if (then_action == NULL) {
1426 first_action, then_action, node,
1430 free_instance_list(then->
rsc, instances);
1446 bool interleave =
false;
1449 if ((first->
rsc == NULL) || (then->
rsc == NULL)) {
1450 crm_trace(
"Not interleaving %s with %s: not resource actions",
1455 if (first->
rsc == then->
rsc) {
1456 crm_trace(
"Not interleaving %s with %s: same resource",
1463 crm_trace(
"Not interleaving %s with %s: not clones or bundles",
1477 pe_rsc_trace(rsc,
"'%s then %s' will %sbe interleaved (based on %s)",
1478 first->
uuid, then->
uuid, (interleave?
"" :
"not "), rsc->
id);
1507 uint32_t
flags, uint32_t filter, uint32_t
type)
1510 uint32_t instance_flags = 0;
1516 if (instance_action == NULL) {
1534 after_iter != NULL; after_iter = after_iter->next) {
1570 uint32_t filter, uint32_t
type,
1575 if (then->
rsc == NULL) {
1578 }
else if (can_interleave_actions(first, then)) {
1579 return update_interleaved_actions(first, then, node, filter,
type);
1583 GList *instances = get_instance_list(then->
rsc);
1590 for (GList *iter = instances; iter != NULL; iter = iter->next) {
1593 changed |= update_noninterleaved_actions(instance, first, then,
1596 free_instance_list(then->
rsc, instances);
1601 #define pe__clear_action_summary_flags(flags, action, flag) do { \ 1602 flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \ 1603 "Action summary", action->rsc->id, \ 1604 flags, flag, #flag); \ 1621 bool any_runnable =
false;
1622 const char *action_name = orig_action_name(
action);
1629 for (
const GList *iter = instances; iter != NULL; iter = iter->next) {
1633 uint32_t instance_flags;
1637 instance_node = node;
1641 action_name, instance_node);
1642 if (instance_action == NULL) {
1644 instance->
id, action_name, pe__node_name(node));
1649 instance->
id, instance_action->
uuid, action_name,
1650 pe__node_name(node));
1657 pe_rsc_trace(instance,
"%s is mandatory because %s is",
1666 any_runnable =
true;
1670 if (!any_runnable) {
1672 "%s is not runnable because no instance can run %s",
1673 action->uuid, action_name);
pcmk_assignment_methods_t * cmds
Resource assignment methods.
#define CRM_CHECK(expr, failure_action)
const char * task2text(enum action_tasks task)
void pe__create_clone_notif_pseudo_ops(pcmk_resource_t *clone, pcmk_action_t *start, pcmk_action_t *started, pcmk_action_t *stop, pcmk_action_t *stopped)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
void pcmk__create_instance_actions(pcmk_resource_t *collective, GList *instances)
#define crm_notice(fmt, args...)
'then' is runnable (and migratable) only if 'first' is runnable
pcmk_scheduler_t * cluster
Cluster that resource is part of.
#define pe_rsc_debug(rsc, fmt, args...)
Whether action should not be executed.
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
#define pe__set_action_flags(action, flags_to_set)
void(* create_actions)(pcmk_resource_t *rsc)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
uint32_t(* action_flags)(pcmk_action_t *action, const pcmk_node_t *node)
GList * children
Resource's child resources, if any.
int count
Counter reused by assignment and promotion code.
gboolean order_actions(pcmk_action_t *lh_action, pcmk_action_t *rh_action, uint32_t flags)
enum rsc_role_e(* state)(const pcmk_resource_t *rsc, gboolean current)
Get resource's current or assigned role.
void pcmk__assign_instances(pcmk_resource_t *collective, GList *instances, int max_total, int max_per_node)
Implementation of pcmk_action_t.
GHashTable * meta
Resource's meta-attributes.
void(* add_colocated_node_scores)(pcmk_resource_t *source_rsc, const pcmk_resource_t *target_rsc, const char *log_id, GHashTable **nodes, const pcmk__colocation_t *colocation, float factor, uint32_t flags)
action_tasks
Possible actions (including some pseudo-actions)
#define CRM_LOG_ASSERT(expr)
pcmk_node_t *(* assign)(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
G_GNUC_INTERNAL uint32_t pcmk__update_ordered_actions(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)
enum crm_ais_msg_types type
G_GNUC_INTERNAL void pcmk__update_action_for_orderings(pcmk_action_t *action, pcmk_scheduler_t *scheduler)
bool pcmk__ends_with(const char *s, const char *match)
Implementation of pcmk_scheduler_t.
G_GNUC_INTERNAL bool pcmk__node_available(const pcmk_node_t *node, bool consider_score, bool consider_guest)
G_GNUC_INTERNAL bool pcmk__assign_resource(pcmk_resource_t *rsc, pcmk_node_t *node, bool force, bool stop_if_fail)
#define pe__set_resource_flags(resource, flags_to_set)
gint pcmk__cmp_instance_number(gconstpointer a, gconstpointer b)
const char * role2text(enum rsc_role_e role)
pcmk_action_t * pe__new_rsc_pseudo_action(pcmk_resource_t *rsc, const char *task, bool optional, bool runnable)
#define PCMK_ACTION_DEMOTE
int weight
Node score for a given resource.
G_GNUC_INTERNAL void pcmk__copy_node_tables(const pcmk_resource_t *rsc, GHashTable **copy)
pcmk_resource_t * parent
Resource's parent resource, if any.
#define crm_warn(fmt, args...)
Whether resource is in the process of being assigned to a node.
Implementation of pcmk_resource_t.
const pcmk_resource_t * pe__get_rsc_in_container(const pcmk_resource_t *instance)
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
int priority
Configured priority.
Whether resource is considered failed.
GList * actions_after
For Pacemaker use only.
#define pe__clear_action_flags(action, flags_to_clear)
#define pe__clear_action_summary_flags(flags, action, flag)
#define crm_trace(fmt, args...)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
Basic node information.
#define PCMK_ACTION_START
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
G_GNUC_INTERNAL void pcmk__unassign_resource(pcmk_resource_t *rsc)
#define PCMK_ACTION_NOTIFIED
Whether resource is blocked from further action.
Implementation of pcmk_node_t.
bool is_set_recursive(const pcmk_resource_t *rsc, long long flag, bool any)
enum pe_obj_types variant
Resource variant.
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
uint32_t pcmk__collective_action_flags(pcmk_action_t *action, const GList *instances, const pcmk_node_t *node)
const char * id
Node ID at the cluster layer.
G_GNUC_INTERNAL pcmk_node_t * pcmk__top_allowed_node(const pcmk_resource_t *rsc, const pcmk_node_t *node)
pcmk_resource_t * primary
Unspecified or unknown action.
Whether resource has not yet been assigned to a node.
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 void pcmk__restore_node_tables(pcmk_resource_t *rsc, GHashTable *backup)
bool pcmk__instance_matches(const pcmk_resource_t *instance, const pcmk_node_t *node, enum rsc_role_e role, bool current)
G_GNUC_INTERNAL GList * pcmk__with_this_colocations(const pcmk_resource_t *rsc)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Whether action is runnable.
pcmk_rsc_methods_t * fns
Resource object methods.
G_GNUC_INTERNAL GHashTable * pcmk__copy_node_table(GHashTable *nodes)
pcmk_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pcmk_node_t *on_node)
#define pcmk__set_updated_flags(au_flags, action, flags_to_set)
#define crm_err(fmt, args...)
pcmk_scheduler_t * scheduler
Whether action does not require invoking an agent.
#define PCMK_ACTION_STOPPED
G_GNUC_INTERNAL GList * pcmk__this_with_colocations(const pcmk_resource_t *rsc)
pcmk_node_t *(* active_node)(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
Find a node (and optionally count all) where resource is active.
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
#define PCMK_ACTION_PROMOTE
pcmk_resource_t * dependent
#define pcmk__plural_s(i)
GList * running_on
Nodes where resource may be active.
uint32_t(* update_ordered_actions)(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pcmk_node_t *active_node)
Whether action is allowed to be part of a live migration.
#define PCMK_ACTION_PROMOTED
gboolean crm_is_true(const char *s)
pcmk_resource_t * rsc
Resource to apply action to, if any.
Resource role is unknown.
#define pe_rsc_trace(rsc, fmt, args...)
#define PCMK_ACTION_RUNNING
#define XML_RSC_ATTR_INTERLEAVE
#define PCMK_ACTION_DEMOTED
enum action_tasks get_complex_task(const pcmk_resource_t *rsc, const char *name)
Whether resource is managed.
Whether resource has been removed from the configuration.
GList * pe__bundle_containers(const pcmk_resource_t *bundle)
#define PCMK_ACTION_NOTIFY
#define pe_rsc_info(rsc, fmt, args...)
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
uint32_t pcmk__instance_update_ordered_actions(pcmk_action_t *first, pcmk_action_t *then, const pcmk_node_t *node, uint32_t flags, uint32_t filter, uint32_t type, pcmk_scheduler_t *scheduler)