SaAisErrorT saCkptSectionOverwrite(
        SaCkptCheckpointHandleT checkpointHandle,
        const SaCkptSectionIdT  *sectionId,
        const void              *dataBuffer,
        SaSizeT                 dataSize)
{
    ClRcT          rc    = CL_OK;
    SaAisErrorT    safRc = SA_AIS_OK;

    /*
     * Call the corresponding ckpt client library function.
     */
    rc = clCkptSectionOverwrite( (ClCkptHdlT) checkpointHandle,
            (ClCkptSectionIdT   *)sectionId,
            (void *)dataBuffer,
            (ClSizeT)dataSize);


    /*
     * Translate the clovis error type to SAF error type.
     */
    clErrorTxlate(rc, &safRc);
    
    return safRc;
}
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
clTestSectionOverwrite_withTime(ClCkptHdlT  ckptHdl,
                      ClUint32T   numSections,
                      ClUint32T   sectionSize)
{
    ClRcT             rc = CL_OK;
    ClUint32T         i  = 0, j = 0, secNum = 0;
    ClUint8T          data[sectionSize];
    ClCkptSectionIdT  secId[numSections];
    ClUint32T         timeDelay[] = {1000000, 100000, 10000, 1000, 100, 10 , 0};

    memset(data, 'a', sectionSize);
    for( i = 0; i < numSections; i++ )
    {
        secId[i].id = clHeapCalloc(1, 15); 
        if( NULL == secId[i].id )
        {
            return CL_OK;
        }
        snprintf((ClCharT *) secId[i].id, 15, "section%d", i);
        secId[i].idLen = strlen((ClCharT *) secId[i].id) + 1;
    }

    for( i = 0; i < sizeof(timeDelay) / sizeof(timeDelay[0]); i++ )
    {
        for( j = 0; j < 1000; j++ )
        {
            for( secNum = 0; secNum < numSections; secNum++ )
            {
                rc = clCkptSectionOverwrite(ckptHdl, &secId[secNum], data, sectionSize);
                if( CL_OK != rc )
                {
                   printf("Section overwrite failed rc[0x %x]", rc);
                }
                usleep(timeDelay[i]);
            }
        }
    }

    if( numSections != 1 )
    {
        for( i = 0; i < numSections; i++ )
        {
            clHeapFree(secId[i].id);
        }
    }
    return CL_OK;
}
/*******************************************************************************
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
clTestSectionOverwrite(ClCkptHdlT  ckptHdl,
                      ClUint32T   numSections,
                      ClUint32T   sectionSize,
                      ClTimeT     *pTime)
{
    ClRcT             rc = CL_OK;
    ClUint32T         i  = 0;
    ClUint8T          data[sectionSize];
    ClCkptSectionIdT  secId[numSections];
    ClTimeT oldTime = 0;
    ClTimeT newTime = 0;
    ClCkptSectionIdT  defaultSecId = CL_CKPT_DEFAULT_SECTION_ID;
    ClUint32T         numWrites    = 0;

    memset(data, 'a', sectionSize);

    if( numSections != 1 )
    {
        for( i = 0; i < numSections; i++ )
        {
            secId[i].id = clHeapCalloc(1, 15); 
            if( NULL == secId[i].id )
            {
                return CL_OK;
            }
            snprintf((ClCharT *) secId[i].id,15, "section%d", i);
            secId[i].idLen = strlen((ClCharT *) secId[i].id) + 1;
        }
        numWrites = numSections;
    }
    if( numSections == 1 )
    {
        numWrites = 100;
        oldTime = clOsalStopWatchTimeGet();
        for( i = 0; i < numWrites; i++ )
        {
            rc = clCkptSectionOverwrite(ckptHdl, &defaultSecId, data, sectionSize);
        }
        newTime = clOsalStopWatchTimeGet();
    }
    else
    {
        oldTime = clOsalStopWatchTimeGet();
        for( i = 0; i < numWrites; i++ )
        {
            rc = clCkptSectionOverwrite(ckptHdl, &secId[i], data, sectionSize);
        }
        newTime = clOsalStopWatchTimeGet();
    }

    *pTime = newTime - oldTime;

    if( numSections != 1 )
    {
        for( i = 0; i < numSections; i++ )
        {
            clHeapFree(secId[i].id);
        }
    }
    return CL_OK;
}
/*******************************************************************************
Feature  API: clTcCkptWrite

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. ClTcCkptDataT : contains the ckpt handle
	2. Section Name Prefix; if NULL no section names; if not NULL then the 
	                        section names will range from 
							<section_name_Prefix>1 to <section_name_prefix>9999
	3. section number
	4. data to write
	5. size of data to write 

Arguments Out:
	1. ClTcCkptDataT : returns time taken to write the section

Return Value:
	integer 0 if success, non zero if failure
*******************************************************************************/
int clTcCkptWrite (
	ClTcCkptDataT* ckpt_data,
	const char*	   section_name_prefix,
	int			   section_num,
	void*		   data,
	int			   data_size )
{
	ClRcT 						ret_code = CL_OK;
#if GO_TO_SECTION_DIRECTLY
	ClCharT						section_id_name[ CL_MAX_NAME_LENGTH ];
#endif
    ClCkptSectionIdT    		section_id;

    ClTimeT startTime = 0;
    ClTimeT endTime = 0;
	ClTimeT					time_taken_us = 0;


	/* Does the ckpt_data have a valid chek point handle
	 */

	
	/* we either iterate through the sections until
	 * we get to the section of interest; or go directly
	 * to the section, assuming a known section Id; 
	 * the former is more general purpose and will be used here
	 */
#if GO_TO_SECTION_DIRECTLY
	if ( section_name_prefix != NULL )
	{
		snprintf(section_id_name,CL_MAX_NAME_LENGTH, "%s%05d", section_name_prefix, section_num);
	}
	else
	{
		snprintf(section_id_name,CL_MAX_NAME_LENGTH, "s%05d", section_num);
	}
	section_id.id = (ClUint8T*)section_id_name;
	section_id.idLen = strlen(section_id_name);
#else
	ret_code = clTcIterToSectionId(ckpt_data, section_num, &section_id);

	if (ret_code != CL_OK)
	{
		printf("clTcCkptWrite: Failed to get section id: 0x%x\n", ret_code); 
		return ret_code;
	}
#endif

	/* Set the local replica to be active 
	 * the api sets it only if required (i.e the type is async collocated)
	 */
	ret_code = clTcActivateReplica(ckpt_data);
	if (ret_code != CL_OK)
	{
		printf("clTcCkptWrite: Failed to activate ckpt: 0x%x\n", ret_code); 
		return ret_code;
	}

	/* time check 1 start 
 	 */
    startTime = clOsalStopWatchTimeGet();
	ret_code = clCkptSectionOverwrite((ClCkptHdlT)ckpt_data->ckpt_hdl,
									  &section_id,
									  data, data_size);
	/* time check 1 end 
	 */
    endTime = clOsalStopWatchTimeGet();
	time_taken_us = endTime - startTime;

	ckpt_data->time_taken_ms = 0;
	ckpt_data->time_taken_us  = time_taken_us;

	if (ret_code != CL_OK)
	{
		printf("clTcCkptWrite: Failed to write: 0x%x\n",
			   ret_code); 
	}

	return ret_code;
}
static ClRcT
clLogMasterFileEntryCheckpoint(ClLogMasterEoDataT  *pMasterEoEntry,
                               ClCntNodeHandleT    hFileNode,
                               ClBoolT             addSection)
{
    ClRcT                             rc        = CL_OK;
    ClUint8T                          *pBuffer  = NULL;
    ClUint32T                         bufferLen = 0;
    ClCkptSectionIdT                  secId     = {0};
    ClCkptSectionCreationAttributesT  secAttr   = {0};

    CL_LOG_DEBUG_TRACE(("Enter"));

    rc = clLogMasterFileEntryPack(pMasterEoEntry, hFileNode, &secId, &pBuffer,
                                  &bufferLen);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clLogMasterFileEntryPack(): rc[0x %x]", rc));
        return rc;
    }

    if( CL_TRUE == addSection )
    {
        secAttr.sectionId      = &secId;
        secAttr.expirationTime = CL_TIME_END;
        rc = clCkptSectionCreate(pMasterEoEntry->hCkpt, &secAttr, NULL, 0);
        if( CL_OK != rc )
        {
            if(CL_GET_ERROR_CODE(rc) == CL_ERR_ALREADY_EXIST)
            {
                rc = CL_OK;
                addSection = CL_FALSE;
            }
            else
            {
                CL_LOG_DEBUG_ERROR(("clCkptSectionCreate(): rc[0x %x]", rc));
                clHeapFree(secId.id);
                clHeapFree(pBuffer);
                return rc;
            }
        }
    }

    rc = clCkptSectionOverwrite(pMasterEoEntry->hCkpt, &secId, pBuffer,
                                bufferLen);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptSectionOverwrite(): rc[0x %x]", rc));
        if( CL_TRUE == addSection )
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pMasterEoEntry->hCkpt, &secId),
                           CL_OK);
            clHeapFree(secId.id);
            clHeapFree(pBuffer);
            return rc;
        }
    }

    clHeapFree(secId.id);
    clHeapFree(pBuffer);

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
static ClRcT clLogMasterEoEntryCheckpoint(ClLogMasterEoDataT *pMasterEoEntry)
{
    ClRcT            rc          = CL_OK;
    ClBufferHandleT  hEoEntryBuf = CL_HANDLE_INVALID_VALUE;
    ClUint8T         *pBuffer    = NULL;
    ClUint32T        bufferLen   = 0;
    ClVersionT       version     = { CL_RELEASE_VERSION, CL_MAJOR_VERSION, CL_MINOR_VERSION };
    CL_LOG_DEBUG_TRACE(("Enter"));

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

    rc = clXdrMarshallClVersionT(&version, hEoEntryBuf, 0);

    if( CL_OK != rc)
    {
        CL_LOG_DEBUG_ERROR(("clXdrMarshallClVersionT(): rc[%#x]", rc));
        CL_LOG_CLEANUP(clBufferDelete(&hEoEntryBuf), CL_OK);
        return rc;
    }

    rc = clXdrMarshallClUint16T(&(pMasterEoEntry->nextStreamId),
                                hEoEntryBuf, 0);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clXdrMarshallClUint16T(): rc[0x %x]", rc));
        CL_LOG_CLEANUP(clBufferDelete(&hEoEntryBuf), CL_OK);
        return rc;
    }

    rc = clBufferLengthGet(hEoEntryBuf, &bufferLen);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clBufferLengthGet: rc[0x %x]", rc));
        CL_LOG_CLEANUP(clBufferDelete(&hEoEntryBuf), CL_OK);
        return rc;
    }

    rc = clBufferFlatten(hEoEntryBuf, &pBuffer);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clBufferFlatten(): rc[0x %x]", rc));
        CL_LOG_CLEANUP(clBufferDelete(&hEoEntryBuf), CL_OK);
        return rc;
    }

    rc = clCkptSectionOverwrite(pMasterEoEntry->hCkpt, &gLogMasterDefaultSectionId, pBuffer, bufferLen);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptSectionOverwrite(): rc[0x %x]", rc));
    }

    clHeapFree(pBuffer);
    CL_LOG_CLEANUP(clBufferDelete(&hEoEntryBuf), CL_OK);

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
ClRcT
clLogStreamOwnerGlobalCheckpoint(ClLogSOEoDataT         *pSoEoEntry,
                                 SaNameT                *pStreamName,
                                 SaNameT                *pStreamScopeNode,
                                 ClLogStreamOwnerDataT  *pStreamOwnerData)
{
    ClRcT                             rc                      = CL_OK;
    ClBufferHandleT                   msg                     = 
        CL_HANDLE_INVALID_VALUE;
    ClUint32T                         size                    = 0;
    ClAddrT                           pBuffer                 = NULL;
    ClCkptSectionIdT                  secId                   = {0};
    ClCkptSectionCreationAttributesT  secAttr                 = {0};
    ClBoolT                           createdSec              = CL_FALSE;
    ClUint32T                         prefixLen               = 0;
    ClUint32T                         versionCode             = 0;
    CL_LOG_DEBUG_TRACE(("Enter"));

    prefixLen   = strlen(soSecPrefix);
    secId.idLen = pStreamName->length + prefixLen; 
    secId.id    = (ClUint8T*)clHeapCalloc(secId.idLen, sizeof(ClCharT)); 
    if( NULL == secId.id )
    {
        CL_LOG_DEBUG_ERROR(("clHeapCalloc()"));
        return CL_LOG_RC(CL_ERR_NO_MEMORY);
    }    
    memcpy(secId.id, soSecPrefix, prefixLen);
    memcpy(secId.id + prefixLen, pStreamName->value,
           pStreamName->length); 
    if( CL_TRUE == pStreamOwnerData->isNewStream )
    {
        secAttr.sectionId      = &secId;
        secAttr.expirationTime = CL_TIME_END;
        rc = clCkptSectionCreate(pSoEoEntry->hCkpt, &secAttr, 
                                 NULL, 0);
        if( CL_OK != rc )
        {
            CL_LOG_DEBUG_ERROR(("clCkptSectionCreate(): rc[0x %x]", rc));
            clHeapFree(secId.id);
            return rc;
        }    
        pStreamOwnerData->isNewStream = CL_FALSE;
        createdSec = CL_TRUE;
    }    
    rc = clBufferCreate(&msg);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clBufferCreate(): rc[0x %x]", rc));
        if( CL_TRUE == createdSec )
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pSoEoEntry->hCkpt, &secId), 
                           CL_OK);
        }
        clHeapFree(secId.id);
        return rc;
    } 
    versionCode = CL_VERSION_CODE(CL_RELEASE_VERSION, CL_MAJOR_VERSION, CL_MINOR_VERSION);
    rc = clXdrMarshallClUint32T(&versionCode, msg, 0);
    if(CL_OK != rc)
    {
        CL_LOG_DEBUG_ERROR(("clXdrMarshallClVersionT() rc[%#x]", rc));
        CL_LOG_CLEANUP(clBufferDelete(&msg), CL_OK);
        if(CL_TRUE == createdSec)
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pSoEoEntry->hCkpt, &secId), CL_OK);
        }
        clHeapFree(secId.id);
        return rc;
    }

    rc = clLogStreamOwnerEntryPack(pStreamName, pStreamScopeNode, 
                                   pStreamOwnerData, msg);
    if( CL_OK != rc )
    {
        CL_LOG_CLEANUP(clBufferDelete(&msg), CL_OK);
        if( CL_TRUE == createdSec )
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pSoEoEntry->hCkpt, &secId), 
                           CL_OK);
        }
        clHeapFree(secId.id);
        return rc;
    }
    rc = clLogServerSerialiser(0, &pBuffer, &size, msg);
    if( CL_OK != rc )
    {
        CL_LOG_CLEANUP(clBufferDelete(&msg), CL_OK);
        if( CL_TRUE == createdSec )
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pSoEoEntry->hCkpt, &secId), 
                           CL_OK);
        }
        clHeapFree(secId.id);
        return rc;
    }    
    rc = clCkptSectionOverwrite(pSoEoEntry->hCkpt,
                                &secId,
                                pBuffer, size);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptSectionOverwrite(): rc[0x %x]", rc));
        if( CL_TRUE == createdSec )
        {
            CL_LOG_CLEANUP(clCkptSectionDelete(pSoEoEntry->hCkpt, &secId), 
                           CL_OK);
        }
    }    
    CL_LOG_CLEANUP(clBufferDelete(&msg), CL_OK);
    clHeapFree(pBuffer);
    clHeapFree(secId.id);
   
    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}