summaryrefslogtreecommitdiffstats
path: root/lib/pengine/pe_digest.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/pengine/pe_digest.c162
1 files changed, 86 insertions, 76 deletions
diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c
index b8047da..546a2a7 100644
--- a/lib/pengine/pe_digest.c
+++ b/lib/pengine/pe_digest.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2022 the Pacemaker project contributors
+ * Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
@@ -93,27 +93,27 @@ attr_in_string(xmlAttrPtr a, void *user_data)
* \param[in] xml_op Unused
* \param[in] op_version CRM feature set to use for digest calculation
* \param[in] overrides Key/value table to override resource parameters
- * \param[in,out] data_set Cluster working set
+ * \param[in,out] scheduler Scheduler data
*/
static void
-calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc,
- const pe_node_t *node, GHashTable *params,
+calculate_main_digest(op_digest_cache_t *data, pcmk_resource_t *rsc,
+ const pcmk_node_t *node, GHashTable *params,
const char *task, guint *interval_ms,
const xmlNode *xml_op, const char *op_version,
- GHashTable *overrides, pe_working_set_t *data_set)
+ GHashTable *overrides, pcmk_scheduler_t *scheduler)
{
- pe_action_t *action = NULL;
+ xmlNode *action_config = NULL;
data->params_all = create_xml_node(NULL, XML_TAG_PARAMS);
/* REMOTE_CONTAINER_HACK: Allow Pacemaker Remote nodes to run containers
* that themselves are Pacemaker Remote nodes
*/
- (void) pe__add_bundle_remote_name(rsc, data_set, data->params_all,
+ (void) pe__add_bundle_remote_name(rsc, scheduler, data->params_all,
XML_RSC_ATTR_REMOTE_RA_ADDR);
- // If interval was overridden, reset it
if (overrides != NULL) {
+ // If interval was overridden, reset it
const char *interval_s = g_hash_table_lookup(overrides, CRM_META "_"
XML_LRM_ATTR_INTERVAL);
@@ -125,34 +125,42 @@ calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc,
*interval_ms = (guint) value_ll;
}
}
- }
- action = custom_action(rsc, pcmk__op_key(rsc->id, task, *interval_ms),
- task, node, TRUE, FALSE, data_set);
- if (overrides != NULL) {
+ // Add overrides to list of all parameters
g_hash_table_foreach(overrides, hash2field, data->params_all);
}
- g_hash_table_foreach(params, hash2field, data->params_all);
- g_hash_table_foreach(action->extra, hash2field, data->params_all);
- g_hash_table_foreach(action->meta, hash2metafield, data->params_all);
- pcmk__filter_op_for_digest(data->params_all);
+ // Add provided instance parameters
+ g_hash_table_foreach(params, hash2field, data->params_all);
- /* Given a non-recurring operation with extra parameters configured,
- * in case that the main digest doesn't match, even if the restart
- * digest matches, enforce a restart rather than a reload-agent anyway.
- * So that it ensures any changes of the extra parameters get applied
- * for this specific operation, and the digests calculated for the
- * resulting lrm_rsc_op will be correct.
- * Mark the implied rc RSC_DIGEST_RESTART for the case that the main
- * digest doesn't match.
+ // Find action configuration XML in CIB
+ action_config = pcmk__find_action_config(rsc, task, *interval_ms, true);
+
+ /* Add action-specific resource instance attributes to the digest list.
+ *
+ * If this is a one-time action with action-specific instance attributes,
+ * enforce a restart instead of reload-agent in case the main digest doesn't
+ * match, even if the restart digest does. This ensures any changes of the
+ * action-specific parameters get applied for this specific action, and
+ * digests calculated for the resulting history will be correct. Default the
+ * result to RSC_DIGEST_RESTART for the case where the main digest doesn't
+ * match.
*/
- if (*interval_ms == 0
- && g_hash_table_size(action->extra) > 0) {
- data->rc = RSC_DIGEST_RESTART;
+ params = pcmk__unpack_action_rsc_params(action_config, node->details->attrs,
+ scheduler);
+ if ((*interval_ms == 0) && (g_hash_table_size(params) > 0)) {
+ data->rc = pcmk__digest_restart;
}
+ g_hash_table_foreach(params, hash2field, data->params_all);
+ g_hash_table_destroy(params);
+
+ // Add action meta-attributes
+ params = pcmk__unpack_action_meta(rsc, node, task, *interval_ms,
+ action_config);
+ g_hash_table_foreach(params, hash2metafield, data->params_all);
+ g_hash_table_destroy(params);
- pe_free_action(action);
+ pcmk__filter_op_for_digest(data->params_all);
data->digest_all_calc = calculate_operation_digest(data->params_all,
op_version);
@@ -177,7 +185,7 @@ is_fence_param(xmlAttrPtr attr, void *user_data)
* \param[in] overrides Key/value hash table to override resource parameters
*/
static void
-calculate_secure_digest(op_digest_cache_t *data, const pe_resource_t *rsc,
+calculate_secure_digest(op_digest_cache_t *data, const pcmk_resource_t *rsc,
GHashTable *params, const xmlNode *xml_op,
const char *op_version, GHashTable *overrides)
{
@@ -288,17 +296,17 @@ calculate_restart_digest(op_digest_cache_t *data, const xmlNode *xml_op,
* \param[in] xml_op XML of operation in CIB status (if available)
* \param[in] overrides Key/value table to override resource parameters
* \param[in] calc_secure Whether to calculate secure digest
- * \param[in,out] data_set Cluster working set
+ * \param[in,out] scheduler Scheduler data
*
* \return Pointer to new digest cache entry (or NULL on memory error)
* \note It is the caller's responsibility to free the result using
* pe__free_digests().
*/
op_digest_cache_t *
-pe__calculate_digests(pe_resource_t *rsc, const char *task, guint *interval_ms,
- const pe_node_t *node, const xmlNode *xml_op,
- GHashTable *overrides, bool calc_secure,
- pe_working_set_t *data_set)
+pe__calculate_digests(pcmk_resource_t *rsc, const char *task,
+ guint *interval_ms, const pcmk_node_t *node,
+ const xmlNode *xml_op, GHashTable *overrides,
+ bool calc_secure, pcmk_scheduler_t *scheduler)
{
op_digest_cache_t *data = calloc(1, sizeof(op_digest_cache_t));
const char *op_version = NULL;
@@ -308,23 +316,23 @@ pe__calculate_digests(pe_resource_t *rsc, const char *task, guint *interval_ms,
return NULL;
}
- data->rc = RSC_DIGEST_MATCH;
+ data->rc = pcmk__digest_match;
if (xml_op != NULL) {
op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION);
}
- if (op_version == NULL && data_set != NULL && data_set->input != NULL) {
- op_version = crm_element_value(data_set->input, XML_ATTR_CRM_VERSION);
+ if (op_version == NULL && scheduler != NULL && scheduler->input != NULL) {
+ op_version = crm_element_value(scheduler->input, XML_ATTR_CRM_VERSION);
}
if (op_version == NULL) {
op_version = CRM_FEATURE_SET;
}
- params = pe_rsc_params(rsc, node, data_set);
+ params = pe_rsc_params(rsc, node, scheduler);
calculate_main_digest(data, rsc, node, params, task, interval_ms, xml_op,
- op_version, overrides, data_set);
+ op_version, overrides, scheduler);
if (calc_secure) {
calculate_secure_digest(data, rsc, params, xml_op, op_version,
overrides);
@@ -343,14 +351,14 @@ pe__calculate_digests(pe_resource_t *rsc, const char *task, guint *interval_ms,
* \param[in,out] node Node action was performed on
* \param[in] xml_op XML of operation in CIB status (if available)
* \param[in] calc_secure Whether to calculate secure digest
- * \param[in,out] data_set Cluster working set
+ * \param[in,out] scheduler Scheduler data
*
* \return Pointer to node's digest cache entry
*/
static op_digest_cache_t *
-rsc_action_digest(pe_resource_t *rsc, const char *task, guint interval_ms,
- pe_node_t *node, const xmlNode *xml_op,
- bool calc_secure, pe_working_set_t *data_set)
+rsc_action_digest(pcmk_resource_t *rsc, const char *task, guint interval_ms,
+ pcmk_node_t *node, const xmlNode *xml_op,
+ bool calc_secure, pcmk_scheduler_t *scheduler)
{
op_digest_cache_t *data = NULL;
char *key = pcmk__op_key(rsc->id, task, interval_ms);
@@ -358,7 +366,7 @@ rsc_action_digest(pe_resource_t *rsc, const char *task, guint interval_ms,
data = g_hash_table_lookup(node->details->digest_cache, key);
if (data == NULL) {
data = pe__calculate_digests(rsc, task, &interval_ms, node, xml_op,
- NULL, calc_secure, data_set);
+ NULL, calc_secure, scheduler);
CRM_ASSERT(data != NULL);
g_hash_table_insert(node->details->digest_cache, strdup(key), data);
}
@@ -370,16 +378,16 @@ rsc_action_digest(pe_resource_t *rsc, const char *task, guint interval_ms,
* \internal
* \brief Calculate operation digests and compare against an XML history entry
*
- * \param[in,out] rsc Resource to check
- * \param[in] xml_op Resource history XML
- * \param[in,out] node Node to use for digest calculation
- * \param[in,out] data_set Cluster working set
+ * \param[in,out] rsc Resource to check
+ * \param[in] xml_op Resource history XML
+ * \param[in,out] node Node to use for digest calculation
+ * \param[in,out] scheduler Scheduler data
*
* \return Pointer to node's digest cache entry, with comparison result set
*/
op_digest_cache_t *
-rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op,
- pe_node_t *node, pe_working_set_t *data_set)
+rsc_action_digest_cmp(pcmk_resource_t *rsc, const xmlNode *xml_op,
+ pcmk_node_t *node, pcmk_scheduler_t *scheduler)
{
op_digest_cache_t *data = NULL;
guint interval_ms = 0;
@@ -397,8 +405,9 @@ rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op,
crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
data = rsc_action_digest(rsc, task, interval_ms, node, xml_op,
- pcmk_is_set(data_set->flags, pe_flag_sanitized),
- data_set);
+ pcmk_is_set(scheduler->flags,
+ pcmk_sched_sanitized),
+ scheduler);
if (digest_restart && data->digest_restart_calc && strcmp(data->digest_restart_calc, digest_restart) != 0) {
pe_rsc_info(rsc, "Parameters to %ums-interval %s action for %s on %s "
@@ -408,11 +417,11 @@ rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op,
data->digest_restart_calc,
op_version,
crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));
- data->rc = RSC_DIGEST_RESTART;
+ data->rc = pcmk__digest_restart;
} else if (digest_all == NULL) {
/* it is unknown what the previous op digest was */
- data->rc = RSC_DIGEST_UNKNOWN;
+ data->rc = pcmk__digest_unknown;
} else if (strcmp(digest_all, data->digest_all_calc) != 0) {
/* Given a non-recurring operation with extra parameters configured,
@@ -421,11 +430,10 @@ rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op,
* So that it ensures any changes of the extra parameters get applied
* for this specific operation, and the digests calculated for the
* resulting lrm_rsc_op will be correct.
- * Preserve the implied rc RSC_DIGEST_RESTART for the case that the main
- * digest doesn't match.
+ * Preserve the implied rc pcmk__digest_restart for the case that the
+ * main digest doesn't match.
*/
- if (interval_ms == 0
- && data->rc == RSC_DIGEST_RESTART) {
+ if ((interval_ms == 0) && (data->rc == pcmk__digest_restart)) {
pe_rsc_info(rsc, "Parameters containing extra ones to %ums-interval"
" %s action for %s on %s "
"changed: hash was %s vs. now %s (restart:%s) %s",
@@ -442,11 +450,11 @@ rsc_action_digest_cmp(pe_resource_t *rsc, const xmlNode *xml_op,
(interval_ms > 0)? "reschedule" : "reload",
op_version,
crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));
- data->rc = RSC_DIGEST_ALL;
+ data->rc = pcmk__digest_mismatch;
}
} else {
- data->rc = RSC_DIGEST_MATCH;
+ data->rc = pcmk__digest_match;
}
return data;
}
@@ -522,34 +530,34 @@ unfencing_digest_matches(const char *rsc_id, const char *agent,
* \internal
* \brief Calculate fence device digests and digest comparison result
*
- * \param[in,out] rsc Fence device resource
- * \param[in] agent Fence device's agent type
- * \param[in,out] node Node with digest cache to use
- * \param[in,out] data_set Cluster working set
+ * \param[in,out] rsc Fence device resource
+ * \param[in] agent Fence device's agent type
+ * \param[in,out] node Node with digest cache to use
+ * \param[in,out] scheduler Scheduler data
*
* \return Node's digest cache entry
*/
op_digest_cache_t *
-pe__compare_fencing_digest(pe_resource_t *rsc, const char *agent,
- pe_node_t *node, pe_working_set_t *data_set)
+pe__compare_fencing_digest(pcmk_resource_t *rsc, const char *agent,
+ pcmk_node_t *node, pcmk_scheduler_t *scheduler)
{
const char *node_summary = NULL;
// Calculate device's current parameter digests
op_digest_cache_t *data = rsc_action_digest(rsc, STONITH_DIGEST_TASK, 0U,
- node, NULL, TRUE, data_set);
+ node, NULL, TRUE, scheduler);
// Check whether node has special unfencing summary node attribute
node_summary = pe_node_attribute_raw(node, CRM_ATTR_DIGESTS_ALL);
if (node_summary == NULL) {
- data->rc = RSC_DIGEST_UNKNOWN;
+ data->rc = pcmk__digest_unknown;
return data;
}
// Check whether full parameter digest matches
if (unfencing_digest_matches(rsc->id, agent, data->digest_all_calc,
node_summary)) {
- data->rc = RSC_DIGEST_MATCH;
+ data->rc = pcmk__digest_match;
return data;
}
@@ -557,9 +565,9 @@ pe__compare_fencing_digest(pe_resource_t *rsc, const char *agent,
node_summary = pe_node_attribute_raw(node, CRM_ATTR_DIGESTS_SECURE);
if (unfencing_digest_matches(rsc->id, agent, data->digest_secure_calc,
node_summary)) {
- data->rc = RSC_DIGEST_MATCH;
- if (!pcmk__is_daemon && data_set->priv != NULL) {
- pcmk__output_t *out = data_set->priv;
+ data->rc = pcmk__digest_match;
+ if (!pcmk__is_daemon && scheduler->priv != NULL) {
+ pcmk__output_t *out = scheduler->priv;
out->info(out, "Only 'private' parameters to %s "
"for unfencing %s changed", rsc->id,
pe__node_name(node));
@@ -568,10 +576,12 @@ pe__compare_fencing_digest(pe_resource_t *rsc, const char *agent,
}
// Parameters don't match
- data->rc = RSC_DIGEST_ALL;
- if (pcmk_is_set(data_set->flags, pe_flag_sanitized) && data->digest_secure_calc) {
- if (data_set->priv != NULL) {
- pcmk__output_t *out = data_set->priv;
+ data->rc = pcmk__digest_mismatch;
+ if (pcmk_is_set(scheduler->flags, pcmk_sched_sanitized)
+ && (data->digest_secure_calc != NULL)) {
+
+ if (scheduler->priv != NULL) {
+ pcmk__output_t *out = scheduler->priv;
char *digest = create_unfencing_summary(rsc->id, agent,
data->digest_secure_calc);