/* $Id: libckpt.c,v 1.4.2.5 2004/11/18 06:54:23 yixiong Exp $ */ /* * ckptlib.c: data checkpoint API library * * Copyright (C) 2003 Jerry Yu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * This library is an implementation of the Application Interface * Specification on Service Availability Forum. Refer to: www.saforum.org/ * specification */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef AF_LOCAL # define AF_LOCAL AF_UNIX #endif /* * TODO list: * 1. make all APIs thread safe */ /* * the request timeout value in seconds */ #define LIB_REQUEST_TIMEOUT 10 /* * the client structure */ typedef struct _SaCkptLibClientT{ char hostName[SA_MAX_NAME_LENGTH]; pid_t pid; int threadID; /* The handle returned by the checkpoint service daemon */ SaCkptHandleT clientHandle; /* * The client channel * channel[0] is for the sync calls * channel[1] is for the async calls */ IPC_Channel* channel[2]; /* * the opened checkpoints */ GList* checkpointList; SaCkptCallbacksT callbacks; } SaCkptLibClientT; /* * the request structure */ typedef struct _SaCkptLibRequestT{ SaCkptLibClientT* client; SaCkptClientRequestT* clientRequest; /* request timeout handler tag */ guint timeoutTag; } SaCkptLibRequestT; typedef struct _SaCkptLibCheckpointT{ SaCkptLibClientT* client; /* * opened checkpoint handle. * Returned by checkpoint service daemon */ SaCkptCheckpointHandleT checkpointHandle; SaNameT ckptName; /* * checkpoint attributes */ SaCkptCheckpointOpenFlagsT openFlag; SaCkptCheckpointCreationAttributesT createAttributes; GList* sectionList; } SaCkptLibCheckpointT; GList* libClientList = NULL; GList* libCheckpointList = NULL; GList* libResponseList = NULL; GList* libAsyncRequestList = NULL; GList* libAsyncResponseList = NULL; GHashTable* libIteratorHash = NULL; static IPC_Channel* SaCkptClientChannelInit(char* pathname) { IPC_Channel *clientChannel = NULL; mode_t mask; char path[] = IPC_PATH_ATTR; char domainsocket[] = IPC_DOMAIN_SOCKET; GHashTable *attrs = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(attrs, path, pathname); mask = umask(0); clientChannel = ipc_channel_constructor(domainsocket, attrs); if (clientChannel == NULL){ cl_log(LOG_ERR, "Checkpoint library Can't create client channel"); return NULL; } mask = umask(mask); g_hash_table_destroy(attrs); return clientChannel; } static SaUint32T SaCkptLibGetReqNO(void) { static SaUint32T ckptLibRequestNO = 1; return ckptLibRequestNO++; } /* FIXME it should not be a global static variable */ static SaCkptSectionIteratorT SaCkptLibGetIterator(void) { static SaCkptSectionIteratorT ckptLibSecIterator = 1; SaCkptSectionIteratorT iterator = 0; GList* sectionList = NULL; do { iterator = ckptLibSecIterator++; sectionList = g_hash_table_lookup( libIteratorHash, &iterator); } while (sectionList != NULL); return iterator; } static SaCkptLibRequestT* SaCkptGetLibRequestByReqno(SaUint32T reqno) { SaCkptLibRequestT* libRequest = NULL; GList* list = NULL; list = libAsyncRequestList; while( list != NULL ) { libRequest= (SaCkptLibRequestT*)(list->data); if(libRequest->clientRequest->requestNO == reqno) { return libRequest; } list = g_list_next(list); } return NULL; } static SaCkptClientResponseT* SaCkptGetLibResponseByReqno(SaUint32T reqno) { SaCkptClientResponseT* libResponse = NULL; GList* list = NULL; list = libResponseList; while( list != NULL ) { libResponse= (SaCkptClientResponseT*)(list->data); if(libResponse->requestNO == reqno) { libResponseList = g_list_remove( libResponseList, libResponse); return libResponse; } list = g_list_next(list); } return NULL; } static SaCkptLibClientT* SaCkptGetLibClientByHandle(SaCkptHandleT clientHandle) { SaCkptLibClientT* libClient = NULL; GList* list = NULL; list = libClientList; while( list != NULL ) { libClient = (SaCkptLibClientT*)(list->data); if(libClient->clientHandle == clientHandle) { return libClient; } list = g_list_next(list); } return NULL; } static SaCkptLibCheckpointT* SaCkptGetLibCheckpointByHandle( SaCkptCheckpointHandleT checkpointHandle) { GList* list = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; list = libCheckpointList; while(list != NULL ) { libCheckpoint = (SaCkptLibCheckpointT*)(list->data); if(libCheckpoint->checkpointHandle == checkpointHandle) { return libCheckpoint; } list = g_list_next(list); } return NULL; } static SaErrorT SaCkptLibRequestSend(IPC_Channel* ch, SaCkptClientRequestT* ckptReq) { IPC_Message* ipcMsg = NULL; int rc = IPC_OK; char* p = NULL; if(ch->ch_status != IPC_CONNECT) { cl_log(LOG_WARNING, "IPC is in state %d before send message", ch->ch_status); return SA_ERR_LIBRARY; } /* build response message */ ipcMsg = (IPC_Message*)ha_malloc(sizeof(IPC_Message)); if (ipcMsg == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); return SA_ERR_NO_MEMORY; } ipcMsg->msg_private = NULL; ipcMsg->msg_done = NULL; ipcMsg->msg_ch = ch; ipcMsg->msg_len = sizeof(SaCkptClientRequestT) - 2* sizeof(void*) + ckptReq->dataLength + ckptReq->reqParamLength ; ipcMsg->msg_body = ha_malloc(ipcMsg->msg_len); if (ipcMsg->msg_body == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); ha_free(ipcMsg); return SA_ERR_NO_MEMORY; } p = ipcMsg->msg_body; memcpy(p, ckptReq, sizeof(SaCkptClientRequestT) - 2*sizeof(void*)); p += sizeof(SaCkptClientRequestT) - 2*sizeof(void*); if (ckptReq->reqParamLength > 0) { memcpy(p, ckptReq->reqParam, ckptReq->reqParamLength); p += ckptReq->reqParamLength; } if (ckptReq->dataLength> 0) { memcpy(p, ckptReq->data, ckptReq->dataLength); p += ckptReq->dataLength; } /* send request message */ while (ch->ops->send(ch, ipcMsg) == IPC_FAIL) { cl_log(LOG_ERR, "Checkpoint library send request failed"); cl_log(LOG_ERR, "Sleep for a while and try again"); cl_shortsleep(); } if(ch->ch_status != IPC_CONNECT) { cl_log(LOG_WARNING, "IPC is in state %d after send message", ch->ch_status); } ch->ops->waitout(ch); /* free ipc message */ if (ipcMsg != NULL) { if (ipcMsg->msg_body != NULL) { ha_free(ipcMsg->msg_body); } ha_free(ipcMsg); } if (rc == IPC_OK) { return SA_OK; } else { return SA_ERR_LIBRARY; } } static SaErrorT SaCkptLibResponseReceive(IPC_Channel* ch, SaUint32T requestNO, SaCkptClientResponseT** pCkptResp) { SaCkptClientResponseT* ckptResp = NULL; IPC_Message *ipcMsg = NULL; int rc = IPC_OK; SaErrorT retval = SA_OK; char *p = NULL; ckptResp = SaCkptGetLibResponseByReqno(requestNO); if (ckptResp != NULL) { *pCkptResp = ckptResp; return SA_OK; } if(ch->ch_status != IPC_CONNECT) { cl_log(LOG_WARNING, "IPC is in state %d before receive message", ch->ch_status); return SA_ERR_LIBRARY; } while (ch->ops->is_message_pending(ch) != TRUE) { cl_shortsleep(); } while (ch->ops->is_message_pending(ch) == TRUE) { /* receive ipc message */ rc = ch->ops->recv(ch, &ipcMsg); if (rc != IPC_OK) { cl_log(LOG_ERR, "Receive response failed"); if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); retval = SA_ERR_LIBRARY; break; } if (ipcMsg->msg_len < sizeof(SaCkptClientResponseT) - sizeof(void*)) { cl_log(LOG_ERR, "Received error response"); if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); retval = SA_ERR_LIBRARY; break; } p = ipcMsg->msg_body; ckptResp = ha_malloc(sizeof(SaCkptClientResponseT)); if (ckptResp == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); if (ipcMsg != NULL) { if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); } retval = SA_ERR_NO_MEMORY; break; } memset(ckptResp, 0, sizeof(SaCkptClientResponseT)); memcpy(ckptResp, p, sizeof(SaCkptClientResponseT) - sizeof(void*)); p += (sizeof(SaCkptClientResponseT) - sizeof(void*)); if (ckptResp->dataLength > 0) { ckptResp->data = ha_malloc(ckptResp->dataLength); if (ckptResp->data == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); if (ipcMsg != NULL) { if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); } ha_free(ckptResp); retval = SA_ERR_NO_MEMORY; break; } else { memcpy(ckptResp->data, p, ckptResp->dataLength); p += ckptResp->dataLength; } } else { ckptResp->data = NULL; } /* free ipc message */ if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); libResponseList = g_list_append(libResponseList, ckptResp); } ckptResp = SaCkptGetLibResponseByReqno(requestNO); if (ckptResp != NULL) { *pCkptResp = ckptResp; return SA_OK; } return retval; } static SaErrorT SaCkptLibResponseReceiveAsync(IPC_Channel* ch) { SaCkptClientResponseT* ckptResp = NULL; IPC_Message *ipcMsg = NULL; int rc = IPC_OK; SaErrorT retval = SA_OK; char *p = NULL; if(ch->ch_status != IPC_CONNECT) { cl_log(LOG_WARNING, "IPC is in state %d before receive message", ch->ch_status); return SA_ERR_LIBRARY; } /* receive ipc message */ rc = ch->ops->recv(ch, &ipcMsg); if (rc != IPC_OK) { cl_log(LOG_ERR, "Receive response failed"); if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); return SA_ERR_LIBRARY; } if (ipcMsg->msg_len < sizeof(SaCkptClientResponseT) - sizeof(void*)) { cl_log(LOG_ERR, "Received error response"); if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); return SA_ERR_LIBRARY; } p = ipcMsg->msg_body; ckptResp = ha_malloc(sizeof(SaCkptClientResponseT)); if (ckptResp == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); if (ipcMsg != NULL) { if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); } return SA_ERR_NO_MEMORY; } memset(ckptResp, 0, sizeof(SaCkptClientResponseT)); memcpy(ckptResp, p, sizeof(SaCkptClientResponseT) - sizeof(void*)); p += (sizeof(SaCkptClientResponseT) - sizeof(void*)); if (ckptResp->dataLength > 0) { ckptResp->data = ha_malloc(ckptResp->dataLength); if (ckptResp->data == NULL) { cl_log(LOG_ERR, "No memory in checkpoint library"); if (ipcMsg != NULL) { if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); } ha_free(ckptResp); return SA_ERR_NO_MEMORY; } else { memcpy(ckptResp->data, p, ckptResp->dataLength); p += ckptResp->dataLength; } } else { ckptResp->data = NULL; } /* free ipc message */ if (ipcMsg->msg_body != NULL) { free(ipcMsg->msg_body); } free(ipcMsg); libAsyncResponseList = g_list_append( libAsyncResponseList, ckptResp); return retval; } /* ------------------------- exported API ------------------------------- */ /* * Initialize the checkpoint service for the invoking process and register * the related callback functions. */ SaErrorT saCkptInitialize(SaCkptHandleT *ckptHandle/*[out]*/, const SaCkptCallbacksT *callbacks, const SaVersionT *version) { SaErrorT libError = SA_OK; SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqInitParamT* initParam = NULL; SaCkptClientResponseT* clientResponse = NULL; int i = 0; cl_log_set_entity("AIS"); cl_log_enable_stderr(TRUE); if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptInitialize"); return SA_ERR_INVALID_PARAM; } if (version == NULL) { cl_log(LOG_ERR, "Null version number in saCkptInitialize"); return SA_ERR_INVALID_PARAM; } libClient = (SaCkptLibClientT*)ha_malloc( sizeof(SaCkptLibClientT)); libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); initParam = (SaCkptReqInitParamT*)ha_malloc( sizeof(SaCkptReqInitParamT)); if ((libClient == NULL) || (libRequest == NULL) || (clientRequest == NULL) || (initParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptInitialize"); libError = SA_ERR_NO_MEMORY; goto initError; } memset(libClient, 0, sizeof(SaCkptLibClientT)); memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(initParam, 0, sizeof(SaCkptReqInitParamT)); libClient->hostName[0] = 0; libClient->pid = getpid(); libClient->threadID = 0; libClient->clientHandle = 0; libClient->checkpointList = NULL; for (i=0; i<2; i++) { IPC_Channel* ch = NULL; char pathname[128]; memset (pathname, 0, sizeof(pathname)); strcpy (pathname, CKPTIPC) ; ch = SaCkptClientChannelInit(pathname); if (ch == NULL) { cl_log(LOG_ERR, "Can not initiate connection in saCkptInitialize"); libError = SA_ERR_LIBRARY; goto initError; } if (ch->ops->initiate_connection(ch) != IPC_OK) { cl_log(LOG_ERR, "Can not connect to daemon in saCkptInitialize"); libError = SA_ERR_LIBRARY; goto initError; } if (i == 1) { /* async channel */ ch->ops->set_recv_qlen(ch, 0); /* ch->ops->set_send_qlen(ch, 0); */ } libClient->channel[i] = ch; } libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = 0; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SERVICE_INIT; clientRequest->reqParamLength = sizeof(SaCkptReqInitParamT); clientRequest->dataLength = 0; clientRequest->reqParam = initParam; clientRequest->data = NULL; initParam->pid = libClient->pid; initParam->tid = libClient->threadID; memcpy(&(initParam->ver), version, sizeof(SaVersionT)); libError = SaCkptLibRequestSend(libClient->channel[0], libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send initialize request failed"); goto initError; } libError = SaCkptLibResponseReceive(libClient->channel[0], libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto initError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto initError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto initError; } *ckptHandle = clientResponse->clientHandle; libClient->clientHandle = *ckptHandle; if (callbacks != NULL) { libClient->callbacks = *callbacks; } libClientList = g_list_append(libClientList, libClient); if (libIteratorHash == NULL) { libIteratorHash = g_hash_table_new(g_int_hash, g_int_equal); } libError = SA_OK; initError: if (libError != SA_OK) { if (libClient != NULL) { for (i=0; i<2; i++) { if (libClient->channel[i] != NULL) { IPC_Channel* ch = libClient->channel[i]; ch->ops->destroy(ch); } } ha_free(libClient); } } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (initParam != NULL) { ha_free(initParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * Returns the fd for asynchronously operation */ SaErrorT saCkptSelectionObjectGet( const SaCkptHandleT *ckptHandle, SaSelectionObjectT *selectionObject/*[out]*/) { SaCkptLibClientT* libClient = NULL; IPC_Channel* ch = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSelectionObjectGet"); return SA_ERR_INVALID_PARAM; } if (selectionObject == NULL) { cl_log(LOG_ERR, "Null selectobject in saCkptSelectionObjectGet"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptSelectionObjectGet"); return SA_ERR_INVALID_PARAM; } ch = libClient->channel[1]; *selectionObject = ch->ops->get_recv_select_fd(ch); return SA_OK; } /* * This function invokes, in the context of the calling thread,one or all * of the pending callbacks for the handle ckptHandle. */ SaErrorT saCkptDispatch(const SaCkptHandleT *ckptHandle, SaDispatchFlagsT dispatchFlags) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptClientResponseT* clientResponse = NULL; SaInvocationT invocation; SaCkptLibCheckpointT* libCheckpoint = NULL; SaCkptCheckpointHandleT checkpointHandle = 0; SaUint32T reqno; SaCkptReqOpenAsyncParamT* openAsyncParam = NULL; SaCkptReqAsyncParamT* asyncParam = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptDispatch"); return SA_ERR_INVALID_PARAM; } if ((dispatchFlags != SA_DISPATCH_ONE) && (dispatchFlags != SA_DISPATCH_ALL) && (dispatchFlags != SA_DISPATCH_BLOCKING)) { cl_log(LOG_ERR, "Invalid dispatchFlags in saCkptDispatch"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptDispatch"); return SA_ERR_INVALID_PARAM; } ch = libClient->channel[1]; /* async channel */ libError = SaCkptLibResponseReceiveAsync(ch); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); return SA_ERR_LIBRARY; } if (g_list_length(libAsyncResponseList) == 0) { return SA_OK; } while (libAsyncResponseList != NULL) { clientResponse = libAsyncResponseList->data; libError = clientResponse->retVal; reqno = clientResponse->requestNO; libRequest = SaCkptGetLibRequestByReqno(reqno); clientRequest = libRequest->clientRequest; switch (clientRequest->req) { case REQ_CKPT_OPEN_ASYNC: openAsyncParam = clientRequest->reqParam; invocation = openAsyncParam->invocation; if (clientResponse->data == NULL){ libError = SA_ERR_LIBRARY; libClient->callbacks.saCkptCheckpointOpenCallback( invocation, NULL, libError); break; } memcpy(&checkpointHandle, clientResponse->data, sizeof(SaCkptCheckpointHandleT)); /* * create libCheckpoint and add it to the * opened checkpoint list */ libCheckpoint = ha_malloc(sizeof(SaCkptLibCheckpointT)); if (libCheckpoint == NULL) { libError = SA_ERR_NO_MEMORY; libClient->callbacks.saCkptCheckpointOpenCallback( invocation, &checkpointHandle, libError); break; } libCheckpoint->client = libClient; libCheckpoint->checkpointHandle = checkpointHandle; libCheckpoint->ckptName.length = openAsyncParam->ckptName.length; memcpy(libCheckpoint->ckptName.value, openAsyncParam->ckptName.value, openAsyncParam->ckptName.length); memcpy(&(libCheckpoint->createAttributes), &openAsyncParam->attr, sizeof(SaCkptCheckpointCreationAttributesT)); libCheckpoint->openFlag = openAsyncParam->openFlag; libClient->checkpointList = g_list_append( libClient->checkpointList, libCheckpoint); libCheckpointList = g_list_append(libCheckpointList, libCheckpoint); libClient->callbacks.saCkptCheckpointOpenCallback( invocation, &checkpointHandle, libError); break; case REQ_CKPT_SYNC_ASYNC: asyncParam = clientRequest->reqParam; invocation = asyncParam->invocation; libClient->callbacks.saCkptCheckpointSynchronizeCallback( invocation, libError); break; default: break; }; libAsyncResponseList = g_list_remove(libAsyncResponseList, clientResponse); libAsyncRequestList = g_list_remove(libAsyncRequestList, libRequest); ha_free(clientResponse->data); ha_free(clientResponse); ha_free(libRequest->clientRequest->reqParam); ha_free(libRequest->clientRequest->data); ha_free(libRequest->clientRequest); ha_free(libRequest); if (dispatchFlags == SA_DISPATCH_ONE) { break; } } return SA_OK; } /* * closes the association, represented by ckptHandle, between the process and * the Checkpoint Service. It frees up resources and close all the opened * checkpoints. */ SaErrorT saCkptFinalize(const SaCkptHandleT *ckptHandle) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqFinalParamT* finalParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; int i = 0; GList* list = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptFinalize"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptFinalize"); return SA_ERR_INVALID_PARAM; } /* * close all opened checkpoints first */ list = libClient->checkpointList; while(list != NULL ) { SaCkptLibCheckpointT* libCheckpoint = NULL; SaCkptCheckpointHandleT* checkpointHandle = NULL; libCheckpoint = (SaCkptLibCheckpointT*)(list->data); checkpointHandle = &(libCheckpoint->checkpointHandle); saCkptCheckpointClose(checkpointHandle); /* ha_free(libCheckpoint); */ list = libClient->checkpointList; } libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); finalParam = (SaCkptReqFinalParamT*)ha_malloc( sizeof(SaCkptReqFinalParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (finalParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptFinalize"); libError = SA_ERR_NO_MEMORY; goto finalError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(finalParam, 0, sizeof(SaCkptReqFinalParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SERVICE_FINL; clientRequest->reqParamLength = sizeof(SaCkptReqFinalParamT); clientRequest->dataLength = 0; clientRequest->reqParam = finalParam; clientRequest->data = NULL; finalParam->clientHandle = *ckptHandle; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send finalize request failed"); goto finalError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto finalError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto finalError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto finalError; } /* * FIXME * cancel all pending callbacks related to this client */ /* remove client */ libClientList = g_list_remove(libClientList, libClient); /* only destroy the hash table after all the clients finalized */ if (g_list_length(libClientList) == 0) { g_hash_table_destroy(libIteratorHash); libIteratorHash = NULL; } libError = SA_OK; finalError: if (libError == SA_OK) { if (libClient != NULL) { for (i=0; i<2; i++) { if (libClient->channel[i] != NULL) { ch = libClient->channel[i]; ch->ops->destroy(ch); } } ha_free(libClient); } } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (finalParam != NULL) { ha_free(finalParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * the invocation of this function is blocking. A new checkpoint handle is * returned upon completion. */ SaErrorT saCkptCheckpointOpen( const SaCkptHandleT *ckptHandle, const SaNameT *checkpointName, const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes, SaCkptCheckpointOpenFlagsT checkpointOpenFlags, SaTimeT timeout, SaCkptCheckpointHandleT *checkpointHandle/*[out]*/) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqOpenParamT* openParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; time_t currentTime; if (checkpointName == NULL) { cl_log(LOG_ERR, "Null checkpoint name in saCkptCheckpointOpen"); return SA_ERR_INVALID_PARAM; } if (checkpointCreationAttributes == NULL) { cl_log(LOG_ERR, "Null attributes in saCkptCheckpointOpen"); return SA_ERR_INVALID_PARAM; } if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null checkpoint handle in saCkptCheckpointOpen"); return SA_ERR_INVALID_PARAM; } if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointOpen"); return SA_ERR_INVALID_PARAM; } time(¤tTime); if (timeout < currentTime * 1000000000LL) { cl_log(LOG_ERR, "Timeout time is earlier than the current time"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptCheckpointOpen"); return SA_ERR_INVALID_PARAM; } libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); openParam = (SaCkptReqOpenParamT*)ha_malloc( sizeof(SaCkptReqOpenParamT)); libCheckpoint = (SaCkptLibCheckpointT*)ha_malloc( sizeof(SaCkptLibCheckpointT)); if ((libRequest == NULL) || (clientRequest == NULL) || (openParam == NULL) || (libCheckpoint == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointOpen"); libError = SA_ERR_NO_MEMORY; goto openError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(openParam, 0, sizeof(SaCkptReqOpenParamT)); memset(libCheckpoint, 0, sizeof(SaCkptLibCheckpointT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_OPEN; clientRequest->reqParamLength = sizeof(SaCkptReqOpenParamT); clientRequest->dataLength = 0; clientRequest->reqParam = openParam; clientRequest->data = NULL; memcpy(&(openParam->attr), checkpointCreationAttributes, sizeof(SaCkptCheckpointCreationAttributesT)); openParam->openFlag = checkpointOpenFlags; openParam->timetout = timeout; openParam->ckptName.length = checkpointName->length; memcpy(openParam->ckptName.value, checkpointName->value, checkpointName->length); ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send open request failed"); goto openError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto openError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto openError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto openError; } memcpy(checkpointHandle, clientResponse->data, sizeof(SaCkptCheckpointHandleT)); /* * create libCheckpoint and add it to the opened checkpoint list */ libCheckpoint->client = libClient; libCheckpoint->checkpointHandle = *checkpointHandle; libCheckpoint->ckptName.length = checkpointName->length; memcpy(libCheckpoint->ckptName.value, checkpointName->value, checkpointName->length); memcpy(&(libCheckpoint->createAttributes), checkpointCreationAttributes, sizeof(SaCkptCheckpointCreationAttributesT)); libCheckpoint->openFlag = checkpointOpenFlags; libClient->checkpointList = g_list_append( libClient->checkpointList, libCheckpoint); libCheckpointList = g_list_append(libCheckpointList, libCheckpoint); libError = SA_OK; openError: if (libError != SA_OK) { if (libCheckpoint != NULL) { ha_free(libCheckpoint); } } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (openParam != NULL) { ha_free(openParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * open a checkpoint asynchronously */ SaErrorT saCkptCheckpointOpenAsync( const SaCkptHandleT *ckptHandle, SaInvocationT invocation, const SaNameT *checkpointName, const SaCkptCheckpointCreationAttributesT *checkpointCreationAttributes, SaCkptCheckpointOpenFlagsT checkpointOpenFlags) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqOpenAsyncParamT* openAsyncParam = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointOpenAsync"); return SA_ERR_INVALID_PARAM; } if (checkpointName == NULL) { cl_log(LOG_ERR, "Null checkpoint name in saCkptCheckpointOpenAsync"); return SA_ERR_INVALID_PARAM; } if (checkpointCreationAttributes == NULL) { cl_log(LOG_ERR, "Null attributes in saCkptCheckpointOpenAsync"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptCheckpointOpenAsync"); return SA_ERR_INVALID_PARAM; } libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); openAsyncParam = (SaCkptReqOpenAsyncParamT*)ha_malloc( sizeof(SaCkptReqOpenAsyncParamT)); libCheckpoint = (SaCkptLibCheckpointT*)ha_malloc( sizeof(SaCkptLibCheckpointT)); if ((libRequest == NULL) || (clientRequest == NULL) || (openAsyncParam == NULL) || (libCheckpoint == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointOpenAsync"); libError = SA_ERR_NO_MEMORY; goto openError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(openAsyncParam, 0, sizeof(SaCkptReqOpenAsyncParamT)); memset(libCheckpoint, 0, sizeof(SaCkptLibCheckpointT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_OPEN_ASYNC; clientRequest->reqParamLength = sizeof(SaCkptReqOpenAsyncParamT); clientRequest->dataLength = 0; clientRequest->reqParam = openAsyncParam; clientRequest->data = NULL; memcpy(&(openAsyncParam->attr), checkpointCreationAttributes, sizeof(SaCkptCheckpointCreationAttributesT)); openAsyncParam->openFlag = checkpointOpenFlags; openAsyncParam->invocation= invocation; openAsyncParam->ckptName.length = checkpointName->length; memcpy(openAsyncParam->ckptName.value, checkpointName->value, checkpointName->length); ch = libClient->channel[1]; /*async channel*/ libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send open request failed"); goto openError; } libAsyncRequestList = g_list_append(libAsyncRequestList, libRequest); return SA_OK; openError: if (libError != SA_OK) { if (libCheckpoint != NULL) { ha_free(libCheckpoint); } } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (openAsyncParam != NULL) { ha_free(openAsyncParam); } return libError; } /* * free the resources allocated for checkpoint handle */ SaErrorT saCkptCheckpointClose( const SaCkptCheckpointHandleT *checkpointHandle) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqCloseParamT* closeParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointClose"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); closeParam = (SaCkptReqCloseParamT*)ha_malloc( sizeof(SaCkptReqCloseParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (closeParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointClose"); libError = SA_ERR_NO_MEMORY; goto closeError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(closeParam, 0, sizeof(SaCkptReqCloseParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_CLOSE; clientRequest->reqParamLength = sizeof(SaCkptReqCloseParamT); clientRequest->dataLength = 0; clientRequest->reqParam = closeParam; clientRequest->data = NULL; closeParam->checkpointHandle = *checkpointHandle; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send close request failed"); goto closeError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto closeError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto closeError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto closeError; } libClient->checkpointList = g_list_remove( libClient->checkpointList, libCheckpoint); libCheckpointList = g_list_remove( libCheckpointList, libCheckpoint); libError = SA_OK; closeError: if (libError == SA_OK) { if (libCheckpoint != NULL) { ha_free(libCheckpoint); libCheckpoint = NULL; } } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (closeParam != NULL) { ha_free(closeParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * remove this checkpoint. */ SaErrorT saCkptCheckpointUnlink( const SaCkptHandleT *ckptHandle, const SaNameT *checkpointName) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqUlnkParamT* unlinkParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointUnlink"); return SA_ERR_INVALID_PARAM; } if (checkpointName == NULL) { cl_log(LOG_ERR, "Null checkpointname in saCkptCheckpointUnlink"); return SA_ERR_INVALID_PARAM; } libClient = SaCkptGetLibClientByHandle(*ckptHandle); if (libClient == NULL) { cl_log(LOG_ERR, "Invalid handle in saCkptCheckpointUnlink"); return SA_ERR_INVALID_PARAM; } libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); unlinkParam = (SaCkptReqUlnkParamT*)ha_malloc( sizeof(SaCkptReqUlnkParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (unlinkParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointUnlink"); libError = SA_ERR_NO_MEMORY; goto unlinkError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(unlinkParam, 0, sizeof(SaCkptReqUlnkParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_ULNK; clientRequest->reqParamLength = sizeof(SaCkptReqUlnkParamT); clientRequest->dataLength = 0; clientRequest->reqParam = unlinkParam; clientRequest->data = NULL; unlinkParam->clientHandle = *ckptHandle; unlinkParam->ckptName.length = checkpointName->length; memcpy(unlinkParam->ckptName.value, checkpointName->value, checkpointName->length); ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send checkpoint_unlink request failed"); goto unlinkError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto unlinkError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto unlinkError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto unlinkError; } libError = SA_OK; unlinkError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (unlinkParam != NULL) { ha_free(unlinkParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * set the checkpoint duration. */ SaErrorT saCkptCheckpointRetentionDurationSet( const SaCkptCheckpointHandleT *checkpointHandle, SaTimeT retentionDuration) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqRtnParamT* rtnParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointRetentionDurationSet"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); rtnParam = (SaCkptReqRtnParamT*)ha_malloc( sizeof(SaCkptReqRtnParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (rtnParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointRetentionDurationSet"); libError = SA_ERR_NO_MEMORY; goto rtnError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(rtnParam, 0, sizeof(SaCkptReqRtnParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_RTN_SET; clientRequest->reqParamLength = sizeof(SaCkptReqRtnParamT); clientRequest->dataLength = 0; clientRequest->reqParam = rtnParam; clientRequest->data = NULL; rtnParam->checkpointHandle = *checkpointHandle; rtnParam->retention = retentionDuration; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send retention duration failed"); goto rtnError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto rtnError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto rtnError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto rtnError; } libCheckpoint->createAttributes.retentionDuration = retentionDuration; libError = SA_OK; rtnError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (rtnParam != NULL) { ha_free(rtnParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * set the local replica as the active replica. */ SaErrorT saCkptActiveCheckpointSet(const SaCkptCheckpointHandleT *checkpointHandle) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqActSetParamT* activeParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptActiveCheckpointSet"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); activeParam = (SaCkptReqActSetParamT*)ha_malloc( sizeof(SaCkptReqActSetParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (activeParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptActiveCheckpointSet"); libError = SA_ERR_NO_MEMORY; goto activeError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(activeParam, 0, sizeof(SaCkptReqActSetParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_ACT_SET; clientRequest->reqParamLength = sizeof(SaCkptReqActSetParamT); clientRequest->dataLength = 0; clientRequest->reqParam = activeParam; clientRequest->data = NULL; activeParam->checkpointHandle = *checkpointHandle; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send activate_checkpoint_set request failed"); goto activeError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto activeError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto activeError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto activeError; } libError = SA_OK; activeError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (activeParam != NULL) { ha_free(activeParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* get the checkpoint status */ SaErrorT saCkptCheckpointStatusGet( const SaCkptCheckpointHandleT *checkpointHandle, SaCkptCheckpointStatusT *checkpointStatus/*[out]*/) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqStatGetParamT* statParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null checkpoint handle in saCkptCheckpointStatusGet"); return SA_ERR_INVALID_PARAM; } if (checkpointStatus == NULL) { cl_log(LOG_ERR, "Null status in saCkptCheckpointStatusGet"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); statParam = (SaCkptReqStatGetParamT*)ha_malloc( sizeof(SaCkptReqStatGetParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (statParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointStatusGet"); libError = SA_ERR_NO_MEMORY; goto statError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(statParam, 0, sizeof(SaCkptReqStatGetParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_STAT_GET; clientRequest->reqParamLength = sizeof(SaCkptReqStatGetParamT); clientRequest->dataLength = 0; clientRequest->reqParam = statParam; clientRequest->data = NULL; statParam->checkpointHandle = *checkpointHandle; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send status_get request failed"); goto statError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto statError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto statError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto statError; } if (clientResponse->dataLength < (SaSizeT)sizeof(SaCkptCheckpointStatusT)) { cl_log(LOG_ERR, "Checkpoint daemon returned error data"); libError = clientResponse->retVal; goto statError; } memcpy(checkpointStatus, clientResponse->data, clientResponse->dataLength); libError = SA_OK; statError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (statParam != NULL) { ha_free(statParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* create a new section within the checkpoint and fill with the initial data. */ SaErrorT saCkptSectionCreate( const SaCkptCheckpointHandleT *checkpointHandle, SaCkptSectionCreationAttributesT *sectionCreationAttributes, const void *initialData, SaUint32T initialDataSize) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSecCrtParamT* secCrtParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; SaCkptSectionIdT* sectionId = NULL; void* data = NULL; time_t currentTime; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } if (sectionCreationAttributes == NULL) { cl_log(LOG_ERR, "Null section attribute in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } if (sectionCreationAttributes->sectionId == NULL) { cl_log(LOG_ERR, "Null section ID in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } if ((sectionCreationAttributes->sectionId->idLen < 0)) { cl_log(LOG_ERR, "Negative sectionId idLen in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } if ((sectionCreationAttributes->sectionId->id == NULL) ^ (sectionCreationAttributes->sectionId->idLen == 0)) { cl_log(LOG_ERR, "Miss match sectionId id and idLen in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } /* * if the section ID is SA_CKPT_GENERATED_SECTION_ID, * generate a random ID for the section */ if ((sectionCreationAttributes->sectionId->id == NULL) && (sectionCreationAttributes->sectionId->idLen == 0)) { int randomNumber = 0; time(¤tTime); srand(currentTime); randomNumber = rand(); sectionCreationAttributes->sectionId->idLen = sizeof(int); sectionCreationAttributes->sectionId->id = (SaUint8T*)ha_malloc(sizeof(int)); if (sectionCreationAttributes->sectionId->id == NULL) { cl_log(LOG_ERR, "No memory in saCkptSectionCreate"); return SA_ERR_NO_MEMORY; } memcpy(sectionCreationAttributes->sectionId->id, &randomNumber, sizeof(int)); } if ((initialDataSize != 0) && (initialData == NULL)) { cl_log(LOG_ERR, "No initial data in saCkptSectionCreate"); return SA_ERR_INVALID_PARAM; } time(¤tTime); if (sectionCreationAttributes->expirationTime < currentTime * 1000000000LL) { cl_log(LOG_ERR, "Expiration time is earlier than the current time"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } if (!(libCheckpoint->openFlag & SA_CKPT_CHECKPOINT_WRITE)) { cl_log(LOG_ERR, "Checkpoint is not opened for write"); return SA_ERR_ACCESS; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); secCrtParam = (SaCkptReqSecCrtParamT*)ha_malloc( sizeof(SaCkptReqSecCrtParamT) \ +sectionCreationAttributes->sectionId->idLen); if (initialDataSize > 0) { data = (void*)ha_malloc(initialDataSize); } if ((libRequest == NULL) || (clientRequest == NULL) || (secCrtParam == NULL) || ((initialDataSize > 0) && (data == NULL))) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secCrtError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(secCrtParam, 0, sizeof(SaCkptReqSecCrtParamT)\ +sectionCreationAttributes->sectionId->idLen); memcpy(data, initialData, initialDataSize); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_CRT; clientRequest->reqParamLength = sizeof(SaCkptReqSecCrtParamT) + sectionCreationAttributes->sectionId->idLen; clientRequest->dataLength = initialDataSize; clientRequest->reqParam = secCrtParam; clientRequest->data = data; secCrtParam->checkpointHandle = *checkpointHandle; secCrtParam->expireTime = sectionCreationAttributes->expirationTime; secCrtParam->sectionID.idLen = sectionCreationAttributes->sectionId->idLen; memcpy(secCrtParam->sectionID.id, sectionCreationAttributes->sectionId->id, sectionCreationAttributes->sectionId->idLen); ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section_create request failed"); goto secCrtError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secCrtError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secCrtError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secCrtError; } /* return the section ID */ if (clientResponse->dataLength > 0) { sectionId = (SaCkptSectionIdT*)clientResponse->data; sectionCreationAttributes->sectionId->idLen = sectionId->idLen; memcpy(sectionCreationAttributes->sectionId->id, sectionId->id, sectionId->idLen); } libError = SA_OK; secCrtError: if (data != NULL) { ha_free(data); } if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (secCrtParam != NULL) { ha_free(secCrtParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * delete the section within the checkpoint. */ SaErrorT saCkptSectionDelete( const SaCkptCheckpointHandleT *checkpointHandle, const SaCkptSectionIdT *sectionId) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSecDelParamT* secDelParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSectionDelete"); return SA_ERR_INVALID_PARAM; } if (sectionId == NULL) { cl_log(LOG_ERR, "Null section ID in saCkptSectionDelete"); return SA_ERR_INVALID_PARAM; } if ((sectionId->id == NULL) && (sectionId->idLen == 0)) { cl_log(LOG_ERR, "Cannot delete default section in saCkptSectionDelete"); return SA_ERR_INVALID_PARAM; } if ((sectionId->id == NULL) ^ (sectionId->idLen == 0)) { cl_log(LOG_ERR, "Mismatch id and idLen on sectionId in saCkptSectionDelete"); return SA_ERR_INVALID_PARAM; } if ((sectionId->idLen < 0)) { cl_log(LOG_ERR, "Negative idLen in saCkptSectionDelete"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } if (!(libCheckpoint->openFlag & SA_CKPT_CHECKPOINT_WRITE)) { cl_log(LOG_ERR, "Checkpoint is not opened for write"); return SA_ERR_ACCESS; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); secDelParam = (SaCkptReqSecDelParamT*)ha_malloc( sizeof(SaCkptReqSecDelParamT) \ + sectionId->idLen); if ((libRequest == NULL) || (clientRequest == NULL) || (secDelParam == NULL) ) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secDelError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(secDelParam, 0, sizeof(SaCkptReqSecDelParamT)\ + sectionId->idLen ); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_DEL; clientRequest->reqParamLength = sizeof(SaCkptReqSecDelParamT) + sectionId->idLen; clientRequest->dataLength = 0; clientRequest->reqParam = secDelParam; clientRequest->data = NULL; secDelParam->checkpointHandle = *checkpointHandle; secDelParam->sectionID.idLen = sectionId->idLen; memcpy(secDelParam->sectionID.id, sectionId->id, sectionId->idLen); ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section_delete request failed"); goto secDelError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secDelError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secDelError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secDelError; } libError = SA_OK; secDelError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (secDelParam != NULL) { ha_free(secDelParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* set the section expiration time */ SaErrorT saCkptSectionExpirationTimeSet( const SaCkptCheckpointHandleT *checkpointHandle, const SaCkptSectionIdT* sectionId, SaTimeT expirationTime) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSecExpSetParamT* secExpSetParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; time_t currentTime; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSectionExpirationTimeSet"); return SA_ERR_INVALID_PARAM; } if (sectionId == NULL) { cl_log(LOG_ERR, "Null section ID in saCkptSectionExpirationTimeSet"); return SA_ERR_INVALID_PARAM; } if ((sectionId->id == NULL) && (sectionId->idLen == 0)) { cl_log(LOG_ERR, "Default section can not expire"); return SA_ERR_INVALID_PARAM; } if ((sectionId->id == NULL) ^ (sectionId->idLen == 0)) { cl_log(LOG_ERR, "Mismatch id and idLen on sectionId in saCkptSectionExpirationTimeSet"); return SA_ERR_INVALID_PARAM; } if ((sectionId->idLen < 0)) { cl_log(LOG_ERR, "Negative idLen in saCkptSectionExpirationTimeSet"); return SA_ERR_INVALID_PARAM; } time(¤tTime); if (expirationTime < currentTime * 1000000000LL) { cl_log(LOG_ERR, "Expiration time is earlier than the current time"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); secExpSetParam = (SaCkptReqSecExpSetParamT*)ha_malloc( sizeof(SaCkptReqSecExpSetParamT) \ + sectionId->idLen); if ((libRequest == NULL) || (clientRequest == NULL) || (secExpSetParam == NULL) ) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secExpSetError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(secExpSetParam, 0, sizeof(SaCkptReqSecExpSetParamT) \ + sectionId->idLen); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_EXP_SET; clientRequest->reqParamLength = sizeof(SaCkptReqSecExpSetParamT) + sectionId->idLen; clientRequest->dataLength = 0; clientRequest->reqParam = secExpSetParam; clientRequest->data = NULL; secExpSetParam->checkpointHandle = *checkpointHandle; secExpSetParam->sectionID.idLen = sectionId->idLen; memcpy(secExpSetParam->sectionID.id, sectionId->id, sectionId->idLen); secExpSetParam->expireTime = expirationTime; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section_expiration_set request failed"); goto secExpSetError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secExpSetError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secExpSetError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secExpSetError; } libError = SA_OK; secExpSetError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (secExpSetParam != NULL) { ha_free(secExpSetParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * initialize the section interator */ SaErrorT saCkptSectionIteratorInitialize( const SaCkptCheckpointHandleT *checkpointHandle, SaCkptSectionsChosenT sectionsChosen, SaTimeT expirationTime, SaCkptSectionIteratorT *sectionIterator/*[out]*/) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSecQueryParamT* secQueryParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; IPC_Channel* ch = NULL; GList* sectionList = NULL; SaCkptSectionDescriptorT* sectionDescriptor = NULL; int sectionNumber = 0; int i = 0; char * p = NULL; SaErrorT libError = SA_OK; time_t currentTime; if (libIteratorHash == NULL) { cl_log(LOG_ERR, "Library is not initialized"); return SA_ERR_INIT; } if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSectionIteratorInitialize"); return SA_ERR_INVALID_PARAM; } if (sectionIterator == NULL) { cl_log(LOG_ERR, "Null sectionIterator in saCkptSectionIteratorInitialize"); return SA_ERR_INVALID_PARAM; } time(¤tTime); if ((expirationTime < currentTime * 1000000000LL) && (sectionsChosen != SA_CKPT_SECTIONS_FOREVER) && (sectionsChosen != SA_CKPT_SECTIONS_ANY) && (sectionsChosen != SA_CKPT_SECTION_CORRUPTED)){ cl_log(LOG_ERR, "Expiration time is earlier than the current time"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); secQueryParam = (SaCkptReqSecQueryParamT*)ha_malloc( sizeof(SaCkptReqSecQueryParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (secQueryParam == NULL) ) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secQueryError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(secQueryParam, 0, sizeof(SaCkptReqSecQueryParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_QUERY; clientRequest->reqParamLength = sizeof(SaCkptReqSecQueryParamT); clientRequest->dataLength = 0; clientRequest->reqParam = secQueryParam; clientRequest->data = NULL; secQueryParam->checkpointHandle = *checkpointHandle; secQueryParam->chosenFlag = sectionsChosen; secQueryParam->expireTime = expirationTime; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send iterator_init request failed"); goto secQueryError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secQueryError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secQueryError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secQueryError; } *sectionIterator = SaCkptLibGetIterator(); if(clientResponse->dataLength < sizeof(int)){ cl_log(LOG_ERR,"response have err datalength"); libError = SA_ERR_LIBRARY; goto secQueryError; } p = clientResponse->data; sectionNumber = *(int *)p; p += sizeof(int); // responseSectionDescriptor = (SaCkptSectionDescriptorT *)p; /* FIXME: Not thread safe */ for(i=0; isectionId.idLen > 0) { sectionDescriptor->sectionId.id = ha_malloc(sectionDescriptor->sectionId.idLen); if(sectionDescriptor->sectionId.id == NULL){ cl_log(LOG_ERR, "No memory in saCkptSectionIteratorInitialize"); libError = SA_ERR_NO_MEMORY; goto secQueryError; } memcpy(sectionDescriptor->sectionId.id, p, sectionDescriptor->sectionId.idLen); p += sectionDescriptor->sectionId.idLen; } else { sectionDescriptor->sectionId.id = NULL; } sectionList = g_list_append(sectionList, sectionDescriptor); } g_hash_table_insert(libIteratorHash, sectionIterator, sectionList); libError = SA_OK; secQueryError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (secQueryParam != NULL) { ha_free(secQueryParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* get the next section in the iterator */ SaErrorT saCkptSectionIteratorNext( SaCkptSectionIteratorT *sectionIterator/*[in/out]*/, SaCkptSectionDescriptorT *sectionDescriptor/*[out]*/) { SaCkptSectionDescriptorT* secDescriptor = NULL; GList* sectionList = NULL; if (libIteratorHash == NULL) { cl_log(LOG_ERR, "Library is not initialized"); return SA_ERR_INIT; } if (sectionIterator == NULL) { cl_log(LOG_ERR, "Null sectionIterator in saCkptSectionIteratorNext"); return SA_ERR_INVALID_PARAM; } if (sectionDescriptor == NULL) { cl_log(LOG_ERR, "Null sectionDescriptor in saCkptSectionIteratorNext"); return SA_ERR_INVALID_PARAM; } sectionList = g_hash_table_lookup(libIteratorHash, sectionIterator); if (sectionList == NULL) { /* FIXME: should be SA_ERR_NO_SECTIONS */ /* return SA_ERR_LIBRARY; */ return SA_ERR_NOT_EXIST; } secDescriptor = (SaCkptSectionDescriptorT*)sectionList->data; memcpy(sectionDescriptor, secDescriptor, sizeof(SaCkptSectionDescriptorT)); if (secDescriptor->sectionId.idLen > 0) { sectionDescriptor->sectionId.id = ha_malloc( secDescriptor->sectionId.idLen); memcpy(sectionDescriptor->sectionId.id, secDescriptor->sectionId.id, secDescriptor->sectionId.idLen); ha_free(secDescriptor->sectionId.id); } ha_free(secDescriptor); sectionList = g_list_remove(sectionList, secDescriptor); /* FIXME: what about when the list is null */ g_hash_table_insert(libIteratorHash, sectionIterator, sectionList); return SA_OK; } /* release the resource allocated to this iterator, sectionIterator should be * that returned by saCkptSectionIteratorInitialize */ SaErrorT saCkptSectionIteratorFinalize( SaCkptSectionIteratorT *sectionIterator) { SaCkptSectionDescriptorT* secDescriptor = NULL; GList* sectionList = NULL; if (libIteratorHash == NULL) { cl_log(LOG_ERR, "Library is not initialized"); return SA_ERR_INIT; } if (sectionIterator == NULL) { cl_log(LOG_ERR, "Null sectionIterator in saCkptSectionIteratorFinalize"); return SA_ERR_INVALID_PARAM; } sectionList = g_hash_table_lookup(libIteratorHash, sectionIterator); while (sectionList != NULL) { secDescriptor = (SaCkptSectionDescriptorT*)sectionList->data; if (secDescriptor->sectionId.idLen > 0) { ha_free(secDescriptor->sectionId.id); } ha_free(secDescriptor); sectionList = g_list_remove(sectionList, secDescriptor); } g_hash_table_remove(libIteratorHash, sectionIterator); return SA_OK; } static SaErrorT saCkptCheckpointSectionWrite( SaCkptReqSecWrtParamT *wrtParam, SaUint32T dataLength, void* data) { SaCkptCheckpointHandleT* checkpointHandle = NULL; SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if ((dataLength != 0) && (data == NULL)) { cl_log(LOG_ERR, "Null data in saCkptCheckpointSectionWrite"); return SA_ERR_INVALID_PARAM; } checkpointHandle = &wrtParam->checkpointHandle; libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); if ((libRequest == NULL) || (clientRequest == NULL) ) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secWrtError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_WRT; clientRequest->reqParamLength = sizeof(SaCkptReqSecWrtParamT) + wrtParam->sectionID.idLen;; clientRequest->dataLength = dataLength; clientRequest->reqParam = wrtParam; clientRequest->data = data; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section_write request failed"); goto secWrtError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secWrtError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secWrtError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secWrtError; } libError = SA_OK; secWrtError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } static SaErrorT saCkptCheckpointSectionRead( SaCkptReqSecReadParamT *readParam, SaSizeT* dataLength, void* data) { SaCkptCheckpointHandleT* checkpointHandle = NULL; SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; checkpointHandle = &readParam->checkpointHandle; libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); if ((libRequest == NULL) || (clientRequest == NULL) ) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto secReadError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_RD; clientRequest->reqParamLength = sizeof(SaCkptReqSecReadParamT) + readParam->sectionID.idLen; clientRequest->dataLength = 0; clientRequest->reqParam = readParam; clientRequest->data = NULL; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section read request failed"); goto secReadError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secReadError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secReadError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secReadError; } *dataLength = clientResponse->dataLength; memcpy(data, clientResponse->data, clientResponse->dataLength); libError = SA_OK; secReadError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } SaErrorT saCkptCheckpointWrite( const SaCkptCheckpointHandleT *checkpointHandle, const SaCkptIOVectorElementT *ioVector, SaUint32T numberOfElements, SaUint32T *erroneousVectorIndex) { SaCkptLibCheckpointT* libCheckpoint = NULL; SaCkptReqSecWrtParamT* wrtParam = NULL; SaUint32T maxSectionIdLen = 0; SaErrorT libError = SA_OK; SaUint32T i = 0; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointWrite"); return SA_ERR_INVALID_PARAM; } if (ioVector == NULL) { cl_log(LOG_ERR, "Null ioVector in saCkptCheckpointWrite"); return SA_ERR_INVALID_PARAM; } if (numberOfElements <= 0) { cl_log(LOG_ERR, "No ioVector in saCkptCheckpointWrite"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } if (!(libCheckpoint->openFlag & SA_CKPT_CHECKPOINT_WRITE)) { cl_log(LOG_ERR, "Checkpoint is not opened for write"); return SA_ERR_ACCESS; } for(i=0; icheckpointHandle = *checkpointHandle; wrtParam->sectionID.idLen= ioVector[i].sectionId.idLen; memcpy(wrtParam->sectionID.id, ioVector[i].sectionId.id, ioVector[i].sectionId.idLen); wrtParam->offset = ioVector[i].dataOffset; libError = saCkptCheckpointSectionWrite(wrtParam, ioVector[i].dataSize, ioVector[i].dataBuffer); if (libError != SA_OK) { if (erroneousVectorIndex != NULL) { *erroneousVectorIndex = i; } break; } if(wrtParam != NULL) { ha_free(wrtParam); wrtParam = NULL; } } if(wrtParam != NULL) ha_free(wrtParam); return libError; } /* overwrite the section */ SaErrorT saCkptSectionOverwrite( const SaCkptCheckpointHandleT *checkpointHandle, const SaCkptSectionIdT *sectionId, SaUint8T *dataBuffer, SaSizeT dataSize) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSecOwrtParamT* secOwrtParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptSectionOverwrite"); return SA_ERR_INVALID_PARAM; } if (sectionId == NULL) { cl_log(LOG_ERR, "Null sectionId in saCkptSectionOverwrite"); return SA_ERR_INVALID_PARAM; } if ((dataSize != 0) && (dataBuffer == NULL)) { cl_log(LOG_ERR, "Null dataBuffer in saCkptSectionOverwrite"); return SA_ERR_INVALID_PARAM; } if (dataSize <0){ cl_log(LOG_ERR, "Negative dataSize in saCkptSectionOverwrite"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } if (!(libCheckpoint->openFlag & SA_CKPT_CHECKPOINT_WRITE)) { cl_log(LOG_ERR, "Checkpoint is not opened for write"); return SA_ERR_ACCESS; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); secOwrtParam = (SaCkptReqSecOwrtParamT*)ha_malloc( sizeof(SaCkptReqSecOwrtParamT) + sectionId->idLen); if ((libRequest == NULL) || (clientRequest == NULL) || (secOwrtParam == NULL) ) { cl_log(LOG_ERR, "No memory in saCkptSectionOverwrite"); libError = SA_ERR_NO_MEMORY; goto secOwrtError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(secOwrtParam, 0, sizeof(SaCkptReqSecOwrtParamT) + sectionId->idLen); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_SEC_OWRT; clientRequest->reqParamLength = sizeof(SaCkptReqSecOwrtParamT)+ sectionId->idLen;; clientRequest->dataLength = dataSize; clientRequest->reqParam = secOwrtParam; clientRequest->data = dataBuffer; secOwrtParam->checkpointHandle = *checkpointHandle; secOwrtParam->sectionID.idLen = sectionId->idLen; memcpy(secOwrtParam->sectionID.id, sectionId->id, sectionId->idLen); ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send section_overwrite request failed"); goto secOwrtError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto secOwrtError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto secOwrtError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto secOwrtError; } libError = SA_OK; secOwrtError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (secOwrtParam != NULL) { ha_free(secOwrtParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * read multiple section data from checkpoint. */ SaErrorT saCkptCheckpointRead( const SaCkptCheckpointHandleT *checkpointHandle, SaCkptIOVectorElementT *ioVector, SaUint32T numberOfElements, SaUint32T *erroneousVectorIndex/*[out]*/) { SaCkptLibCheckpointT* libCheckpoint = NULL; SaCkptReqSecReadParamT* readParam = NULL; SaUint32T maxSectionIdLen = 0; SaErrorT libError = SA_OK; int i = 0; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointRead"); return SA_ERR_INVALID_PARAM; } if (ioVector == NULL) { cl_log(LOG_ERR, "Null ioVector in saCkptCheckpointRead"); return SA_ERR_INVALID_PARAM; } if (numberOfElements <= 0) { cl_log(LOG_ERR, "No ioVector in saCkptCheckpointRead"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } if (!(libCheckpoint->openFlag & SA_CKPT_CHECKPOINT_READ)) { cl_log(LOG_ERR, "Checkpoint is not opened for read"); return SA_ERR_ACCESS; } for(i=0; icheckpointHandle = *checkpointHandle; readParam->sectionID.idLen= ioVector[i].sectionId.idLen; memcpy(readParam->sectionID.id, ioVector[i].sectionId.id, ioVector[i].sectionId.idLen); readParam->offset = ioVector[i].dataOffset; readParam->dataSize = ioVector[i].dataSize; libError = saCkptCheckpointSectionRead(readParam, &(ioVector[i].readSize), ioVector[i].dataBuffer); if (libError != SA_OK) { if (erroneousVectorIndex != NULL) { *erroneousVectorIndex = i; } break; } } if( readParam != NULL) ha_free(readParam); return libError; } /* * synchronize the checkpoint to all replicas */ SaErrorT saCkptCheckpointSynchronize( const SaCkptCheckpointHandleT *checkpointHandle, SaTimeT timeout) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqSyncParamT* syncParam = NULL; SaCkptClientResponseT* clientResponse = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; time_t currentTime; if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointSynchronize"); return SA_ERR_INVALID_PARAM; } time(¤tTime); if (timeout < currentTime * 1000000000LL) { cl_log(LOG_ERR, "Timeout time is earlier than the current time"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); syncParam = (SaCkptReqSyncParamT*)ha_malloc( sizeof(SaCkptReqSyncParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (syncParam == NULL)) { cl_log(LOG_ERR, "No memory in saCkptCheckpointSynchronize"); libError = SA_ERR_NO_MEMORY; goto syncError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(syncParam, 0, sizeof(SaCkptReqSyncParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_SYNC; clientRequest->reqParamLength = sizeof(SaCkptReqSyncParamT); clientRequest->dataLength = 0; clientRequest->reqParam = syncParam; clientRequest->data = NULL; syncParam->checkpointHandle = *checkpointHandle; syncParam->timeout = timeout; ch = libClient->channel[0]; libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send activate_checkpoint_set request failed"); goto syncError; } libError = SaCkptLibResponseReceive(ch, libRequest->clientRequest->requestNO, &clientResponse); if (libError != SA_OK) { cl_log(LOG_ERR, "Receive response failed"); goto syncError; } if (clientResponse == NULL) { cl_log(LOG_ERR, "Received null response"); libError = SA_ERR_LIBRARY; goto syncError; } if (clientResponse->retVal != SA_OK) { cl_log(LOG_ERR, "Checkpoint daemon returned error"); libError = clientResponse->retVal; goto syncError; } libError = SA_OK; syncError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (syncParam != NULL) { ha_free(syncParam); } if (clientResponse != NULL) { if (clientResponse->dataLength > 0) { ha_free(clientResponse->data); } ha_free(clientResponse); } return libError; } /* * sychronize the checkpoint replica on all nodes */ SaErrorT saCkptCheckpointSynchronizeAsync( const SaCkptHandleT *ckptHandle, SaInvocationT invocation, const SaCkptCheckpointHandleT *checkpointHandle) { SaCkptLibClientT* libClient = NULL; SaCkptLibRequestT* libRequest = NULL; SaCkptClientRequestT* clientRequest = NULL; SaCkptReqAsyncParamT* asyncParam = NULL; SaCkptLibCheckpointT* libCheckpoint = NULL; SaErrorT libError = SA_OK; IPC_Channel* ch = NULL; if (ckptHandle == NULL) { cl_log(LOG_ERR, "Null handle in saCkptCheckpointSynchronizeAsync"); return SA_ERR_INVALID_PARAM; } if (checkpointHandle == NULL) { cl_log(LOG_ERR, "Null checkpoint handle in saCkptCheckpointSynchronizeAsync"); return SA_ERR_INVALID_PARAM; } libCheckpoint = SaCkptGetLibCheckpointByHandle( *checkpointHandle); if (libCheckpoint == NULL) { cl_log(LOG_ERR, "Checkpoint is not open"); return SA_ERR_INVALID_PARAM; } libClient = libCheckpoint->client; libRequest = (SaCkptLibRequestT*)ha_malloc( sizeof(SaCkptLibRequestT)); clientRequest = (SaCkptClientRequestT*)ha_malloc( sizeof(SaCkptClientRequestT)); asyncParam = (SaCkptReqAsyncParamT*)ha_malloc( sizeof(SaCkptReqAsyncParamT)); if ((libRequest == NULL) || (clientRequest == NULL) || (asyncParam == NULL)) { cl_log(LOG_ERR, "No memory in checkpoint library"); libError = SA_ERR_NO_MEMORY; goto syncError; } memset(libRequest, 0, sizeof(SaCkptLibRequestT)); memset(clientRequest, 0, sizeof(SaCkptClientRequestT)); memset(asyncParam, 0, sizeof(SaCkptReqAsyncParamT)); libRequest->client = libClient; libRequest->timeoutTag = 0; libRequest->clientRequest = clientRequest; clientRequest->clientHandle = libClient->clientHandle; clientRequest->requestNO = SaCkptLibGetReqNO(); clientRequest->req = REQ_CKPT_SYNC_ASYNC; clientRequest->reqParamLength = sizeof(SaCkptReqAsyncParamT); clientRequest->dataLength = 0; clientRequest->reqParam = asyncParam; clientRequest->data = NULL; asyncParam->checkpointHandle = *checkpointHandle; asyncParam->invocation = invocation; ch = libClient->channel[1]; /* async channel */ libError = SaCkptLibRequestSend(ch, libRequest->clientRequest); if (libError != SA_OK) { cl_log(LOG_ERR, "Send activate_checkpoint_set request failed"); goto syncError; } libAsyncRequestList = g_list_append(libAsyncRequestList, libRequest); return SA_OK; syncError: if (libRequest != NULL) { ha_free(libRequest); } if (clientRequest != NULL) { ha_free(clientRequest); } if (asyncParam != NULL) { ha_free(asyncParam); } return libError; }