From 4bdda97ff76d0e682f4f58bc632cd2cbd417c423 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Tue, 14 Jan 2020 12:52:21 -0600 Subject: [PATCH 01/18] Log: controller: improve messages when deleting CIB resource history This also moves delete_rsc_status() to controld_based.c and renames it. --- daemons/controld/controld_based.c | 71 +++++++++++++++++++++++++++++++++++++++ daemons/controld/controld_execd.c | 47 +++++--------------------- daemons/controld/controld_utils.h | 4 ++- 3 files changed, 83 insertions(+), 39 deletions(-) diff --git a/daemons/controld/controld_based.c b/daemons/controld/controld_based.c index 42e321f..f3a7c4f 100644 --- a/daemons/controld/controld_based.c +++ b/daemons/controld/controld_based.c @@ -243,3 +243,74 @@ controld_delete_node_state(const char *uname, enum controld_section_e section, } free(xpath); } + +// Takes node name and resource ID +#define XPATH_RESOURCE_HISTORY "//" XML_CIB_TAG_STATE \ + "[@" XML_ATTR_UNAME "='%s'] /" \ + XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES \ + "/" XML_LRM_TAG_RESOURCE \ + "[@" XML_ATTR_ID "='%s']" +// @TODO could add "and @XML_CONFIG_ATTR_SHUTDOWN_LOCK" to limit to locks + +/*! + * \internal + * \brief Clear resource history from CIB for a given resource and node + * + * \param[in] rsc_id ID of resource to be cleared + * \param[in] node Node whose resource history should be cleared + * \param[in] user_name ACL user name to use + * \param[in] call_options CIB call options + * + * \return Standard Pacemaker return code + */ +int +controld_delete_resource_history(const char *rsc_id, const char *node, + const char *user_name, int call_options) +{ + char *desc = NULL; + char *xpath = NULL; + int rc = pcmk_rc_ok; + + CRM_CHECK((rsc_id != NULL) && (node != NULL), return EINVAL); + + desc = crm_strdup_printf("resource history for %s on %s", rsc_id, node); + if (fsa_cib_conn == NULL) { + crm_err("Unable to clear %s: no CIB connection", desc); + free(desc); + return ENOTCONN; + } + + // Ask CIB to delete the entry + xpath = crm_strdup_printf(XPATH_RESOURCE_HISTORY, node, rsc_id); + rc = cib_internal_op(fsa_cib_conn, CIB_OP_DELETE, NULL, xpath, NULL, + NULL, call_options|cib_xpath, user_name); + + if (rc < 0) { + rc = pcmk_legacy2rc(rc); + crm_err("Could not delete resource status of %s on %s%s%s: %s " + CRM_XS " rc=%d", rsc_id, node, + (user_name? " for user " : ""), (user_name? user_name : ""), + pcmk_rc_str(rc), rc); + free(desc); + free(xpath); + return rc; + } + + if (is_set(call_options, cib_sync_call)) { + if (is_set(call_options, cib_dryrun)) { + crm_debug("Deletion of %s would succeed", desc); + } else { + crm_debug("Deletion of %s succeeded", desc); + } + free(desc); + + } else { + crm_info("Clearing %s (via CIB call %d) " CRM_XS " xpath=%s", + desc, rc, xpath); + fsa_register_cib_callback(rc, FALSE, desc, cib_delete_callback); + // CIB library handles freeing desc + } + + free(xpath); + return pcmk_rc_ok; +} diff --git a/daemons/controld/controld_execd.c b/daemons/controld/controld_execd.c index 16751b9..212739e 100644 --- a/daemons/controld/controld_execd.c +++ b/daemons/controld/controld_execd.c @@ -36,8 +36,6 @@ struct delete_event_s { static gboolean is_rsc_active(lrm_state_t * lrm_state, const char *rsc_id); static gboolean build_active_RAs(lrm_state_t * lrm_state, xmlNode * rsc_list); static gboolean stop_recurring_actions(gpointer key, gpointer value, gpointer user_data); -static int delete_rsc_status(lrm_state_t * lrm_state, const char *rsc_id, int call_options, - const char *user_name); static lrmd_event_data_t *construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, const char *operation); @@ -169,7 +167,8 @@ update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_ if (op->rsc_deleted) { crm_debug("Purged history for '%s' after %s", op->rsc_id, op->op_type); - delete_rsc_status(lrm_state, op->rsc_id, cib_quorum_override, NULL); + controld_delete_resource_history(op->rsc_id, lrm_state->node_name, + NULL, crmd_cib_smart_opt()); return; } @@ -917,31 +916,6 @@ lrm_remove_deleted_op(gpointer key, gpointer value, gpointer user_data) return FALSE; } -/* - * Remove the rsc from the CIB - * - * Avoids refreshing the entire LRM section of this host - */ -#define RSC_TEMPLATE "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']" - -static int -delete_rsc_status(lrm_state_t * lrm_state, const char *rsc_id, int call_options, - const char *user_name) -{ - char *rsc_xpath = NULL; - int rc = pcmk_ok; - - CRM_CHECK(rsc_id != NULL, return -ENXIO); - - rsc_xpath = crm_strdup_printf(RSC_TEMPLATE, lrm_state->node_name, rsc_id); - - rc = cib_internal_op(fsa_cib_conn, CIB_OP_DELETE, NULL, rsc_xpath, - NULL, NULL, call_options | cib_xpath, user_name); - - free(rsc_xpath); - return rc; -} - static void delete_rsc_entry(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id, GHashTableIter * rsc_gIter, int rc, const char *user_name) @@ -958,7 +932,8 @@ delete_rsc_entry(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rs else g_hash_table_remove(lrm_state->resource_history, rsc_id_copy); crm_debug("sync: Sending delete op for %s", rsc_id_copy); - delete_rsc_status(lrm_state, rsc_id_copy, cib_quorum_override, user_name); + controld_delete_resource_history(rsc_id_copy, lrm_state->node_name, + user_name, crmd_cib_smart_opt()); g_hash_table_foreach_remove(lrm_state->pending_ops, lrm_remove_deleted_op, rsc_id_copy); free(rsc_id_copy); @@ -1694,21 +1669,17 @@ do_lrm_delete(ha_msg_input_t *input, lrm_state_t *lrm_state, gboolean unregister = TRUE; #if ENABLE_ACL - int cib_rc = delete_rsc_status(lrm_state, rsc->id, - cib_dryrun|cib_sync_call, user_name); + int cib_rc = controld_delete_resource_history(rsc->id, lrm_state->node_name, + user_name, + cib_dryrun|cib_sync_call); - if (cib_rc != pcmk_ok) { + if (cib_rc != pcmk_rc_ok) { lrmd_event_data_t *op = NULL; - crm_err("Could not delete resource status of %s for %s (user %s) on %s: %s" - CRM_XS " rc=%d", - rsc->id, from_sys, (user_name? user_name : "unknown"), - from_host, pcmk_strerror(cib_rc), cib_rc); - op = construct_op(lrm_state, input->xml, rsc->id, CRMD_ACTION_DELETE); op->op_status = PCMK_LRM_OP_ERROR; - if (cib_rc == -EACCES) { + if (cib_rc == EACCES) { op->rc = PCMK_OCF_INSUFFICIENT_PRIV; } else { op->rc = PCMK_OCF_UNKNOWN_ERROR; diff --git a/daemons/controld/controld_utils.h b/daemons/controld/controld_utils.h index f902361..ca8cddb 100644 --- a/daemons/controld/controld_utils.h +++ b/daemons/controld/controld_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2019 the Pacemaker project contributors + * Copyright 2004-2020 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -95,6 +95,8 @@ enum controld_section_e { void controld_delete_node_state(const char *uname, enum controld_section_e section, int options); +int controld_delete_resource_history(const char *rsc_id, const char *node, + const char *user_name, int call_options); const char *get_node_id(xmlNode *lrm_rsc_op); -- 1.8.3.1