/** * Adds a new definition of transaction to txn-database */ ClRcT clTxnDbNewTxnDefnAdd( CL_IN ClTxnDbHandleT txnDb, CL_IN ClTxnDefnT *pNewTxn, CL_IN ClTxnTransactionIdT *pTxnId) { ClRcT rc = CL_OK; ClTxnDefnT *pTxnDef; CL_FUNC_ENTER(); rc = clCntDataForKeyGet(txnDb, (ClCntKeyHandleT) pTxnId, (ClCntDataHandleT *) &pTxnDef); if (CL_OK != rc) { rc = clCntNodeAdd(txnDb, (ClCntKeyHandleT) pTxnId, (ClCntDataHandleT) pNewTxn, 0); } else { rc = CL_ERR_DUPLICATE; } CL_FUNC_EXIT(); return (CL_GET_ERROR_CODE(rc)); }
/** * Get Node Name given MoId. * * API to get Logical NodeName given MOId. * * * @param pMoId MOId of the Blade. * @param nodeName Node name corresponding to blade MOId * * @returns * CL_OK on success <br/> * CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST) If an entry is not present for given MOId<br/> * CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) if moId is NULL <br/> */ ClRcT _clCorMoIdToNodeNameGet(ClCorMOIdPtrT pMoId, ClNameT** nodeName) { ClRcT rc; ClUint16T OriginalDepth; ClCorMOServiceIdT svcId; ClCorMOClassPathT moclassPath; CORMOClass_h moClassH; if(pMoId == NULL) return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR); /* First check if the MOId passed by the user is valid or not*/ /* The minimum condition that must be satisfied is */ /* taht the MO class should exist*/ rc = clCorMoIdToMoClassPathGet(pMoId, &moclassPath); if(CL_OK != rc) CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nCould not get MO class path from MOID", rc); /* Check if the MO class exists or not */ rc = corMOClassHandleGet(&moclassPath, &moClassH); if (rc != CL_OK) { /* The mo class does not exist. Return*/ CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nIncorrect path specified. MO class does not exist\n", rc); } /* The user has passed MOId, Since we are going to work on MOId */ /* Passed by the user, let's store the original depth and svc Id */ OriginalDepth = pMoId->depth; svcId = pMoId->svcId; pMoId->svcId = CL_COR_INVALID_SVC_ID; for(; pMoId->depth>=1; pMoId->depth--) { /* Find if the MOId is present in the Hash Table */ rc = clCntDataForKeyGet(moIdToNodeNameTableHandle, (ClCntKeyHandleT) pMoId, (ClCntDataHandleT *) nodeName); if(CL_OK == rc && *nodeName !=NULL ) { /* Found the node name for given MOId. Return.*/ /* Before returning restore svc Id and depth */ pMoId->depth = OriginalDepth; pMoId->svcId = svcId; return CL_OK; } } /* If we are here then the node Name could not be found*/ /* Restore original depth and svcId and return */ pMoId->depth = OriginalDepth; pMoId->svcId = svcId; CL_COR_RETURN_ERROR(CL_DEBUG_TRACE, "\n Node Name not found for given MOId.\n", CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST)); }
/** * Retrieve txn-definition using txn-id as index */ ClRcT clTxnDbTxnDefnGet( CL_IN ClTxnDbHandleT txnDb, CL_IN ClTxnTransactionIdT txnId, CL_OUT ClTxnDefnT **pTxnDefn) { ClRcT rc = CL_OK; CL_FUNC_ENTER(); if (NULL == pTxnDefn) { CL_FUNC_EXIT(); return (CL_ERR_NULL_POINTER); } rc = clCntDataForKeyGet(txnDb, (ClCntKeyHandleT) &txnId, (ClCntDataHandleT *) pTxnDefn); CL_FUNC_EXIT(); return (CL_GET_ERROR_CODE(rc)); }
ClRcT clAlarmPayloadCntDataGet(ClAlarmProbableCauseT probCause, ClAlarmSpecificProblemT specificProblem, ClCorMOIdPtrT pMoId, ClAlarmPayloadCntT **payloadInfo) { ClRcT rc = CL_OK; ClCntNodeHandleT nodeH; ClAlarmPayloadCntKeyT *pCntKey = clHeapAllocate(sizeof(ClAlarmPayloadCntKeyT)); if(NULL == pCntKey) { CL_DEBUG_PRINT (CL_DEBUG_CRITICAL,("Memory allocation failed with rc 0x%x ", rc)); return (rc); } pCntKey->probCause = probCause; pCntKey->specificProblem = specificProblem; pCntKey->moId = *pMoId; clOsalMutexLock(gClAlarmPayloadCntMutex); rc = clCntNodeFind(gPayloadCntHandle,(ClCntKeyHandleT)pCntKey,&nodeH); if(CL_OK == rc) { rc = clCntDataForKeyGet(gPayloadCntHandle, (ClCntKeyHandleT)pCntKey, (ClCntDataHandleT*)payloadInfo); if (CL_OK != rc) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clCntDataForKeyGet failed with rc 0x%x\n", rc)); } } else { CL_DEBUG_PRINT(CL_DEBUG_INFO, ("Node does not exist with rc:0x%x\n", rc)); } clHeapFree(pCntKey); clOsalMutexUnlock(gClAlarmPayloadCntMutex); return rc; }
ClRcT clCkptMasterPeerUpdateNoLock(ClIocPortT portId, ClUint32T flag, ClIocNodeAddressT localAddr, ClUint8T credential) { ClRcT rc = CL_OK; CkptPeerInfoT *pPeerInfo = NULL; CkptNodeListInfoT *pPeerInfoDH = NULL; ClCntNodeHandleT nodeHdl = 0; ClCntNodeHandleT tempHdl = 0; ClHandleT *pMasterHandle = NULL; /* * Check whether node/component is coming up or going down. */ if(flag == CL_CKPT_SERVER_UP) { /* * Checkpoint server up scenario. */ clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_ANNOUNCE, "Received welcome message from master, updating the peerlist for [%d]", localAddr); /* Reset the replica list for peer being welcomed without knowing the peer is available or not */ if(localAddr != gCkptSvr->localAddr) { clLogNotice("PEER", "UPDATE", "Resetting the replica list for the peer [%#x] being welcomed", localAddr); clCkptMasterReplicaListUpdateNoLock(localAddr); } /* * Add an entry to the peer list if not existing. * Mark the node as "available" i.e. available for checkpoint * operations like storing replicas etc.. */ rc = clCntDataForKeyGet( gCkptSvr->masterInfo.peerList, (ClPtrT)(ClWordT)localAddr, (ClCntDataHandleT *)&pPeerInfo); if( rc == CL_OK && pPeerInfo != NULL) { CL_ASSERT(pPeerInfo->ckptList != 0); pPeerInfo->credential = credential; pPeerInfo->available = CL_CKPT_NODE_AVAIL; if(localAddr != gCkptSvr->localAddr) { pPeerInfo->replicaCount = 0; } } else { if( CL_OK !=( rc = _ckptMasterPeerListInfoCreate(localAddr, credential,0))) { return rc; } } } else { /* * Node/component down scenario. */ clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Updating the peerAddr [%d] for down notification", localAddr); /* * Find the corresponding entry from the peer list. */ if( CL_OK != (rc = clCntDataForKeyGet(gCkptSvr->masterInfo.peerList, (ClCntKeyHandleT)(ClWordT)localAddr, (ClCntDataHandleT *) &pPeerInfo))) { rc = CL_OK; goto exitOnError; } if( flag != CL_CKPT_COMP_DOWN) { clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Either ckpt server or node down, " "changing active address"); clCntFirstNodeGet(pPeerInfo->mastHdlList,&nodeHdl); tempHdl = 0; while(nodeHdl != 0) { rc = clCntNodeUserKeyGet(pPeerInfo->mastHdlList,nodeHdl, (ClCntKeyHandleT *)&pMasterHandle); if( CL_OK != rc ) { clLogError(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Not able get the data for node handle rc[0x %x]", rc); goto exitOnError; } rc = clCntNextNodeGet(pPeerInfo->mastHdlList, nodeHdl, &tempHdl); /* * Update the active address and inform the clients. */ if( CL_OK != (rc = _clCkpMastertReplicaAddressUpdate(*pMasterHandle, localAddr))) { return rc; } nodeHdl = tempHdl; tempHdl = 0; } } if (flag != CL_CKPT_SVR_DOWN) { /* * Component down/ node down case. * In case of component down close the associated client Hdl. * Incase of node down close all client Hdl. * Delete the ckpt Hdls from the client handle List. */ clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Closing the opened handles from this slot id [%d]...", localAddr); clCntFirstNodeGet(pPeerInfo->ckptList,&nodeHdl); while(nodeHdl != 0) { rc = clCntNodeUserDataGet(pPeerInfo->ckptList,nodeHdl, (ClCntDataHandleT *)&pPeerInfoDH); if( CL_OK != rc ) { clLogError(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Not able get the data for node handle rc[0x %x]", rc); goto exitOnError; } clCntNextNodeGet(pPeerInfo->ckptList,nodeHdl,&tempHdl); if ( (flag == CL_CKPT_COMP_DOWN && pPeerInfoDH->appPortNum == portId) || (flag == CL_CKPT_NODE_DOWN) ) { /* * Close the checkpoint hdl but dont delete the entry from * masterHdl list. */ if(gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr) { clLogInfo(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, "Closing the handle [%#llX]...", pPeerInfoDH->clientHdl); _clCkptMasterCloseNoLock(pPeerInfoDH->clientHdl, localAddr, !CL_CKPT_MASTER_HDL); } } nodeHdl = tempHdl; tempHdl = 0; } } else if (flag == CL_CKPT_SVR_DOWN) { /* * Mark the availability of checkpoint server as UNAVAILABLE. */ if(pPeerInfo->credential == CL_CKPT_CREDENTIAL_POSITIVE) gCkptSvr->masterInfo.availPeerCount--; pPeerInfo->available = CL_CKPT_NODE_UNAVAIL; } if(flag == CL_CKPT_NODE_DOWN || flag == CL_CKPT_SVR_DOWN) { /* * Node down case, delete the entry from master's peer list. */ rc = clCntAllNodesForKeyDelete(gCkptSvr->masterInfo.peerList, (ClPtrT)(ClWordT)localAddr); CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, (" MasterPeerUpdate failed rc[0x %x]\n",rc), rc); } if( flag != CL_CKPT_COMP_DOWN) { /* * Find other nodes to store the replicas of checkpoints for whom * this node was storing the replicas. */ if(gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr) { _ckptCheckpointLoadBalancing(); } } } exitOnError: { return rc; } }
/** * API to un-register a service with transaction-agent */ ClRcT clTxnAgentServiceUnRegister(CL_IN ClTxnAgentServiceHandleT tHandle) { ClRcT rc = CL_OK; ClUint8T twoPC = 0; ClTxnAgentCompServiceInfoT *pCompService = NULL; CL_FUNC_ENTER(); if (tHandle == 0x0) { CL_FUNC_EXIT(); return CL_TXN_RC(CL_ERR_INVALID_HANDLE); } /* This is a request from service hosted in the component to unregister from the transaction-management. Remove the entry from the data-structure and invalidate the handle FIXME: Before actually deleting it, check to see if this service is part of any active txn or not */ rc = clCntDataForKeyGet(clTxnAgntCfg->compServiceMap, (ClCntKeyHandleT) &(((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType), (ClCntDataHandleT *)&pCompService); if (CL_OK == rc) { ClUint32T srvCount; if (pCompService->serviceCapability == CL_TXN_AGENT_SERVICE_1PC) { twoPC = 0; clTxnAgntCfg->agentCapability &= ~(CL_TXN_AGENT_SERVICE_1PC); } else if(pCompService->serviceCapability == CL_TXN_AGENT_SERVICE_2PC) { twoPC = 1; } rc = clCntAllNodesForKeyDelete(clTxnAgntCfg->compServiceMap, (ClCntKeyHandleT) &(((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType)); if(CL_OK != rc) { clLogError("AGT", NULL, "Failed to delete node from compServiceMap corresponding to service[%d]", ((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType); return rc; } /* Reset agent capability, if necessary */ rc = clCntSizeGet(clTxnAgntCfg->compServiceMap, &srvCount); if ( (CL_OK == rc) && (srvCount == 0x0) ) { clTxnAgntCfg->agentCapability = CL_TXN_AGENT_NO_SERVICE_REGD; } else if ( (CL_OK == rc) && (srvCount == 0x1) && ( (clTxnAgntCfg->agentCapability & CL_TXN_AGENT_SERVICE_1PC) == CL_TXN_AGENT_SERVICE_1PC) ) { clTxnAgntCfg->agentCapability = CL_TXN_AGENT_SERVICE_1PC; } else if ( CL_OK != rc ) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Error while reading number of service registered. rc:0x%x", rc)); } } if(CL_OK == rc) clLogNotice("AGT", "FIN", "Unregistering [%s] service successfull", twoPC ? "2PC":"READ"); CL_TXN_RETURN_RC(rc, ("Failed to unregister component-service rc:0x%x\n", rc)); }
/** * API to register a service with transaction agent */ ClRcT clTxnAgentServiceRegister( CL_IN ClInt32T serviceId, CL_IN ClTxnAgentCallbacksT tCallback, CL_OUT ClTxnAgentServiceHandleT *pHandle) { /* This is registration request from a service hosted in this component. (There could be multiple such services). Store these callbacks in an appropriate data-structure indexed with service-id (identication of service under considered). */ ClRcT rc = CL_OK; ClUint8T serviceCapability = 0xFF; ClTxnAgentCompServiceInfoT *pNewCompService = NULL; CL_FUNC_ENTER(); CL_TXN_NULL_CHECK_RETURN(pHandle, CL_ERR_NULL_POINTER, ("Invalid handle\n")); if (NULL == clTxnAgntCfg) { clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, CL_TXN_AGENT_LIB, CL_LOG_MESSAGE_0_COMPONENT_UNINITIALIZED); CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Agent library is not initialized. clTxnAgntCfg is NULL\n")); CL_FUNC_EXIT(); return CL_TXN_RC(CL_ERR_NOT_INITIALIZED); } /* Validate callback function */ if( (tCallback.fpTxnAgentJobPrepare == NULL) && (tCallback.fpTxnAgentJobRollback == NULL) && (tCallback.fpTxnAgentJobCommit != NULL) ) { serviceCapability = CL_TXN_AGENT_SERVICE_1PC; clTxnMutexLock(clTxnAgntCfg->actMtx); /* Check if this is not the first one to declare as 1-PC Capable service */ if ( (clTxnAgntCfg->agentCapability & CL_TXN_AGENT_SERVICE_1PC) == CL_TXN_AGENT_SERVICE_1PC) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Txn-Agent does not allow more than one service of 1-PC Type")); CL_FUNC_EXIT(); clTxnMutexUnlock(clTxnAgntCfg->actMtx); return CL_TXN_RC(CL_ERR_INVALID_PARAMETER); } clTxnMutexUnlock(clTxnAgntCfg->actMtx); } else if ( (tCallback.fpTxnAgentJobPrepare != NULL) && (tCallback.fpTxnAgentJobCommit != NULL) && (tCallback.fpTxnAgentJobRollback != NULL) ) { serviceCapability = CL_TXN_AGENT_SERVICE_2PC; } else { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid parameter - callback function not defined properly")); CL_FUNC_EXIT(); return CL_TXN_RC(CL_ERR_INVALID_PARAMETER); } /* Check if entry already exists or not */ rc = clCntDataForKeyGet( (ClCntHandleT) clTxnAgntCfg->compServiceMap, (ClCntKeyHandleT) &serviceId, (ClCntDataHandleT *) &pNewCompService); if ( CL_OK == rc ) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Component-service already registered\n")); CL_FUNC_EXIT(); return (CL_TXN_RC(CL_ERR_DUPLICATE)); } pNewCompService = (ClTxnAgentCompServiceInfoT *) clHeapAllocate(sizeof(ClTxnAgentCompServiceInfoT)); CL_TXN_NULL_CHECK_RETURN(pNewCompService, CL_ERR_NO_MEMORY, ("Failed to allocate memory\n")); memset(pNewCompService, 0, sizeof(ClTxnAgentCompServiceInfoT)); pNewCompService->serviceType = serviceId; pNewCompService->serviceCapability = serviceCapability; pNewCompService->pCompCallbacks = (ClTxnAgentCallbacksT *) clHeapAllocate(sizeof(ClTxnAgentCallbacksT)); CL_TXN_NULL_CHECK_RETURN(pNewCompService->pCompCallbacks, CL_ERR_NO_MEMORY, ("Failed to allocate memory\n")); memcpy(pNewCompService->pCompCallbacks, &tCallback, sizeof(ClTxnAgentCallbacksT)); /* Put the entry into hash-map with service-id to be the key */ rc = clCntNodeAdd(clTxnAgntCfg->compServiceMap, (ClCntKeyHandleT) &(pNewCompService->serviceType), (ClCntDataHandleT)pNewCompService, NULL); if (CL_OK != rc) { clHeapFree(pNewCompService->pCompCallbacks); clHeapFree(pNewCompService); } else { /* Update agent-cfg */ if (serviceCapability == CL_TXN_AGENT_SERVICE_1PC) { #ifdef CL_TXN_DEBUG CL_DEBUG_PRINT(CL_DEBUG_ERROR,( "Service registered is 1pc\n")); #endif clTxnAgntCfg->agentCapability |= CL_TXN_AGENT_SERVICE_1PC; } else clTxnAgntCfg->agentCapability |= CL_TXN_AGENT_SERVICE_2PC; *pHandle = (ClTxnAgentServiceHandleT )pNewCompService; clLogNotice("AGT", "INI", "Registered [%s] service successfully having serviceId [%d]", (serviceCapability == CL_TXN_AGENT_SERVICE_1PC)?"READ": "2P", serviceId); } CL_TXN_RETURN_RC(rc, ("Failed to register new component-service rc:0x%x\n", rc)); }