18 static void group_add_unallocated_utilization(GHashTable * all_utilization,
resource_t * rsc,
28 do_compare_capacity1(gpointer key, gpointer value, gpointer user_data)
30 int node1_capacity = 0;
31 int node2_capacity = 0;
32 struct compare_data *
data = user_data;
36 crm_parse_int(g_hash_table_lookup(data->node2->details->utilization, key),
"0");
38 if (node1_capacity > node2_capacity) {
40 }
else if (node1_capacity < node2_capacity) {
46 do_compare_capacity2(gpointer key, gpointer value, gpointer user_data)
48 int node1_capacity = 0;
49 int node2_capacity = 0;
50 struct compare_data *data = user_data;
52 if (g_hash_table_lookup_extended(data->node1->details->utilization, key, NULL, NULL)) {
59 if (node1_capacity > node2_capacity) {
61 }
else if (node1_capacity < node2_capacity) {
72 struct compare_data data;
84 struct calculate_data {
85 GHashTable *current_utilization;
90 do_calculate_utilization(gpointer key, gpointer value, gpointer user_data)
92 const char *current = NULL;
94 struct calculate_data *data = user_data;
96 current = g_hash_table_lookup(data->current_utilization, key);
99 g_hash_table_replace(data->current_utilization, strdup(key), result);
101 }
else if (current) {
103 g_hash_table_replace(data->current_utilization, strdup(key), result);
112 GHashTable * utilization, gboolean plus)
114 struct calculate_data data;
116 data.current_utilization = current_utilization;
119 g_hash_table_foreach(utilization, do_calculate_utilization, &data);
123 struct capacity_data {
130 check_capacity(gpointer key, gpointer value, gpointer user_data)
134 struct capacity_data *data = user_data;
137 remaining =
crm_parse_int(g_hash_table_lookup(data->node->details->utilization, key),
"0");
139 if (required > remaining) {
143 crm_debug(
"Node %s does not have enough %s for %s: required=%d remaining=%d",
144 data->node->details->uname, (
char *)key, data->rsc_id, required, remaining);
145 data->is_enough = FALSE;
150 have_enough_capacity(
node_t * node,
const char * rsc_id, GHashTable * utilization)
152 struct capacity_data data;
155 data.rsc_id = rsc_id;
156 data.is_enough = TRUE;
158 g_hash_table_foreach(utilization, check_capacity, &data);
160 return data.is_enough;
165 native_add_unallocated_utilization(GHashTable * all_utilization,
resource_t * rsc)
175 add_unallocated_utilization(GHashTable * all_utilization,
resource_t * rsc,
183 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
184 orig_rsc->
id, rsc->
id);
185 native_add_unallocated_utilization(all_utilization, rsc);
188 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
189 orig_rsc->
id, rsc->
id);
190 group_add_unallocated_utilization(all_utilization, rsc, all_rscs);
192 }
else if (pe_rsc_is_clone(rsc)) {
194 gboolean existing = FALSE;
198 for (; gIter1 != NULL; gIter1 = gIter1->next) {
202 if (g_list_find(all_rscs, child)) {
208 for (; gIter2 != NULL; gIter2 = gIter2->next) {
211 if (g_list_find(all_rscs, grandchild)) {
212 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
213 orig_rsc->
id, child->
id);
214 add_unallocated_utilization(all_utilization, child, all_rscs, orig_rsc);
222 if (existing == FALSE) {
225 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
226 orig_rsc->
id,
ID(first_child->
xml));
227 add_unallocated_utilization(all_utilization, first_child, all_rscs, orig_rsc);
237 GHashTable *all_utilization = crm_str_table_new();
239 all_rscs = g_list_copy(colocated_rscs);
240 if (g_list_find(all_rscs, rsc) == FALSE) {
241 all_rscs = g_list_append(all_rscs, rsc);
244 for (gIter = all_rscs; gIter != NULL; gIter = gIter->next) {
251 pe_rsc_trace(rsc,
"%s: Processing unallocated colocated %s", rsc->
id, listed_rsc->
id);
252 add_unallocated_utilization(all_utilization, listed_rsc, all_rscs, rsc);
255 g_list_free(all_rscs);
257 return all_utilization;
266 return colocated_rscs;
268 }
else if (g_list_find(colocated_rscs, rsc)) {
269 return colocated_rscs;
272 crm_trace(
"%s: %s is supposed to be colocated with %s", orig_rsc->
id, rsc->
id, orig_rsc->
id);
273 colocated_rscs = g_list_append(colocated_rscs, rsc);
275 for (gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
280 if (rsc_rh == orig_rsc) {
289 colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);
292 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);
297 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
302 if (rsc_lh == orig_rsc) {
306 if (pe_rsc_is_clone(rsc_lh) == FALSE && pe_rsc_is_clone(rsc)) {
316 colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);
319 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);
324 return colocated_rscs;
332 CRM_CHECK(rsc && prefer && data_set,
return);
336 gboolean any_capable = FALSE;
339 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, rsc);
340 if (colocated_rscs) {
341 GHashTable *unallocated_utilization = NULL;
342 char *rscs_id = crm_concat(rsc->
id,
"and its colocated resources",
' ');
343 node_t *most_capable_node = NULL;
345 unallocated_utilization = sum_unallocated_utilization(rsc, colocated_rscs);
348 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
353 if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
357 if (most_capable_node == NULL ||
360 most_capable_node = node;
366 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
371 if (have_enough_capacity(node, rscs_id, unallocated_utilization) == FALSE) {
373 "Resource %s and its colocated resources"
374 " cannot be allocated to node %s: not enough capacity",
380 }
else if (*prefer == NULL) {
381 *prefer = most_capable_node;
384 if (unallocated_utilization) {
385 g_hash_table_destroy(unallocated_utilization);
388 g_list_free(colocated_rscs);
392 if (any_capable == FALSE) {
394 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
399 if (have_enough_capacity(node, rsc->
id, rsc->
utilization) == FALSE) {
401 "Resource %s cannot be allocated to node %s:"
402 " not enough capacity",
412 #define VARIANT_GROUP 1
418 group_variant_data_t *group_data = NULL;
420 get_group_variant_data(group_data, rsc);
421 if (group_data->colocated || pe_rsc_is_clone(rsc->
parent)) {
424 for (; gIter != NULL; gIter = gIter->next) {
427 colocated_rscs = find_colocated_rscs(colocated_rscs, child_rsc, orig_rsc);
431 if (group_data->first_child) {
432 colocated_rscs = find_colocated_rscs(colocated_rscs, group_data->first_child, orig_rsc);
436 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, orig_rsc);
438 return colocated_rscs;
442 group_add_unallocated_utilization(GHashTable * all_utilization,
resource_t * rsc,
445 group_variant_data_t *group_data = NULL;
447 get_group_variant_data(group_data, rsc);
448 if (group_data->colocated || pe_rsc_is_clone(rsc->
parent)) {
451 for (; gIter != NULL; gIter = gIter->next) {
455 g_list_find(all_rscs, child_rsc) == FALSE) {
456 native_add_unallocated_utilization(all_utilization, child_rsc);
461 if (group_data->first_child &&
463 g_list_find(all_rscs, group_data->first_child) == FALSE) {
464 native_add_unallocated_utilization(all_utilization, group_data->first_child);
#define CRM_CHECK(expr, failure_action)
#define pe_rsc_debug(rsc, fmt, args...)
gboolean safe_str_neq(const char *a, const char *b)
int compare_capacity(const node_t *node1, const node_t *node2)
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
void calculate_utilization(GHashTable *current_utilization, GHashTable *utilization, gboolean plus)
#define pe_rsc_provisional
void process_utilization(resource_t *rsc, node_t **prefer, pe_working_set_t *data_set)
#define crm_debug(fmt, args...)
#define crm_trace(fmt, args...)
struct pe_node_shared_s * details
enum filter_colocation_res filter_colocation_constraint(resource_t *rsc_lh, resource_t *rsc_rh, rsc_colocation_t *constraint, gboolean preview)
enum pe_obj_types variant
const char * placement_strategy
gboolean can_run_resources(const node_t *node)
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
#define pe_rsc_trace(rsc, fmt, args...)
#define dump_node_scores(level, rsc, text, nodes)
GHashTable * allowed_nodes