23 get_node_score(
const char *rule,
const char *score,
bool raw,
29 pe_err(
"Rule %s: no score specified. Assuming 0.", rule);
35 const char *attr_score = NULL;
41 if (attr_score == NULL) {
42 crm_debug(
"Rule %s: %s did not have a value for %s",
43 rule, pe__node_name(node), score);
47 crm_debug(
"Rule %s: %s had value %s for %s",
48 rule, pe__node_name(node), attr_score, score);
57 const char *discovery,
crm_time_t *next_change,
60 const char *rule_id = NULL;
61 const char *score = NULL;
62 const char *
boolean = NULL;
63 const char *role = NULL;
70 bool raw_score =
true;
71 bool score_allocated =
false;
76 if (rule_xml == NULL) {
84 crm_trace(
"Processing rule: %s", rule_id);
87 pe_err(
"Bad role specified for %s: %s", rule_id, role);
104 if (location_rule == NULL) {
108 if ((re_match_data != NULL) && (re_match_data->
nregs > 0)
109 && (re_match_data->
pmatch[0].rm_so != -1) && !raw_score) {
115 score_allocated =
true;
120 crm_trace(
"Setting role filter: %s", role);
132 for (iter = nodes; iter != NULL; iter = iter->next) {
135 node->
weight = get_node_score(rule_id, score, raw_score, node, rsc);
139 for (iter = rsc->
cluster->
nodes; iter != NULL; iter = iter->next) {
151 crm_trace(
"Rule %s %s on %s",
ID(rule_xml), accept?
"passed" :
"failed",
152 pe__node_name(node));
154 score_f = get_node_score(rule_id, score, raw_score, node, rsc);
159 if ((
local == NULL) && do_and) {
162 }
else if (
local == NULL) {
164 nodes = g_list_append(nodes,
local);
170 crm_trace(
"%s has score %s after %s", pe__node_name(node),
173 }
else if (do_and && !accept) {
177 if (
delete != NULL) {
178 nodes = g_list_remove(nodes,
delete);
179 crm_trace(
"%s did not match", pe__node_name(node));
185 if (score_allocated) {
191 crm_trace(
"No matching nodes for rule %s", rule_id);
197 return location_rule;
201 unpack_rsc_location(xmlNode *xml_obj,
pcmk_resource_t *rsc,
const char *role,
213 "does not exist",
id, rsc_id);
221 if ((node != NULL) && (score != NULL)) {
242 generate_location_rule(rsc, rule_xml, discovery, next_change,
258 "location rule evaluation");
268 if ((location != NULL) && (role != NULL)) {
270 pe_err(
"Invalid constraint %s: Bad role %s",
id, role);
300 unpack_rsc_location(xml_obj, rsc, NULL, NULL, NULL);
305 regex_t *r_patt = calloc(1,
sizeof(regex_t));
308 if (value[0] ==
'!') {
313 if (regcomp(r_patt, value, REG_EXTENDED) != 0) {
316 " has invalid value '%s'",
id, value);
326 regmatch_t *pmatch = NULL;
329 if (r_patt->re_nsub > 0) {
330 nregs = r_patt->re_nsub + 1;
334 pmatch = calloc(nregs,
sizeof(regmatch_t));
336 status = regexec(r_patt, r->
id, nregs, pmatch, 0);
338 if (!invert && (status == 0)) {
345 crm_debug(
"'%s' matched '%s' for %s", r->
id, value,
id);
346 unpack_rsc_location(xml_obj, r, NULL, NULL, &re_match_data);
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, 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);
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;
441 unpack_location_set(xmlNode *location, xmlNode *
set,
444 xmlNode *xml_rsc = NULL;
448 const char *local_score;
453 if (set_id == NULL) {
456 pcmk__s(
ID(location),
"(missing ID)"));
468 if (resource == NULL) {
470 set_id,
ID(xml_rsc));
474 unpack_rsc_location(location, resource, role, local_score, NULL);
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,
scheduler);
539 int node_score,
const char *discover_mode,
pcmk_node_t *node)
544 pe_err(
"Invalid constraint: no ID specified");
547 }
else if (rsc == NULL) {
548 pe_err(
"Invalid constraint %s: no resource specified",
id);
551 }
else if (node == NULL) {
556 if (new_con != NULL) {
557 new_con->
id = strdup(
id);
562 if (pcmk__str_eq(discover_mode,
"always",
569 }
else if (pcmk__str_eq(discover_mode,
"exclusive",
pcmk__str_casei)) {
575 "in location constraint", discover_mode);
581 copy->
weight = node_score;
603 iter != NULL; iter = iter->next) {
623 bool need_role =
false;
625 CRM_ASSERT((rsc != NULL) && (location != NULL));
631 "Not applying %s to %s because role will be %s not %s",
638 pe_rsc_trace(rsc,
"Not applying %s to %s because no nodes match",
639 location->
id, rsc->
id);
644 (need_role?
" for role " :
""),
648 iter != NULL; iter = iter->next) {
654 if (allowed_node == NULL) {
656 node->
weight, pe__node_name(node));
663 node->
weight, pe__node_name(node));
pcmk_assignment_methods_t * cmds
Resource assignment methods.
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
#define CRM_CHECK(expr, failure_action)
enum rsc_role_e role_filter
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
GHashTable * attrs
Node attributes.
bool crm_time_is_defined(const crm_time_t *t)
Check whether a time object has been initialized yet.
void pcmk__unpack_location(xmlNode *xml_obj, pcmk_scheduler_t *scheduler)
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, const pcmk_scheduler_t *scheduler)
struct crm_time_s crm_time_t
#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)
#define XML_RULE_ATTR_SCORE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
enum rsc_role_e next_role
Resource's scheduled next role.
gboolean exclusive_discover
Whether exclusive probing is enabled.
int char2score(const char *score)
Get the integer value of a score string.
#define pcmk__config_err(fmt...)
GHashTable * meta
Resource's meta-attributes.
#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.
void pcmk__apply_locations(pcmk_scheduler_t *scheduler)
Always probe resource on node.
#define XML_LOC_ATTR_SOURCE
Implementation of pcmk_scheduler_t.
#define XML_CONS_TAG_RSC_SET
GList * resources
Resources in cluster.
GList * nodes
Nodes in cluster.
xmlNode * copy_xml(xmlNode *src_node)
const char * role2text(enum rsc_role_e role)
int weight
Node score for a given resource.
enum pe_discover_e discover_mode
Implementation of pcmk_resource_t.
#define crm_debug(fmt, args...)
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
void(* apply_location)(pcmk_resource_t *rsc, pe__location_t *location)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
pcmk_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
#define XML_LOC_ATTR_SOURCE_PATTERN
const char * pe__node_attribute_calculated(const pcmk_node_t *node, const char *name, const pcmk_resource_t *rsc, enum pcmk__rsc_node node_type, bool force_host)
#define crm_trace(fmt, args...)
pcmk_node_t * pe_find_node(const GList *node_list, const char *node_name)
Find a node by name in a list of nodes.
struct pe_node_shared_s * details
Basic node information.
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
void pcmk__apply_location(pcmk_resource_t *rsc, pe__location_t *location)
Never probe resource on node.
#define XML_TAG_RESOURCE_REF
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id, pcmk_resource_t **rsc, pcmk_tag_t **tag)
void free_xml(xmlNode *child)
Implementation of pcmk_node_t.
enum rsc_role_e text2role(const char *role)
long long crm_time_get_seconds_since_epoch(const crm_time_t *dt)
void pe__update_recheck_time(time_t recheck, pcmk_scheduler_t *scheduler, const char *reason)
int rsc_discover_mode
Probe mode (enum pe_discover_e)
const char * id
Node ID at the cluster layer.
#define XML_RULE_ATTR_BOOLEAN_OP
pe__location_t * pcmk__new_location(const char *id, pcmk_resource_t *rsc, int node_score, const char *discover_mode, pcmk_node_t *node)
Cluster status and scheduling.
pcmk__action_result_t result
GList * pcmk__copy_node_list(const GList *list, bool reset)
pcmk_scheduler_t * scheduler
void xml_remove_prop(xmlNode *obj, const char *name)
Configuration tag object.
GList * placement_constraints
Location constraints.
int pcmk__add_scores(int score1, int score2)
#define crm_log_xml_trace(xml, text)
#define XML_RULE_ATTR_SCORE_ATTRIBUTE
Resource role is unknown.
#define pe_rsc_trace(rsc, fmt, args...)
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
crm_time_t * now
Current time for evaluation purposes.
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
char * pe_expand_re_matches(const char *string, const pe_re_match_data_t *match_data)
Expand any regular expression submatches (%0-%9) in a string.
#define XML_RULE_ATTR_ROLE
Where resource is running.
void crm_time_free(crm_time_t *dt)