29 utilization_value(
const char *s)
34 pe_warn(
"Using 0 for utilization instead of invalid value '%s'", value);
65 compare_utilization_value(gpointer key, gpointer value, gpointer user_data)
67 int node1_capacity = 0;
68 int node2_capacity = 0;
69 struct compare_data *
data = user_data;
70 const char *node2_value = NULL;
72 if (
data->node2_only) {
73 if (g_hash_table_lookup(
data->node1->details->utilization, key)) {
77 node1_capacity = utilization_value((
const char *) value);
80 node2_value = g_hash_table_lookup(
data->node2->details->utilization, key);
81 node2_capacity = utilization_value(node2_value);
83 if (node1_capacity > node2_capacity) {
85 }
else if (node1_capacity < node2_capacity) {
104 struct compare_data
data = {
116 data.node2_only =
true;
128 struct calculate_data {
129 GHashTable *current_utilization;
142 update_utilization_value(gpointer key, gpointer value, gpointer user_data)
145 const char *current = NULL;
146 struct calculate_data *
data = user_data;
148 current = g_hash_table_lookup(
data->current_utilization, key);
150 result = utilization_value(current) + utilization_value(value);
151 }
else if (current) {
152 result = utilization_value(current) - utilization_value(value);
154 g_hash_table_replace(
data->current_utilization,
155 strdup(key), pcmk__itoa(
result));
168 struct calculate_data
data = {
169 .current_utilization = current_utilization,
173 g_hash_table_foreach(rsc->
utilization, update_utilization_value, &
data);
186 struct calculate_data
data = {
187 .current_utilization = current_utilization,
191 g_hash_table_foreach(rsc->
utilization, update_utilization_value, &
data);
199 struct capacity_data {
214 check_capacity(gpointer key, gpointer value, gpointer user_data)
218 const char *node_value_s = NULL;
219 struct capacity_data *
data = user_data;
221 node_value_s = g_hash_table_lookup(
data->node->details->utilization, key);
223 required = utilization_value(value);
224 remaining = utilization_value(node_value_s);
226 if (required > remaining) {
227 crm_debug(
"Remaining capacity for %s on %s (%d) is insufficient " 228 "for resource %s usage (%d)",
229 (
const char *) key,
data->node->details->uname, remaining,
230 data->rsc_id, required);
231 data->is_enough =
false;
246 have_enough_capacity(
pe_node_t *node,
const char *rsc_id,
247 GHashTable *utilization)
249 struct capacity_data
data = {
255 g_hash_table_foreach(utilization, check_capacity, &
data);
256 return data.is_enough;
271 sum_resource_utilization(
pe_resource_t *orig_rsc, GList *rscs)
275 for (GList *iter = rscs; iter != NULL; iter = iter->next) {
295 bool any_capable =
false;
296 char *rscs_id = NULL;
299 GList *colocated_rscs = NULL;
300 GHashTable *unallocated_utilization = NULL;
313 if (colocated_rscs == NULL) {
320 if (g_list_find(colocated_rscs, rsc) == NULL) {
321 colocated_rscs = g_list_append(colocated_rscs, rsc);
325 unallocated_utilization = sum_resource_utilization(rsc, colocated_rscs);
329 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
334 if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
339 if ((most_capable_node == NULL)
341 most_capable_node = node;
348 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
350 && !have_enough_capacity(node, rscs_id,
351 unallocated_utilization)) {
352 pe_rsc_debug(rsc,
"%s does not have enough capacity for %s",
353 node->details->uname, rscs_id);
361 if (*prefer == NULL) {
362 *prefer = most_capable_node;
365 while (g_hash_table_iter_next(&iter, NULL, (
void **) &node)) {
368 pe_rsc_debug(rsc,
"%s does not have enough capacity for %s",
369 node->details->uname, rsc->
id);
376 g_hash_table_destroy(unallocated_utilization);
377 g_list_free(colocated_rscs);
400 if (load_stopped->
node == NULL) {
404 free(load_stopped_task);
422 pe_rsc_trace(rsc,
"Creating utilization constraints for %s - strategy: %s",
426 for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
428 load_stopped = new_load_stopped_op(node, rsc->
cluster);
434 for (GList *iter = allowed_nodes; iter; iter = iter->next) {
436 load_stopped = new_load_stopped_op(node, rsc->
cluster);
458 for (GList *iter =
data_set->
nodes; iter != NULL; iter = iter->next) {
462 out->message(out,
"node-capacity", node, desc);
#define CRM_CHECK(expr, failure_action)
void(* add_utilization)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *all_rscs, GHashTable *utilization)
#define pe_rsc_debug(rsc, fmt, args...)
#define pe__show_node_weights(level, rsc, text, nodes, data_set)
int pcmk__scan_min_int(const char *text, int *result, int minimum)
G_GNUC_INTERNAL bool pcmk__node_available(const pe_node_t *node)
resource_alloc_functions_t * cmds
void pcmk__ban_insufficient_capacity(pe_resource_t *rsc, pe_node_t **prefer, pe_working_set_t *data_set)
void pcmk__release_node_capacity(GHashTable *current_utilization, pe_resource_t *rsc)
G_GNUC_INTERNAL void pcmk__new_ordering(pe_resource_t *lh_rsc, char *lh_task, pe_action_t *lh_action, pe_resource_t *rh_rsc, char *rh_task, pe_action_t *rh_action, enum pe_ordering type, pe_working_set_t *data_set)
pe_node_t * pe__copy_node(const pe_node_t *this_node)
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
void pcmk__consume_node_capacity(GHashTable *current_utilization, pe_resource_t *rsc)
pe_action_t * get_pseudo_op(const char *name, pe_working_set_t *data_set)
#define crm_debug(fmt, args...)
#define pe__clear_action_flags(action, flags_to_clear)
void pcmk__show_node_capacities(const char *desc, pe_working_set_t *data_set)
GList *(* colocated_resources)(pe_resource_t *rsc, pe_resource_t *orig_rsc, GList *colocated_rscs)
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
pe_working_set_t * data_set
const char * placement_strategy
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
void pcmk__create_utilization_constraints(pe_resource_t *rsc, GList *allowed_nodes)
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
#define pe_flag_show_utilization
This structure contains everything that makes up a single output formatter.
pe_working_set_t * cluster
#define pe_rsc_trace(rsc, fmt, args...)
int pcmk__compare_node_capacities(const pe_node_t *node1, const pe_node_t *node2)
GHashTable * allowed_nodes