osaf/libs/agents/saf/imma/imma_cb.h              |    3 +-
 osaf/libs/agents/saf/imma/imma_db.c              |   14 +-
 osaf/libs/agents/saf/imma/imma_oi_api.c          |    2 +-
 osaf/libs/agents/saf/imma/imma_om_api.c          |  415 ++++++++++++++++++++++-
 osaf/libs/agents/saf/imma/imma_proc.c            |   48 ++-
 osaf/libs/common/immsv/immsv_evt.c               |   24 +-
 osaf/libs/common/immsv/include/immsv_evt.h       |    2 +
 osaf/libs/common/immsv/include/immsv_evt_model.h |    1 +
 osaf/libs/saf/include/saImmOm_A_2_16.h           |    2 +
 osaf/libs/saf/include/saImmOm_A_2_17.h           |    6 +
 10 files changed, 490 insertions(+), 27 deletions(-)


The patch contains code for the library part of transactional safe read

diff --git a/osaf/libs/agents/saf/imma/imma_cb.h 
b/osaf/libs/agents/saf/imma/imma_cb.h
--- a/osaf/libs/agents/saf/imma/imma_cb.h
+++ b/osaf/libs/agents/saf/imma/imma_cb.h
@@ -96,6 +96,7 @@ typedef struct imma_ccb_node {
        SaImmCcbHandleT ccb_hdl;        /* locally generated handle */
        SaImmHandleT mImmHandle;        /* The immOm handle */
        SaImmAdminOwnerHandleT mAdminOwnerHdl;
+       SaImmAccessorHandleT mCcbObjectReadAccessorHandle; 
        SaImmCcbFlagsT mCcbFlags;
        SaUint32T mCcbId;   /* Om client uses 32 bit ccbId. */
        SaStringT* mErrorStrings;
@@ -200,7 +201,7 @@ int imma_oi_ccb_record_set_error(IMMA_CL
 SaStringT imma_oi_ccb_record_get_error(IMMA_CLIENT_NODE *cl_node, 
SaImmOiCcbIdT ccbId);
 void imma_oi_ccb_allow_error_string(IMMA_CLIENT_NODE *cl_node, SaImmOiCcbIdT 
ccbId);
 int imma_oi_ccb_record_note_callback(IMMA_CLIENT_NODE *cl_node, SaImmOiCcbIdT 
ccbId,
-       struct imma_callback_info *callback);
+       struct imma_callback_info *callback, SaUint8T augPermission);
 struct imma_callback_info * imma_oi_ccb_record_ok_augment(IMMA_CLIENT_NODE 
*cl_node, 
        SaImmOiCcbIdT ccbId, SaImmHandleT *privateOmHandle, 
SaImmAdminOwnerHandleT *privateAoHandle);
 void imma_oi_ccb_record_augment(IMMA_CLIENT_NODE *cl_node, SaImmOiCcbIdT 
ccbId, SaImmHandleT privateOmHandle,
diff --git a/osaf/libs/agents/saf/imma/imma_db.c 
b/osaf/libs/agents/saf/imma/imma_db.c
--- a/osaf/libs/agents/saf/imma/imma_db.c
+++ b/osaf/libs/agents/saf/imma/imma_db.c
@@ -344,8 +344,8 @@ int imma_oi_ccb_record_ok_for_critical(I
                                TRACE_5("op-count matches with inv:%u", inv);
                        }
                }
-               tmp->isCcbAugOk = false; /* not allowed to augment ccb in 
completed UC */
-               tmp->ccbCallback = NULL;
+               tmp->isCcbAugOk = 1; /* only allowed to augment ccb with 
safe-read in completed UC */
+               //tmp->ccbCallback = NULL;
        } else {
                LOG_NO("Record for ccb 0x%llx not found or found aborted in 
ok_for_critical", ccbId);
        }
@@ -365,7 +365,7 @@ int imma_oi_ccb_record_set_critical(IMMA
                tmp->isCritical = true;
                rs = 1;
                tmp->isCcbErrOk = false;
-               tmp->isCcbAugOk = false;
+               tmp->isCcbAugOk = 0;
                tmp->ccbCallback = NULL;
                if(tmp->opCount) {
                        if(!(cl_node->isPbe || cl_node->isApplier)) {
@@ -510,7 +510,7 @@ int imma_oi_ccb_record_close_augment(IMM
        struct imma_oi_ccb_record *tmp = imma_oi_ccb_record_find(cl_node, 
ccbId);
 
        if(tmp) {
-               tmp->isCcbAugOk = false;
+               tmp->isCcbAugOk = 0;
                if(privateOmHandle) {
                        *privateOmHandle = tmp->privateAugOmHandle;
                        if(ccbDone) {
@@ -529,7 +529,7 @@ int imma_oi_ccb_record_close_augment(IMM
 }
 
 int imma_oi_ccb_record_note_callback(IMMA_CLIENT_NODE *cl_node, SaImmOiCcbIdT 
ccbId, 
-       IMMA_CALLBACK_INFO *callback)
+       IMMA_CALLBACK_INFO *callback, SaUint8T augPermission)
 {
        /* Stores pointer to callback record in oi_ccb_record, but should only
           be done for ccb create/delete/modify upcalls and only for main OI 
@@ -546,7 +546,9 @@ int imma_oi_ccb_record_note_callback(IMM
        if(tmp && !(tmp->isAborted)) {
                tmp->ccbCallback = callback;
                if(callback) {
-                       tmp->isCcbAugOk = true;
+                       tmp->isCcbAugOk = augPermission; /* 0, 1, or 2 */
+                               /* see: imma_oi_ccb_record  in imma_cb.h*/
+
                        osafassert(!(tmp->isCritical));
                        osafassert(!(cl_node->isApplier));
                        rs = 1;
diff --git a/osaf/libs/agents/saf/imma/imma_oi_api.c 
b/osaf/libs/agents/saf/imma/imma_oi_api.c
--- a/osaf/libs/agents/saf/imma/imma_oi_api.c
+++ b/osaf/libs/agents/saf/imma/imma_oi_api.c
@@ -3655,7 +3655,7 @@ SaAisErrorT saImmOiAugmentCcbInitialize(
        IMMA_CALLBACK_INFO * cbi=NULL;
        SaImmHandleT privateOmHandle = 0LL;
        SaImmAdminOwnerHandleT privateAoHandle = 0LL;
-       SaVersionT version = {'A', 2, 11};
+       SaVersionT version = {'A', 2, 17};
        SaUint32T adminOwnerId = 0;
        SaUint32T ccbId = 0;
 
diff --git a/osaf/libs/agents/saf/imma/imma_om_api.c 
b/osaf/libs/agents/saf/imma/imma_om_api.c
--- a/osaf/libs/agents/saf/imma/imma_om_api.c
+++ b/osaf/libs/agents/saf/imma/imma_om_api.c
@@ -3463,7 +3463,8 @@ SaAisErrorT imma_applyCcb(SaImmCcbHandle
                                 Ccb handle is still valid.
 
                    SA_AIS_ERR_VERSION - Not allowed for IMM API version below 
A.2.14.
-                   SA_AIS_ERR_BAD_OPERATION - saImmOmCcbAbort not allowed on 
augmented ccb.
+                   SA_AIS_ERR_BAD_OPERATION - saImmOmCcbAbort not allowed in 
ccb
+                                              augmentation
 
                    Remaining returncodes identical to saImmOmFinalize.
 
@@ -3488,7 +3489,7 @@ SaAisErrorT saImmOmCcbAbort(SaImmCcbHand
                    such as some problem with the PBE (persistent back end), or 
a crash
                    of some vital IMM process. 
 
-                   Thus after a successfull saImmOmCcbVAlidate, the ccb is in 
a state
+                   Thus after a successfull saImmOmCcbValidate, the ccb is in 
a state
                    that only accepts one of:
 
                       - saImmOmCcbApply(ccbHandle);  - Only applicable if 
saImmOmCcbValidate
@@ -3513,6 +3514,8 @@ SaAisErrorT saImmOmCcbAbort(SaImmCcbHand
                    SA_AIS_ERR_FAILED_OPERATION - Ccb is aborted possibly due 
to failed
                                                  validation.
 
+
+
  
 ******************************************************************************/
 SaAisErrorT saImmOmCcbValidate(SaImmCcbHandleT ccbHandle)
@@ -3520,8 +3523,6 @@ SaAisErrorT saImmOmCcbValidate(SaImmCcbH
        return imma_applyCcb(ccbHandle, true);
 }
 
-
-
 /****************************************************************************
   Name          :  saImmOmAdminOperationInvoke_2/_o2/_o3
  
@@ -5705,7 +5706,8 @@ static SaAisErrorT accessor_get_common(S
                                 SaConstStringT objectName,
                                 const SaImmAttrNameT *attributeNames,
                                 SaImmAttrValuesT_2 ***attributes,
-                                bool bUseString);
+                                bool bUseString,
+                                SaUint32T ccbId);
 
 SaAisErrorT saImmOmAccessorGet_2(SaImmAccessorHandleT accessorHandle,
                                 const SaNameT *objectName,
@@ -5732,7 +5734,7 @@ SaAisErrorT saImmOmAccessorGet_2(SaImmAc
                }
        }
 
-       rc = accessor_get_common(accessorHandle, objectNameStr, attributeNames, 
attributes, false);
+       rc = accessor_get_common(accessorHandle, objectNameStr, attributeNames, 
attributes, false, 0);
 
        if(freeMemory == SA_TRUE) {
                free(objectNameStr);
@@ -5745,14 +5747,15 @@ SaAisErrorT saImmOmAccessorGet_o3(SaImmA
                                 SaConstStringT objectName,
                                 const SaImmAttrNameT *attributeNames, 
SaImmAttrValuesT_2 ***attributes)
 {
-       return accessor_get_common(accessorHandle, objectName, attributeNames, 
attributes, true);
+       return accessor_get_common(accessorHandle, objectName, attributeNames, 
attributes, true, 0);
 }
 
 static SaAisErrorT accessor_get_common(SaImmAccessorHandleT accessorHandle,
                                 SaConstStringT objectName,
                                 const SaImmAttrNameT *attributeNames,
                                 SaImmAttrValuesT_2 ***attributes,
-                                bool bUseString)
+                                bool bUseString,
+                                SaUint32T ccbId)
 {
        SaAisErrorT rc = SA_AIS_OK;
        uint32_t proc_rc;
@@ -5765,6 +5768,9 @@ static SaAisErrorT accessor_get_common(S
        SaUint32T timeout;
 
        TRACE_ENTER();
+       if(ccbId) {
+               TRACE_2("This is a SAFE read, ccbId:%u", ccbId);
+       }
 
        if (cb->sv_id == 0) {
                TRACE_2("ERR_BAD_HANDLE: No initialized handle exists!");
@@ -5861,11 +5867,12 @@ static SaAisErrorT accessor_get_common(S
 
        memset(&evt, 0, sizeof(IMMSV_EVT));
        evt.type = IMMSV_EVT_TYPE_IMMND;
-       evt.info.immnd.type = IMMND_EVT_A2ND_ACCESSOR_GET;
+       evt.info.immnd.type = 
(ccbId)?IMMND_EVT_A2ND_OBJ_SAFE_READ:IMMND_EVT_A2ND_ACCESSOR_GET;
        IMMSV_OM_SEARCH_INIT *req = &(evt.info.immnd.info.searchInit);
        req->client_hdl = immHandle;
        req->rootName.size = strlen(objectName) + 1;
        req->rootName.buf = (char *)objectName;
+       req->ccbId = ccbId; /* Zero if not safe read. */
 
        req->scope = SA_IMM_ONE;
        if(osaf_is_extended_names_enabled()) {
@@ -6163,6 +6170,384 @@ static unsigned int get_obj_size(const I
        return obj_size;
 }
 
+/****************************************************************************
+  Name          :  saImmOmCcbObjectRead
+
+  Description   :  Adds support for an OM CCB client to read-access a config 
object
+                   transactionally. The API works exactly the same way as
+                   saImmOmAccessorGet, except that
+
+                   a) The API takes a SaImmCcbHandleT instead of a 
SaImmAccessorHandleT
+
+                   b) The values returned for the objects config attributes 
are from
+                      a version of the object consistent with the 
CCB/transaction.
+                      This means either the latest applied version or a newer 
version
+                      created in the same CCB but not yet applied.
+
+                   c) Access to an object that has been deleted in the same 
CCB but
+                      not applied is rejected with ERR_NOT_EXIST.
+
+                   d) Access to an object that has been created in the same 
CCB but
+                      not applied is allowed, providing the latest version of
+                      the config attributes in that CCB.
+
+                   e) Safe read is not allowed using a runtime object as 
target.
+
+                   Runtime attributes residing in a config object are handled 
exactly
+                   the same as for saImmOmAccessorGet. The reason a safe-read 
call
+                   is not allowed on a runtime *object* is that a runtime 
object *only*
+                   contains runtime attributes. Performing a safe-read on a 
runtime
+                   object makes no sense.
+
+
+  Arguments     :  ccbHandle - Ccb Handle
+
+  Return Values :  
+                   Same return values as saImmOmAccessorGet_2 with adjustments 
to exceptions
+                   in stated in the description
+
+                   Refer to SAI-AIS IMM A.2.1 specification for the other 
return values
+                   and to the OpenSAF_IMMSv_PR (programmers reference) for 
implementation
+                   specific details. 
+
+******************************************************************************/
+SaAisErrorT saImmOmCcbObjectRead(SaImmCcbHandleT ccbHandle, SaConstStringT 
objectName,
+         const SaImmAttrNameT *attributeNames, SaImmAttrValuesT_2 
***attributes)
+{
+       SaAisErrorT rc = SA_AIS_OK;
+       IMMA_CB *cb = &imma_cb;
+       bool locked = false;
+       SaImmAccessorHandleT accessorHandle=0LL; // handle value will be copied 
from ccb-node
+       IMMA_ADMIN_OWNER_NODE *ao_node = NULL;
+       IMMA_CCB_NODE *ccb_node = NULL;
+       SaImmHandleT immHandle=0LL;
+       IMMA_CLIENT_NODE *cl_node = NULL;
+       SaUint32T ccbId = 0;
+       SaUint32T adminOwnerId = 0;
+       //SaStringT *newErrorStrings = NULL;
+       TRACE_ENTER();
+
+       /* Library checks below follows same "pattern" as 
ccb_object_modify_common */
+       if (cb->sv_id == 0) {
+               TRACE_2("ERR_BAD_HANDLE: No initialized handle exists!");
+               return SA_AIS_ERR_BAD_HANDLE;
+       }
+
+       if (objectName == NULL) {
+               TRACE_2("ERR_INVALID_PARAM: objectName is NULL");
+               TRACE_LEAVE();
+               return SA_AIS_ERR_INVALID_PARAM;
+       }
+
+       if (!objectName[0]) {
+               TRACE_2("ERR_INVALID_PARAM: objectName is empty");
+               TRACE_LEAVE();
+               return SA_AIS_ERR_INVALID_PARAM;
+       }
+
+       if (cb->is_immnd_up == false) {
+               TRACE_3("ERR_TRY_AGAIN: IMMND is DOWN");
+               /* Any on going ccb has been aborted and this will be detected
+                  in resurrect processing. But this could be the first 
operation
+                  attempted for a new ccb-id, i.e. there is no on-going ccb-id,
+                  (remember that a ccb-handle is associated with a chain of 
actual
+                  ccb-ids). In that case resurrection may succeed.
+               */
+               return SA_AIS_ERR_TRY_AGAIN;
+       }
+
+       /* get the CB Lock */
+       if (m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != NCSCC_RC_SUCCESS) {
+               rc = SA_AIS_ERR_LIBRARY;
+               TRACE_4("ERR_LIBRARY: Lock failed");
+               goto lock_fail;
+       }
+       locked = true;
+
+       /* Get the CCB info */
+       imma_ccb_node_get(&cb->ccb_tree, &ccbHandle, &ccb_node);
+       if (!ccb_node) {
+               rc = SA_AIS_ERR_BAD_HANDLE;
+               TRACE_2("ERR_BAD_HANDLE: Ccb handle not valid");
+               goto done;
+       }
+
+       if (ccb_node->mExclusive) {
+               rc = SA_AIS_ERR_TRY_AGAIN;
+               TRACE_3("ERR_TRY_AGAIN: Ccb-id %u being created or in critical 
phase, in another thread",
+                       ccb_node->mCcbId);
+               goto done;
+       }
+
+       if (ccb_node->mAborted) {
+               TRACE_2("ERR_FAILED_OPERATION: CCB %u has already been aborted",
+                       ccb_node->mCcbId);
+               rc = SA_AIS_ERR_FAILED_OPERATION;
+               goto done;
+       }
+
+       immHandle = ccb_node->mImmHandle;
+
+
+       /* Free string from previous ccb-op */
+       imma_free_errorStrings(ccb_node->mErrorStrings);
+       ccb_node->mErrorStrings = NULL;
+
+       /*Look up client node also, to verify that the client handle
+          is still active. */
+       imma_client_node_get(&cb->client_tree, &immHandle, &cl_node);
+       if (!(cl_node && cl_node->isOm)) {
+               rc = SA_AIS_ERR_LIBRARY;
+               TRACE_4("ERR_LIBRARY: No valid SaImmHandleT associated with 
Ccb");
+               goto done;
+       }
+
+       if(!cl_node->isImmA2x11) {
+               rc = SA_AIS_ERR_VERSION;
+               TRACE_2("ERR_VERSION: saImmOmCcbObjectRead only supported for "
+                       "A.02.17 and above");
+               goto done;
+       }
+
+       /* Stale check and possible resurrect done here for the complete 
ccb-handle level.
+          The stale check later done in the call via accessorGet wil be 
redundant. But
+          the handle should never be stale there if call arrived from here.
+        */
+       if (cl_node->stale) {
+               TRACE_1("IMM Handle %llx is stale", immHandle);
+
+               if(!(ccb_node->mApplied)) {
+                       TRACE_3("ERR_FAILED_OPERATION: IMMND DOWN discards ccb "
+                               "in active but non-critical state");
+                       ccb_node->mAborted = true;
+                       rc = SA_AIS_ERR_FAILED_OPERATION;
+                       /* We drop the resurrect task since this ccb is doomed. 
*/
+                       goto done;
+               }
+
+               /* Why do we bother trying resurrect? See ##1## above. */
+
+               bool resurrected = imma_om_resurrect(cb, cl_node, &locked);
+               cl_node = NULL;
+               ccb_node =NULL;
+
+               if (!locked && m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != 
NCSCC_RC_SUCCESS) {
+                       TRACE_4("ERR_LIBRARY: Lock failed");
+                       rc = SA_AIS_ERR_LIBRARY;
+                       goto done;
+               }
+               locked = true;
+
+               imma_client_node_get(&cb->client_tree, &immHandle, &cl_node);
+
+               if (!resurrected || !cl_node || !(cl_node->isOm) || 
cl_node->stale) {
+                       TRACE_3("ERR_BAD_HANDLE: Reactive ressurect of handle 
%llx failed", immHandle);
+                       if (cl_node && cl_node->stale) {cl_node->exposed = 
true;}
+                       rc = SA_AIS_ERR_BAD_HANDLE;
+                       goto done;
+               }
+
+               TRACE_1("Reactive resurrect of handle %llx succeeded", 
immHandle);
+
+               /* Look up ccb_node again */
+               imma_ccb_node_get(&cb->ccb_tree, &ccbHandle, &ccb_node);
+               if (!ccb_node) {
+                       rc = SA_AIS_ERR_BAD_HANDLE;
+                       TRACE_3("ERR_BAD_HANDLE: Ccb handle not valid after 
successful resurrect");
+                       goto done;
+               }
+
+               if (ccb_node->mExclusive) {
+                       rc = SA_AIS_ERR_TRY_AGAIN;
+                       TRACE_3("ERR_TRY_AGAIN: Ccb-id %u being created or in 
critical phase, "
+                               "in another thread", ccb_node->mCcbId);
+                       goto done;
+               }
+
+               if (ccb_node->mAborted) {
+                       TRACE_3("ERR_FAILED_OPERATION: Ccb-id %u was aborted", 
ccb_node->mCcbId);
+                       rc = SA_AIS_ERR_FAILED_OPERATION;
+                       goto done;
+               }
+       }
+
+       /* Get the Admin Owner info  Although not really interested in admo for 
safe-read. */
+       imma_admin_owner_node_get(&cb->admin_owner_tree, 
&(ccb_node->mAdminOwnerHdl), &ao_node);
+       if (!ao_node) {
+               rc = SA_AIS_ERR_LIBRARY;
+               TRACE_4("ERR_LIBRARY: No Amin-Owner associated with Ccb");
+               goto done;
+       }
+
+       osafassert(ccb_node->mImmHandle == ao_node->mImmHandle);
+       adminOwnerId = ao_node->mAdminOwnerId;
+       ao_node=NULL;
+
+       if (ccb_node->mApplied) {  /* Current ccb-id is closed, get a new one.*/
+               if((rc = imma_proc_increment_pending_reply(cl_node, true)) != 
SA_AIS_OK) {
+                       TRACE_4("ERR_LIBRARY: Overlapping use of IMM handle by 
multiple threads");
+                       goto done;
+               }
+               rc = imma_newCcbId(cb, ccb_node, adminOwnerId, &locked, 
cl_node->syncr_timeout);
+               cl_node = NULL;
+               if(rc == SA_AIS_ERR_LIBRARY) {goto done;}
+               /* ccb_node still valid if rc == SA_AIS_OK. */
+               if(rc == SA_AIS_OK) {
+                       osafassert(!(ccb_node->mExclusive));
+                       osafassert(locked);
+               }
+
+               if (!locked) {
+                       if (m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != 
NCSCC_RC_SUCCESS) {
+                               rc = SA_AIS_ERR_LIBRARY;
+                               TRACE_4("ERR_LIBRARY: Lock failed");
+                               goto done;
+                       }
+                       locked = true;
+               }
+
+               imma_client_node_get(&cb->client_tree, &immHandle, &cl_node);
+               if (!(cl_node && cl_node->isOm)) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       TRACE_4("ERR_LIBRARY: No client associated with Admin 
Owner");
+                       goto done;
+               }
+
+               imma_proc_decrement_pending_reply(cl_node, true);
+
+               if (rc != SA_AIS_OK) {
+                       goto done;
+               }
+
+               /* successfully obtained new ccb-id */
+
+               if (cl_node->stale) {
+                       /* Became stale AFTER we successfully obtained new 
ccb-id ! */
+                       TRACE_3("ERR_FAILED_OPERATION: IMM Handle %llx became 
stale", immHandle);
+
+                       rc = SA_AIS_ERR_FAILED_OPERATION;
+                       /* We know the ccb WAS terminated*/
+                       ccb_node->mCcbId = 0;
+                       ccb_node->mAborted = true;
+                       goto done;
+               }
+       }
+
+       osafassert(locked);
+       osafassert(cl_node);
+       osafassert(ccb_node);
+
+       ccbId = ccb_node->mCcbId;
+       accessorHandle = ccb_node->mCcbObjectReadAccessorHandle;
+
+       m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+       locked = false;
+
+       if(accessorHandle == 0LL) {
+               rc = saImmOmAccessorInitialize(immHandle, &accessorHandle);
+               if (rc != SA_AIS_OK) {
+                       TRACE_2("Failed to initialize accessor-handle");
+                       goto done;
+               }
+               TRACE_2("Initialized CCB safe-read accessor handle %llu", 
accessorHandle);
+
+               /* get the CB Lock */
+               if (m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != 
NCSCC_RC_SUCCESS) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       TRACE_4("ERR_LIBRARY: Lock failed");
+                       goto lock_fail;
+               }
+               locked = true;
+
+               /* Get the CCB info */
+               imma_ccb_node_get(&cb->ccb_tree, &ccbHandle, &ccb_node);
+               if (!ccb_node) {
+                       rc = SA_AIS_ERR_BAD_HANDLE;
+                       TRACE_2("ERR_BAD_HANDLE: Ccb handle not valid");
+                       goto done;
+               }
+
+               ccb_node->mCcbObjectReadAccessorHandle = accessorHandle;
+
+               m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+               locked = false;
+       }
+
+       TRACE("Optimistically invoking accessor_get_common with ccbid:%u", 
ccbId);
+       rc = accessor_get_common(accessorHandle, objectName, attributeNames, 
attributes, true, ccbId);
+       if(rc == SA_AIS_ERR_INTERRUPT) {
+               TRACE("CcbObjectRead: Object was not locked. Get global shared 
read lock");
+               IMMSV_EVT evt;
+               IMMSV_EVT *out_evt = NULL;
+
+               /* get the CB Lock */
+               if (m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) != 
NCSCC_RC_SUCCESS) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       TRACE_4("ERR_LIBRARY: Lock failed");
+                       goto lock_fail;
+               }
+               locked = true;
+
+               imma_client_node_get(&cb->client_tree, &immHandle, &cl_node);
+               if (!(cl_node && cl_node->isOm)) {
+                       rc = SA_AIS_ERR_LIBRARY;
+                       TRACE_4("ERR_LIBRARY: No client associated with Admin 
Owner");
+                       goto done;
+               }
+
+               /* Obtain a safe-read CCB lock for this the object over fevs. */
+               memset(&evt, 0, sizeof(IMMSV_EVT));
+               evt.type = IMMSV_EVT_TYPE_IMMND;
+               /* This is a hack. Re-using the SAFE_READ msg type here only to 
ackquire lock. */
+               evt.info.immnd.type = IMMND_EVT_A2ND_OBJ_SAFE_READ;
+               IMMSV_OM_SEARCH_INIT *req = &(evt.info.immnd.info.searchInit);
+               req->client_hdl = immHandle;
+               req->rootName.size = strlen(objectName) + 1;
+               req->rootName.buf = (char *)objectName;
+               req->ccbId = ccbId; 
+               req->scope = SA_IMM_ONE;
+               if(osaf_is_extended_names_enabled()) {
+                       req->searchParam.present = 
ImmOmSearchParameter_PR_NOTHING;
+               } else {
+                       req->searchParam.present = 
ImmOmSearchParameter_PR_nonExtendedName_NOTHING;
+               }
+               req->searchOptions = SA_IMM_SEARCH_ONE_ATTR | 
SA_IMM_SEARCH_GET_ALL_ATTR;
+               req->searchOptions |= SA_IMM_SEARCH_NO_RDN;
+
+               rc = imma_evt_fake_evs(cb, &evt, &out_evt, 
cl_node->syncr_timeout, cl_node->handle, &locked, false);
+               if(rc != SA_AIS_OK ) { 
+                       goto done;
+               }
+
+               rc = out_evt->info.imma.info.errRsp.error;
+               if(rc != SA_AIS_OK ) { 
+                       goto done;
+               }
+
+               if (locked) {
+                       m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+                       locked = false;
+               }
+               TRACE("Ccb %u Obtained shared safe-read lock for object '%s' 
over fevs", 
+                       ccbId, objectName);
+                       
+               rc = accessor_get_common(accessorHandle, objectName, 
attributeNames, attributes, true, ccbId);
+       }
+
+ done:
+       //imma_free_errorStrings(newErrorStrings); /* In case of failed 
resurrect only */
+
+       if (locked) {
+               m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+               locked = false;
+       }
+
+ lock_fail:
+
+       TRACE_LEAVE();
+       return rc;
+
+}
 
 
 SaAisErrorT immsv_sync(SaImmHandleT immHandle, const SaImmClassNameT className,
@@ -8429,6 +8814,7 @@ static SaAisErrorT imma_finalizeCcb(SaIm
        SaImmAdminOwnerHandleT adminOwnerHdl = 0LL;
        SaUint32T adminOwnerId = 0;
        SaUint32T timeout = 0;
+       SaImmAccessorHandleT safeReadAccessorHandle=0LL; // Copied from 
ccb_node later.
        TRACE_ENTER();
 
        if (cb->sv_id == 0) {
@@ -8476,10 +8862,13 @@ static SaAisErrorT imma_finalizeCcb(SaIm
                goto done;
        }
 
+
+
        immHandle = ccb_node->mImmHandle;
        adminOwnerHdl = ccb_node->mAdminOwnerHdl;
        ccbActive = ccb_node->mCcbId && !(ccb_node->mApplied);
        ccbId = ccb_node->mCcbId;
+       safeReadAccessorHandle = ccb_node->mCcbObjectReadAccessorHandle; /* 
Safe read handle */
 
        ccb_node->mExclusive = true; 
 
@@ -8647,8 +9036,14 @@ static SaAisErrorT imma_finalizeCcb(SaIm
        }
 
  done:
-       if (locked)
+       if (locked) {
                m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE);
+       }
+
+       if(safeReadAccessorHandle &&  !keepCcbHandleOpen) {
+               TRACE_3("Finalizing CCB safe-read accessor handle %llu", 
safeReadAccessorHandle);
+               saImmOmAccessorFinalize(safeReadAccessorHandle);
+       }
 
  lock_fail:
 
diff --git a/osaf/libs/agents/saf/imma/imma_proc.c 
b/osaf/libs/agents/saf/imma/imma_proc.c
--- a/osaf/libs/agents/saf/imma/imma_proc.c
+++ b/osaf/libs/agents/saf/imma/imma_proc.c
@@ -1880,14 +1880,21 @@ static void imma_proc_ccbaug_setup(IMMA_
                case IMMA_CALLBACK_OI_CCB_CREATE:
                case IMMA_CALLBACK_OI_CCB_DELETE:
                case IMMA_CALLBACK_OI_CCB_MODIFY:
-                       if(!(imma_oi_ccb_record_note_callback(cl_node, 
callback->ccbID, callback))) {
+                       if(!(imma_oi_ccb_record_note_callback(cl_node, 
callback->ccbID, callback, 2))) {
                                TRACE_3("Failed to note callback for ccb %u, "
                                        "Ccb augment not possible", 
callback->ccbID);
                        }
                        break;
 
+               case IMMA_CALLBACK_OI_CCB_COMPLETED:
+                       if(!(imma_oi_ccb_record_note_callback(cl_node, 
callback->ccbID, callback, 1))) {
+                               TRACE_3("Failed to note completed callback for 
ccb %u, "
+                                       "Ccb augment not possible", 
callback->ccbID);
+                       }
+                       break;
+
                default:
-                       imma_oi_ccb_record_note_callback(cl_node, 
callback->ccbID, NULL);
+                       imma_oi_ccb_record_note_callback(cl_node, 
callback->ccbID, NULL, 0);
        }
 }
 
@@ -2162,10 +2169,41 @@ static bool imma_process_callback_info(I
                                }
 
                                if(!(cl_node->isApplier) || (isPbeOp && 
cl_node->isPbe)) {
+                                       SaImmHandleT privateAugOmHandle = 0LL;
                                        /* Appliers dont reply on completed 
except PBE slave replying on completed
                                           for PRTO- delete. PRTO-delete means 
ccb-id is in the high rannge.
                                           So PBE slave does NOT reply on 
completed for regular CCBs. 
                                        */
+
+                                       //Add code for closing safe-read 
augmentations in completed callback.
+                                       
if(!imma_oi_ccb_record_close_augment(cl_node, callback->ccbID, 
&privateAugOmHandle, false)) {
+                                               
TRACE_3("CcbObjectCompletedCallback: imma_oi_ccb_record_close_augment "
+                                                       "returned false for ccb 
%u", callback->ccbID);
+                                       }
+
+                                       if(privateAugOmHandle) {
+                                               osafassert(locked);
+                                               
osafassert(m_NCS_UNLOCK(&cb->cb_lock, NCS_LOCK_WRITE) == NCSCC_RC_SUCCESS);
+                                               locked = false;
+
+                                               
osafassert(immsv_om_augment_ccb_get_result);
+                                               SaAisErrorT augResult = 
immsv_om_augment_ccb_get_result(privateAugOmHandle,
+                                                       callback->ccbID);
+
+                                               
osafassert(m_NCS_LOCK(&cb->cb_lock, NCS_LOCK_WRITE) == NCSCC_RC_SUCCESS);
+                                               locked = true;
+
+                                               if(augResult != SA_AIS_OK) {
+                                                       TRACE("A non-ok result 
%u from an augmented CCB overrides the reply from "
+                                                               "the OI %u on 
completed", augResult,
+                                                               
ccbCompletedRpl.info.immnd.info.ccbUpcallRsp.result);
+
+                                                       
ccbCompletedRpl.info.immnd.info.ccbUpcallRsp.result = augResult;
+                                               }                               
                        
+                                       }
+
+
+
                                        localEr = imma_evt_fake_evs(cb, 
&ccbCompletedRpl, NULL, 0, cl_node->handle, &locked, false);
                                        if (localEr != NCSCC_RC_SUCCESS) {
                                                /*Cant do anything but log 
error and drop this reply. */
@@ -2486,7 +2524,7 @@ static bool imma_process_callback_info(I
                                                locked = true;
 
                                                if(augResult != SA_AIS_OK) {
-                                                       TRACE("A non-ok result 
from an augmented CCB %u overrides the reply from "
+                                                       TRACE("A non-ok result 
%u from an augmented CCB overrides the reply from "
                                                                "the OI %u on 
create-uc", augResult,
                                                                
ccbObjCrRpl.info.immnd.info.ccbUpcallRsp.result);
 
@@ -2652,7 +2690,7 @@ static bool imma_process_callback_info(I
                                                locked = true;
 
                                                if(augResult != SA_AIS_OK) {
-                                                       TRACE("A non-ok result 
from an augmented CCB %u overrides the reply from "
+                                                       TRACE("A non-ok result 
%u from an augmented CCB overrides the reply from "
                                                                "the OI %u on 
delete-op", augResult,
                                                                
ccbObjDelRpl.info.immnd.info.ccbUpcallRsp.result);
 
@@ -2891,7 +2929,7 @@ static bool imma_process_callback_info(I
                                                locked = true;
 
                                                if(augResult != SA_AIS_OK) {
-                                                       TRACE("A non-ok result 
from an augmented CCB %u overrides the reply from "
+                                                       TRACE("A non-ok result 
%u from an augmented CCB overrides the reply from "
                                                                "the OI %u on 
modify-uc", augResult, 
                                                                
ccbObjModRpl.info.immnd.info.ccbUpcallRsp.result);
 
diff --git a/osaf/libs/common/immsv/immsv_evt.c 
b/osaf/libs/common/immsv/immsv_evt.c
--- a/osaf/libs/common/immsv/immsv_evt.c
+++ b/osaf/libs/common/immsv/immsv_evt.c
@@ -181,6 +181,7 @@ static const char *immnd_evt_names[] = {
        "IMMND_EVT_D2ND_IMPLSET_RSP_2", /* Implementer set reply from D with 
impl id */
        "IMMND_EVT_A2ND_OBJ_CREATE_2",  /* saImmOmCcbObjectCreate_o3 */
        "IMMND_EVT_A2ND_OI_OBJ_CREATE_2",       /* saImmOiRtObjectCreate_o3 */
+       "IMMND_EVT_A2ND_OBJ_SAFE_READ",       /* saImmOmCcbObjectRead */
        "undefined (high)"
 };
 
@@ -1860,7 +1861,8 @@ static uint32_t immsv_evt_enc_sublevels(
                                }
                        }
                } else if ((i_evt->info.immnd.type == 
IMMND_EVT_A2ND_SEARCHINIT) ||
-                       (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_ACCESSOR_GET)) {
+                       (i_evt->info.immnd.type == IMMND_EVT_A2ND_ACCESSOR_GET) 
||
+                       (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OBJ_SAFE_READ)) {
                        int depth = 0;
                        /*Encode the rootName */
                        IMMSV_OCTET_STRING *os = 
&(i_evt->info.immnd.info.searchInit.rootName);
@@ -1901,7 +1903,6 @@ static uint32_t immsv_evt_enc_sublevels(
                                LOG_ER("TOO MANY attribute names line:%u", 
__LINE__);
                                return NCSCC_RC_OUT_OF_MEM;
                        }
-
                } else if (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_RT_ATT_UPPD_RSP) {
                        int depth = 0;
                        /*Encode the objectName */
@@ -2406,8 +2407,9 @@ static uint32_t immsv_evt_dec_sublevels(
                                        ++depth;
                                }
                        }
-               } else if ((o_evt->info.immnd.type == 
IMMND_EVT_A2ND_SEARCHINIT) || 
-                       (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_ACCESSOR_GET)) {
+               } else if ((o_evt->info.immnd.type == 
IMMND_EVT_A2ND_SEARCHINIT) ||
+                       (o_evt->info.immnd.type == IMMND_EVT_A2ND_ACCESSOR_GET) 
||
+                       (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_OBJ_SAFE_READ)) {
                        /*Decode the rootName */
                        IMMSV_OCTET_STRING *os = 
&(o_evt->info.immnd.info.searchInit.rootName);
                        if (os->size) {
@@ -3235,6 +3237,7 @@ static uint32_t immsv_evt_enc_toplevel(I
 
                case IMMND_EVT_A2ND_SEARCHINIT: /* SearchInitialize */
                case IMMND_EVT_A2ND_ACCESSOR_GET:       /* AccessorGet */
+               case IMMND_EVT_A2ND_OBJ_SAFE_READ:      /* saImmOmCcbObjectRead 
*/
 
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 8);
                        ncs_encode_64bit(&p8, 
immndevt->info.searchInit.client_hdl);
@@ -3274,6 +3277,12 @@ static uint32_t immsv_evt_enc_toplevel(I
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 1);
                        ncs_encode_8bit(&p8, 
(immndevt->info.searchInit.attributeNames) ? 1 : 0);
                        ncs_enc_claim_space(o_ub, 1);
+
+                       if(immndevt->type == IMMND_EVT_A2ND_OBJ_SAFE_READ) {
+                               IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 4);
+                               ncs_encode_32bit(&p8, 
immndevt->info.searchInit.ccbId);
+                               ncs_enc_claim_space(o_ub, 4);
+                       }
                        break;
 
                case IMMND_EVT_A2ND_SEARCHNEXT: /* SearchNext */
@@ -4638,6 +4647,7 @@ static uint32_t immsv_evt_dec_toplevel(N
 
                case IMMND_EVT_A2ND_ACCESSOR_GET:       /* AccessorGet */
                case IMMND_EVT_A2ND_SEARCHINIT: /* SearchInitialize */
+               case IMMND_EVT_A2ND_OBJ_SAFE_READ: /* saImmOmCcbObjectRead */
                        IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 8);
                        immndevt->info.searchInit.client_hdl = 
ncs_decode_64bit(&p8);
                        ncs_dec_skip_space(i_ub, 8);
@@ -4677,6 +4687,12 @@ static uint32_t immsv_evt_dec_toplevel(N
                                immndevt->info.searchInit.attributeNames = 
(void *)0x1;
                        }
                        ncs_dec_skip_space(i_ub, 1);
+
+                       if(immndevt->type == IMMND_EVT_A2ND_OBJ_SAFE_READ) {
+                               IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 
4);
+                               immndevt->info.searchInit.ccbId =  
ncs_decode_32bit(&p8);
+                               ncs_dec_skip_space(i_ub, 4);
+                       }
                        break;
 
                case IMMND_EVT_A2ND_SEARCHNEXT: /* SearchNext */
diff --git a/osaf/libs/common/immsv/include/immsv_evt.h 
b/osaf/libs/common/immsv/include/immsv_evt.h
--- a/osaf/libs/common/immsv/include/immsv_evt.h
+++ b/osaf/libs/common/immsv/include/immsv_evt.h
@@ -214,6 +214,8 @@ typedef enum immnd_evt_type {
        IMMND_EVT_A2ND_OBJ_CREATE_2 = 98,       /* saImmOmCcbObjectCreate_o3 */
        IMMND_EVT_A2ND_OI_OBJ_CREATE_2 = 99,    /* saImmOiRtObjectCreate_o3 */
 
+       IMMND_EVT_A2ND_OBJ_SAFE_READ = 100,     /* saImmOmCcbObjectRead */
+
        IMMND_EVT_MAX
 } IMMND_EVT_TYPE;
 /* Make sure the string array in immsv_evt.c matches the IMMND_EVT_TYPE enum. 
*/
diff --git a/osaf/libs/common/immsv/include/immsv_evt_model.h 
b/osaf/libs/common/immsv/include/immsv_evt_model.h
--- a/osaf/libs/common/immsv/include/immsv_evt_model.h
+++ b/osaf/libs/common/immsv/include/immsv_evt_model.h
@@ -208,6 +208,7 @@ extern "C" {
                SaUint64T searchOptions;
                IMMSV_SEARCH_PARAM searchParam;
                IMMSV_ATTR_NAME_LIST *attributeNames;
+               SaUint32T ccbId; /* Only for saImmOmCcbObjectRead */
        } IMMSV_OM_SEARCH_INIT;
 
        typedef struct ImmsvOmSearchRemote {
diff --git a/osaf/libs/saf/include/saImmOm_A_2_16.h 
b/osaf/libs/saf/include/saImmOm_A_2_16.h
--- a/osaf/libs/saf/include/saImmOm_A_2_16.h
+++ b/osaf/libs/saf/include/saImmOm_A_2_16.h
@@ -66,4 +66,6 @@ extern "C" {
 
 #include <saImmOm_A_2_17.h>
 
+#include <saImmOm_A_2_17.h>
+
 #endif   /* _SA_IMM_OM_A_2_16_H */
diff --git a/osaf/libs/saf/include/saImmOm_A_2_17.h 
b/osaf/libs/saf/include/saImmOm_A_2_17.h
--- a/osaf/libs/saf/include/saImmOm_A_2_17.h
+++ b/osaf/libs/saf/include/saImmOm_A_2_17.h
@@ -59,6 +59,12 @@ extern "C" {
 #define SA_IMM_ATTR_STRONG_DEFAULT    0x0000000020000000    /* See: 
https://sourceforge.net/p/opensaf/tickets/1425
                                                          Supported in OpenSaf 
5.0 */
 
+/* 4.8.x saImmOmCcb  */
+
+       extern SaAisErrorT
+        saImmOmCcbObjectRead(SaImmCcbHandleT ccbHandle, SaConstStringT 
objectName,
+                        const SaImmAttrNameT *attributeNames, 
SaImmAttrValuesT_2 ***attributes);
+
 
 #ifdef  __cplusplus
 }

------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785351&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to