static void entityStart(ClAmsEntityConfigT& ent)
{
    ClRcT rc;

  do
    {
    rc = clAmsMgmtEntityUnlock(mgmtHandle,&ent);
    } while(CL_GET_ERROR_CODE(rc) == CL_ERR_TRY_AGAIN);

  // Already running so nothing to do
  if (CL_GET_ERROR_CODE(rc) == CL_ERR_NO_OP) return;

  do
    {
    rc = clAmsMgmtEntityLockAssignment(mgmtHandle,&ent);
    } while(CL_GET_ERROR_CODE(rc) == CL_ERR_TRY_AGAIN);

  do
    {
    rc = clAmsMgmtEntityUnlock(mgmtHandle,&ent);
    } while(CL_GET_ERROR_CODE(rc) == CL_ERR_TRY_AGAIN);

  if ((rc)&&(CL_GET_ERROR_CODE(rc) != CL_ERR_NO_OP))
    {
      checkError("Start entity", rc);
    }
  
}
ClRcT clJobQueueStop(ClJobQueueT* hdl)
{
    ClJobT* jb=0;
    ClRcT rc;

    if( !(hdl->flags & CreatedQueue) ) return CL_JOBQUEUE_RC(CL_ERR_INVALID_STATE);
    JQ_PFX(hdl);

    /* Clear out all pending jobs */
    do{
        ClQueueDataT temp;
        rc = clQueueNodeDelete(hdl->queue, &temp);
        if (CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST)
        {
            jb = (ClJobT*) temp;
            CL_ASSERT(jb);
            releaseJob(hdl,jb);
        }
    } while (CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST);

    /* GAS TODO: Let all the tasks finish up */

    hdl->flags &= ~Running;

    rc = CL_OK;

    JQ_SFX(hdl);
    return rc;
}
void clMsgQueueEmpty(ClMsgQueueInfoT *pQInfo)
{
    ClRcT rc;
    ClCntNodeHandleT nodeHandle = NULL, nextNodeHandle = NULL;
    ClUint32T i;
    ClRcT retCode;

    for(i = 0; i < CL_MSG_QUEUE_PRIORITIES; i++)
    {
        rc = clCntFirstNodeGet(pQInfo->pPriorityContainer[i], &nodeHandle);
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
            continue;

        do {
            rc = clCntNextNodeGet(pQInfo->pPriorityContainer[i], nodeHandle, &nextNodeHandle);
            if(CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST && rc != CL_OK)
            {
                clLogError("QUE", "EMT", "Failed to get the next node from container. error code [0x%x].", rc);
                break;
            }

            retCode = clCntNodeDelete(pQInfo->pPriorityContainer[i], nodeHandle);
            if(retCode != CL_OK)
                clLogError("QUE", "EMT", "Failed to delete a node from container. error code [0x%x].", retCode);

            nodeHandle = nextNodeHandle;
        }while(CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST);
    }
}
static void checkError(const char* operation, ClRcT rc)
{
  if (rc != 0)
    {
      Log(SevError,"%s: Error 0x%x", operation, rc);
      if ((CL_GET_ERROR_CODE(rc) != CL_ERR_DUPLICATE)&&(CL_GET_ERROR_CODE(rc) != CL_ERR_ALREADY_EXIST))
        {
          throw AmfException(rc);
        }
    }
}
} END_TEST_EXTERN


START_TEST_EXTERN(eject_with_proper_values)
{
    ClRcT       rc = CL_OK;

    /* Initialize gms client without any callbacks being registered. */
    rc = clGmsInitialize(&handle,NULL,&correct_version);
    fail_unless(rc == CL_OK,
            "clGmsInitialize with NULL callbacks failed with rc 0x%x",rc);

    rc = clGmsClusterJoin(handle, &clusterManageCallbacks, 0, 0, 100, &nodeName);
    fail_unless(CL_GET_ERROR_CODE(rc) == CL_OK,
            "ClusterJoin with 0 handle failed with rc = 0x%x",rc);

    callback_invoked = CL_FALSE;

    rc = clGmsClusterMemberEject(handle, 100, CL_GMS_MEMBER_EJECT_REASON_API_REQUEST);
    fail_unless(rc == CL_OK,
            "Cluster Leave for nodeId 100 failed with rc 0x%x",rc);

    /* Wait for the callback to be invoked */
    sleep(5);
    fail_unless(callback_invoked == CL_TRUE,
            "Cluster Eject callback is not invoked");
    
    /* Finalize */
    rc = clGmsFinalize(handle);
    fail_unless(rc == CL_OK,
            "clGmsFinalize failed with rc = 0x%x",rc);
 
} END_TEST_EXTERN
ClRcT
clLogSOLocalStateRecover(ClHandleT       hLibCkpt, 
                         ClLogSOEoDataT  *pSoEoEntry)
{
    ClRcT                  rc              = CL_OK;

    CL_LOG_DEBUG_TRACE(("Enter"));
    /* internally calls the deserializer, clLogSODsIdMapRecreate() */
    CL_LOG_DEBUG_TRACE(("clLogSODsIdMapRecreate: %s  %d\n",
                gSOLocalCkptName.value, CL_LOG_DSID_START));
    rc = clCkptLibraryCkptDataSetRead(hLibCkpt, 
                                      (SaNameT *) &gSOLocalCkptName,
                                      CL_LOG_DSID_START, 
                                      CL_HANDLE_INVALID_VALUE);
    if( CL_ERR_NOT_EXIST == CL_GET_ERROR_CODE(rc) )
    {
        return CL_OK;
    }    
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptLibraryCkptDataSetRead(): rc[0x %x]", rc));
        return rc;
    }    

    rc = clBitmapWalkUnlocked(pSoEoEntry->hDsIdMap, 
                              clLogSOLocalStreamEntryRecover, NULL);
    if( CL_OK != rc )
    {
        /* What do we do, revert back or proceed */
        CL_LOG_DEBUG_ERROR(("clBitmapWalkUnlocked(): rc[0x %x]", rc));
    }    
        
    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
ClRcT clCkptEntryDelete(ClCachedCkptSvcInfoT *serviceInfo, const SaNameT *sectionName)
{
    ClRcT rc = CL_OK;

    SaCkptSectionIdT ckptSectionId = {        /* Section id for checkpoints   */
        sectionName->length,
        (SaUint8T *) sectionName->value
    };
    ClInt32T tries = 0;
    ClTimerTimeOutT delay = { 0, 500 };

    /* Delete section from the ckpt */
    if (clCkptEntryExist(serviceInfo, sectionName) == CL_TRUE)
    {
retry:
        rc = clCkptSectionDelete(serviceInfo->ckptHandle, (ClCkptSectionIdT *)&ckptSectionId);
        if (CL_ERR_TRY_AGAIN == CL_GET_ERROR_CODE(rc))
        {
            if ((++tries < 5) && (clOsalTaskDelay(delay) == CL_OK))
            {
                goto retry;
            }
        }
    }

    return rc;
}
/**
 * API to delete checkpoint recovery-log details of a given transaction.
 */
ClRcT clTxnServiceCkptRecoveryLogCheckpointDelete(
    CL_IN   ClTxnTransactionIdT     txnId)
{
    ClRcT   rc  = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;
        ClCharT     elementName[200];

        CL_FUNC_ENTER();

        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        elementName[0] = '\0';
        sprintf(elementName, "TXN_%x_%x", txnId.txnMgrNodeAddress, txnId.txnId);

        rc = clCkptLibraryCkptElementDelete (clTxnServiceCfg->txnCkptHandle,
                                             &txnCkptName, CL_TXN_RECOVERY_DATA_SET,
                                             elementName, (strlen(elementName) + 1));
        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                           ("Failed to delete element of txn-recovery data for txn 0x%x:0x%x, rc:0x%x",
                            txnId.txnMgrNodeAddress, txnId.txnId, rc));
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
/**
 * Finalize Transaction service Checkpointing
 */
ClRcT clTxnServiceCkptFinalize()
{
    ClRcT       rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        rc = clCkptLibraryCkptDataSetDelete (clTxnServiceCfg->txnCkptHandle,
                                             &txnCkptName, CL_TXN_SERVICE_DATA_SET);
        rc = clCkptLibraryCkptDataSetDelete (clTxnServiceCfg->txnCkptHandle,
                                             &txnCkptName, CL_TXN_RECOVERY_DATA_SET);
        rc = clCkptLibraryCkptDelete(clTxnServiceCfg->txnCkptHandle, &txnCkptName);

        rc = clCkptLibraryFinalize(clTxnServiceCfg->txnCkptHandle);

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to delete cktp. rc:0x%x", rc));
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
/* 
 * This API creates the container class and populates it with  data from the obj deltaDb
 * The API iterates over the database, fetching the key and associated data.
 * It  calls clCorDeltaDbContAdd which places MO/MSO create/set operating in the hash list.
 */
ClRcT clCorDeltaDbObjContCreate()
{
	ClRcT rc = CL_OK;
	ClCorDeltaSaveKeyT *deltaDbKey = NULL, *deltaDbKeyNext = NULL;
	ClUint32T keySize = 0, keySizeNext = 0;
	ClDBRecordT deltaDbData, deltaDbDataNext ;
	ClUint32T dataSize = 0;
    ClVersionT dbVersion = {0};

   /* Create the container for retreiving data from the Delta DB */
	if ((rc = clCorDeltaContInit()) != CL_OK)
        return rc ;

	if((rc = clDbalFirstRecordGet( hDeltaObjDb,
								  (ClDBKeyT *)&deltaDbKey, 
								  (ClUint32T *)&keySize, 
								  (ClDBRecordT *)&deltaDbData, 
								  (ClUint32T *)&dataSize )) != CL_OK)
	{
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
        {
            clLog(CL_LOG_SEV_NOTICE, "DLS", "OBR", "The object Db doesn't \
                    contain anything. rc[0x%x]", rc);
            return CL_OK;
        }

		CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to get the first Record for the Key. rc [0x%x]",rc));
		return rc;
	}
/*
 * This function initializes all the Basic ASP library 
 */
ClRcT clEoEssentialLibInitialize(void)
{
    ClRcT rc = CL_OK;

    ClUint32T i = 0;
    ClUint32T tableSize =  CL_EO_LIB_ID_RES; // CL_SIZEOF_ARRAY(gEssentialLibInfo);

    /*
     * Initializing the Essential Libraries
     */

    for (i = 0; i < tableSize; i++)
    {
        clLog(CL_LOG_SEV_DEBUG, CL_LOG_AREA, CL_LOG_CTXT_INI, "Initializing essential library [%s]...", gEssentialLibInfo[i].libName);
        if (CL_OK != (rc = gEssentialLibInfo[i].pLibInitializeFunc(gEssentialLibInfo[i].pConfig)))
        {
            if (CL_GET_ERROR_CODE(rc) != CL_ERR_INITIALIZED) /* Already Initialized is benign */
            {
               
            clLog(CL_LOG_SEV_CRITICAL, CL_LOG_AREA, CL_LOG_CTXT_INI, "Failed to initialize essential library [%s], error [0x%x]",
                  gEssentialLibInfo[i].libName, rc);
            return rc;
            }
            
        }
    }
    return CL_OK;
}
/**
 * API to restore status of transaction-service from check-point
 */
ClRcT clTxnServiceCkptAppStateRestore()
{
    ClRcT       rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Restoring transaction-service state"));

        clLogDebug("SER", NULL,
                   "Ckpt exists, reading data");
        rc = clCkptLibraryCkptDataSetRead(clTxnServiceCfg->txnCkptHandle, &txnCkptName,
                                          CL_TXN_SERVICE_DATA_SET, 0x0);

        if (CL_OK != rc)
        {
            clLogError("SER", NULL,
                       "Failed to restore transaction-service state, rc [0x%x]", rc);
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
static ClRcT clCorDeltaDbContAdd(ClCorDeltaSaveKeyT *deltaDbKey, ClDBRecordT deltaDbData, ClUint32T dataSize)
{
	ClRcT	rc = CL_OK;
	ClCorDeltaSaveKeyT *tempKey = deltaDbKey;
	ClCorDeltaContDataT *tempCont = clHeapCalloc(1, sizeof(ClCorDeltaContDataT));

    CL_ASSERT(tempCont != NULL);

    tempCont->data = deltaDbData;
    tempCont->dataSize = dataSize;

    if( tempKey == NULL || tempCont->data == NULL)
    {
		clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
				CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
		return CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
    }

    rc = clCntNodeAdd(gCorDeltaSaveKeyTable, (ClCntKeyHandleT) tempKey, (ClCntDataHandleT) tempCont , NULL);
    if(CL_OK != rc)
    {
        if (CL_GET_ERROR_CODE(rc) == CL_ERR_DUPLICATE)
            rc = CL_OK;
        else
            CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "Could not add node in the Delta Save Key Table", rc);    

        clHeapFree(tempCont);
    }  
	
	return rc;
}
/**
 * Adds a new definition of transaction to txn-database
 */
ClRcT clTxnDbNewTxnDefnAdd(
        CL_IN   ClTxnDbHandleT      txnDb,
        CL_IN   ClTxnDefnT          *pNewTxn,
        CL_IN   ClTxnTransactionIdT *pTxnId)
{
    ClRcT       rc  = CL_OK;
    ClTxnDefnT  *pTxnDef;
    CL_FUNC_ENTER();

    rc = clCntDataForKeyGet(txnDb, (ClCntKeyHandleT) pTxnId, 
                            (ClCntDataHandleT *) &pTxnDef);
    if (CL_OK != rc)
    {
        rc = clCntNodeAdd(txnDb, 
                          (ClCntKeyHandleT) pTxnId, 
                          (ClCntDataHandleT) pNewTxn, 0);
    }
    else
    {
        rc = CL_ERR_DUPLICATE;
    }

    CL_FUNC_EXIT();
    return (CL_GET_ERROR_CODE(rc));
}
static ClRcT nodeCacheMemberGetExtended(ClIocNodeAddressT node, ClNodeCacheMemberT *pMember,ClUint32T retries, ClUint32T msecDelay, ClBoolT compat)
{
    ClRcT rc = CL_OK;
    ClUint32T i = 0;
    ClTimerTimeOutT delay;
    delay.tsSec = 0;
    delay.tsMilliSec = msecDelay;
    
    clOsalSemLock(gClNodeCacheSem);
    while(i++ <= retries)
    {
        rc = nodeCacheMemberGetFast(node, pMember, compat);
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
        {
            clOsalSemUnlock(gClNodeCacheSem);
            if(i > retries)
                goto out;
            clOsalTaskDelay(delay);
            delay.tsMilliSec += msecDelay; /* Back off the time as retries increase */
            clOsalSemLock(gClNodeCacheSem);
        }
        else break;
    }
    clOsalSemUnlock(gClNodeCacheSem);

    out:
    return rc;
}
/*
 * Create the section if it doesn't exist.
 * Called on becoming active
 */
SaAisErrorT alarmClockCkptActivate(SaCkptCheckpointHandleT ckptHdl, ClUint32T section_num)
{
    SaAisErrorT rc = SA_AIS_OK;
    SaCkptSectionIdT *id;

    if(section_num > NUM_SECTION_ID_MAPS)
        return SA_AIS_ERR_INVALID_PARAM;

    id = &sectionIdMap[section_num-1].sectionId;

    rc = clCkptSectionCheck(ckptHdl, (ClCkptSectionIdT*)id);
    if(rc != CL_OK)
    {
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
        {
            rc = alarmClockCkptSectionCreate(ckptHdl, 1);
            if(rc == SA_AIS_OK)
            {
                alarmClockLogWrite(CL_LOG_SEV_INFO, 
                                   "alarmClockActivate: Section [%.*s] created successfully", 
                                   id->idLen, (const char *)id->id);
            }
        }
        else rc = SA_AIS_ERR_UNAVAILABLE; /* internal error */
    }
    else rc = SA_AIS_OK;

    if(rc != SA_AIS_OK)
    {
        alarmClockLogWrite(CL_LOG_SEV_INFO, "alarmClockActivate: Section operation on section [%d] "
                           "failed with [%#x]", section_num, rc);
    }
    
    return rc;
}
/**
 * API to checkpoint current state of transaction-service
 */
ClRcT clTxnServiceCkptAppStateCheckpoint()
{
    ClRcT rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        rc = clCkptLibraryCkptDataSetWrite(clTxnServiceCfg->txnCkptHandle, &txnCkptName,
                                           CL_TXN_SERVICE_DATA_SET, 0x0);

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to write data-set [0x%x], rc:0x%x",
                                            CL_TXN_SERVICE_DATA_SET, rc));
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
/**
 * API to restore recovery logs of previously active transactions
 * from check-point
 */
ClRcT clTxnServiceCkptRecoveryLogRestore()
{
    ClRcT       rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Restoring transaction-recovery logs"));

        /* AD-1: To use the checkpoint exists api to check whether its recovery or
         * normal startup */
        clLogDebug("SER", NULL,
                   "Checkpoint exists, reading data for recovery");
        rc = clCkptLibraryCkptDataSetRead(clTxnServiceCfg->txnCkptHandle, &txnCkptName,
                                          CL_TXN_RECOVERY_DATA_SET, 0x0);

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to restore transaction-service state. rc:0x%x", rc));
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
/*******************************************************************************
Feature  API: alarmClockCkptWrite

Description : 

This API will not attempt to validate arguments, the thinking being that 
this is a volitional act by the invoker of this API to ensure that invalid 
parameters can be handled gracefully by the subsystem

Arguments In: 
    1. ClCkptHdlT : ckpt handle
    2. section number
    3. data to write
    4. size of data to write 

Return Value:
    ClInt32Teger 0 if success, non zero if failure
*******************************************************************************/
ClRcT 
alarmClockCkptWrite (
    ClCkptHdlT     ckpt_hdl,
    ClInt32T       section_num,
    void*          data,
    ClInt32T       data_size )
{
    ClRcT                ret_code = CL_OK;
    ClInt32T             pid = getpid();
    ClCharT              section_id_name[ CL_MAX_NAME_LENGTH ];
    ClCkptSectionIdT     section_id;

    sprintf(section_id_name, "s%05d", section_num);
    section_id.id = (ClUint8T*)section_id_name;
    section_id.idLen = strlen(section_id_name);

    ret_code = clCkptSectionOverwrite(ckpt_hdl,
                                      &section_id,
                                      data, data_size);
    if (ret_code != CL_OK)
    {
        if(CL_GET_ERROR_CODE(ret_code) == 0xa || 
           CL_GET_ERROR_CODE(ret_code) == CL_ERR_NOT_EXIST)
        {
            ClCkptSectionCreationAttributesT     section_cr_attr;
            section_cr_attr.sectionId = &section_id;
            section_cr_attr.expirationTime = (ClTimeT)CL_TIME_END;
            ret_code = clCkptSectionCreate(ckpt_hdl, &section_cr_attr,
                                           data, data_size);
        }
    }

    if(ret_code != CL_OK)
    {
            alarmClockLogWrite(CL_LOG_SEV_ERROR, 
                               "alarmClockCkptWrite(pid=%d): Failed to write: 0x%x\n", 
                               pid, ret_code); 
    }
    else
    {
        alarmClockLogWrite(CL_LOG_SEV_DEBUG, 
                           "alarmClockCkptWrite(pid=%d): wrote %d bytes to %s\n", 
                           pid, data_size, section_id_name); 
    }

    return ret_code;
}
ClRcT
clLogStreamOwnerCheckpointCreate(ClLogSOEoDataT  *pSoEoEntry,
                                 SaNameT         *pCkptName,
                                 ClHandleT       *phCkpt)
{
    ClRcT         rc     = CL_OK;
    ClCkptCheckpointCreationAttributesT  creationAtt    = {0};
    ClCkptOpenFlagsT                     openFlags      = 0;
    ClLogSvrCommonEoDataT                *pCommonEoData = NULL;
    ClUint32T                            sectionSize    = 0;
    ClInt32T                             tries = 0;
    ClIocNodeAddressT                    localAddr = clIocLocalAddressGet();
    static ClTimerTimeOutT delay = { 0,  500};

    CL_LOG_DEBUG_TRACE(("Enter"));
    
    rc = clLogStreamOwnerEoEntryGet(NULL, &pCommonEoData);
    if( CL_OK != rc )
    {
        return rc;
    }

    creationAtt.creationFlags     = CL_CKPT_CHECKPOINT_COLLOCATED | CL_CKPT_ALL_OPEN_ARE_REPLICAS;
    creationAtt.checkpointSize    = pCommonEoData->maxStreams * CL_LOG_SO_SEC_SIZE; 
    creationAtt.retentionDuration = CL_STREAMOWNER_CKPT_RETENTION_DURATION;
    creationAtt.maxSections       = pCommonEoData->maxStreams;
    sectionSize                   = pCommonEoData->maxComponents * sizeof(ClLogCompKeyT); 
    creationAtt.maxSectionSize    = CL_LOG_SO_SEC_SIZE + sectionSize;
    creationAtt.maxSectionIdSize  = CL_LOG_SO_SEC_ID_SIZE;

    openFlags = CL_CKPT_CHECKPOINT_CREATE | CL_CKPT_CHECKPOINT_WRITE | CL_CKPT_CHECKPOINT_READ;

    reopen:
    rc = clCkptCheckpointOpen(pCommonEoData->hSvrCkpt, pCkptName, &creationAtt, openFlags, 5000L, &pSoEoEntry->hCkpt);
    if( rc != CL_OK )
    {
        /*
         * No replica found and we are the only master.
         * Delete and try re-opening the checkpoint
         */
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_NO_RESOURCE &&
           pCommonEoData->masterAddr == localAddr)
        {
            if(tries++ < 1)
            {
                clLogNotice("CKP", "GET", "No replica for log checkpoint."
                            "Deleting ckpt [%.*s] and retrying the ckpt open",
                            pCkptName->length, pCkptName->value);
                clCkptCheckpointDelete(pCommonEoData->hSvrCkpt, pCkptName);
                clOsalTaskDelay(delay);
                goto reopen;
            }
        }
        CL_LOG_DEBUG_ERROR(("clCkptCheckpointOpen(): rc[0x %x]", rc));
    }    

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}    
ClRcT clCkptEntryUpdate(ClCachedCkptSvcInfoT *serviceInfo,
                        const ClCachedCkptDataT *sectionData)
{
    ClRcT rc;

    SaCkptSectionIdT ckptSectionId = {        /* Section id for checkpoints   */
        sectionData->sectionName.length,
        (SaUint8T *) sectionData->sectionName.value
    };

    ClUint8T *ckptedData, *copyData;
    ClSizeT ckptedDataSize = sectionData->dataSize + sizeof(ClIocAddressT);
    ClUint32T network_byte_order;
    ClInt32T tries = 0;
    ClTimerTimeOutT delay = { 0,  500 };

    ckptedData = (ClUint8T *) clHeapAllocate(ckptedDataSize);
    if(ckptedData == NULL)
    {
        rc = CL_ERR_NO_MEMORY;
        clLogError("CCK", "UPD", "Failed to allocate memory. error code [0x%x].", rc);
        goto out1;
    }

    /* Marshall section data*/
    copyData = ckptedData;
    network_byte_order = (ClUint32T) htonl((ClUint32T)sectionData->sectionAddress.iocPhyAddress.nodeAddress);
    memcpy(copyData, &network_byte_order, sizeof(ClUint32T));
    copyData = copyData + sizeof(ClUint32T);
    network_byte_order = (ClUint32T) htonl((ClUint32T)sectionData->sectionAddress.iocPhyAddress.portId);
    memcpy(copyData, &network_byte_order, sizeof(ClUint32T));
    copyData = copyData + sizeof(ClUint32T);
    memcpy(copyData, sectionData->data, sectionData->dataSize);

    /* Try to update the section */
retry:
    rc = clCkptSectionOverwrite(serviceInfo->ckptHandle,         /* Checkpoint handle  */
                                (ClCkptSectionIdT *)&ckptSectionId,         /* Section ID         */
                                ckptedData,             /* Initial data       */
                                ckptedDataSize);        /* Size of data       */
    if (CL_ERR_TRY_AGAIN == CL_GET_ERROR_CODE(rc))
    {
        if ((++tries < 5) && (clOsalTaskDelay(delay) == CL_OK))
        {
            goto retry;
        }
    }
    if (rc != CL_OK)
    {
        clLogError("CCK", "UPD", "CkptSectionUpdate failed with rc [0x%x].",rc);
        goto out2;
    }

out2:
    clHeapFree(ckptedData);
out1:
    return rc;
}
ClRcT _clTxnAgentAppendActiveJob(CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;
    ClTxnDefnT              *pTxnDefn;
    ClCntNodeHandleT        currTxnNode;
    ClCharT                 pOutMsg[1024];
    
    CL_FUNC_ENTER();
   
    rc = clCntFirstNodeGet(clTxnAgntCfg->activeTxnMap, &currTxnNode);
    
    while (rc == CL_OK)
    {
        ClCntNodeHandleT    nodeTxn;
        ClCntNodeHandleT    currJobNode;
        ClTxnAppJobDefnT    *pNewTxnJob;
        
        /* Retrieve data-node for node */
        rc = clCntNodeUserDataGet(clTxnAgntCfg->activeTxnMap, currTxnNode,
                                           (ClCntDataHandleT *)&pTxnDefn);
        if(CL_OK != rc)
        {
            clLogError("AGT", "CLI",
                    "User data get failed with error [0x%x]", rc);
            
            return rc;
        }
        
        rc = clCntFirstNodeGet(pTxnDefn->jobList, &currJobNode);
        
        while (rc == CL_OK)
        {
            ClCntNodeHandleT        nodeJob;
        
            /* Retrieve data-node for node */
            rc = clCntNodeUserDataGet(pTxnDefn->jobList, currJobNode,
                                           (ClCntDataHandleT *)&pNewTxnJob);
            pOutMsg[0] = '\0';
            sprintf(pOutMsg,
                    "   0x%x:0x%x\t|   0x%x\t|   %30s \n",
                    pTxnDefn->serverTxnId.txnMgrNodeAddress, pTxnDefn->serverTxnId.txnId,
                    pNewTxnJob->jobId.jobId, gCliTxnStatusStr[pNewTxnJob->currentState]);
 
            clXdrMarshallArrayClUint8T(&pOutMsg, strlen((char*)pOutMsg), outMsg, 0);
  
            nodeJob = currJobNode;
            rc = clCntNextNodeGet(pTxnDefn->jobList, nodeJob, &currJobNode);
        }
        
        nodeTxn = currTxnNode;
        rc = clCntNextNodeGet(clTxnAgntCfg->activeTxnMap, nodeTxn, &currTxnNode);
    }
    if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
        rc = CL_OK;

    CL_FUNC_EXIT();
    return(rc);
}
static ClRcT
clLogDoLogWrite(ClLogDeferredHeaderT  *pMsg, 
                ClUint16T             numRecs,
                ClUint16T             *pNumNotFlushed)
{
   ClUint16T  idx = 0;
   ClRcT      rc  = CL_OK;

   *pNumNotFlushed = numRecs;
   while( idx < numRecs )
   {
        /*
         * If the handle is 0, redirecting the output to SYS file,
         * two reasons, those are ASP components logs came before 
         * log library initialization, or really bad handle logs,
         * either case just redirecting to the file
         */
        if( pMsg[idx].handle == CL_HANDLE_INVALID_VALUE )
        {
            if( CL_LOG_HANDLE_SYS == CL_HANDLE_INVALID_VALUE )
            {
                /* still log library has not been initialized */
                idx++;
                continue;
            }
            pMsg[idx].handle = CL_LOG_HANDLE_SYS;
        }
        rc = clLogWriteWithHeader(pMsg[idx].handle,
                                  pMsg[idx].severity,
                                  pMsg[idx].serviceId,
                                  pMsg[idx].msgId,   
                                  pMsg[idx].msgHeader,
                                  "%s", pMsg[idx].msg);
        if( CL_OK != rc ) 
        {
            if( CL_GET_ERROR_CODE(rc) == CL_ERR_INVALID_HANDLE )
            {
                idx++;
                continue;
            }
            /*
             * log client is not seem to be ready, 
             * just go back and sleep 
             */
            break;      
        }
        idx++;
    }
   /* return num of not flushed records  */
    if( idx != 0 )
    {
      *pNumNotFlushed -= idx;
      //fprintf(stderr, "Num of not flushed records [%d], written [%d] pid [%d]\n", *pNumNotFlushed,
        //      idx, getpid());
    }
    
    return CL_OK;
}
ClRcT clTxnAgentListCreate(ClCntHandleT *pAgentCntHandle)
{
    ClRcT   rc  = CL_OK;
    CL_FUNC_ENTER();
    rc = clCntLlistCreate(_clTxnAgentCmpFn, _clTxnAgentDelFn, 
                                            _clTxnAgentDestroy,
                                            CL_CNT_UNIQUE_KEY,
                                            pAgentCntHandle);
    CL_FUNC_EXIT();
    return (CL_GET_ERROR_CODE(rc));
}
ClRcT
clLogClntStreamEntryGet(ClLogClntEoDataT  *pClntEoEntry,
                        SaNameT           *pStreamName,
                        SaNameT           *pNodeName,
                        ClStringT         *pShmName,
                        ClUint32T         shmSize,
                        ClCntNodeHandleT  *phStreamNode,
                        ClBoolT           *pAddedEntry)
{
    ClRcT             rc            = CL_OK;
    ClLogStreamKeyT   *pStreamKey   = NULL;

    CL_LOG_DEBUG_TRACE(("Enter"));

    *pAddedEntry = CL_FALSE;

    rc = clLogClntEoEntryGet(&pClntEoEntry);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clLogClntEoEntryGet(): rc[0x %x]", rc));
        return rc;
    }

    rc = clLogStreamKeyCreate(pStreamName, pNodeName,
                              pClntEoEntry->maxStreams, &pStreamKey);
    if( CL_OK != rc )
    {
        return rc;
    }

    rc = clCntNodeFind(pClntEoEntry->hClntStreamTable,
                       (ClCntKeyHandleT) pStreamKey,
                       phStreamNode);
    if( CL_ERR_NOT_EXIST == CL_GET_ERROR_CODE(rc) )
    {
        rc = clLogClntStreamEntryAdd(pClntEoEntry->hClntStreamTable,
                                     pStreamKey, pShmName, shmSize,
                                     phStreamNode);
        if( CL_OK != rc )
        {
            clLogStreamKeyDestroy(pStreamKey);
        }
        else
        {
            *pAddedEntry = CL_TRUE;
        }
        return rc;
    }
    clLogStreamKeyDestroy(pStreamKey);

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
ClRcT
clLogSvrCkptGet(ClLogSvrEoDataT        *pSvrEoEntry,
                ClLogSvrCommonEoDataT  *pSvrCommonEoEntry,
                ClBoolT                *pLogRestart)
{
    ClRcT    rc         = CL_OK;
    ClBoolT  ckptExists = CL_FALSE;

    CL_LOG_DEBUG_TRACE(("Enter"));

    *pLogRestart = CL_FALSE;
    rc = clCkptLibraryDoesCkptExist(pSvrCommonEoEntry->hLibCkpt,
                                    (SaNameT *) &gSvrLocalCkptName,
                                    &ckptExists);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptLibraryDoesCkptExist(): rc[0x %x]", rc));
        return rc;
    }

    rc = clLogSvrCkptCreate(pSvrEoEntry, pSvrCommonEoEntry);

    if(CL_OK != rc)
    {
        return rc;
    }

    if( CL_TRUE == ckptExists )/*Log Service restart*/
    {
        *pLogRestart = CL_TRUE;
        rc = clLogSvrStateRecover(pSvrEoEntry, pSvrCommonEoEntry);
        if( CL_OK != rc )
        {
            /*
             * Just restart incase there were no streamowners checkpointed in the first place
             */
            if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
            {
                rc = CL_OK;
                *pLogRestart = CL_FALSE;
            }
            else
            {
                CL_LOG_DEBUG_ERROR(("clCkptLibraryDoesCkptExist(): rc[0x %x]", rc));
                return rc;
            }
        }
    }

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
ClRcT _clTxnAgentAppendServices(CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;
    ClTxnAgentCompServiceInfoT  *pCompInstance;
    ClCntNodeHandleT        currNode;
    ClCharT                 pOutMsg[1024];
    
    CL_FUNC_ENTER();
   
    rc = clCntFirstNodeGet(clTxnAgntCfg->compServiceMap, &currNode);
    
    while (rc == CL_OK)
    {
        ClCntNodeHandleT        node;
        /* Retrieve data-node for node */
        rc = clCntNodeUserDataGet(clTxnAgntCfg->compServiceMap, currNode,
                                       (ClCntDataHandleT *)&pCompInstance);
        if(CL_OK != rc)
        {
            clLogError("AGT", "CLI",
                    "User data get failed with error [0x%x]", rc);
            return rc;
        }

         pOutMsg[0] = '\0';

        if(pCompInstance->serviceCapability == CL_TXN_AGENT_SERVICE_2PC)
        {
            sprintf(pOutMsg,
                    "   %6d\t|   2PC Capable  \n",
                    pCompInstance->serviceType);
        }
        else if(pCompInstance->serviceCapability == CL_TXN_AGENT_SERVICE_1PC)
        {
            sprintf(pOutMsg,
                    "   %6d\t|   1PC Capable  \n",
                    pCompInstance->serviceType);
        }

        clXdrMarshallArrayClUint8T(&pOutMsg, strlen((char*)pOutMsg), outMsg, 0);
        
        node = currNode;
        rc = clCntNextNodeGet(clTxnAgntCfg->compServiceMap, node, &currNode);
    }
    if(CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
        rc = CL_OK;
    
    CL_FUNC_EXIT();
    return(rc);
}
/**
 *  Returns an OM class entry.
 *
 *  This function returns a pointer to an OM class entry given 
 * OM class Id.
 *                                                                        
 *  @param omClassKey - OM class type
 *
 *  @returns 
 *    Pointer to class control block
 */
ClOmClassControlBlockT *
clOmClassEntryGet(ClOmClassTypeT omClassKey)
{
	ClRcT			rc = CL_OK;
#ifdef CL_DEBUG
	ClUint8T		aFuncName[] = "clOmClassEntryGet()";
#endif
	ClCntNodeHandleT tempNodeHandle = 0;
	ClOmClassControlBlockT 		*pClassEntry = 0;

    CL_FUNC_ENTER();

	if ((rc = omClassTypeValidate(omClassKey)) != CL_OK)
	{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Invalid input OM class (rc = 0x%x)!\r\n", 
			aFuncName, rc));
		CL_ASSERT(NULL);
		CL_FUNC_EXIT();
		return NULL;
	}

	/* find the node for this MO ID */
	if ((rc = clCntNodeFind(ghOmClassHashTbl, 
		(ClCntKeyHandleT)(ClWordT)omClassKey, &tempNodeHandle)) != CL_OK)
		{
		if (CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
			{
			CL_DEBUG_PRINT(CL_DEBUG_INFO, ("%s: Node does not exist for OM class "
				"(0x%x), with rc 0x%x!\r\n", aFuncName, omClassKey, rc));
			}
		else
			{
			CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to find node for OM class "
				"(0x%x), with rc 0x%x!\r\n", aFuncName, omClassKey, rc));
			}
		return NULL;
		}
	/* now get the OM handle for this MO ID */
	if ((rc = clCntNodeUserDataGet(ghOmClassHashTbl, 
		tempNodeHandle, (ClCntDataHandleT *)&pClassEntry)) != CL_OK)
		{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to get the OM class entry from the "
			"node for OM class 0x%x, with rc 0x%x!\r\n", aFuncName, 
			omClassKey, rc));
		CL_ASSERT(NULL);
		return  NULL;
		}
 	
   	return pClassEntry;
}
/**
 * Internal function to unpack saved state of a transaction
 * from checkpoint
 */
static ClRcT _clTxnServiceCkptTxnUnpack(
    CL_IN   ClUint32T   dataSetId,
    CL_IN   ClAddrT     pData,
    CL_IN   ClUint32T   dataLen,
    CL_IN   ClPtrT      cookie)
{
    ClRcT                   rc = CL_OK;
    ClBufferHandleT  txnStateBuf;
    ClTxnDefnT              *pTxnDefn;

    CL_FUNC_ENTER();

    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("To unpack data-set 0x%x\n", dataSetId));
    rc = clBufferCreate(&txnStateBuf);

    if (CL_OK == rc)
    {
        rc = clBufferNBytesWrite(txnStateBuf, (ClUint8T *)pData, dataLen);

        if (CL_OK == rc)
        {
            rc = clTxnStreamTxnCfgInfoUnpack(txnStateBuf, &pTxnDefn);
        }

        if ( (CL_OK == rc) &&
                ((pTxnDefn->serverTxnId.txnId + CL_TXN_CKPT_TXN_DATA_SET_ID_OFFSET) == dataSetId) )
        {
            /* Add this definition into txnDefnDb */
            rc = clTxnRecoverySessionUpdate (pTxnDefn);
        }
        else
        {
            if (CL_OK == rc)
                rc = CL_ERR_INVALID_PARAMETER;
        }

        rc = clBufferDelete(&txnStateBuf);

    }
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                       ("Failed to extract transaction definition from data-set[0x%x], rc:0x%x", dataSetId, rc));
        rc = CL_GET_ERROR_CODE(rc);
    }

    CL_FUNC_EXIT();
    return (rc);
}
ClRcT clMsgFinalizeBlocker(void)
{
    ClRcT rc = CL_OK;
    SaTimeT timeout = (SaTimeT)(CL_MSG_FIN_BLOCK_TIME * 1000000000LL);
    ClTimerTimeOutT tempTime = {0};

    CL_OSAL_MUTEX_LOCK(&gFinBlockMutex);

    if(gMsgMoveStatus == MSG_MOVE_DONE)
        goto out;

    clLogDebug("FIN", "BLOCK", "Message service finalize will be blocked for [%llu ns].", timeout);

    if(gMsgMoveStatus == MSG_MOVE_FIN_UNINIT)
    {
        rc = clOsalTaskCreateDetached("allClosedQueueMoverThread", CL_OSAL_SCHED_OTHER, CL_OSAL_THREAD_PRI_NOT_APPLICABLE, 0, clMsgClosedQueueMoveThread, NULL);
        if(rc != CL_OK)
        {
            clLogError("FIN", "BLOCK", "Failed to create a Queue mover thread. error code [0x%x].", rc);
            goto error_out;
        }
        clMsgTimeConvert(&tempTime, timeout);

        rc = clOsalCondWait(gFinBlockCond, &gFinBlockMutex, tempTime);
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_TIMEOUT)
        {   
            clLogError("FIN", "BLOCK", "Finalize blocking timed out. Timeout is [%lld ns]. error code [0x%x].", timeout, rc);
        }   
        else if(rc != CL_OK)
        {
            clLogError("FIN", "BLOCK", "Failed at Conditional Wait. error code [0x%x].", rc);
        }
        else
        {
            clLogDebug("FIN", "BLOCK", "Message queues are failed over to [0x%x] node.", gQMoveDestNode);
        }
    }

    gMsgMoveStatus = MSG_MOVE_DONE;

    goto out;

    error_out:
    out:
    CL_OSAL_MUTEX_UNLOCK(&gFinBlockMutex);
     
    return rc;
}