int ckpt_read(void *hp, const char *secid, void *buf, size_t maxlen) { ckpt_handle *h = (ckpt_handle *)hp; SaCkptIOVectorElementT iov = {SA_CKPT_DEFAULT_SECTION_ID, NULL, 0, 0, 0}; SaAisErrorT err; VALIDATE(h); //printf("reading ckpt %s\n", keyid); iov.sectionId.id = (uint8_t *)secid; iov.sectionId.idLen = strlen(secid); iov.dataBuffer = buf; iov.dataSize = (SaSizeT)maxlen; iov.dataOffset = 0; iov.readSize = 0; err = saCkptCheckpointRead(h->ck_checkpoint, &iov, 1, NULL); errno = ais_to_posix(err); if (errno) return -1; return iov.readSize; /* XXX */ }
/******************************************************************************* 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 *******************************************************************************/ SaAisErrorT alarmClockCkptRead ( SaCkptCheckpointHandleT ckpt_hdl, SaUint32T section_num, void* data, SaUint32T data_size ) { SaAisErrorT ret_code = SA_AIS_OK; SaUint32T error_index; SaCkptIOVectorElementT io_vector; /* * If we are in sync via the hot-standby, no need to read */ if((g_hot_standby & HOT_STANDBY_ACTIVE)) return SA_AIS_ERR_NO_OP; io_vector.sectionId.id = (SaUint8T*)§ion_num; io_vector.sectionId.idLen = sizeof(section_num); /* 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 = saCkptCheckpointRead(ckpt_hdl, &io_vector, 1, &error_index ); if (ret_code != SA_AIS_OK) { alarmClockLogWrite(CL_LOG_SEV_ERROR, "alarmClockCkptRead: (error_index=%d) Failed to read: 0x%x\n", error_index, ret_code); goto finalizeRet; } 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 section:%d\n", getpid(), data_size, section_num); } } finalizeRet: return ret_code; }
SaAisErrorT checkpoint_read_seq(ClUint32T *seq) { SaAisErrorT rc = SA_AIS_OK; ClUint32T err_idx; /* Error index in ioVector */ ClUint32T seq_no = 0xffffffff; SaCkptIOVectorElementT iov = { .sectionId = ckpt_sid, .dataBuffer = (ClPtrT)&seq_no, .dataSize = sizeof(ClUint32T), .dataOffset = (ClOffsetT)0, .readSize = sizeof(ClUint32T) }; rc = saCkptCheckpointRead(ckpt_handle, &iov, 1, &err_idx); if (rc != SA_AIS_OK) { if (rc != SA_AIS_ERR_NOT_EXIST) /* NOT_EXIST is ok, just means no active has written */ return SA_AIS_OK; clprintf(CL_LOG_SEV_ERROR,"Error: [0x%x] from checkpoint read, err_idx = %u", rc, err_idx); } *seq = ntohl(seq_no); return SA_AIS_OK; } SaAisErrorT checkpoint_replica_activate(void) { SaAisErrorT rc = SA_AIS_OK; if ((rc = saCkptActiveReplicaSet(ckpt_handle)) != SA_AIS_OK) { clprintf(CL_LOG_SEV_ERROR, "checkpoint_replica_activate failed [0x%x] in ActiveReplicaSet", rc); } else rc = SA_AIS_OK; return rc; }
static SaAisErrorT checkpoint_read_seq(ClUint32T *seq) { SaAisErrorT rc = SA_AIS_OK; SaUint32T err_idx; /* Error index in ioVector */ SaUint32T seq_no = 0xffffffff; SaCkptIOVectorElementT iov = { .sectionId = ckpt_sid, .dataBuffer = (void *)&seq_no, .dataSize = sizeof(SaUint32T), .dataOffset = (SaSizeT)0, .readSize = sizeof(SaUint32T) }; rc = saCkptCheckpointRead(ckpt_handle, &iov, 1, &err_idx); if (rc != SA_AIS_OK ) { clprintf(CL_LOG_SEV_ERROR,"Error: [0x%x] from checkpoint read, err_idx = %u\n", rc, err_idx); } /* FIXME: How to process this err_idx? */ *seq = ntohl(seq_no); // clOsalPrintf("checkpoint_read_seq: seq_no = %lu, seq = %lu\n", seq_no, *seq); fflush(stdout); return rc; } static SaAisErrorT checkpoint_replica_activate(void) { SaAisErrorT rc = SA_AIS_OK; if ((rc = saCkptActiveReplicaSet(ckpt_handle)) != SA_AIS_OK) { clprintf( CL_LOG_SEV_ERROR, "checkpoint_replica_activate failed [0x%x] in ActiveReplicaSet", rc); } return rc; }
/**************************************************************************** * Name : cpsv_test_sync_app_process * * Description : This is the function which is given as the input to the * Application task. * * Arguments : info - This is the information which is passed during * spawing Application task. * * Return Values : None. * * Notes : None. *****************************************************************************/ void cpsv_test_sync_app_process(void *info) { SaCkptHandleT ckptHandle; SaCkptCheckpointHandleT checkpointHandle; SaCkptCallbacksT callbk; SaVersionT version; SaNameT ckptName; SaAisErrorT rc; SaCkptCheckpointCreationAttributesT ckptCreateAttr; SaCkptCheckpointOpenFlagsT ckptOpenFlags; SaCkptSectionCreationAttributesT sectionCreationAttributes; SaCkptIOVectorElementT writeVector, readVector; SaUint32T erroneousVectorIndex; void *initialData = "Default data in the section"; unsigned char read_buff[100] = {0}; SaTimeT timeout = 1000000000; unsigned int temp_var = (unsigned int)(long)info; memset(&ckptName, 0, 255); ckptName.length = strlen(DEMO_CKPT_NAME); memcpy(ckptName.value,DEMO_CKPT_NAME,strlen(DEMO_CKPT_NAME)); callbk.saCkptCheckpointOpenCallback = AppCkptOpenCallback; callbk.saCkptCheckpointSynchronizeCallback = AppCkptSyncCallback; version.releaseCode= 'B'; version.majorVersion = 2; version.minorVersion = 2; printf("*******************************************************************\n"); printf("Demonstrating Checkpoint Service Usage with a collocated Checkpoint \n"); printf("*******************************************************************\n"); sleep(2); printf("Initialising With Checkpoint Service....\n"); rc = saCkptInitialize(&ckptHandle,&callbk,&version); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); ckptCreateAttr.creationFlags = SA_CKPT_CHECKPOINT_COLLOCATED|SA_CKPT_WR_ACTIVE_REPLICA; ckptCreateAttr.checkpointSize = 1024; ckptCreateAttr.retentionDuration= 100000; ckptCreateAttr.maxSections= 2; ckptCreateAttr.maxSectionSize = 700; ckptCreateAttr.maxSectionIdSize = 4; ckptOpenFlags = SA_CKPT_CHECKPOINT_CREATE|SA_CKPT_CHECKPOINT_READ|SA_CKPT_CHECKPOINT_WRITE; printf("Opening Collocated Checkpoint = %s with create flags....\n",ckptName.value); rc = saCkptCheckpointOpen(ckptHandle,&ckptName,&ckptCreateAttr,ckptOpenFlags,timeout,&checkpointHandle); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); if(temp_var == 1) { printf("Setting the Active Replica for my checkpoint ....\t"); rc = saCkptActiveReplicaSet(checkpointHandle); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); sectionCreationAttributes.sectionId = (SaCkptSectionIdT*) malloc(sizeof \ (SaCkptSectionIdT)); sectionCreationAttributes.sectionId->id = (unsigned char *)"11"; sectionCreationAttributes.sectionId->idLen = 2; sectionCreationAttributes.expirationTime = 3600000000000ll; /* One Hour */ printf("Created Section ....\t"); rc = saCkptSectionCreate(checkpointHandle,§ionCreationAttributes,initialData,28); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); writeVector.sectionId.id = (unsigned char *)"11"; writeVector.sectionId.idLen = 2; writeVector.dataBuffer = "The Checkpoint Service provides a facility for processes to store checkpoint data"; writeVector.dataSize = strlen(writeVector.dataBuffer); writeVector.dataOffset = 0; writeVector.readSize = 0; printf("Writing to Checkpoint %s ....\n",DEMO_CKPT_NAME); printf("Section-Id = %s ....\n",writeVector.sectionId.id); printf("CheckpointData being written = \"%s\"\n",(char *)writeVector.dataBuffer); printf("DataOffset = %llu ....\n",writeVector.dataOffset); rc = saCkptCheckpointWrite(checkpointHandle,&writeVector,1,&erroneousVectorIndex); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); sleep(1); printf("Press <Enter> key to continue...\n"); getchar(); } else { sleep(4); readVector.sectionId.id = (unsigned char *)"11"; readVector.sectionId.idLen = 2; readVector.dataBuffer = read_buff; readVector.dataSize = 90; readVector.dataOffset = 0; printf("Waiting to Read from Checkpoint %s....\n",DEMO_CKPT_NAME); printf("Press <Enter> key to continue...\n"); getchar(); rc = saCkptCheckpointRead(checkpointHandle,&readVector,1,&erroneousVectorIndex); printf("Checkpoint Data Read = \"%s\"\n",(char *)readVector.dataBuffer); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); } printf("Synchronizing My Checkpoint being called ....\n"); rc = saCkptCheckpointSynchronize(checkpointHandle,timeout); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); if(temp_var==1) { printf("Unlink My Checkpoint ....\t"); rc = saCkptCheckpointUnlink(ckptHandle,&ckptName); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); } printf("Ckpt Closed ....\t"); rc = saCkptCheckpointClose(checkpointHandle); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); printf("Ckpt Finalize being called ....\t"); rc = saCkptFinalize(ckptHandle); if(rc == SA_AIS_OK) printf("PASSED \n"); else printf("Failed \n"); sleep(2); return; }
SaAisErrorT alarmClockCkptRead ( SaCkptCheckpointHandleT ckpt_hdl, SaUint32T section_num, void* data, SaUint32T data_size ) { SaAisErrorT ret_code = SA_AIS_OK; SaUint32T error_index = 0; SaCkptIOVectorElementT *ioVecIter = ioVecs; ClUint32T bitmapChunks = 0; ClUint32T chunkSize = 0; ClUint32T ctrlHeaderSize = sessionBitmapHeaderSize(&chunkSize); if(g_hot_standby & HOT_STANDBY_ACTIVE) { /* * Start session buffering if hotstandby mode is active */ sessionBufferStart(); return SA_AIS_ERR_EXIST; } if(section_num > NUM_SECTION_ID_MAPS) return SA_AIS_ERR_INVALID_PARAM; /* * If section doesn't exist, then skip the read */ if(!sectionCreated) { if(__alarmClockCkptSectionCheck(ckpt_hdl, section_num) != CL_OK) return SA_AIS_ERR_NOT_EXIST; sectionCreated = CL_TRUE; } memset(ioVecs, 0, sizeof(*ioVecs) * MAX_NUM_IOVECS); /* * We don't need to read in the ctrl section since we would * be syncing our session bitmaps while reading the session data */ memcpy(&ioVecIter->sectionId, §ionIdMap[section_num-1].ctrlSectionId, sizeof(ioVecIter->sectionId)); ++ioVecIter; memcpy(&ioVecIter->sectionId, §ionIdMap[section_num-1].sectionId, sizeof(ioVecIter->sectionId)); ++ioVecIter; ret_code = saCkptCheckpointRead(ckpt_hdl, ioVecs, 2, &error_index); if(ret_code == SA_AIS_OK) { if(!ioVecs[0].readSize) { alarmClockLogWrite(CL_LOG_SEV_NOTICE, "alarmClockCkptRead(pid=%d): " "Session empty", getpid()); goto out_free; } if(ioVecs[0].readSize < ctrlHeaderSize) { alarmClockLogWrite(CL_LOG_SEV_WARNING, "alarmClockCkptRead(pid=%d): " "read [%d] bytes, expected [%d] bytes", getpid(), (ClUint32T)ioVecs[0].readSize, ctrlHeaderSize); ret_code = SA_AIS_ERR_BAD_OPERATION; goto out_free; } bitmapChunks = *(ClUint32T*)ioVecs[0].dataBuffer; alarmClockLogWrite(CL_LOG_SEV_DEBUG, "alarmClockCkptRead(pid=%d): " "Bitmap chunks [%d], Bitmap size [%d]\n", getpid(), bitmapChunks, (ClUint32T)(ioVecs[0].readSize - sizeof(bitmapChunks))); BitmapT bitmap = {0}; bitmap.map = (ClUint8T*)ioVecs[0].dataBuffer + sizeof(bitmapChunks); bitmap.words = BYTES_TO_WORDS(bitmapChunks * chunkSize); /* * We can also walk the session itself (#else case) without using the bitmap segment * but could be slightly costly in the worst case with session holes in between * for deleted or empty sessions. */ #if 1 __find_next_bit_walk(&bitmap, &ioVecs[1], bitmapWalkCallback); alarmClockLogWrite(CL_LOG_SEV_DEBUG, "alarmClockCkptRead(pid=%d): " "Found [%d] active sessions", getpid(), bitmap.bits); #else __find_next_bit_walk(&bitmap, NULL, bitmapWalkCallback); /* * Read in session data */ ClUint32T numSessions = 0; ClUint8T *sessionBuffer = ioVecs[1].dataBuffer; SessionT *sessionIter = (SessionT*)sessionBuffer; ClUint32T sessionDataSize = ioVecs[1].readSize; numSessions = sessionDataSize/sizeof(SessionT); alarmClockLogWrite(CL_LOG_SEV_DEBUG, "alarmClockCkptRead(pid=%d): " "Found [%d] sessions with ckpt size of [%d] bytes", getpid(), numSessions, sessionDataSize); for(ClUint32T i = 0; i < numSessions; ++i, ++sessionIter) { /* * Real world, has to unmarshall or copy-in to avoid unaligned access */ sessionUpdate(sessionIter, i); } #endif } out_free: if(ioVecs[0].dataBuffer) { clHeapFree(ioVecs[0].dataBuffer); ioVecs[0].dataBuffer = NULL; } if(ioVecs[1].dataBuffer) { clHeapFree(ioVecs[1].dataBuffer); ioVecs[1].dataBuffer = NULL; } return ret_code; }
int main (void) { SaCkptHandleT ckptHandle; SaCkptCheckpointHandleT checkpointHandle; SaAisErrorT error; char data[MAX_DATA_SIZE]; struct timespec delay; struct timespec delay2; SaCkptIOVectorElementT writeElement; long count = 0; SaUint32T erroroneousVectorIndex = 0; delay.tv_sec = 1; delay.tv_nsec = 0; error = saCkptInitialize (&ckptHandle, &callbacks, &version); error = saCkptCheckpointOpen (ckptHandle, &checkpointName, &checkpointCreationAttributes, SA_CKPT_CHECKPOINT_CREATE|SA_CKPT_CHECKPOINT_READ|SA_CKPT_CHECKPOINT_WRITE, 0, &checkpointHandle); printf ("%s: initial open of checkpoint\n", get_test_output (error, SA_AIS_OK)); do{ error = saCkptCheckpointRead (checkpointHandle, ReadVectorElements, 1, &erroroneousVectorIndex); if (error != SA_AIS_OK) { if (error == SA_AIS_ERR_TRY_AGAIN) { continue; } printf ("error is %d\n", error); return (0); } if (ReadVectorElements->dataBuffer == 0) { printf ("Default Checkpoint has no data\n"); } else { count = atol((char *)ReadVectorElements->dataBuffer); } count++; sprintf((char*)&data, "%d",(int)count); writeElement.sectionId = (SaCkptSectionIdT)SA_CKPT_DEFAULT_SECTION_ID; writeElement.dataBuffer = data; writeElement.dataSize = strlen (data) + 1; writeElement.dataOffset = 0; writeElement.readSize = 0; do { error = saCkptCheckpointWrite (checkpointHandle, &writeElement, 1, &erroroneousVectorIndex); printf ("%s: checkpoint write with data %s\n", get_test_output (error, SA_AIS_OK), (char*)data); }while (error == SA_AIS_ERR_TRY_AGAIN); nanosleep(&delay,&delay2); }while (1); return (0); }