14 #include <qb/qbdefs.h> 52 pcmk__rsc_debug(rsc,
"Assignment dependency loop detected involving %s",
73 iter != NULL; iter = iter->next) {
81 if (first_assigned_node == NULL) {
82 first_assigned_node = node;
87 "first group member");
93 return first_assigned_node;
131 iter != NULL; iter = iter->next) {
171 member_internal_constraints(gpointer
data, gpointer user_data)
174 struct member_data *member_data = (
struct member_data *) user_data;
185 if (member_data->previous_member == NULL) {
187 if (member_data->ordered) {
192 }
else if (member_data->colocated) {
201 member, member_data->previous_member, NULL, NULL,
205 if (member_data->promotable) {
242 if (!member_data->ordered) {
247 if (member_data->promotable) {
256 }
else if (member_data->previous_member == NULL) {
258 if (member_data->promotable) {
281 && (member_data->previous_member->priv->active_nodes == NULL)) {
283 member_data->previous_member,
289 if (member_data->promotable) {
296 member_data->previous_member,
303 if (member_data->ordered && (member_data->previous_member != NULL)
304 && (member_data->previous_member->priv->active_nodes == NULL)
305 && (member_data->last_active != NULL)
306 && (member_data->last_active->priv->active_nodes != NULL)) {
310 member_data->last_active = member;
313 member_data->previous_member = member;
325 struct member_data member_data = {
false, };
348 g_list_foreach(rsc->
priv->
children, member_internal_constraints,
370 int priority_delta = 0;
376 pcmk__rsc_trace(primary,
"Processing %s (group %s with %s) for dependent",
377 colocation->
id, dependent->
id, primary->
id);
389 "non-colocated group and %s",
390 dependent->
id, primary->
id);
395 for (GList *iter = dependent->
priv->
children; iter != NULL;
398 int instance_delta = 0;
415 if (priority_delta != 0) {
420 "Applied %s to %s promotion priority " 421 "(now %s after %s %d)",
422 colocation->
id, dependent->
id,
424 ((priority_delta > 0)?
"adding" :
"subtracting"),
425 QB_ABS(priority_delta));
427 return priority_delta;
448 int priority_delta = 0;
452 "Processing colocation %s (%s with group %s) for primary",
453 colocation->
id, dependent->
id, primary->
id);
474 if (member == NULL) {
484 " non-colocated group %s",
485 dependent->
id, primary->
id);
491 iter != NULL; iter = iter->next) {
493 int instance_delta = 0;
502 return priority_delta;
527 && (colocation != NULL));
530 return colocate_group_with(dependent, primary, colocation);
536 return colocate_with_group(dependent, primary, colocation);
560 for (GList *iter =
action->rsc->priv->children;
561 iter != NULL; iter = iter->next) {
572 if (member_action != NULL) {
573 uint32_t member_flags = 0U;
606 "%s is not runnable because %s will not %s",
641 uint32_t filter, uint32_t
type,
656 iter != NULL; iter = iter->next) {
663 if (member_action == NULL) {
685 GList *node_list_orig = NULL;
686 GList *node_list_copy = NULL;
688 pcmk__assert(pcmk__is_group(rsc) && (location != NULL));
691 node_list_orig = location->
nodes;
704 iter != NULL; iter = iter->next) {
722 location->
nodes = node_list_copy;
728 location->
nodes = node_list_orig;
729 g_list_free_full(node_list_copy, free);
736 GList *colocated_rscs)
740 if (orig_rsc == NULL) {
750 colocated_rscs = g_list_prepend(colocated_rscs, (gpointer) rsc);
752 for (
const GList *iter = rsc->priv->children;
753 iter != NULL; iter = iter->next) {
770 return colocated_rscs;
781 pcmk__assert((orig_rsc != NULL) && (list != NULL) && pcmk__is_group(rsc));
798 rsc->
id, orig_rsc->
id);
806 parent->priv->cmds->with_this_colocations(
parent, orig_rsc, list);
816 iter != NULL; iter = iter->next) {
820 if (member == orig_rsc) {
835 pcmk__assert((orig_rsc != NULL) && (list != NULL) && pcmk__is_group(rsc));
846 if ((rsc == orig_rsc) || (orig_rsc == rsc->
priv->
children->data)) {
848 rsc->
id, orig_rsc->
id);
856 parent->priv->cmds->this_with_colocations(
parent, orig_rsc, list);
866 iter != NULL; iter = iter->next) {
869 if (member == orig_rsc) {
883 iter != NULL; iter = iter->next) {
886 if (orig_rsc == member) {
891 crm_trace(
"Adding mandatory '%s with' colocations to list for " 892 "member %s because earlier member %s is unmanaged",
893 rsc->
id, orig_rsc->
id, member->
id);
895 cons_iter != NULL; cons_iter = cons_iter->next) {
942 const char *log_id, GHashTable **nodes,
944 float factor, uint32_t
flags)
948 pcmk__assert(pcmk__is_group(source_rsc) && (nodes != NULL)
949 && ((colocation != NULL)
950 || ((target_rsc == NULL) && (*nodes == NULL))));
952 if (log_id == NULL) {
953 log_id = source_rsc->
id;
959 log_id, source_rsc->
id);
979 if (*nodes == NULL) {
985 pcmk__rsc_trace(source_rsc,
"%s: Merging scores from group %s using member %s " 986 "(at %.6f)", log_id, source_rsc->
id, member->
id, factor);
988 nodes, colocation, factor,
997 GHashTable *utilization)
1001 pcmk__assert((orig_rsc != NULL) && (utilization != NULL)
1002 && pcmk__is_group(rsc));
1008 pcmk__rsc_trace(orig_rsc,
"%s: Adding group %s as colocated utilization",
1009 orig_rsc->
id, rsc->
id);
1015 iter != NULL; iter = iter->next) {
1020 && (g_list_find(all_rscs, member) == NULL)) {
1029 if ((member != NULL)
1031 && (g_list_find(all_rscs, member) == NULL)) {
1045 iter != NULL; iter = iter->next) {
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
void pcmk__group_create_actions(pcmk_resource_t *rsc)
pcmk_node_t * pcmk__group_assign(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
G_GNUC_INTERNAL GList * pcmk__colocated_resources(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
#define pcmk__order_starts(rsc1, rsc2, flags)
void pcmk__group_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)
'then' is runnable (and migratable) only if 'first' is runnable
G_GNUC_INTERNAL void pcmk__apply_location(pcmk_resource_t *rsc, pcmk__location_t *constraint)
#define PCMK_META_PROMOTABLE
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)
void(* create_actions)(pcmk_resource_t *rsc)
int pcmk__group_apply_coloc_score(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
enum pcmk_ipc_server type
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
pcmk_node_t *(* assign)(pcmk_resource_t *rsc, const pcmk_node_t *prefer, bool stop_if_fail)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define pcmk__order_stops(rsc1, rsc2, flags)
#define pcmk__rsc_info(rsc, fmt, args...)
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__config_err(fmt...)
void(* add_utilization)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
void(* with_this_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
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)
void(* this_with_colocations)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
enum pcmk__action_type get_complex_task(const pcmk_resource_t *rsc, const char *name)
#define pcmk__set_relation_flags(ar_flags, flags_to_set)
void(* internal_constraints)(pcmk_resource_t *rsc)
uint32_t pcmk__group_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)
#define pcmk__rsc_debug(rsc, fmt, args...)
#define PCMK_ACTION_DEMOTE
void pe__set_next_role(pcmk_resource_t *rsc, enum rsc_role_e role, const char *why)
G_GNUC_INTERNAL void pcmk__add_with_this_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
pcmk_scheduler_t * scheduler
uint32_t pcmk__group_action_flags(pcmk_action_t *action, const pcmk_node_t *node)
Actions are ordered (optionally, if no other flags are set)
#define pcmk__clear_action_flags(action, flags_to_clear)
pcmk_resource_t * pe__last_group_member(const pcmk_resource_t *group)
G_GNUC_INTERNAL void pcmk__add_this_with(GList **list, const pcmk__colocation_t *colocation, const pcmk_resource_t *rsc)
#define crm_trace(fmt, args...)
G_GNUC_INTERNAL void pcmk__new_colocation(const char *id, const char *node_attr, int score, pcmk_resource_t *dependent, pcmk_resource_t *primary, const char *dependent_role_spec, const char *primary_role_spec, uint32_t flags)
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)
pcmk_node_t * assigned_node
GList * with_this_colocations
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
void(* apply_location)(pcmk_resource_t *rsc, pcmk__location_t *location)
#define PCMK_ACTION_START
pcmk__resource_private_t * priv
void(* shutdown_lock)(pcmk_resource_t *rsc)
Wrappers for and extensions to libxml2.
GList * pcmk__group_colocated_resources(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
enum rsc_role_e next_role
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
void pcmk__group_with_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
int pcmk__add_scores(int score1, int score2)
#define pcmk__order_resource_actions(first_rsc, first_task, then_rsc, then_task, flags)
GHashTable * allowed_nodes
pcmk_action_t * custom_action(pcmk_resource_t *rsc, char *key, const char *task, const pcmk_node_t *on_node, gboolean optional, pcmk_scheduler_t *scheduler)
Create or update an action object.
void pcmk__group_apply_location(pcmk_resource_t *rsc, pcmk__location_t *location)
#define pcmk__assert(expr)
uint32_t(* action_flags)(pcmk_action_t *action, const pcmk_node_t *node)
If 'then' is required, 'first' must be added to the transition graph.
GList * pcmk__copy_node_list(const GList *list, bool reset)
pcmk_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pcmk_node_t *on_node)
pcmk_scheduler_t * scheduler
G_GNUC_INTERNAL void pcmk__add_this_with_list(GList **list, GList *addition, const pcmk_resource_t *rsc)
If 'first' is required and runnable, 'then' must be in graph.
#define PCMK_ACTION_STOPPED
enum rsc_role_e orig_role
void pcmk__group_add_utilization(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
GList * this_with_colocations
void pcmk__group_shutdown_lock(pcmk_resource_t *rsc)
#define PCMK_ACTION_PROMOTE
void pcmk__with_group_colocations(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList **list)
gboolean crm_is_true(const char *s)
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
const char * pcmk__action_text(enum pcmk__action_type action)
#define pcmk__set_action_flags(action, flags_to_set)
#define PCMK_ACTION_PROMOTED
GList *(* colocated_resources)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
Location constraint object.
#define PCMK_ACTION_RUNNING
#define pcmk__clear_raw_action_flags(action_flags, action_name, to_clear)
bool pe__group_flag_is_set(const pcmk_resource_t *group, uint32_t flags)
#define PCMK_ACTION_DEMOTED
int(* apply_coloc_score)(pcmk_resource_t *dependent, const pcmk_resource_t *primary, const pcmk__colocation_t *colocation, bool for_dependent)
void pcmk__group_internal_constraints(pcmk_resource_t *rsc)
const pcmk__assignment_methods_t * cmds
No relation (compare with equality rather than bit set)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".