From f587cdf6456f23d51b849f5b31b467722df21e79 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Feb 05 2021 06:23:11 +0000 Subject: Refactor: scheduler: pull interval from digest overrides if appropriate When calculating an operation digest, we previously used an operation key provided by the caller, along with a table of parameter overrides. However, if CRM_meta_interval is one of the overrides, that should be used in the operation key instead of the caller-provided key. Now, the caller passes in a pointer to the interval, and if it's overridden, pe__calculate_digests() will use the overridden value and reset the caller's interval to it. As of this commit, no caller passes overrides, so it has no effect, but it will be useful for an upcoming feature. --- 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) {