Hi Anand,

1. A general comment is that we should read from imm at amfnd's startup or in a thread, we had many problems in the past that amfnd's stuck in imm calls why immnd is restarted.

2. Can you please point to the saforum spec that how AMF should handle this new type of component (INTER_NODE_NP)? I tried but could not find it, or maybe I have missed it.

3. Is the existing type AVND_COMP_TYPE_INTER_NODE not good enough to reuse? There are avnd_evt_ava_csi_quiescing_compl_evh and avnd_evt_ava_resp_evh that have code patterns to forward to destined node to process the api calls.

Thanks

Minh

On 24/7/20 12:28 pm, s.an...@gethighavailability.com wrote:
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, &reg_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) ||


_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to