void clCkptTrackCallback(ClGmsHandleT handle, ClGmsClusterNotificationBufferT *notificationBuffer, ClUint32T numberOfMembers, ClRcT rc) { ClIocNodeAddressT deputy = 0; ClIocNodeAddressT newDeputy = 0; /* Set Master and deputy addresses */ if(!gCkptSvr) { clLogWarning("GMS", "TRACK", "CKPT server context is not initialized"); return; } clOsalMutexLock(&gCkptSvr->ckptClusterSem); deputy = gCkptSvr->masterInfo.deputyAddr; newDeputy = notificationBuffer->deputy; _clCkptAddressesUpdate(notificationBuffer); clOsalMutexUnlock(&gCkptSvr->ckptClusterSem); CKPT_LOCK(gCkptSvr->masterInfo.ckptMasterDBSem); if (gCkptSvr->localAddr == newDeputy && (deputy != gCkptSvr->localAddr || !gCkptSvr->isSynced) ) { /* * Add the deputy to our masterinfo peer list and announce the master about our arrival * and do the same. */ _ckptSvrArrvlAnnounce(); if (CL_OK != ckptMasterDatabaseSyncup(gCkptSvr->masterInfo.masterAddr)) { clLogWarning(CL_CKPT_AREA_ACTIVE, "IOC", "ckptMasterDatabaseSyncup failed"); } else { clLogWarning(CL_CKPT_AREA_ACTIVE, "IOC", "ckptMasterDatabaseSyncup succeeded"); } /* * If the masterdbsyncup fetched an old deputy during a IOC callback update * overlapping on the master, then just patch it with the right one here. */ if(gCkptSvr->masterInfo.deputyAddr != newDeputy) gCkptSvr->masterInfo.deputyAddr = newDeputy; } CKPT_UNLOCK(gCkptSvr->masterInfo.ckptMasterDBSem); }
void ckptTerminate(SaInvocationT invocation, const SaNameT *compName) { SaAisErrorT rc = SA_AIS_OK; clLogWarning(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED,"Checkpoint service is stopping."); /* * Deregister with debug server. */ ckptDebugDeregister(gCkptSvr->eoHdl); /* * Wait for all the other threads to finalize */ clEoQueuesQuiesce(); /* * Deregister with cpm. */ rc = saAmfComponentUnregister(amfHandle, compName, NULL); /* * Cleanup the persistent DB information. */ /* Feature not supported -- see bug 6017 -- don't forget to uncomment ckptDataBackupInitialize()! ckptDataBackupFinalize(); */ /* * Cleanup resources taken by ckpt server. */ ckptShutDown(); /* Ok tell SAFplus that we handled it properly */ saAmfResponse(amfHandle, invocation, SA_AIS_OK); unblockNow = CL_TRUE; }
/* * Frees up the handle database specified by databaseHandle. If the handle * database is empty, it frees up the database immediately. Otherwise, * it will mark the database for deletion and free it when the last entry * is deleted. */ ClRcT clHandleDatabaseDestroy(ClHandleDatabaseHandleT databaseHandle) { ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*)databaseHandle; ClRcT ec = CL_OK; ClHandleT handle = 0; hdlDbValidityChk(hdbp); ec = pthread_mutex_lock(&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); } clDbgResourceNotify(clDbgHandleGroupResource, clDbgRelease, 0, hdbp, ("Handle database %p released", (ClPtrT) hdbp)); /* * Go thru the list of handles and delete everything, if they have not * been cleaned up properly, through warning message and destroy the * database */ if (hdbp->n_handles_used > 0) /* database is not empty */ { for( handle = 0; handle < hdbp->n_handles; handle++) { if( hdbp->handles[handle].state != HANDLE_STATE_EMPTY ) { /* explicitly making '0' for smooth removal of handles */ hdbp->handles[handle].ref_count = 1; hdbp->handles[handle].state = HANDLE_STATE_PENDINGREMOVAL; ec = pthread_mutex_unlock(&hdbp->mutex); if( ec != 0 ) { /* Who cares about the error code, during shut down */ goto free_exit; } clLogWarning(CL_HDL_AREA, CL_HDL_CTX_DBDESTROY, "Handle [%p:%#llX] has not been cleaned, destroying...", (ClPtrT) hdbp, (handle + 1)); clHandleCheckin(databaseHandle, handle + 1); ec = pthread_mutex_lock(&hdbp->mutex); if( ec != 0 ) { goto free_exit; } } } } /* Explicitly not checking the error code */ pthread_mutex_unlock(&hdbp->mutex); free_exit: if( NULL != hdbp->handles ) { free(hdbp->handles); } hdbp->pValidDb = (void *) CL_HDL_INVALID_COOKIE; clHeapFree(hdbp); return CL_OK; }
ClRcT clNodeCacheLeaderIocSend(ClIocNodeAddressT currentLeader, ClIocAddressT *dstAddr) { ClRcT rc = CL_OK; ClIocSendOptionT sendOption = {CL_IOC_HIGH_PRIORITY,0,0,CL_IOC_PERSISTENT_MSG,200 }; ClIocPhysicalAddressT compAddr = { CL_IOC_BROADCAST_ADDRESS, CL_IOC_CPM_PORT }; ClTimerTimeOutT delay = { 0, 200 }; ClUint32T i = 0; ClBufferHandleT message = 0; ClEoExecutionObjT *eoObj = NULL; ClIocNotificationT notification; memset(¬ification,0,sizeof(ClIocNotificationT)); notification.protoVersion = htonl(CL_IOC_NOTIFICATION_VERSION); notification.id = (ClIocNotificationIdT) htonl(CL_IOC_NODE_ARRIVAL_NOTIFICATION); notification.nodeAddress.iocPhyAddress.nodeAddress = htonl(clIocLocalAddressGet()); notification.nodeAddress.iocPhyAddress.portId = htonl(CL_IOC_GMS_PORT); clEoMyEoObjectGet(&eoObj); while(!eoObj && i++ <= 3) { clEoMyEoObjectGet(&eoObj); clOsalTaskDelay(delay); } if(!eoObj) { clLogWarning("CAP", "ARP", "Could not send current leader update since EO still uninitialized."); return CL_ERR_NOT_INITIALIZED; } clBufferCreate(&message); currentLeader = htonl(currentLeader); rc = clBufferNBytesWrite(message, (ClUint8T *)¬ification, sizeof(ClIocNotificationT)); rc |= clBufferNBytesWrite(message, (ClUint8T*)¤tLeader, sizeof(currentLeader)); if (rc != CL_OK) { clLogError("CAP", "ARP", "clBufferNBytesWrite failed with rc = %#x", rc); clBufferDelete(&message); return rc; } rc = clIocSend(eoObj->commObj, message, CL_IOC_PORT_NOTIFICATION_PROTO, dstAddr, &sendOption); clBufferDelete(&message); return rc; }
static void cpmPayload2StandbySC(const ClGmsClusterNotificationBufferT *notificationBuffer, ClCpmLocalInfoT *pCpmLocalInfo) { ClUint32T rc = CL_OK; if(gpClCpm->haState == CL_AMS_HA_STATE_STANDBY) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Payload node already promoted to Deputy. Skipping initialization of controller functions"); return; } clLogNotice(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Payload node promoted to deputy. Initializing System controller functions on this node."); gpClCpm->pCpmConfig->cpmType = CL_CPM_GLOBAL; rc = cpmUpdateTL(CL_AMS_HA_STATE_STANDBY); if (rc != CL_OK) { clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_DEBUG, NULL, CL_CPM_LOG_1_TL_UPDATE_FAILURE, rc); } rc = clAmsStart(&gAms, CL_AMS_INSTANTIATE_MODE_STANDBY); gpClCpm->haState = CL_AMS_HA_STATE_STANDBY; gpClCpm->activeMasterNodeId = notificationBuffer->leader; gpClCpm->deputyNodeId = notificationBuffer->deputy; if (CL_OK != rc) { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Unable to initialize AMS, " "error = [%#x]", rc); cpmSelfShutDown(); return; } clLogInfo(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "initialization of AMS is successful. "); if (gpClCpm->bmTable->currentBootLevel == pCpmLocalInfo->defaultBootLevel) { cpmInitializeStandby(); } clLogNotice(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Payload to System Controller conversion done"); return ; }
ClRcT clAmsMgmtCCBBatchCommit(CL_IN ClAmsMgmtCCBBatchHandleT batchHandle) { ClRcT rc = CL_OK; ClAmsMgmtCCBBatchT *batch = (ClAmsMgmtCCBBatchT*)batchHandle; ClUint32T saveOffset = 0; if(!batch) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); if(!batch->buffer) return CL_AMS_RC(CL_ERR_NOT_INITIALIZED); if(!batch->items) { clLogWarning("CCB", "COMMIT", "Batch commit tried with no items"); return CL_OK; } rc = clBufferWriteOffsetGet(batch->buffer, &saveOffset); if(rc != CL_OK) goto out; rc = clBufferWriteOffsetSet(batch->buffer, batch->itemsOffset, CL_BUFFER_SEEK_SET); if(rc != CL_OK) goto out; /* * Update the item count */ rc = clXdrMarshallClUint32T(&batch->items, batch->buffer, 0); if(rc != CL_OK) goto out; rc = clBufferWriteOffsetSet(batch->buffer, saveOffset, CL_BUFFER_SEEK_SET); if(rc != CL_OK) goto out; rc = cl_ams_ccb_batch_rmd(CL_AMS_MGMT_CCB_BATCH_COMMIT, batch->buffer, CL_VERSION_CODE(5, 1, 0)); if(rc != CL_OK) goto out; /* * Clear the buffer for reuse */ rc = amsMgmtCCBBatchBufferInitialize(batch); out: return rc; }
ClBoolT clParseEnvBoolean(const ClCharT* envvar) { ClCharT* val = NULL; ClBoolT rc = CL_FALSE; val = getenv(envvar); if (val != NULL) { /* If the env var is defined as "". */ if (strlen(val) == 0) { rc = CL_TRUE; } else if (!strncmp(val, "1", 1) || !strncasecmp(val, "yes", 3) || !strncasecmp(val, "y", 1) || !strncasecmp(val, "true", 4) || !strncasecmp(val, "t", 1) ) { rc = CL_TRUE; } else if (!strncmp(val, "0", 1) || !strncasecmp(val, "no", 2) || !strncasecmp(val, "n", 1) || !strncasecmp(val, "false", 5) || !strncasecmp(val, "f", 1) ) { rc = CL_FALSE; } else { clLogWarning("UTL", "ENV", "Environment variable [%s] value is not understood. " "Please use 'YES' or 'NO'. Assuming 'NO'", envvar); rc = CL_FALSE; } } else { rc = CL_FALSE; } return rc; }
SaAisErrorT clClovisToSafError(ClRcT clError) { SaAisErrorT safError = SA_AIS_ERR_LIBRARY; /* First check component specific error translations */ switch(clError) { case CL_CPM_RC(CL_CPM_ERR_OPERATION_IN_PROGRESS): safError = SA_AIS_ERR_BUSY; break; } if (safError != SA_AIS_ERR_LIBRARY) return safError; /* Next check to see if the error can be translated generically */ switch(CL_GET_ERROR_CODE(clError)) { case CL_OK: { safError = SA_AIS_OK; break; } case CL_ERR_VERSION_MISMATCH: { safError = SA_AIS_ERR_VERSION; break; } case CL_ERR_TIMEOUT: { safError = SA_AIS_ERR_TIMEOUT; break; } case CL_ERR_TRY_AGAIN: { safError = SA_AIS_ERR_TRY_AGAIN; break; } case CL_ERR_INVALID_PARAMETER: { safError = SA_AIS_ERR_INVALID_PARAM; break; } case CL_ERR_NO_MEMORY: { safError = SA_AIS_ERR_NO_MEMORY; break; } case CL_ERR_INVALID_HANDLE: { safError = SA_AIS_ERR_BAD_HANDLE; break; } case CL_ERR_OP_NOT_PERMITTED: { safError = SA_AIS_ERR_ACCESS; break; } case CL_ERR_DOESNT_EXIST: { safError = SA_AIS_ERR_NOT_EXIST; break; } case CL_ERR_ALREADY_EXIST: { safError = SA_AIS_ERR_EXIST; break; } case CL_ERR_NO_SPACE: { safError = SA_AIS_ERR_NO_SPACE; break; } case CL_ERR_NO_RESOURCE: { safError = SA_AIS_ERR_NO_RESOURCES; break; } case CL_ERR_NOT_IMPLEMENTED: { safError = SA_AIS_ERR_NOT_SUPPORTED; break; } case CL_ERR_BAD_OPERATION: { safError = SA_AIS_ERR_BAD_OPERATION; break; } case CL_ERR_BAD_FLAG: { safError = SA_AIS_ERR_BAD_FLAGS; break; } case CL_ERR_NULL_POINTER: { safError = SA_AIS_ERR_INVALID_PARAM; break; } default: { clLogWarning("AMF", "SAF", "Clovis error code [%#x] is not mapped to a valid " "SAF error code, returning default [%#x]", CL_GET_ERROR_CODE(clError), (ClUint32T)safError); break; } } return safError; }
ClRcT clSafToClovisError(SaAisErrorT safError) { ClRcT clError = CL_ERR_UNSPECIFIED; switch (safError) { case SA_AIS_OK: { clError = CL_OK; break; } case SA_AIS_ERR_LIBRARY: { clError = CL_ERR_INITIALIZED; break; } case SA_AIS_ERR_VERSION: { clError = CL_ERR_VERSION_MISMATCH; break; } case SA_AIS_ERR_INIT: { clError = CL_ERR_NOT_INITIALIZED; break; } case SA_AIS_ERR_TIMEOUT: { clError = CL_ERR_TIMEOUT; break; } case SA_AIS_ERR_TRY_AGAIN: { clError = CL_ERR_TRY_AGAIN; break; } case SA_AIS_ERR_INVALID_PARAM: { clError = CL_ERR_INVALID_PARAMETER; break; } case SA_AIS_ERR_NO_MEMORY: { clError = CL_ERR_NO_MEMORY; break; } case SA_AIS_ERR_BAD_HANDLE: { clError = CL_ERR_INVALID_HANDLE; break; } case SA_AIS_ERR_BUSY: { clError = CL_ERR_TRY_AGAIN; break; } case SA_AIS_ERR_ACCESS: { clError = CL_ERR_OP_NOT_PERMITTED; break; } case SA_AIS_ERR_NOT_EXIST: { clError = CL_ERR_DOESNT_EXIST; break; } case SA_AIS_ERR_NAME_TOO_LONG: { clError = CL_ERR_OUT_OF_RANGE; break; } case SA_AIS_ERR_EXIST: { clError = CL_ERR_ALREADY_EXIST; break; } case SA_AIS_ERR_NO_SPACE: { clError = CL_ERR_NO_SPACE; break; } case SA_AIS_ERR_INTERRUPT: { clError = CL_ERR_UNSPECIFIED; break; } case SA_AIS_ERR_NAME_NOT_FOUND: { clError = CL_ERR_DOESNT_EXIST; break; } case SA_AIS_ERR_NO_RESOURCES: { clError = CL_ERR_NO_RESOURCE; break; } case SA_AIS_ERR_NOT_SUPPORTED: { clError = CL_ERR_NOT_IMPLEMENTED; break; } case SA_AIS_ERR_BAD_OPERATION: { clError = CL_ERR_BAD_OPERATION; break; } case SA_AIS_ERR_FAILED_OPERATION: { clError = CL_ERR_BAD_OPERATION; break; } case SA_AIS_ERR_BAD_FLAGS: { clError = CL_ERR_BAD_FLAG; break; } case SA_AIS_ERR_TOO_BIG: { clError = CL_ERR_OUT_OF_RANGE; break; } default: { clLogWarning("AMF", "SAF", "SAF error code [%#x] is not mapped to a valid " "Clovis error code, returning default [%#x]", (ClUint32T)safError, clError); break; } } return clError; }
ClRcT clLogFlusherCookieHandleDestroy(ClHandleT hFlusher, ClBoolT timerExpired) { ClRcT rc = CL_OK; ClLogFlushCookieT *pFlushCookie = NULL; ClLogSvrEoDataT *pSvrEoEntry = NULL; CL_LOG_DEBUG_TRACE(("Enter")); /* * FIXME: * Unable to flush this set of records but will this be true in * future also, DON'T know * Also need to reset the startAck otherwise it will not enter * the cond_wait */ rc = clLogSvrEoEntryGet(&pSvrEoEntry, NULL); if( CL_OK != rc ) { return rc; } rc = clHandleValidate(pSvrEoEntry->hFlusherDB, hFlusher); if( CL_OK != rc ) { return rc;/*Flusher handle has already been destroyed*/ } rc = clHandleCheckout(pSvrEoEntry->hFlusherDB, hFlusher, (void **) &pFlushCookie); if( (CL_TRUE == timerExpired) && (CL_OK != rc) ) { clLogTrace("LOG", "FLS", "Timer has already destroyed the handle"); return CL_OK; } if( CL_OK != rc ) { clLogError("LOG", "FLS", "Flusher handle checkout failed : " "rc[0x %x]", rc); return rc; } if( CL_FALSE == timerExpired ) { clLogWarning("LOG", "FLS", "Didn't get ack for %d records", pFlushCookie->numRecords); } CL_LOG_CLEANUP(clTimerDelete(&pFlushCookie->hTimer), CL_OK); rc = clHandleCheckin(pSvrEoEntry->hFlusherDB, hFlusher); if( CL_OK != rc ) { clLogError("LOG", "FLS", "clHandleCheckin(): rc[0x %x]", rc); } CL_LOG_CLEANUP(clHandleDestroy(pSvrEoEntry->hFlusherDB, hFlusher), CL_OK); CL_LOG_DEBUG_TRACE(("Exit")); return rc; }
ClRcT cpmGmsInitialize(void) { ClRcT rc = CL_OK; ClTimerTimeOutT timeOut = {0, 0}; ClGmsCallbacksT cpmGmsCallbacks = { NULL, cpmClusterTrackCallBack, NULL, NULL }; gpClCpm->version.releaseCode = 'B'; gpClCpm->version.majorVersion = 0x01; gpClCpm->version.minorVersion = 0x01; rc = clGmsInitialize(&gpClCpm->cpmGmsHdl, &cpmGmsCallbacks, &gpClCpm->version); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Failed to do GMS initialization, error [%#x]", rc); gpClCpm->cpmGmsHdl = CL_HANDLE_INVALID_VALUE; goto failure; } rc = clOsalMutexLock(&gpClCpm->cpmGmsMutex); CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_OSAL_MUTEX_LOCK_ERR, rc, rc, CL_LOG_HANDLE_APP); rc = clGmsClusterTrack(gpClCpm->cpmGmsHdl, CL_GMS_TRACK_CHANGES_ONLY | CL_GMS_TRACK_CURRENT, NULL); if (CL_OK != rc) { clOsalMutexUnlock(&gpClCpm->cpmGmsMutex); clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "The GMS cluster track function failed, error [%#x]", rc); goto failure; } /* * Wait for the GMS callback */ retry: #ifdef VXWORKS_BUILD timeOut.tsSec = gpClCpm->cpmGmsTimeout + 20; #else timeOut.tsSec = gpClCpm->cpmGmsTimeout + 60; /* There is no reason to not wait for a long time. 100% cpu could cause GMS to come up slowly */ #endif timeOut.tsMilliSec = 0; clLogInfo(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Node [%s] waiting for GMS cluster track callback for [%d.%d] secs", gpClCpm->pCpmLocalInfo->nodeName, timeOut.tsSec, timeOut.tsMilliSec); rc = clOsalCondWait(&gpClCpm->cpmGmsCondVar, &gpClCpm->cpmGmsMutex, timeOut); if (CL_OK != rc) { if(gpClCpm->trackCallbackInProgress) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "GMS cluster track callback in progress. Waiting for it to complete ..."); goto retry; } clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Failed to receive GMS cluster track callback, " "error [%#x].", rc); clOsalMutexUnlock(&gpClCpm->cpmGmsMutex); goto failure; } rc = clOsalMutexUnlock(&gpClCpm->cpmGmsMutex); CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_OSAL_MUTEX_UNLOCK_ERR, rc, rc, CL_LOG_HANDLE_APP); return CL_OK; failure: return rc; }
static ClRcT cpmNodeRmv(ClCharT *nodeName) { ClRcT rc = CL_OK; ClUint16T nodeKey = 0; ClCntNodeHandleT hNode = 0; ClUint32T numNode = 0; ClCpmLT *cpm = NULL; ClBoolT done = CL_NO; if (!nodeName) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "NULL pointer passed."); goto failure; } rc = clCksm16bitCompute((ClUint8T *)nodeName, strlen(nodeName), &nodeKey); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to compute checksum for node, " "error [%#x]", rc); goto failure; } clOsalMutexLock(gpClCpm->cpmTableMutex); rc = clCntNodeFind(gpClCpm->cpmTable, (ClCntKeyHandleT)(ClWordT)nodeKey, &hNode); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to find node [%s], error [%#x]", nodeName, rc); goto unlock; } rc = clCntKeySizeGet(gpClCpm->cpmTable, (ClCntKeyHandleT)(ClWordT)nodeKey, &numNode); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Unable to get key size, error [%#x]", rc); goto unlock; } while (numNode > 0) { rc = clCntNodeUserDataGet(gpClCpm->cpmTable, hNode, (ClCntNodeHandleT *) &cpm); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Unable to get user data, error [%#x]", rc); goto unlock; } if (!strncmp(nodeName, cpm->nodeName, CL_MAX_NAME_LENGTH-1)) { clCntNodeDelete(gpClCpm->cpmTable, hNode); done = CL_YES; break; } if (--numNode) { rc = clCntNextNodeGet(gpClCpm->cpmTable, hNode, &hNode); if (CL_OK != rc) { break; } } } if (!done) { rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST); goto unlock; } --gpClCpm->noOfCpm; clOsalMutexUnlock(gpClCpm->cpmTableMutex); /* * Delete from slot table */ clOsalMutexLock(&gpClCpm->cpmMutex); if(cpmSlotClassDelete(nodeName) != CL_OK) { clLogWarning("CPM", "MGMT", "Slot class delete failed for node [%s]", nodeName); } clOsalMutexUnlock(&gpClCpm->cpmMutex); return CL_OK; unlock: clOsalMutexUnlock(gpClCpm->cpmTableMutex); failure: return rc; }
ClRcT cpmInvocationAddKey(ClUint32T cbType, void *data, ClInvocationT invocationId, ClUint32T flags) { ClRcT rc = CL_OK; ClCpmInvocationT *temp = NULL; ClUint32T invocationKey = 0; if (cbType < 0x1LL || cbType >= CL_CPM_MAX_CALLBACK) CL_CPM_CHECK(CL_LOG_SEV_ERROR, ("Invalid parameter passed \n"), CL_CPM_RC(CL_ERR_INVALID_PARAMETER)); temp = (ClCpmInvocationT *) clHeapAllocate(sizeof(ClCpmInvocationT)); if (temp == NULL) CL_CPM_CHECK(CL_LOG_SEV_ERROR, ("Unable to allocate memory \n"), CL_CPM_RC(CL_ERR_NO_MEMORY)); clOsalMutexLock(gpClCpm->invocationMutex); temp->invocation = invocationId; temp->data = data; temp->flags = flags; CL_CPM_INVOCATION_KEY_GET(invocationId, invocationKey); rc = clCntNodeAdd(gpClCpm->invocationTable, (ClCntKeyHandleT)&temp->invocation, (ClCntDataHandleT) temp, NULL); if (rc != CL_OK) { if(CL_GET_ERROR_CODE(rc) == CL_ERR_DUPLICATE) { clLogWarning("ADD", "INVOCATION", "Invocation entry [%#llx] already exists", invocationId); rc = CL_OK; } else { clLogError("ADD", "INVOCATION", "Invocation entry [%#llx] returned [%#x]", invocationId, rc); } goto withLock; } /* * Try preventing reuse of the invocation key for new invocations. */ if(gpClCpm->invocationKey <= invocationKey) { gpClCpm->invocationKey = invocationKey + 1; } clLogDebug("ADD", "INVOCATION", "Added entry for invocation [%#llx]", invocationId); clOsalMutexUnlock(gpClCpm->invocationMutex); return rc; withLock: clOsalMutexUnlock(gpClCpm->invocationMutex); failure: if (temp != NULL) clHeapFree(temp); return rc; }
static void cpmMakeSCActiveOrDeputy(const ClGmsClusterNotificationBufferT *notificationBuffer, ClCpmLocalInfoT *pCpmLocalInfo) { ClUint32T rc = CL_OK; ClGmsNodeIdT prevMasterNodeId = gpClCpm->activeMasterNodeId; ClBoolT leadershipChanged = notificationBuffer->leadershipChanged; /* * Check for initial leadership state incase the cluster track from AMF was issued * after GMS leader election was done and GMS responded back with a track with a leadership changed * set to FALSE for a CURRENT async request from AMF. */ if(leadershipChanged == CL_FALSE && (ClInt32T) notificationBuffer->leader == pCpmLocalInfo->nodeId && (ClInt32T) prevMasterNodeId != pCpmLocalInfo->nodeId && gpClCpm->haState == CL_AMS_HA_STATE_NONE) leadershipChanged = CL_TRUE; if (leadershipChanged == CL_TRUE) { if ( (ClInt32T) notificationBuffer->leader == pCpmLocalInfo->nodeId) { clLogInfo(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Node [%d] has become the leader of the cluster", pCpmLocalInfo->nodeId); if(gpClCpm->haState != CL_AMS_HA_STATE_ACTIVE) { rc = cpmUpdateTL(CL_AMS_HA_STATE_ACTIVE); if (rc != CL_OK) { clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_DEBUG, NULL, CL_CPM_LOG_1_TL_UPDATE_FAILURE, rc); } } gpClCpm->deputyNodeId = notificationBuffer->deputy; } else if ((ClInt32T) notificationBuffer->deputy == pCpmLocalInfo->nodeId) { clLogInfo(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Node [%d] has become the deputy of the cluster", pCpmLocalInfo->nodeId); /* * Deregister the active registration if going from active to standby. */ if(gpClCpm->haState == CL_AMS_HA_STATE_ACTIVE) { clIocTransparencyDeregister(pCpmLocalInfo->nodeId << CL_CPM_IOC_SLOT_BITS); } rc = cpmUpdateTL(CL_AMS_HA_STATE_STANDBY); if (rc != CL_OK) { clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_DEBUG, NULL, CL_CPM_LOG_1_TL_UPDATE_FAILURE, rc); } } if ((gpClCpm->haState == CL_AMS_HA_STATE_ACTIVE) && ( (ClInt32T) notificationBuffer->leader != pCpmLocalInfo->nodeId)) { clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Node [%d] is changing HA state from active to standby", pCpmLocalInfo->nodeId); /* * Deregister the entry during a state change. */ if ( (ClInt32T) notificationBuffer->deputy != pCpmLocalInfo->nodeId) { clIocTransparencyDeregister((pCpmLocalInfo->nodeId) << CL_CPM_IOC_SLOT_BITS); } /* * Inform AMS to become standby and read the checkpoint. */ if ((gpClCpm->cpmToAmsCallback != NULL) && (gpClCpm->cpmToAmsCallback->amsStateChange != NULL)) { clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Informing AMS on node [%d] to change state " "from active to standby...", pCpmLocalInfo->nodeId); rc = gpClCpm->cpmToAmsCallback->amsStateChange(CL_AMS_STATE_CHANGE_ACTIVE_TO_STANDBY | CL_AMS_STATE_CHANGE_USE_CHECKPOINT); if (CL_OK != rc) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "AMS state change from active to standby " "returned [%#x]", rc); } cpmWriteNodeStatToFile("AMS", CL_NO); if(!gClAmsSwitchoverInline) { if (((notificationBuffer->numberOfItems == 0) && (notificationBuffer->notification == NULL)) && gpClCpm->polling && (gpClCpm->nodeLeaving == CL_FALSE)) { /* * This indicates that leader election API of * GMS was called. Since this involves * interaction among only system controllers, * we don't need to restart the worker nodes * like in the case of split brain handling. */ cpmActive2Standby(CL_NO); } else if (( (ClInt32T) notificationBuffer->deputy == pCpmLocalInfo->nodeId) && gpClCpm->polling && (gpClCpm->nodeLeaving == CL_FALSE)) { /* * We try and handle a possible split brain * since presently GMS shouldnt be reelecting. * And even if it does, its pretty much * invalid with respect to AMS where you could * land up with 2 actives. */ /* * We arent expected to return back. */ cpmActive2Standby(CL_NO); } } } /* * Bug 4168: * Updating the data structure gpClCpm, when the active becomes * standby. */ gpClCpm->haState = CL_AMS_HA_STATE_STANDBY; gpClCpm->activeMasterNodeId = notificationBuffer->leader; gpClCpm->deputyNodeId = notificationBuffer->deputy; if(gClAmsSwitchoverInline) { /* *Re-register with active. */ clOsalMutexUnlock(&gpClCpm->clusterMutex); cpmSwitchoverActive(); clOsalMutexLock(&gpClCpm->clusterMutex); } } else if ((gpClCpm->haState == CL_AMS_HA_STATE_STANDBY) && ( (ClInt32T) notificationBuffer->leader == pCpmLocalInfo->nodeId)) { rc = cpmStandby2Active(prevMasterNodeId, notificationBuffer->deputy); if (CL_OK != rc) { return; } } else if ((gpClCpm->haState == CL_AMS_HA_STATE_NONE) && ( (ClInt32T) notificationBuffer->leader == pCpmLocalInfo->nodeId)) { /* * Bug 4411: * Added the if-else block. * Calling the AMS initialize only if both the callback pointers * are not NULL. * FIXME: This change is sort of workaround for 2.2. * Neat solution is to protect gpClCpm structure and fields properly */ if ((gpClCpm->amsToCpmCallback != NULL) && (gpClCpm->cpmToAmsCallback != NULL)) { clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS,"Starting AMS in active mode..."); rc = clAmsStart(&gAms,CL_AMS_INSTANTIATE_MODE_ACTIVE | CL_AMS_INSTANTIATE_USE_CHECKPOINT); /* * Bug 4092: * If the AMS intitialize fails then do the * self shut down. */ if (CL_OK != rc) { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS,"Unable to initialize AMF, error = [%#x]", rc); gpClCpm->amsToCpmCallback = NULL; cpmReset(NULL,NULL); return; } } else { rc = CL_CPM_RC(CL_ERR_NULL_POINTER); if (!gpClCpm->polling) { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "AMF finalize called before AMF initialize during node shutdown."); } else { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Unable to initialize AMF, error = [%#x]", rc); cpmRestart(NULL,NULL); } return; } gpClCpm->haState = CL_AMS_HA_STATE_ACTIVE; gpClCpm->activeMasterNodeId = notificationBuffer->leader; gpClCpm->deputyNodeId = notificationBuffer->deputy; } /* * There could be more than 1 standby SC. * Every none HA-state SC except the master is updated to become to standby SC. */ else if (gpClCpm->haState == CL_AMS_HA_STATE_NONE) { /* * Bug 4411: * Added the if-else block. * Calling the clAmsStart only if both the callback pointers * are not NULL. * FIXME: This change is sort of workaround for 2.2. * Neat solution is to protect gpClCpm structure and fields properly */ if ((gpClCpm->amsToCpmCallback != NULL) && (gpClCpm->cpmToAmsCallback != NULL)) { clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Starting AMS in standby mode..."); rc = clAmsStart(&gAms,CL_AMS_INSTANTIATE_MODE_STANDBY); /* * Bug 4092: * If the AMS initialize fails then do the * self shut down. */ if (CL_OK != rc) { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS,"Unable to initialize AMS, error = [%#x]", rc); gpClCpm->amsToCpmCallback = NULL; cpmRestart(NULL,NULL); return; } } else { rc = CL_CPM_RC(CL_ERR_NULL_POINTER); if (!gpClCpm->polling) { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS,"AMS finalize called before AMS initialize during node shutdown."); } else { clLogCritical(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS,"Unable to initialize AMS, error = [%#x]", rc); cpmRestart(NULL,NULL); } return; } gpClCpm->haState = CL_AMS_HA_STATE_STANDBY; gpClCpm->activeMasterNodeId = notificationBuffer->leader; gpClCpm->deputyNodeId = notificationBuffer->deputy; if(gpClCpm->bmTable->currentBootLevel == pCpmLocalInfo->defaultBootLevel) { cpmInitializeStandby(); } } else { gpClCpm->activeMasterNodeId = notificationBuffer->leader; gpClCpm->deputyNodeId = notificationBuffer->deputy; } clLogNotice(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_CPM, "HA state of node [%s] with node ID [%d] is [%s], " "Master node is [%d]", pCpmLocalInfo->nodeName, pCpmLocalInfo->nodeId, gpClCpm->haState == CL_AMS_HA_STATE_ACTIVE ? "Active": gpClCpm->haState == CL_AMS_HA_STATE_STANDBY ? "Standby": "None", gpClCpm->activeMasterNodeId); } else { /* * Always update the deputy node ID. It may be that this * path is reached because a deputy node failed. */ gpClCpm->deputyNodeId = notificationBuffer->deputy; if (CL_CPM_IS_ACTIVE()) { if(notificationBuffer->notification && notificationBuffer->numberOfItems == 1) { if (CL_GMS_NODE_LEFT == notificationBuffer->notification->clusterChange) { cpmFailoverNode(notificationBuffer->notification-> clusterNode.nodeId, CL_FALSE); } else { clLogNotice(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Ignoring notification of type [%d] for node [%d]", notificationBuffer->notification->clusterChange, notificationBuffer->notification->clusterNode.nodeId); } } else if(notificationBuffer->notification) { clLogNotice(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_AMS, "Ignoring notification with number of items [%d], first type [%d]", notificationBuffer->numberOfItems, notificationBuffer->notification->clusterChange); } } else if ((gpClCpm->haState == CL_AMS_HA_STATE_NONE) && ( (ClInt32T) notificationBuffer->deputy == pCpmLocalInfo->nodeId)) { if(CL_GMS_NODE_JOINED == notificationBuffer->notification->clusterChange) { cpmStandbyRecover(notificationBuffer); } else if(gpClCpm->bmTable->currentBootLevel == pCpmLocalInfo->defaultBootLevel) { cpmStandbyRecover(notificationBuffer); cpmInitializeStandby(); } } } return ; }
ClRcT clBackingStorageReadWalkFile(ClBackingStorageHandleT handle, ClBackingStorageCallbackT pCallback, ClPtrT pArg, ClUint32T readSize, ClPtrT pPrivateData) { ClBackingStorageAttributesFileT *pAttr = (ClBackingStorageAttributesFileT *) pPrivateData; ClCharT data[0xffff+1]; ClSizeT size = 0; ClOffsetT curOffset = 0; struct stat st = {0}; ClRcT rc = CL_BACKING_STORAGE_RC(CL_ERR_LIBRARY); if(fstat(pAttr->fd, &st) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "stat error [%s]", strerror(errno)); goto out; } if(!st.st_size) { rc = CL_OK; clLogWarning(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "File [%s] size is empty", pAttr->baseAttr.location); goto out; } curOffset = lseek(pAttr->fd, 0, SEEK_CUR); if(curOffset < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "lseek error [%s]", strerror(errno)); goto out; } if(lseek(pAttr->fd, 0, SEEK_SET) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "lseek error [%s]", strerror(errno)); goto out; } size = st.st_size; while(size > 0) { ClInt32T err = 0; ClCharT *pData = data; ClInt32T chunkSize = CL_MIN((ClInt32T)sizeof(data), size); ClUint32T bytes = 0; if(readSize) { if(size < readSize) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "Read walk error. Chunksize doesnt match readsize [%d]", chunkSize); goto out_restore; } chunkSize = readSize; pData = (ClCharT*) clHeapAllocate(chunkSize); if(!pData) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "No memory"); goto out_restore; } } while(chunkSize > 0) { err = read(pAttr->fd, pData+bytes, chunkSize); if(err < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "read error [%s]", strerror(errno)); if(pData != data) { clHeapFree(pData); } goto out_restore; } bytes += err; chunkSize -= err; } rc = pCallback(handle, (ClPtrT)pData, bytes, pArg); if(rc != CL_OK) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_READW_FILE, "readwalk callback error [%#x]", rc); if(pData != data) { clHeapFree(pData); } goto out_restore; } size -= bytes; } rc = CL_OK; out_restore: lseek(pAttr->fd, curOffset, SEEK_SET); out: return rc; }
ClRcT clBackingStorageWriteFile(ClBackingStorageHandleT handle, ClPtrT pData, ClUint32T size, ClOffsetT offset, ClPtrT pPrivateData) { ClBackingStorageAttributesFileT *pAttr = (ClBackingStorageAttributesFileT *) pPrivateData; ClRcT rc = CL_OK; ClInt32T err = 0; ClOffsetT curOffset = 0; ClInt32T whence = SEEK_SET; rc = CL_BACKING_STORAGE_RC(CL_ERR_LIBRARY); if( offset != (ClOffsetT)-1) { curOffset = lseek(pAttr->fd, 0, SEEK_CUR); if(curOffset < 0 ) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "File lseek save error [%s]", strerror(errno)); goto out; } if(offset < 0) { whence = SEEK_END; size = -offset; } else { size -= offset; } if(lseek(pAttr->fd, offset, whence) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "File lseek error [%s]", strerror(errno)); goto out; } } while(size > 0 ) { ClInt32T n = CL_MIN(size, 32768); err = write(pAttr->fd, pData, n); if(err < 0 ) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "Write error [%s]", strerror(errno)); if(offset != (ClOffsetT)-1) { if(lseek(pAttr->fd, curOffset, SEEK_SET) < 0) { clLogError(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "lseek error [%s] restoring back offset", strerror(errno)); } } goto out; } if(err != n) { clLogWarning(CL_LOG_AREA_BACKING_STORAGE, CL_LOG_CONTEXT_WRITE_FILE, "Write wrote [%d] bytes. Expected [%d] bytes", err, n); } size -= err; pData = (ClPtrT)((ClUint8T*)pData + err); } rc = CL_OK; out: return rc; }
SaAisErrorT saCkptCheckpointOpen( SaCkptHandleT ckptHandle, const SaNameT *checkpointName, const SaCkptCheckpointCreationAttributesT *ckptAttributes, SaCkptCheckpointOpenFlagsT checkpointOpenFlags, SaTimeT timeout, SaCkptCheckpointHandleT *checkpointHandle) { ClRcT rc = CL_OK; SaAisErrorT safRc = SA_AIS_OK; ClCkptHdlT tmpCkptHdl = 0; ClCkptCheckpointCreationAttributesT ckptAttr = {0}; /* * Validate the input parameters. */ if(checkpointHandle == NULL) return SA_AIS_ERR_INVALID_PARAM; /* * Call the ckpt client open function. */ if(ckptAttributes != NULL) { if( ckptAttributes->checkpointSize > (ckptAttributes->maxSections * ckptAttributes->maxSectionSize) ) { clLogWarning("CKP", "INI", "Possible inconsistency in SAF checkpoint open. Your passed configuration parameters should have this relationship: checkpointSize (%d) is less than or equal to maxSections (%d) * maxSectionSize (%d). Reducing checkpointSize to = maxSections * maxSectionSize (which is %d).", (int) ckptAttributes->checkpointSize, (int) ckptAttributes->maxSections, (int) ckptAttributes->maxSectionSize, (int) (ckptAttributes->maxSections * ckptAttributes->maxSectionSize)); ckptAttr.checkpointSize = ckptAttributes->maxSections * ckptAttributes->maxSectionSize; } else ckptAttr.checkpointSize = ckptAttributes->checkpointSize; ckptAttr.creationFlags = ckptAttributes->creationFlags; ckptAttr.retentionDuration = ckptAttributes->retentionDuration; ckptAttr.maxSectionSize = ckptAttributes->maxSectionSize; ckptAttr.maxSections = ckptAttributes->maxSections; ckptAttr.maxSectionIdSize = ckptAttributes->maxSectionIdSize; rc = clCkptCheckpointOpen( (ClCkptSvcHdlT) ckptHandle, (SaNameT *)checkpointName, &ckptAttr, (ClCkptOpenFlagsT) checkpointOpenFlags, (ClTimeT)timeout, &tmpCkptHdl); } else { rc = clCkptCheckpointOpen( (ClCkptSvcHdlT) ckptHandle, (SaNameT *)checkpointName, NULL, (ClCkptOpenFlagsT) checkpointOpenFlags, (ClTimeT)timeout, &tmpCkptHdl); } /* * Copy the checkpoint handle to the output variable. */ *checkpointHandle = tmpCkptHdl; /* * Translate the clovis error type to SAF error type. */ clErrorTxlate(rc, &safRc); return safRc; }
ClRcT _clCkpMastertReplicaAddressUpdate(ClHandleT mastHdl, ClIocNodeAddressT actAddr) { ClRcT rc = CL_OK; ClCntNodeHandleT nodeHdl = 0; ClCntDataHandleT dataHdl = 0; CkptMasterDBEntryT *pMasterDBEntry = NULL; ClCkptClientUpdInfoT eventInfo = {0}; ClEventIdT eventId = 0; clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Changing the active address of ckpt handle [%#llX]", mastHdl); /* * Retrieve the information associated with the master hdl. */ if( CL_OK != (rc = clHandleCheckout(gCkptSvr->masterInfo.masterDBHdl, mastHdl, (void **) &pMasterDBEntry))) { clLogError(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Master db entry doesn't have this handle [%#llX]", mastHdl); return rc; } /* * Delete the entry of the node that went down from the checkpoint's * replica list. */ if (pMasterDBEntry->replicaList) clCntAllNodesForKeyDelete(pMasterDBEntry->replicaList, (ClPtrT)(ClWordT)actAddr); else { clLogWarning(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN,"Replicalist for %s is empty",pMasterDBEntry->name.value); } /* * Store the node's address as prev active address. */ pMasterDBEntry->prevActiveRepAddr = actAddr; /* * Select the new active address. In case of COLLOCATED checkpoint, * the new active address to UNINIT value. */ if (CL_CKPT_IS_COLLOCATED(pMasterDBEntry->attrib.creationFlags)) { if(pMasterDBEntry->activeRepAddr == actAddr) { pMasterDBEntry->activeRepAddr = CL_CKPT_UNINIT_ADDR; } else { if(pMasterDBEntry->activeRepAddr != CL_CKPT_UNINIT_ADDR) { /* * If we have traces of the master handle in our peer list * missed by the active replica set, then remove it here. */ clLogNotice(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Active replica is [%d]." "Removing master ckpt handle [%#llX] from last active [%d]", pMasterDBEntry->activeRepAddr, mastHdl, actAddr); _ckptPeerListMasterHdlAdd(mastHdl, actAddr, CL_CKPT_UNINIT_ADDR); } goto exitOnError; } } else { rc = clCntFirstNodeGet(pMasterDBEntry->replicaList, &nodeHdl); if(CL_ERR_INVALID_HANDLE == CL_GET_ERROR_CODE(rc) || nodeHdl == 0) { rc = CL_OK; pMasterDBEntry->activeRepAddr = CL_CKPT_UNINIT_ADDR; } CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, ("clCkptActiveReplicaAddrGet failed rc[0x %x]\n",rc), rc); if( nodeHdl != 0 ) { rc = clCntNodeUserDataGet(pMasterDBEntry->replicaList, nodeHdl, &dataHdl); CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, ("clCkptActiveReplicaAddrGet failed rc[0x %x]\n",rc), rc); pMasterDBEntry->activeRepAddr = (ClIocNodeAddressT)(ClWordT)dataHdl; } } /* * Inform the client about the change in active replica. */ if((gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr) || (clCpmIsSCCapable() && (pMasterDBEntry->prevActiveRepAddr == gCkptSvr->masterInfo.masterAddr))) { eventInfo.eventType = htonl(CL_CKPT_ACTIVE_REP_CHG_EVENT); eventInfo.actAddr = htonl(pMasterDBEntry->activeRepAddr); saNameCopy(&eventInfo.name, &pMasterDBEntry->name); eventInfo.name.length = htons(pMasterDBEntry->name.length); clLogNotice(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Changing the address from [%d] to [%d] for checkpoint [%.*s]", actAddr, pMasterDBEntry->activeRepAddr, pMasterDBEntry->name.length, pMasterDBEntry->name.value); rc = clEventPublish(gCkptSvr->clntUpdEvtHdl, (const void*)&eventInfo, sizeof(ClCkptClientUpdInfoT), &eventId); } /* * Delete the masterHdl from old address's peerlist and add to * new address's peerlist. */ if(!CL_CKPT_IS_COLLOCATED(pMasterDBEntry->attrib.creationFlags)) { _ckptPeerListMasterHdlAdd(mastHdl, actAddr, pMasterDBEntry->activeRepAddr); } exitOnError: { /* * Checkin the updated stuff. */ clHandleCheckin(gCkptSvr->masterInfo.masterDBHdl, mastHdl); return rc; } }
ClParserPtrT clParserOpenFileWithVer(const ClCharT *path, const ClCharT *file, ClVersionT *version) { ClParserPtrT top = NULL; ClCharT verStr[CL_MAX_NAME_LENGTH] = {0}; ClParserPtrT verTag = NULL; ClBoolT found = 0; const ClCharT *attrVal = NULL; ClUint32T vIndex = 0; ClCharT attrName[CL_MAX_NAME_LENGTH] = {0}; if (path == NULL || file == NULL || version == NULL) return NULL; top = clParserOpenFileAllVer(path, file); if (top == NULL) goto done; snprintf(verStr, sizeof(verStr), "%d.%d.%d", version->releaseCode, version->majorVersion, version->minorVersion); /* top is pointing to <OpenClovisAsp> tag. Look for the child * with given version */ verTag = clParserChild(top, "version"); while (verTag != NULL) { vIndex = 0; snprintf(attrName, sizeof(attrName), "v%d",vIndex); attrVal = clParserAttr(verTag, attrName); while (attrVal != NULL) { if (!strcmp(attrVal, verStr)) { found = 1; break; } vIndex++; snprintf(attrName, sizeof(attrName), "v%d",vIndex); attrVal = clParserAttr(verTag, attrName); } if (found == 1) break; verTag = verTag->next; } if (!found) { clLogWarning(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_VERSION, "Could not find the entry for version %s in %s",verStr,file); goto done; } /* Get the attributes and look for version */ return verTag->child; done: return top; }
ClRcT clHandleDestroy ( ClHandleDatabaseHandleT databaseHandle, ClHandleT handle) { ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*) databaseHandle; ClRcT ec = CL_OK; hdlDbValidityChk(hdbp); handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */ /* * Decrementing handle to ensure the non-zero handle interface. */ if (CL_HANDLE_INVALID_VALUE == handle--) { clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Passed handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */ } /* Verify this particular handle has been already created */ if( (NULL == hdbp->handles) || (0 == hdbp->n_handles_used) ) { clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Invalid attempt to delete the non exiting handle [%p:%#llX]", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } ec = pthread_mutex_lock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); } if (handle >= (ClHandleT)hdbp->n_handles) { ec = pthread_mutex_unlock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Passed handle [%p:%#llX] has not been created", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } clDbgResourceNotify(clDbgHandleResource, clDbgRelease, hdbp, handle+1, ("Handle [%p:%#llX] (state: %d, ref: %d) released", (ClPtrT)hdbp, handle+1,hdbp->handles[handle].state,hdbp->handles[handle].ref_count)); if (HANDLE_STATE_USED == hdbp->handles[handle].state) { hdbp->handles[handle].state = HANDLE_STATE_PENDINGREMOVAL; ec = pthread_mutex_unlock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } /* * Adding 1 to handle to ensure the non-zero handle interface. */ ec = clHandleCheckin (databaseHandle, handle+1); return ec; } else if (HANDLE_STATE_EMPTY == hdbp->handles[handle].state) { ec = CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } else if (HANDLE_STATE_PENDINGREMOVAL == hdbp->handles[handle].state) { ec = pthread_mutex_unlock( &hdbp->mutex); if( ec != 0 ) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } clLogWarning(CL_HDL_AREA, CL_HDL_CTX_DESTROY, "Destroy has been called for this handle [%p:%#llX]" "returning CL_OK", (ClPtrT) hdbp, (handle + 1)); return CL_OK; } else { clDbgCodeError(CL_ERR_INVALID_HANDLE, ("Passed handle [%p:%#llX] doesn't have any proper state," "corrupted code", (ClPtrT) hdbp, (handle + 1))); /* * Invalid state - this musn't happen! */ } if(pthread_mutex_unlock (&hdbp->mutex) != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } #if 0 clLogTrace(CL_HDL_AREA, CL_HDL_CTX_DESTROY, "Handle [%p:%#llX] has been deleted successfully", (ClPtrT) hdbp, (handle + 1)); #endif return ec; }
/*Process each tag*/ static ClRcT clParseTag(ClParserPtrT node,ClParserTagT *pTag,ClParserDataT *pData,ClPtrT pCurrentBase) { ClRcT rc = CL_OK; const ClCharT *pAttr; ClPtrT pValue; ClPtrT pDest; pAttr = clParserAttr(node,pTag->pTag); if(pAttr == NULL) { clLogWarning(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"XML attribute [%s] not defined, but may be optional.",pTag->pTag); /* clDbgCodeError(CL_LOG_SEV_WARNING,("Required attribute %s in xml configuration file is not defined\n",pTag->pTag)); */ goto out; } /*The place to copy*/ pDest = (ClPtrT) ((ClUint8T*)pCurrentBase+pTag->tagOffset); pValue = (ClPtrT)calloc(1,pTag->tagSize); if(pValue == NULL) { rc = CL_PARSER_RC(CL_ERR_NO_MEMORY); clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"Error allocating memory\n"); goto out; } switch(pTag->tagType) { case CL_PARSER_STR_TAG: { strncpy((ClCharT*)pValue,pAttr,pTag->tagSize); } break; /*byte stream*/ case CL_PARSER_STREAM_TAG: { memcpy(pValue,pAttr,pTag->tagSize); } break; case CL_PARSER_IP_TAG: { in_addr_t addr = inet_addr((char *)pAttr); bcopy((const char*)&addr,pValue,pTag->tagSize); } break; case CL_PARSER_BOOL_TAG: { ClBoolT v = CL_FALSE; if(!strcasecmp(pAttr,"true")) { v = CL_TRUE; } else if(!strcasecmp(pAttr,"false")) { v = CL_FALSE; } else { clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"Unknown bool value:%s " \ "for tag:%s\n", pAttr,pData->pTag); rc = CL_PARSER_RC(CL_ERR_INVALID_PARAMETER); goto out_free; } memcpy(pValue,&v,pTag->tagSize); } break; case CL_PARSER_UINT8_TAG: { ClUint8T v = (ClUint8T)atoi(pAttr); *(ClUint8T*)pValue = v; } break; case CL_PARSER_UINT16_TAG: { ClUint16T v = (ClUint16T)atoi(pAttr); memcpy(pValue,&v,pTag->tagSize); } break; case CL_PARSER_UINT32_TAG: { ClUint32T v = (ClUint32T)strtoul(pAttr,NULL,10); memcpy(pValue,&v,pTag->tagSize); } break; case CL_PARSER_UINT64_TAG: { ClUint64T v = (ClUint64T)strtoll(pAttr,NULL,10); memcpy(pValue,&v,pTag->tagSize); } break; case CL_PARSER_CUSTOM_TAG: if(pTag->pTagFmt == NULL) { rc = CL_PARSER_RC(CL_ERR_UNSPECIFIED); clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"Tag:%s - Custom tag type with no fmt handler\n",pTag->pTag); goto out_free; } break; default: { rc = CL_PARSER_RC(CL_ERR_UNSPECIFIED); clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"Unknown tag type:%d\n",pTag->tagType); goto out_free; } } if(pTag->pTagFmt) { rc = pTag->pTagFmt(pTag,pData,pCurrentBase,(ClCharT*)pAttr,pValue,CL_PARSER_TAG_FMT); CL_PARSER_TAG_RESULT(rc,out_free); /* * Validate tag */ goto validate_tag; } /*Call tag validate*/ validate_tag: if(pTag->pTagValidate && pTag->pTagValidate(pTag,pValue) == CL_FALSE ) { rc = CL_PARSER_RC(CL_ERR_INVALID_PARAMETER); clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_TAG,"Tag validation failed for tag:%s\n",pTag->pTag); goto out_free; } /*Now commit the value to the tag*/ memcpy(pDest,pValue,pTag->tagSize); out_free: free(pValue); out: return rc; }
/** * INIT: The below function initializes the checkpoint service client * and opens a checkpoint to store data. */ ClRcT clCachedCkptInitialize(ClCachedCkptSvcInfoT *serviceInfo, const SaNameT *ckptName, const SaCkptCheckpointCreationAttributesT *ckptAttributes, SaCkptCheckpointOpenFlagsT openFlags, ClUint32T cachSize) { ClRcT rc = CL_OK; SaCkptHandleT ckptSvcHandle = 0; SaCkptCheckpointHandleT ckptHandle = 0; SaVersionT ckptVersion = {'B', 0x01, 0x01}; ClTimerTimeOutT delay = { 0, 500}; ClInt32T tries = 0; ClCharT cacheName[CL_MAX_NAME_LENGTH]; ClUint32T shmSize = clCachedCkptShmSizeGet(cachSize); ClUint32T *numberOfSections; ClUint32T *sizeOfCache; serviceInfo->cachSize = shmSize; if(serviceInfo->ckptHandle != CL_HANDLE_INVALID_VALUE) { clLogWarning("CCK", "INI", "Checkpoint already initialized. Skipping initialization"); return CL_ERR_ALREADY_EXIST; } snprintf(cacheName, sizeof(cacheName), "%s_%d", ckptName->value, gIocLocalBladeAddress); rc = clOsalSemCreate((ClUint8T*)cacheName, 1, &serviceInfo->cacheSem); if(rc != CL_OK) { ClOsalSemIdT semId = 0; if(clOsalSemIdGet((ClUint8T*)cacheName, &semId) != CL_OK) { clLogError("CCK", "INI", "cache semaphore creation error while fetching semaphore id"); goto out1; } if(clOsalSemDelete(semId) != CL_OK) { clLogError("CCK", "INI", "cache semaphore creation error while deleting old semaphore id"); goto out1; } rc = clOsalSemCreate((ClUint8T*)cacheName, 1, &serviceInfo->cacheSem); } if(ckptAttributes || openFlags) { if(serviceInfo->ckptSvcHandle == CL_HANDLE_INVALID_VALUE) { /* Initialize checkpoint service instance */ do { rc = clCkptInitialize(&ckptSvcHandle, NULL, (ClVersionT *)&ckptVersion); } while(rc != CL_OK && tries++ < 100 && clOsalTaskDelay(delay) == CL_OK); if(rc != CL_OK) { clLogError("CCK", "INI", "Failed to initialize checkpoint service instance. error code [0x%x].", rc); goto out2; } serviceInfo->ckptSvcHandle = ckptSvcHandle; } /* Create the checkpoint for read and write. */ do { rc = clCkptCheckpointOpen(serviceInfo->ckptSvcHandle, (SaNameT *)ckptName, (ClCkptCheckpointCreationAttributesT *)ckptAttributes, openFlags, 0L, &ckptHandle); } while(rc != CL_OK && tries++ < 100 && clOsalTaskDelay(delay) == CL_OK); if(rc != CL_OK) { clLogError("CCK", "INI", "Failed to open checkpoint. error code [0x%x].", rc); goto out3; } serviceInfo->ckptHandle = ckptHandle; } /* Create shm */ rc = clOsalShmOpen((ClCharT *)cacheName, CL_CACHED_CKPT_SHM_EXCL_CREATE_FLAGS, CL_CACHED_CKPT_SHM_MODE, &serviceInfo->fd); if( CL_ERR_ALREADY_EXIST == CL_GET_ERROR_CODE(rc) ) { rc = clOsalShmOpen((ClCharT *)cacheName, CL_CACHED_CKPT_SHM_OPEN_FLAGS, CL_CACHED_CKPT_SHM_MODE, &serviceInfo->fd); if( CL_OK != rc ) { clLogError("CCK", "INI", "Could not open shared memory."); goto out4; } } rc = clOsalFtruncate(serviceInfo->fd, shmSize); if( CL_OK != rc ) { clLogError("CCK", "INI", "clOsalFtruncate(): error code [0x%x].", rc); goto out5; } rc = clOsalMmap(0, shmSize, CL_CACHED_CKPT_MMAP_PROT_FLAGS, CL_CACHED_CKPT_MMAP_FLAGS, serviceInfo->fd, 0, (void **) &serviceInfo->cache); if( CL_OK != rc ) { clLogError("CCK", "INI", "clOsalMmap(): error code [0x%x].", rc); goto out5; } numberOfSections = (ClUint32T *)(serviceInfo->cache); sizeOfCache = (ClUint32T *)(numberOfSections + 1); *numberOfSections = 0; *sizeOfCache = 0; clOsalMsync(serviceInfo->cache, shmSize, MS_SYNC); goto out1; out5: clOsalShmClose(&serviceInfo->fd); out4: if(serviceInfo->ckptHandle) { clCkptCheckpointClose(serviceInfo->ckptHandle); serviceInfo->ckptHandle = CL_HANDLE_INVALID_VALUE; } out3: if(serviceInfo->ckptSvcHandle) { clCkptFinalize(serviceInfo->ckptSvcHandle); serviceInfo->ckptSvcHandle = CL_HANDLE_INVALID_VALUE; } out2: clOsalSemDelete(serviceInfo->cacheSem); out1: return rc; }
ClRcT clAmsGetFaultReport( CL_IN const SaNameT *compName, CL_IN ClAmsLocalRecoveryT recommendedRecovery, CL_IN ClUint64T instantiateCookie) { ClRcT rc = CL_OK; ClUint32T escalation = 0; ClAmsEntityRefT entityRef = {{CL_AMS_ENTITY_TYPE_ENTITY},0,0}; AMS_FUNC_ENTER (("\n")); if(!compName) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); /* * First find the name reported by the fault API in the component database * If the name is not found in the component database it means that its a node * level fault escalation. In this case find the node in the node database. */ memcpy (&entityRef.entity.name, compName, sizeof (SaNameT)); entityRef.entity.type = CL_AMS_ENTITY_TYPE_COMP; AMS_CALL ( clOsalMutexLock(gAms.mutex)); if ( (rc = clAmsEntityDbFindEntity(&gAms.db.entityDb[CL_AMS_ENTITY_TYPE_COMP],&entityRef)) == CL_OK ) { ClUint64T currentInstantiateCookie = 0; ClAmsCompT *comp = (ClAmsCompT*)entityRef.ptr; clLogInfo("COMP", "FAILURE", "Processing fault for component [%s], instantiate Cookie [%lld]", comp->config.entity.name.value, instantiateCookie); currentInstantiateCookie = comp->status.instantiateCookie; if(instantiateCookie && instantiateCookie < currentInstantiateCookie) { clLogInfo("COMP", "FAILURE", "Ignoring fault for component [%s], instantiation identifier [%lld] " "as component has already been recovered with instantiation identifier [%lld]", comp->config.entity.name.value, instantiateCookie, comp->status.instantiateCookie); goto exitfn; } AMS_CHECK_RC_ERROR ( clAmsPeEntityFaultReport( entityRef.ptr, &recommendedRecovery, &escalation) ); } else { if ( CL_GET_ERROR_CODE (rc) != CL_ERR_NOT_EXIST ) { clLogWarning("COMP", "FAILURE", "Unable to find component [%s:%d] in AMS database", compName->value, compName->length); goto exitfn; } /* * See if its node level fault escalation */ entityRef.entity.type = CL_AMS_ENTITY_TYPE_NODE; AMS_CHECK_RC_ERROR( clAmsEntityDbFindEntity( &gAms.db.entityDb[CL_AMS_ENTITY_TYPE_NODE], &entityRef) ); AMS_CHECK_RC_ERROR( clAmsPeEntityFaultReport( entityRef.ptr, &recommendedRecovery, &escalation) ); } exitfn: AMS_CALL ( clOsalMutexUnlock(gAms.mutex)); return CL_AMS_RC (rc); }
static ClRcT clAmsMgmtSGRedundancyModelNoRedundancy(ClAmsSGRedundancyModelT model, const ClCharT *sg, const ClCharT *prefix, ClUint32T numActiveSUs, ClUint32T numStandbySUs, ClAmsMgmtMigrateListT *migrateList) { ClAmsSGConfigT sgConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClAmsEntityConfigT *entityConfig = NULL; ClRcT rc = CL_OK; ClAmsEntityT sgName = {CL_AMS_ENTITY_TYPE_ENTITY}; ClUint64T bitMask = 0; sgName.type = CL_AMS_ENTITY_TYPE_SG; saNameSet(&sgName.name, sg); ++sgName.name.length; rc = clAmsMgmtEntityGetConfig(gHandle, &sgName, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS entity get config returned [%#x]", rc); goto out; } memcpy(&sgConfig, entityConfig, sizeof(sgConfig)); clHeapFree(entityConfig); if(sgConfig.redundancyModel == CL_AMS_SG_REDUNDANCY_MODEL_NONE) { clLogWarning("AMS", "MIGRATE", "Redundancy model is already no redundancy"); goto out; } bitMask |= SG_CONFIG_REDUNDANCY_MODEL; sgConfig.redundancyModel = CL_AMS_SG_REDUNDANCY_MODEL_NONE; bitMask |= SG_CONFIG_NUM_PREF_ACTIVE_SUS_PER_SI; sgConfig.numPrefActiveSUsPerSI = 1; bitMask |= SG_CONFIG_NUM_PREF_ACTIVE_SUS; sgConfig.numPrefActiveSUs = numActiveSUs; bitMask |= SG_CONFIG_NUM_PREF_STANDBY_SUS; sgConfig.numPrefStandbySUs = numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_INSERVICE_SUS; sgConfig.numPrefInserviceSUs = numActiveSUs + numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_ASSIGNED_SUS; sgConfig.numPrefAssignedSUs = numActiveSUs + numStandbySUs; rc = clAmsMgmtCCBEntitySetConfig(gCcbHandle, &sgConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg set config returned [%#x]", rc); goto out; } rc = clAmsMgmtCCBCommit(gCcbHandle); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS database commit returned [%#x]", rc); goto out; } out: return rc; }
ClRcT cpmNodeAdd(ClCharT *nodeName) { ClRcT rc = CL_OK; ClCpmLT *cpm = NULL; ClUint16T nodeKey = 0; ClCpmSlotInfoT slotInfo = {0}; if (!nodeName) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "NULL pointer passed."); goto failure; } clOsalMutexLock(gpClCpm->cpmTableMutex); rc = cpmNodeFindLocked((SaUint8T *)nodeName, &cpm); clOsalMutexUnlock(gpClCpm->cpmTableMutex); if (cpm) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Node [%s] already exists on this node.", nodeName); rc = CL_CPM_RC(CL_ERR_ALREADY_EXIST); goto failure; } cpm = (ClCpmLT*) clHeapAllocate(sizeof(ClCpmLT)); if (!cpm) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Unable to allocate memory"); goto failure; } memset(cpm, 0, sizeof(ClCpmLT)); strncpy(cpm->nodeName, nodeName, strlen(nodeName)); rc = clCksm16bitCompute((ClUint8T *)cpm->nodeName, strlen(cpm->nodeName), &nodeKey); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to compute checksum for node, " "error [%#x]", rc); goto failure; } /* * Filling the CPML with defaults. */ saNameSet(&cpm->nodeType, nodeName); saNameSet(&cpm->nodeIdentifier, nodeName); /* * Set the class type to CLASS_C. */ strncpy(cpm->classType, "CL_AMS_NODE_CLASS_C", sizeof(cpm->classType)-1); /* * Get the MOID of the master node. Assuming that node add is * only invoked on the master. */ slotInfo.slotId = clIocLocalAddressGet(); rc = clCpmSlotInfoGet(CL_CPM_SLOT_ID, &slotInfo); if(rc == CL_OK) { rc = cpmCorMoIdToMoIdNameGet(&slotInfo.nodeMoId, &cpm->nodeMoIdStr); } if(rc != CL_OK) { if((CL_GET_ERROR_CODE(rc) != CL_IOC_ERR_COMP_UNREACHABLE) && (CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST) && (CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_SUPPORTED)) { goto failure; } else { rc = CL_OK; clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "COR server not running so cannot discover the Node's MoId"); } } clOsalMutexLock(gpClCpm->cpmTableMutex); rc = clCntNodeAdd(gpClCpm->cpmTable, (ClCntKeyHandleT)(ClWordT)nodeKey, (ClCntDataHandleT) cpm, NULL); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to add node to the CPM node table, " "error [%#x]", rc); clOsalMutexUnlock(gpClCpm->cpmTableMutex); goto failure; } ++gpClCpm->noOfCpm; clOsalMutexUnlock(gpClCpm->cpmTableMutex); /* * Add this to the slotinfo. */ clOsalMutexLock(&gpClCpm->cpmMutex); rc = cpmSlotClassAdd(&cpm->nodeType, &cpm->nodeIdentifier, 0); clOsalMutexUnlock(&gpClCpm->cpmMutex); if(rc != CL_OK) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Node [%s] class add returned [%#x]", cpm->nodeType.value, rc); } clLogNotice("DYN", "NODE", "Node [%s] added to the cpm table with identity [%.*s]", cpm->nodeName, cpm->nodeIdentifier.length, cpm->nodeIdentifier.value); return CL_OK; failure: return rc; }
/* * This is the main flusher therad function. This is where the flusher action * starts. */ void* clLogFlusherStart(void *pData) { ClRcT rc = CL_OK; ClLogSvrStreamDataT *pStreamData = (ClLogSvrStreamDataT*) pData; ClLogStreamHeaderT *pHeader = pStreamData->pStreamHeader; ClTimerTimeOutT timeout = {0, 0}; ClOsalTaskIdT taskId = CL_HANDLE_INVALID_VALUE; clLogDebug(CL_LOG_AREA_SVR, CL_LOG_CTX_BOOTUP, "Flusher started for stream [%.*s]", pStreamData->shmName.length, pStreamData->shmName.pValue); timeout.tsSec = pHeader->flushInterval / (1000L * 1000L * 1000L); timeout.tsMilliSec = (pHeader->flushInterval % (1000L * 1000L * 1000L)) / (1000L * 1000L); clLogDebug("LOG", "FLS", "timeout: %u sec %u millisec", timeout.tsSec, timeout.tsMilliSec); rc = clLogServerStreamMutexLockFlusher(pStreamData); if( CL_OK != rc ) { clLogError("LOG", "FLS", "CL_LOG_LOCK(): rc[0x %x]", rc); pHeader->streamStatus = CL_LOG_STREAM_THREAD_EXIT; return NULL; } if ((CL_LOG_STREAM_HEADER_STRUCT_ID != pHeader->struct_id) || (CL_LOG_STREAM_HEADER_UPDATE_COMPLETE != pHeader->update_status)) {/* Stream Header is corrupted so reset Header parameters */ clLogStreamHeaderReset(pHeader); } /* * Create a thread for flush interval */ if( CL_LOG_SEM_MODE == clLogLockModeGet() ) { rc = clLogFlushIntervalThreadCreate(pStreamData, &taskId); if( CL_OK != rc ) { clLogWarning("SVR", "FLU", "Flusher interval thread create failed" "flushFrequency function will still work..continuing..."); rc = CL_OK; taskId = CL_HANDLE_INVALID_VALUE; } } while( gClLogSvrExiting == CL_FALSE ) { CL_LOG_DEBUG_TRACE(("startIdx in server: %d startAck %d \n", pHeader->recordIdx, pHeader->startAck)); do { CL_LOG_DEBUG_TRACE(("recordIdx: %u startAck: %u cnt %d", pHeader->recordIdx, pHeader->startAck, pStreamData->ackersCount + pStreamData->nonAckersCount)); #ifndef POSIX_BUILD rc = clLogServerStreamCondWait(pStreamData, &pHeader->flushCond, timeout); #else rc = clLogServerStreamCondWait(pStreamData, NULL, timeout); #endif if( gClLogSvrExiting == CL_TRUE || ( (CL_OK != CL_GET_ERROR_CODE(rc)) && (CL_ERR_TIMEOUT != CL_GET_ERROR_CODE(rc))) ) { /* Log service is exiting or Stream is closed so come out of polling loop */ pHeader->update_status = CL_LOG_STREAM_HEADER_UPDATE_INPROGRESS; pHeader->streamStatus = CL_LOG_STREAM_CLOSE; } }while( (CL_LOG_STREAM_CLOSE != pHeader->streamStatus) && (0 == abs(pHeader->recordIdx - pHeader->startAck))); if( gClLogSvrExiting || CL_LOG_STREAM_CLOSE == pHeader->streamStatus ) { clLogInfo("SVR", "FLU", "Stream status: CLOSE...Exiting flusher [%lu] " " [%lu]", (unsigned long)pStreamData->flusherId, (long unsigned int)pthread_self()); pHeader->streamStatus = CL_LOG_STREAM_THREAD_EXIT; pHeader->update_status = CL_LOG_STREAM_HEADER_UPDATE_COMPLETE; goto exitFlusher; } rc = clLogFlusherRecordsFlush(pStreamData); if( CL_OK != rc ) { if(pHeader->streamStatus == CL_LOG_STREAM_CLOSE) { break; } } } pHeader->streamStatus = CL_LOG_STREAM_THREAD_EXIT; exitFlusher: if( CL_HANDLE_INVALID_VALUE != taskId ) { /* Flusher interval thread has been created, so signal to that guy and * wait on the variable */ clLogFlushIntervalThreadJoin(pStreamData, taskId); taskId = CL_HANDLE_INVALID_VALUE; } clLogInfo("SVR", "FLU", "Flusher for stream [%.*s] is exiting..Id [%llu]", pStreamData->shmName.length, pStreamData->shmName.pValue, pStreamData->flusherId); rc = clLogServerStreamMutexUnlock(pStreamData); if( CL_OK != rc ) { clLogError("SVR", "FLU", "Faild to unlock the stream"); } CL_LOG_DEBUG_TRACE(("Exit")); return NULL; }
static ClRcT cpmComponentAdd(ClCharT *compName) { ClRcT rc = CL_CPM_RC(CL_ERR_NULL_POINTER); ClCpmCompConfigT compConfig = { "", CL_FALSE, CL_AMS_COMP_PROPERTY_SA_AWARE, CL_CPM_COMP_SINGLE_PROCESS, "invalid", {(ClCharT*) "invalid", NULL}, {NULL}, "", "", 0, 0, 0, 0, 0, { CL_CPM_COMPONENT_DEFAULT_HC_TIMEOUT, 2 * CL_CPM_COMPONENT_DEFAULT_HC_TIMEOUT, CL_AMS_RECOVERY_NO_RECOMMENDATION } }; ClCpmComponentT *comp = NULL; ClUint16T compKey = 0; const ClCharT *config = NULL; ClCharT cleanupCMD[CL_MAX_NAME_LENGTH]; if (!compName) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "NULL pointer passed."); goto failure; } cleanupCMD[0] = 0; if( (config = getenv("ASP_CONFIG")) ) { snprintf(cleanupCMD, sizeof(cleanupCMD), "%s/%s", config, CL_CPM_COMP_CLEANUP_SCRIPT); if(access(cleanupCMD, R_OK | X_OK)) cleanupCMD[0] = 0; } rc = cpmCompFind((SaUint8T *)compName, gpClCpm->compTable, &comp); if (comp) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Component [%s] already exists on this node", compName); rc = CL_CPM_RC(CL_ERR_ALREADY_EXIST); goto failure; } strncpy(compConfig.compName, compName, CL_MAX_NAME_LENGTH-1); if(cleanupCMD[0]) strncpy(compConfig.cleanupCMD, cleanupCMD, sizeof(compConfig.cleanupCMD)-1); rc = cpmCompConfigure(&compConfig, &comp); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to configure component, error [%#x]", rc); goto failure; } rc = clCksm16bitCompute((ClUint8T *) comp->compConfig->compName, strlen(comp->compConfig->compName), &compKey); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to compute checksum for component, " "error [%#x]", rc); goto failure; } clOsalMutexLock(gpClCpm->compTableMutex); rc = clCntNodeAdd(gpClCpm->compTable, (ClCntKeyHandleT)(ClWordT)compKey, (ClCntDataHandleT) comp, NULL); if (CL_OK != rc) { clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Failed to add node to the CPM component table, " "error [%#x]", rc); clOsalMutexUnlock(gpClCpm->compTableMutex); goto failure; } ++gpClCpm->noOfComponent; clOsalMutexUnlock(gpClCpm->compTableMutex); return CL_OK; failure: return rc; }
ClRcT cpmUpdateTL(ClAmsHAStateT haState) { ClIocTLInfoT tlInfo = {0}; ClRcT rc = CL_OK; ClIocNodeAddressT localAddr = clIocLocalAddressGet(); /* * Populate the TL structure */ cpmGetOwnLogicalAddress(&(tlInfo.logicalAddr)); /* * CPM's component ID is slot number shifted * by CL_CPM_IOC_SLOT_BITS */ CL_CPM_IOC_ADDRESS_SLOT_GET(clAspLocalId, tlInfo.compId); tlInfo.compId = tlInfo.compId << CL_CPM_IOC_SLOT_BITS; tlInfo.contextType = CL_IOC_TL_GLOBAL_SCOPE; tlInfo.physicalAddr.nodeAddress = localAddr; tlInfo.physicalAddr.portId = CL_IOC_CPM_PORT; tlInfo.haState = haState; if (haState == CL_AMS_HA_STATE_ACTIVE) { tlInfo.haState = CL_IOC_TL_ACTIVE; if( (ClInt32T) gpClCpm->activeMasterNodeId != -1) { clLogDebug(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Deregistering TL entry for node [%d]", gpClCpm->activeMasterNodeId); clIocTransparencyDeregister((gpClCpm->activeMasterNodeId) << CL_CPM_IOC_SLOT_BITS); } } else if(haState == CL_AMS_HA_STATE_STANDBY) { tlInfo.haState = CL_IOC_TL_STDBY; } clLogMultiline(CL_LOG_SEV_DEBUG, CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Updating transparency layer information for node [%s] -- \n" "Component ID : [%#x] \n" "Context type : [%s] \n" "Node address : [%d] \n" "Port ID : [%d] \n" "HA state : [%s]", gpClCpm->pCpmLocalInfo->nodeName, tlInfo.compId, tlInfo.contextType == CL_IOC_TL_GLOBAL_SCOPE ? "Global" : "Local", tlInfo.physicalAddr.nodeAddress, tlInfo.physicalAddr.portId, tlInfo.haState == CL_IOC_TL_ACTIVE ? "Active" : "Standby"); /* * Update the TL with the CPM's logical address */ rc = clIocTransparencyRegister(&tlInfo); if(haState == CL_AMS_HA_STATE_ACTIVE) { /* * Reset the master segment cache for all components */ clIocMasterCacheSet(localAddr); } else { clIocMasterCacheReset(); } if (CL_IOC_ERR_TL_DUPLICATE_ENTRY == CL_GET_ERROR_CODE(rc) || CL_ERR_ALREADY_EXIST == CL_GET_ERROR_CODE(rc)) { clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS, "Transparency register returned " "duplicate entry for node address [%d]", tlInfo.physicalAddr.nodeAddress); return CL_OK; } return rc; }