847 lines
30 KiB
Diff
847 lines
30 KiB
Diff
From df587aaec07b4a08364d4024b3d0c73e6dede562 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 9 Nov 2020 14:55:42 -0600
|
|
Subject: [PATCH 1/9] Refactor: scheduler: simplify XML attribute filtering
|
|
function
|
|
|
|
---
|
|
lib/pengine/pe_digest.c | 52 ++++++++++++++++++++++++++-----------------------
|
|
1 file changed, 28 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c
|
|
index 5bcd22b..1e119f9 100644
|
|
--- a/lib/pengine/pe_digest.c
|
|
+++ b/lib/pengine/pe_digest.c
|
|
@@ -45,30 +45,38 @@ pe__free_digests(gpointer ptr)
|
|
}
|
|
}
|
|
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Remove named attributes from an XML element
|
|
+ *
|
|
+ * \param[in,out] param_set XML to be filtered
|
|
+ * \param[in] param_string Space-separated list of attribute names
|
|
+ * \param[in] need_present Whether to remove attributes that match,
|
|
+ * or those that don't match
|
|
+ */
|
|
static void
|
|
-filter_parameters(xmlNode * param_set, const char *param_string, bool need_present)
|
|
+filter_parameters(xmlNode *param_set, const char *param_string,
|
|
+ bool need_present)
|
|
{
|
|
- if (param_set && param_string) {
|
|
- xmlAttrPtr xIter = param_set->properties;
|
|
-
|
|
- while (xIter) {
|
|
- const char *prop_name = (const char *)xIter->name;
|
|
- char *name = crm_strdup_printf(" %s ", prop_name);
|
|
- char *match = strstr(param_string, name);
|
|
+ if ((param_set == NULL) || (param_string == NULL)) {
|
|
+ return;
|
|
+ }
|
|
+ for (xmlAttrPtr xIter = param_set->properties; xIter; ) {
|
|
+ const char *prop_name = (const char *) xIter->name;
|
|
+ char *name = crm_strdup_printf(" %s ", prop_name);
|
|
+ char *match = strstr(param_string, name);
|
|
|
|
- free(name);
|
|
+ free(name);
|
|
|
|
- // Do now, because current entry might get removed below
|
|
- xIter = xIter->next;
|
|
+ // Do now, because current entry might get removed below
|
|
+ xIter = xIter->next;
|
|
|
|
- if (need_present && match == NULL) {
|
|
- crm_trace("%s not found in %s", prop_name, param_string);
|
|
- xml_remove_prop(param_set, prop_name);
|
|
+ if ((need_present && (match == NULL))
|
|
+ || (!need_present && (match != NULL))) {
|
|
|
|
- } else if (need_present == FALSE && match) {
|
|
- crm_trace("%s found in %s", prop_name, param_string);
|
|
- xml_remove_prop(param_set, prop_name);
|
|
- }
|
|
+ crm_trace("Filtering %s (%sfound in '%s')",
|
|
+ prop_name, (need_present? "not " : ""), param_string);
|
|
+ xml_remove_prop(param_set, prop_name);
|
|
}
|
|
}
|
|
}
|
|
@@ -203,9 +211,7 @@ calculate_secure_digest(op_digest_cache_t *data, pe_resource_t *rsc,
|
|
g_hash_table_foreach(overrides, hash2field, data->params_secure);
|
|
}
|
|
g_hash_table_foreach(rsc->parameters, hash2field, data->params_secure);
|
|
- if (secure_list != NULL) {
|
|
- filter_parameters(data->params_secure, secure_list, FALSE);
|
|
- }
|
|
+ filter_parameters(data->params_secure, secure_list, FALSE);
|
|
if (pcmk_is_set(pcmk_get_ra_caps(class),
|
|
pcmk_ra_cap_fence_params)) {
|
|
/* For stonith resources, Pacemaker adds special parameters,
|
|
@@ -259,9 +265,7 @@ calculate_restart_digest(op_digest_cache_t *data, xmlNode *xml_op,
|
|
|
|
// Then filter out reloadable parameters, if any
|
|
value = crm_element_value(xml_op, XML_LRM_ATTR_OP_RESTART);
|
|
- if (value != NULL) {
|
|
- filter_parameters(data->params_restart, value, TRUE);
|
|
- }
|
|
+ filter_parameters(data->params_restart, value, TRUE);
|
|
|
|
value = crm_element_value(xml_op, XML_ATTR_CRM_VERSION);
|
|
data->digest_restart_calc = calculate_operation_digest(data->params_restart,
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From f030af8771601d46947ac9276538c46c6c296504 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 9 Nov 2020 18:37:37 -0600
|
|
Subject: [PATCH 2/9] Refactor: scheduler: remember whether action is probe
|
|
when unpacking
|
|
|
|
... to reduce code duplication and improve readability
|
|
---
|
|
lib/pengine/utils.c | 8 ++++----
|
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
|
|
index 04110be..b0922fa 100644
|
|
--- a/lib/pengine/utils.c
|
|
+++ b/lib/pengine/utils.c
|
|
@@ -995,6 +995,8 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
|
|
{
|
|
int timeout_ms = 0;
|
|
const char *value = NULL;
|
|
+ bool is_probe = pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
|
|
+ && (interval_ms == 0);
|
|
#if ENABLE_VERSIONED_ATTRS
|
|
pe_rsc_action_details_t *rsc_details = NULL;
|
|
#endif
|
|
@@ -1026,8 +1028,7 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
|
|
action->meta, NULL, FALSE, data_set);
|
|
|
|
// Determine probe default timeout differently
|
|
- if (pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
|
|
- && (interval_ms == 0)) {
|
|
+ if (is_probe) {
|
|
xmlNode *min_interval_mon = find_min_interval_mon(action->rsc, FALSE);
|
|
|
|
if (min_interval_mon) {
|
|
@@ -1099,8 +1100,7 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
|
|
if (pcmk_is_set(pcmk_get_ra_caps(rsc_rule_data.standard),
|
|
pcmk_ra_cap_fence_params)
|
|
&& (pcmk__str_eq(action->task, RSC_START, pcmk__str_casei)
|
|
- || (pcmk__str_eq(action->task, RSC_STATUS, pcmk__str_casei)
|
|
- && (interval_ms == 0)))
|
|
+ || is_probe)
|
|
&& action->rsc->parameters) {
|
|
|
|
value = g_hash_table_lookup(action->rsc->parameters,
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 9de547849697cd6a3581db3f83b04f68d0405d9d Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Tue, 10 Nov 2020 15:15:01 -0600
|
|
Subject: [PATCH 3/9] Refactor: scheduler: don't include originally unpacked
|
|
resource parameters in digest
|
|
|
|
Previously, when calculating an operation digest, calculate_main_digest() would
|
|
grab the following, in order of highest to lowest precedence:
|
|
|
|
* instance attributes evaluated for the appropriate node
|
|
* instance attributes specified with the operation
|
|
* instance attributes as originally unpacked (without evaluating for any node)
|
|
* resource meta-attributes
|
|
|
|
Adding the originally unpacked instance attributes was redundant, since
|
|
node-evaluated instance attributes would always be a superset of those and
|
|
would take precedence.
|
|
---
|
|
lib/pengine/pe_digest.c | 1 -
|
|
1 file changed, 1 deletion(-)
|
|
|
|
diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c
|
|
index 1e119f9..dd6b753 100644
|
|
--- a/lib/pengine/pe_digest.c
|
|
+++ b/lib/pengine/pe_digest.c
|
|
@@ -162,7 +162,6 @@ calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc,
|
|
}
|
|
g_hash_table_foreach(local_rsc_params, hash2field, data->params_all);
|
|
g_hash_table_foreach(action->extra, hash2field, data->params_all);
|
|
- g_hash_table_foreach(rsc->parameters, hash2field, data->params_all);
|
|
g_hash_table_foreach(action->meta, hash2metafield, data->params_all);
|
|
|
|
#if ENABLE_VERSIONED_ATTRS
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From e9921b2ab3e9eeab6227d97cc12b85fa04dfd187 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Fri, 13 Nov 2020 09:27:12 -0600
|
|
Subject: [PATCH 4/9] Refactor: scheduler: reuse existing function to check for
|
|
remote in XML
|
|
|
|
... to reduce code duplication and improve readability
|
|
---
|
|
lib/pengine/bundle.c | 21 +++------------------
|
|
1 file changed, 3 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/lib/pengine/bundle.c b/lib/pengine/bundle.c
|
|
index 76730c7..4f6eac3 100644
|
|
--- a/lib/pengine/bundle.c
|
|
+++ b/lib/pengine/bundle.c
|
|
@@ -959,28 +959,13 @@ pe__bundle_needs_remote_name(pe_resource_t *rsc)
|
|
const char *value;
|
|
|
|
if (rsc == NULL) {
|
|
- return FALSE;
|
|
+ return false;
|
|
}
|
|
|
|
value = g_hash_table_lookup(rsc->parameters, XML_RSC_ATTR_REMOTE_RA_ADDR);
|
|
- if (!pcmk__str_eq(value, "#uname", pcmk__str_casei)) {
|
|
- return FALSE;
|
|
|
|
- } else {
|
|
- const char *match[3][2] = {
|
|
- { XML_ATTR_TYPE, "remote" },
|
|
- { XML_AGENT_ATTR_CLASS, PCMK_RESOURCE_CLASS_OCF },
|
|
- { XML_AGENT_ATTR_PROVIDER, "pacemaker" },
|
|
- };
|
|
-
|
|
- for (int m = 0; m < 3; m++) {
|
|
- value = crm_element_value(rsc->xml, match[m][0]);
|
|
- if (!pcmk__str_eq(value, match[m][1], pcmk__str_casei)) {
|
|
- return FALSE;
|
|
- }
|
|
- }
|
|
- }
|
|
- return TRUE;
|
|
+ return pcmk__str_eq(value, "#uname", pcmk__str_casei)
|
|
+ && xml_contains_remote_node(rsc->xml);
|
|
}
|
|
|
|
const char *
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 0f220e1cd25ec095492ac4b346452520f4b71cf1 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Wed, 11 Nov 2020 15:29:46 -0600
|
|
Subject: [PATCH 5/9] Refactor: scheduler: remove dead code
|
|
|
|
Several internal expression-testing functions were unused. While they might
|
|
have had some potential future value, the abundance of similarly named
|
|
functions made debugging difficult. Comment blocks were added to the functions
|
|
they wrapped, which should add similar value.
|
|
|
|
Also, we had an internal wrapper for pe__eval_date_expr() that was used
|
|
only in crm_rule, so it was moved there.
|
|
---
|
|
include/crm/pengine/rules_internal.h | 10 +--
|
|
lib/pengine/rules.c | 130 +++++++++++------------------------
|
|
tools/crm_rule.c | 27 +++++++-
|
|
3 files changed, 66 insertions(+), 101 deletions(-)
|
|
|
|
diff --git a/include/crm/pengine/rules_internal.h b/include/crm/pengine/rules_internal.h
|
|
index f60263a..7380826 100644
|
|
--- a/include/crm/pengine/rules_internal.h
|
|
+++ b/include/crm/pengine/rules_internal.h
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2015-2019 the Pacemaker project contributors
|
|
+ * Copyright 2015-2020 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -28,14 +28,6 @@ gboolean pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
|
|
gboolean pe__eval_role_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
|
|
gboolean pe__eval_rsc_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
|
|
|
|
-int pe_eval_date_expression(xmlNode *time_expr,
|
|
- crm_time_t *now,
|
|
- crm_time_t *next_change);
|
|
-gboolean pe_test_date_expression(xmlNode *time_expr, crm_time_t *now,
|
|
- crm_time_t *next_change);
|
|
int pe_cron_range_satisfied(crm_time_t * now, xmlNode * cron_spec);
|
|
-gboolean pe_test_attr_expression(xmlNode *expr, GHashTable *hash, crm_time_t *now,
|
|
- pe_match_data_t *match_data);
|
|
-gboolean pe_test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now);
|
|
|
|
#endif
|
|
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
|
|
index 28562aa..be30e67 100644
|
|
--- a/lib/pengine/rules.c
|
|
+++ b/lib/pengine/rules.c
|
|
@@ -140,37 +140,6 @@ find_expression_type(xmlNode * expr)
|
|
return attr_expr;
|
|
}
|
|
|
|
-gboolean
|
|
-pe_test_role_expression(xmlNode *expr, enum rsc_role_e role, crm_time_t *now)
|
|
-{
|
|
- pe_rule_eval_data_t rule_data = {
|
|
- .node_hash = NULL,
|
|
- .role = role,
|
|
- .now = now,
|
|
- .match_data = NULL,
|
|
- .rsc_data = NULL,
|
|
- .op_data = NULL
|
|
- };
|
|
-
|
|
- return pe__eval_role_expr(expr, &rule_data);
|
|
-}
|
|
-
|
|
-gboolean
|
|
-pe_test_attr_expression(xmlNode *expr, GHashTable *hash, crm_time_t *now,
|
|
- pe_match_data_t *match_data)
|
|
-{
|
|
- pe_rule_eval_data_t rule_data = {
|
|
- .node_hash = hash,
|
|
- .role = RSC_ROLE_UNKNOWN,
|
|
- .now = now,
|
|
- .match_data = match_data,
|
|
- .rsc_data = NULL,
|
|
- .op_data = NULL
|
|
- };
|
|
-
|
|
- return pe__eval_attr_expr(expr, &rule_data);
|
|
-}
|
|
-
|
|
/* As per the nethack rules:
|
|
*
|
|
* moon period = 29.53058 days ~= 30, year = 365.2422 days
|
|
@@ -331,38 +300,6 @@ pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec)
|
|
return end;
|
|
}
|
|
|
|
-/*!
|
|
- * \internal
|
|
- * \brief Test a date expression (pass/fail) for a specific time
|
|
- *
|
|
- * \param[in] time_expr date_expression XML
|
|
- * \param[in] now Time for which to evaluate expression
|
|
- * \param[out] next_change If not NULL, set to when evaluation will change
|
|
- *
|
|
- * \return TRUE if date expression is in effect at given time, FALSE otherwise
|
|
- */
|
|
-gboolean
|
|
-pe_test_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
|
|
-{
|
|
- pe_rule_eval_data_t rule_data = {
|
|
- .node_hash = NULL,
|
|
- .role = RSC_ROLE_UNKNOWN,
|
|
- .now = now,
|
|
- .match_data = NULL,
|
|
- .rsc_data = NULL,
|
|
- .op_data = NULL
|
|
- };
|
|
-
|
|
- switch (pe__eval_date_expr(expr, &rule_data, next_change)) {
|
|
- case pcmk_rc_within_range:
|
|
- case pcmk_rc_ok:
|
|
- return TRUE;
|
|
-
|
|
- default:
|
|
- return FALSE;
|
|
- }
|
|
-}
|
|
-
|
|
// Set next_change to t if t is earlier
|
|
static void
|
|
crm_time_set_if_earlier(crm_time_t *next_change, crm_time_t *t)
|
|
@@ -375,31 +312,6 @@ crm_time_set_if_earlier(crm_time_t *next_change, crm_time_t *t)
|
|
}
|
|
}
|
|
|
|
-/*!
|
|
- * \internal
|
|
- * \brief Evaluate a date expression for a specific time
|
|
- *
|
|
- * \param[in] time_expr date_expression XML
|
|
- * \param[in] now Time for which to evaluate expression
|
|
- * \param[out] next_change If not NULL, set to when evaluation will change
|
|
- *
|
|
- * \return Standard Pacemaker return code
|
|
- */
|
|
-int
|
|
-pe_eval_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
|
|
-{
|
|
- pe_rule_eval_data_t rule_data = {
|
|
- .node_hash = NULL,
|
|
- .role = RSC_ROLE_UNKNOWN,
|
|
- .now = now,
|
|
- .match_data = NULL,
|
|
- .rsc_data = NULL,
|
|
- .op_data = NULL
|
|
- };
|
|
-
|
|
- return pe__eval_date_expr(expr, &rule_data, next_change);
|
|
-}
|
|
-
|
|
// Information about a block of nvpair elements
|
|
typedef struct sorted_set_s {
|
|
int score; // This block's score for sorting
|
|
@@ -908,7 +820,16 @@ pe_eval_subexpr(xmlNode *expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_
|
|
break;
|
|
|
|
case time_expr:
|
|
- accept = pe_test_date_expression(expr, rule_data->now, next_change);
|
|
+ switch (pe__eval_date_expr(expr, rule_data, next_change)) {
|
|
+ case pcmk_rc_within_range:
|
|
+ case pcmk_rc_ok:
|
|
+ accept = TRUE;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ accept = FALSE;
|
|
+ break;
|
|
+ }
|
|
break;
|
|
|
|
case role_expr:
|
|
@@ -1104,6 +1025,16 @@ accept_attr_expr(const char *l_val, const char *r_val, const char *type,
|
|
return false; // Should never reach this point
|
|
}
|
|
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Evaluate a node attribute expression based on #uname, #id, #kind,
|
|
+ * or a generic node attribute
|
|
+ *
|
|
+ * \param[in] expr XML of rule expression
|
|
+ * \param[in] rule_data The match_data and node_hash members are used
|
|
+ *
|
|
+ * \return TRUE if rule_data satisfies the expression, FALSE otherwise
|
|
+ */
|
|
gboolean
|
|
pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
|
|
{
|
|
@@ -1169,8 +1100,16 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
|
|
return accept_attr_expr(h_val, value, type, op);
|
|
}
|
|
|
|
-
|
|
-
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Evaluate a date_expression
|
|
+ *
|
|
+ * \param[in] expr XML of rule expression
|
|
+ * \param[in] rule_data Only the now member is used
|
|
+ * \param[out] next_change If not NULL, set to when evaluation will change
|
|
+ *
|
|
+ * \return Standard Pacemaker return code
|
|
+ */
|
|
int
|
|
pe__eval_date_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
|
|
{
|
|
@@ -1285,6 +1224,15 @@ pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data) {
|
|
return TRUE;
|
|
}
|
|
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Evaluate a node attribute expression based on #role
|
|
+ *
|
|
+ * \param[in] expr XML of rule expression
|
|
+ * \param[in] rule_data Only the role member is used
|
|
+ *
|
|
+ * \return TRUE if rule_data->role satisfies the expression, FALSE otherwise
|
|
+ */
|
|
gboolean
|
|
pe__eval_role_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
|
|
{
|
|
diff --git a/tools/crm_rule.c b/tools/crm_rule.c
|
|
index 0e44828..2871f3d 100644
|
|
--- a/tools/crm_rule.c
|
|
+++ b/tools/crm_rule.c
|
|
@@ -75,6 +75,31 @@ mode_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **e
|
|
return TRUE;
|
|
}
|
|
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Evaluate a date expression for a specific time
|
|
+ *
|
|
+ * \param[in] time_expr date_expression XML
|
|
+ * \param[in] now Time for which to evaluate expression
|
|
+ * \param[out] next_change If not NULL, set to when evaluation will change
|
|
+ *
|
|
+ * \return Standard Pacemaker return code
|
|
+ */
|
|
+static int
|
|
+eval_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
|
|
+{
|
|
+ pe_rule_eval_data_t rule_data = {
|
|
+ .node_hash = NULL,
|
|
+ .role = RSC_ROLE_UNKNOWN,
|
|
+ .now = now,
|
|
+ .match_data = NULL,
|
|
+ .rsc_data = NULL,
|
|
+ .op_data = NULL
|
|
+ };
|
|
+
|
|
+ return pe__eval_date_expr(expr, &rule_data, next_change);
|
|
+}
|
|
+
|
|
static int
|
|
crm_rule_check(pe_working_set_t *data_set, const char *rule_id, crm_time_t *effective_date)
|
|
{
|
|
@@ -156,7 +181,7 @@ crm_rule_check(pe_working_set_t *data_set, const char *rule_id, crm_time_t *effe
|
|
CRM_ASSERT(match != NULL);
|
|
CRM_ASSERT(find_expression_type(match) == time_expr);
|
|
|
|
- rc = pe_eval_date_expression(match, effective_date, NULL);
|
|
+ rc = eval_date_expression(match, effective_date, NULL);
|
|
|
|
if (rc == pcmk_rc_within_range) {
|
|
printf("Rule %s is still in effect\n", rule_id);
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 91a6ec4bec86de7389fcd64cb27e315da760f0dd Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Wed, 11 Nov 2020 16:44:57 -0600
|
|
Subject: [PATCH 6/9] Refactor: scheduler: make constraint unpacking function
|
|
static
|
|
|
|
... for linker efficiency and readability. Also change the return type to void
|
|
since it was ignored (and the same for some related functions).
|
|
---
|
|
include/pcmki/pcmki_sched_allocate.h | 4 +--
|
|
lib/pacemaker/pcmk_sched_constraints.c | 46 ++++++++++++++++------------------
|
|
2 files changed, 23 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/include/pcmki/pcmki_sched_allocate.h b/include/pcmki/pcmki_sched_allocate.h
|
|
index efc0da6..a7f8c11 100644
|
|
--- a/include/pcmki/pcmki_sched_allocate.h
|
|
+++ b/include/pcmki/pcmki_sched_allocate.h
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2004-2019 the Pacemaker project contributors
|
|
+ * Copyright 2004-2020 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -143,8 +143,6 @@ extern gboolean unpack_rsc_order(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
|
|
extern gboolean unpack_rsc_colocation(xmlNode * xml_obj, pe_working_set_t * data_set);
|
|
|
|
-extern gboolean unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set);
|
|
-
|
|
extern gboolean unpack_rsc_ticket(xmlNode * xml_obj, pe_working_set_t * data_set);
|
|
|
|
void LogNodeActions(pe_working_set_t * data_set, gboolean terminal);
|
|
diff --git a/lib/pacemaker/pcmk_sched_constraints.c b/lib/pacemaker/pcmk_sched_constraints.c
|
|
index 6ed2d8c..121754d 100644
|
|
--- a/lib/pacemaker/pcmk_sched_constraints.c
|
|
+++ b/lib/pacemaker/pcmk_sched_constraints.c
|
|
@@ -48,6 +48,7 @@ static pe__location_t *generate_location_rule(pe_resource_t *rsc,
|
|
crm_time_t *next_change,
|
|
pe_working_set_t *data_set,
|
|
pe_match_data_t *match_data);
|
|
+static void unpack_location(xmlNode *xml_obj, pe_working_set_t *data_set);
|
|
|
|
static bool
|
|
evaluate_lifetime(xmlNode *lifetime, pe_working_set_t *data_set)
|
|
@@ -709,11 +710,13 @@ tag_to_set(xmlNode * xml_obj, xmlNode ** rsc_set, const char * attr,
|
|
return TRUE;
|
|
}
|
|
|
|
-static gboolean unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role,
|
|
- const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data);
|
|
+static void unpack_rsc_location(xmlNode *xml_obj, pe_resource_t *rsc_lh,
|
|
+ const char *role, const char *score,
|
|
+ pe_working_set_t *data_set,
|
|
+ pe_match_data_t *match_data);
|
|
|
|
-static gboolean
|
|
-unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
+static void
|
|
+unpack_simple_location(xmlNode *xml_obj, pe_working_set_t *data_set)
|
|
{
|
|
const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
|
|
const char *value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
|
|
@@ -721,7 +724,7 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
if(value) {
|
|
pe_resource_t *rsc_lh = pe_find_constraint_resource(data_set->resources, value);
|
|
|
|
- return unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
|
|
+ unpack_rsc_location(xml_obj, rsc_lh, NULL, NULL, data_set, NULL);
|
|
}
|
|
|
|
value = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE_PATTERN);
|
|
@@ -741,7 +744,7 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
" has invalid value '%s'", id, value);
|
|
regfree(r_patt);
|
|
free(r_patt);
|
|
- return FALSE;
|
|
+ return;
|
|
}
|
|
|
|
for (rIter = data_set->resources; rIter; rIter = rIter->next) {
|
|
@@ -787,13 +790,12 @@ unpack_simple_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
regfree(r_patt);
|
|
free(r_patt);
|
|
}
|
|
-
|
|
- return FALSE;
|
|
}
|
|
|
|
-static gboolean
|
|
-unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role,
|
|
- const char * score, pe_working_set_t * data_set, pe_match_data_t * match_data)
|
|
+static void
|
|
+unpack_rsc_location(xmlNode *xml_obj, pe_resource_t *rsc_lh, const char *role,
|
|
+ const char *score, pe_working_set_t *data_set,
|
|
+ pe_match_data_t *match_data)
|
|
{
|
|
pe__location_t *location = NULL;
|
|
const char *id_lh = crm_element_value(xml_obj, XML_LOC_ATTR_SOURCE);
|
|
@@ -804,7 +806,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
|
|
if (rsc_lh == NULL) {
|
|
pcmk__config_warn("Ignoring constraint '%s' because resource '%s' "
|
|
"does not exist", id, id_lh);
|
|
- return FALSE;
|
|
+ return;
|
|
}
|
|
|
|
if (score == NULL) {
|
|
@@ -816,7 +818,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
|
|
pe_node_t *match = pe_find_node(data_set->nodes, node);
|
|
|
|
if (!match) {
|
|
- return FALSE;
|
|
+ return;
|
|
}
|
|
location = rsc2node_new(id, rsc_lh, score_i, discovery, match, data_set);
|
|
|
|
@@ -850,7 +852,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
|
|
pe__update_recheck_time(t, data_set);
|
|
}
|
|
crm_time_free(next_change);
|
|
- return TRUE;
|
|
+ return;
|
|
}
|
|
|
|
if (role == NULL) {
|
|
@@ -860,7 +862,7 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
|
|
if (location && role) {
|
|
if (text2role(role) == RSC_ROLE_UNKNOWN) {
|
|
pe_err("Invalid constraint %s: Bad role %s", id, role);
|
|
- return FALSE;
|
|
+ return;
|
|
|
|
} else {
|
|
enum rsc_role_e r = text2role(role);
|
|
@@ -877,8 +879,6 @@ unpack_rsc_location(xmlNode * xml_obj, pe_resource_t * rsc_lh, const char * role
|
|
}
|
|
}
|
|
}
|
|
-
|
|
- return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -992,8 +992,8 @@ unpack_location_set(xmlNode * location, xmlNode * set, pe_working_set_t * data_s
|
|
return TRUE;
|
|
}
|
|
|
|
-gboolean
|
|
-unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
+static void
|
|
+unpack_location(xmlNode *xml_obj, pe_working_set_t *data_set)
|
|
{
|
|
xmlNode *set = NULL;
|
|
gboolean any_sets = FALSE;
|
|
@@ -1002,7 +1002,7 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
xmlNode *expanded_xml = NULL;
|
|
|
|
if (unpack_location_tags(xml_obj, &expanded_xml, data_set) == FALSE) {
|
|
- return FALSE;
|
|
+ return;
|
|
}
|
|
|
|
if (expanded_xml) {
|
|
@@ -1020,7 +1020,7 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
if (expanded_xml) {
|
|
free_xml(expanded_xml);
|
|
}
|
|
- return FALSE;
|
|
+ return;
|
|
}
|
|
}
|
|
}
|
|
@@ -1031,10 +1031,8 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set)
|
|
}
|
|
|
|
if (any_sets == FALSE) {
|
|
- return unpack_simple_location(xml_obj, data_set);
|
|
+ unpack_simple_location(xml_obj, data_set);
|
|
}
|
|
-
|
|
- return TRUE;
|
|
}
|
|
|
|
static int
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From df842adafca8ba56ddb5b448490ffef54ea785d4 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Fri, 13 Nov 2020 09:19:51 -0600
|
|
Subject: [PATCH 7/9] Refactor: scheduler: trivial refactoring of nvpair
|
|
evaluation
|
|
|
|
... for readability
|
|
---
|
|
lib/pengine/rules.c | 15 +++++++--------
|
|
1 file changed, 7 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
|
|
index be30e67..86e7899 100644
|
|
--- a/lib/pengine/rules.c
|
|
+++ b/lib/pengine/rules.c
|
|
@@ -529,20 +529,19 @@ static GList *
|
|
make_pairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
|
|
const char *always_first)
|
|
{
|
|
- GListPtr unsorted = NULL;
|
|
- const char *score = NULL;
|
|
- sorted_set_t *pair = NULL;
|
|
- xmlNode *attr_set = NULL;
|
|
+ GList *unsorted = NULL;
|
|
|
|
if (xml_obj == NULL) {
|
|
return NULL;
|
|
}
|
|
- for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
|
|
+ for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
|
|
attr_set = pcmk__xe_next(attr_set)) {
|
|
|
|
- /* Uncertain if set_name == NULL check is strictly necessary here */
|
|
- if (pcmk__str_eq(set_name, (const char *)attr_set->name, pcmk__str_null_matches)) {
|
|
- pair = NULL;
|
|
+ if (pcmk__str_eq(set_name, (const char *) attr_set->name,
|
|
+ pcmk__str_null_matches)) {
|
|
+ const char *score = NULL;
|
|
+ sorted_set_t *pair = NULL;
|
|
+
|
|
attr_set = expand_idref(attr_set, top);
|
|
if (attr_set == NULL) {
|
|
continue;
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 373c224ac1c41bd47a928a7523744c6c678a6543 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Fri, 13 Nov 2020 09:21:35 -0600
|
|
Subject: [PATCH 8/9] Low: scheduler: correctly skip dangling id-ref
|
|
|
|
When evaluating XML nvpair blocks, make_pairs() previously reused the
|
|
"for" loop variable when expanding id-ref's. However if the id-ref was dangling
|
|
(only possible if schema enforcement is turned off), this would make it NULL
|
|
and thus exiting the loop instead of continuing.
|
|
---
|
|
lib/pengine/rules.c | 11 ++++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
|
|
index 86e7899..1bd807f 100644
|
|
--- a/lib/pengine/rules.c
|
|
+++ b/lib/pengine/rules.c
|
|
@@ -541,18 +541,19 @@ make_pairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
|
|
pcmk__str_null_matches)) {
|
|
const char *score = NULL;
|
|
sorted_set_t *pair = NULL;
|
|
+ xmlNode *expanded_attr_set = expand_idref(attr_set, top);
|
|
|
|
- attr_set = expand_idref(attr_set, top);
|
|
- if (attr_set == NULL) {
|
|
+ if (expanded_attr_set == NULL) {
|
|
+ // Schema (if not "none") prevents this
|
|
continue;
|
|
}
|
|
|
|
pair = calloc(1, sizeof(sorted_set_t));
|
|
- pair->name = ID(attr_set);
|
|
+ pair->name = ID(expanded_attr_set);
|
|
pair->special_name = always_first;
|
|
- pair->attr_set = attr_set;
|
|
+ pair->attr_set = expanded_attr_set;
|
|
|
|
- score = crm_element_value(attr_set, XML_RULE_ATTR_SCORE);
|
|
+ score = crm_element_value(expanded_attr_set, XML_RULE_ATTR_SCORE);
|
|
pair->score = char2score(score);
|
|
|
|
unsorted = g_list_prepend(unsorted, pair);
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From b59717751c168ec745bedbcc5696bee11036d931 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Thu, 12 Nov 2020 14:37:27 -0600
|
|
Subject: [PATCH 9/9] Low: scheduler: treat missing parameter as NULL in rules
|
|
with value-source
|
|
|
|
Previously, if value-source were set to "param" or "meta", and an affected
|
|
resource did not have the specified parameter, the parameter name would wrongly
|
|
be used as the value to compare against. Now, use NULL as the value to compare
|
|
against.
|
|
---
|
|
lib/pengine/rules.c | 11 ++++++++---
|
|
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
|
|
index 1bd807f..e5d452f 100644
|
|
--- a/lib/pengine/rules.c
|
|
+++ b/lib/pengine/rules.c
|
|
@@ -1041,6 +1041,7 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
|
|
gboolean attr_allocated = FALSE;
|
|
const char *h_val = NULL;
|
|
GHashTable *table = NULL;
|
|
+ bool literal = true;
|
|
|
|
const char *op = NULL;
|
|
const char *type = NULL;
|
|
@@ -1071,18 +1072,22 @@ pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
|
|
}
|
|
|
|
if (pcmk__str_eq(value_source, "param", pcmk__str_casei)) {
|
|
+ literal = false;
|
|
table = rule_data->match_data->params;
|
|
} else if (pcmk__str_eq(value_source, "meta", pcmk__str_casei)) {
|
|
+ literal = false;
|
|
table = rule_data->match_data->meta;
|
|
}
|
|
}
|
|
|
|
- if (table) {
|
|
+ if (!literal) {
|
|
const char *param_name = value;
|
|
const char *param_value = NULL;
|
|
|
|
- if (param_name && param_name[0]) {
|
|
- if ((param_value = (const char *)g_hash_table_lookup(table, param_name))) {
|
|
+ value = NULL;
|
|
+ if ((table != NULL) && !pcmk__str_empty(param_name)) {
|
|
+ param_value = (const char *)g_hash_table_lookup(table, param_name);
|
|
+ if (param_value != NULL) {
|
|
value = param_value;
|
|
}
|
|
}
|
|
--
|
|
1.8.3.1
|
|
|