From: Anand Sundararaj <s.an...@gethighavailability.com>
---
src/amf/amfnd/amfnd.cc | 22 ++++--
src/amf/amfnd/avnd_cb.h | 2 +
src/amf/amfnd/avnd_comp.h | 2 +
src/amf/amfnd/clm.cc | 33 ++++++++-
src/amf/amfnd/err.cc | 182 +++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 228 insertions(+), 13 deletions(-)
diff --git a/src/amf/amfnd/amfnd.cc b/src/amf/amfnd/amfnd.cc
index 1bf057d..9c0aa03 100644
--- a/src/amf/amfnd/amfnd.cc
+++ b/src/amf/amfnd/amfnd.cc
@@ -27,7 +27,6 @@
#include <cinttypes>
#include "amf/amfnd/avnd.h"
-
// Remember MDS install version of Agents. It can be used to send msg to Agent
// based on their versions.
std::map<MDS_DEST, MDS_SVC_PVT_SUB_PART_VER> agent_mds_ver_db;
@@ -203,12 +202,17 @@ uint32_t avnd_evt_avnd_avnd_api_resp_msg_hdl(AVND_CB *cb,
AVND_EVT *evt) {
AVND_COMP *o_comp =
m_AVND_INT_EXT_COMPDB_REC_GET(cb->internode_avail_comp_db, comp_name);
if (nullptr == o_comp) {
- LOG_ER("Couldn't find comp in Inter/Ext Comp DB");
- res = NCSCC_RC_FAILURE;
- goto done;
+ TRACE("Couldn't find comp in Inter/Ext Comp DB");
+ // Check if it is a internode responses like error report, etc.
+ o_comp = avnd_cb->compdb_internode.find(comp_name);
+ if (nullptr == o_comp) {
+ LOG_ER("Couldn't find comp in internode comp DB");
+ res = NCSCC_RC_FAILURE;
+ goto done;
+ } else
+ TRACE("Comp '%s' found in internode comp DB", o_comp->name.c_str());
}
reg_dest = o_comp->reg_dest;
-
/*****************************************************************************
* Some processing for registration and unregistration starts
*****************************************************************************/
@@ -275,9 +279,13 @@ uint32_t avnd_evt_avnd_avnd_api_resp_msg_hdl(AVND_CB *cb,
AVND_EVT *evt) {
/* We have to fprwrd this message to AvA. */
res = avnd_amf_resp_send(cb, resp_info->type, resp_info->rc,
- (uint8_t *)ha_state, ®_dest, &avnd_msg->mds_ctxt,
+ (uint8_t *)ha_state, &o_comp->reg_dest,
&avnd_msg->mds_ctxt,
nullptr, false);
-
+ if (o_comp->comp_type == AVND_COMP_TYPE_INTER_NODE_NP) {
+ TRACE("Comp '%s' deleted from internode comp DB", o_comp->name.c_str());
+ cb->compdb_internode.erase(o_comp->name);
+ delete o_comp;
+ }
if (NCSCC_RC_SUCCESS != res) {
LOG_ER("%s: Msg Send to AvA Failed:Comp:%s ,Type: %u, rc:%u, Dest:%"
PRIu64,
__FUNCTION__, comp_name.c_str(), resp_info->type, resp_info->rc,
diff --git a/src/amf/amfnd/avnd_cb.h b/src/amf/amfnd/avnd_cb.h
index 8b0cc23..a2e5213 100644
--- a/src/amf/amfnd/avnd_cb.h
+++ b/src/amf/amfnd/avnd_cb.h
@@ -125,6 +125,8 @@ typedef struct avnd_cb_tag {
SaTimeT scs_absence_max_duration;
/* the timer for supervision of the absence of SC */
AVND_TMR sc_absence_tmr;
+ // Used for storing comp, residing on other node.
+ AmfDb<std::string, AVND_COMP> compdb_internode;
} AVND_CB;
#define AVND_CB_NULL ((AVND_CB *)0)
diff --git a/src/amf/amfnd/avnd_comp.h b/src/amf/amfnd/avnd_comp.h
index 49c610e..bbc2aa0 100644
--- a/src/amf/amfnd/avnd_comp.h
+++ b/src/amf/amfnd/avnd_comp.h
@@ -296,6 +296,8 @@ typedef struct avnd_pxied_rec {
#define AVND_COMP_TYPE_LOCAL_NODE 0x00000001
#define AVND_COMP_TYPE_INTER_NODE 0x00000002
#define AVND_COMP_TYPE_EXT_CLUSTER 0x00000004
+// Not for proxy or proxied, it is used for error report, etc.
+#define AVND_COMP_TYPE_INTER_NODE_NP 0x00000008
/*##########################################################################
COMPONENT DEFINITION (TOP LEVEL)
diff --git a/src/amf/amfnd/clm.cc b/src/amf/amfnd/clm.cc
index 73c8ff8..111e70a 100644
--- a/src/amf/amfnd/clm.cc
+++ b/src/amf/amfnd/clm.cc
@@ -226,9 +226,36 @@ static void clm_track_cb(
(avnd_cb->node_info.member == SA_TRUE)) {
// Act only once on CLM callback.
clm_node_left(notifItem->clusterNode.nodeId);
- }
- }
-
+ } else {
+ AVND_COMP *comp = nullptr;
+ uint32_t rc;
+ std::string name = "";
+ LOG_NO("Node Id:'%d'", notifItem->clusterNode.nodeId);
+ // Delete the responses, which was expected to come from this node.
+ while (nullptr != (comp =
+ avnd_compdb_rec_get_next(avnd_cb->compdb_internode, ""))) {
+ name = comp->name;
+ // Check the node id
+ TRACE("Comp '%s'", comp->name.c_str());
+ if (comp->node_id == notifItem->clusterNode.nodeId) {
+ TRACE("Comp '%s' matched", comp->name.c_str());
+ if (comp->comp_type == AVND_COMP_TYPE_INTER_NODE_NP) {
+ // We have to forward this message to AvA. As of now
+ // hardcode the value of ERROR_REPORT.
+ rc = avnd_amf_resp_send(avnd_cb, AVSV_AMF_ERR_REP,
SA_AIS_ERR_TIMEOUT,
+ nullptr, &comp->reg_dest, &comp->mds_ctxt,
+ nullptr, false);
+ if (NCSCC_RC_SUCCESS != rc) {
+ LOG_ER("Sending error response failed for %s",
comp->name.c_str());
+ }
+ TRACE("Comp '%s' deleted from internode comp DB",
comp->name.c_str());
+ avnd_cb->compdb_internode.erase(comp->name);
+ delete comp;
+ } // comp type
+ } // Node id match
+ } // while loop
+ } // Different node id.
+ } // if (false == avnd_cb->first_time_up)
} else if (notifItem->clusterChange == SA_CLM_NODE_RECONFIGURED) {
if (avnd_cb->node_info.nodeId == notifItem->clusterNode.nodeId) {
TRACE("local CLM node reconfigured");
diff --git a/src/amf/amfnd/err.cc b/src/amf/amfnd/err.cc
index aeec373..5ca142a 100644
--- a/src/amf/amfnd/err.cc
+++ b/src/amf/amfnd/err.cc
@@ -59,9 +59,9 @@
*/
#include "amf/amfnd/avnd.h"
+#include "osaf/immutil/immutil.h"
/* static function declarations */
-
static uint32_t avnd_err_escalate(AVND_CB *, AVND_SU *, AVND_COMP *,
uint32_t *);
@@ -173,9 +173,185 @@ uint32_t avnd_evt_ava_err_rep_evh(AVND_CB *cb, AVND_EVT *evt) {
/* check if component exists on local AvND node */
comp = avnd_compdb_rec_get(cb->compdb, Amf::to_string(&err_rep->err_comp));
- if (!comp) amf_rc = SA_AIS_ERR_NOT_EXIST;
- /* determine other error codes, if any */
+ if (!comp) {
+ // Check if this component is already in the internode db.
+ // If it is, then it means that Error Report operation
+ // is already undergoing on this comp, so return TRY_AGAIN.
+ if (nullptr !=
cb->compdb_internode.find(Amf::to_string(&err_rep->err_comp))) {
+ LOG_NO("Already Error Report Operation undergoing on '%s'",
+ Amf::to_string(&err_rep->err_comp).c_str());
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ goto goto_error;
+ }
+ // Check if component is configured in the Cluster.
+ SaImmAccessorHandleT accessorHandle = 0;
+ const SaImmAttrValuesT_2 **attributes;
+ SaImmHandleT immOmHandle = 0;
+ SaVersionT immVersion = {'A', 2, 15};
+ std::string su_name;
+ SaNameT node_name, clm_node_name;
+ SaClmNodeIdT node_id;
+ SaAmfOperationalStateT oper_status;
+ bool is_member;
+ SaAisErrorT error = saImmOmInitialize_cond(&immOmHandle, nullptr,
&immVersion);
+ if (error != SA_AIS_OK) {
+ LOG_ER("saImmOmInitialize failed: %u", error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ goto goto_error;
+ }
+
+ error = amf_saImmOmAccessorInitialize(immOmHandle, accessorHandle);
+ if (error != SA_AIS_OK) {
+ LOG_ER("amf_saImmOmAccessorInitialize failed: %u", error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ goto goto_finalize;
+ }
+
+ // Find the component in the Imm DB.
+ if ((error = amf_saImmOmAccessorGet_o2(
+ immOmHandle, accessorHandle, Amf::to_string(&err_rep->err_comp),
+ nullptr, (SaImmAttrValuesT_2 ***)&attributes)) != SA_AIS_OK) {
+ if (error == SA_AIS_ERR_NOT_EXIST) {
+ LOG_NO("Component '%s' is not configured",
+ Amf::to_string(&err_rep->err_comp).c_str());
+ amf_rc = SA_AIS_ERR_NOT_EXIST;
+ } else {
+ LOG_ER("amf_saImmOmAccessorGet_o2(for Comp '%s') failed: %u",
+ Amf::to_string(&err_rep->err_comp).c_str(), error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ }
+
+ goto goto_finalize;
+ }
+
+ // Component is configured. Now, extract SU name from comp name.
+ avnd_cpy_SU_DN_from_DN(su_name, Amf::to_string(&err_rep->err_comp));
+ TRACE("SU name '%s'", su_name.c_str());
+
+ // Get the SU attributes from Imm DB.
+ if ((error = amf_saImmOmAccessorGet_o2(
+ immOmHandle, accessorHandle, su_name,
+ nullptr, (SaImmAttrValuesT_2 ***)&attributes)) != SA_AIS_OK) {
+ if (error == SA_AIS_ERR_NOT_EXIST) {
+ LOG_NO("SU '%s' is not configured", su_name.c_str());
+ amf_rc = SA_AIS_ERR_NOT_EXIST;
+ } else {
+ LOG_ER("amf_saImmOmAccessorGet_o2(for SU '%s') failed: %u",
+ su_name.c_str(), error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ }
+
+ goto goto_finalize;
+ }
+
+ // Get Amf node name, where this SU is hosted.
+ if (immutil_getAttr(
+ const_cast<SaImmAttrNameT>("saAmfSUHostedByNode"),
+ attributes, 0, &node_name) != SA_AIS_OK) {
+ }
+ TRACE("Hosting Amf node '%s'", Amf::to_string(&node_name).c_str());
+
+ // Get Amf node attributes from Imm DB.
+ if ((error = amf_saImmOmAccessorGet_o2(
+ immOmHandle, accessorHandle, Amf::to_string(&node_name),
+ nullptr, (SaImmAttrValuesT_2 ***)&attributes)) != SA_AIS_OK) {
+ if (error == SA_AIS_ERR_NOT_EXIST) {
+ LOG_NO("Amf Node '%s' is not configured",
Amf::to_string(&node_name).c_str());
+ amf_rc = SA_AIS_ERR_NOT_EXIST;
+ } else {
+ LOG_ER("amf_saImmOmAccessorGet_o2(for node '%s') failed: %u",
+ Amf::to_string(&node_name).c_str(), error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ }
+
+ goto goto_finalize;
+ }
+ TRACE("Hosting Amf node '%s' found.", Amf::to_string(&node_name).c_str());
+
+ // Find the values of oper status from Amf node attributes.
+ if (immutil_getAttr(
+ const_cast<SaImmAttrNameT>("saAmfNodeOperState"),
+ attributes, 0, &oper_status) != SA_AIS_OK) {
+ }
+ // Find the Clm Node name from Amf node attributes.
+ if (immutil_getAttr(
+ const_cast<SaImmAttrNameT>("saAmfNodeClmNode"),
+ attributes, 0, &clm_node_name) != SA_AIS_OK) {
+ }
+ TRACE("Amf node saAmfNodeOperState '%u' and Clm node name '%s'",
+ oper_status, Amf::to_string(&clm_node_name).c_str());
+
+ // Get Clm node attributes from Imm DB.
+ if ((error = amf_saImmOmAccessorGet_o2(
+ immOmHandle, accessorHandle, Amf::to_string(&clm_node_name),
+ nullptr, (SaImmAttrValuesT_2 ***)&attributes)) != SA_AIS_OK) {
+ if (error == SA_AIS_ERR_NOT_EXIST) {
+ LOG_NO("Clm Node '%s' is not configured",
+ Amf::to_string(&clm_node_name).c_str());
+ amf_rc = SA_AIS_ERR_NOT_EXIST;
+ } else {
+ LOG_ER("amf_saImmOmAccessorGet_o2(for clm node '%s') failed: %u",
+ Amf::to_string(&clm_node_name).c_str(), error);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ }
+
+ goto goto_finalize;
+ }
+ TRACE("Clm node '%s' found.", Amf::to_string(&clm_node_name).c_str());
+
+ // Find the configured value of saClmNodeIsMember from Clm node attributes.
+ if (immutil_getAttr(
+ const_cast<SaImmAttrNameT>("saClmNodeIsMember"),
+ attributes, 0, &is_member) != SA_AIS_OK) {
+ }
+ // Find the configured value of saClmNodeID from Clm node attributes.
+ if (immutil_getAttr(
+ const_cast<SaImmAttrNameT>("saClmNodeID"),
+ attributes, 0, &node_id) != SA_AIS_OK) {
+ }
+ TRACE("Node id '%u' and Clm member '%u'", node_id, is_member);
+
+ // If the node is disabled (DOWN) or is not a member of Clm cluster, then
+ // return Unavailable for any operation like this.
+ if ((oper_status == SA_AMF_OPERATIONAL_DISABLED) || (is_member == false)) {
+ amf_rc = SA_AIS_ERR_UNAVAILABLE;
+ goto goto_finalize;
+ }
+
+ // We have all the information, send the event to the destined node.
+ rc = avnd_avnd_msg_send(cb, (uint8_t *)api_info, api_info->type,
&evt->mds_ctxt,
+ node_id);
+ if (NCSCC_RC_SUCCESS != rc) {
+ // We couldn't send this to the destined AvND, tell user to try again.
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ LOG_ER("avnd_int_ext_comp_hdlr:Msg Send Failed: '%u'", rc);
+ goto goto_finalize;
+ } else {
+ TRACE("avnd_avnd_msg_send:Msg Send Success");
+ // Add the internode component in the DB
+ comp = new AVND_COMP();
+ comp->name = Amf::to_string(&err_rep->err_comp);
+ comp->node_id = node_id;
+ comp->reg_dest = api_info->dest;
+ comp->mds_ctxt = evt->mds_ctxt;
+ comp->comp_type = AVND_COMP_TYPE_INTER_NODE_NP;
+ // Add to the internode available compdb.
+ rc = avnd_cb->compdb_internode.insert(comp->name, comp);
+ if (NCSCC_RC_SUCCESS != rc) {
+ delete comp;
+ comp = nullptr;
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ LOG_ER("compdb_internode.insert failed: '%u'", rc);
+ goto goto_finalize;
+ }
+ immutil_saImmOmFinalize(immOmHandle);
+ goto done;
+ }
+goto_finalize:
+ immutil_saImmOmFinalize(immOmHandle);
+ }
+goto_error:
/* We need not entertain errors when comp is not in shape */
if (comp && (m_AVND_COMP_PRES_STATE_IS_UNINSTANTIATED(comp) ||