Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624579
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index 6a46c1c032..7b6559b708 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -1,225 +1,227 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <glib.h>
#include <crm/crm.h>
#include <crm/common/xml.h>
#include <crm/pengine/rules.h>
#include <crm/common/iso8601_internal.h>
#include <crm/common/nvpair_internal.h>
#include <crm/common/rules_internal.h>
#include <crm/common/xml_internal.h>
#include <crm/pengine/internal.h>
#include <crm/pengine/rules_internal.h>
#include <sys/types.h>
#include <regex.h>
CRM_TRACE_INIT_DATA(pe_rules);
/*!
* \internal
* \brief Map pe_rule_eval_data_t to pcmk_rule_input_t
*
* \param[out] new New data struct
* \param[in] old Old data struct
*/
static void
map_rule_input(pcmk_rule_input_t *new, const pe_rule_eval_data_t *old)
{
if (old == NULL) {
return;
}
new->now = old->now;
new->node_attrs = old->node_hash;
if (old->rsc_data != NULL) {
new->rsc_standard = old->rsc_data->standard;
new->rsc_provider = old->rsc_data->provider;
new->rsc_agent = old->rsc_data->agent;
}
if (old->match_data != NULL) {
new->rsc_params = old->match_data->params;
new->rsc_meta = old->match_data->meta;
if (old->match_data->re != NULL) {
new->rsc_id = old->match_data->re->string;
new->rsc_id_submatches = old->match_data->re->pmatch;
new->rsc_id_nmatches = old->match_data->re->nregs;
}
}
if (old->op_data != NULL) {
new->op_name = old->op_data->op_name;
new->op_interval_ms = old->op_data->interval;
}
}
-static void
-populate_hash(xmlNode *nvpair_list, GHashTable *hash, bool overwrite)
+/*!
+ * \internal
+ * \brief Unpack a single nvpair XML element into a hash table
+ *
+ * \param[in] nvpair XML nvpair element to unpack
+ * \param[in,out] userdata Unpack data
+ *
+ * \return pcmk_rc_ok (to always proceed to next nvpair)
+ */
+static int
+unpack_nvpair(xmlNode *nvpair, void *userdata)
{
- if (pcmk__xe_is(nvpair_list->children, PCMK__XE_ATTRIBUTES)) {
- nvpair_list = nvpair_list->children;
+ pcmk__nvpair_unpack_t *unpack_data = userdata;
+
+ const char *name = NULL;
+ const char *value = NULL;
+ const char *old_value = NULL;
+ const xmlNode *ref_nvpair = pcmk__xe_resolve_idref(nvpair, NULL);
+
+ if (ref_nvpair == NULL) {
+ /* Not possible with schema validation enabled (error already
+ * logged)
+ */
+ return pcmk_rc_ok;
}
- for (xmlNode *nvpair = pcmk__xe_first_child(nvpair_list, PCMK_XE_NVPAIR,
- NULL, NULL);
- nvpair != NULL; nvpair = pcmk__xe_next(nvpair, PCMK_XE_NVPAIR)) {
-
- xmlNode *ref_nvpair = pcmk__xe_resolve_idref(nvpair, NULL);
- const char *name = NULL;
- const char *value = NULL;
- const char *old_value = NULL;
-
- if (ref_nvpair == NULL) {
- /* Not possible with schema validation enabled (error already
- * logged)
- */
- continue;
- }
+ name = crm_element_value(ref_nvpair, PCMK_XA_NAME);
+ value = crm_element_value(ref_nvpair, PCMK_XA_VALUE);
+ if ((name == NULL) || (value == NULL)) {
+ return pcmk_rc_ok; // Not possible with schema validation enabled
+ }
- name = crm_element_value(ref_nvpair, PCMK_XA_NAME);
- value = crm_element_value(ref_nvpair, PCMK_XA_VALUE);
- if ((name == NULL) || (value == NULL)) {
- continue;
+ old_value = g_hash_table_lookup(unpack_data->values, name);
+
+ if (pcmk__str_eq(value, "#default", pcmk__str_casei)) {
+ // @COMPAT Deprecated since 2.1.8
+ pcmk__config_warn("Support for setting meta-attributes (such as "
+ "%s) to the explicit value '#default' is "
+ "deprecated and will be removed in a future "
+ "release", name);
+ if (old_value != NULL) {
+ crm_trace("Letting %s default (removing explicit value \"%s\")",
+ name, value);
+ g_hash_table_remove(unpack_data->values, name);
}
- old_value = g_hash_table_lookup(hash, name);
-
- if (pcmk__str_eq(value, "#default", pcmk__str_casei)) {
- // @COMPAT Deprecated since 2.1.8
- pcmk__config_warn("Support for setting meta-attributes (such as "
- "%s) to the explicit value '#default' is "
- "deprecated and will be removed in a future "
- "release", name);
- if (old_value != NULL) {
- crm_trace("Letting %s default (removing explicit value \"%s\")",
- name, value);
- g_hash_table_remove(hash, name);
- }
-
- } else if (old_value == NULL) {
- crm_trace("Setting %s=\"%s\"", name, value);
- pcmk__insert_dup(hash, name, value);
-
- } else if (overwrite) {
- crm_trace("Setting %s=\"%s\" (overwriting old value \"%s\")",
- name, value, old_value);
- pcmk__insert_dup(hash, name, value);
- }
+ } else if ((old_value == NULL) || unpack_data->overwrite) {
+ crm_trace("Setting %s=\"%s\" (was %s)",
+ name, value, pcmk__s(old_value, "unset"));
+ pcmk__insert_dup(unpack_data->values, name, value);
}
+ return pcmk_rc_ok;
}
static void
unpack_attr_set(gpointer data, gpointer user_data)
{
xmlNode *pair = data;
pcmk__nvpair_unpack_t *unpack_data = user_data;
xmlNode *rule_xml = pcmk__xe_first_child(pair, PCMK_XE_RULE, NULL, NULL);
if ((rule_xml != NULL)
&& (pcmk_evaluate_rule(rule_xml, &(unpack_data->rule_input),
unpack_data->next_change) != pcmk_rc_ok)) {
return;
}
crm_trace("Adding name/value pairs from %s %s overwrite",
pcmk__xe_id(pair), (unpack_data->overwrite? "with" : "without"));
- populate_hash(pair, unpack_data->values, unpack_data->overwrite);
+ if (pcmk__xe_is(pair->children, PCMK__XE_ATTRIBUTES)) {
+ pair = pair->children;
+ }
+ pcmk__xe_foreach_child(pair, PCMK_XE_NVPAIR, unpack_nvpair, unpack_data);
}
/*!
* \brief Extract nvpair blocks contained by an XML element into a hash table
*
* \param[in,out] top Ignored
* \param[in] xml_obj XML element containing blocks of nvpair elements
* \param[in] set_name If not NULL, only use blocks of this element
* \param[in] rule_data Matching parameters to use when unpacking
* \param[out] hash Where to store extracted name/value pairs
* \param[in] always_first If not NULL, process block with this ID first
* \param[in] overwrite Whether to replace existing values with same
* name (all internal callers pass \c FALSE)
* \param[out] next_change If not NULL, set to when evaluation will change
*/
void
pe_eval_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name,
const pe_rule_eval_data_t *rule_data, GHashTable *hash,
const char *always_first, gboolean overwrite,
crm_time_t *next_change)
{
GList *pairs = pcmk__xe_dereference_children(xml_obj, set_name);
if (pairs) {
pcmk__nvpair_unpack_t data = {
.values = hash,
.first_id = always_first,
.overwrite = overwrite,
.next_change = next_change,
};
map_rule_input(&(data.rule_input), rule_data);
pairs = g_list_sort_with_data(pairs, pcmk__cmp_nvpair_blocks, &data);
g_list_foreach(pairs, unpack_attr_set, &data);
g_list_free(pairs);
}
}
/*!
* \brief Extract nvpair blocks contained by an XML element into a hash table
*
* \param[in,out] top Ignored
* \param[in] xml_obj XML element containing blocks of nvpair elements
* \param[in] set_name Element name to identify nvpair blocks
* \param[in] node_hash Node attributes to use when evaluating rules
* \param[out] hash Where to store extracted name/value pairs
* \param[in] always_first If not NULL, process block with this ID first
* \param[in] overwrite Whether to replace existing values with same
* name (all internal callers pass \c FALSE)
* \param[in] now Time to use when evaluating rules
* \param[out] next_change If not NULL, set to when evaluation will change
*/
void
pe_unpack_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name,
GHashTable *node_hash, GHashTable *hash,
const char *always_first, gboolean overwrite,
crm_time_t *now, crm_time_t *next_change)
{
pe_rule_eval_data_t rule_data = {
.node_hash = node_hash,
.now = now,
.match_data = NULL,
.rsc_data = NULL,
.op_data = NULL
};
pe_eval_nvpairs(NULL, xml_obj, set_name, &rule_data, hash,
always_first, overwrite, next_change);
}
// Deprecated functions kept only for backward API compatibility
// LCOV_EXCL_START
#include <crm/pengine/rules_compat.h>
gboolean
test_rule(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
{
pcmk_rule_input_t rule_input = {
.node_attrs = node_hash,
.now = now,
};
return pcmk_evaluate_rule(rule, &rule_input, NULL) == pcmk_rc_ok;
}
// LCOV_EXCL_STOP
// End deprecated API
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:35 PM (2 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2002701
Default Alt Text
(9 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment