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).
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.
3. It has lots of code duplicity and maintenance.
Thanks
-Nagu
> -----Original Message-----
> From: Hans Nordeback [mailto:[email protected]]
> Sent: 28 May 2014 14:27
> To: [email protected]; Nagendra Kumar; Praveen Malviya
> Cc: [email protected]
> 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 *)¶m->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(¶m, 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, ¶m);
> +
> +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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel