17 #define VARIANT_CLONE 1 30 while (g_hash_table_iter_next(&iter, NULL, (
void **)&local_node)) {
31 can_run_instance(rsc, local_node, limit);
49 if (local_node == NULL) {
50 crm_warn(
"%s cannot run on %s: node not allowed",
51 rsc->
id, pe__node_name(node));
54 }
else if (local_node->
weight < 0) {
56 pe_rsc_trace(rsc,
"%s cannot run on %s: Parent node weight doesn't allow it.",
57 rsc->
id, pe__node_name(node));
59 }
else if (local_node->
count < limit) {
60 pe_rsc_trace(rsc,
"%s can run on %s (already running %d)",
61 rsc->
id, pe__node_name(node), local_node->
count);
65 pe_rsc_trace(rsc,
"%s cannot run on %s: node full (%d >= %d)",
66 rsc->
id, pe__node_name(node), local_node->
count, limit);
81 GHashTable *backup = NULL;
84 pe_rsc_trace(rsc,
"Checking allocation of %s (preferring %s, using %s parent colocations)",
86 (all_coloc?
"all" :
"some"));
92 pe_rsc_debug(rsc,
"Dependency loop detected involving %s", rsc->
id);
99 append_parent_colocation(rsc->
parent, rsc, all_coloc);
104 if (local_prefer == NULL || local_prefer->
weight < 0) {
105 pe_rsc_trace(rsc,
"Not pre-allocating %s to %s - unavailable", rsc->
id,
106 pe__node_name(prefer));
111 can_run_instance(rsc, NULL, limit);
117 crm_info(
"Not pre-allocating %s to %s because %s is better",
118 rsc->
id, pe__node_name(prefer), pe__node_name(chosen));
140 g_hash_table_destroy(backup);
152 for (; gIter != NULL; gIter = gIter->next) {
161 for (; gIter != NULL; gIter = gIter->next) {
164 if (!pcmk__colocation_has_influence(cons, child)) {
167 if (all || cons->
score < 0) {
184 int available_nodes = 0;
185 bool all_coloc =
false;
188 for(GList *nIter = nodes; nIter != NULL; nIter = nIter->next) {
197 all_coloc = (max < available_nodes) ?
true :
false;
199 if(available_nodes) {
200 loop_max = max / available_nodes;
206 pe_rsc_debug(rsc,
"Allocating up to %d %s instances to a possible %d nodes (at most %d per host, %d optimal)",
207 max, rsc->
id, available_nodes, per_host_max, loop_max);
210 for (GList *gIter = children; gIter != NULL && allocated < max; gIter = gIter->next) {
222 child_node = pe__current_node(child);
226 "Checking pre-allocation of %s to %s (%d remaining of %d)",
227 child->
id, pe__node_name(child_node), max - allocated,
231 pe_rsc_trace(rsc,
"Not pre-allocating because %s can not run %s",
232 pe__node_name(child_node), child->
id);
236 if ((local_node != NULL) && (local_node->
count >= loop_max)) {
238 "Not pre-allocating because %s already allocated " 239 "optimal instances", pe__node_name(child_node));
243 if (allocate_instance(child, child_node, all_coloc, per_host_max,
246 pe__node_name(child_node));
251 pe_rsc_trace(rsc,
"Done pre-allocating (%d of %d)", allocated, max);
253 for (GList *gIter = children; gIter != NULL; gIter = gIter->next) {
257 pe_node_t *child_node = pe__current_node(child);
260 if (local_node == NULL) {
261 crm_err(
"%s is running on %s which isn't allowed",
262 child->
id, pe__node_name(child_node));
267 }
else if (allocated >= max) {
268 pe_rsc_debug(rsc,
"Child %s not allocated - limit reached %d %d", child->
id, allocated, max);
271 if (allocate_instance(child, NULL, all_coloc, per_host_max,
278 pe_rsc_debug(rsc,
"Allocated %d %s instances of a possible %d",
279 allocated, rsc->
id, max);
295 clone_variant_data_t *clone_data = NULL;
297 get_clone_variant_data(clone_data, rsc);
303 pe_rsc_debug(rsc,
"Dependency loop detected involving %s", rsc->
id);
316 for (GList *gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
324 for (GList *gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
327 if (pcmk__colocation_has_influence(constraint, NULL)) {
347 clone_data->clone_node_max, rsc->
cluster);
360 clone_update_pseudo_status(
pe_resource_t * rsc, gboolean * stopping, gboolean * starting,
368 for (; gIter != NULL; gIter = gIter->next) {
371 clone_update_pseudo_status(child, stopping, starting, active);
386 for (; gIter != NULL; gIter = gIter->next) {
389 if (*starting && *stopping) {
396 }
else if (!pcmk_any_flags_set(
action->flags,
407 pe_rsc_trace(rsc,
"Skipping pseudo-op: %s run=%d, pseudo=%d",
429 for (GList *item = actions; item != NULL; item = item->next) {
441 g_list_free(actions);
461 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
464 stop = find_rsc_action(child,
RSC_STOP);
473 start = find_rsc_action(child,
RSC_START);
487 clone_variant_data_t *clone_data = NULL;
489 get_clone_variant_data(clone_data, rsc);
493 &clone_data->stop_notify);
494 child_ordering_constraints(rsc, rsc->
cluster);
506 gboolean child_active = FALSE;
507 gboolean child_starting = FALSE;
508 gboolean child_stopping = FALSE;
509 gboolean allow_dependent_migrations = TRUE;
519 for (GList *gIter = children; gIter != NULL; gIter = gIter->next) {
521 gboolean starting = FALSE;
522 gboolean stopping = FALSE;
525 clone_update_pseudo_status(child_rsc, &stopping, &starting, &child_active);
526 if (stopping && starting) {
527 allow_dependent_migrations = FALSE;
530 child_stopping |= stopping;
531 child_starting |= starting;
540 if (child_active || child_starting) {
544 if (start_notify != NULL && *start_notify == NULL) {
554 if (allow_dependent_migrations) {
558 if (stop_notify != NULL && *stop_notify == NULL) {
561 if (start_notify && *start_notify && *stop_notify) {
593 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
602 if (ordered && (last_rsc != NULL)) {
609 if (ordered && (last_rsc != NULL)) {
613 last_rsc = child_rsc;
627 CRM_CHECK(child_rsc && local_node,
return FALSE);
630 node = child_rsc->
fns->
location(child_rsc, NULL, current);
642 crm_trace(
"%s - %s vs %s", child_rsc->
id, pe__node_name(node),
643 pe__node_name(local_node));
646 crm_trace(
"%s - not allocated %d", child_rsc->
id, current);
658 GList *scratch = NULL;
661 local_node = local_child->
fns->
location(local_child, NULL, current);
666 scratch = g_hash_table_get_values(local_child->
allowed_nodes);
670 for (; gIter != NULL; gIter = gIter->next) {
681 g_list_free(scratch);
705 gboolean do_interleave = FALSE;
706 const char *interleave_s = NULL;
714 CRM_CHECK((colocation != NULL) && (dependent != NULL) && (primary != NULL),
718 pe_rsc_trace(primary,
"Processing constraint %s: %s -> %s %d",
719 colocation->
id, dependent->
id, primary->
id, colocation->
score);
729 pe_rsc_trace(primary,
"Handling %s as a clone colocation",
747 interleave_s = g_hash_table_lookup(colocation->
dependent->
meta,
756 "support the same number of instances per node",
761 do_interleave = TRUE;
769 }
else if (do_interleave) {
774 if (primary_instance != NULL) {
776 dependent->
id, primary_instance->
id);
781 crm_notice(
"Cannot pair %s with instance of %s",
782 dependent->
id, primary->
id);
786 pe_rsc_debug(primary,
"Cannot pair %s with instance of %s",
787 dependent->
id, primary->
id);
793 GList *affected_nodes = NULL;
796 for (; gIter != NULL; gIter = gIter->next) {
802 colocation->
id, pe__node_name(chosen),
804 affected_nodes = g_list_prepend(affected_nodes, chosen);
809 g_list_free(affected_nodes);
814 for (; gIter != NULL; gIter = gIter->next) {
834 int lpc = strlen(key);
836 for (; lpc > 0; lpc--) {
837 if (key[lpc] ==
'_' && stop == 0) {
840 }
else if (key[lpc] ==
'_') {
841 char *task_mutable = NULL;
844 task_mutable = strdup(key + lpc);
845 task_mutable[stop - lpc] = 0;
847 crm_trace(
"Extracted action '%s' from '%s'", task_mutable, key);
860 #define pe__clear_action_summary_flags(flags, action, flag) do { \ 861 flags = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \ 862 "Action summary", action->rsc->id, \ 863 flags, flag, #flag); \ 871 gboolean any_runnable = FALSE;
872 gboolean check_runnable = TRUE;
877 for (gIter = children; gIter != NULL; gIter = gIter->next) {
883 pe__node_name(node), child_action?child_action->
uuid:
"NA");
900 if (check_runnable && any_runnable == FALSE) {
922 pe_rsc_trace(rsc,
"Processing location constraint %s for %s", constraint->
id, rsc->
id);
926 for (; gIter != NULL; gIter = gIter->next) {
943 clone_variant_data_t *clone_data = NULL;
945 get_clone_variant_data(clone_data, rsc);
957 for (; gIter != NULL; gIter = gIter->next) {
967 clone_data->demote_notify = NULL;
969 clone_data->stop_notify = NULL;
971 clone_data->start_notify = NULL;
973 clone_data->promote_notify = NULL;
981 for (GList *child_iter = rsc->
children; child_iter != NULL;
982 child_iter = child_iter->next) {
986 if (rsc_known_on(child, node)) {
995 g_hash_table_iter_init(&iter, rsc->
known_on);
996 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &known_node)) {
997 if (node->
details == known_node->details) {
1009 for (GList *gIter = clone->
children; gIter != NULL; gIter = gIter->next) {
1012 if (rsc_known_on(child, node)) {
1028 if (child == NULL) {
1029 for (GList *child_iter = rsc->
children; child_iter && !child;
1030 child_iter = child_iter->next) {
1036 local_node = child_rsc->
fns->
location(child_rsc, NULL, FALSE);
1045 if (child == NULL) {
1069 pe_warn(
"Clone %s has no children", rsc->
id);
1093 return probe_anonymous_clone(rsc, node, rsc->
cluster);
1101 clone_variant_data_t *clone_data = NULL;
1103 get_clone_variant_data(clone_data, rsc);
1150 GHashTable *utilization)
1152 bool existing =
false;
1160 for (GList *iter = rsc->
children; iter != NULL; iter = iter->next) {
1162 if (g_list_find(all_rscs, child)) {
1166 for (GList *member_iter = child->
children; member_iter != NULL;
1167 member_iter = member_iter->next) {
1171 if (g_list_find(all_rscs, member) != NULL) {
1182 if (!existing && (rsc->
children != NULL)) {
#define CRM_CHECK(expr, failure_action)
#define PCMK_XA_PROMOTED_MAX_LEGACY
const char * task2text(enum action_tasks task)
#define pcmk__order_starts(rsc1, rsc2, flags)
#define crm_notice(fmt, args...)
G_GNUC_INTERNAL void pcmk__add_rsc_actions_to_graph(pe_resource_t *rsc)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe__set_action_flags(action, flags_to_set)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
int pe__clone_promoted_node_max(pe_resource_t *clone)
#define pe__clear_action_summary_flags(flags, action, flag)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
void(* internal_constraints)(pe_resource_t *rsc)
resource_alloc_functions_t * cmds
#define pcmk__order_stops(rsc1, rsc2, flags)
void pcmk__clone_shutdown_lock(pe_resource_t *rsc)
int pe__clone_promoted_max(pe_resource_t *clone)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
gboolean exclusive_discover
void clone_create_actions(pe_resource_t *rsc)
pe_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pe_node_t *on_node)
#define pcmk__config_err(fmt...)
G_GNUC_INTERNAL void pcmk__set_instance_roles(pe_resource_t *rsc)
resource_object_functions_t * fns
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pe_resource_t * dependent
void node_list_exclude(GHashTable *list, GList *list2, gboolean merge_scores)
G_GNUC_INTERNAL GList * pcmk__sort_nodes(GList *nodes, pe_node_t *active_node)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
pe_action_t * pe__new_rsc_pseudo_action(pe_resource_t *rsc, const char *task, bool optional, bool runnable)
G_GNUC_INTERNAL void pcmk__add_with_this(pe_resource_t *rsc, pcmk__colocation_t *colocation)
G_GNUC_INTERNAL void pcmk__add_colocated_node_scores(pe_resource_t *rsc, const char *log_id, GHashTable **nodes, const char *attr, float factor, uint32_t flags)
#define XML_RSC_ATTR_INCARNATION_MAX
void(* add_actions_to_graph)(pe_resource_t *rsc)
void clone_internal_constraints(pe_resource_t *rsc)
char * crm_meta_name(const char *field)
#define pe__set_resource_flags(resource, flags_to_set)
pe_node_t *(* assign)(pe_resource_t *rsc, const pe_node_t *prefer)
enum pe_action_flags(* action_flags)(pe_action_t *action, const pe_node_t *node)
#define PCMK_XA_PROMOTED_NODE_MAX_LEGACY
void clone_create_pseudo_actions(pe_resource_t *rsc, GList *children, notify_data_t **start_notify, notify_data_t **stop_notify)
#define pe_rsc_provisional
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
#define crm_warn(fmt, args...)
void clone_append_meta(pe_resource_t *rsc, xmlNode *xml)
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node, bool consider_score, bool consider_guest)
enum pe_action_flags clone_action_flags(pe_action_t *action, const pe_node_t *node)
G_GNUC_INTERNAL void pcmk__order_promotable_instances(pe_resource_t *clone)
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
enum action_tasks get_complex_task(pe_resource_t *rsc, const char *name, gboolean allow_non_atomic)
G_GNUC_INTERNAL bool pcmk__probe_resource_list(GList *rscs, pe_node_t *node)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
G_GNUC_INTERNAL gint pcmk__cmp_instance(gconstpointer a, gconstpointer b)
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
#define pe_rsc_promotable
pe_working_set_t * data_set
void(* create_actions)(pe_resource_t *rsc)
void distribute_children(pe_resource_t *rsc, GList *children, GList *nodes, int max, int per_host_max, pe_working_set_t *data_set)
bool pe__clone_is_ordered(pe_resource_t *clone)
pe_resource_t * find_compatible_child_by_node(const pe_resource_t *local_child, const pe_node_t *local_node, const pe_resource_t *rsc, enum rsc_role_e filter, gboolean current)
#define XML_RSC_ATTR_INCARNATION_NODEMAX
bool is_set_recursive(const pe_resource_t *rsc, long long flag, bool any)
G_GNUC_INTERNAL gint pcmk__cmp_instance_number(gconstpointer a, gconstpointer b)
#define pe_rsc_allocating
enum pe_obj_types variant
void(* add_utilization)(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void common_update_score(pe_resource_t *rsc, const char *id, int score)
G_GNUC_INTERNAL void pcmk__unassign_resource(pe_resource_t *rsc)
#define XML_RSC_ATTR_NOTIFY
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
void(* apply_coloc_score)(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
enum action_tasks clone_child_action(pe_action_t *action)
pe_node_t * pcmk__clone_allocate(pe_resource_t *rsc, const pe_node_t *prefer)
#define XML_RSC_ATTR_UNIQUE
void pe__free_notification_data(notify_data_t *n_data)
G_GNUC_INTERNAL void pcmk__update_dependent_with_promotable(const pe_resource_t *primary, pe_resource_t *dependent, const pcmk__colocation_t *colocation)
Update dependent for a colocation with a promotable clone.
G_GNUC_INTERNAL void pcmk__apply_location(pe_resource_t *rsc, pe__location_t *constraint)
void pe__create_notifications(pe_resource_t *rsc, notify_data_t *n_data)
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
#define XML_RSC_ATTR_PROMOTED_MAX
bool(* create_probe)(pe_resource_t *rsc, pe_node_t *node)
pcmk__action_result_t result
void pcmk__clone_apply_coloc_score(pe_resource_t *dependent, const pe_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
G_GNUC_INTERNAL GHashTable * pcmk__copy_node_table(GHashTable *nodes)
#define crm_err(fmt, args...)
void clone_rsc_location(pe_resource_t *rsc, pe__location_t *constraint)
G_GNUC_INTERNAL pe_node_t * pcmk__top_allowed_node(const pe_resource_t *rsc, const pe_node_t *node)
G_GNUC_INTERNAL void pcmk__create_promotable_actions(pe_resource_t *clone)
G_GNUC_INTERNAL void pcmk__update_promotable_dependent_priority(const pe_resource_t *primary, pe_resource_t *dependent, const pcmk__colocation_t *colocation)
G_GNUC_INTERNAL bool pcmk__assign_resource(pe_resource_t *rsc, pe_node_t *node, bool force)
pe_resource_t * find_compatible_child(const pe_resource_t *local_child, const pe_resource_t *rsc, enum rsc_role_e filter, gboolean current)
#define pe__clear_resource_flags(resource, flags_to_clear)
G_GNUC_INTERNAL void pcmk__add_promotion_scores(pe_resource_t *rsc)
void clone_expand(pe_resource_t *rsc)
rsc_role_e
Possible roles that a resource can be in.
#define XML_RSC_ATTR_PROMOTED_NODEMAX
enum pe_action_flags flags
pe_working_set_t * cluster
const char * node_attribute
G_GNUC_INTERNAL void pcmk__add_this_with(pe_resource_t *rsc, pcmk__colocation_t *colocation)
bool clone_create_probe(pe_resource_t *rsc, pe_node_t *node)
gboolean crm_is_true(const char *s)
void(* apply_location)(pe_resource_t *rsc, pe__location_t *location)
#define pe_rsc_trace(rsc, fmt, args...)
notify_data_t * pe__clone_notif_pseudo_ops(pe_resource_t *rsc, const char *task, pe_action_t *action, pe_action_t *complete)
#define XML_RSC_ATTR_INTERLEAVE
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
gboolean is_child_compatible(const pe_resource_t *child_rsc, const pe_node_t *local_node, enum rsc_role_e filter, gboolean current)
enum pe_action_flags summary_action_flags(pe_action_t *action, GList *children, const pe_node_t *node)
#define pe_flag_show_scores
#define crm_info(fmt, args...)
void pcmk__clone_add_utilization(const pe_resource_t *rsc, const pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
int copies_per_node(pe_resource_t *rsc)
GHashTable * allowed_nodes