} END_TEST_EXTERN START_TEST_EXTERN(eject_with_proper_values) { ClRcT rc = CL_OK; /* Initialize gms client without any callbacks being registered. */ rc = clGmsInitialize(&handle,NULL,&correct_version); fail_unless(rc == CL_OK, "clGmsInitialize with NULL callbacks failed with rc 0x%x",rc); rc = clGmsClusterJoin(handle, &clusterManageCallbacks, 0, 0, 100, &nodeName); fail_unless(CL_GET_ERROR_CODE(rc) == CL_OK, "ClusterJoin with 0 handle failed with rc = 0x%x",rc); callback_invoked = CL_FALSE; rc = clGmsClusterMemberEject(handle, 100, CL_GMS_MEMBER_EJECT_REASON_API_REQUEST); fail_unless(rc == CL_OK, "Cluster Leave for nodeId 100 failed with rc 0x%x",rc); /* Wait for the callback to be invoked */ sleep(5); fail_unless(callback_invoked == CL_TRUE, "Cluster Eject callback is not invoked"); /* Finalize */ rc = clGmsFinalize(handle); fail_unless(rc == CL_OK, "clGmsFinalize failed with rc = 0x%x",rc); } END_TEST_EXTERN
} END_TEST_EXTERN START_TEST_EXTERN(eject_with_non_existing_node_id) { ClRcT rc = CL_OK; /* Initialize gms client without any callbacks being registered. */ rc = clGmsInitialize(&handle,NULL,&correct_version); fail_unless(rc == CL_OK, "clGmsInitialize with NULL callbacks failed with rc 0x%x",rc); rc = clGmsClusterMemberEject(handle, 100, CL_GMS_MEMBER_EJECT_REASON_API_REQUEST); fail_unless(CL_GET_ERROR_CODE(rc) == CL_ERR_INVALID_PARAMETER, "ClusterJoin with NULL clusterManage callback failed with rc = 0x%x",rc); /* Finalize */ rc = clGmsFinalize(handle); fail_unless(rc == CL_OK, "clGmsFinalize failed with rc = 0x%x",rc); } END_TEST_EXTERN
ClRcT clCkptMasterAddressesSet() { ClRcT rc = CL_OK; #ifdef CL_CKPT_GMS /* * GMS available. */ /* * Contact GMS to get master and backup master addresses. */ ClGmsClusterNotificationBufferT notBuffer; memset((void*)¬Buffer , 0, sizeof(notBuffer)); memset( ¬Buffer , '\0' ,sizeof(ClGmsClusterNotificationBufferT)); /* * Initialize the gms client library. */ rc = clGmsInitialize(&gCkptSvr->gmsHdl, &ckptGmsCallbacks, &gVersion); CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, (" clCkptMasterAddressesSet failed rc[0x %x]\n",rc), rc); /* * Register for current track and track changes. */ rc = clGmsClusterTrack(gCkptSvr->gmsHdl, CL_GMS_TRACK_CHANGES|CL_GMS_TRACK_CURRENT, ¬Buffer); /* * Call the track change callback function. This is needed for getting * current track information. */ if(rc == CL_OK && notBuffer.leader && notBuffer.leader != CL_GMS_INVALID_NODE_ID) { _clCkptAddressesUpdate(¬Buffer); } if (notBuffer.notification != NULL) clHeapFree(notBuffer.notification); #else /* * GMS unavailable. */ /* * Select cpm master as ckpt master. Deputy will be unspecified. */ clCpmMasterAddressGet(&gCkptSvr->masterInfo.masterAddr); gCkptSvr->masterInfo.deputyAddr = -1; /* * Update the TL with ckpt master address. */ if(gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr ) { ClIocTLInfoT tlInfo = {0}; ClUint32T compId = 0; SaNameT name = {0}; clCpmComponentNameGet(gCkptSvr->amfHdl, &name); clCpmComponentIdGet(gCkptSvr->amfHdl, &name, &compId); tlInfo.compId = compId; gCkptSvr->masterInfo.compId = compId; ckptOwnLogicalAddressGet(&tlInfo.logicalAddr); tlInfo.contextType = CL_IOC_TL_GLOBAL_SCOPE; tlInfo.physicalAddr.nodeAddress = clIocLocalAddressGet(); tlInfo.physicalAddr.portId = CL_IOC_CKPT_PORT; tlInfo.haState = CL_IOC_TL_ACTIVE; rc = clIocTransparencyRegister(&tlInfo); } #endif #ifdef CL_CKPT_GMS exitOnError: #endif { return rc; } }
SaAisErrorT saClmInitialize ( SaClmHandleT*const clmHandle, const SaClmCallbacksT*const clmCallbacks, SaVersionT*const version ) { ClRcT rc = CL_OK; ClGmsCallbacksT gmsCallbacks = {0}; ClGmsHandleT gmsHandle = CL_HANDLE_INVALID_VALUE; /* * Use a 32 bit handle type to create a handle. Dont * use the 64 bit clmHandle directly as it would create issues * in mixed mode operations. */ ClHandleT localHandle = CL_HANDLE_INVALID_VALUE; SaClmInstanceT *clmInstance = NULL; ClHandleT dispatchHandle = CL_HANDLE_INVALID_VALUE; if (clmHandle == (const void*)NULL) { return _aspErrToAisErr(CL_ERR_NULL_POINTER); } rc = clASPInitialize(); if(CL_OK != rc) { clLogCritical("CLM", "INI", "ASP initialize failed, rc[0x%X]", rc); return SA_AIS_ERR_LIBRARY; } /* * Create the handle database for clm first, if it is * not already created */ saClmLibInitialize(); if (clmCallbacks != (const void*)NULL) { /*Set GMS callbacks to callback wrappers*/ if (clmCallbacks->saClmClusterNodeGetCallback != NULL) { gmsCallbacks.clGmsClusterMemberGetCallback = clGmsClusterMemberGetCallbackWrapper; } if (clmCallbacks->saClmClusterTrackCallback != NULL) { gmsCallbacks.clGmsClusterTrackCallback = clGmsClusterTrackCallbackWrapper; } } /* Initialize GMS */ rc = clGmsInitialize(&gmsHandle, &gmsCallbacks, (ClVersionT*)version); if(rc != CL_OK) { clLogError("CLM","INI", "clGmsInitialize failed with rc 0x%x\n",rc); return _aspErrToAisErr(rc); } localHandle = gmsHandle; /* * Create a local handle to be returned as clmHandle * Here we will create the handle value same as that of * gmsHandle so that we can keep the reference during * callback invocation through thread specific data */ rc = clHandleCreateSpecifiedHandle(databaseHandle, sizeof(SaClmInstanceT), localHandle); if (rc != CL_OK) { clLogError("CLM","INI", "clHandleCreateSpecifiedHandle failed with rc 0x%x\n",rc); return _aspErrToAisErr(rc); } /* * Assign localHandle to clmHandle, but keep using localHandle, * as it is compliant with ASP APIs. */ *clmHandle = localHandle; SA_GMS_INIT_COUNT_INC(); /* Checkout the handle */ rc = clHandleCheckout(databaseHandle, localHandle, (void**)&clmInstance); CL_ASSERT((rc == CL_OK) && (clmInstance != NULL)); if (clmCallbacks != (const void*)NULL) { /*Save the saf callbacks in the handle*/ memcpy(&clmInstance->callbacks, clmCallbacks, sizeof(SaClmCallbacksT)); } /* Initialize dispatch */ rc = clDispatchRegister(&dispatchHandle, localHandle, dispatchWrapperCallback, dispatchQDestroyCallback); if (rc != CL_OK) { clLogError("CLM","INI", "clDispatchRegister failed with rc 0x%x\n",rc); goto error_return; } /* Store dispatchHandle in the clmHandle */ clmInstance->dispatchHandle = dispatchHandle; error_return: if ((clHandleCheckin(databaseHandle, localHandle)) != CL_OK) { clLogError(CL_LOG_AREA_UNSPECIFIED,CL_LOG_CONTEXT_UNSPECIFIED, "clHandleCheckin failed"); } return _aspErrToAisErr(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; }