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 *)¶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 Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel