OpenClovis Logo

API Usage Examples
Checkpointing Service

Code Examples. More...

Code Examples.

The below code example shows the usage of server based checkpointing.

The usage model of this example is to to have 2 applications running in 1+1 redundancy on 2 worker nodes. The Active application keeps writing a counter value inthe checkpoint and the standby application will be idle. After some time we kill the node running the active instance, which triggers the standby application to now take over as Active. At this point the new active application reads the checkpoint, and starts updating counter from the point where the old active had left it.

Note that the below code snippets are been tested. However please follow the instructions given in the comment blocks before each function.

#include "ckptTest.h"
/*********************************************************************
Definitions: Below are the datastructure definitions used
in this application
*********************************************************************/
#define CKPT_NAME "SampleCkptTest" /* Checkpoint Name */
#define CKPT_SID_NAME "1" /* Checkpoint section id */
ClUint32T seq; /* The sequence no which will be
written into the checkpoint */
ClCkptSvcHdlT ckpt_svc_handle; /* Checkpointing service handle */
ClCkptHdlT ckpt_handle; /* Checkpoint handle */
ClCkptSectionIdT ckpt_sid = { /* Section id for checkpoints */
(ClUint16T)sizeof(CKPT_SID_NAME)-1,
(ClUint8T*)CKPT_SID_NAME
};
int running = 1;
int exiting = 0;
ClAmsHAStateT ha_state = CL_AMS_HA_STATE_NONE;
/**********************************************************************
INIT: The below function initializes the checkpoint service client
and opens a collocated checkpoint in read, write mode. This function
should be invoked from the AppInitialize of the application before
doing a clCpmRegister
**********************************************************************/
ClRcT checkpoint_initialize()
{
ClRcT rc = CL_OK;
ClVersionT ckpt_version = {'B', 1, 1};
ClNameT ckpt_name = { strlen(CKPT_NAME), CKPT_NAME };
.checkpointSize = sizeof(ClUint32T),
.retentionDuration = (ClTimeT)0,
.maxSections = 2, /* Default section,
plus section we create */
.maxSectionSize = sizeof(ClUint32T),
.maxSectionIdSize = (ClSizeT)64
};
clOsalPrintf("Initializing the checkpoint\n");
/* Initialize checkpointing service instance */
rc = clCkptInitialize(&ckpt_svc_handle, /* Checkpoint service handle */
NULL, /* Optional callbacks table */
&ckpt_version); /* Required verison number */
if (rc != CL_OK)
{
clOsalPrintf("clCkptInitialize failed with rc 0x%x\n",rc);
return rc;
}
clOsalPrintf("Checkpoint service initialized [handle=0x%x]\n",
ckpt_svc_handle);
/* Create the checkpoint for read and write. */
rc = clCkptCheckpointOpen(ckpt_svc_handle, /* Service handle */
&ckpt_name, /* Checkpoint name */
&create_atts, /* Optional creation attr.*/
(ClTimeT)-1, /* No timeout */
&ckpt_handle); /* Checkpoint handle */
if (rc != CL_OK)
{
clOsalPrintf("clCkptCheckpointOpen failed with [rc=0x%x]\n",rc);
clCkptFinalize(ckpt_svc_handle);
return rc;
}
clOsalPrintf("Checkpoint opened [Checkpoint handle=0x%x]\n",
ckpt_handle);
return CL_OK;
}
/************************************************************************
Finalize: The below function closes the checkpoint and finalizes the
checkpoint svc handle. This should be called from AppTerminate function
of the application.
************************************************************************/
ClRcT checkpoint_finalize(void)
{
ClRcT rc;
rc = clCkptCheckpointClose(ckpt_handle);
if (rc != CL_OK)
{
clOsalPrintf("Checkpoint close failed with rc 0x%x\n",rc);
}
rc = clCkptFinalize(ckpt_svc_handle);
if (rc != CL_OK)
{
clOsalPrintf("Checkpoint Finalize failed with rc 0x%x\n",rc);
}
return rc;
}
/*************************************************************************
active_replica_set: This function sets the local checkpoint db as the
active replica. This will be initially called in the section_create
function before creating the section into the checkpoint. However,
this function also needs to be explicitly invoked by the application
as soon as it takes over from Standby state to Active State.
*************************************************************************/
ClRcT active_replica_set()
{
ClRcT rc = CL_OK;
rc = clCkptActiveReplicaSet(ckpt_handle);
if (rc != CL_OK)
{
clOsalPrintf("Ckpt Active replica set failed with [rc = 0x%x\n",rc);
return rc;
}
return rc;
}
/*************************************************************************
section_create: This function creates a section into the checkpoint.
************************************************************************/
ClRcT checkpoint_section_create()
{
/*
Try to create a section so that updates can operate by overwriting
the section over and over again.
*/
ClRcT rc = CL_OK;
ClUint8T initData = 0;
.sectionId = &ckpt_sid,
.expirationTime = CL_TIME_END /* Setting an infinite time */
};
active_replica_set();
/* Create the section */
rc = clCkptSectionCreate(ckpt_handle, /* Checkpoint handle */
&section_atts, /* Section attributes */
&initData, /* Initial data */
(ClSizeT)sizeof(initData));
/* Size of data */
{
clOsalPrintf("CkptSectionCreate failed with rc 0x%x\n",rc);
clCkptCheckpointClose(ckpt_handle);
clCkptFinalize(ckpt_svc_handle);
return rc;
}
else if (rc != CL_OK && (CL_GET_ERROR_CODE(rc) == CL_ERR_ALREADY_EXIST))
{
/* Section already exists. So read the checkpointed value and
continue to write from the point where it is left */
rc = checkpoint_read_seq(&seq);
if (rc != CL_OK)
{
clOsalPrintf("Checkpoint read failed with rc 0x%x\n",rc);
clCkptCheckpointClose(ckpt_handle);
clCkptFinalize(ckpt_svc_handle);
return rc;
}
clOsalPrintf("Sequence Number read from chekpoint %lu\n",seq);
}
else
{
clOsalPrintf("Section created successful\n");
}
return rc;
}
/*************************************************************************
READ: This function reads the checkpointed data and stores
in the global seq variable
*************************************************************************/
ClRcT checkpoint_read_seq(ClUint32T *seq)
{
ClRcT rc = CL_OK;
ClUint32T err_idx; /* Error index in ioVector */
ClUint32T seq_no = 0xffffffff;
.sectionId = ckpt_sid,
.dataBuffer = (ClPtrT)&seq_no,
.dataSize = sizeof(ClUint32T),
.dataOffset = (ClOffsetT)0,
.readSize = sizeof(ClUint32T)
};
rc = clCkptCheckpointRead(ckpt_handle, &iov, 1, &err_idx);
if (rc != CL_OK)
{
clOsalPrintf("CkptRead ERROR [rc = 0x%x]\n",rc);
}
*seq = ntohl(seq_no);
clOsalPrintf("CheckpointRead: seq = %lu\n", *seq);
fflush(stdout);
return rc;
}
/*************************************************************************
WRITE: The below function writes the seq no into the checkpoint.
*************************************************************************/
ClRcT checkpoint_write_seq(ClUint32T seq)
{
ClRcT rc = CL_OK;
ClUint32T seq_no;
seq_no = htonl(seq);
clOsalPrintf("CkptWrite: seq = %lu\n", seq);
fflush(stdout);
/* Write checkpoint */
rc = clCkptSectionOverwrite(ckpt_handle,
&ckpt_sid,
&seq_no,
sizeof(ClUint32T));
if (rc != CL_OK)
{
clOsalPrintf("CheckpointSectionOverWrite failed with rc 0x%x\n",rc);
}
else
{
/* If write is successful, then synchronise the checkpoints on all
replicas */
if (rc != CL_OK)
{
clOsalPrintf("Failed [0x%x] to synchronize the checkpoint\n",
rc);
}
}
return rc;
}
/*************************************************************************
LOOP: The below function is the critical part of the code. This
function needs to be invoked at the end of the AppInitialize function
of the application. On the active application,this function keeps
writing the incremented sequence number into the checkpoint. Note that
the seq no is a global variable. During the switchover, when the standby
takes over as new active it first reads the latest value from the
checkpoint into the global seq no, and then marks the ha_state variable
to CL_AMS_HA_STATE_ACTIVE.This will make the below loop on the active
application to start writing checkpoint with the new value.
*************************************************************************/
ClRcT get_into_loop()
{
ClRcT rc = CL_OK;
while (!exiting)
{
if (running && ha_state == CL_AMS_HA_STATE_ACTIVE)
{
/* Checkpoint new sequence number */
rc = checkpoint_write_seq(seq);
if (rc != CL_OK)
{
printf("Checkpoint write failed... Exiting..\n");
break;
}
seq++;
}
sleep(1);
}
return rc;
}
/*************************************************************************
AppInit: Following code needs to be put into the AppInitialize function
of the application
*************************************************************************/
{/*START*/
/* Initialize the checkpoint */
checkpoint_initialize();
/* Create the sections */
checkpoint_section_create();
/*
---END_APPLICATION_CODE---
*/
get_into_loop();
}/*END*/
/*************************************************************************
StateChange: Following code needs to be put into the CSI Set function
of the application. Please note that the other part of the
auto generated code in the application SHOULD NOT be altered
*************************************************************************/
case CL_AMS_HA_STATE_ACTIVE:
{
/* Set this local checkpoint as active replica */
active_replica_set();
/* Read the value in the section so that u can start
from where it is left */
checkpoint_read_seq(&seq);
ha_state = haState;
}
case CL_AMS_HA_STATE_STANDBY:
{
ha_state = haState;
/*
---END_APPLICATION_CODE---
*/
}
/*************************************************************************
Header File: Below code needs to be put into ckptTest.h file under
same directory and this also needs to be included in
the clCompAppMain.c file.
*************************************************************************/
#include <clCkptApi.h>
#include <clCommon.h>
#include <clOsalApi.h>
#include <clIocServices.h>
/*
ASP Client Includes.
*/
#include <clRmdApi.h>
#include <clDebugApi.h>
#include <clOmApi.h>
#include <clOampRtApi.h>
#include <clProvApi.h>
#include <clAlarmApi.h>
#include <clEoApi.h>
#include <clCpmApi.h>
#include <clIdlApi.h>
#include <string.h>
#include <netinet/in.h>
extern ClUint32T seq; /* The sequence no which will be
written into the checkpoint */
extern int running;
extern int exiting;
extern ClAmsHAStateT ha_state;
extern ClRcT checkpoint_initialize();
extern ClRcT checkpoint_finalize(void);
extern ClRcT checkpoint_section_create();
extern ClRcT checkpoint_read_seq(ClUint32T *seq);
extern ClRcT checkpoint_write_seq(ClUint32T seq);
extern ClRcT get_into_loop();
extern ClRcT active_replica_set();

Generated on Tue Jan 10 10:29:15 PST 2012 for OpenClovis SDK using Doxygen