24 get_node_score(
const char *rule,
const char *score,
bool raw,
37 const char *attr_score = NULL;
44 if (attr_score == NULL) {
45 crm_debug(
"Rule %s: %s did not have a value for %s",
46 rule, pcmk__node_name(node), score);
50 crm_debug(
"Rule %s: %s had value %s for %s",
51 rule, pcmk__node_name(node), attr_score, score);
68 parse_location_role(
const char *role_spec,
enum rsc_role_e *role)
70 if (role_spec == NULL) {
112 const char *discovery,
crm_time_t *next_change,
115 const char *rule_id = NULL;
116 const char *score = NULL;
117 const char *
boolean = NULL;
118 const char *role_spec = NULL;
122 bool raw_score =
true;
123 bool score_allocated =
false;
130 if (rule_xml == NULL) {
135 if (rule_id == NULL) {
137 " in location constraint");
144 if (parse_location_role(role_spec, &role)) {
145 crm_trace(
"Setting rule %s role filter to %s", rule_id, role_spec);
152 crm_trace(
"Processing location constraint rule %s", rule_id);
181 CRM_CHECK(location_rule != NULL,
return NULL);
194 score_allocated =
true;
198 for (iter = rsc->
cluster->
nodes; iter != NULL; iter = iter->next) {
209 local->weight = get_node_score(rule_id, score, raw_score, node,
211 crm_trace(
"%s has score %s after %s", pcmk__node_name(node),
216 if (score_allocated) {
220 if (location_rule->
nodes == NULL) {
221 crm_trace(
"No matching nodes for location constraint rule %s", rule_id);
223 crm_trace(
"Location constraint rule %s matched %d nodes",
224 rule_id, g_list_length(location_rule->
nodes));
231 const char *role_spec,
const char *score,
232 char *rsc_id_match,
int rsc_id_nmatches,
233 regmatch_t *rsc_id_submatches)
243 "does not exist",
id, rsc_id);
251 if ((node != NULL) && (score != NULL)) {
258 crm_info(
"Ignoring location constraint %s " 259 "because '%s' is not a known node",
260 pcmk__s(
id,
"without ID"), node);
264 if (role_spec == NULL) {
267 if (parse_location_role(role_spec, &role)) {
268 crm_trace(
"Setting location constraint %s role filter: %s",
276 "Invalid value '%s'",
id, role_spec);
280 if (location == NULL) {
290 .rsc_meta = rsc->
meta,
291 .rsc_id = rsc_id_match,
292 .rsc_id_submatches = rsc_id_submatches,
293 .rsc_id_nmatches = rsc_id_nmatches,
309 if (generate_location_rule(rsc, rule_xml, discovery, next_change,
317 " elements in a location constraint is " 318 "deprecated and will be removed in a future " 319 "release (use a single new rule combining the " 327 "no valid rules",
id);
337 "location rule evaluation");
353 unpack_rsc_location(xml_obj, rsc, NULL, NULL, NULL, 0, NULL);
361 if (value[0] ==
'!') {
366 if (regcomp(®ex, value, REG_EXTENDED) != 0) {
369 " has invalid value '%s'",
id, value);
378 regmatch_t *pmatch = NULL;
381 if (regex.re_nsub > 0) {
382 nregs = regex.re_nsub + 1;
388 status = regexec(®ex, r->
id, nregs, pmatch, 0);
390 if (!invert && (status == 0)) {
391 crm_debug(
"'%s' matched '%s' for %s", r->
id, value,
id);
392 unpack_rsc_location(xml_obj, r, NULL, NULL, r->
id, nregs,
395 }
else if (invert && (status != 0)) {
396 crm_debug(
"'%s' is an inverted match of '%s' for %s",
398 unpack_rsc_location(xml_obj, r, NULL, NULL, NULL, 0, NULL);
401 crm_trace(
"'%s' does not match '%s' for %s", r->
id, value,
id);
413 unpack_location_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
416 const char *
id = NULL;
417 const char *rsc_id = NULL;
418 const char *state = NULL;
421 xmlNode *rsc_set = NULL;
423 *expanded_xml = NULL;
425 CRM_CHECK(xml_obj != NULL,
return EINVAL);
427 id = pcmk__xe_id(xml_obj);
436 if (*expanded_xml != NULL) {
442 if (rsc_id == NULL) {
448 "valid resource or tag",
id, rsc_id);
451 }
else if (rsc != NULL) {
466 *expanded_xml = NULL;
470 if (rsc_set != NULL) {
483 *expanded_xml = NULL;
491 unpack_location_set(xmlNode *location, xmlNode *
set,
494 xmlNode *xml_rsc = NULL;
498 const char *local_score;
502 set_id = pcmk__xe_id(
set);
503 if (set_id == NULL) {
506 pcmk__s(pcmk__xe_id(location),
"(missing ID)"));
517 pcmk__xe_id(xml_rsc));
518 if (resource == NULL) {
520 set_id, pcmk__xe_id(xml_rsc));
524 unpack_rsc_location(location, resource, role, local_score, NULL, 0,
535 bool any_sets =
false;
537 xmlNode *orig_xml = NULL;
538 xmlNode *expanded_xml = NULL;
546 xml_obj = expanded_xml;
570 unpack_simple_location(xml_obj,
scheduler);
590 int node_score,
const char *discover_mode,
pcmk_node_t *node)
594 CRM_CHECK((node != NULL) || (node_score == 0),
return NULL);
609 new_con->
nodes = NULL;
627 "in location constraint", discover_mode);
633 copy->
weight = node_score;
634 new_con->
nodes = g_list_prepend(NULL, copy);
654 iter != NULL; iter = iter->next) {
674 bool need_role =
false;
676 CRM_ASSERT((rsc != NULL) && (location != NULL));
682 "Not applying %s to %s because role will be %s not %s",
688 if (location->
nodes == NULL) {
690 location->
id, rsc->
id);
694 for (GList *iter = location->
nodes; iter != NULL; iter = iter->next) {
701 (need_role?
" for role " :
""),
703 rsc->
id, pcmk__node_name(node),
704 ((allowed_node == NULL)?
'=' :
'+'),
707 if (allowed_node == NULL) {
pcmk_assignment_methods_t * cmds
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
#define CRM_CHECK(expr, failure_action)
pcmk_node_t * pcmk_find_node(const pcmk_scheduler_t *scheduler, const char *node_name)
Find a node by name in scheduler data.
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
pcmk_scheduler_t * cluster
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
enum pcmk__combine pcmk__parse_combine(const char *combine)
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
pcmk__location_t * pcmk__new_location(const char *id, pcmk_resource_t *rsc, int node_score, const char *discover_mode, pcmk_node_t *node)
#define pcmk__config_warn(fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define PCMK_META_CONTAINER_ATTRIBUTE_TARGET
#define PCMK_XA_RESOURCE_DISCOVERY
#define PCMK_XE_RESOURCE_REF
enum rsc_role_e next_role
gboolean exclusive_discover
#define pcmk__config_err(fmt...)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define PCMK_XA_SCORE_ATTRIBUTE
void pcmk__apply_locations(pcmk_scheduler_t *scheduler)
enum rsc_role_e pcmk_parse_role(const char *role)
Parse a resource role from a string role specification.
char * pcmk__replace_submatches(const char *string, const char *match, const regmatch_t submatches[], int nmatches)
#define PCMK_VALUE_ALWAYS
#define crm_debug(fmt, args...)
#define PCMK_XE_RSC_LOCATION
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
int pcmk_evaluate_rule(xmlNode *rule, const pcmk_rule_input_t *rule_input, crm_time_t *next_change)
Evaluate a single rule, including all its conditions.
int char2score(const char *score)
Get the integer value of a score string.
#define crm_trace(fmt, args...)
struct pe_node_shared_s * details
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
void pcmk__xe_remove_attr(xmlNode *element, const char *name)
void(* apply_location)(pcmk_resource_t *rsc, pcmk__location_t *location)
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)
void pcmk__apply_location(pcmk_resource_t *rsc, pcmk__location_t *location)
int pcmk__add_scores(int score1, int score2)
#define pcmk__str_copy(str)
#define pcmk__warn_once(wo_flag, fmt...)
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)
Cluster status and scheduling.
pcmk__action_result_t result
#define PCMK_VALUE_EXCLUSIVE
pcmk_scheduler_t * scheduler
#define PCMK_XE_RESOURCE_SET
const char * pcmk__node_attr(const pcmk_node_t *node, const char *name, const char *target, enum pcmk__rsc_node node_type)
enum rsc_role_e role_filter
#define PCMK_XA_RSC_PATTERN
#define PCMK_XA_BOOLEAN_OP
GList * placement_constraints
#define crm_log_xml_trace(xml, text)
Resource role is unknown.
enum pe_discover_e discover_mode
Location constraint object.
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
#define pcmk__assert_alloc(nmemb, size)
xmlNode * pcmk__xe_next_same(const xmlNode *node)
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define crm_info(fmt, args...)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
GHashTable * allowed_nodes
Where resource is running.
void crm_time_free(crm_time_t *dt)