From b38525aeebd3446b0bfa6903c294bb933405596f Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Jan 22 2021 12:12:32 +0000 Subject: Fix: scheduler: filter Pacemaker-supplied stonith parameters from secure hash Pacemaker calculates "secure digests" of resource operations as hashes of non-sensitive resource parameters, for use when running crm_simulate on sanitized data sets. Previously, the controller and scheduler could calculate different secure digests for the same resource history entry for stonith resources. The controller created its hash based on all resource parameters listed in the agent meta-data. The scheduler created its hash based on all configured resource parameters, which could include the special parameters (such as "provides") that are interpreted directly by Pacemaker and not passed to the agent. Now, the scheduler excludes the special parameters before hashing. This avoids the annoying situation where running crm_simulate on a sanitized data set shows unnecessary stonith resource restarts. --- diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c index a80dab3..a78bd24 100644 --- a/lib/pengine/utils.c +++ b/lib/pengine/utils.c @@ -2124,6 +2124,9 @@ rsc_action_digest(pe_resource_t *rsc, const char *task, const char *key, data->digest_all_calc = calculate_operation_digest(data->params_all, op_version); if (calc_secure) { + const char *class = crm_element_value(rsc->xml, + XML_AGENT_ATTR_CLASS); + /* The controller doesn't create a digest of *all* non-sensitive * parameters, only those listed in resource agent meta-data. The * equivalent here is rsc->parameters. @@ -2133,6 +2136,23 @@ rsc_action_digest(pe_resource_t *rsc, const char *task, const char *key, if(secure_list) { filter_parameters(data->params_secure, secure_list, FALSE); } + if (pcmk_is_set(pcmk_get_ra_caps(class), + pcmk_ra_cap_fence_params)) { + /* For stonith resources, Pacemaker adds special parameters, + * but these are not listed in fence agent meta-data, so the + * controller will not hash them. That means we have to filter + * them out before calculating our hash for comparison. + */ + for (xmlAttrPtr iter = data->params_secure->properties; + iter != NULL; ) { + const char *prop_name = (const char *) iter->name; + + iter = iter->next; // Grab next now in case we remove current + if (pcmk_stonith_param(prop_name)) { + xml_remove_prop(data->params_secure, prop_name); + } + } + } data->digest_secure_calc = calculate_operation_digest(data->params_secure, op_version); }