33 parse_location_role(
const char *role_spec,
enum rsc_role_e *role)
35 if (role_spec == NULL) {
74 score_attribute_name(
const xmlNode *rule_xml,
char **allocated,
77 const char *
name = NULL;
93 if (*allocated != NULL) {
110 score_from_rule(
const xmlNode *rule_xml,
int *score)
115 if (score_s == NULL) {
119 pcmk__xe_id(rule_xml));
149 score_from_attr(
const char *constraint_id,
const char *attr_name,
153 const char *
target = NULL;
154 const char *score_s = NULL;
159 if (pcmk__str_empty(score_s)) {
160 crm_info(
"Ignoring location %s for %s on %s " 161 "because it has no node attribute %s",
162 constraint_id, rsc->
id, pcmk__node_name(node), attr_name);
168 crm_warn(
"Ignoring location %s for node %s because node " 169 "attribute %s value '%s' is not a valid score: %s",
170 constraint_id, pcmk__node_name(node), attr_name,
195 const char *discovery,
crm_time_t *next_change,
198 const char *rule_id = NULL;
199 const char *score_attr = NULL;
200 const char *
boolean = NULL;
201 const char *role_spec = NULL;
205 char *local_score_attr = NULL;
211 if (rule_xml == NULL) {
216 if (rule_id == NULL) {
226 if (parse_location_role(role_spec, &role)) {
227 crm_trace(
"Setting rule %s role filter to %s", rule_id, role_spec);
231 constraint_id, rule_id, role_spec);
244 constraint_id, rule_id,
boolean);
252 score_attr = score_attribute_name(rule_xml, &local_score_attr, rule_input);
253 if ((score_attr == NULL)
254 && (score_from_rule(rule_xml, &score) !=
pcmk_rc_ok)) {
259 CRM_CHECK(location_rule != NULL,
return NULL);
264 iter != NULL; iter = iter->next) {
278 if ((score_attr != NULL)
279 && (score_from_attr(constraint_id, score_attr, node, rsc,
286 local->assign->score = score;
288 "Location %s score for %s on %s is %s via rule %s",
289 constraint_id, rsc->
id, pcmk__node_name(node),
293 free(local_score_attr);
295 if (location_rule->
nodes == NULL) {
296 crm_trace(
"No matching nodes for location constraint rule %s", rule_id);
298 crm_trace(
"Location constraint rule %s matched %d nodes",
299 rule_id, g_list_length(location_rule->
nodes));
306 const char *role_spec,
const char *score,
307 char *rsc_id_match,
int rsc_id_nmatches,
308 regmatch_t *rsc_id_submatches)
318 "does not exist",
id, rsc_id);
326 if ((node != NULL) && (score != NULL)) {
334 crm_info(
"Ignoring location constraint %s " 335 "because '%s' is not a known node",
336 pcmk__s(
id,
"without ID"), node);
343 "because '%s' is not a valid score",
id, score);
347 if (role_spec == NULL) {
350 if (parse_location_role(role_spec, &role)) {
351 crm_trace(
"Setting location constraint %s role filter: %s",
361 if (location == NULL) {
373 .rsc_id = rsc_id_match,
374 .rsc_id_submatches = rsc_id_submatches,
375 .rsc_id_nmatches = rsc_id_nmatches,
378 generate_location_rule(rsc, rule_xml, discovery, next_change,
388 "location rule evaluation");
404 unpack_rsc_location(xml_obj, rsc, NULL, NULL, NULL, 0, NULL);
412 if (value[0] ==
'!') {
417 if (regcomp(®ex, value, REG_EXTENDED) != 0) {
420 " has invalid value '%s'",
id, value);
425 iter != NULL; iter = iter->next) {
429 regmatch_t *pmatch = NULL;
432 if (regex.re_nsub > 0) {
433 nregs = regex.re_nsub + 1;
439 status = regexec(®ex, r->
id, nregs, pmatch, 0);
441 if (!invert && (status == 0)) {
442 crm_debug(
"'%s' matched '%s' for %s", r->
id, value,
id);
443 unpack_rsc_location(xml_obj, r, NULL, NULL, r->
id, nregs,
446 }
else if (invert && (status != 0)) {
447 crm_debug(
"'%s' is an inverted match of '%s' for %s",
449 unpack_rsc_location(xml_obj, r, NULL, NULL, NULL, 0, NULL);
452 crm_trace(
"'%s' does not match '%s' for %s", r->
id, value,
id);
464 unpack_location_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
467 const char *
id = NULL;
468 const char *rsc_id = NULL;
469 const char *state = NULL;
472 xmlNode *rsc_set = NULL;
474 *expanded_xml = NULL;
476 CRM_CHECK(xml_obj != NULL,
return EINVAL);
478 id = pcmk__xe_id(xml_obj);
487 if (*expanded_xml != NULL) {
493 if (rsc_id == NULL) {
499 "valid resource or tag",
id, rsc_id);
502 }
else if (rsc != NULL) {
517 *expanded_xml = NULL;
521 if (rsc_set != NULL) {
534 *expanded_xml = NULL;
542 unpack_location_set(xmlNode *location, xmlNode *
set,
545 xmlNode *xml_rsc = NULL;
549 const char *local_score;
553 set_id = pcmk__xe_id(
set);
554 if (set_id == NULL) {
557 pcmk__s(pcmk__xe_id(location),
"(missing ID)"));
569 pcmk__xe_id(xml_rsc));
570 if (resource == NULL) {
572 set_id, pcmk__xe_id(xml_rsc));
576 unpack_rsc_location(location, resource, role, local_score, NULL, 0,
587 bool any_sets =
false;
589 xmlNode *orig_xml = NULL;
590 xmlNode *expanded_xml = NULL;
598 xml_obj = expanded_xml;
622 unpack_simple_location(xml_obj,
scheduler);
642 int node_score,
const char *probe_mode,
pcmk_node_t *node)
646 CRM_CHECK((node != NULL) || (node_score == 0),
return NULL);
661 new_con->
nodes = NULL;
678 "in location constraint", probe_mode);
685 new_con->
nodes = g_list_prepend(NULL, copy);
707 iter != NULL; iter = iter->next) {
727 bool need_role =
false;
735 "Not applying %s to %s because role will be %s not %s",
736 location->
id, rsc->
id,
742 if (location->
nodes == NULL) {
744 location->
id, rsc->
id);
748 for (GList *iter = location->
nodes; iter != NULL; iter = iter->next) {
757 (need_role?
" for role " :
""),
759 rsc->
id, pcmk__node_name(node),
760 ((allowed_node == NULL)?
'=' :
'+'),
763 if (allowed_node == NULL) {
766 (gpointer) allowed_node->
priv->
id,
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.
enum pcmk__probe_mode probe_mode
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
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
#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 pcmk__probe_mode probe_mode
#define pcmk__set_rsc_flags(resource, flags_to_set)
#define pcmk__config_err(fmt...)
GList * location_constraints
pcmk__scheduler_private_t * priv
#define PCMK_XA_SCORE_ATTRIBUTE
void pcmk__xe_remove_attr(xmlNode *element, const char *name)
void pcmk__apply_locations(pcmk_scheduler_t *scheduler)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
enum rsc_role_e pcmk_parse_role(const char *role)
Parse a resource role from a string role specification.
pcmk__location_t * pcmk__new_location(const char *id, pcmk_resource_t *rsc, int node_score, const char *probe_mode, pcmk_node_t *node)
void pcmk__xml_free(xmlNode *xml)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
pcmk__node_private_t * priv
char * pcmk__replace_submatches(const char *string, const char *match, const regmatch_t submatches[], int nmatches)
#define crm_warn(fmt, args...)
#define PCMK_VALUE_ALWAYS
#define crm_debug(fmt, args...)
#define PCMK_XE_RSC_LOCATION
pcmk_scheduler_t * scheduler
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
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.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define crm_trace(fmt, args...)
void(* apply_location)(pcmk_resource_t *rsc, pcmk__location_t *location)
pcmk__resource_private_t * priv
enum rsc_role_e next_role
GList * location_constraints
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)
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)
GHashTable * allowed_nodes
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
#define pcmk__assert(expr)
Cluster status and scheduling.
#define PCMK_VALUE_EXCLUSIVE
pcmk_scheduler_t * scheduler
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id, pcmk_resource_t **rsc, pcmk__idref_t **tag)
#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
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
#define PCMK_XA_RSC_PATTERN
#define PCMK_XA_BOOLEAN_OP
#define crm_log_xml_trace(xml, text)
Resource role is unknown.
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)
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define crm_info(fmt, args...)
const pcmk__assignment_methods_t * cmds
void crm_time_free(crm_time_t *dt)
struct pcmk__node_assignment * assign