+ 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..b442d98 100644
--- a/src/amf/amfnd/err.cc
+++ b/src/amf/amfnd/err.cc
@@ -59,9 +59,10 @@
*/
#include "amf/amfnd/avnd.h"
+#include "osaf/immutil/immutil.h"
+#include "amf/amfnd/imm.h"
/* static function declarations */
-
static uint32_t avnd_err_escalate(AVND_CB *, AVND_SU *, AVND_COMP *,
uint32_t *);
@@ -173,10 +174,24 @@ 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) {
+ // Send the message to imm reader thread for further processing
+ TRACE("Err_Rep: Sending to Imm thread.");
+ AVSV_NDA_AVA_MSG *ava_msg =
+ static_cast<AVSV_NDA_AVA_MSG *>(calloc(1, sizeof(AVSV_NDA_AVA_MSG)));
+ memcpy(ava_msg, evt->info.ava.msg, sizeof(AVSV_NDA_AVA_MSG));
+ AVND_EVT *evt_er = avnd_evt_create(cb, AVND_EVT_AVA_ERR_REP,
+ &evt->mds_ctxt, &api_info->dest, (void *)ava_msg, 0, 0);
+ rc = m_NCS_IPC_SEND(&ir_cb.mbx, evt_er, evt_er->priority);
+ if (NCSCC_RC_SUCCESS != rc) {
+ LOG_CR("AvND send event to IR mailbox failed, type = %u", evt_er->type);
+ /* if failure, free the event */
+ if (evt_er) avnd_evt_destroy(evt_er);
+ amf_rc = SA_AIS_ERR_TRY_AGAIN;
+ } else
+ goto done;
+ }
/* We need not entertain errors when comp is not in shape */
if (comp && (m_AVND_COMP_PRES_STATE_IS_UNINSTANTIATED(comp) ||
m_AVND_COMP_PRES_STATE_IS_INSTANTIATIONFAILED(comp) ||
diff --git a/src/amf/amfnd/imm.cc b/src/amf/amfnd/imm.cc
index f6b175a..f3a83a7 100644
--- a/src/amf/amfnd/imm.cc
+++ b/src/amf/amfnd/imm.cc
@@ -20,6 +20,7 @@
#include <atomic>
#include "amf/amfnd/avnd.h"
#include <poll.h>
+#include "osaf/immutil/immutil.h"
#include "amf/amfnd/imm.h"
ir_cb_t ir_cb;
@@ -106,45 +107,238 @@ void ImmReader::ir_process_event(AVND_EVT *evt) {
uint32_t res = NCSCC_RC_SUCCESS;
AVND_SU *su = 0;
TRACE_ENTER2("Evt type:%u", evt->type);
+ if(AVND_EVT_IR == evt->type) {
+ /* get the su */
+ su = avnd_sudb_rec_get(avnd_cb->sudb,
+ Amf::to_string(&evt->info.ir_evt.su_name));
+ if (!su) {
+ TRACE("SU'%s', not found in DB",
+ osaf_extended_name_borrow(&evt->info.ir_evt.su_name));
+ goto done;
+ }
- /* get the su */
- su = avnd_sudb_rec_get(avnd_cb->sudb,
- Amf::to_string(&evt->info.ir_evt.su_name));
- if (!su) {
- TRACE("SU'%s', not found in DB",
- osaf_extended_name_borrow(&evt->info.ir_evt.su_name));
- goto done;
- }
-
- if (false == su->is_ncs) {
- res = avnd_comp_config_get_su(su);
- } else {
- res = NCSCC_RC_FAILURE;
- }
+ if (false == su->is_ncs) {
+ res = avnd_comp_config_get_su(su);
+ } else {
+ res = NCSCC_RC_FAILURE;
+ }
- {
- AVND_EVT *evt_ir = 0;
- SaNameT copy_name;
- TRACE("Sending to main thread.");
- osaf_extended_name_alloc(su->name.c_str(), ©_name);
- evt_ir =
+ {
+ AVND_EVT *evt_ir = 0;
+ SaNameT copy_name;
+ TRACE("Sending to main thread.");
+ osaf_extended_name_alloc(su->name.c_str(), ©_name);
+ evt_ir =
avnd_evt_create(avnd_cb, AVND_EVT_IR, 0, nullptr, ©_name, 0, 0);
- osaf_extended_name_free(©_name);
- if (res == NCSCC_RC_SUCCESS)
- evt_ir->info.ir_evt.status = true;
- else
- evt_ir->info.ir_evt.status = false;
+ osaf_extended_name_free(©_name);
+ if (res == NCSCC_RC_SUCCESS)
+ evt_ir->info.ir_evt.status = true;
+ else
+ evt_ir->info.ir_evt.status = false;
+
+ res = m_NCS_IPC_SEND(&avnd_cb->mbx, evt_ir, evt_ir->priority);
+
+ if (NCSCC_RC_SUCCESS != res)
+ LOG_CR("AvND send event to main thread mailbox failed, type = %u",
+ evt_ir->type);
+
+ TRACE("Imm Read:'%d'", evt_ir->info.ir_evt.status);
+
+ /* if failure, free the event */
+ if (NCSCC_RC_SUCCESS != res) avnd_evt_destroy(evt_ir);
+ }
+ } else if (AVND_EVT_AVA_ERR_REP == evt->type) {
+ AVSV_AMF_API_INFO *api_info = &evt->info.ava.msg->info.api_info;
+ AVSV_AMF_ERR_REP_PARAM *err_rep = &api_info->param.err_rep;
+ SaAisErrorT amf_rc = SA_AIS_OK;
+ AVND_COMP *comp = 0;
+ SaImmHandleT immOmHandle = 0;
+ SaVersionT immVersion = {'A', 2, 15};
+ SaImmAccessorHandleT accessorHandle = 0;
+ const SaImmAttrValuesT_2 **attributes;
+ std::string su_name;
+ SaNameT node_name, clm_node_name;
+ SaAmfOperationalStateT oper_status;
+ bool is_member;
+ SaClmNodeIdT node_id;
+ SaAisErrorT error;
+ // 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 !=
avnd_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 imm_not_initialized;
+ }
+ // Check if component is configured in the Cluster.
+ 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 imm_not_initialized;
+ }
+
+ 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 immOmHandle_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 immOmAccessor_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;
+ }
- res = m_NCS_IPC_SEND(&avnd_cb->mbx, evt_ir, evt_ir->priority);
+ goto immOmAccessor_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());
- if (NCSCC_RC_SUCCESS != res)
- LOG_CR("AvND send event to main thread mailbox failed, type = %u",
- evt_ir->type);
+ // 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;
+ }
- TRACE("Imm Read:'%d'", evt_ir->info.ir_evt.status);
+ goto immOmAccessor_finalize;
+ }
+ TRACE("Hosting Amf node '%s' found.", Amf::to_string(&node_name).c_str());
- /* if failure, free the event */
- if (NCSCC_RC_SUCCESS != res) avnd_evt_destroy(evt_ir);
+ // 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 immOmAccessor_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 immOmAccessor_finalize;
+ }
+