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

Reply via email to