Hi Hung, Reviewed and tested the patch. Ack from me.
Best regards, Zoran -----Original Message----- From: Hung Nguyen [mailto:hung.d.ngu...@dektech.com.au] Sent: Wednesday, December 23, 2015 10:12 AM To: Zoran Milinkovic; reddy.neelaka...@oracle.com Cc: opensaf-devel@lists.sourceforge.net Subject: [PATCH 1 of 1] imm: Canonicalize attributes presented by OiCcbObjectModifyCallback [#801] osaf/services/saf/immsv/immnd/ImmModel.cc | 100 +++++++++++++++++++++++ osaf/services/saf/immsv/immnd/ImmModel.hh | 7 + osaf/services/saf/immsv/immnd/immnd_evt.c | 49 +++++++++- osaf/services/saf/immsv/immnd/immnd_init.h | 2 + osaf/services/saf/immsv/immpbed/immpbe_daemon.cc | 4 + 5 files changed, 155 insertions(+), 7 deletions(-) If the modType is SA_IMM_ATTR_VALUES_ADD or SA_IMM_ATTR_VALUES_DELETE, it will be converted to SA_IMM_ATTR_VALUES_REPLACE and the values of the attr-mod will be the values in the after image. This feature is only for OIs with version A.2.17 or later so we don't modify the content of incoming IMMND_EVT_A2ND_OBJ_MODIFY messages. New memory is allocated for canonicalized attribute-modifications instead. PBE will also receive canonicalized attMods. OIs and appliers which are initialized as A.2.17 or later MUST support SA_IMM_ATTR_VALUES_REPLACE in their callbacks. diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc b/osaf/services/saf/immsv/immnd/ImmModel.cc --- a/osaf/services/saf/immsv/immnd/ImmModel.cc +++ b/osaf/services/saf/immsv/immnd/ImmModel.cc @@ -717,6 +717,11 @@ immModel_genSpecialModify(IMMND_CB *cb, genSpecialModify(req); } +struct immsv_attr_mods_list* +immModel_canonicalizeAttrModification(IMMND_CB *cb, const struct ImmsvOmCcbObjectModify *req) +{ + return ImmModel::instance(&cb->immModel)->canonicalizeAttrModification(req); +} SaUint32T immModel_getLocalAppliersForObj(IMMND_CB *cb, @@ -6997,6 +7002,101 @@ ImmModel::specialApplierTrimCreate(SaUin return attrValues; } +/* This function converts value(s) of an attribute into a single attr-mod. + * attrModType is always SA_IMM_ATTR_VALUES_REPLACE. + */ +immsv_attr_mods_list* +ImmModel::attrValueToAttrMod(const ObjectInfo* obj, const std::string& attrName, + SaUint32T attrType) +{ + ImmAttrValueMap::const_iterator avi = obj->mAttrValueMap.find(attrName); + osafassert(avi != obj->mAttrValueMap.end()); + ImmAttrValue* attrValue = avi->second; + + immsv_attr_mods_list* attrMod = (immsv_attr_mods_list*) calloc(1, sizeof(immsv_attr_mods_list)); + osafassert(attrMod); + attrMod->attrModType = SA_IMM_ATTR_VALUES_REPLACE; + + /* attrValue.attrValueType */ + attrMod->attrValue.attrValueType = attrType; + + /* attrValue.attrName */ + attrMod->attrValue.attrName.size = strlen(attrName.c_str()) + 1; + attrMod->attrValue.attrName.buf = (char*) malloc(attrMod->attrValue.attrName.size); + osafassert(attrMod->attrValue.attrName.buf); + strncpy(attrMod->attrValue.attrName.buf, attrName.c_str(), attrMod->attrValue.attrName.size); + + /* attrValue.attrValuesNumber, attrValue.attrValue and attrValue.attrMoreValues */ + attrMod->attrValue.attrValuesNumber = 0; + if (!attrValue->empty()) { + attrValue->copyValueToEdu(&(attrMod->attrValue.attrValue), (SaImmValueTypeT) attrType); + if (attrValue->extraValues()) { + ImmAttrMultiValue* multiVal = (ImmAttrMultiValue *) attrValue; + multiVal->copyExtraValuesToEdu(&(attrMod->attrValue.attrMoreValues), (SaImmValueTypeT) attrType); + } + attrMod->attrValue.attrValuesNumber = 1 + attrValue->extraValues(); + } /* else, attrValuesNumber is already set to 0 */ + + return attrMod; +} + +/* This function allocates new memory for canonicalized attribute-modifications. + * The 'attrMods' of input ImmsvOmCcbObjectModify remains untouched. + * Remember to free the memory with immsv_free_attrmods(). + */ +immsv_attr_mods_list* +ImmModel::canonicalizeAttrModification(const ImmsvOmCcbObjectModify *req) +{ + TRACE_ENTER(); + immsv_attr_mods_list* result = NULL; + std::string objectName; + CcbVector::iterator ci; + CcbInfo* ccb = NULL; + ObjectInfo* afim = NULL; + ObjectMutationMap::iterator omuti; + ObjectMutation* oMut = NULL; + + /* Get object Name */ + size_t sz = strnlen(req->objectName.buf, (size_t) req->objectName.size); + objectName.append((const char*) req->objectName.buf, sz); + osafassert(!objectName.empty()); + + /* Get ccb info */ + ci = std::find_if(sCcbVector.begin(), sCcbVector.end(), CcbIdIs(req->ccbId)); + osafassert(ci != sCcbVector.end()); + ccb = *ci; + + /* Get object mutation */ + omuti = ccb->mMutations.find(objectName); + osafassert(omuti != ccb->mMutations.end()); + oMut = omuti->second; + + /* Get after image */ + osafassert(oMut->mOpType != IMM_DELETE); + if (oMut->mOpType == IMM_CREATE) { /* Chained operation */ + ObjectMap::iterator oi = sObjectMap.find(objectName); + osafassert(oi != sObjectMap.end()); + afim = oi->second; + } else if (oMut->mOpType == IMM_MODIFY) { + afim = oMut->mAfterImage; + } + + /* Build canonicalized attr-mod list */ + immsv_attr_mods_list* reqAttrMods = req->attrMods; + for (; reqAttrMods; reqAttrMods = reqAttrMods->next) { + size_t sz = strnlen(reqAttrMods->attrValue.attrName.buf, + (size_t) reqAttrMods->attrValue.attrName.size); + std::string attrName((const char *) reqAttrMods->attrValue.attrName.buf, sz); + immsv_attr_mods_list* attrMod = attrValueToAttrMod(afim, attrName, + reqAttrMods->attrValue.attrValueType); + attrMod->next = result; + result = attrMod; + } + + TRACE_LEAVE(); + return result; +} + /** * Creates an object */ diff --git a/osaf/services/saf/immsv/immnd/ImmModel.hh b/osaf/services/saf/immsv/immnd/ImmModel.hh --- a/osaf/services/saf/immsv/immnd/ImmModel.hh +++ b/osaf/services/saf/immsv/immnd/ImmModel.hh @@ -239,6 +239,9 @@ public: SaUint32T ccbId, ConnVector& connVector, SaUint32T* appCtnPtr); + + immsv_attr_mods_list* canonicalizeAttrModification( + const struct ImmsvOmCcbObjectModify *req); SaAisErrorT ccbObjectModify( const ImmsvOmCcbObjectModify* req, @@ -709,6 +712,10 @@ private: ObjectInfo *obj, const char *noDanglingRef); + immsv_attr_mods_list* attrValueToAttrMod(const ObjectInfo* obj, + const std::string& attrName, + SaUint32T attrType); + }; #endif diff --git a/osaf/services/saf/immsv/immnd/immnd_evt.c b/osaf/services/saf/immsv/immnd/immnd_evt.c --- a/osaf/services/saf/immsv/immnd/immnd_evt.c +++ b/osaf/services/saf/immsv/immnd/immnd_evt.c @@ -6212,6 +6212,8 @@ static void immnd_evt_proc_object_modify SaNameT objName; osaf_extended_name_clear(&objName); bool hasLongDns=false; + IMMSV_ATTR_MODS_LIST* canonicalizedAttrMod = NULL; + TRACE_ENTER(); #if 0 /*ABT DEBUG PRINTOUTS START */ TRACE_2("ABT immnd_evt_proc_object_modify object:%s", evt->info.objModify.objectName.buf); @@ -6271,6 +6273,8 @@ static void immnd_evt_proc_object_modify /* PBE is internal => can handle long DNs */ send_evt.info.imma.type = IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC; send_evt.info.imma.info.objModify = evt->info.objModify; + canonicalizedAttrMod = immModel_canonicalizeAttrModification(cb, &(evt->info.objModify)); + send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod; send_evt.info.imma.info.objModify.adminOwnerId = 0; /*We re-use the adminOwner member of the ccbModify message to hold the invocation id. In this case, 0 => no reply is expected. */ @@ -6317,6 +6321,17 @@ static void immnd_evt_proc_object_modify IMMA_EVT_ND2A_OI_OBJ_MODIFY_LONG_UC : IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC; send_evt.info.imma.info.objModify = evt->info.objModify; + + /* For A.2.17 or later */ + if (oi_cl_node->version.minorVersion >= 0x11 && + oi_cl_node->version.majorVersion == 0x2 && + oi_cl_node->version.releaseCode == 'A') { + if (!canonicalizedAttrMod) { /* Check if canonicalizedAttrMod is already built */ + canonicalizedAttrMod = immModel_canonicalizeAttrModification(cb, &(evt->info.objModify)); + } + send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod; + } + /* shallow copy into stack alocated structure. */ send_evt.info.imma.info.objModify.adminOwnerId = continuationId; @@ -6358,6 +6373,8 @@ static void immnd_evt_proc_object_modify invocation id. In this case, 0 => no reply is expected. */ for (; ix < arrSize && err == SA_AIS_OK; ++ix) { + bool isSpecialApplier = false; + send_evt.info.imma.info.objModify.attrMods = evt->info.objModify.attrMods; implHandle = m_IMMSV_PACK_HANDLE(applConnArr[ix], cb->node_id); send_evt.info.imma.info.objModify.immHandle = implHandle; @@ -6367,14 +6384,35 @@ static void immnd_evt_proc_object_modify If not special applier, then attribute-list will be untouched since the last applier is then a regular applier. */ - evt->info.objModify.attrMods = send_evt.info.imma.info.objModify.attrMods = + send_evt.info.imma.info.objModify.attrMods = immModel_specialApplierTrimModify(cb, applConnArr[ix], &(evt->info.objModify)); + /* If attrMods of 'send_evt' is different from attrMods of 'evt' + * then we are sending to the special applier. */ + if (send_evt.info.imma.info.objModify.attrMods != evt->info.objModify.attrMods) { + isSpecialApplier = true; + evt->info.objModify.attrMods = send_evt.info.imma.info.objModify.attrMods; + } } /*Fetch client node for Applier OI ! */ immnd_client_node_get(cb, implHandle, &oi_cl_node); osafassert(oi_cl_node != NULL); + + /* For A.2.17 or later */ + if (!isSpecialApplier && + oi_cl_node->version.minorVersion >= 0x11 && + oi_cl_node->version.majorVersion == 0x2 && + oi_cl_node->version.releaseCode == 'A') { + if (!canonicalizedAttrMod) { /* Check if canonicalizedAttrMod is already built */ + canonicalizedAttrMod = immModel_canonicalizeAttrModification(cb, &(evt->info.objModify)); + } + send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod; + } + /* Slave pbe is initialized with latest OI api version, + * it will also receive canonicalized attrMod like the primary pbe + */ + if (oi_cl_node->mIsStale) { LOG_WA("Applier client went down so modify upcall not sent"); continue; @@ -6416,12 +6454,9 @@ static void immnd_evt_proc_object_modify } done: - /*Free the incomming events substructure. */ - free(evt->info.objModify.objectName.buf); - evt->info.objModify.objectName.buf = NULL; - evt->info.objModify.objectName.size = 0; - immsv_free_attrmods(evt->info.objModify.attrMods); - evt->info.objModify.attrMods = NULL; + /* Free the canonicalized attr mods */ + immsv_free_attrmods(canonicalizedAttrMod); + canonicalizedAttrMod = NULL; osaf_extended_name_free(&objName); TRACE_LEAVE(); } diff --git a/osaf/services/saf/immsv/immnd/immnd_init.h b/osaf/services/saf/immsv/immnd/immnd_init.h --- a/osaf/services/saf/immsv/immnd/immnd_init.h +++ b/osaf/services/saf/immsv/immnd/immnd_init.h @@ -296,6 +296,8 @@ extern "C" { void immModel_genSpecialModify(IMMND_CB *cb, struct ImmsvOmCcbObjectModify *req); + struct immsv_attr_mods_list* + immModel_canonicalizeAttrModification(IMMND_CB *cb, const struct ImmsvOmCcbObjectModify *req); SaBoolT immModel_protocol41Allowed(IMMND_CB *cb); SaBoolT immModel_protocol43Allowed(IMMND_CB *cb); diff --git a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc --- a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc +++ b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc @@ -136,6 +136,10 @@ static SaAisErrorT sqlite_prepare_ccb(Sa TRACE("Modify of object with DN: %s", osaf_extended_name_borrow(ccbUtilOperationData->param.modify.objectName)); + /* Pbe receives canonicalized attrMod for config-object modifications (CCB) + * but it still receive normal attrMod for runtime-object modifications (updating PRTA). + * So we have to support all kinds of SaImmAttrModificationTypeT here. + */ objName.append(osaf_extended_name_borrow(ccbUtilOperationData-> param.modify.objectName)); attrMods = ccbUtilOperationData->param.modify.attrMods; ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel