Hi Minh,
Thanks for your comments.
For #1: We are only using amf_saImmOmAccessorGet_o2() api, so shouldn't be any 
issue. But, I am working on it to read the information in imm thread, will 
publish it shortly, Minh.
For #2: No, you didn't miss it, Minh. Since, this is internal to Amf and not 
exposed to the user, we can have few enums like this for making Amf work.
For #3: I came to know and you may already know, Minh that 
AVND_COMP_TYPE_INTER_NODE is used for internode(also for external components) 
proxy-proxied components and this feature is badly broken in amfnd code. If I 
use it for error reporting, then it will collide with the feature of 
proxy-proxied and the code may go in some wrong flow in some use case and 
fixing that will take more energy and effort. Also proxy-proxied feature is 
diffferent than error report, so better to have a separate enum for this 
feature. So, I decided to use a separate enum for 
code-modularity/clarity/clean-code/easy-to-use.
Please comment.

Thanks
Anand Sundararaj
Senior Solutions Architect | +1 480 686 4772
www.GetHighAvailability.com 
(https://am2.myprofessionalmail.com/appsuite/www.GetHighAvailability.com)
Get High Availability Today!
NJ, USA: +1 508-507-6507

> On 07/29/2020 4:49 PM minhchau <minh.c...@dektech.com.au> wrote:
> 
>  
> Sorry, typo
> 
> ... imm calls *while* immnd is restarted
> 
> On 30/7/20 9:46 am, minhchau wrote:
> > 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