20 static void group_add_unallocated_utilization(GHashTable * all_utilization,
pe_resource_t * rsc,
30 do_compare_capacity1(gpointer key, gpointer value, gpointer user_data)
32 int node1_capacity = 0;
33 int node2_capacity = 0;
34 struct compare_data *
data = user_data;
40 if (node1_capacity > node2_capacity) {
42 }
else if (node1_capacity < node2_capacity) {
48 do_compare_capacity2(gpointer key, gpointer value, gpointer user_data)
50 int node1_capacity = 0;
51 int node2_capacity = 0;
52 struct compare_data *
data = user_data;
54 if (g_hash_table_lookup_extended(
data->node1->details->utilization, key, NULL, NULL)) {
61 if (node1_capacity > node2_capacity) {
63 }
else if (node1_capacity < node2_capacity) {
74 struct compare_data
data;
86 struct calculate_data {
87 GHashTable *current_utilization;
92 do_calculate_utilization(gpointer key, gpointer value, gpointer user_data)
94 const char *current = NULL;
96 struct calculate_data *
data = user_data;
98 current = g_hash_table_lookup(
data->current_utilization, key);
101 g_hash_table_replace(
data->current_utilization, strdup(key), result);
103 }
else if (current) {
105 g_hash_table_replace(
data->current_utilization, strdup(key), result);
114 GHashTable * utilization, gboolean plus)
116 struct calculate_data
data;
118 data.current_utilization = current_utilization;
121 g_hash_table_foreach(utilization, do_calculate_utilization, &
data);
125 struct capacity_data {
132 check_capacity(gpointer key, gpointer value, gpointer user_data)
136 struct capacity_data *
data = user_data;
139 remaining =
crm_parse_int(g_hash_table_lookup(
data->node->details->utilization, key),
"0");
141 if (required > remaining) {
145 crm_debug(
"Node %s does not have enough %s for %s: required=%d remaining=%d",
146 data->node->details->uname, (
char *)key,
data->rsc_id, required, remaining);
147 data->is_enough = FALSE;
152 have_enough_capacity(
pe_node_t * node,
const char * rsc_id, GHashTable * utilization)
154 struct capacity_data
data;
157 data.rsc_id = rsc_id;
158 data.is_enough = TRUE;
160 g_hash_table_foreach(utilization, check_capacity, &
data);
162 return data.is_enough;
167 native_add_unallocated_utilization(GHashTable * all_utilization,
pe_resource_t * rsc)
177 add_unallocated_utilization(GHashTable * all_utilization,
pe_resource_t * rsc,
185 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
186 orig_rsc->
id, rsc->
id);
187 native_add_unallocated_utilization(all_utilization, rsc);
190 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
191 orig_rsc->
id, rsc->
id);
192 group_add_unallocated_utilization(all_utilization, rsc, all_rscs);
194 }
else if (pe_rsc_is_clone(rsc)) {
196 gboolean existing = FALSE;
200 for (; gIter1 != NULL; gIter1 = gIter1->next) {
204 if (g_list_find(all_rscs, child)) {
210 for (; gIter2 != NULL; gIter2 = gIter2->next) {
213 if (g_list_find(all_rscs, grandchild)) {
214 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
215 orig_rsc->
id, child->
id);
216 add_unallocated_utilization(all_utilization, child, all_rscs, orig_rsc);
225 if (!existing && (rsc->
children != NULL)) {
228 pe_rsc_trace(orig_rsc,
"%s: Adding %s as colocated utilization",
229 orig_rsc->
id,
ID(first_child->
xml));
230 add_unallocated_utilization(all_utilization, first_child, all_rscs, orig_rsc);
240 GHashTable *all_utilization = crm_str_table_new();
242 all_rscs = g_list_copy(colocated_rscs);
243 if (g_list_find(all_rscs, rsc) == FALSE) {
244 all_rscs = g_list_append(all_rscs, rsc);
247 for (gIter = all_rscs; gIter != NULL; gIter = gIter->next) {
254 pe_rsc_trace(rsc,
"%s: Processing unallocated colocated %s", rsc->
id, listed_rsc->
id);
255 add_unallocated_utilization(all_utilization, listed_rsc, all_rscs, rsc);
258 g_list_free(all_rscs);
260 return all_utilization;
269 return colocated_rscs;
271 }
else if (g_list_find(colocated_rscs, rsc)) {
272 return colocated_rscs;
275 crm_trace(
"%s: %s is supposed to be colocated with %s", orig_rsc->
id, rsc->
id, orig_rsc->
id);
276 colocated_rscs = g_list_append(colocated_rscs, rsc);
278 for (gIter = rsc->
rsc_cons; gIter != NULL; gIter = gIter->next) {
283 if (rsc_rh == orig_rsc) {
292 colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);
295 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_rh, orig_rsc);
300 for (gIter = rsc->
rsc_cons_lhs; gIter != NULL; gIter = gIter->next) {
305 if (rsc_lh == orig_rsc) {
309 if (pe_rsc_is_clone(rsc_lh) == FALSE && pe_rsc_is_clone(rsc)) {
319 colocated_rscs = group_find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);
322 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc_lh, orig_rsc);
327 return colocated_rscs;
333 CRM_CHECK(rsc && prefer && data_set,
return);
337 gboolean any_capable = FALSE;
340 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, rsc);
341 if (colocated_rscs) {
342 GHashTable *unallocated_utilization = NULL;
347 unallocated_utilization = sum_unallocated_utilization(rsc, colocated_rscs);
350 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
355 if (have_enough_capacity(node, rscs_id, unallocated_utilization)) {
359 if (most_capable_node == NULL ||
362 most_capable_node = node;
368 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
373 if (have_enough_capacity(node, rscs_id, unallocated_utilization) == FALSE) {
375 "Resource %s and its colocated resources" 376 " cannot be allocated to node %s: not enough capacity",
377 rsc->
id, node->details->uname);
382 }
else if (*prefer == NULL) {
383 *prefer = most_capable_node;
386 if (unallocated_utilization) {
387 g_hash_table_destroy(unallocated_utilization);
390 g_list_free(colocated_rscs);
394 if (any_capable == FALSE) {
396 while (g_hash_table_iter_next(&iter, NULL, (
void **)&node)) {
401 if (have_enough_capacity(node, rsc->
id, rsc->
utilization) == FALSE) {
403 "Resource %s cannot be allocated to node %s:" 404 " not enough capacity",
405 rsc->
id, node->details->uname);
414 #define VARIANT_GROUP 1 420 group_variant_data_t *group_data = NULL;
422 get_group_variant_data(group_data, rsc);
423 if (group_data->colocated || pe_rsc_is_clone(rsc->
parent)) {
426 for (; gIter != NULL; gIter = gIter->next) {
429 colocated_rscs = find_colocated_rscs(colocated_rscs, child_rsc, orig_rsc);
433 if (group_data->first_child) {
434 colocated_rscs = find_colocated_rscs(colocated_rscs, group_data->first_child, orig_rsc);
438 colocated_rscs = find_colocated_rscs(colocated_rscs, rsc, orig_rsc);
440 return colocated_rscs;
444 group_add_unallocated_utilization(GHashTable * all_utilization,
pe_resource_t * rsc,
447 group_variant_data_t *group_data = NULL;
449 get_group_variant_data(group_data, rsc);
450 if (group_data->colocated || pe_rsc_is_clone(rsc->
parent)) {
453 for (; gIter != NULL; gIter = gIter->next) {
457 g_list_find(all_rscs, child_rsc) == FALSE) {
458 native_add_unallocated_utilization(all_utilization, child_rsc);
463 if (group_data->first_child &&
465 g_list_find(all_rscs, group_data->first_child) == FALSE) {
466 native_add_unallocated_utilization(all_utilization, group_data->first_child);
#define CRM_CHECK(expr, failure_action)
void process_utilization(pe_resource_t *rsc, pe_node_t **prefer, pe_working_set_t *data_set)
#define pe_rsc_debug(rsc, fmt, args...)
void calculate_utilization(GHashTable *current_utilization, GHashTable *utilization, gboolean plus)
#define pe__show_node_weights(level, rsc, text, nodes)
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
gboolean can_run_resources(const pe_node_t *node)
#define pe_rsc_provisional
#define crm_debug(fmt, args...)
enum filter_colocation_res filter_colocation_constraint(pe_resource_t *rsc_lh, pe_resource_t *rsc_rh, rsc_colocation_t *constraint, gboolean preview)
int compare_capacity(const pe_node_t *node1, const pe_node_t *node2)
#define crm_trace(fmt, args...)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
enum pe_obj_types variant
const char * placement_strategy
#define pe_rsc_trace(rsc, fmt, args...)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
GHashTable * allowed_nodes