From 4bdda97ff76d0e682f4f58bc632cd2cbd417c423 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
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