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, §ion_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 = §ion_id; section_cr_attr.expirationTime = (ClTimeT)CL_TIME_END; ret_code = clCkptSectionCreate(ckpt_hdl, §ion_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, §ion_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, §ion_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; }