32 utilization_value(
const char *s)
38 "invalid value '%s'", s);
69 compare_utilization_value(gpointer key, gpointer value, gpointer user_data)
71 int node1_capacity = 0;
72 int node2_capacity = 0;
73 struct compare_data *
data = user_data;
74 const char *node2_value = NULL;
76 if (
data->node2_only) {
77 if (g_hash_table_lookup(
data->node1->details->utilization, key)) {
81 node1_capacity = utilization_value((
const char *) value);
84 node2_value = g_hash_table_lookup(
data->node2->details->utilization, key);
85 node2_capacity = utilization_value(node2_value);
87 if (node1_capacity > node2_capacity) {
89 }
else if (node1_capacity < node2_capacity) {
109 struct compare_data
data = {
121 data.node2_only =
true;
133 struct calculate_data {
134 GHashTable *current_utilization;
147 update_utilization_value(gpointer key, gpointer value, gpointer user_data)
149 struct calculate_data *
data = user_data;
150 const char *current = g_hash_table_lookup(
data->current_utilization, key);
151 long long result = utilization_value(current)
152 + (
data->plus? 1LL : -1LL) * utilization_value(value);
156 }
else if (
result > INT_MAX) {
159 g_hash_table_replace(
data->current_utilization,
160 strdup(key), pcmk__itoa((
int)
result));
174 struct calculate_data
data = {
175 .current_utilization = current_utilization,
179 g_hash_table_foreach(rsc->
utilization, update_utilization_value, &
data);
193 struct calculate_data
data = {
194 .current_utilization = current_utilization,
198 g_hash_table_foreach(rsc->
utilization, update_utilization_value, &
data);
206 struct capacity_data {
221 check_capacity(gpointer key, gpointer value, gpointer user_data)
225 const char *node_value_s = NULL;
226 struct capacity_data *
data = user_data;
228 node_value_s = g_hash_table_lookup(
data->node->details->utilization, key);
230 required = utilization_value(value);
231 remaining = utilization_value(node_value_s);
233 if (required > remaining) {
234 crm_debug(
"Remaining capacity for %s on %s (%d) is insufficient " 235 "for resource %s usage (%d)",
236 (
const char *) key, pcmk__node_name(
data->node), remaining,
237 data->rsc_id, required);
238 data->is_enough =
false;
253 have_enough_capacity(
const pcmk_node_t *node,
const char *rsc_id,
254 GHashTable *utilization)
256 struct capacity_data
data = {
262 g_hash_table_foreach(utilization, check_capacity, &
data);
263 return data.is_enough;
282 for (GList *iter = rscs; iter != NULL; iter = iter->next) {
302 bool any_capable =
false;
303 char *rscs_id = NULL;
306 GList *colocated_rscs = NULL;
307 GHashTable *unassigned_utilization = NULL;
320 if (colocated_rscs == NULL) {
327 if (g_list_find(colocated_rscs, rsc) == NULL) {
328 colocated_rscs = g_list_append(colocated_rscs, rsc);
332 unassigned_utilization = sum_resource_utilization(rsc, colocated_rscs);
336 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
341 if (have_enough_capacity(node, rscs_id, unassigned_utilization)) {
346 if ((most_capable_node == NULL)
348 most_capable_node = node;
355 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
357 && !have_enough_capacity(node, rscs_id,
358 unassigned_utilization)) {
360 pcmk__node_name(node), rscs_id);
362 "__limit_utilization__", rsc->
cluster);
365 most_capable_node = NULL;
370 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
374 pcmk__node_name(node), rsc->
id);
376 "__limit_utilization__", rsc->
cluster);
381 g_hash_table_destroy(unassigned_utilization);
382 g_list_free(colocated_rscs);
387 return most_capable_node;
406 if (load_stopped->
node == NULL) {
410 free(load_stopped_task);
423 const GList *allowed_nodes)
425 const GList *iter = NULL;
429 "Creating utilization constraints for %s - strategy: %s",
433 for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
434 load_stopped = new_load_stopped_op(iter->data);
440 for (iter = allowed_nodes; iter; iter = iter->next) {
441 load_stopped = new_load_stopped_op(iter->data);
466 iter != NULL; iter = iter->next) {
470 out->message(out,
"node-capacity", node, desc);
pcmk_assignment_methods_t * cmds
#define CRM_CHECK(expr, failure_action)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
pcmk_scheduler_t * cluster
Actions are ordered if on same node (or migration target for migrate_to)
pcmk_action_t * get_pseudo_op(const char *name, pcmk_scheduler_t *scheduler)
int pcmk__scan_min_int(const char *text, int *result, int minimum)
G_GNUC_INTERNAL void pcmk__new_ordering(pcmk_resource_t *first_rsc, char *first_task, pcmk_action_t *first_action, pcmk_resource_t *then_rsc, char *then_task, pcmk_action_t *then_action, uint32_t flags, pcmk_scheduler_t *sched)
void pcmk__consume_node_capacity(GHashTable *current_utilization, const pcmk_resource_t *rsc)
#define pcmk__config_warn(fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
void pcmk__show_node_capacities(const char *desc, pcmk_scheduler_t *scheduler)
const pcmk_node_t * pcmk__ban_insufficient_capacity(pcmk_resource_t *rsc)
#define PCMK_VALUE_DEFAULT
#define PCMK_ACTION_MIGRATE_TO
pcmk_scheduler_t * data_set
G_GNUC_INTERNAL bool pcmk__node_available(const pcmk_node_t *node, bool consider_score, bool consider_guest)
#define pcmk__rsc_debug(rsc, fmt, args...)
void pcmk__create_utilization_constraints(pcmk_resource_t *rsc, const GList *allowed_nodes)
#define crm_debug(fmt, args...)
#define pcmk__clear_action_flags(action, flags_to_clear)
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
Wrappers for and extensions to libxml2.
GList *(* colocated_resources)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *colocated_rscs)
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
const char * placement_strategy
#define PCMK_ACTION_LOAD_STOPPED
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
int pcmk__compare_node_capacities(const pcmk_node_t *node1, const pcmk_node_t *node2)
pcmk_scheduler_t * scheduler
void pcmk__release_node_capacity(GHashTable *current_utilization, const pcmk_resource_t *rsc)
This structure contains everything that makes up a single output formatter.
#define pe__show_node_scores(level, rsc, text, nodes, scheduler)
void(* add_utilization)(const pcmk_resource_t *rsc, const pcmk_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
GHashTable * allowed_nodes