From: Neelakanta R. <red...@or...> - 2015-12-18 08:51:40
|
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 : red...@or... >> Datum : 17-12-2015 - 12:48 (GMT) >> Till : and...@co..., hun...@de... >> Kopia : ope...@li... >> Ä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 : hun...@de... >>>> Datum : 17-12-2015 - 10:37 (GMT) >>>> Till : red...@or..., zor...@er... >>>> Kopia : ope...@li... >>>> Ä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 red...@or... >>>> Sent: Thursday, December 17, 2015 5:02PM >>>> To: Hung Nguyen, Zoran Milinkovic >>>> hun...@de..., zor...@er... >>>> Cc: Opensaf-devel >>>> ope...@li... >>>> 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 >>>> Ope...@li... >>>> https://lists.sourceforge.net/lists/listinfo/opensaf-devel >>>> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Opensaf-devel mailing list >> Ope...@li... >> https://lists.sourceforge.net/lists/listinfo/opensaf-devel >> |