/******************************************************************************* Feature API: alarmClockCkptRead 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 read 4. size of data to read Return Value: ClInt32Teger 0 if success, non zero if failure *******************************************************************************/ ClRcT alarmClockCkptRead ( ClCkptHdlT ckpt_hdl, ClInt32T section_num, void* data, ClInt32T data_size ) { ClRcT ret_code = CL_OK; ClUint32T error_index; ClCharT section_id_name[ CL_MAX_NAME_LENGTH ]; ClCkptIOVectorElementT io_vector; /* * Check if its in sync through hot standby update before reading */ if((g_hot_standby & __HOT_STANDBY_ACTIVE)) return CL_ERR_NO_OP; sprintf(section_id_name, "s%05d", section_num); io_vector.sectionId.id = (ClUint8T*)section_id_name; io_vector.sectionId.idLen = strlen(section_id_name); /* assign other fields of the IoVector */ io_vector.dataBuffer = data; io_vector.dataSize = data_size; io_vector.dataOffset = 0; io_vector.readSize = 0; ret_code = clCkptCheckpointRead(ckpt_hdl, &io_vector, 1, &error_index ); if (ret_code != CL_OK) { alarmClockLogWrite(CL_LOG_SEV_ERROR, "alarmClockCkptRead(pid=%d): (error_index=%d) " "Failed to read section [%s]: 0x%x\n", getpid(), error_index, section_id_name, ret_code); return ret_code; } else { if ( io_vector.readSize != data_size ) { alarmClockLogWrite(CL_LOG_SEV_ERROR, "alarmClockCkptRead(pid=%d): read %d bytes; expected %d bytes\n", getpid(), (ClInt32T)io_vector.readSize, data_size); } else { alarmClockLogWrite(CL_LOG_SEV_DEBUG, "alarmClockCkptRead(pid=%d): read %d bytes from %s\n", getpid(), data_size, section_id_name); } } return ret_code; }
ClRcT clTestCkptRead_withTime(ClCkptHdlT ckptHdl, ClUint32T numSections) { ClRcT rc = CL_OK; ClUint32T i = 0, j = 0; ClCkptIOVectorElementT iov[numSections]; ClUint32T readIdx = 0; ClUint32T timeDelay[] = {1000000, 100000, 10000, 1000, 100, 10 , 0}; memset(iov, 0, numSections * sizeof(ClCkptIOVectorElementT)); for( i = 0; i < numSections; i++ ) { if( numSections != 1 ) { iov[i].sectionId.id = clHeapCalloc(1, 15); if( NULL == iov[i].sectionId.id ) { return CL_OK; } snprintf( (ClCharT *) iov[i].sectionId.id,15, "section%d", i); iov[i].sectionId.idLen = strlen((ClCharT *) iov[i].sectionId.id) + 1; } iov[i].dataSize = 0; iov[i].dataBuffer = NULL; iov[i].readSize = 0; iov[i].dataOffset = 0; } for( i = 0; i < (sizeof(timeDelay) / sizeof(sizeof(timeDelay[0]))); i++ ) { for( j = 0; j < 1000; j++ ) { rc = clCkptCheckpointRead(ckptHdl, iov, numSections, &readIdx); for( i = 0; i < numSections; i++ ) { clHeapFree(iov[i].dataBuffer); iov[i].dataBuffer = NULL; } usleep(timeDelay[i]); } } for( i = 0; i < numSections; i++ ) { if( NULL != iov[i].sectionId.id ) { clHeapFree(iov[i].sectionId.id); } } return CL_OK; }
ClRcT clTestCheckpointReadWithOffSet(ClCkptHdlT ckptHdl, ClUint32T numSections) { ClRcT rc = CL_OK; ClUint32T i = 0; ClCkptIOVectorElementT iov[numSections]; ClUint32T readIdx = 0; memset(iov, 0, numSections * sizeof(ClCkptIOVectorElementT)); for( i = 0; i < numSections; i++ ) { if( numSections != 1 ) { iov[i].sectionId.id = clHeapCalloc(1, 15); if( NULL == iov[i].sectionId.id ) { return CL_OK; } snprintf( (ClCharT *) iov[i].sectionId.id, 15,"section%d", i); iov[i].sectionId.idLen = strlen((ClCharT *) iov[i].sectionId.id) + 1; } iov[i].dataSize = 30; if( NULL != (iov[i].dataBuffer = clHeapCalloc(1, iov[i].dataSize)) ) { iov[i].dataBuffer = NULL; } iov[i].readSize = 0; iov[i].dataOffset = 20; } rc = clCkptCheckpointRead(ckptHdl, iov, numSections, &readIdx); if( CL_OK != rc ) { return rc; } for( i = 0; i < numSections; i++ ) { if( NULL != iov[i].sectionId.id ) { clHeapFree(iov[i].sectionId.id); } clHeapFree(iov[i].dataBuffer); } return CL_OK; }
ClRcT clTestCkptRead(ClCkptHdlT ckptHdl, ClUint32T numSections, ClTimeT *pTime) { ClRcT rc = CL_OK; ClUint32T i = 0; ClCkptIOVectorElementT iov[numSections]; ClUint32T readIdx = 0; ClTimeT oldTime = 0; ClTimeT newTime = 0; ClCkptSectionIdT defaultSecId = CL_CKPT_DEFAULT_SECTION_ID; memset(iov, 0, numSections * sizeof(ClCkptIOVectorElementT)); for( i = 0; i < numSections; i++ ) { if( numSections != 1 ) { iov[i].sectionId.id = clHeapCalloc(1, 15); if( NULL == iov[i].sectionId.id ) { return CL_OK; } snprintf( (ClCharT *) iov[i].sectionId.id, 15,"section%d", i); iov[i].sectionId.idLen = strlen((ClCharT *) iov[i].sectionId.id) + 1; } else { iov[i].sectionId = defaultSecId; } iov[i].dataSize = 0; iov[i].dataBuffer = NULL; iov[i].readSize = 0; iov[i].dataOffset = 0; } if( numSections == 1 ) { oldTime = clOsalStopWatchTimeGet(); for( i = 0; i < 100; i++ ) { rc = clCkptCheckpointRead(ckptHdl, &iov[0], numSections, &readIdx); } newTime = clOsalStopWatchTimeGet(); } else { oldTime = clOsalStopWatchTimeGet(); rc = clCkptCheckpointRead(ckptHdl, iov, numSections, &readIdx); newTime = clOsalStopWatchTimeGet(); } *pTime = newTime - oldTime; for( i = 0; i < numSections; i++ ) { clHeapFree(iov[i].dataBuffer); if( NULL != iov[i].sectionId.id ) { clHeapFree(iov[i].sectionId.id); } } return CL_OK; }
/******************************************************************************* Feature API: clTcCkptRead 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 read 5. size of data to read Arguments Out: 1. ClTcCkptDataT : returns time taken to read the section Return Value: integer 0 if success, non zero if failure *******************************************************************************/ int clTcCkptRead ( ClTcCkptDataT* ckpt_data, const char* section_name_prefix, int section_num, void* data, int data_size ) { ClRcT ret_code = CL_OK; ClUint32T error_index; #if GO_TO_SECTION_DIRECTLY ClCharT section_id_name[ CL_MAX_NAME_LENGTH ]; #endif ClCkptIOVectorElementT io_vector; ClTimeT startTime = 0; ClTimeT endTime = 0; ClTimeT time_taken_us = 0; /* 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); } io_vector.sectionId.id = (ClUint8T*)section_id_name; io_vector.sectionId.idLen = strlen(section_id_name); #else ret_code = clTcIterToSectionId(ckpt_data, section_num, &io_vector.sectionId); if (ret_code != CL_OK) { printf("clTcCkptRead: Failed to get section id: 0x%x\n", ret_code); return ret_code; } #endif /* assign other fields of the IoVector */ io_vector.dataBuffer = NULL; io_vector.dataSize = data_size; io_vector.dataOffset = 0; io_vector.readSize = 0; /* time check 1 start */ startTime = clOsalStopWatchTimeGet(); ret_code = clCkptCheckpointRead((ClCkptHdlT)ckpt_data->ckpt_hdl, &io_vector, 1, &error_index ); /* 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("clTcCkptRead: Failed to read: 0x%x\n", ret_code); return ret_code; } else { if ( io_vector.readSize != data_size ) { printf("clTcCkptRead: Read %d bytes; expected %d bytes\n", (int)io_vector.readSize, data_size); } if (data_size <= io_vector.readSize) { memcpy(data, io_vector.dataBuffer, data_size); } else { memcpy(data, io_vector.dataBuffer, io_vector.readSize); } /* Free up buffer allocated by Ckpt Service */ clHeapFree(io_vector.dataBuffer); } return ret_code; }
ClRcT clLogMasterStateRecover(ClLogSvrCommonEoDataT *pCommonEoEntry, ClLogMasterEoDataT *pMasterEoEntry, ClBoolT switchover) { ClRcT rc = CL_OK; ClHandleT hSecIter = CL_HANDLE_INVALID_VALUE; ClCkptSectionDescriptorT secDescriptor = {{0}}; ClCkptIOVectorElementT ioVector = {{0}}; ClUint32T errIndex = 0; ClCkptSectionCreationAttributesT secAttr = {0}; ClBoolT logReadFlag = CL_FALSE; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogMasterEoEntrySet(pMasterEoEntry); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogMasterEoEntrySet(): rc[0x %x]", rc)); return rc; } if(switchover) { rc = clCkptActiveReplicaSetSwitchOver(pMasterEoEntry->hCkpt); } else { rc = clCkptActiveReplicaSet(pMasterEoEntry->hCkpt); } if (CL_OK != rc) { CL_LOG_DEBUG_ERROR(("clCkptActiveReplicaSet(): rc[%#x],switchover flag [%d]", rc, switchover)); return rc; } rc = clCkptSectionIterationInitialize(pMasterEoEntry->hCkpt, CL_CKPT_SECTIONS_ANY, CL_TIME_END, &hSecIter); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCkptSectionIterationInitialize(): rc[0x %x]", rc)); return rc; } do { rc = clCkptSectionIterationNext(hSecIter, &secDescriptor); if( CL_OK != rc) { break; } logReadFlag = CL_TRUE; if( pCommonEoEntry->masterAddr == clIocLocalAddressGet() ) { ioVector.sectionId = secDescriptor.sectionId; ioVector.dataBuffer = NULL; ioVector.dataSize = 0; ioVector.readSize = 0; ioVector.dataOffset = 0; clLogNotice(CL_LOG_AREA_MASTER, CL_LOG_CTX_CKPT_READ, "Got section [%.*s] to be read", secDescriptor.sectionId.idLen, secDescriptor.sectionId.id); if( 0 != strncmp((ClCharT *) ioVector.sectionId.id, (ClCharT *) gLogMasterCompDataSectionId.id, gLogMasterCompDataSectionId.idLen) ) { rc = clCkptCheckpointRead(pMasterEoEntry->hCkpt, &ioVector, 1, &errIndex); if( CL_OK == rc ) /* create whatever we can */ { if( 0 == strncmp((ClCharT *) ioVector.sectionId.id, (ClCharT *) gLogMasterDefaultSectionId.id, gLogMasterDefaultSectionId.idLen) ) { rc = clLogMasterEoEntryRecover(pMasterEoEntry, &ioVector, &errIndex); if( CL_OK != rc ) { clHeapFree(ioVector.dataBuffer); clHeapFree(ioVector.sectionId.id); break; /* break out of the loop, can't continue */ } clHeapFree(ioVector.dataBuffer); } else { /* create whatever we can */ clLogMasterFileEntryRecover(pMasterEoEntry, &ioVector, &errIndex); clHeapFree(ioVector.dataBuffer); } } } clHeapFree(secDescriptor.sectionId.id); } else { return rc; } } while( (rc == CL_OK) ); CL_LOG_CLEANUP(clCkptSectionIterationFinalize(hSecIter), CL_OK); if( CL_TRUE == logReadFlag ) { ioVector.sectionId = gLogMasterCompDataSectionId; ioVector.dataBuffer = NULL; ioVector.dataSize = 0; ioVector.readSize = 0; ioVector.dataOffset = 0; rc = clCkptCheckpointRead(pMasterEoEntry->hCkpt, &ioVector, 1, &errIndex); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCkptCheckpointRead():rc[0x %x]", rc)); return rc; } rc = clLogMasterCompTableStateRecover(pMasterEoEntry, (ClUint8T*) ioVector.dataBuffer, ioVector.readSize); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("Unable to recreate the state of compTable")); } clHeapFree(ioVector.dataBuffer); } else { secAttr.sectionId = &gLogMasterDefaultSectionId; secAttr.expirationTime = CL_TIME_END; rc = clCkptSectionCreate(pMasterEoEntry->hCkpt, &secAttr, NULL, 0); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCkptSectionCreate(): rc[0x %x]", rc)); return rc; } secAttr.sectionId = &gLogMasterCompDataSectionId; secAttr.expirationTime = CL_TIME_END; rc = clCkptSectionCreate(pMasterEoEntry->hCkpt, &secAttr, NULL, 0); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCkptSectionCreate(): rc[0x %x]", rc)); CL_LOG_CLEANUP(clCkptSectionDelete(pMasterEoEntry->hCkpt, &gLogMasterDefaultSectionId), CL_OK); } } CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
SaAisErrorT saCkptCheckpointRead(SaCkptCheckpointHandleT checkpointHandle, SaCkptIOVectorElementT *pIoVector, SaUint32T numberOfElements, SaUint32T *erroneousVectorIndex) { ClRcT rc = CL_OK; SaAisErrorT safRc = SA_AIS_OK; ClCkptIOVectorElementT *pTempVec = NULL; SaCkptIOVectorElementT *pTempOutVec = NULL; ClCkptIOVectorElementT *pInVector = NULL; ClUint32T count = 0; /* * Validate the input parameters. */ if(pIoVector == NULL) return SA_AIS_ERR_INVALID_PARAM; /* * Copy the iovector in clovis format. */ pTempVec = (ClCkptIOVectorElementT *)pIoVector; if(pIoVector != NULL) { pInVector = (ClCkptIOVectorElementT *)clHeapAllocate( sizeof(ClCkptIOVectorElementT) * numberOfElements); if(pInVector == NULL) { safRc = SA_AIS_ERR_NO_MEMORY; return safRc; } memset(pInVector, '\0', sizeof(ClCkptIOVectorElementT) * numberOfElements); pTempVec = pInVector; pTempOutVec = pIoVector; for(count = 0; count < numberOfElements; count ++) { pInVector->sectionId.idLen = pIoVector->sectionId.idLen; pInVector->sectionId.id = (ClUint8T *) clHeapAllocate( pIoVector->sectionId.idLen); if(pInVector->sectionId.id == NULL) { safRc = SA_AIS_ERR_NO_MEMORY; return safRc; } memset(pInVector->sectionId.id,'\0',pInVector->sectionId.idLen); memcpy(pInVector->sectionId.id, pIoVector->sectionId.id, pInVector->sectionId.idLen); pInVector->dataBuffer = (ClUint8T*)pIoVector->dataBuffer; pInVector->dataSize = pIoVector->dataSize; pInVector->dataOffset = pIoVector->dataOffset; pInVector->readSize = pIoVector->readSize; pInVector++; pIoVector++; } } /* * Call the corresponding ckpt client library function. */ rc = clCkptCheckpointRead( (ClCkptHdlT) checkpointHandle, pTempVec, (ClUint32T) numberOfElements, (ClUint32T *)erroneousVectorIndex); if(pTempVec != NULL) { pInVector = pTempVec; pIoVector = pTempOutVec; for(count = 0; count < numberOfElements; count++) { pIoVector->dataBuffer = pInVector->dataBuffer; pIoVector->readSize = pInVector->readSize; clHeapFree(pInVector->sectionId.id); pInVector++; pIoVector++; } clHeapFree(pTempVec); } pIoVector = pTempOutVec; /* * Translate the clovis error type to SAF error type. */ clErrorTxlate(rc, &safRc); return safRc; }
ClRcT clLogStreamOwnerGlobalEntryRecover(ClLogSOEoDataT *pSoEoEntry, ClCkptSectionDescriptorT *pSecDescriptor) { ClRcT rc = CL_OK; ClCkptIOVectorElementT ioVector = {{0}}; ClUint32T errIndex = 0; ClLogSvrCommonEoDataT *pCommonEoData = NULL; ClUint32T versionCode = 0; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogStreamOwnerEoEntryGet(NULL, &pCommonEoData); if( CL_OK != rc ) { return rc; } ioVector.sectionId = pSecDescriptor->sectionId; ioVector.dataBuffer = NULL; ioVector.dataSize = 0; ioVector.readSize = 0; ioVector.dataOffset = 0; rc = clCkptCheckpointRead(pSoEoEntry->hCkpt, &ioVector, 1, &errIndex); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCkptCheckpointRead(): rc[0x %x]", rc)); return rc; } if(ioVector.readSize <= sizeof(versionCode)) { CL_LOG_DEBUG_ERROR(("Global stream recovery failed because of inconsistent ckpt " "data of size [%lld]", ioVector.readSize)); clHeapFree(ioVector.dataBuffer); return CL_LOG_RC(CL_ERR_INVALID_STATE); } ioVector.readSize -= sizeof(versionCode); versionCode = ntohl(*(ClUint32T*)ioVector.dataBuffer); switch(versionCode) { case CL_VERSION_CODE(CL_RELEASE_VERSION, CL_MAJOR_VERSION, CL_MINOR_VERSION): { rc = clLogSOStreamEntryRecreate(0, (ClAddrT)( (ClUint8T*)ioVector.dataBuffer + sizeof(versionCode)), ioVector.readSize, CL_HANDLE_INVALID_VALUE); } break; default: rc = CL_LOG_RC(CL_ERR_VERSION_MISMATCH); clLogError("GLOBAL", "RECOVER", "Version unsupported [%d.%d.%d]", CL_VERSION_RELEASE(versionCode), CL_VERSION_MAJOR(versionCode), CL_VERSION_MINOR(versionCode)); break; } clHeapFree(ioVector.dataBuffer); CL_LOG_DEBUG_TRACE(("Exit")); return rc; }
ClRcT clCachedCkptSynch(ClCachedCkptSvcInfoT *serviceInfo, ClBoolT isEmpty) { ClRcT rc = CL_OK; ClHandleT hSecIter = CL_HANDLE_INVALID_VALUE; ClCkptSectionDescriptorT secDescriptor = {{0}}; ClCkptIOVectorElementT ioVector = {{0}}; ClUint32T errIndex = 0; rc = clCkptSectionIterationInitialize(serviceInfo->ckptHandle, CL_CKPT_SECTIONS_ANY, CL_TIME_END, &hSecIter); if( CL_OK != rc ) { clLogError("CCK", "SYNC", "clCkptSectionIterationInitialize(): rc [0x%x].",rc); return rc; } do { rc = clCkptSectionIterationNext(hSecIter, &secDescriptor); if( CL_OK != rc) { break; } ioVector.sectionId = secDescriptor.sectionId; ioVector.dataBuffer = NULL; ioVector.dataSize = 0; ioVector.readSize = 0; ioVector.dataOffset = 0; rc = clCkptCheckpointRead(serviceInfo->ckptHandle, &ioVector, 1, &errIndex); if( CL_OK == rc ) { ClUint8T *ckptedData, *copyData; ClUint32T network_byte_order; ClCachedCkptDataT sectionData; ckptedData = (ClUint8T*) ioVector.dataBuffer; copyData = ckptedData; memset(§ionData.sectionName, 0, sizeof (SaNameT)); sectionData.sectionName.length = ioVector.sectionId.idLen; memcpy(sectionData.sectionName.value, ioVector.sectionId.id, sectionData.sectionName.length); memcpy(&network_byte_order, copyData, sizeof(ClUint32T)); sectionData.sectionAddress.iocPhyAddress.nodeAddress = (ClUint32T) ntohl((ClUint32T)network_byte_order); copyData = copyData + sizeof(ClUint32T); memcpy(&network_byte_order, copyData, sizeof(ClUint32T)); sectionData.sectionAddress.iocPhyAddress.portId = (ClUint32T) ntohl((ClUint32T)network_byte_order); copyData = copyData + sizeof(ClUint32T); sectionData.data = copyData; sectionData.dataSize = ioVector.readSize - sizeof(ClIocAddressT); if (isEmpty) clCacheEntryAdd(serviceInfo, (ClCachedCkptDataT *)§ionData); else clCacheEntryUpdate(serviceInfo, (ClCachedCkptDataT *)§ionData); clHeapFree(ioVector.dataBuffer); } clHeapFree(secDescriptor.sectionId.id); } while( (rc == CL_OK) ); rc = clCkptSectionIterationFinalize(hSecIter); if( CL_OK != rc ) { clLogError("CCK", "SYNC", "clCkptSectionIterationFinalize(): rc [0x%x].",rc); return rc; } return CL_OK; }