Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F2825275
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/crm/pengine/rules_compat.h b/include/crm/pengine/rules_compat.h
index 8dcaabbfd8..644496b38f 100644
--- a/include/crm/pengine/rules_compat.h
+++ b/include/crm/pengine/rules_compat.h
@@ -1,106 +1,40 @@
/*
* 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.
*/
#ifndef PCMK__CRM_PENGINE_RULES_COMPAT__H
# define PCMK__CRM_PENGINE_RULES_COMPAT__H
#include <glib.h>
#include <libxml/tree.h> // xmlNode
#include <crm/common/iso8601.h> // crm_time_t
#include <crm/pengine/pe_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Deprecated Pacemaker rule API
* \ingroup pengine
* \deprecated Do not include this header directly. The rule APIs in this
* header, and the header itself, will be removed in a future
* release.
*/
-//! \deprecated Use pcmk_evaluate_rule() on each rule instead
-gboolean pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash,
- crm_time_t *now, crm_time_t *next_change);
-
-//! \deprecated Use pcmk_evaluate_rule() on each rule instead
-gboolean pe_eval_rules(xmlNode *ruleset, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change);
-
-//! \deprecated Use pcmk_evaluate_rule() on each rule instead
-gboolean test_ruleset(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now);
-
+// @COMPAT sbd's configure script checks for this (as of at least 1.5.2)
//! \deprecated Use pcmk_evaluate_rule() instead
gboolean test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role,
crm_time_t *now);
-//! \deprecated Use pcmk_evaluate_rule() instead
-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);
-
-//! \deprecated Use pcmk_evaluate_rule() instead
-gboolean pe_test_rule_re(xmlNode *rule, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now,
- pe_re_match_data_t *re_match_data);
-
-//! \deprecated Use pcmk_evaluate_rule() instead
-gboolean pe_test_rule_full(xmlNode *rule, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now,
- pe_match_data_t *match_data);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean pe_test_expression(xmlNode *expr, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now,
- crm_time_t *next_change,
- pe_match_data_t *match_data);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean test_expression(xmlNode *expr, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean pe_test_expression_re(xmlNode *expr, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now,
- pe_re_match_data_t *re_match_data);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean pe_test_expression_full(xmlNode *expr, GHashTable *node_hash,
- enum rsc_role_e role,
- crm_time_t *now, pe_match_data_t *match_data);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean pe_eval_expr(xmlNode *rule, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change);
-
-//! \deprecated Use pcmk_evaluate_rule() on parent rule instead
-gboolean pe_eval_subexpr(xmlNode *expr, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change);
-
-//! \deprecated Use pe_unpack_nvpairs() instead
-void unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj,
- const char *set_name, GHashTable *node_hash,
- GHashTable *hash, const char *always_first,
- gboolean overwrite, crm_time_t *now);
-
-//! \deprecated Do not use
-enum expression_type find_expression_type(xmlNode *expr);
-
-//! \deprecated Do not use
-char *pe_expand_re_matches(const char *string,
- const pe_re_match_data_t *match_data);
-
#ifdef __cplusplus
}
#endif
#endif // PCMK__CRM_PENGINE_RULES_COMPAT__H
diff --git a/include/crm/pengine/status_compat.h b/include/crm/pengine/status_compat.h
index 1ff55066e8..b349df5a7e 100644
--- a/include/crm/pengine/status_compat.h
+++ b/include/crm/pengine/status_compat.h
@@ -1,72 +1,38 @@
/*
* 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.
*/
#ifndef PCMK__CRM_PENGINE_STATUS_COMPAT__H
#define PCMK__CRM_PENGINE_STATUS_COMPAT__H
#include <stdbool.h> // bool
#include <crm/common/util.h> // pcmk_is_set()
#include <crm/common/scheduler.h> // pcmk_resource_t, pcmk_rsc_unique, etc.
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Deprecated Pacemaker scheduler utilities
* \ingroup pengine
* \deprecated Do not include this header directly. The utilities in this
* header, and the header itself, will be removed in a future
* release.
*/
// NOTE: sbd (as of at least 1.5.2) uses this
//! \deprecated Use pcmk_find_node() with scheduler object instead
pcmk_node_t *pe_find_node(const GList *node_list, const char *node_name);
-//! \deprecated Compare variant directly instead
-static inline bool
-pe_rsc_is_clone(const pcmk_resource_t *rsc)
-{
- return (rsc != NULL) && (rsc->variant == pcmk_rsc_variant_clone);
-}
-
-//! \deprecated Compare variant and flags directly
-static inline bool
-pe_rsc_is_unique_clone(const pcmk_resource_t *rsc)
-{
- return pe_rsc_is_clone(rsc) && pcmk_is_set(rsc->flags, pcmk_rsc_unique);
-}
-
-//! \deprecated Compare variant and flags directly
-static inline bool
-pe_rsc_is_anon_clone(const pcmk_resource_t *rsc)
-{
- return pe_rsc_is_clone(rsc) && !pcmk_is_set(rsc->flags, pcmk_rsc_unique);
-}
-
-//! \deprecated Compare ancestor variants directly
-static inline bool
-pe_rsc_is_bundled(const pcmk_resource_t *rsc)
-{
- if (rsc == NULL) {
- return false;
- }
- while (rsc->parent != NULL) {
- rsc = rsc->parent;
- }
- return rsc->variant == pcmk_rsc_variant_bundle;
-}
-
#ifdef __cplusplus
}
#endif
#endif // PCMK__CRM_PENGINE_STATUS_COMPAT__H
diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
index 540bc0d391..e0ecad1051 100644
--- a/lib/pengine/rules.c
+++ b/lib/pengine/rules.c
@@ -1,471 +1,321 @@
/*
* 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 gint
sort_pairs(gconstpointer a, gconstpointer b, gpointer user_data)
{
const xmlNode *pair_a = a;
const xmlNode *pair_b = b;
pcmk__nvpair_unpack_t *unpack_data = user_data;
const char *score = NULL;
int score_a = 0;
int score_b = 0;
if (a == NULL && b == NULL) {
return 0;
} else if (a == NULL) {
return 1;
} else if (b == NULL) {
return -1;
}
if (pcmk__str_eq(pcmk__xe_id(pair_a), unpack_data->first_id,
pcmk__str_none)) {
return -1;
} else if (pcmk__str_eq(pcmk__xe_id(pair_b), unpack_data->first_id,
pcmk__str_none)) {
return 1;
}
score = crm_element_value(pair_a, PCMK_XA_SCORE);
score_a = char2score(score);
score = crm_element_value(pair_b, PCMK_XA_SCORE);
score_b = char2score(score);
/* If we're overwriting values, we want lowest score first, so the highest
* score is processed last; if we're not overwriting values, we want highest
* score first, so nothing else overwrites it.
*/
if (score_a < score_b) {
return unpack_data->overwrite? -1 : 1;
} else if (score_a > score_b) {
return unpack_data->overwrite? 1 : -1;
}
return 0;
}
static void
populate_hash(xmlNode *nvpair_list, GHashTable *hash, bool overwrite)
{
const char *name = NULL;
const char *value = NULL;
const char *old_value = NULL;
xmlNode *list = nvpair_list;
xmlNode *an_attr = NULL;
if (pcmk__xe_is(list->children, PCMK__XE_ATTRIBUTES)) {
list = list->children;
}
for (an_attr = pcmk__xe_first_child(list, NULL, NULL, NULL);
an_attr != NULL; an_attr = pcmk__xe_next(an_attr)) {
if (pcmk__xe_is(an_attr, PCMK_XE_NVPAIR)) {
xmlNode *ref_nvpair = expand_idref(an_attr, NULL);
name = crm_element_value(an_attr, PCMK_XA_NAME);
if ((name == NULL) && (ref_nvpair != NULL)) {
name = crm_element_value(ref_nvpair, PCMK_XA_NAME);
}
value = crm_element_value(an_attr, PCMK_XA_VALUE);
if ((value == NULL) && (ref_nvpair != NULL)) {
value = crm_element_value(ref_nvpair, PCMK_XA_VALUE);
}
if (name == NULL || value == NULL) {
continue;
}
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) {
crm_trace("Letting %s default (removing explicit value \"%s\")",
name, value);
g_hash_table_remove(hash, name);
}
continue;
} 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);
}
}
}
}
static void
unpack_attr_set(gpointer data, gpointer user_data)
{
xmlNode *pair = data;
pcmk__nvpair_unpack_t *unpack_data = user_data;
if (pcmk__evaluate_rules(pair, &(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);
}
/*!
* \internal
* \brief Create a sorted list of nvpair blocks
*
* \param[in] xml_obj XML element containing blocks of nvpair elements
* \param[in] set_name If not NULL, only get blocks of this element
*
* \return List of XML blocks of name/value pairs
*/
static GList *
make_pairs(const xmlNode *xml_obj, const char *set_name)
{
GList *unsorted = NULL;
if (xml_obj == NULL) {
return NULL;
}
for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL);
attr_set != NULL; attr_set = pcmk__xe_next(attr_set)) {
if ((set_name == NULL) || pcmk__xe_is(attr_set, set_name)) {
xmlNode *expanded_attr_set = expand_idref(attr_set, NULL);
if (expanded_attr_set == NULL) {
continue; // Not possible with schema validation enabled
}
unsorted = g_list_prepend(unsorted, expanded_attr_set);
}
}
return unsorted;
}
/*!
* \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
* \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 = make_pairs(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, sort_pairs, &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
* \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
-pe_eval_rules(xmlNode *ruleset, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change)
-{
- pcmk_rule_input_t rule_input = { NULL, };
-
- map_rule_input(&rule_input, rule_data);
- return pcmk__evaluate_rules(ruleset, &rule_input,
- next_change) == pcmk_rc_ok;
-}
-
-gboolean
-pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now,
- crm_time_t *next_change)
-{
- pcmk_rule_input_t rule_input = {
- .node_attrs = node_hash,
- .now = now,
- };
-
- return pcmk__evaluate_rules(ruleset, &rule_input, next_change);
-}
-
-gboolean
+static 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)
{
pcmk_rule_input_t rule_input = {
.node_attrs = node_hash,
.now = now,
};
if (match_data != NULL) {
rule_input.rsc_params = match_data->params;
rule_input.rsc_meta = match_data->meta;
if (match_data->re != NULL) {
rule_input.rsc_id = match_data->re->string;
rule_input.rsc_id_submatches = match_data->re->pmatch;
rule_input.rsc_id_nmatches = match_data->re->nregs;
}
}
return pcmk_evaluate_rule(rule, &rule_input, next_change) == pcmk_rc_ok;
}
-gboolean
-test_ruleset(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now)
-{
- return pe_evaluate_rules(ruleset, node_hash, now, NULL);
-}
-
gboolean
test_rule(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
{
return pe_test_rule(rule, node_hash, role, now, NULL, NULL);
}
-gboolean
-pe_test_rule_re(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_re_match_data_t * re_match_data)
-{
- pe_match_data_t match_data = {
- .re = re_match_data,
- .params = NULL,
- .meta = NULL,
- };
- return pe_test_rule(rule, node_hash, role, now, NULL, &match_data);
-}
-
-gboolean
-pe_test_rule_full(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role,
- crm_time_t *now, pe_match_data_t *match_data)
-{
- return pe_test_rule(rule, node_hash, role, now, NULL, match_data);
-}
-
-gboolean
-pe_test_expression(xmlNode *expr, GHashTable *node_hash, enum rsc_role_e role,
- crm_time_t *now, crm_time_t *next_change,
- pe_match_data_t *match_data)
-{
- pcmk_rule_input_t rule_input = {
- .now = now,
- .node_attrs = node_hash,
- };
-
- if (match_data != NULL) {
- rule_input.rsc_params = match_data->params;
- rule_input.rsc_meta = match_data->meta;
- if (match_data->re != NULL) {
- rule_input.rsc_id = match_data->re->string;
- rule_input.rsc_id_submatches = match_data->re->pmatch;
- rule_input.rsc_id_nmatches = match_data->re->nregs;
- }
- }
- return pcmk__evaluate_condition(expr, &rule_input,
- next_change) == pcmk_rc_ok;
-}
-
-gboolean
-test_expression(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
-{
- return pe_test_expression(expr, node_hash, role, now, NULL, NULL);
-}
-
-gboolean
-pe_test_expression_re(xmlNode * expr, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now, pe_re_match_data_t * re_match_data)
-{
- pe_match_data_t match_data = {
- .re = re_match_data,
- .params = NULL,
- .meta = NULL,
- };
- return pe_test_expression(expr, node_hash, role, now, NULL, &match_data);
-}
-
-gboolean
-pe_test_expression_full(xmlNode *expr, GHashTable *node_hash,
- enum rsc_role_e role, crm_time_t *now,
- pe_match_data_t *match_data)
-{
- return pe_test_expression(expr, node_hash, role, now, NULL, match_data);
-}
-
-gboolean
-pe_eval_expr(xmlNode *rule, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change)
-{
- pcmk_rule_input_t rule_input = { NULL, };
-
- map_rule_input(&rule_input, rule_data);
- return pcmk_evaluate_rule(rule, &rule_input, next_change) == pcmk_rc_ok;
-}
-
-gboolean
-pe_eval_subexpr(xmlNode *expr, const pe_rule_eval_data_t *rule_data,
- crm_time_t *next_change)
-{
- pcmk_rule_input_t rule_input = { NULL, };
-
- map_rule_input(&rule_input, rule_data);
- return pcmk__evaluate_condition(expr, &rule_input,
- next_change) == pcmk_rc_ok;
-}
-
-void
-unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name,
- GHashTable *node_hash, GHashTable *hash,
- const char *always_first, gboolean overwrite,
- crm_time_t *now)
-{
- 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, NULL);
-}
-
-enum expression_type
-find_expression_type(xmlNode *expr)
-{
- return pcmk__condition_type(expr);
-}
-
-char *
-pe_expand_re_matches(const char *string, const pe_re_match_data_t *match_data)
-{
- if (match_data == NULL) {
- return NULL;
- }
- return pcmk__replace_submatches(string, match_data->string,
- match_data->pmatch, match_data->nregs);
-}
-
// LCOV_EXCL_STOP
// End deprecated API
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:59 AM (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322480
Default Alt Text
(22 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment