diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h index a4f8086..1e5aee1 100644 --- a/include/crm/pengine/internal.h +++ b/include/crm/pengine/internal.h @@ -503,7 +503,7 @@ typedef struct op_digest_cache_s { } op_digest_cache_t; op_digest_cache_t *pe__calculate_digests(pe_resource_t *rsc, const char *task, - const char *key, pe_node_t *node, + guint *interval_ms, pe_node_t *node, xmlNode *xml_op, GHashTable *overrides, bool calc_secure, pe_working_set_t *data_set); diff --git a/lib/pengine/pe_digest.c b/lib/pengine/pe_digest.c index 03aa3bc..b608f22 100644 --- a/lib/pengine/pe_digest.c +++ b/lib/pengine/pe_digest.c @@ -121,19 +121,19 @@ append_all_versioned_params(pe_resource_t *rsc, pe_node_t *node, * \internal * \brief Add digest of all parameters to a digest cache entry * - * \param[out] data Digest cache entry to modify - * \param[in] rsc Resource that action was for - * \param[in] node Node action was performed on - * \param[in] task Name of action performed - * \param[in] key Action's task key - * \param[in] xml_op XML of operation in CIB status (if available) - * \param[in] op_version CRM feature set to use for digest calculation - * \param[in] overrides Key/value hash table to override resource parameters - * \param[in] data_set Cluster working set + * \param[out] data Digest cache entry to modify + * \param[in] rsc Resource that action was for + * \param[in] node Node action was performed on + * \param[in] task Name of action performed + * \param[in,out] interval_ms Action's interval (will be reset if in overrides) + * \param[in] xml_op XML of operation in CIB status (if available) + * \param[in] op_version CRM feature set to use for digest calculation + * \param[in] overrides Key/value table to override resource parameters + * \param[in] data_set Cluster working set */ static void calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc, - pe_node_t *node, const char *task, const char *key, + pe_node_t *node, const char *task, guint *interval_ms, xmlNode *xml_op, const char *op_version, GHashTable *overrides, pe_working_set_t *data_set) { @@ -153,7 +153,24 @@ calculate_main_digest(op_digest_cache_t *data, pe_resource_t *rsc, rsc->id, node->details->uname); } - action = custom_action(rsc, strdup(key), task, node, TRUE, FALSE, data_set); + // If interval was overridden, reset it + if (overrides != NULL) { + const char *interval_s = g_hash_table_lookup(overrides, CRM_META "_" + XML_LRM_ATTR_INTERVAL); + + if (interval_s != NULL) { + long long value_ll; + + errno = 0; + value_ll = crm_parse_ll(interval_s, NULL); + if ((errno == 0) && (value_ll >= 0) && (value_ll <= G_MAXUINT)) { + *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) { g_hash_table_foreach(overrides, hash2field, data->params_all); } @@ -280,21 +297,21 @@ calculate_restart_digest(op_digest_cache_t *data, xmlNode *xml_op, * \internal * \brief Create a new digest cache entry with calculated digests * - * \param[in] rsc Resource that action was for - * \param[in] task Name of action performed - * \param[in] key Action's task key - * \param[in] node Node action was performed on - * \param[in] xml_op XML of operation in CIB status (if available) - * \param[in] overrides Key/value hash table to override resource parameters - * \param[in] calc_secure Whether to calculate secure digest - * \param[in] data_set Cluster working set + * \param[in] rsc Resource that action was for + * \param[in] task Name of action performed + * \param[in,out] interval_ms Action's interval (will be reset if in overrides) + * \param[in] node Node action was performed on + * \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] data_set Cluster working set * * \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, const char *key, +pe__calculate_digests(pe_resource_t *rsc, const char *task, guint *interval_ms, pe_node_t *node, xmlNode *xml_op, GHashTable *overrides, bool calc_secure, pe_working_set_t *data_set) { @@ -307,8 +324,9 @@ pe__calculate_digests(pe_resource_t *rsc, const char *task, const char *key, if (xml_op != NULL) { op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION); } - calculate_main_digest(data, rsc, node, task, key, xml_op, op_version, - overrides, data_set); + + calculate_main_digest(data, rsc, node, task, interval_ms, xml_op, + op_version, overrides, data_set); if (calc_secure) { calculate_secure_digest(data, rsc, xml_op, op_version, overrides); } @@ -322,7 +340,7 @@ pe__calculate_digests(pe_resource_t *rsc, const char *task, const char *key, * * \param[in] rsc Resource that action was for * \param[in] task Name of action performed - * \param[in] key Action's task key + * \param[in] interval_ms Action's interval * \param[in] 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 @@ -331,29 +349,40 @@ pe__calculate_digests(pe_resource_t *rsc, const char *task, const char *key, * \return Pointer to node's digest cache entry */ static op_digest_cache_t * -rsc_action_digest(pe_resource_t *rsc, const char *task, const char *key, +rsc_action_digest(pe_resource_t *rsc, const char *task, guint interval_ms, pe_node_t *node, xmlNode *xml_op, bool calc_secure, pe_working_set_t *data_set) { op_digest_cache_t *data = NULL; + char *key = pcmk__op_key(rsc->id, task, interval_ms); data = g_hash_table_lookup(node->details->digest_cache, key); if (data == NULL) { - data = pe__calculate_digests(rsc, task, key, node, xml_op, NULL, - calc_secure, data_set); + data = pe__calculate_digests(rsc, task, &interval_ms, node, xml_op, + NULL, calc_secure, data_set); CRM_ASSERT(data != NULL); g_hash_table_insert(node->details->digest_cache, strdup(key), data); } + free(key); return data; } +/*! + * \internal + * \brief Calculate operation digests and compare against an XML history entry + * + * \param[in] rsc Resource to check + * \param[in] xml_op Resource history XML + * \param[in] node Node to use for digest calculation + * \param[in] data_set Cluster working set + * + * \return Pointer to node's digest cache entry, with comparison result set + */ op_digest_cache_t * rsc_action_digest_cmp(pe_resource_t * rsc, xmlNode * xml_op, pe_node_t * node, pe_working_set_t * data_set) { op_digest_cache_t *data = NULL; - - char *key = NULL; guint interval_ms = 0; const char *op_version; @@ -368,17 +397,18 @@ rsc_action_digest_cmp(pe_resource_t * rsc, xmlNode * xml_op, pe_node_t * node, digest_restart = crm_element_value(xml_op, XML_LRM_ATTR_RESTART_DIGEST); crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms); - key = pcmk__op_key(rsc->id, task, interval_ms); - data = rsc_action_digest(rsc, task, key, node, xml_op, + data = rsc_action_digest(rsc, task, interval_ms, node, xml_op, pcmk_is_set(data_set->flags, pe_flag_sanitized), data_set); data->rc = RSC_DIGEST_MATCH; if (digest_restart && data->digest_restart_calc && strcmp(data->digest_restart_calc, digest_restart) != 0) { - pe_rsc_info(rsc, "Parameters to %s on %s changed: was %s vs. now %s (restart:%s) %s", - key, node->details->uname, - crm_str(digest_restart), data->digest_restart_calc, - op_version, crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); + pe_rsc_info(rsc, "Parameters to %ums-interval %s action for %s on %s " + "changed: hash was %s vs. now %s (restart:%s) %s", + interval_ms, task, rsc->id, node->details->uname, + crm_str(digest_restart), data->digest_restart_calc, + op_version, + crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); data->rc = RSC_DIGEST_RESTART; } else if (digest_all == NULL) { @@ -386,15 +416,15 @@ rsc_action_digest_cmp(pe_resource_t * rsc, xmlNode * xml_op, pe_node_t * node, data->rc = RSC_DIGEST_UNKNOWN; } else if (strcmp(digest_all, data->digest_all_calc) != 0) { - pe_rsc_info(rsc, "Parameters to %s on %s changed: was %s vs. now %s (%s:%s) %s", - key, node->details->uname, - crm_str(digest_all), data->digest_all_calc, - (interval_ms > 0)? "reschedule" : "reload", - op_version, crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); + pe_rsc_info(rsc, "Parameters to %ums-interval %s action for %s on %s " + "changed: hash was %s vs. now %s (%s:%s) %s", + interval_ms, task, rsc->id, node->details->uname, + crm_str(digest_all), data->digest_all_calc, + (interval_ms > 0)? "reschedule" : "reload", + op_version, + crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC)); data->rc = RSC_DIGEST_ALL; } - - free(key); return data; } @@ -483,12 +513,9 @@ pe__compare_fencing_digest(pe_resource_t *rsc, const char *agent, const char *node_summary = NULL; // Calculate device's current parameter digests - char *key = pcmk__op_key(rsc->id, STONITH_DIGEST_TASK, 0); - op_digest_cache_t *data = rsc_action_digest(rsc, STONITH_DIGEST_TASK, key, + op_digest_cache_t *data = rsc_action_digest(rsc, STONITH_DIGEST_TASK, 0U, node, NULL, TRUE, data_set); - free(key); - // Check whether node has special unfencing summary node attribute node_summary = pe_node_attribute_raw(node, CRM_ATTR_DIGESTS_ALL); if (node_summary == NULL) {