From 3d8a7dc405e98cd8fe637d3e283bc0468d50bc71 Mon Sep 17 00:00:00 2001 From: Ken Gaillot 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 #include @@ -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