/* * This function shall change when the CPM has a devoted queue to handle the death & leave * Notifications. The pRecvParam shall be of use then for queuing. */ ClRcT clEoProcessIocRecvPortNotification(ClEoExecutionObjT* pThis, ClBufferHandleT eoRecvMsg, ClUint8T priority, ClUint8T protoType, ClUint32T length, ClIocPhysicalAddressT srcAddr) { ClRcT rc = CL_OK; ClIocNotificationT notificationInfo = {0}; ClUint32T msgLength = sizeof(ClIocNotificationT); ClIocNotificationIdT notificationId = 0; ClUint32T protoVersion = 0; CL_EO_LIB_VERIFY(); rc = clBufferNBytesRead(eoRecvMsg, (ClUint8T *)¬ificationInfo, &msgLength); if (rc != CL_OK) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("EO: clBufferNBytesRead() Failed, rc=[0x%x]\n", rc)); goto out_delete; } protoVersion = ntohl(notificationInfo.protoVersion); if(protoVersion != CL_IOC_NOTIFICATION_VERSION) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("EO: Ioc recv notification received with version [%d]. Supported [%d]\n", protoVersion, CL_IOC_NOTIFICATION_VERSION)); goto out_delete; } notificationId = ntohl(notificationInfo.id); switch(notificationId) { case CL_IOC_SENDQ_WM_NOTIFICATION: if(gIsNodeRepresentative == CL_FALSE) { CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Got sendq wm notification for non-node representative\n")); rc = CL_EO_RC(CL_ERR_BAD_OPERATION); goto out_delete; } /*fall through*/ case CL_IOC_COMM_PORT_WM_NOTIFICATION: { ClIocNodeAddressT nodeId = 0; ClIocPortT portId = ntohl(notificationInfo.nodeAddress.iocPhyAddress.portId); ClIocNodeAddressT nodeAddress = ntohl(notificationInfo.nodeAddress.iocPhyAddress.nodeAddress); CL_CPM_IOC_ADDRESS_SLOT_GET(nodeAddress,nodeId); rc = clEoIocWMNotification(CL_CID_IOC,portId,nodeId,¬ificationInfo); if (rc != CL_OK) { CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("EO: clEoIocWMNotification() Failed, rc=[0x%x]\n", rc)); goto out_delete; } } break; case CL_IOC_NODE_ARRIVAL_NOTIFICATION: case CL_IOC_NODE_LINK_UP_NOTIFICATION: case CL_IOC_COMP_ARRIVAL_NOTIFICATION: /* Need to add functionality if the components wants a specific operation...*/ clEoClientNotification(¬ificationInfo); rc = CL_OK; break; case CL_IOC_NODE_LEAVE_NOTIFICATION: case CL_IOC_NODE_LINK_DOWN_NOTIFICATION: case CL_IOC_COMP_DEATH_NOTIFICATION: rc = clBufferDelete(&eoRecvMsg); CL_ASSERT(rc == CL_OK); rc = clRmdDatabaseCleanup(pThis->rmdObj, ¬ificationInfo); clEoClientNotification(¬ificationInfo); return rc; default: CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Invalid notification id[%d]\n", notificationId)); rc = CL_EO_RC(CL_ERR_BAD_OPERATION); goto out_delete; } out_delete: clBufferDelete(&eoRecvMsg); 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; }