2
2
* Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
4
4
* This program is free software; you can redistribute it and/or
5
5
* modify it under the terms of the GNU General Public
6
6
* License as published by the Free Software Foundation; either
7
7
* version 2 of the License, or (at your option) any later version.
9
9
* This software is distributed in the hope that it will be useful,
10
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
12
* General Public License for more details.
14
14
* You should have received a copy of the GNU General Public
15
15
* License along with this library; if not, write to the Free Software
16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
28
extern gint sort_clone_instance(gconstpointer a, gconstpointer b, gpointer data_set);
31
extern int master_score(resource_t * rsc, node_t * node, int not_set_value);
30
static int master_score(resource_t * rsc, node_t * node, int not_set_value);
34
33
child_promoting_constraints(clone_variant_data_t * clone_data, enum pe_ordering type,
38
37
if (child == NULL) {
39
38
if (clone_data->ordered && last != NULL) {
40
crm_trace("Ordered version (last node)");
39
pe_rsc_trace(rsc, "Ordered version (last node)");
41
40
/* last child promote before promoted started */
42
41
new_rsc_order(last, RSC_PROMOTE, rsc, RSC_PROMOTED, type, data_set);
51
50
new_rsc_order(rsc, RSC_PROMOTE, child, RSC_PROMOTE, type, data_set);
53
52
if (clone_data->ordered) {
54
crm_trace("Ordered version");
53
pe_rsc_trace(rsc, "Ordered version");
55
54
if (last == NULL) {
56
55
/* global promote before first child promote */
62
61
new_rsc_order(last, RSC_PROMOTE, child, RSC_PROMOTE, type, data_set);
65
crm_trace("Un-ordered version");
64
pe_rsc_trace(rsc, "Un-ordered version");
74
73
if (child == NULL) {
75
74
if (clone_data->ordered && last != NULL) {
76
crm_trace("Ordered version (last node)");
75
pe_rsc_trace(rsc, "Ordered version (last node)");
77
76
/* global demote before first child demote */
78
77
new_rsc_order(rsc, RSC_DEMOTE, last, RSC_DEMOTE, pe_order_optional, data_set);
87
86
new_rsc_order(rsc, RSC_DEMOTE, child, RSC_DEMOTE, pe_order_implies_first_printed, data_set);
89
88
if (clone_data->ordered && last != NULL) {
90
crm_trace("Ordered version");
89
pe_rsc_trace(rsc, "Ordered version");
92
91
/* child/child relative demote */
93
92
new_rsc_order(child, RSC_DEMOTE, last, RSC_DEMOTE, type, data_set);
95
94
} else if (clone_data->ordered) {
96
crm_trace("Ordered version (1st node)");
95
pe_rsc_trace(rsc, "Ordered version (1st node)");
97
96
/* first child stop before global stopped */
98
97
new_rsc_order(child, RSC_DEMOTE, rsc, RSC_DEMOTED, type, data_set);
101
crm_trace("Un-ordered version");
100
pe_rsc_trace(rsc, "Un-ordered version");
147
146
cons_node = NULL; \
148
147
if(cons->role_filter == RSC_ROLE_MASTER) { \
149
crm_trace("Applying %s to %s", \
148
pe_rsc_trace(rsc, "Applying %s to %s", \
150
149
cons->id, child_rsc->id); \
151
150
cons_node = pe_find_node_id( \
152
151
cons->node_list_rh, chosen->details->id); \
154
153
if(cons_node != NULL) { \
155
154
int new_priority = merge_weights( \
156
155
child_rsc->priority, cons_node->weight); \
157
crm_trace("\t%s: %d->%d (%d)", child_rsc->id, \
156
pe_rsc_trace(rsc, "\t%s: %d->%d (%d)", child_rsc->id, \
158
157
child_rsc->priority, new_priority, cons_node->weight); \
159
158
child_rsc->priority = new_priority; \
183
182
resource_t *child = (resource_t *) gIter->data;
185
184
if (can_be_master(child) == NULL) {
186
crm_trace( "Child %s of %s can't be promoted", child->id, rsc->id);
185
pe_rsc_trace(rsc, "Child %s of %s can't be promoted", child->id, rsc->id);
192
191
node = rsc->fns->location(rsc, NULL, FALSE);
193
192
if (node == NULL) {
194
crm_trace( "%s cannot be master: not allocated", rsc->id);
193
pe_rsc_trace(rsc, "%s cannot be master: not allocated", rsc->id);
197
196
} else if (is_not_set(rsc->flags, pe_rsc_managed)) {
206
205
} else if (rsc->priority < 0) {
207
crm_trace( "%s cannot be master: preference: %d", rsc->id, rsc->priority);
206
pe_rsc_trace(rsc, "%s cannot be master: preference: %d", rsc->id, rsc->priority);
210
209
} else if (can_run_resources(node) == FALSE) {
211
crm_trace( "Node cant run any resources: %s", node->details->uname);
210
crm_trace("Node cant run any resources: %s", node->details->uname);
265
263
return sort_clone_instance(a, b, data_set);
267
master_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes, const char *attr,
268
float factor, enum pe_weights flags)
270
return rsc_merge_weights(rsc, rhs, nodes, attr, factor, flags);
269
274
master_promotion_order(resource_t * rsc, pe_working_set_t * data_set)
281
286
clone_data->merged_master_weights = TRUE;
282
crm_trace("Merging weights for %s", rsc->id);
287
pe_rsc_trace(rsc, "Merging weights for %s", rsc->id);
283
288
set_bit(rsc->flags, pe_rsc_merging);
285
290
gIter = rsc->children;
286
291
for (; gIter != NULL; gIter = gIter->next) {
287
292
resource_t *child = (resource_t *) gIter->data;
289
crm_trace("Sort index: %s = %d", child->id, child->sort_index);
294
pe_rsc_trace(rsc, "Sort index: %s = %d", child->id, child->sort_index);
291
296
dump_node_scores(LOG_DEBUG_3, rsc, "Before", rsc->allowed_nodes);
297
302
chosen = child->fns->location(child, NULL, FALSE);
298
303
if (chosen == NULL || child->sort_index < 0) {
299
crm_trace("Skipping %s", child->id);
304
pe_rsc_trace(rsc, "Skipping %s", child->id);
303
308
node = (node_t *) pe_hash_table_lookup(rsc->allowed_nodes, chosen->details->id);
304
309
CRM_ASSERT(node != NULL);
305
310
/* adds in master preferences and rsc_location.role=Master */
306
crm_trace("Adding %s to %s from %s", score2char(child->sort_index), node->details->uname,
311
pe_rsc_trace(rsc, "Adding %s to %s from %s", score2char(child->sort_index),
312
node->details->uname, child->id);
308
313
node->weight = merge_weights(child->sort_index, node->weight);
318
323
* master instance should/must be colocated with
320
325
if (constraint->role_lh == RSC_ROLE_MASTER) {
321
crm_trace("RHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
326
enum pe_weights flags = constraint->score == INFINITY ? 0 : pe_weights_rollback;
328
pe_rsc_trace(rsc, "RHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
323
330
rsc->allowed_nodes =
324
331
constraint->rsc_rh->cmds->merge_weights(constraint->rsc_rh, rsc->id,
325
332
rsc->allowed_nodes,
326
333
constraint->node_attribute,
327
constraint->score / INFINITY,
329
INFINITY ? FALSE : TRUE, FALSE);
334
(float)constraint->score / INFINITY, flags);
338
343
* colocated with the master instance
340
345
if (constraint->role_rh == RSC_ROLE_MASTER) {
341
crm_trace("LHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
346
pe_rsc_trace(rsc, "LHS: %s with %s: %d", constraint->rsc_lh->id, constraint->rsc_rh->id,
343
348
rsc->allowed_nodes =
344
349
constraint->rsc_lh->cmds->merge_weights(constraint->rsc_lh, rsc->id,
345
350
rsc->allowed_nodes,
346
351
constraint->node_attribute,
347
constraint->score / INFINITY, TRUE, TRUE);
352
(float)constraint->score / INFINITY,
353
(pe_weights_rollback |
354
pe_weights_positive));
352
359
for (; gIter != NULL; gIter = gIter->next) {
353
360
rsc_ticket_t *rsc_ticket = (rsc_ticket_t *) gIter->data;
355
if (rsc_ticket->role_lh == RSC_ROLE_MASTER
362
if (rsc_ticket->role_lh == RSC_ROLE_MASTER
356
363
&& (rsc_ticket->ticket->granted == FALSE || rsc_ticket->ticket->standby)) {
357
364
resource_location(rsc, NULL, -INFINITY, "__stateful_without_ticket__", data_set);
371
378
child->sort_index = INFINITY;
373
380
} else if (chosen == NULL || child->sort_index < 0) {
374
crm_trace("%s: %d", child->id, child->sort_index);
381
pe_rsc_trace(rsc, "%s: %d", child->id, child->sort_index);
377
384
node = (node_t *) pe_hash_table_lookup(rsc->allowed_nodes, chosen->details->id);
380
387
child->sort_index = node->weight;
382
crm_trace("Set sort index: %s = %d", child->id, child->sort_index);
389
pe_rsc_trace(rsc, "Set sort index: %s = %d", child->id, child->sort_index);
385
392
rsc->children = g_list_sort_with_data(rsc->children, sort_master_instance, data_set);
386
393
clear_bit(rsc->flags, pe_rsc_merging);
397
filter_anonymous_instance(resource_t * rsc, node_t * node)
399
GListPtr rIter = NULL;
400
char *key = clone_strip(rsc->id);
401
resource_t *parent = uber_parent(rsc);
403
for (rIter = parent->children; rIter; rIter = rIter->next) {
404
resource_t *child = rIter->data;
405
resource_t *active = parent->fns->find_rsc(child, key, node, pe_find_clone|pe_find_current);
408
* Look for an active instance on $node, if there is one, only it recieves the master score
409
* Use ->find_rsc() because we might be a cloned group
412
pe_rsc_trace(rsc, "Found %s for %s active on %s: done", active->id, key, node->details->uname);
416
pe_rsc_trace(rsc, "Found %s for %s on %s: not %s", active->id, key, node->details->uname, rsc->id);
420
pe_rsc_trace(rsc, "%s on %s: not active", key, node->details->uname);
424
for (rIter = parent->children; rIter; rIter = rIter->next) {
425
resource_t *child = rIter->data;
428
* We know its not running, but any score will still count if
429
* the instance has been probed on $node
431
* Again use ->find_rsc() because we might be a cloned group
432
* and knowing that other members of the group are known here
435
rsc = parent->fns->find_rsc(child, key, NULL, pe_find_clone);
436
pe_rsc_trace(rsc, "Checking %s for %s on %s", rsc->id, key, node->details->uname);
437
if (g_hash_table_lookup(rsc->known_on, node->details->id)) {
390
447
master_score(resource_t * rsc, node_t * node, int not_set_value)
413
if (rsc->fns->state(rsc, TRUE) < RSC_ROLE_STARTED) {
471
if (rsc->fns->state(rsc, TRUE) < RSC_ROLE_STARTED) {
472
pe_rsc_trace(rsc, "Ingoring master score for %s: unknown state", rsc->id);
418
477
node_t *match = pe_find_node_id(rsc->running_on, node->details->id);
421
crm_trace("%s is not active on %s - ignoring", rsc->id, node->details->uname);
478
node_t *known = pe_hash_table_lookup(rsc->known_on, node->details->id);
480
if (is_not_set(rsc->flags, pe_rsc_unique) && filter_anonymous_instance(rsc, node)) {
481
pe_rsc_trace(rsc, "Anonymous clone %s is allowed on %s", rsc->id, node->details->uname);
483
} else if (match == NULL && known == NULL) {
484
pe_rsc_trace(rsc, "%s (aka. %s) has been filtered on %s - ignoring", rsc->id,
485
rsc->clone_name, node->details->uname);
429
493
} else if (match->weight < 0) {
430
crm_trace("%s on %s has score: %d - ignoring",
431
rsc->id, match->details->uname, match->weight);
494
pe_rsc_trace(rsc, "%s on %s has score: %d - ignoring",
495
rsc->id, match->details->uname, match->weight);
443
507
len = 8 + strlen(name);
444
crm_malloc0(attr_name, len);
508
attr_name = calloc(1, len);
445
509
sprintf(attr_name, "master-%s", name);
448
512
attr_value = g_hash_table_lookup(node->details->attrs, attr_name);
449
crm_trace("%s: %s[%s] = %s", rsc->id, attr_name, node->details->uname, crm_str(attr_value));
513
pe_rsc_trace(rsc, "%s: %s[%s] = %s", rsc->id, attr_name, node->details->uname,
514
crm_str(attr_value));
452
517
if (attr_value != NULL) {
453
518
score = char2score(attr_value);
495
560
new_score = merge_weights(node->weight, score);
496
561
if (new_score != node->weight) {
497
crm_trace("\t%s: Updating preference for %s (%d->%d)",
498
child_rsc->id, node->details->uname, node->weight, new_score);
562
pe_rsc_trace(rsc, "\t%s: Updating preference for %s (%d->%d)",
563
child_rsc->id, node->details->uname, node->weight, new_score);
499
564
node->weight = new_score;
503
568
new_score = max(child_rsc->priority, score);
504
569
if (new_score != child_rsc->priority) {
505
crm_trace("\t%s: Updating priority (%d->%d)",
506
child_rsc->id, child_rsc->priority, new_score);
570
pe_rsc_trace(rsc, "\t%s: Updating priority (%d->%d)",
571
child_rsc->id, child_rsc->priority, new_score);
507
572
child_rsc->priority = new_score;
602
667
GListPtr list = NULL;
603
668
resource_t *child_rsc = (resource_t *) gIter->data;
605
crm_trace("Assigning priority for %s: %s", child_rsc->id,
606
role2text(child_rsc->next_role));
670
pe_rsc_trace(rsc, "Assigning priority for %s: %s", child_rsc->id,
671
role2text(child_rsc->next_role));
608
673
if (child_rsc->fns->state(child_rsc, TRUE) == RSC_ROLE_STARTED) {
609
674
set_role_slave(child_rsc, TRUE);
661
726
child_rsc->sort_index = child_rsc->priority;
662
crm_trace("Assigning priority for %s: %d", child_rsc->id, child_rsc->priority);
727
pe_rsc_trace(rsc, "Assigning priority for %s: %d", child_rsc->id, child_rsc->priority);
664
729
if (next_role == RSC_ROLE_MASTER) {
665
730
child_rsc->sort_index = INFINITY;
685
750
do_crm_log(scores_log_level, "%s promotion score on %s: %s",
686
child_rsc->id, chosen ? chosen->details->uname : "none", score);
751
child_rsc->id, chosen ? chosen->details->uname : "none", score);
690
755
chosen = NULL; /* nuke 'chosen' so that we don't promote more than the
691
756
* required number of instances
694
759
if (child_rsc->sort_index < 0) {
695
crm_trace("Not supposed to promote child: %s", child_rsc->id);
760
pe_rsc_trace(rsc, "Not supposed to promote child: %s", child_rsc->id);
697
762
} else if (promoted < clone_data->master_max || is_not_set(rsc->flags, pe_rsc_managed)) {
698
763
chosen = can_be_master(child_rsc);
701
crm_debug("%s master score: %d", child_rsc->id, child_rsc->priority);
766
pe_rsc_debug(rsc, "%s master score: %d", child_rsc->id, child_rsc->priority);
703
768
if (chosen == NULL) {
704
769
set_role_slave(child_rsc, FALSE);
709
crm_info("Promoting %s (%s %s)",
710
child_rsc->id, role2text(child_rsc->role), chosen->details->uname);
774
pe_rsc_info(rsc, "Promoting %s (%s %s)",
775
child_rsc->id, role2text(child_rsc->role), chosen->details->uname);
711
776
set_role_master(child_rsc);
715
780
clone_data->masters_allocated = promoted;
716
crm_info("%s: Promoted %d instances of a possible %d to master",
717
rsc->id, promoted, clone_data->master_max);
781
pe_rsc_info(rsc, "%s: Promoted %d instances of a possible %d to master",
782
rsc->id, promoted, clone_data->master_max);
719
784
clear_bit(rsc->flags, pe_rsc_provisional);
720
785
clear_bit(rsc->flags, pe_rsc_allocating);
738
803
get_clone_variant_data(clone_data, rsc);
740
crm_debug("Creating actions for %s", rsc->id);
805
pe_rsc_debug(rsc, "Creating actions for %s", rsc->id);
742
807
/* create actions as normal */
743
808
clone_create_actions(rsc, data_set);
747
812
gboolean child_demoting = FALSE;
748
813
resource_t *child_rsc = (resource_t *) gIter->data;
750
crm_trace("Creating actions for %s", child_rsc->id);
815
pe_rsc_trace(rsc, "Creating actions for %s", child_rsc->id);
751
816
child_rsc->cmds->create_actions(child_rsc, data_set);
752
817
master_update_pseudo_status(child_rsc, &child_demoting, &child_promoting);
754
819
any_demoting = any_demoting || child_demoting;
755
820
any_promoting = any_promoting || child_promoting;
756
crm_trace("Created actions for %s: %d %d", child_rsc->id, child_promoting,
821
pe_rsc_trace(rsc, "Created actions for %s: %d %d", child_rsc->id, child_promoting,
903
968
master_rsc_colocation_rh(resource_t * rsc_lh, resource_t * rsc_rh, rsc_colocation_t * constraint)
905
970
GListPtr gIter = NULL;
906
clone_variant_data_t *clone_data = NULL;
908
get_clone_variant_data(clone_data, rsc_rh);
910
972
CRM_CHECK(rsc_rh != NULL, return);
911
973
if (is_set(rsc_rh->flags, pe_rsc_provisional)) {
914
976
} else if (constraint->role_rh == RSC_ROLE_UNKNOWN) {
915
crm_trace("Handling %s as a clone colocation", constraint->id);
977
pe_rsc_trace(rsc_rh, "Handling %s as a clone colocation", constraint->id);
916
978
clone_rsc_colocation_rh(rsc_lh, rsc_rh, constraint);
920
982
CRM_CHECK(rsc_lh != NULL, return);
921
983
CRM_CHECK(rsc_lh->variant == pe_native, return);
922
crm_trace("Processing constraint %s: %d", constraint->id, constraint->score);
984
pe_rsc_trace(rsc_rh, "Processing constraint %s: %d", constraint->id, constraint->score);
924
986
if (constraint->role_rh == RSC_ROLE_UNKNOWN) {
939
1001
node_t *chosen = child_rsc->fns->location(child_rsc, NULL, FALSE);
940
1002
enum rsc_role_e next_role = child_rsc->fns->state(child_rsc, FALSE);
942
crm_trace("Processing: %s", child_rsc->id);
1004
pe_rsc_trace(rsc_rh, "Processing: %s", child_rsc->id);
943
1005
if (chosen != NULL && next_role == constraint->role_rh) {
944
crm_trace("Applying: %s %s %s %d", child_rsc->id,
945
role2text(next_role), chosen->details->uname, constraint->score);
1006
pe_rsc_trace(rsc_rh, "Applying: %s %s %s %d", child_rsc->id,
1007
role2text(next_role), chosen->details->uname, constraint->score);
946
1008
if (constraint->score < INFINITY) {
947
1009
node_hash_update_one(rsc_lh->allowed_nodes, chosen,
948
1010
constraint->node_attribute, constraint->score);
965
1027
resource_t *rh_child = find_compatible_child(rsc_lh, rsc_rh, constraint->role_rh, FALSE);
967
1029
if (rh_child == NULL && constraint->score >= INFINITY) {
968
crm_trace("%s can't be promoted %s", rsc_lh->id, constraint->id);
1030
pe_rsc_trace(rsc_lh, "%s can't be promoted %s", rsc_lh->id, constraint->id);
969
1031
rsc_lh->priority = -INFINITY;
971
1033
} else if (rh_child != NULL) {
972
1034
int new_priority = merge_weights(rsc_lh->priority, constraint->score);
974
crm_debug("Applying %s to %s", constraint->id, rsc_lh->id);
975
crm_debug("\t%s: %d->%d", rsc_lh->id, rsc_lh->priority, new_priority);
1036
pe_rsc_debug(rsc_lh, "Applying %s to %s", constraint->id, rsc_lh->id);
1037
pe_rsc_debug(rsc_lh, "\t%s: %d->%d", rsc_lh->id, rsc_lh->priority, new_priority);
976
1038
rsc_lh->priority = new_priority;
993
1055
name = crm_meta_name(XML_RSC_ATTR_MASTER_MAX);
994
1056
crm_xml_add_int(xml, name, clone_data->master_max);
997
1059
name = crm_meta_name(XML_RSC_ATTR_MASTER_NODEMAX);
998
1060
crm_xml_add_int(xml, name, clone_data->master_node_max);