diff options
Diffstat (limited to '')
-rw-r--r-- | lib/pengine/pe_digest.c | 162 |
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); |