Hi AndersBj/Hung, The present #801 may be handled for only Canonicalize attributes presented by OiCcbObjectModifyCallback.
Sending All attributes including NOT writable attributes is debatable and not backward compatible for appliers also. A new Enhancement ticket may be opened which talks about sending all attribute to appliers or for both appliers and OIs. Thanks, Neel. On Thursday 17 December 2015 06:44 PM, Anders Bjornerstedt wrote: > H iNeel, > Comments inline. > > >> ----Ursprungligt meddelande---- >> Från : [email protected] >> Datum : 17-12-2015 - 12:48 (GMT) >> Till : [email protected], [email protected] >> Kopia : [email protected] >> Ämne : Re: [devel] [PATCH 1 of 1] imm: Canonicalize attributes presented by >> OiCcbObjectModifyCallback [#801] >> >> Hi AndersBj, >> >> 1. In the previous discussion, the following is the differentiation >> between OI and applier: >> >> snippet from previous discussion: >> >> Converning point (c): I would say that how light or heavy an appplier vs OI >> is is completely up to the developers of these functions. >> They should preferrably get the same callbacks with the same contents as the >> OI unless there is a very good reason to break that rule. >> The reason is the old KISS rule. Not folowing it will result in the average >> OI/applier developer getting it wrong. As we all know the average >> developer does not read much if any documentation, unless they really run >> into problems... > In this case we have a good reason to very slightly "break the rule". > By "very slightly" I mean that we are not breaking any rule of ligical > equivalence. > The only "rule" we would be breaking by sending all attributes to appliers > (if they have initialized with the latest release) > is a a silly "rule" that says that the actual set of values at every instance > of a cllaback has to be the same. > That is a much much stromnger rule and I claim it is unnecesarily restrictive. > It has the disadvantage that we would not be allowed to treat the applier in > any way diferently (in the callbacks) despite the fact > that it is already treated differently. Appliers can not reply to the > callbacks and appliers are not supposed to validate. > We should avoid making things more different and complex than they need to be. > But we should not be afraid to make some differences if tyhose differences > actually simplify the job of the eveloper. > >> 2. Going by the real usage of(OI and applier) this (in middleware >> services AMF ) : >> >> The code for active and standby(where applier) has similar code. >> The only difference is the standby(applier) will not validate. > So how would the AMF applier have a problem with receiving all the values ? > Have you actually looked at the AMF code and checked this ? > I suspect (but I have not checked) that the only problem the AMF applier has > is that it can not handle > receiving values for NOT writable attributes, even when those values are > identical to the existing ones. > That is a minor issue in the AMF applier and is very easy to fix. > The advantage is that we solve the applier initialization prooblem which is a > really hard problem currently with no > no good solution. The AMF OI will not be impacted as long as it does not > increas its API version. > >> 3. If the writable attributes are not sent, still applier want to >> initialize then the applier has to read using searchnext/accessorget . >> Then, sending all writable attributes may not be useful as intended. > I think you mean "if the NOT writable attributes are not sent" or ? > I am actually saying that all attributes including NOT writable attributes > could be sent to appliers. > An applier that initializes with the latest version will only do so because > it wants to get what that new version > provides. It will then know that it is getting the after value of all > attributes. > That would solve the initialization problem for appliers and the applier > would know that if the attribute is not writable > then the received value must be the same as any previous one. It could even > assert on such an equality check, except when > it is initializing. > > So in summary. > I just dont see what the AMFs big hangup is with this. Why the AMF has to > prevent a solution for the initialization pproblem for > ALL appliers for ALL future just becausee iit parhaps has some extra > ooverzealos check that can be removed the day the AMF wants > to uppgrade its OI. > > /AndersBj > >> Thanks, >> Neel. >> >> >> On Thursday 17 December 2015 05:27 PM, Anders Bjornerstedt wrote: >>> Hi >>> >>> (having problems getting through to the list). >>> >>> I think Hungs's opatch was/is ok. Otherwise i would have commented it. >>> >>> Point (1) as I see it should be taken in the sense of logic, not of >>> conctent. >>> Thus the basic logic for correctly receiving the callback should be the >>> same in both OI anbd applier. >>> But the content (values actually received) does not necessarily have to be >>> the same. >>> Specifically, the applier should not do any validation or checking of the >>> values. >>> The applier should always simply record the values and apply them if/when >>> it receives the apply callback. >>> The completed callback has no meaning for appliers. >>> >>> Point (2) as I believe to drop sending all values to the regular OI. >>> It was not necessary to drop sendiing all values to apppliers. >>> Neel if you see some problem with this then please explain what that >>> problem would be. >>> The only possible problem I could see is if a value appears for an >>> attribute that does not have the writable flag >>> and the applier checks against tthat. But the applier should not do such >>> checking anyway. It is not the appliers >>> job to do so. In addition if it really did check the value it would >>> discover that it was the same value as the current one, >>> i.e. no change logically. So even if the aplier did "validate" (which it >>> should not do) it should still not have a logical problem >>> with the value. >>> >>> The significant *advantage* with getting all values in the applier callback >>> I have already explained. >>> It solves the initialization pproblem. >>> >>> I dont see any point in adding this feature later, if we have it >>> implemented now. >>> If there is a "problem" in adding this now with the version check in olace, >>> then there will always be a problem and it will >>> never get added. Converesely If there is a problem now it would only be for >>> an applier that explicitly sets to the new API version >>> and such an applier has oovverzealous checking of the type reject a >>> replacement with the same value as the current one for >>> attributes that dont have the writable flag set. >>> >>> /AndersBj >>> >>>> ----Ursprungligt meddelande---- >>>> Från : [email protected] >>>> Datum : 17-12-2015 - 10:37 (GMT) >>>> Till : [email protected], [email protected] >>>> Kopia : [email protected] >>>> Ämne : Re: [devel] [PATCH 1 of 1] imm: Canonicalize attributes presented >>>> by OiCcbObjectModifyCallback [#801] >>>> >>>> Hi Neel, >>>> >>>> I misunderstood the discussion, I will fix that. >>>> >>>> In future, do you think we will implement that >>>> sending-all-writable-attributes feature? >>>> If so, I will keep the code for canonicalizing all writable attributes. We >>>> just simply don't use it for now. >>>> Otherwise, I will clean up the unused code. >>>> >>>> Thanks, >>>> >>>> Hung Nguyen - DEK Technologies >>>> >>>> >>>> -------------------------------------------------------------------------------- >>>> From: Neelakanta Reddy [email protected] >>>> Sent: Thursday, December 17, 2015 5:02PM >>>> To: Hung Nguyen, Zoran Milinkovic >>>> [email protected], [email protected] >>>> Cc: Opensaf-devel >>>> [email protected] >>>> Subject: Re: [PATCH 1 of 1] imm: Canonicalize attributes presented by >>>> OiCcbObjectModifyCallback [#801] >>>> >>>> >>>> Hi Hung, >>>> >>>> The following is the final conclusion from the discussion and from >>>> AndersBj( view point): >>>> >>>> 1. Both Appliers and implementer "*must*" receive the same >>>> modification values for modify callback. >>>> 2. The "final" proposal below was to drop the notion of sending all >>>> values. >>>> 3. The only change the enhancement should consider is, for modify >>>> callback for appliers and implementers from A.2.17 will have atrrModType >>>> as SA_IMM_ATTR_VALUES_REPLACE. Only modify attributes must be sent to >>>> modifycallback. Only afterimage values must be sent through modify >>>> callback. >>>> >>>> The published patch has : >>>> a. For applier modify callback all writable attributes are sent (this >>>> violates point 1 above) >>>> b. The, PBE must also be compatible with new changes and the PBE >>>> callback must also be sent with canonicalize attributes. >>>> >>>> /Neel. >>>> >>>> >>>> On Monday 14 December 2015 03:02 PM, Hung Nguyen wrote: >>>>> osaf/services/saf/immsv/immnd/ImmModel.cc | 142 >>>>> +++++++++++++++++++++++++++++ >>>>> osaf/services/saf/immsv/immnd/ImmModel.hh | 8 + >>>>> osaf/services/saf/immsv/immnd/immnd_evt.c | 66 +++++++++++- >>>>> osaf/services/saf/immsv/immnd/immnd_init.h | 2 + >>>>> 4 files changed, 209 insertions(+), 9 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. >>>>> >>>>> 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, bool allWritable, bool* hasLongDns) >>>>> +{ >>>>> + return >>>>> ImmModel::instance(&cb->immModel)->canonicalizeAttrModification(req, >>>>> allWritable, hasLongDns); >>>>> +} >>>>> >>>>> SaUint32T >>>>> immModel_getLocalAppliersForObj(IMMND_CB *cb, >>>>> @@ -6996,6 +7001,143 @@ ImmModel::specialApplierTrimCreate(SaUin >>>>> return attrValues; >>>>> } >>>>> >>>>> +immsv_attr_mods_list* >>>>> +ImmModel::attrValueToAttrMod(const ObjectInfo* obj, const std::string& >>>>> attrName, >>>>> + SaUint32T attrType, bool* hasLongDns) >>>>> +{ >>>>> + 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 */ >>>>> + >>>>> + /* Check for long DN. Will be skipped if hasLongDns is NULL or >>>>> already 'true' */ >>>>> + if (hasLongDns && !(*hasLongDns) && !attrValue->empty()) { >>>>> + /* Check head value */ >>>>> + if (strlen(attrValue->getValueC_str()) >= >>>>> SA_MAX_UNEXTENDED_NAME_LENGTH) { >>>>> + *hasLongDns = true; /* Found! Skip checking more values */ >>>>> + } else if (attrValue->extraValues()) { >>>>> + /* Check more values */ >>>>> + ImmAttrMultiValue* multiVal = ((ImmAttrMultiValue *) >>>>> attrValue)->getNextAttrValue(); >>>>> + while (multiVal) { >>>>> + if (!multiVal->empty() && >>>>> strlen(multiVal->getValueC_str()) >= SA_MAX_UNEXTENDED_NAME_LENGTH) { >>>>> + *hasLongDns = true; /* Found! Stop checking */ >>>>> + break; /* while */ >>>>> + } >>>>> + multiVal = multiVal->getNextAttrValue(); >>>>> + } >>>>> + } >>>>> + } >>>>> + >>>>> + 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(). >>>>> + * >>>>> + * 'hasLongDns' is an in/out argument. If it's NULL or 'true', no >>>>> checking for long DNs will be done. >>>>> + * 'hasLongDns' will only be returned when canonicalizing all writable >>>>> attributes. >>>>> + * In case of canonicalizing only modified attributes, we can use >>>>> 'hasLongDns' ouput >>>>> + * from immModel_ccbObjectModify(), no need to check the attributes for >>>>> long DN again. >>>>> + */ >>>>> +immsv_attr_mods_list* >>>>> +ImmModel::canonicalizeAttrModification(const ImmsvOmCcbObjectModify >>>>> *req, bool allWritable, bool* hasLongDns) >>>>> +{ >>>>> + 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; >>>>> + } >>>>> + >>>>> + if (allWritable) { >>>>> + /* add all writable attributes of class to list */ >>>>> + osafassert(hasLongDns); >>>>> + ClassInfo* classInfo = afim->mClassInfo; >>>>> + AttrMap::iterator ai = classInfo->mAttrMap.begin(); >>>>> + for (; ai != classInfo->mAttrMap.end(); ai++) { >>>>> + if (ai->second->mFlags & SA_IMM_ATTR_WRITABLE) { >>>>> + immsv_attr_mods_list* attrMod = NULL; >>>>> + if (((ai->second->mValueType == SA_IMM_ATTR_SANAMET) || >>>>> + (ai->second->mValueType == SA_IMM_ATTR_SASTRINGT >>>>> && (ai->second->mFlags & SA_IMM_ATTR_DN)))) { >>>>> + attrMod = attrValueToAttrMod(afim, (std::string&) >>>>> ai->first, >>>>> + ai->second->mValueType, >>>>> hasLongDns); >>>>> + } else { >>>>> + attrMod = attrValueToAttrMod(afim, (std::string&) >>>>> ai->first, >>>>> + ai->second->mValueType, >>>>> NULL); >>>>> + } >>>>> + attrMod->next = result; >>>>> + result = attrMod; >>>>> + } >>>>> + } >>>>> + } else { >>>>> + /* add only modified attributes to 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, NULL); >>>>> + 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, bool allWritable, >>>>> bool* hasLongDns); >>>>> >>>>> SaAisErrorT ccbObjectModify( >>>>> const ImmsvOmCcbObjectModify* >>>>> req, >>>>> @@ -709,6 +712,11 @@ private: >>>>> ObjectInfo *obj, >>>>> const char *noDanglingRef); >>>>> >>>>> + immsv_attr_mods_list* attrValueToAttrMod(const ObjectInfo* obj, >>>>> + const std::string& attrName, >>>>> + SaUint32T attrType, >>>>> + bool* hasLongDns); >>>>> + >>>>> }; >>>>> >>>>> #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,13 @@ static void immnd_evt_proc_object_modify >>>>> SaNameT objName; >>>>> osaf_extended_name_clear(&objName); >>>>> bool hasLongDns=false; >>>>> + /* These 2 attr-mods lists will only be generated on demand */ >>>>> + IMMSV_ATTR_MODS_LIST* canonicalizedAttrMod = NULL; >>>>> + IMMSV_ATTR_MODS_LIST* canonicalizedWritableAttr = NULL; >>>>> + /* Used when canonicalizing all writable attributes */ >>>>> + bool writableAttrHasLongDns = false; >>>>> + >>>>> + >>>>> TRACE_ENTER(); >>>>> #if 0 /*ABT DEBUG PRINTOUTS START */ >>>>> TRACE_2("ABT immnd_evt_proc_object_modify object:%s", >>>>> evt->info.objModify.objectName.buf); >>>>> @@ -6243,6 +6250,11 @@ static void immnd_evt_proc_object_modify >>>>> err = immModel_ccbObjectModify(cb, &(evt->info.objModify), >>>>> &implConn, &implNodeId, >>>>> &continuationId, &pbeConn, pbeNodeIdPtr, &objName, >>>>> &hasLongDns); >>>>> >>>>> + /* If 'hasLongDns' is already true, canonicalizedWritableAttr will also >>>>> contain long DN. >>>>> + * No need to do any check for long DN in >>>>> immModel_canonicalizeAttrModification. >>>>> + */ >>>>> + writableAttrHasLongDns = hasLongDns; >>>>> + >>>>> if(pbeNodeIdPtr && pbeConn && err == SA_AIS_OK) { >>>>> /*The persistent back-end is present and executing at >>>>> THIS node. */ >>>>> osafassert(cb->mIsCoord); >>>>> @@ -6317,6 +6329,19 @@ 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) { >>>>> + canonicalizedAttrMod = >>>>> + >>>>> immModel_canonicalizeAttrModification(cb, &(evt->info.objModify), >>>>> + >>>>> false, NULL); >>>>> + } >>>>> + >>>>> send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod; >>>>> + } >>>>> + >>>>> /* shallow copy into stack alocated >>>>> structure. */ >>>>> >>>>> >>>>> send_evt.info.imma.info.objModify.adminOwnerId = continuationId; >>>>> @@ -6350,14 +6375,16 @@ static void immnd_evt_proc_object_modify >>>>> if(arrSize) { >>>>> memset(&send_evt, '\0', sizeof(IMMSV_EVT)); >>>>> send_evt.type = IMMSV_EVT_TYPE_IMMA; >>>>> - send_evt.info.imma.type = hasLongDns ? >>>>> IMMA_EVT_ND2A_OI_OBJ_MODIFY_LONG_UC : >>>>> - IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC; >>>>> send_evt.info.imma.info.objModify = >>>>> evt->info.objModify; >>>>> send_evt.info.imma.info.objModify.adminOwnerId >>>>> = 0; >>>>> /* Re-use the adminOwner member of the >>>>> ccbModify message to hold the >>>>> 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; >>>>> + send_evt.info.imma.type = hasLongDns ? >>>>> + IMMA_EVT_ND2A_OI_OBJ_MODIFY_LONG_UC : >>>>> IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC; >>>>> implHandle = >>>>> m_IMMSV_PACK_HANDLE(applConnArr[ix], cb->node_id); >>>>> >>>>> send_evt.info.imma.info.objModify.immHandle = implHandle; >>>>> >>>>> @@ -6367,14 +6394,36 @@ 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 (!canonicalizedWritableAttr) { >>>>> + canonicalizedWritableAttr = >>>>> + >>>>> immModel_canonicalizeAttrModification(cb, &(evt->info.objModify), >>>>> + >>>>> true, >>>>> &writableAttrHasLongDns); >>>>> + } >>>>> + >>>>> send_evt.info.imma.info.objModify.attrMods = canonicalizedWritableAttr; >>>>> + send_evt.info.imma.type = >>>>> writableAttrHasLongDns ? >>>>> + >>>>> IMMA_EVT_ND2A_OI_OBJ_MODIFY_LONG_UC : IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC; >>>>> + } >>>>> + >>>>> if (oi_cl_node->mIsStale) { >>>>> LOG_WA("Applier client went >>>>> down so modify upcall not sent"); >>>>> continue; >>>>> @@ -6416,12 +6465,11 @@ 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; >>>>> + immsv_free_attrmods(canonicalizedWritableAttr); >>>>> + canonicalizedWritableAttr = 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, bool allWritable, bool* hasLongDns); >>>>> >>>>> SaBoolT immModel_protocol41Allowed(IMMND_CB *cb); >>>>> SaBoolT immModel_protocol43Allowed(IMMND_CB *cb); >>>> ------------------------------------------------------------------------------ >>>> _______________________________________________ >>>> Opensaf-devel mailing list >>>> [email protected] >>>> https://lists.sourceforge.net/lists/listinfo/opensaf-devel >>>> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Opensaf-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/opensaf-devel >> ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensaf-devel
