From 3d8a7dc405e98cd8fe637d3e283bc0468d50bc71 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 15 Jan 2020 17:56:44 -0600
Subject: [PATCH 02/18] Refactor: controller: functionize parts of resource
deletion notification
... for future reuse
---
daemons/controld/controld_execd.c | 116 +++++++++++++++++++++++++-------------
daemons/controld/controld_lrm.h | 11 +++-
2 files changed, 88 insertions(+), 39 deletions(-)
diff --git a/daemons/controld/controld_execd.c b/daemons/controld/controld_execd.c
index 212739e..82f2bf1 100644
--- a/daemons/controld/controld_execd.c
+++ b/daemons/controld/controld_execd.c
@@ -42,9 +42,6 @@ static lrmd_event_data_t *construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op
static void do_lrm_rsc_op(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc,
const char *operation, xmlNode *msg);
-void send_direct_ack(const char *to_host, const char *to_sys,
- lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, const char *rsc_id);
-
static gboolean lrm_state_verify_stopped(lrm_state_t * lrm_state, enum crmd_fsa_state cur_state,
int log_level);
static int do_update_resource(const char *node_name, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op);
@@ -278,7 +275,7 @@ send_task_ok_ack(lrm_state_t *lrm_state, ha_msg_input_t *input,
op->rc = PCMK_OCF_OK;
op->op_status = PCMK_LRM_OP_DONE;
- send_direct_ack(ack_host, ack_sys, rsc, op, rsc_id);
+ controld_ack_event_directly(ack_host, ack_sys, rsc, op, rsc_id);
lrmd_free_event(op);
}
@@ -850,6 +847,57 @@ controld_query_executor_state(const char *node_name)
node_update_cluster|node_update_peer);
}
+/*!
+ * \internal
+ * \brief Map standard Pacemaker return code to operation status and OCF code
+ *
+ * \param[out] event Executor event whose status and return code should be set
+ * \param[in] rc Standard Pacemaker return code
+ */
+void
+controld_rc2event(lrmd_event_data_t *event, int rc)
+{
+ switch (rc) {
+ case pcmk_rc_ok:
+ event->rc = PCMK_OCF_OK;
+ event->op_status = PCMK_LRM_OP_DONE;
+ break;
+ case EACCES:
+ event->rc = PCMK_OCF_INSUFFICIENT_PRIV;
+ event->op_status = PCMK_LRM_OP_ERROR;
+ break;
+ default:
+ event->rc = PCMK_OCF_UNKNOWN_ERROR;
+ event->op_status = PCMK_LRM_OP_ERROR;
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief Trigger a new transition after CIB status was deleted
+ *
+ * If a CIB status delete was not expected (as part of the transition graph),
+ * trigger a new transition by updating the (arbitrary) "last-lrm-refresh"
+ * cluster property.
+ *
+ * \param[in] from_sys IPC name that requested the delete
+ * \param[in] rsc_id Resource whose status was deleted (for logging only)
+ */
+void
+controld_trigger_delete_refresh(const char *from_sys, const char *rsc_id)
+{
+ if (safe_str_neq(from_sys, CRM_SYSTEM_TENGINE)) {
+ char *now_s = crm_strdup_printf("%lld", (long long) time(NULL));
+
+ crm_debug("Triggering a refresh after %s cleaned %s", from_sys, rsc_id);
+ update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
+ NULL, NULL, NULL, NULL, "last-lrm-refresh", now_s,
+ FALSE, NULL, NULL);
+ free(now_s);
+ }
+}
+
static void
notify_deleted(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id, int rc)
{
@@ -860,33 +908,11 @@ notify_deleted(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_
crm_info("Notifying %s on %s that %s was%s deleted",
from_sys, (from_host? from_host : "localhost"), rsc_id,
((rc == pcmk_ok)? "" : " not"));
-
op = construct_op(lrm_state, input->xml, rsc_id, CRMD_ACTION_DELETE);
-
- if (rc == pcmk_ok) {
- op->op_status = PCMK_LRM_OP_DONE;
- op->rc = PCMK_OCF_OK;
- } else {
- op->op_status = PCMK_LRM_OP_ERROR;
- op->rc = PCMK_OCF_UNKNOWN_ERROR;
- }
-
- send_direct_ack(from_host, from_sys, NULL, op, rsc_id);
+ controld_rc2event(op, pcmk_legacy2rc(rc));
+ controld_ack_event_directly(from_host, from_sys, NULL, op, rsc_id);
lrmd_free_event(op);
-
- if (safe_str_neq(from_sys, CRM_SYSTEM_TENGINE)) {
- /* this isn't expected - trigger a new transition */
- time_t now = time(NULL);
- char *now_s = crm_itoa(now);
-
- crm_debug("Triggering a refresh after %s deleted %s from the executor",
- from_sys, rsc_id);
-
- update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
- "last-lrm-refresh", now_s, FALSE, NULL, NULL);
-
- free(now_s);
- }
+ controld_trigger_delete_refresh(from_sys, rsc_id);
}
static gboolean
@@ -1495,7 +1521,7 @@ fail_lrm_resource(xmlNode *xml, lrm_state_t *lrm_state, const char *user_name,
#if ENABLE_ACL
if (user_name && is_privileged(user_name) == FALSE) {
crm_err("%s does not have permission to fail %s", user_name, ID(xml_rsc));
- send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc));
+ controld_ack_event_directly(from_host, from_sys, NULL, op, ID(xml_rsc));
lrmd_free_event(op);
return;
}
@@ -1514,7 +1540,7 @@ fail_lrm_resource(xmlNode *xml, lrm_state_t *lrm_state, const char *user_name,
crm_log_xml_warn(xml, "bad input");
}
- send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc));
+ controld_ack_event_directly(from_host, from_sys, NULL, op, ID(xml_rsc));
lrmd_free_event(op);
}
@@ -1684,7 +1710,7 @@ do_lrm_delete(ha_msg_input_t *input, lrm_state_t *lrm_state,
} else {
op->rc = PCMK_OCF_UNKNOWN_ERROR;
}
- send_direct_ack(from_host, from_sys, NULL, op, rsc->id);
+ controld_ack_event_directly(from_host, from_sys, NULL, op, rsc->id);
lrmd_free_event(op);
return;
}
@@ -2000,9 +2026,23 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons
return op;
}
+/*!
+ * \internal
+ * \brief Send a (synthesized) event result
+ *
+ * Reply with a synthesized event result directly, as opposed to going through
+ * the executor.
+ *
+ * \param[in] to_host Host to send result to
+ * \param[in] to_sys IPC name to send result to (NULL for transition engine)
+ * \param[in] rsc Type information about resource the result is for
+ * \param[in] op Event with result to send
+ * \param[in] rsc_id ID of resource the result is for
+ */
void
-send_direct_ack(const char *to_host, const char *to_sys,
- lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, const char *rsc_id)
+controld_ack_event_directly(const char *to_host, const char *to_sys,
+ lrmd_rsc_info_t *rsc, lrmd_event_data_t *op,
+ const char *rsc_id)
{
xmlNode *reply = NULL;
xmlNode *update, *iter;
@@ -2221,7 +2261,7 @@ do_lrm_rsc_op(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc,
op->rc = PCMK_OCF_UNKNOWN_ERROR;
op->op_status = PCMK_LRM_OP_INVALID;
- send_direct_ack(NULL, NULL, rsc, op, rsc->id);
+ controld_ack_event_directly(NULL, NULL, rsc, op, rsc->id);
lrmd_free_event(op);
free(op_id);
return;
@@ -2288,7 +2328,7 @@ do_lrm_rsc_op(lrm_state_t *lrm_state, lrmd_rsc_info_t *rsc,
decode_transition_key(op->user_data, NULL, NULL, NULL, &target_rc);
op->rc = target_rc;
op->op_status = PCMK_LRM_OP_DONE;
- send_direct_ack(NULL, NULL, rsc, op, rsc->id);
+ controld_ack_event_directly(NULL, NULL, rsc, op, rsc->id);
}
pending->params = op->params;
@@ -2388,7 +2428,7 @@ do_update_resource(const char *node_name, lrmd_rsc_info_t * rsc, lrmd_event_data
} else {
crm_warn("Resource %s no longer exists in the executor", op->rsc_id);
- send_direct_ack(NULL, NULL, rsc, op, op->rsc_id);
+ controld_ack_event_directly(NULL, NULL, rsc, op, op->rsc_id);
goto cleanup;
}
@@ -2660,7 +2700,7 @@ process_lrm_event(lrm_state_t *lrm_state, lrmd_event_data_t *op,
}
if (need_direct_ack) {
- send_direct_ack(NULL, NULL, NULL, op, op->rsc_id);
+ controld_ack_event_directly(NULL, NULL, NULL, op, op->rsc_id);
}
if(remove == FALSE) {
diff --git a/daemons/controld/controld_lrm.h b/daemons/controld/controld_lrm.h
index 3ab7048..7acac2a 100644
--- a/daemons/controld/controld_lrm.h
+++ b/daemons/controld/controld_lrm.h
@@ -1,11 +1,13 @@
/*
- * 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.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
+#ifndef CONTROLD_LRM__H
+# define CONTROLD_LRM__H
#include <controld_messages.h>
#include <controld_metadata.h>
@@ -169,3 +171,10 @@ gboolean remote_ra_controlling_guest(lrm_state_t * lrm_state);
void process_lrm_event(lrm_state_t *lrm_state, lrmd_event_data_t *op,
active_op_t *pending, xmlNode *action_xml);
+void controld_ack_event_directly(const char *to_host, const char *to_sys,
+ lrmd_rsc_info_t *rsc, lrmd_event_data_t *op,
+ const char *rsc_id);
+void controld_rc2event(lrmd_event_data_t *event, int rc);
+void controld_trigger_delete_refresh(const char *from_sys, const char *rsc_id);
+
+#endif
--
1.8.3.1