22 get_node_score(
const char *rule,
const char *score,
bool raw,
28 pe_err(
"Rule %s: no score specified. Assuming 0.", rule);
36 if (attr_score == NULL) {
37 crm_debug(
"Rule %s: %s did not have a value for %s",
38 rule, pe__node_name(node), score);
42 crm_debug(
"Rule %s: %s had value %s for %s",
43 rule, pe__node_name(node), attr_score, score);
52 const char *discovery,
crm_time_t *next_change,
56 const char *rule_id = NULL;
57 const char *score = NULL;
58 const char *
boolean = NULL;
59 const char *role = NULL;
62 GList *match_L = NULL;
66 bool raw_score =
true;
67 bool score_allocated =
false;
72 if (rule_xml == NULL) {
80 crm_trace(
"Processing rule: %s", rule_id);
83 pe_err(
"Bad role specified for %s: %s", rule_id, role);
101 if (location_rule == NULL) {
105 if ((re_match_data != NULL) && (re_match_data->
nregs > 0)
106 && (re_match_data->
pmatch[0].rm_so != -1) && !raw_score) {
112 score_allocated =
true;
117 crm_trace(
"Setting role filter: %s", role);
131 for (gIter = match_L; gIter != NULL; gIter = gIter->next) {
134 node->
weight = get_node_score(rule_id, score, raw_score, node, rsc);
138 for (gIter =
data_set->
nodes; gIter != NULL; gIter = gIter->next) {
150 crm_trace(
"Rule %s %s on %s",
ID(rule_xml), accept?
"passed" :
"failed",
151 pe__node_name(node));
153 score_f = get_node_score(rule_id, score, raw_score, node, rsc);
158 if ((
local == NULL) && do_and) {
161 }
else if (
local == NULL) {
163 match_L = g_list_append(match_L,
local);
170 pe__node_name(node),
local->weight);
172 }
else if (do_and && !accept) {
176 if (
delete != NULL) {
177 match_L = g_list_remove(match_L,
delete);
178 crm_trace(
"%s did not match", pe__node_name(node));
184 if (score_allocated) {
190 crm_trace(
"No matching nodes for rule %s", rule_id);
196 return location_rule;
200 unpack_rsc_location(xmlNode *xml_obj,
pe_resource_t *rsc,
const char *role,
212 "does not exist",
id, rsc_id);
220 if ((node != NULL) && (score != NULL)) {
242 generate_location_rule(rsc, rule_xml, discovery, next_change,
267 if ((location != NULL) && (role != NULL)) {
269 pe_err(
"Invalid constraint %s: Bad role %s",
id, role);
299 unpack_rsc_location(xml_obj, rsc, NULL, NULL,
data_set, NULL);
304 regex_t *r_patt = calloc(1,
sizeof(regex_t));
308 if (value[0] ==
'!') {
313 if (regcomp(r_patt, value, REG_EXTENDED)) {
316 " has invalid value '%s'",
id, value);
325 regmatch_t *pmatch = NULL;
328 if(r_patt->re_nsub > 0) {
329 nregs = r_patt->re_nsub + 1;
333 pmatch = calloc(nregs,
sizeof(regmatch_t));
335 status = regexec(r_patt, r->
id, nregs, pmatch, 0);
337 if (!invert && (status == 0)) {
344 crm_debug(
"'%s' matched '%s' for %s", r->
id, value,
id);
345 unpack_rsc_location(xml_obj, r, NULL, NULL,
data_set,
348 }
else if (invert && (status != 0)) {
349 crm_debug(
"'%s' is an inverted match of '%s' for %s",
351 unpack_rsc_location(xml_obj, r, NULL, NULL,
data_set, NULL);
354 crm_trace(
"'%s' does not match '%s' for %s", r->
id, value,
id);
367 unpack_location_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
370 const char *
id = NULL;
371 const char *rsc_id = NULL;
372 const char *state = NULL;
375 xmlNode *rsc_set = NULL;
377 *expanded_xml = NULL;
379 CRM_CHECK(xml_obj != NULL,
return EINVAL);
384 crm_element_name(xml_obj));
390 if (*expanded_xml != NULL) {
396 if (rsc_id == NULL) {
402 "valid resource or tag",
id, rsc_id);
405 }
else if (rsc != NULL) {
418 *expanded_xml = NULL;
422 if (rsc_set != NULL) {
433 *expanded_xml = NULL;
443 xmlNode *xml_rsc = NULL;
447 const char *local_score;
452 if (set_id == NULL) {
455 pcmk__s(
ID(location),
"(missing ID)"));
467 if (resource == NULL) {
469 set_id,
ID(xml_rsc));
473 unpack_rsc_location(location, resource, role, local_score,
data_set,
484 bool any_sets =
false;
486 xmlNode *orig_xml = NULL;
487 xmlNode *expanded_xml = NULL;
495 xml_obj = expanded_xml;
519 unpack_simple_location(xml_obj,
data_set);
540 int node_weight,
const char *discover_mode,
546 pe_err(
"Invalid constraint: no ID specified");
549 }
else if (rsc == NULL) {
550 pe_err(
"Invalid constraint %s: no resource specified",
id);
553 }
else if (node == NULL) {
554 CRM_CHECK(node_weight == 0,
return NULL);
558 if (new_con != NULL) {
559 new_con->
id = strdup(
id);
564 if (pcmk__str_eq(discover_mode,
"always",
571 }
else if (pcmk__str_eq(discover_mode,
"exclusive",
pcmk__str_casei)) {
577 "in location constraint", discover_mode);
583 copy->
weight = node_weight;
605 iter != NULL; iter = iter->next) {
625 bool need_role =
false;
627 CRM_CHECK((rsc != NULL) && (location != NULL),
return);
633 "Not applying %s to %s because role will be %s not %s",
640 pe_rsc_trace(rsc,
"Not applying %s to %s because no nodes match",
641 location->
id, rsc->
id);
646 (need_role?
" for role " :
""),
649 for (GList *gIter = location->
node_list_rh; gIter != NULL;
650 gIter = gIter->next) {
657 if (weighted_node == NULL) {
659 node->
weight, pe__node_name(node));
662 (gpointer) weighted_node->details->id,
666 node->
weight, pe__node_name(node));
671 if (weighted_node->rsc_discover_mode < location->
discover_mode) {
GList * pcmk__copy_node_list(const GList *list, bool reset)
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
#define CRM_CHECK(expr, failure_action)
pe_node_t * pe_find_node(GList *node_list, const char *uname)
enum rsc_role_e role_filter
const char * pe_node_attribute_calculated(const pe_node_t *node, const char *name, const pe_resource_t *rsc)
bool crm_time_is_defined(const crm_time_t *t)
Check whether a time object has been initialized yet.
struct crm_time_s crm_time_t
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
#define pcmk__config_warn(fmt...)
gboolean pe_test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role, crm_time_t *now, crm_time_t *next_change, pe_match_data_t *match_data)
resource_alloc_functions_t * cmds
#define XML_RULE_ATTR_SCORE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
enum rsc_role_e next_role
gboolean exclusive_discover
int char2score(const char *score)
Get the integer value of a score string.
#define pcmk__config_err(fmt...)
void pcmk__unpack_location(xmlNode *xml_obj, pe_working_set_t *data_set)
#define XML_LOCATION_ATTR_DISCOVERY
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pe_node_t * pe__copy_node(const pe_node_t *this_node)
#define XML_LOC_ATTR_SOURCE
#define XML_CONS_TAG_RSC_SET
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, pe_working_set_t *data_set)
xmlNode * copy_xml(xmlNode *src_node)
const char * role2text(enum rsc_role_e role)
enum pe_discover_e discover_mode
#define crm_debug(fmt, args...)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_LOC_ATTR_SOURCE_PATTERN
#define crm_trace(fmt, args...)
struct pe_node_shared_s * details
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
pe_working_set_t * data_set
#define XML_TAG_RESOURCE_REF
char * pe_expand_re_matches(const char *string, pe_re_match_data_t *match_data)
void free_xml(xmlNode *child)
enum rsc_role_e text2role(const char *role)
long long crm_time_get_seconds_since_epoch(const crm_time_t *dt)
G_GNUC_INTERNAL pe_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
#define XML_RULE_ATTR_BOOLEAN_OP
pe_node_t * pe_find_node_id(GList *node_list, const char *id)
pe__location_t * pcmk__new_location(const char *id, pe_resource_t *rsc, int node_weight, const char *discover_mode, pe_node_t *node, pe_working_set_t *data_set)
Cluster status and scheduling.
pcmk__action_result_t result
void xml_remove_prop(xmlNode *obj, const char *name)
GHashTable * pe_rsc_params(pe_resource_t *rsc, const pe_node_t *node, pe_working_set_t *data_set)
Get a table of resource parameters.
rsc_role_e
Possible roles that a resource can be in.
GList * placement_constraints
int pcmk__add_scores(int score1, int score2)
void pcmk__apply_locations(pe_working_set_t *data_set)
#define crm_log_xml_trace(xml, text)
#define XML_RULE_ATTR_SCORE_ATTRIBUTE
void(* apply_location)(pe_resource_t *rsc, pe__location_t *location)
#define pe_rsc_trace(rsc, fmt, args...)
void pcmk__apply_location(pe_resource_t *rsc, pe__location_t *location)
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(pe_working_set_t *data_set, const char *id, pe_resource_t **rsc, pe_tag_t **tag)
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, pe_working_set_t *data_set)
GHashTable * allowed_nodes
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
#define XML_RULE_ATTR_ROLE
void crm_time_free(crm_time_t *dt)