Hi, see inline. /Regards HansN
On 05/28/14 12:18, Hans Feldt wrote:
> See inline and please comment.
> /HansF
>
>> -----Original Message-----
>> From: Nagendra Kumar [mailto:nagendr...@oracle.com]
>> Sent: den 28 maj 2014 12:13
>> To: Hans Nordebäck; Hans Feldt; Praveen Malviya
>> Cc: opensaf-devel@lists.sourceforge.net
>> Subject: RE: [PATCH 1 of 1] AMF: Use IMM applier in the AMF node director V3 
>> [#819]
>>
>> I have few concerns:
>>
>> 1.   It has severe performance issues(when number of nodes increases with 
>> configurations) as we had discussed in #517
>> patch(Sent on 2 Sep 2013).
> [Hans] I don't understand. This change actually reduces cluster impact during 
> change. The AMF director validates and lets IMM distribute the change.
>
> 517 is something else. The relation to this patch is that handling of 
> BADHANDLE needs to be added. I have looked at 517 an my conclusion is that 
> amfnd needs a helper thread to read from IMM. That thread can block and 
> reinitialize with IMM.
>
>> 2.   Due to syncing between directors and node directors(when complete 
>> configuration of sg is loaded at one go), there may be
>> issues like #926,
>>      because directors will send su/comp information to amfnd and amfnd will 
>> also get it from immnd as applier.
> [Hans] well I guess the idea as to only handle modifications of existing 
> already used objects. How can something similar like 926 happen to amfnd you 
> mean?
>
>> 3.   It has lots of code duplicity and maintenance.
> [Hans] that could be true as I have already pointed out.
[HansN] I agree, but shouldn't this be a separate ticket (refactoring) 
to make common code reusable, e.g object_name_to_class_type etc and 
place them in a separate directory?
>> Thanks
>> -Nagu
>>
>>> -----Original Message-----
>>> From: Hans Nordeback [mailto:hans.nordeb...@ericsson.com]
>>> Sent: 28 May 2014 14:27
>>> To: hans.fe...@ericsson.com; Nagendra Kumar; Praveen Malviya
>>> Cc: opensaf-devel@lists.sourceforge.net
>>> Subject: [PATCH 1 of 1] AMF: Use IMM applier in the AMF node director V3
>>> [#819]
>>>
>>>   osaf/libs/common/amf/include/amf_defs.h         |    6 +
>>>   osaf/services/saf/amf/amfnd/Makefile.am         |    1 +
>>>   osaf/services/saf/amf/amfnd/evt.cc              |    7 +
>>>   osaf/services/saf/amf/amfnd/hcdb.cc             |  150 ++++
>>>   osaf/services/saf/amf/amfnd/imm.cc              |  758
>>> ++++++++++++++++++++++++
>>>   osaf/services/saf/amf/amfnd/include/Makefile.am |    1 +
>>>   osaf/services/saf/amf/amfnd/include/avnd.h      |    1 +
>>>   osaf/services/saf/amf/amfnd/include/avnd_evt.h  |    8 +
>>>   osaf/services/saf/amf/amfnd/include/avnd_hc.h   |    1 +
>>>   osaf/services/saf/amf/amfnd/include/avnd_imm.h  |  148 ++++
>>>   osaf/services/saf/amf/amfnd/main.cc             |   10 +-
>>>   11 files changed, 1090 insertions(+), 1 deletions(-)
>>>
>>>
>>> This first patch adds support for changing attributes in class
>>> SaAmfHealthcheckType
>>> Updated with review comments.
>>>
>>> diff --git a/osaf/libs/common/amf/include/amf_defs.h
>>> b/osaf/libs/common/amf/include/amf_defs.h
>>> --- a/osaf/libs/common/amf/include/amf_defs.h
>>> +++ b/osaf/libs/common/amf/include/amf_defs.h
>>> @@ -254,6 +254,12 @@ typedef enum
>>>      saAmfHealthcheckMaxDuration_ID = 2,
>>>   } AVSV_AMF_HEALTHCHECK_ATTR_ID;
>>>
>>> +/* Attribute ID enum for the SaAmfHealthcheckType class */
>>> +typedef enum
>>> +{
>>> +   saAmfHctDefPeriod_ID = 1,
>>> +   saAmfHctDefMaxDuration_ID = 2,
>>> +} AMF_HEALTHCHECK_TYPE_ATTR_ID;
>>>
>>>   #define AVSV_COMMON_SUB_ID_DEFAULT_VAL 1
>>>   #define SA_AMF_PRESENCE_ORPHANED
>>> (SA_AMF_PRESENCE_TERMINATION_FAILED+1)
>>> diff --git a/osaf/services/saf/amf/amfnd/Makefile.am
>>> b/osaf/services/saf/amf/amfnd/Makefile.am
>>> --- a/osaf/services/saf/amf/amfnd/Makefile.am
>>> +++ b/osaf/services/saf/amf/amfnd/Makefile.am
>>> @@ -51,6 +51,7 @@ osafamfnd_SOURCES = \
>>>     err.cc \
>>>     evt.cc \
>>>     hcdb.cc \
>>> +   imm.cc \
>>>     main.cc \
>>>     mbcsv.cc \
>>>     mds.cc \
>>> diff --git a/osaf/services/saf/amf/amfnd/evt.cc
>>> b/osaf/services/saf/amf/amfnd/evt.cc
>>> --- a/osaf/services/saf/amf/amfnd/evt.cc
>>> +++ b/osaf/services/saf/amf/amfnd/evt.cc
>>> @@ -32,6 +32,7 @@
>>>   */
>>>
>>>   #include "avnd.h"
>>> +#include "avnd_imm.h"
>>>
>>>
>>> /************************************************************
>>> ****************
>>>     Name          : avnd_evt_create
>>> @@ -200,6 +201,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb,
>>>   void avnd_evt_destroy(AVND_EVT *evt)
>>>   {
>>>     uint32_t type = 0;
>>> +   AvndImmEvt *imm = 0;
>>>
>>>     if (!evt)
>>>             return;
>>> @@ -294,6 +296,11 @@ void avnd_evt_destroy(AVND_EVT *evt)
>>>     case AVND_EVT_PID_EXIT:
>>>             break;
>>>
>>> +   case AVND_EVT_IMM:
>>> +           imm = static_cast<AvndImmEvt*>(evt->info.imm.imm_evt);
>>> +           delete imm;
>>> +           break;
>>> +
>>>     default:
>>>             LOG_NO("%s: unknown event type %u", __FUNCTION__,
>>> type);
>>>             break;
>>> diff --git a/osaf/services/saf/amf/amfnd/hcdb.cc
>>> b/osaf/services/saf/amf/amfnd/hcdb.cc
>>> --- a/osaf/services/saf/amf/amfnd/hcdb.cc
>>> +++ b/osaf/services/saf/amf/amfnd/hcdb.cc
>>> @@ -36,6 +36,7 @@
>>>   #include "avnd.h"
>>>   #include <saImmOm.h>
>>>   #include <immutil.h>
>>> +#include <string>
>>>
>>>   static NCS_PATRICIA_TREE hctypedb;        /* healthcheck type db */
>>>
>>> @@ -339,6 +340,93 @@ SaAisErrorT avnd_hctype_config_get(SaImm
>>>     return error;
>>>   }
>>>
>>> +// Search for a given key and return its value  or empty string if not 
>>> found.
>>> +static std::string search_key(const std::string& str, const std::string& 
>>> key)
>>> +{
>>> +   std::string value;
>>> +
>>> +   std::string::size_type idx1;
>>> +
>>> +   idx1 = str.find(key);
>>> +
>>> +   // if key was found
>>> +   if (idx1 != std::string::npos) {
>>> +           // get value, idx2 points to value
>>> +           idx1 += key.length();
>>> +           std::string part2 = str.substr(idx1);
>>> +
>>> +           idx1 = part2.find(",");
>>> +
>>> +           // get value
>>> +           value = part2.substr(0, idx1);
>>> +   }
>>> +
>>> +   return value;
>>> +}
>>> +
>>> +//
>>> +static void comp_hctype_update_compdb(AVND_CB *cb,
>>> AVSV_PARAM_INFO *param)
>>> +{
>>> +   AVND_COMP_HC_REC *comp_hc_rec;
>>> +   AVND_COMP * comp;
>>> +   char *comp_type_name;
>>> +   AVSV_HLT_KEY hlt_chk;
>>> +   AVND_COMP_HC_REC tmp_hc_rec;
>>> +
>>> +   // 1. find component from componentType,
>>> +   // input example, param->name.value =
>>> safHealthcheckKey=AmfDemo,safVersion=1,safCompType=AmfDemo1
>>> +   comp_type_name = strstr((char *) param->name.value, "safVersion");
>>> +   TRACE("comp_type_name: %s", comp_type_name);
>>> +   osafassert(comp_type_name);
>>> +
>>> +   // 2. search each component for a matching compType
>>> +   comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb,
>>> (uint8_t *) 0);
>>> +   while (comp != 0) {
>>> +           if (strncmp((const char*) comp->saAmfCompType.value,
>>> comp_type_name, comp->saAmfCompType.length) == 0) {
>>> +
>>> +                   // 3. matching compType found, check that component
>>> does not have a SaAmfHealthcheck rec (specialization)
>>> +                   std::string hlt_chk_key = search_key((const char*)
>>> param->name.value, "safHealthcheckKey=");
>>> +                   if (hlt_chk_key.empty()) {
>>> +                           LOG_ER("%s: failed to get healthcheckKey
>>> from %s", __FUNCTION__, param->name.value);
>>> +                           return;
>>> +                   }
>>> +
>>> +                   memset(&hlt_chk, 0, sizeof(AVSV_HLT_KEY));
>>> +                   hlt_chk.comp_name.length = comp->name.length;
>>> +                   memcpy(hlt_chk.comp_name.value, comp-
>>>> name.value, hlt_chk.comp_name.length);
>>> +                   hlt_chk.key_len = hlt_chk_key.size();
>>> +                   memcpy(hlt_chk.name.key, hlt_chk_key.c_str(),
>>> hlt_chk_key.size());
>>> +                   hlt_chk.name.keyLen = hlt_chk.key_len;
>>> +                   TRACE("comp_name %s key %s keyLen %u",
>>> hlt_chk.comp_name.value, hlt_chk.name.key, hlt_chk.name.keyLen);
>>> +                   if (avnd_hcdb_rec_get(cb, &hlt_chk) == 0) {
>>> +                           TRACE("comp uses healthcheckType rec");
>>> +                           // 4. found a component that uses the
>>> healthcheckType record, update the comp_hc_rec
>>> +                           memset(&tmp_hc_rec, '\0',
>>> sizeof(AVND_COMP_HC_REC));
>>> +                           tmp_hc_rec.key = hlt_chk.name;
>>> +                           tmp_hc_rec.req_hdl = comp->reg_hdl;
>>> +                           TRACE("tmp_hc_rec: key %s req_hdl %llu",
>>> tmp_hc_rec.key.key, tmp_hc_rec.req_hdl);
>>> +                           if ((comp_hc_rec =
>>> m_AVND_COMPDB_REC_HC_GET(*comp, tmp_hc_rec)) != 0) {
>>> +                                   TRACE("comp_hc_rec: period %llu
>>> max_dur %llu", comp_hc_rec->period, comp_hc_rec->max_dur);
>>> +                                   switch (param->attr_id) {
>>> +                                   case saAmfHctDefPeriod_ID:
>>> +                                           comp_hc_rec->period =
>>> *((SaTimeT *) param->value);
>>> +                                           LOG_NO("%s:
>>> saAmfHctDefPeriod updated, new value: %" PRIu64, __FUNCTION__,
>>> (uint64_t) comp_hc_rec->period);
>>> +                                           break;
>>> +                                   case saAmfHctDefMaxDuration_ID:
>>> +                                           comp_hc_rec->max_dur =
>>> *((SaTimeT *) param->value);
>>> +                                           LOG_NO("%s:
>>> saAmfHctDefMaxDuration updated, new value: %" PRIu64, __FUNCTION__,
>>> (uint64_t) comp_hc_rec->max_dur);
>>> +                                           break;
>>> +                                   default:
>>> +                                           osafassert(0);
>>> +                                   }
>>> +                           }
>>> +                   }
>>> +           }
>>> +           comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb-
>>>> compdb, (uint8_t *) & comp->name);
>>> +   }
>>> +}
>>> +
>>> +//
>>>   uint32_t avnd_hc_oper_req(AVND_CB *cb, AVSV_PARAM_INFO *param)
>>>   {
>>>     uint32_t rc = NCSCC_RC_FAILURE;
>>> @@ -401,3 +489,65 @@ done:
>>>     return rc;
>>>   }
>>>
>>> +uint32_t avnd_hctype_oper_req(AVND_CB *cb, AVSV_PARAM_INFO
>>> *param)
>>> +{
>>> +   uint32_t rc = NCSCC_RC_FAILURE;
>>> +
>>> +   TRACE_ENTER2("'%s'", param->name.value);
>>> +   AVND_HCTYPE *hctype = (AVND_HCTYPE *)
>>> ncs_patricia_tree_get(&hctypedb, (uint8_t *)&param->name);
>>> +
>>> +   switch (param->act) {
>>> +   case AVSV_OBJ_OPR_MOD: {
>>> +           if (!hctype) {
>>> +                   LOG_ER("%s: failed to get %s", __FUNCTION__,
>>> param->name.value);
>>> +                   goto done;
>>> +           }
>>> +
>>> +           switch (param->attr_id) {
>>> +           case saAmfHctDefPeriod_ID:
>>> +                   osafassert(sizeof(SaTimeT) == param->value_len);
>>> +                   hctype->saAmfHctDefPeriod = *((SaTimeT *)param-
>>>> value);
>>> +                   comp_hctype_update_compdb(cb, param);
>>> +                   break;
>>> +
>>> +           case saAmfHctDefMaxDuration_ID:
>>> +                   osafassert(sizeof(SaTimeT) == param->value_len);
>>> +                   hctype->saAmfHctDefMaxDuration = *((SaTimeT
>>> *)param->value);
>>> +                   comp_hctype_update_compdb(cb, param);
>>> +                   break;
>>> +
>>> +           default:
>>> +                   LOG_NO("%s: Unsupported attribute %u",
>>> __FUNCTION__, param->attr_id);
>>> +                   goto done;
>>> +           }
>>> +           break;
>>> +   }
>>> +
>>> +   case AVSV_OBJ_OPR_DEL: {
>>> +           if (hctype != NULL) {
>>> +                   rc = ncs_patricia_tree_del(&hctypedb, &hctype-
>>>> tree_node);
>>> +                   osafassert(rc == NCSCC_RC_SUCCESS);
>>> +                   LOG_IN("Deleted '%s'", param->name.value);
>>> +           } else {
>>> +                   /*
>>> +                    ** Normal case that happens if a parent of this HC was
>>> +                    ** the real delete target for the CCB.
>>> +                    */
>>> +                        TRACE("already deleted!");
>>> +           }
>>> +
>>> +           break;
>>> +   }
>>> +   default:
>>> +           LOG_NO("%s: Unsupported action %u", __FUNCTION__,
>>> param->act);
>>> +           goto done;
>>> +   }
>>> +
>>> +   rc = NCSCC_RC_SUCCESS;
>>> +
>>> +done:
>>> +   rc = NCSCC_RC_SUCCESS;
>>> +
>>> +   TRACE_LEAVE();
>>> +   return rc;
>>> +}
>>> diff --git a/osaf/services/saf/amf/amfnd/imm.cc
>>> b/osaf/services/saf/amf/amfnd/imm.cc
>>> new file mode 100644
>>> --- /dev/null
>>> +++ b/osaf/services/saf/amf/amfnd/imm.cc
>>> @@ -0,0 +1,758 @@
>>> +/*      -*- OpenSAF  -*-
>>> + *
>>> + * (C) Copyright 2014 The OpenSAF Foundation
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> MERCHANTABILITY
>>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
>>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>>> + * The complete license can be accessed from the following location:
>>> + * http://opensource.org/licenses/lgpl-license.php
>>> + * See the Copying file included with the OpenSAF distribution for full
>>> + * licensing terms.
>>> + *
>>> + * Author(s): Ericsson AB
>>> + *
>>> + */
>>> +
>>> +/***********************************************************
>>> ******************
>>> +
>>> +  DESCRIPTION:
>>> +
>>> +
>>> *************************************************************
>>> ***************/
>>> +#include <string>
>>> +#include <cstring>
>>> +#include <algorithm>
>>> +#include <poll.h>
>>> +#include "avnd_imm.h"
>>> +#include "immutil.h"
>>> +
>>> +extern struct ImmutilWrapperProfile immutilWrapperProfile;
>>> +
>>> +//
>>> +SaVersionT AvndImm::immVersion_ = {'A', 2, 11};
>>> +SaImmOiHandleT AvndImm::immOiHandle_ = 0;
>>> +SaImmOiHandleT AvndImm::immOmHandle_ = 0;
>>> +SaSelectionObjectT AvndImm::imm_sel_obj_ = -1;
>>> +AvndImm::UpdateFn
>>> AvndImm::update_callback_[AVSV_SA_AMF_CLASS_MAX] = {0};
>>> +
>>> +// This string array must match the AVND_AMF_CLASS_ID enum
>>> +const char *AvndImm::avnd_class_names_[] = {
>>> +  "SaAmfHealthcheckType"
>>> +};
>>> +
>>> +/**
>>> + * This method adds IMM modification attribute to attribute vector
>>> + *
>>> + * @param attr
>>> + */
>>> +void AvndImmEvt::set_mod_attr(const SaImmAttrModificationT_2& attr) {
>>> +  SaImmAttrModificationT_2 *tmp = new SaImmAttrModificationT_2;
>>> +  tmp->modType = attr.modType;
>>> +  AvndImmUtil::copySaImmAttrValuesT(tmp->modAttr, attr.modAttr);
>>> +  attr_.push_back(tmp);
>>> +}
>>> +
>>> +
>>> +/**
>>> + * Destructor
>>> + */
>>> +AvndImmEvt::~AvndImmEvt() {
>>> +  std::for_each(attr_.begin(), attr_.end(), AvndImmUtil::remove_attr);
>>> +  attr_.clear();
>>> +}
>>> +
>>> +/**
>>> + * This function returns a pointer to a new string which is a duplicate of 
>>> the
>>> string s.
>>> + *
>>> + * @param s
>>> + *
>>> + * @return pointer to new string
>>> + */
>>> +char *AvndImmUtil::str_dup(const char *s) {
>>> +  char *c = new char[strlen(s) + 1];
>>> +  std::strcpy(c, s);
>>> +  return c;
>>> +}
>>> +
>>> +/**
>>> + * This function returns the size of given attribute value type.
>>> + *
>>> + * @param attrValueType
>>> + *
>>> + * @return attrValueType size
>>> + */
>>> +size_t AvndImmUtil::value_size(SaImmValueTypeT attrValueType) {
>>> +  size_t value_size = 0;
>>> +
>>> +  switch (attrValueType) {
>>> +    case SA_IMM_ATTR_SAINT32T:
>>> +      value_size = sizeof(SaInt32T);
>>> +      break;
>>> +    case SA_IMM_ATTR_SAUINT32T:
>>> +      value_size = sizeof(SaUint32T);
>>> +      break;
>>> +    case SA_IMM_ATTR_SAINT64T:
>>> +      value_size = sizeof(SaInt64T);
>>> +      break;
>>> +    case SA_IMM_ATTR_SAUINT64T:
>>> +      value_size = sizeof(SaUint64T);
>>> +      break;
>>> +    case SA_IMM_ATTR_SATIMET:
>>> +      value_size = sizeof(SaTimeT);
>>> +      break;
>>> +    case SA_IMM_ATTR_SANAMET:
>>> +      value_size = sizeof(SaNameT);
>>> +      break;
>>> +    case SA_IMM_ATTR_SAFLOATT:
>>> +      value_size = sizeof(SaFloatT);
>>> +      break;
>>> +    case SA_IMM_ATTR_SADOUBLET:
>>> +      value_size = sizeof(SaDoubleT);
>>> +      break;
>>> +    case SA_IMM_ATTR_SASTRINGT:
>>> +      value_size = sizeof(SaStringT);
>>> +      break;
>>> +    case SA_IMM_ATTR_SAANYT:
>>> +      osafassert(0);
>>> +      break;
>>> +  }
>>> +
>>> +  return value_size;
>>> +}
>>> +
>>> +/**
>>> + * This function returns class enum corresponding to object name.
>>> + *
>>> + * @param obj_name
>>> + * @param class_type
>>> + *
>>> + * @return AVSV_AMF_CLASS_ID
>>> + */
>>> +AVSV_AMF_CLASS_ID AvndImmUtil::object_name_to_class_type(const
>>> SaNameT *obj_name) {
>>> +  AVSV_AMF_CLASS_ID class_type = AVSV_SA_AMF_CLASS_INVALID;
>>> +
>>> +  /* Cluster and Node Class Related */
>>> +  if (strncmp((char *)&obj_name->value, "safAmfCluster=", 14) == 0) {
>>> +    class_type = AVSV_SA_AMF_CLUSTER;
>>> +  } else if (strncmp((char *)&obj_name->value, "safAmfNode=", 11) == 0) {
>>> +    class_type = AVSV_SA_AMF_NODE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safAmfNodeGroup=", 16) ==
>>> 0) {
>>> +    class_type = AVSV_SA_AMF_NODE_GROUP;
>>> +  } else if (strncmp((char *)&obj_name->value, "safInstalledSwBundle=", 21)
>>> == 0) {
>>> +    class_type = AVSV_SA_AMF_NODE_SW_BUNDLE;
>>> +  }
>>> +
>>> +  /* Application Class Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safApp=", 7) == 0) {
>>> +    class_type = AVSV_SA_AMF_APP;
>>> +  } else if (strncmp((char *)&obj_name->value, "safAppType=", 11) == 0) {
>>> +    class_type = AVSV_SA_AMF_APP_BASE_TYPE;
>>> +  }
>>> +
>>> +  /* Service Group Class Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safSg=", 6) == 0) {
>>> +    class_type = AVSV_SA_AMF_SG;
>>> +  } else if (strncmp((char *)&obj_name->value, "safSgType=", 10) == 0) {
>>> +    class_type = AVSV_SA_AMF_SG_BASE_TYPE;
>>> +  }
>>> +
>>> +  /* Service Unit Class Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safSu=", 6) == 0) {
>>> +    class_type = AVSV_SA_AMF_SU;
>>> +  } else if (strncmp((char *)&obj_name->value, "safSuType=", 10) == 0) {
>>> +    class_type = AVSV_SA_AMF_SU_BASE_TYPE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safMemberCompType=", 18)
>>> == 0) {
>>> +    class_type = AVSV_SA_AMF_SUT_COMP_TYPE;
>>> +  }
>>> +
>>> +  /* Service Instance Class Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safSi=", 6) == 0) {
>>> +    class_type = AVSV_SA_AMF_SI;
>>> +  } else if (strncmp((char *)&obj_name->value, "safSvcType=", 11) == 0) {
>>> +    class_type = AVSV_SA_AMF_SVC_BASE_TYPE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safDepend=", 10) == 0) {
>>> +    class_type = AVSV_SA_AMF_SI_DEPENDENCY;
>>> +  } else if (strncmp((char *)&obj_name->value, "safRankedSu=", 12) == 0) {
>>> +    class_type = AVSV_SA_AMF_SI_RANKED_SU;
>>> +  } else if (strncmp((char *)&obj_name->value, "safSISU=", 8) == 0) {
>>> +    class_type = AVSV_SA_AMF_SI_ASSIGNMENT;
>>> +  } else if (strncmp((char *)&obj_name->value, "safMemberCSType=", 16) ==
>>> 0) {
>>> +    class_type = AVSV_SA_AMF_SVC_TYPE_CS_TYPES;
>>> +  }
>>> +
>>> +  /* Component Service Instance Class Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safCsi=", 7) == 0) {
>>> +    class_type = AVSV_SA_AMF_CSI;
>>> +  } else if (strncmp((char *)&obj_name->value, "safCSType=", 10) == 0) {
>>> +    class_type = AVSV_SA_AMF_CS_BASE_TYPE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safCsiAttr=", 11) == 0) {
>>> +    class_type = AVSV_SA_AMF_CSI_ATTRIBUTE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safCSIComp=", 11) == 0) {
>>> +    class_type = AVSV_SA_AMF_CSI_ASSIGNMENT;
>>> +  }
>>> +
>>> +  /* Component and component types Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safCompType=", 12) == 0) {
>>> +    class_type = AVSV_SA_AMF_COMP_BASE_TYPE;
>>> +  } else if (strncmp((char *)&obj_name->value, "safSupportedCsType=", 19) 
>>> ==
>>> 0) {
>>> +    if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_CT_CS_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
>>> +      class_type = AVSV_SA_AMF_COMP_CS_TYPE;
>>> +    }
>>> +  } else if (strncmp((char *)&obj_name->value, "safComp=", 8) == 0) {
>>> +    class_type = AVSV_SA_AMF_COMP;
>>> +  }
>>> +
>>> +  /* Global Component Attributes and Health Check Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safRdn=", 7) == 0) {
>>> +    class_type = AVSV_SA_AMF_COMP_GLOBAL_ATTR;
>>> +  } else if (strncmp((char *)&obj_name->value, "safHealthcheckKey=", 18) ==
>>> 0) {
>>> +    if (strstr((char *)&obj_name->value, "safVersion=") != 0) {
>>> +      class_type = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
>>> +      class_type = AVSV_SA_AMF_HEALTH_CHECK;
>>> +    }
>>> +  }
>>> +
>>> +  /* Common Version Related */
>>> +  else if (strncmp((char *)&obj_name->value, "safVersion=", 11) == 0) {
>>> +    if (strstr((char *)&obj_name->value, "safAppType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_APP_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safSgType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_SG_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safSuType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_SU_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safSvcType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_SVC_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safCSType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_CS_TYPE;
>>> +    } else if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
>>> +      class_type = AVSV_SA_AMF_COMP_TYPE;
>>> +    }
>>> +  }
>>> +
>>> +  return class_type;
>>> +}
>>> +
>>> +/**
>>> + * Delete attribute structures.
>>> + *
>>> + * @param attr
>>> + */
>>> +void AvndImmUtil::remove_attr(SaImmAttrModificationT_2* attr) {
>>> +  AvndImmUtil::deleteSaImmAttrValuesT(attr->modAttr);
>>> +  delete attr;
>>> +}
>>> +
>>> +/**
>>> + * Delete attribute values.
>>> + *
>>> + * @param reference to attrValue
>>> + */
>>> +void AvndImmUtil::deleteSaImmAttrValuesT(SaImmAttrValuesT_2&
>>> attr_value) {
>>> +  unsigned int i;
>>> +
>>> +  if (attr_value.attrValueType == SA_IMM_ATTR_SASTRINGT) {
>>> +    for (i = 0; i < attr_value.attrValuesNumber; i++) {
>>> +      char *p = *((char**) attr_value.attrValues[i]);
>>> +      delete [] p;
>>> +    }
>>> +  }
>>> +
>>> +  delete [] attr_value.attrName;
>>> +  delete [] static_cast<char*> (attr_value.attrValues[0]); // free blob 
>>> shared by
>>> all values
>>> +  delete [] attr_value.attrValues;
>>> +
>>> +}
>>> +
>>> +/**
>>> + * Copy IMM attr values,
>>> + *
>>> + * @param to
>>> + * @param from
>>> + */
>>> +void AvndImmUtil::copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const
>>> SaImmAttrValuesT_2& from) {
>>> +  size_t val_size = 0;
>>> +  unsigned int i;
>>> +  unsigned int value_count = from.attrValuesNumber;
>>> +  char *databuffer;
>>> +
>>> +  to.attrName = str_dup(from.attrName);
>>> +
>>> +  to.attrValuesNumber = value_count;
>>> +  to.attrValueType = from.attrValueType;
>>> +  if (value_count == 0)
>>> +    return; /* (just in case...) */
>>> +
>>> +  to.attrValues = new SaImmAttrValueT[value_count];
>>> +
>>> +  val_size = value_size(from.attrValueType);
>>> +
>>> +  // alloc blob shared by all values
>>> +  databuffer = new char[value_count * val_size];
>>> +
>>> +  for (i = 0; i < value_count; i++) {
>>> +    to.attrValues[i] = databuffer;
>>> +    if (from.attrValueType == SA_IMM_ATTR_SASTRINGT) {
>>> +      char *cporig = *((char **) from.attrValues[i]);
>>> +      char **cpp = (char **) databuffer;
>>> +      *cpp = str_dup(cporig);
>>> +    } else {
>>> +      memcpy(databuffer, from.attrValues[i], val_size);
>>> +    }
>>> +    databuffer += val_size;
>>> +  }
>>> +}
>>> +
>>> +/**
>>> + * Function called for not implemented callback types.
>>> + *
>>> + * @param object_name
>>> + * @param imm_attr
>>> + *
>>> + * @return   NCSCC_RC_FAILURE;
>>> + */
>>> +uint32_t AvndImm::not_yet_implemented(const std::string& object_name,
>>> const SaImmAttrModificationT_2* imm_attr) {
>>> +  LOG_WA("Not yet implemented");
>>> +  return NCSCC_RC_FAILURE;
>>> +}
>>> +
>>> +/**
>>> + * Function called for updating health check type.
>>> + *
>>> + * @param object_name
>>> + * @param imm_attr
>>> + *
>>> + * @return   NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE;
>>> + */
>>> +uint32_t AvndImm::update_health_check_type(const std::string&
>>> object_name, const SaImmAttrModificationT_2* imm_attr) {
>>> +  uint32_t rc = NCSCC_RC_FAILURE;
>>> +  AVND_CB *cb = avnd_cb;
>>> +
>>> +  AVSV_PARAM_INFO param;
>>> +  memset(&param, 0, sizeof(param));
>>> +  param.class_id = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
>>> +
>>> +  std::string attr_name = imm_attr->modAttr.attrName;
>>> +
>>> +  strncpy((char*) param.name.value, object_name.c_str(),
>>> object_name.size());
>>> +  param.name.length = object_name.size();
>>> +
>>> +  if (attr_name == "saAmfHctDefPeriod") {
>>> +    param.attr_id = saAmfHctDefPeriod_ID;
>>> +  } else if (attr_name == "saAmfHctDefMaxDuration") {
>>> +    param.attr_id = saAmfHctDefMaxDuration_ID;
>>> +  } else {
>>> +    LOG_WA("Unknown attribute name %s", attr_name.c_str());
>>> +    rc = NCSCC_RC_FAILURE;
>>> +    goto done;
>>> +  }
>>> +
>>> +  if (imm_attr->modType == SA_IMM_ATTR_VALUES_REPLACE) {
>>> +    param.act = AVSV_OBJ_OPR_MOD;
>>> +  } else if (imm_attr->modType == SA_IMM_ATTR_VALUES_DELETE) {
>>> +    param.act = AVSV_OBJ_OPR_DEL;
>>> +  } else {
>>> +    LOG_WA("Unknown modificaton type %d", imm_attr->modType);
>>> +    rc = NCSCC_RC_FAILURE;
>>> +    goto done;
>>> +  }
>>> +
>>> +  param.value_len = AvndImmUtil::value_size(imm_attr-
>>>> modAttr.attrValueType);
>>> +  memcpy(param.value, *imm_attr->modAttr.attrValues, param.value_len);
>>> +
>>> +  rc = avnd_hctype_oper_req(cb, &param);
>>> +
>>> +done:
>>> +  return rc;
>>> +}
>>> +
>>> +/**
>>> + * IMM event handle, dispatch callback function for each changed attribute 
>>> in
>>> the current event.
>>> + *
>>> + * @param cb
>>> + * @param evt
>>> + *
>>> + * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
>>> + */
>>> +uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt) {
>>> +  AVSV_AMF_CLASS_ID type;
>>> +  uint32_t rc = NCSCC_RC_FAILURE;
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  AvndImmEvt *imm_evt = (AvndImmEvt*) evt->info.imm.imm_evt;
>>> +
>>> +  // TODO(uabhano) change object_name_to_class_type argument to
>>> std::string, then the SaNameT code below can be removed
>>> +  SaNameT obj_name;
>>> +  obj_name.length = imm_evt->get_object_name().size();
>>> +  memcpy((char*)obj_name.value, imm_evt->get_object_name().c_str(),
>>> obj_name.length);
>>> +  type = AvndImmUtil::object_name_to_class_type(&obj_name);
>>> +
>>> +  for (std::vector<SaImmAttrModificationT_2*>::const_iterator it = imm_evt-
>>>> begin(); it != imm_evt->end(); ++it) {
>>> +    const SaImmAttrModificationT_2 *imm_attr = *it;
>>> +    rc = AvndImm::update_callback_[type](imm_evt->get_object_name(),
>>> imm_attr);
>>> +  }
>>> +
>>> +  TRACE_LEAVE();
>>> +  return rc;
>>> +}
>>> +
>>> +/**
>>> + * Handle imm apply, create and send an AvndImmEvt object to the avnd main
>>> thread.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id
>>> +  */
>>> +void AvndImm::ccb_apply_cb(SaImmOiHandleT immoi_handle,
>>> SaImmOiCcbIdT ccb_id) {
>>> +  AVND_EVT_TYPE type = AVND_EVT_IMM;
>>> +
>>> +  AVND_EVT *evt = 0;
>>> +  const SaImmAttrModificationT_2 *mod;
>>> +  int i = 0;
>>> +  CcbUtilCcbData_t *ccb_util_ccb_data;
>>> +  CcbUtilOperationData_t *opdata = NULL;
>>> +  AvndImmEvt *imm_evt;
>>> +  uint32_t rc = NCSCC_RC_SUCCESS;
>>> +  AVND_CB *cb = avnd_cb;
>>> +
>>> +  TRACE_ENTER2("CCB ID %llu", ccb_id);
>>> +
>>> +  while ((opdata = ccbutil_getNextCcbOp(ccb_id, opdata)) != NULL) {
>>> +    imm_evt = new AvndImmEvt(opdata->objectName);
>>> +    while ((mod = opdata->param.modify.attrMods[i++]) != NULL) {
>>> +      imm_evt->set_mod_attr(*mod);
>>> +    }
>>> +
>>> +    i = 0;
>>> +
>>> +    /* create and send an event */
>>> +
>>> +    evt = new AVND_EVT();
>>> +
>>> +    evt->type = type;
>>> +    evt->priority = NCS_IPC_PRIORITY_NORMAL;
>>> +    evt->info.imm.imm_evt = imm_evt;
>>> +
>>> +    rc = m_NCS_IPC_SEND(&cb->mbx, evt, evt->priority);
>>> +    if (rc != NCSCC_RC_SUCCESS) {
>>> +      LOG_CR("AvND send event to mailbox failed, type = %u", evt->type);
>>> +    }
>>> +  }
>>> +
>>> +  /* Return CCB container memory */
>>> +  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
>>> +  osafassert(ccb_util_ccb_data);
>>> +  ccbutil_deleteCcbData(ccb_util_ccb_data);
>>> +
>>> +  TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * IMM modify callback, memorize the request.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id
>>> + * @param object_name
>>> + * @param attr_mods
>>> + *
>>> + * @return SA_AIS_OK or or SA_AIS_ERR_xx
>>> + */
>>> +SaAisErrorT AvndImm::ccb_object_modify_cb(SaImmOiHandleT
>>> immoi_handle,
>>> +   SaImmOiCcbIdT ccb_id, const SaNameT *object_name,
>>> +   const SaImmAttrModificationT_2 **attr_mods) {
>>> +  SaAisErrorT rc = SA_AIS_OK;
>>> +  struct CcbUtilCcbData *ccb_util_ccb_data;
>>> +
>>> +  TRACE_ENTER2("CCB ID %llu, %s", ccb_id, object_name->value);
>>> +
>>> +  if ((ccb_util_ccb_data = ccbutil_getCcbData(ccb_id)) != NULL) {
>>> +    /* "memorize the request" */
>>> +    if (ccbutil_ccbAddModifyOperation(ccb_util_ccb_data, object_name,
>>> attr_mods) != 0) {
>>> +      LOG_ER("Failed '%s'", object_name->value);
>>> +      rc = SA_AIS_ERR_BAD_OPERATION;
>>> +    }
>>> +  } else {
>>> +    LOG_ER("Failed to get CCB object for %llu", ccb_id);
>>> +    rc = SA_AIS_ERR_NO_MEMORY;
>>> +  }
>>> +
>>> +  TRACE_LEAVE();
>>> +
>>> +  return rc;
>>> +}
>>> +
>>> +/**
>>> + * IMM ccb abort callback.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id
>>> + */
>>> +void AvndImm::ccb_abort_cb(SaImmOiHandleT immoi_handle,
>>> SaImmOiCcbIdT ccb_id) {
>>> +  TRACE_ENTER();
>>> +
>>> +  CcbUtilCcbData_t *ccb_util_ccb_data;
>>> +
>>> +  /* Return CCB container memory */
>>> +  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
>>> +  osafassert(ccb_util_ccb_data);
>>> +  ccbutil_deleteCcbData(ccb_util_ccb_data);
>>> +
>>> +  TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * IMM ccb object delete callback.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id,
>>> + * @param object_name
>>> +  *
>>> + * @return SA_AIS_OK
>>> + */
>>> +SaAisErrorT AvndImm::ccb_object_delete_cb(SaImmOiHandleT
>>> immoi_handle,
>>> +   SaImmOiCcbIdT ccb_id, const SaNameT *object_name) {
>>> +
>>> +  TRACE_ENTER();
>>> +  TRACE_LEAVE();
>>> +
>>> +  return SA_AIS_OK;
>>> +}
>>> +
>>> +/**
>>> + * IMM ccb completed callback.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id,
>>> +   *
>>> + * @return SA_AIS_OK
>>> + */
>>> +SaAisErrorT AvndImm::ccb_completed_cb(SaImmOiHandleT immoi_handle,
>>> +   SaImmOiCcbIdT ccb_id) {
>>> +
>>> +  TRACE_ENTER();
>>> +  TRACE_LEAVE();
>>> +
>>> +  return SA_AIS_OK;
>>> +}
>>> +
>>> +/**
>>> + * IMM ccb object create callback.
>>> + *
>>> + * @param immoi_handle
>>> + * @param ccb_id
>>> + * @param class_name
>>> + * @param parent_name
>>> + * @param attr
>>> + *
>>> + * @return SA_AIS_OK
>>> + */
>>> +SaAisErrorT AvndImm::ccb_object_create_cb(SaImmOiHandleT
>>> immoi_handle,
>>> +   SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
>>> +   const SaNameT *parent_name, const SaImmAttrValuesT_2 **attr) {
>>> +
>>> +  TRACE_ENTER();
>>> +  TRACE_LEAVE();
>>> +
>>> +  return SA_AIS_OK;
>>> +}
>>> +
>>> +const SaImmOiCallbacksT_2 AvndImm::avnd_callbacks_ = {
>>> +  .saImmOiAdminOperationCallback = NULL,
>>> +  .saImmOiCcbAbortCallback = ccb_abort_cb,
>>> +  .saImmOiCcbApplyCallback = ccb_apply_cb,
>>> +  .saImmOiCcbCompletedCallback = ccb_completed_cb,
>>> +  .saImmOiCcbObjectCreateCallback = ccb_object_create_cb,
>>> +  .saImmOiCcbObjectDeleteCallback = ccb_object_delete_cb,
>>> +  .saImmOiCcbObjectModifyCallback = ccb_object_modify_cb,
>>> +  .saImmOiRtAttrUpdateCallback = NULL
>>> +};
>>> +
>>> +/**
>>> + * Set IMM applier.
>>> + *
>>> + * @return SA_AIS_OK or or SA_AIS_ERR_xx
>>> + */
>>> +SaAisErrorT AvndImm::imm_applier_set() {
>>> +  SaAisErrorT rc = SA_AIS_OK;
>>> +  uint32_t i;
>>> +  std::string applier_name = "@safAmfNodeDirector_";
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  char hostname[_POSIX_HOST_NAME_MAX];
>>> +  if (gethostname(hostname, _POSIX_HOST_NAME_MAX) == -1) {
>>> +    LOG_ER("gethostname failed: %s\n", strerror(errno));
>>> +
>>> +    /* use the node id of the node on which the AVD is running instead. */
>>> +    SaClmNodeIdT node_id_avnd = m_NCS_GET_NODE_ID;
>>> +    snprintf(hostname, _POSIX_HOST_NAME_MAX, "%x", node_id_avnd);
>>> +  }
>>> +
>>> +  applier_name += hostname;
>>> +
>>> +  LOG_NO("IMM applier name: %s", applier_name.c_str());
>>> +
>>> +  //
>>> +  if ((rc = immutil_saImmOiImplementerSet(immOiHandle_, (char*)
>>> applier_name.c_str())) != SA_AIS_OK) {
>>> +    LOG_ER("saImmOiImplementerSet failed %u", rc);
>>> +    return rc;
>>> +  }
>>> +
>>> +  //
>>> +  for (i = 0; i < AVND_SA_AMF_CLASS_MAX; i++) {
>>> +    if ((rc = immutil_saImmOiClassImplementerSet(immOiHandle_,
>>> avnd_class_names_[i])) != SA_AIS_OK) {
>>> +      LOG_ER("Impl Set Failed for %s, returned %d", avnd_class_names_[i], 
>>> rc);
>>> +      break;
>>> +    }
>>> +  }
>>> +
>>> +  TRACE_LEAVE();
>>> +
>>> +  return rc;
>>> +}
>>> +
>>> +/**
>>> + * Initialize IMM.
>>> + *
>>> + * @return SA_AIS_OK or or SA_AIS_ERR_xx
>>> + */
>>> +SaAisErrorT AvndImm::imm_init() {
>>> +  SaAisErrorT rc = SA_AIS_OK ;
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  for (int i = 0; i < AVSV_SA_AMF_CLASS_MAX; ++i) {
>>> +    update_callback_[i] = not_yet_implemented;
>>> +  }
>>> +
>>> +  update_callback_[AVSV_SA_AMF_HEALTH_CHECK_TYPE] =
>>> update_health_check_type;
>>> +
>>> +  /* Setup immutils profile once and for all */
>>> +  immutilWrapperProfile.errorsAreFatal = false;
>>> +  immutilWrapperProfile.retryInterval = 1000;
>>> +  immutilWrapperProfile.nTries = 180;
>>> +
>>> +  if ((rc = immutil_saImmOiInitialize_2(&immOiHandle_, &avnd_callbacks_,
>>> &immVersion_)) != SA_AIS_OK) {
>>> +    LOG_ER("saImmOiInitialize failed %u", rc);
>>> +    goto done;
>>> +  }
>>> +
>>> +  if ((rc = immutil_saImmOmInitialize(&immOmHandle_, NULL,
>>> &immVersion_)) != SA_AIS_OK) {
>>> +    LOG_ER("saImmOmInitialize failed %u", rc);
>>> +    goto done;
>>> +  }
>>> +
>>> +  if ((rc = immutil_saImmOiSelectionObjectGet(immOiHandle_,
>>> &imm_sel_obj_)) != SA_AIS_OK) {
>>> +    LOG_ER("saImmOiSelectionObjectGet failed %u", rc);
>>> +    goto done;
>>> +  }
>>> +
>>> +  TRACE("Successfully initialized IMM");
>>> +
>>> +done:
>>> +  TRACE_LEAVE();
>>> +
>>> +  return rc;
>>> +}
>>> +
>>> +/**
>>> + * IMM thread main function, waits for IMM events and dispatch callback
>>> functions.
>>> + */
>>> +void AvndImm::imm_main() {
>>> +  SaAisErrorT rc = SA_AIS_OK;
>>> +
>>> +  enum {
>>> +    FD_IMM = 0
>>> +  };
>>> +
>>> +  static nfds_t nfds = FD_IMM + 1;
>>> +  int polltmo = -1;
>>> +  static struct pollfd fds[FD_IMM + 1];
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  fds[FD_IMM].fd = imm_sel_obj_;
>>> +  fds[FD_IMM].events = POLLIN;
>>> +  nfds = FD_IMM + 1;
>>> +
>>> +  while (true) {
>>> +    int pollretval = poll(fds, nfds, polltmo);
>>> +
>>> +    if (pollretval == -1) {
>>> +      if (errno == EINTR)
>>> +        continue;
>>> +
>>> +      LOG_ER("main: poll FAILED - %s", strerror(errno));
>>> +      break;
>>> +    }
>>> +
>>> +    if (immOiHandle_ && fds[FD_IMM].revents & POLLIN) {
>>> +      TRACE("IMM event rec");
>>> +      rc = saImmOiDispatch(immOiHandle_, SA_DISPATCH_ALL);
>>> +      if (rc != SA_AIS_OK) {
>>> +        LOG_ER("saImmOiDispatch failed: %d", rc);
>>> +
>>> +      }
>>> +    }
>>> +  }
>>> +
>>> +  TRACE_LEAVE();
>>> +}
>>> +
>>> +/**
>>> + * IMM thread start function. Init IMM and set as applier.
>>> + *
>>> + * @return 0
>>> + */
>>> +void *AvndImm::imm_start(void *) {
>>> +  SaAisErrorT rc = SA_AIS_OK;
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  if ((rc = imm_init()) != SA_AIS_OK) {
>>> +    LOG_ER("avnd_imm_init FAILED");
>>> +    goto done;
>>> +  }
>>> +
>>> +  if ((rc = imm_applier_set()) != SA_AIS_OK) {
>>> +    LOG_ER("avnd_imm_applier set FAILED");
>>> +    goto done;
>>> +  }
>>> +
>>> +  imm_main();
>>> +
>>> +done:
>>> +
>>> +  return 0;
>>> +}
>>> +
>>> +/**
>>> + * Create IMM thread for applier functionality.
>>> + *
>>> + * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
>>> + */
>>> +uint32_t avnd_create_imm_thread() {
>>> +  uint32_t rc = NCSCC_RC_SUCCESS;
>>> +  pthread_t thread;
>>> +  pthread_attr_t attr;
>>> +
>>> +  TRACE_ENTER();
>>> +
>>> +  pthread_attr_init(&attr);
>>> +  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
>>> +
>>> +  if (pthread_create(&thread, &attr, AvndImm::imm_start, 0) != 0) {
>>> +    LOG_ER("pthread_create FAILED: %s", strerror(errno));
>>> +    rc = NCSCC_RC_FAILURE;
>>> +  }
>>> +
>>> +  pthread_attr_destroy(&attr);
>>> +
>>> +  TRACE_LEAVE();
>>> +
>>> +  return rc;
>>> +}
>>> +
>>> diff --git a/osaf/services/saf/amf/amfnd/include/Makefile.am
>>> b/osaf/services/saf/amf/amfnd/include/Makefile.am
>>> --- a/osaf/services/saf/amf/amfnd/include/Makefile.am
>>> +++ b/osaf/services/saf/amf/amfnd/include/Makefile.am
>>> @@ -29,6 +29,7 @@ noinst_HEADERS = \
>>>      avnd_evt.h \
>>>      avnd.h \
>>>      avnd_hc.h \
>>> +   avnd_imm.h \
>>>      avnd_mds.h \
>>>      avnd_mon.h \
>>>      avnd_pg.h \
>>> diff --git a/osaf/services/saf/amf/amfnd/include/avnd.h
>>> b/osaf/services/saf/amf/amfnd/include/avnd.h
>>> --- a/osaf/services/saf/amf/amfnd/include/avnd.h
>>> +++ b/osaf/services/saf/amf/amfnd/include/avnd.h
>>> @@ -34,6 +34,7 @@
>>>   #define AVND_H
>>>
>>>   #include <saImmOm.h>
>>> +#include <saImmOi.h>
>>>
>>>   #include "amf.h"
>>>   #include "ncs_main_papi.h"
>>> diff --git a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
>>> b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
>>> --- a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
>>> +++ b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
>>> @@ -110,6 +110,8 @@ typedef enum avnd_evt_type {
>>>     AVND_EVT_PID_EXIT,
>>>     AVND_EVT_TMR_QSCING_CMPL,
>>>
>>> +   AVND_EVT_IMM,
>>> +
>>>     AVND_EVT_MAX
>>>   } AVND_EVT_TYPE;
>>>
>>> @@ -155,6 +157,11 @@ typedef struct avnd_pm_mon_evt {
>>>     AVND_COMP_PM_REC *pm_rec;
>>>   } AVND_PM_MON_EVT;
>>>
>>> +/* imm event definition */
>>> +typedef struct avnd_imm_evt {
>>> +   void *imm_evt; /* AvndImmEvt ptr */
>>> +} AVND_IMM_EVT;
>>> +
>>>   /* AVND top-level event structure */
>>>   typedef struct avnd_evt_tag {
>>>     struct avnd_evt_tag *next;
>>> @@ -173,6 +180,7 @@ typedef struct avnd_evt_tag {
>>>             AVND_CLC_EVT clc;
>>>             AVND_COMP_FSM_EVT comp_fsm;
>>>             AVND_PM_MON_EVT pm_evt;
>>> +           AVND_IMM_EVT imm;
>>>     } info;
>>>
>>>   } AVND_EVT;
>>> diff --git a/osaf/services/saf/amf/amfnd/include/avnd_hc.h
>>> b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
>>> --- a/osaf/services/saf/amf/amfnd/include/avnd_hc.h
>>> +++ b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
>>> @@ -59,5 +59,6 @@ extern SaAisErrorT avnd_hc_config_get(st
>>>   extern SaAisErrorT avnd_hctype_config_get(SaImmHandleT immOmHandle,
>>> const SaNameT *comptype_dn);
>>>   extern AVND_HCTYPE *avnd_hctypedb_rec_get(const SaNameT
>>> *comp_type_dn, const SaAmfHealthcheckKeyT *key);
>>>   extern uint32_t avnd_hc_oper_req(struct avnd_cb_tag *, AVSV_PARAM_INFO
>>> *param);
>>> +extern uint32_t avnd_hctype_oper_req(struct avnd_cb_tag *,
>>> AVSV_PARAM_INFO *param);
>>>
>>>   #endif   /* !AVND_HC_H */
>>> diff --git a/osaf/services/saf/amf/amfnd/include/avnd_imm.h
>>> b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
>>> new file mode 100644
>>> --- /dev/null
>>> +++ b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
>>> @@ -0,0 +1,148 @@
>>> +/*      -*- OpenSAF  -*-
>>> + *
>>> + * (C) Copyright 2014 The OpenSAF Foundation
>>> + *
>>> + * This program is distributed in the hope that it will be useful, but
>>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>>> MERCHANTABILITY
>>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
>>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>>> + * The complete license can be accessed from the following location:
>>> + * http://opensource.org/licenses/lgpl-license.php
>>> + * See the Copying file included with the OpenSAF distribution for full
>>> + * licensing terms.
>>> + *
>>> + * Author(s): Ericsson AB
>>> + *
>>> + */
>>> +
>>> +/***********************************************************
>>> ******************
>>> +  DESCRIPTION:
>>> +
>>> +  Classes used for implementing AMF node director as an IMM applier.
>>> +
>>> +
>>> *************************************************************
>>> *****************
>>> + */
>>> +
>>> +#ifndef AVND_IMM_H
>>> +#define    AVND_IMM_H
>>> +
>>> +#ifdef __cplusplus
>>> +
>>> +#include <vector>
>>> +#include <string>
>>> +#include "avnd.h"
>>> +
>>> +//
>>> +typedef enum {
>>> +  AVND_SA_AMF_HEALTH_CHECK_TYPE = 0,
>>> +  AVND_SA_AMF_CLASS_MAX
>>> +} AVND_AMF_CLASS_ID;
>>> +
>>> +//--------------------------------------------------------------------------
>>> +// < \ingroup avndImm
>>> +//
>>> +// This class is used as a container for one IMM modify callback.
>>> +// >
>>> +//--------------------------------------------------------------------------
>>> +class AvndImmEvt {
>>> +public:
>>> +  //
>>> +  explicit AvndImmEvt(const SaNameT& obj_name) : object_name_((const
>>> char*) obj_name.value, obj_name.length) {}
>>> +
>>> +  //
>>> +  ~AvndImmEvt();
>>> +
>>> +  //
>>> +  std::string get_object_name() {return object_name_;}
>>> +
>>> +  //
>>> +  void set_mod_attr(const SaImmAttrModificationT_2& attr);
>>> +
>>> +  //
>>> +  typedef typename std::vector<SaImmAttrModificationT_2*>::const_iterator
>>> const_iterator;
>>> +  const_iterator begin() const {return attr_.begin();}
>>> +  const_iterator end() const {return attr_.end();}
>>> +
>>> +private:
>>> +  //
>>> +  AvndImmEvt(const AvndImmEvt&);
>>> +  void operator=(const AvndImmEvt&);
>>> +
>>> +  std::string object_name_;
>>> +
>>> +  std::vector<SaImmAttrModificationT_2*> attr_;
>>> +};
>>> +
>>> +//--------------------------------------------------------------------------
>>> +// < \ingroup avndImm
>>> +//
>>> +// This class contains utility functions for IMM.
>>> +// >
>>> +//--------------------------------------------------------------------------
>>> +class AvndImmUtil {
>>> +public:
>>> +  //
>>> +  static void deleteSaImmAttrValuesT(SaImmAttrValuesT_2& attr_value);
>>> +  static void copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const
>>> SaImmAttrValuesT_2& from);
>>> +  static char *str_dup(const char *str);
>>> +  static size_t value_size(SaImmValueTypeT attrValueType);
>>> +  static AVSV_AMF_CLASS_ID object_name_to_class_type(const SaNameT*
>>> obj_name);
>>> +  static void remove_attr(SaImmAttrModificationT_2* attr);
>>> +private:
>>> +  AvndImmUtil();
>>> +  AvndImmUtil(const AvndImmUtil&);
>>> +  void operator=(const AvndImmUtil&);
>>> +};
>>> +
>>> +//--------------------------------------------------------------------------
>>> +// < \ingroup avndImm
>>> +//
>>> +// This class contains IMM callback, init and set functions.
>>> +// >
>>> +//--------------------------------------------------------------------------
>>> +class AvndImm {
>>> + public:
>>> +  //
>>> +  typedef uint32_t (*UpdateFn) (const std::string& dn, const
>>> SaImmAttrModificationT_2* attr);
>>> +
>>> +  //
>>> +  static void ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT
>>> ccb_id);
>>> +  static SaAisErrorT ccb_object_delete_cb(SaImmOiHandleT immoi_handle,
>>>     SaImmOiCcbIdT ccb_id, const SaNameT *object_name);
>>> +  static void ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT
>>> ccb_id);
>>> +  static SaAisErrorT ccb_completed_cb(SaImmOiHandleT immoi_handle,
>>> SaImmOiCcbIdT ccb_id);
>>> +  static SaAisErrorT ccb_object_create_cb(SaImmOiHandleT immoi_handle,
>>> SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
>>> +                                          const SaNameT *parent_name, const
>>> SaImmAttrValuesT_2 **attr);
>>> +  static SaAisErrorT ccb_object_modify_cb(SaImmOiHandleT immoi_handle,
>>> SaImmOiCcbIdT ccb_id, const SaNameT *object_name, const
>>> SaImmAttrModificationT_2 **attr_mods);
>>> +  static void *imm_start(void *);
>>> +
>>> +  //
>>> +  static uint32_t not_yet_implemented(const std::string& object_name, const
>>> SaImmAttrModificationT_2* imm_attr);
>>> +  static uint32_t update_health_check_type(const std::string& object_name,
>>> const SaImmAttrModificationT_2* imm_attr);
>>> +
>>> +  //
>>> +  static SaVersionT immVersion_;
>>> +  static SaImmOiHandleT immOiHandle_;
>>> +  static SaImmOiHandleT immOmHandle_;
>>> +  static SaSelectionObjectT imm_sel_obj_;
>>> +  static UpdateFn update_callback_[AVSV_SA_AMF_CLASS_MAX];
>>> +  static const char *avnd_class_names_[];
>>> + private:
>>> +  static SaAisErrorT imm_init();
>>> +  static void imm_main();
>>> +  static SaAisErrorT imm_applier_set();
>>> +  static const SaImmOiCallbacksT_2 avnd_callbacks_;
>>> +
>>> +  //
>>> +  AvndImm();
>>> +  AvndImm(const AvndImmUtil&);
>>> +  void operator=(const AvndImm&);
>>> +};
>>> +
>>> +//
>>> +extern uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt);
>>> +extern uint32_t avnd_create_imm_thread();
>>> +
>>> +#endif /* __cplusclpus */
>>> +
>>> +#endif     /* AVND_IMM_H */
>>> +
>>> diff --git a/osaf/services/saf/amf/amfnd/main.cc
>>> b/osaf/services/saf/amf/amfnd/main.cc
>>> --- a/osaf/services/saf/amf/amfnd/main.cc
>>> +++ b/osaf/services/saf/amf/amfnd/main.cc
>>> @@ -31,6 +31,7 @@
>>>   #include "immutil.h"
>>>   #include "logtrace.h"
>>>   #include "nid_api.h"
>>> +#include "avnd_imm.h"
>>>
>>>   #define FD_MBX   0
>>>   #define FD_TERM  1
>>> @@ -117,7 +118,8 @@ extern const AVND_EVT_HDLR g_avnd_func_l
>>>     avnd_evt_comp_pres_fsm_evh,     /* AVND_EVT_COMP_PRES_FSM_EV
>>> */
>>>     avnd_evt_last_step_term_evh,    /* AVND_EVT_LAST_STEP_TERM */
>>>     avnd_evt_pid_exit_evh,  /* AVND_EVT_PID_EXIT */
>>> -   avnd_evt_tmr_qscing_cmpl_evh    /*
>>> AVND_EVT_TMR_QSCING_CMPL */
>>> +   avnd_evt_tmr_qscing_cmpl_evh,   /*
>>> AVND_EVT_TMR_QSCING_CMPL */
>>> +   avnd_evt_imm_evh                /* AVND_EVT_IMML */
>>>   };
>>>
>>>   /* global task handle */
>>> @@ -273,6 +275,12 @@ uint32_t avnd_create(void)
>>>             rc = NCSCC_RC_FAILURE;
>>>             goto done;
>>>     }
>>> +
>>> +   rc = avnd_create_imm_thread();
>>> +   if (NCSCC_RC_SUCCESS != rc) {
>>> +           rc = NCSCC_RC_FAILURE;
>>> +           goto done;
>>> +   }
>>>
>>>   done:
>>>     TRACE_LEAVE();


------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to