void clPluginHelperAddRemVirtualAddress(const ClCharT *cmd, const ClPluginHelperVirtualIpAddressT *vip) { int up = 0; if (cmd[0] == 'u') up = 1; ClPluginHelperVirtualIpAddressT* vipCopy = (ClPluginHelperVirtualIpAddressT*) malloc(sizeof(ClPluginHelperVirtualIpAddressT)); memcpy(vipCopy, vip, sizeof(ClPluginHelperVirtualIpAddressT)); /* * Ignore configure if IP and dev are already existing on node */ if (_clCheckExistingDevIf(vipCopy->ip, vipCopy->dev)) { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Ignored assignment IP address: %s, for device: %s", vipCopy->ip, vipCopy->dev); goto out; } if (vipCopy->ip && vipCopy->dev && vipCopy->netmask) { char execLine[301]; snprintf(execLine, 300, "%s/virtualIp %s %s %s %s %s ", ASP_BINDIR, cmd, vipCopy->ip, vipCopy->netmask, vipCopy->dev, vipCopy->subnetPrefix); clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Executing %s", execLine); __attribute__((unused)) ClRcT result = system(execLine); if (up) /* If we are coming up, do a gratuitous arp */ { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Sending gratuitous arps: IP address: %s, device: %s", vipCopy->ip, vipCopy->dev); _clPluginHelperSendArp(vipCopy->ip, vipCopy->dev); clOsalTaskCreateDetached("arpTask", CL_OSAL_SCHED_OTHER, 0, 0, _clPluginHelperPummelArps, vipCopy); vipCopy = NULL; /* freed by the arp thread*/ } else { /* If we are going down, delay a bit so that the machine that takes over will not do so too soon. (the assumption being that the machine taking over will not do so until this remove returns) */ clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Removing IP; not sending gratuitous arps"); /* sleep(1); */ } } else { clLogNotice("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Virtual IP work assignment values incorrect: got IP address: %s, device: %s, mask: %s, net prefix: %s", vipCopy->ip, vipCopy->dev, vipCopy->netmask, vipCopy->subnetPrefix); } out: if(vipCopy) free(vipCopy); }
/** * get DM Handle from given ClCorMOId */ ClRcT moId2DMHandle(ClCorMOIdPtrT path, DMObjHandle_h dmh) { ObjTreeNode_h obj; CORObject_h dmObj; CL_FUNC_ENTER(); if(!path || !dmh) { CL_FUNC_EXIT(); return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR); } memset(dmh,0,sizeof(DMObjHandle_t)); obj = corMOObjGet(path); if(obj) { ClCorMOServiceIdT svcId=(path)->svcId; dmObj = obj->data; if(svcId!=CL_COR_INVALID_SRVC_ID) { dmObj=corMSOObjGet(obj, svcId); } if (dmObj != NULL && dmObj->dmObjH.classId != 0) { (dmh)->classId = dmObj->dmObjH.classId; (dmh)->instanceId = dmObj->dmObjH.instanceId; } else { clLogInfo("COR", "OBH", "The Dm object node doesn't exist. rc[0x%x]", CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID)); return CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID); } } else { clLogInfo("COR", "OBJ", "The object node doesn't exist in the object tree. rc [0x%x]", CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID)); return CL_COR_SET_RC(CL_COR_INST_ERR_INVALID_MOID); } CL_FUNC_EXIT(); return CL_OK; }
static ClRcT _clPluginHelperGetLinkName(const ClCharT *xportType, ClCharT *inf) { ClCharT net_addr[CL_MAX_FIELD_LENGTH] = "eth0"; ClCharT *linkName = NULL; ClCharT envlinkNameType[CL_MAX_FIELD_LENGTH] = { 0 }; if (!xportType) { return CL_ERR_INVALID_PARAMETER; } else { snprintf(envlinkNameType, CL_MAX_FIELD_LENGTH, "ASP_%s_LINK_NAME", xportType); linkName = getenv(envlinkNameType); if (linkName == NULL) { // try with default LINK_NAME linkName = getenv("LINK_NAME"); if (linkName == NULL) { clLogNotice("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s and LINK_NAME environment variable is not exported. Using 'eth0:10' interface as default", envlinkNameType); } else { clLogNotice("IOC", CL_LOG_PLUGIN_HELPER_AREA, "LINK_NAME env is exported. Value is %s", linkName); net_addr[0] = 0; strncat(net_addr, linkName, sizeof(net_addr)-1); ClCharT *token = NULL; strtok_r(net_addr, ":", &token); } snprintf(inf, CL_MAX_FIELD_LENGTH, "%s:%d", net_addr, gIocLocalBladeAddress + 10); } else { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s env is exported. Value is %s", envlinkNameType, linkName); snprintf(inf, CL_MAX_FIELD_LENGTH, "%s", linkName); } } return CL_OK; }
void clLogSvrTerminate(SaInvocationT invocation, const SaNameT *compName) { ClRcT rc = CL_OK; ClLogSvrEoDataT *pSvrEoEntry = NULL; //ClHandleT hCpm = CL_HANDLE_INVALID_VALUE; CL_LOG_DEBUG_TRACE(("Enter")); clLogInfo("SVR", "MAI", "Unregistering with cpm...... [%.*s]\n", compName->length, compName->value); gClLogSvrExiting = CL_TRUE; rc = clLogSvrEoEntryGet(&pSvrEoEntry, NULL); if( CL_OK != rc ) { return ; } //hCpm = pSvrEoEntry->hCpm; saAmfComponentUnregister(amfHandle,compName, NULL); #if 1 CL_LOG_CLEANUP(clLogSvrShutdown(), CL_OK); #endif saAmfResponse(amfHandle, invocation, SA_AIS_OK); CL_LOG_DEBUG_TRACE(("Exit")); unblockNow = CL_TRUE; //(void)hCpm; }
ClRcT clNodeCacheCapabilitySet(ClIocNodeAddressT nodeAddress, ClUint32T capability, ClUint32T flag) { if(nodeAddress >= CL_IOC_MAX_NODES || !gpClNodeCache) return CL_ERR_INVALID_PARAMETER; clOsalSemLock(gClNodeCacheSem); switch(flag) { case CL_NODE_CACHE_CAP_ASSIGN: CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress].capability = capability; break; case CL_NODE_CACHE_CAP_AND: CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress].capability &= capability; break; case CL_NODE_CACHE_CAP_MERGE: CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress].capability |= capability; break; case CL_NODE_CACHE_CAP_CLEAR: CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress].capability &= ~capability; break; default: break; } capability = CL_NODE_CACHE_ENTRY_BASE(gpClNodeCache)[nodeAddress].capability; clOsalSemUnlock(gClNodeCacheSem); clLogInfo("CAP", "SET", "Node cache capability set to [%#x] for node [%d]", capability, nodeAddress); return CL_OK; }
static ClRcT fileEntryRecoverBaseVersion(ClLogMasterEoDataT *pMasterEoEntry, ClBufferHandleT hFileEntryBuf) { ClRcT rc = CL_OK; ClLogFileKeyT fileKey = {{0}}; ClLogFileKeyT *pFileKey = NULL; ClLogFileDataT *pFileData = NULL; rc = clLogMasterFileKeyUnpack(&fileKey, hFileEntryBuf); if( CL_OK != rc ) { return rc; } clLogInfo(CL_LOG_AREA_MASTER, CL_LOG_CTX_CKPT_READ, "Recreating files fileName: %.*s fileLocation: %.*s", fileKey.fileName.length, fileKey.fileName.pValue, fileKey.fileLocation.length, fileKey.fileLocation.pValue); rc = clLogFileKeyCreate(&fileKey.fileName, &fileKey.fileLocation, pMasterEoEntry->maxFiles, &pFileKey); if( CL_OK != rc ) { clHeapFree(fileKey.fileName.pValue); clHeapFree(fileKey.fileLocation.pValue); return rc; } clHeapFree(fileKey.fileName.pValue); clHeapFree(fileKey.fileLocation.pValue); /* find out the filelocation is available */ pFileData = (ClLogFileDataT*) clHeapCalloc(1, sizeof(ClLogFileDataT)); if( NULL == pFileData ) { CL_LOG_DEBUG_ERROR(("clHeapCalloc()")); clLogFileKeyDestroy(pFileKey); return rc; } pFileData->nActiveStreams = 0; rc = clLogMasterFileDataRecreate(pFileData, hFileEntryBuf); if( CL_OK != rc ) { clLogFileKeyDestroy(pFileKey); return rc; } rc = clCntNodeAdd(pMasterEoEntry->hMasterFileTable, (ClCntKeyHandleT) pFileKey, (ClCntDataHandleT) pFileData, NULL); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCntNodeAdd()")); CL_LOG_CLEANUP(clCntDelete(pFileData->hStreamTable), CL_OK); //FIXME clHeapFree(pFileData); clLogFileKeyDestroy(pFileKey); return rc; } 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 clLogFlusherTimerCallback(void *pData) { ClHandleT hFlusher = *(ClHandleT *)(ClWordT)pData; CL_LOG_DEBUG_TRACE(("Enter")); clLogInfo("LOG", "FLS", "Timer expired"); clLogFlusherCookieHandleDestroy(hFlusher, CL_FALSE); clHeapFree(pData); CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
static ClRcT _clPluginHelperGetIpNodeAddress(const ClCharT *xportType, ClCharT *hostAddress, ClCharT *networkMask, ClCharT *broadcast, ClUint32T *ipAddressMask, ClCharT *xportSubnetPrefix) { ClCharT envSubNetType[CL_MAX_FIELD_LENGTH] = { 0 }; ClCharT xportSubnet[CL_MAX_FIELD_LENGTH] = { 0 }; ClCharT *subnetMask = NULL; ClCharT *subnetPrefix = NULL; ClUint32T CIDR, ipMask, ip, mask; if (!xportType) { return CL_ERR_INVALID_PARAMETER; } else { snprintf(envSubNetType, CL_MAX_FIELD_LENGTH, "ASP_%s_SUBNET", xportType); subnetMask = getenv(envSubNetType); if (subnetMask == NULL) { subnetMask = ASP_PLUGIN_SUBNET_DEFAULT; } subnetPrefix = strrchr(subnetMask, '/'); if(!subnetPrefix) { subnetPrefix = ASP_PLUGIN_SUBNET_PREFIX_DEFAULT; } else { ++subnetPrefix; } if(! (CIDR = atoi(subnetPrefix) ) ) { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s", subnetMask); return CL_ERR_INVALID_PARAMETER; } xportSubnetPrefix[0] = 0; strncat(xportSubnetPrefix, subnetPrefix, CL_MAX_FIELD_LENGTH-1); snprintf(xportSubnet, sizeof(xportSubnet), "%s", subnetMask); mask = _clPluginHelperBitFillRShift(CIDR); _clPluginHelperConvertInternetToHostAddress(&ip, xportSubnet); /* network address */ ipMask = (ip & mask); _clPluginHelperConvertHostToInternetAddress(ipMask + gIocLocalBladeAddress, hostAddress); _clPluginHelperConvertHostToInternetAddress(mask, networkMask); _clPluginHelperConvertHostToInternetAddress(ip | ~mask, broadcast); *ipAddressMask = ipMask; } return CL_OK; }
static ClRcT _clPluginHelperGetLinkName(const ClCharT *xportType, ClCharT *inf) { ClCharT net_addr[CL_MAX_FIELD_LENGTH] = "eth0"; ClCharT *linkName = NULL; ClCharT envlinkNameType[CL_MAX_FIELD_LENGTH] = { 0 }; if (!xportType) { return CL_ERR_INVALID_PARAMETER; } else { snprintf(envlinkNameType, CL_MAX_FIELD_LENGTH, "ASP_%s_LINK_NAME", xportType); linkName = getenv(envlinkNameType); if (linkName == NULL) { // try with default LINK_NAME linkName = getenv("LINK_NAME"); if (linkName == NULL) { clLogNotice("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s and LINK_NAME environment variable is not exported. Using 'eth0:10' interface as default", envlinkNameType); } else { clLogNotice("IOC", CL_LOG_PLUGIN_HELPER_AREA, "LINK_NAME env is exported. Value is %s", linkName); net_addr[0] = 0; strncat(net_addr, linkName, sizeof(net_addr)-1); ClCharT *token = NULL; strtok_r(net_addr, ":", &token); } /* If we are not using the existing IP addr then we need to use a virtual device to make sure we don't overwrite an already-configured address */ if (!ASP_UDP_USE_EXISTING_IP) snprintf(inf, CL_MAX_FIELD_LENGTH, "%s:%d", net_addr, gIocLocalBladeAddress + 10); /* If we ARE using the existing IP, then whatever interfaces LINK_NAME is set to IS that address */ else snprintf(inf, CL_MAX_FIELD_LENGTH, "%s", net_addr); } else { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s env is exported. Value is %s", envlinkNameType, linkName); snprintf(inf, CL_MAX_FIELD_LENGTH, "%s", linkName); } } return CL_OK; }
SaAisErrorT saCkptFinalize (const SaCkptHandleT ckptHandle) { ClRcT rc = CL_OK; SaAisErrorT safRc = SA_AIS_OK; rc = clCkptFinalize((ClCkptSvcHdlT)ckptHandle); /* * Translate the clovis error type to SAF error type. */ clErrorTxlate(rc, &safRc); if(CL_OK != clASPFinalize()) { clLogInfo("CKP", "FIN", "ASP finalize failed, rc[0x%X]", rc); return SA_AIS_ERR_LIBRARY; } return safRc; }
/* * The main parser entry point * */ ClRcT clParseXML(ClCharT *pPath,const ClCharT *pFileName,ClParserDataT *pData) { ClRcT rc = CL_OK; ClParserPtrT root; rc = CL_PARSER_RC(CL_ERR_INVALID_PARAMETER); if(pFileName == NULL || pData == NULL) { clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_XML,"Invalid parameter\n"); goto out; } if(pPath == NULL) { pPath = getenv("ASP_CONFIG"); if(pPath == NULL) { clLogError(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_XML,"Please export ASP_CONFIG\n"); goto out; } } /*Start the parse*/ root = clParserOpenFile(pPath,pFileName); if(root == NULL) { clLogInfo(PARSER_LOG_AREA_PARSER,PARSER_LOG_CTX_XML,"Opening xml configuration file [%s] failed", pFileName); goto out; } rc = clParseChild(NULL,root,pData,NULL); CL_PARSER_RESULT(pData,rc,out_free); out_free: clParserFree(root); out: return rc; }
/* ip route configure */ void clPluginHelperAddRouteAddress(const ClCharT *ipAddress, const ClCharT *ifDevName) { FILE *route_file; ClUint32T dest; ClCharT dummyStr[CL_MAX_NAME_LENGTH]; ClCharT dummyDev[CL_MAX_FIELD_LENGTH]; ClUint32T ipMulticast; ClBoolT foundDestRoute = CL_FALSE; __attribute__((unused)) ClRcT result; clPluginHelperConvertInternetToHostAddress(&ipMulticast, ipAddress); // open route file to get the route destination route_file = fopen("/proc/net/route", "r"); result = fscanf(route_file, "%[^\n]", dummyStr); while (!feof(route_file)) { result = fscanf(route_file, "%s %8X %[^\n]", dummyDev, &dest, dummyStr); if (!(ipMulticast ^ dest)) { foundDestRoute = CL_TRUE; break; } } fclose(route_file); if (!foundDestRoute) { char execLine[301]; snprintf(execLine, 300, "/sbin/ip route add %s dev %s", ipAddress, ifDevName); clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "Executing %s", execLine); result = system(execLine); } }
SaAisErrorT saClmFinalize ( const SaClmHandleT clmHandle ) { ClRcT rc = CL_OK; ClHandleT localHandle = CL_HANDLE_INVALID_VALUE; SaClmInstanceT *clmInstance = NULL; SA_GMS_CHECK_INIT_COUNT(); /* Handle checkout */ localHandle = (ClHandleT)clmHandle; rc = clHandleCheckout(databaseHandle, localHandle, (void**)&clmInstance); if (rc != CL_OK) { return _aspErrToAisErr(rc); } CL_ASSERT(clmInstance != NULL); /* Finalize with GMS */ rc = clGmsFinalize(localHandle); if (rc != CL_OK) { clLogError("CLM","FIN", "clGmsFinalize failed with rc 0x%x\n",rc); } /* Deregister with dispatch */ rc = clDispatchDeregister(clmInstance->dispatchHandle); if (rc != CL_OK) { clLogError(GMS_LOG_AREA_CLM,GMS_LOG_CTX_CLM_FINALISE, "clDispatchDeregister failed with rc 0x%x\n",rc); } /* Checkin the handle */ if ((clHandleCheckin(databaseHandle, localHandle)) != CL_OK) { clLogError(GMS_LOG_AREA_CLM,GMS_LOG_CTX_CLM_FINALISE, "clHandleCheckin failed"); } /* Destroy the handle */ if ((clHandleDestroy(databaseHandle, localHandle)) != CL_OK) { clLogError(GMS_LOG_AREA_CLM,GMS_LOG_CTX_CLM_FINALISE, "clHandleDestroy failed"); } SA_GMS_INIT_COUNT_DEC(); if (isLastFinalize() == CL_TRUE) { rc = clHandleDatabaseDestroy(databaseHandle); if (rc != CL_OK) { clLogError(GMS_LOG_AREA_CLM,GMS_LOG_CTX_CLM_DB, "clHandleDatabaseDestroy failed with rc 0x%x\n",rc); } } if(CL_OK != clASPFinalize()) { clLogInfo("CLM", "FIN", "ASP finalize failed, rc[0x%X]", rc); return SA_AIS_ERR_LIBRARY; } return _aspErrToAisErr(rc); }
ClRcT clLogSvrInitialize(ClUint32T argc,ClCharT *argv[]) { SaAmfCallbacksT callbacks = {0}; SaVersionT version; ClRcT rc = CL_OK; ClLogSvrEoDataT *pSvrEoEntry = NULL; ClBoolT *pCookie = NULL; ClIocAddressT invalidAddr = {{0}}; clLogCompName =(ClCharT*) "LOG"; /* Override generated eo name with a short name for our server */ gClLogServer = CL_FALSE; /* Mark me as the log server */ clLogInfo(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED, "Log Server initialization started..."); clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); version.releaseCode = 'B'; version.majorVersion = 0x01; version.minorVersion = 0x01; callbacks.saAmfHealthcheckCallback = NULL; /* rarely necessary because SAFplus monitors the process */ callbacks.saAmfComponentTerminateCallback = clLogSvrTerminate; callbacks.saAmfCSISetCallback = NULL; callbacks.saAmfCSIRemoveCallback = NULL; callbacks.saAmfProtectionGroupTrackCallback = NULL; callbacks.saAmfProxiedComponentInstantiateCallback = NULL; callbacks.saAmfProxiedComponentCleanupCallback = NULL; rc = saAmfInitialize(&amfHandle, &callbacks, &version); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfInitialize(): rc[0x %x]", rc)); return rc; } #if defined(CL_DEBUG) && defined(CL_DEBUG_START) clLogDebugLevelSet(); #endif CL_LOG_DEBUG_TRACE(("Enter")); clLogSvrMutexModeSet(); /* * Here dummy initialization of Idl handle to avoid mutiple database * Initialization & finalization databases. Keeping this handle alive * will avoid this. coz Idl library will delete the handle database if the * handle count becomes zero. Mutiple times we are initializing & deleting * the handles in our log service usage. */ rc = clLogIdlHandleInitialize(invalidAddr, &shLogDummyIdl); if( CL_OK != rc ) { return rc; } rc = clLogSvrCommonDataInit(); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogSvrCommonDataInit(): rc[0x %x]", rc)); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } rc = clLogStreamOwnerLocalBootup(); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogStreamOwnerLocalInit(): rc[0x %x]", rc)); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } pCookie = (ClBoolT*) clHeapCalloc(1, sizeof(ClBoolT)); if( NULL == pCookie ) { CL_LOG_DEBUG_ERROR(("clHeapCalloc()")); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return CL_LOG_RC(CL_ERR_NO_MEMORY); } *pCookie = CL_FALSE; rc = clLogSvrBootup(pCookie); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogSvrDataInit(): rc[0x %x]", rc)); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } clLogInfo(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED, "Log server boot type is [%s]", (*pCookie == 1)? "Restart": "Normal"); rc = clLogSvrEoEntryGet(&pSvrEoEntry, NULL); if( CL_OK != rc ) { CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } pSvrEoEntry->hCpm = amfHandle; rc = saAmfComponentNameGet(amfHandle, &logServerName); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfComponentNameGet(): rc[0x %x]", rc)); saAmfFinalize(amfHandle); CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } rc = saAmfComponentRegister(amfHandle, &logServerName, NULL); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfComponentRegister(): rc[0x %x]", rc)); CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); saAmfFinalize(amfHandle); return rc; } pSvrEoEntry->hTimer = CL_HANDLE_INVALID_VALUE; if( CL_FALSE == *pCookie ) { rc = clLogSvrTimerDeleteNStart(pSvrEoEntry, pCookie); } else { rc = clLogTimerCallback((void *) pCookie); } if( CL_OK != rc ) { saAmfComponentUnregister(amfHandle, &logServerName, NULL); CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); saAmfFinalize(amfHandle); return rc; } rc = clLogDebugRegister(); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogDebugRegister(): rc[0x %x]", rc)); } clLogNotice(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED, "Log Server partially up"); CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
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; } }
ClRcT clSnmpSendSyncRequestToServer (void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, ClUint32T tableType, ClSnmpOpCodeT opCode) { netsnmp_variable_list *vptr = NULL; ClInt32T errorCode = 0; ClInt32T retVal = 0; ClSnmpReqInfoT reqInfo = {0}; ClUint32T count = 0; ClUint32T tblIndex = 0; ClCharT *sendData = NULL; ClRcT rc = CL_OK; ClSnmpOidInfoT *appOidInfo = NULL; /*Set my_loop_context to an application specific iterator context. * Typically it will be a linked list of values where each node * corresponds to a row in the table. But here we are not maintaining any * linked list.*/ /*Actually we can set my_loop_context to NULL pointer also as we are not * maintaining a linked list of rows in a table here. All the required * things are maintained in COR. And net-SNMP uses the index we set by * calling snmp_set_var_value() function for the next index. So just set * it to &reqInfo here*/ *my_loop_context = &gReqInfo; *my_data_context = &gReqInfo; memset(&reqInfo, 0, sizeof(ClSnmpReqInfoT)); vptr = put_index_data; sendData = (ClCharT*) &reqInfo.index; extern ClRcT snmpBuildAppOIDInfo(ClSnmpOidInfoT **); rc = snmpBuildAppOIDInfo(&appOidInfo); if (rc != CL_OK) { return rc; } /* Get table entry from appOidInfo[] */ while (appOidInfo[tblIndex].numAttr != 0) { if (appOidInfo[tblIndex].tableType == tableType) { break; } tblIndex++; } clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Finding Index Information for OID[%s] with SNMP GET_FIRST[%d]/GET-NEXT[%d] CURRENT[%d]", appOidInfo[tblIndex].oid, CL_SNMP_GET_FIRST, CL_SNMP_GET_NEXT, opCode ); if (appOidInfo[tblIndex].numAttr == 0) { /* Table entry not found after entries being exhausted */ retVal = CL_MED_SET_RC(CL_ERR_NOT_EXIST); clLog(CL_LOG_SEV_ERROR, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "appOidInfo don't have necessary index information"); return retVal; } if((opCode == CL_SNMP_GET_NEXT) || (my_loop_context != NULL && (*(ClInt32T*)*my_loop_context)!= 1)) { for(count =0; (count < appOidInfo[tblIndex].numAttr) && sendData; count++) { /*We are assuming that the ClSnmpReqInfoT structure is * properly completed by the application writer and the union part * contains all indices*/ /*Copy the index got from snmp agent*/ /*COR supports only Integer / array of character types (string). * So we are not handling the case for float/bitstring/double etc * which are part of the put_index_data->val union*/ switch(appOidInfo[tblIndex].attr[count].type) { case CL_SNMP_STRING_ATTR: clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Input : Possion[%d] AttrType[STRING] Value [%s] Size[%d]",count, vptr->val.string, appOidInfo[tblIndex].attr[count].size); memcpy(sendData, vptr->val.string, (vptr->val_len + 1)); /*Add 1 here so that when * vptr->val_len is added after the * switch() it makes up for the * length copied above*/ sendData += 1; break; case CL_SNMP_NON_STRING_ATTR: clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Input : Possion[%d] AttrType[NON-STRING] Value[%d] Size[%d]",count, *(ClUint32T*)vptr->val.integer, appOidInfo[tblIndex].attr[count].size); memcpy(sendData, vptr->val.integer, appOidInfo[tblIndex].attr[count].size); break; default: break; } sendData += appOidInfo[tblIndex].attr[count].size; vptr = vptr->next_variable; } } { ClUint32T oidLen = strlen(appOidInfo[tblIndex].oid) + 1; if( oidLen > sizeof reqInfo.oid) { return CL_ERR_NO_SPACE; } else strncpy(reqInfo.oid, appOidInfo[tblIndex].oid, oidLen); } reqInfo.oidLen = strlen(reqInfo.oid); reqInfo.opCode = opCode; reqInfo.tableType = tableType; reqInfo.dataLen = sizeof(reqInfo.index); clLogInfo("SNMP", "SUB", "Before calling execute SNMP, oid is [%s]", reqInfo.oid); /*Now call clExecuteSnmp which talks to mediation library and fills the * index information for the next data or first data based on request * opcode*/ retVal = clExecuteSnmp( &reqInfo, &reqInfo.index, NULL, &errorCode); vptr = put_index_data; /*Now set the result in vptr*/ switch (retVal) { case CL_OK: /* No errors : successful operation */ { clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Successfully got index information for OID[%s]",appOidInfo[tblIndex].oid); put_index_data->val.string = NULL; memset(vptr->buf, '\0', sizeof(vptr->buf)); sendData = (ClCharT*) &reqInfo.index; for(count =0; (count < appOidInfo[tblIndex].numAttr) && sendData; count++) { switch(appOidInfo[tblIndex].attr[count].type) { case CL_SNMP_STRING_ATTR: clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Output : Possion[%d] AttrType[STRING] Value[%s] Size[%d] ",count, sendData, appOidInfo[tblIndex].attr[count].size); snmp_set_var_value(vptr, (u_char *) sendData, strlen(sendData) + 1); sendData += 1; break; case CL_SNMP_NON_STRING_ATTR: clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Output : Possion[%d] AttrType[NON-STRING] Value[%d] Size[%d]",count, *(ClUint32T*)sendData, appOidInfo[tblIndex].attr[count].size); snmp_set_var_value(vptr, (u_char *)sendData, appOidInfo[tblIndex].attr[count].size); break; default: clLog(CL_LOG_SEV_ERROR, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "AttrType is not Supported"); } sendData += appOidInfo[tblIndex].attr[count].size; vptr = vptr->next_variable; } break; } default: /* Failed due to other reasons */ clLogDebug("SNP", "OPE", "Failed while getting next entry. rc[0x%x]", retVal); return retVal; } return CL_OK; }
static ClRcT clAmsMgmtGetSUFreeNodes(ClAmsEntityT *sgName, const ClCharT *prefix, ClInt32T extraSUs, ClInt32T extraNodes, ClAmsEntityT *nodes, ClInt32T *pNumNodes) { ClRcT rc = CL_OK; ClUint32T i; ClAmsEntityBufferT suBuffer = {0}; ClAmsEntityBufferT nodeBuffer = {0}; ClAmsEntityT *nodeList = NULL; ClAmsEntityConfigT *entityConfig = NULL; ClAmsSUConfigT suConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClAmsEntityT *controllers = NULL; ClAmsEntityT *workers = NULL; ClUint32T numControllers = 0; ClUint32T numWorkers = 0; ClUint32T totalNodes = 0; if(!nodes || !pNumNodes) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); if(!extraSUs) return rc; *pNumNodes = 0; rc = clAmsMgmtGetNodeList(gHandle, &nodeBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Get node list returned [%#x]", rc); goto out; } /* * First try distributing to the extra nodes. */ if(extraNodes > 0) { for(i = nodeBuffer.count; i < nodeBuffer.count + extraNodes; ++i) { nodes[i - nodeBuffer.count].type= CL_AMS_ENTITY_TYPE_NODE; snprintf((ClCharT*)nodes[i-nodeBuffer.count].name.value, sizeof(nodes[i-nodeBuffer.count].name.value), "%s_Node%d", prefix, i); nodes[i-nodeBuffer.count].name.length = strlen((const ClCharT*)nodes[i-nodeBuffer.count].name.value)+1; nodes[i-nodeBuffer.count].debugFlags = 1; } *pNumNodes = extraNodes; } if(extraSUs <= extraNodes) { clHeapFree(nodeBuffer.entity); return CL_OK; } controllers = (ClAmsEntityT*) clHeapCalloc(nodeBuffer.count, sizeof(*controllers)); workers = (ClAmsEntityT*) clHeapCalloc(nodeBuffer.count, sizeof(*controllers)); CL_ASSERT(controllers && workers); /* * Separate controllers and workers as node distribution preference is * higher for workers than controllers. */ clOsalMutexLock(gpClCpm->cpmTableMutex); for(i = 0 ; i < nodeBuffer.count; ++i) { ClCpmLT *cpmL = NULL; rc = cpmNodeFindLocked(nodeBuffer.entity[i].name.value, &cpmL); if(rc != CL_OK) { /* * We skip the controller and worker ordering. */ if(controllers) { clHeapFree(controllers); } if(workers) { clHeapFree(workers); } controllers = nodeBuffer.entity; numControllers = nodeBuffer.count; break; } if(!strcmp(cpmL->classType, "CL_AMS_NODE_CLASS_C")) { memcpy(workers+numWorkers, nodeBuffer.entity+i, sizeof(*workers)); ++numWorkers; } else { memcpy(controllers+numControllers, nodeBuffer.entity+i, sizeof(*controllers)); ++numControllers; } } clOsalMutexUnlock(gpClCpm->cpmTableMutex); nodeList = (ClAmsEntityT*) clHeapCalloc(nodeBuffer.count + extraNodes, sizeof(ClAmsEntityT)); CL_ASSERT(nodeList); memcpy(nodeList, nodes, sizeof(*nodes)*extraNodes); if(workers) { memcpy(nodeList + extraNodes, workers, sizeof(*workers) * numWorkers); clHeapFree(workers); } if(controllers) { memcpy(nodeList + extraNodes + numWorkers, controllers, sizeof(*controllers) * numControllers); clHeapFree(controllers); } clHeapFree(nodeBuffer.entity); extraSUs -= extraNodes; for(i = 0; i < (ClUint32T) extraNodes; ++i) nodeList[i].debugFlags = 1; for(; i < nodeBuffer.count + extraNodes; ++i) nodeList[i].debugFlags = 0; /* * Now find nodes that are unmapped to the SUs of this SG */ rc = clAmsMgmtGetSGSUList(gHandle, sgName, &suBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SG su list returned [%#x]", rc); goto out_free; } for(i = 0; i < suBuffer.count; ++i) { ClUint32T j; rc = clAmsMgmtEntityGetConfig(gHandle, suBuffer.entity+i, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SU get config returned [%#x]", rc); goto out_free; } memcpy(&suConfig, entityConfig, sizeof(suConfig)); clHeapFree(entityConfig); for(j = 0; j < nodeBuffer.count+extraNodes; ++j) { if(!strncmp((const ClCharT*)nodeList[j].name.value, (const ClCharT*)suConfig.parentNode.entity.name.value, nodeList[j].name.length-1)) { /* * Mark this entry as seen. */ nodeList[j].debugFlags = 1; } } } clLogInfo("AMS", "MIGRATE", "Scanning free node list"); totalNodes = nodeBuffer.count + extraNodes; for(i = 0; (i < totalNodes) && extraSUs ; ++i) { if(!nodeList[i].debugFlags) { clLogInfo("AMS", "MIGRATE", "Copying node [%s]", nodeList[i].name.value); memcpy(nodes + extraNodes, nodeList+i, sizeof(ClAmsEntityT)); ++extraNodes; --extraSUs; } } /* * Distribute the remaining cyclically. */ if(extraSUs && extraNodes) { ClInt32T index = 0; ClInt32T currentNodes = extraNodes; while(extraSUs--) { memcpy(nodes+extraNodes, nodes+index, sizeof(ClAmsEntityT)); ++index; index %= currentNodes; ++extraNodes; } } *pNumNodes = extraNodes; rc = CL_OK; out_free: if(suBuffer.entity) clHeapFree(suBuffer.entity); if(nodeList) clHeapFree(nodeList); out: 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 ; }
static ClRcT clLogSvrStreamEntryUnpackNAdd(ClLogSvrEoDataT *pSvrEoEntry, ClLogSvrCommonEoDataT *pSvrCommonEoEntry, ClBufferHandleT msg, ClUint32T dsId) { ClRcT rc = CL_OK; SaNameT streamName = {0}; SaNameT streamScopeNode = {0}; ClUint32T compTableSize = 0; ClCntNodeHandleT hSvrStreamNode = CL_HANDLE_INVALID_VALUE; ClLogStreamKeyT *pStreamKey = NULL; ClStringT shmName = {0}; ClStringT fileName = {0}; ClStringT fileLocation = {0}; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogSvrStreamTableGet(pSvrEoEntry); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clLogSvrStreamTableCreate(): rc[0x %x]\n", rc)); return rc; } rc = clXdrUnmarshallSaNameT(msg, &streamName); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrUnmarshallSaNameT(): rc[0x %x]\n", rc)); return rc; } CL_LOG_DEBUG_VERBOSE(("streamName: %*s", streamName.length, streamName.value)); rc = clXdrUnmarshallSaNameT(msg, &streamScopeNode); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrUnmarshallSaNameT(): rc[0x %x]\n", rc)); return rc; } CL_LOG_DEBUG_VERBOSE(("streamScopeNode: %*s", streamScopeNode.length, streamScopeNode.value)); rc = clXdrUnmarshallClStringT(msg, &fileName); if(CL_OK != rc) { CL_LOG_DEBUG_ERROR(("clXdrUnmarshallClStringT(): rc[%#x]\n", rc)); return rc; } rc = clXdrUnmarshallClStringT(msg, &fileLocation); if(CL_OK != rc) { CL_LOG_DEBUG_ERROR(("clXdrUnmarshallClStringT(): rc[%#x]\n", rc)); return rc; } rc = clXdrUnmarshallClUint32T(msg, &compTableSize); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrUnmarshallClUint32T(): rc[0x %x]\n", rc)); return rc; } CL_LOG_DEBUG_VERBOSE(("compSize : %u", compTableSize)); rc = clLogStreamKeyCreate(&streamName, &streamScopeNode, pSvrCommonEoEntry->maxStreams, &pStreamKey); if( CL_OK != rc ) { return rc; } rc = clLogShmNameCreate(&streamName,&streamScopeNode,&shmName); if( CL_OK != rc ) { return rc; } clLogInfo("LOG","CRT","Recreating log stream [%*s] shared memory [%*s] located at [%*s] from persistent checkpoint",streamName.length,streamName.value,shmName.length,shmName.pValue,streamScopeNode.length, streamScopeNode.value); rc = clLogSvrStreamEntryAdd(pSvrEoEntry, pSvrCommonEoEntry, pStreamKey, &shmName, &hSvrStreamNode); clHeapFree(shmName.pValue); shmName.pValue=NULL; shmName.length=0; if (CL_ERR_DUPLICATE == CL_GET_ERROR_CODE(rc)) /* But if it is a duplicate stream should we do the items below? (if so we need to load hSvrStreamNode...) */ { return rc; } if( CL_OK != rc ) { clLogStreamKeyDestroy(pStreamKey); return rc; } rc = clLogSvrCompEntryRecreate(pSvrCommonEoEntry, pSvrEoEntry,hSvrStreamNode, msg, compTableSize); if(( CL_OK != rc )&&(CL_ERR_DUPLICATE != CL_GET_ERROR_CODE(rc))) { CL_LOG_CLEANUP(clCntNodeDelete(pSvrEoEntry->hSvrStreamTable, hSvrStreamNode), CL_OK); return rc; } rc = clLogSvrShmOpenNFlusherCreate(pSvrEoEntry, &streamName, &streamScopeNode, &fileName, &fileLocation, hSvrStreamNode, dsId); if (( CL_OK != rc )&&(CL_ERR_DUPLICATE != CL_GET_ERROR_CODE(rc))) { CL_LOG_DEBUG_ERROR(("clLogSvrShmOpenAndFlusherCreate(): rc[0x %x]\n", rc)); CL_LOG_CLEANUP(clCntNodeDelete(pSvrEoEntry->hSvrStreamTable, hSvrStreamNode), 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 clLogMasterStreamTableRecreate(ClLogSvrCommonEoDataT *pCommonEoEntry, ClBufferHandleT hFileEntryBuf, ClLogFileDataT *pFileData) { ClRcT rc = CL_OK; ClLogStreamKeyT streamKey = {{0}}; ClLogStreamKeyT *pStreamKey = NULL; ClLogMasterStreamDataT *pStreamData = NULL; ClCntNodeHandleT hStreamNode = CL_HANDLE_INVALID_VALUE; ClUint32T bitNum = 0; ClLogMasterEoDataT *pMasterEoEntry = NULL; CL_LOG_DEBUG_TRACE(("Enter")); rc = clLogMasterEoEntryGet(&pMasterEoEntry, &pCommonEoEntry); if( CL_OK != rc ) { return rc; } rc = clXdrUnmarshallSaNameT(hFileEntryBuf, &(streamKey.streamName)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrMarshallSaNameT(): rc[0x %x]", rc)); return rc; } rc = clXdrUnmarshallSaNameT(hFileEntryBuf, &(streamKey.streamScopeNode)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrMarshallSaNameT(): rc[0x %x]", rc)); return rc; } rc = clLogStreamKeyCreate(&streamKey.streamName, &streamKey.streamScopeNode, pCommonEoEntry->maxStreams, &pStreamKey); if( CL_OK != rc ) { return rc; } pStreamData = (ClLogMasterStreamDataT*) clHeapCalloc(1, sizeof(ClLogMasterStreamDataT)); if( NULL == pStreamData ) { CL_LOG_DEBUG_ERROR(("clHeapCalloc()")); clLogStreamKeyDestroy(pStreamKey); return rc; } rc = clXdrUnmarshallClUint64T(hFileEntryBuf, &(pStreamData->streamMcastAddr)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrMarshallClUint64T(): rc[0x %x]", rc)); clHeapFree(pStreamData); clLogStreamKeyDestroy(pStreamKey); return rc; } rc = clXdrUnmarshallClUint16T(hFileEntryBuf, &(pStreamData->streamId)); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clXdrMarshallClUint16T(): rc[0x %x]", rc)); clHeapFree(pStreamData); clLogStreamKeyDestroy(pStreamKey); return rc; } rc = clCntNodeAddAndNodeGet(pFileData->hStreamTable, (ClCntKeyHandleT) pStreamKey, (ClCntDataHandleT) pStreamData, NULL, &hStreamNode); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clCntNodeAdd(): rc[0x %x]", rc)); clHeapFree(pStreamData); clLogStreamKeyDestroy(pStreamKey); return rc; } /* Find out the partiuclar stream is still valid */ if( strncmp(gStreamScopeGlobal, (const ClCharT *)pStreamKey->streamScopeNode.value, pStreamKey->streamScopeNode.length) && CL_FALSE == clLogMasterStreamIsValid(&pStreamKey->streamScopeNode)) { /* * marking this as invalid by assigining CL_IOC_RESERVED_ADDRESS * so that streamMcastAddr will not be allocated & bit will not be set * numActive streams count also will be valid */ pStreamData->streamMcastAddr = CL_IOC_RESERVED_ADDRESS; clLogNotice(CL_LOG_AREA_FILE_OWNER, CL_LOG_CTX_FO_INIT, "Invalidating the stream [%.*s:%.*s]", pStreamKey->streamScopeNode.length, pStreamKey->streamScopeNode.value, pStreamKey->streamName.length, pStreamKey->streamName.value); } if( CL_IOC_RESERVED_ADDRESS != pStreamData->streamMcastAddr ) { bitNum = pStreamData->streamMcastAddr - pMasterEoEntry->startMcastAddr; CL_LOG_DEBUG_TRACE(("bitNUm: %d pStreamData->streamMcastAddr : %lld \n", bitNum, pStreamData->streamMcastAddr)); rc = clBitmapBitSet(pMasterEoEntry->hAllocedAddrMap, bitNum); if( CL_OK != rc ) { CL_LOG_DEBUG_ERROR(("clBitmapBitClear()")); CL_LOG_CLEANUP(clCntNodeDelete(pFileData->hStreamTable, hStreamNode), CL_OK); } pFileData->nActiveStreams++; clLogInfo(CL_LOG_AREA_MASTER, CL_LOG_CTX_CKPT_READ, "Active stream [%.*s:%.*s] has been added", pStreamKey->streamScopeNode.length, pStreamKey->streamScopeNode.value, pStreamKey->streamName.length, pStreamKey->streamName.value); } CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
static ClRcT _clPluginHelperGetIpNodeAddress(const ClCharT *xportType, const ClCharT *devIf, ClCharT *hostAddress, ClCharT *networkMask, ClCharT *broadcast, ClUint32T *ipAddressMask, ClCharT *xportSubnetPrefix) { ClCharT envSubNetType[CL_MAX_FIELD_LENGTH] = { 0 }; ClCharT xportSubnet[CL_MAX_FIELD_LENGTH] = { 0 }; ClCharT *subnetMask = NULL; ClCharT *subnetPrefix = NULL; ClUint32T CIDR, ipMask, ip, mask; ClRcT rc; if (!xportType) { return CL_ERR_INVALID_PARAMETER; } else { snprintf(envSubNetType, CL_MAX_FIELD_LENGTH, "ASP_%s_SUBNET", xportType); subnetMask = getenv(envSubNetType); if (subnetMask == NULL) { subnetMask = ASP_PLUGIN_SUBNET_DEFAULT; } subnetPrefix = strrchr(subnetMask, '/'); if(!subnetPrefix) { subnetPrefix = ASP_PLUGIN_SUBNET_PREFIX_DEFAULT; } else { ++subnetPrefix; } if(! (CIDR = atoi(subnetPrefix) ) ) { clLogInfo("IOC", CL_LOG_PLUGIN_HELPER_AREA, "%s", subnetMask); return CL_ERR_INVALID_PARAMETER; } xportSubnetPrefix[0] = 0; strncat(xportSubnetPrefix, subnetPrefix, CL_MAX_FIELD_LENGTH-1); snprintf(xportSubnet, sizeof(xportSubnet), "%s", subnetMask); mask = _clPluginHelperBitFillRShift(CIDR); _clPluginHelperConvertInternetToHostAddress(&ip, xportSubnet); /* network address */ ipMask = (ip & mask); /* Try to get address from devif */ rc = CL_OK+1; /* start with any error condition, so the if below this one will be taken */ if (clParseEnvBoolean("ASP_UDP_USE_EXISTING_IP")) { rc = _clPluginHelperDevToIpAddress(devIf, hostAddress); if (rc == CL_OK) clLogInfo("IOC",CL_LOG_PLUGIN_HELPER_AREA,"Use existing IP address [%s] as this nodes transport address.", hostAddress); else clLogError("IOC",CL_LOG_PLUGIN_HELPER_AREA,"Configured to use an existing IP address for message transport. But address lookup failed on device [%s] error [0x%x]", devIf, rc); } if (rc != CL_OK) { /* Automatic assignment of IP address */ _clPluginHelperConvertHostToInternetAddress(ipMask + gIocLocalBladeAddress, hostAddress); } _clPluginHelperConvertHostToInternetAddress(mask, networkMask); _clPluginHelperConvertHostToInternetAddress(ip | ~mask, broadcast); *ipAddressMask = ipMask; } return CL_OK; }
/* * 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; }
ClRcT clLogSvrInitialize(ClUint32T argc,ClCharT *argv[]) { SaAmfCallbacksT callbacks = {0}; SaVersionT version; ClRcT rc = CL_OK; ClBoolT *pCookie = NULL; clLogCompName =(ClCharT*) "LOG"; /* Override generated eo name with a short name for our server */ gClLogServer = CL_FALSE; /* Mark me as the log server */ clLogInfo(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED, "Log Server initialization started..."); clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); version.releaseCode = 'B'; version.majorVersion = 0x01; version.minorVersion = 0x01; callbacks.saAmfHealthcheckCallback = NULL; /* rarely necessary because SAFplus monitors the process */ callbacks.saAmfComponentTerminateCallback = clLogSvrTerminate; callbacks.saAmfCSISetCallback = NULL; callbacks.saAmfCSIRemoveCallback = NULL; callbacks.saAmfProtectionGroupTrackCallback = NULL; callbacks.saAmfProxiedComponentInstantiateCallback = NULL; callbacks.saAmfProxiedComponentCleanupCallback = NULL; rc = saAmfInitialize(&amfHandle, &callbacks, &version); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfInitialize(): rc[0x %x]", rc)); return rc; } rc = saAmfComponentNameGet(amfHandle, &logServerName); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfComponentNameGet(): rc[0x %x]", rc)); saAmfFinalize(amfHandle); CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); return rc; } rc = saAmfComponentRegister(amfHandle, &logServerName, NULL); if( SA_AIS_OK != rc ) { CL_LOG_DEBUG_ERROR(("saAmfComponentRegister(): rc[0x %x]", rc)); CL_LOG_CLEANUP(clLogSvrEoDataFinalize(), CL_OK); CL_LOG_CLEANUP(clLogSvrEoDataFree(), CL_OK); clHeapFree(pCookie); CL_LOG_CLEANUP(clLogStreamOwnerLocalShutdown(), CL_OK); CL_LOG_CLEANUP(clLogStreamOwnerEoDataFree(), CL_OK); CL_LOG_CLEANUP(clLogSvrCommonDataFinalize(), CL_OK); CL_LOG_CLEANUP(clIdlHandleFinalize(shLogDummyIdl), CL_OK); saAmfFinalize(amfHandle); return rc; } clLogNotice(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED, "Log Server partially up"); CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
static ClRcT clLogFlusherRecordsFlush(ClLogSvrStreamDataT *pStreamData) { ClRcT rc = CL_OK; ClLogStreamHeaderT *pHeader = pStreamData->pStreamHeader; ClLogSvrCommonEoDataT *pSvrCommonEoEntry = NULL; ClLogSvrEoDataT *pSvrEoEntry = NULL; ClUint32T nFlushableRecords = 0; ClUint32T nFlushedRecords = 0; ClLogFlushRecordT flushRecord = {0}; CL_LOG_DEBUG_TRACE(("Enter")); if( (pStreamData->fileOwnerAddr != clIocLocalAddressGet()) && (0 == pStreamData->ackersCount + pStreamData->nonAckersCount) ) { clLogInfo("LOG", "FLS", "No one has registered for the Stream"); return CL_OK; } rc = clLogSvrEoEntryGet(&pSvrEoEntry, &pSvrCommonEoEntry); if( CL_OK != rc ) { return rc; } CL_LOG_DEBUG_TRACE((" recordIdx: %d startAck : %d \n", pHeader->recordIdx, pHeader->startAck)); if (pHeader->recordIdx < pHeader->startAck) { /* Ring buffer wraparound Case */ nFlushableRecords = (pHeader->recordIdx + pHeader->maxRecordCount) - pHeader->startAck; } else { nFlushableRecords = pHeader->recordIdx - pHeader->startAck; } flushRecord.fileName.pValue = (ClCharT*) clHeapCalloc(1, pStreamData->fileName.length+1); CL_ASSERT(flushRecord.fileName.pValue != NULL); flushRecord.fileName.length = pStreamData->fileName.length; memcpy(flushRecord.fileName.pValue, pStreamData->fileName.pValue, flushRecord.fileName.length); flushRecord.fileLocation.pValue = (ClCharT*) clHeapCalloc(1, pStreamData->fileLocation.length+1); CL_ASSERT(flushRecord.fileLocation.pValue != NULL); flushRecord.fileLocation.length = pStreamData->fileLocation.length; memcpy(flushRecord.fileLocation.pValue, pStreamData->fileLocation.pValue, flushRecord.fileLocation.length); flushRecord.fileOwnerAddr = pStreamData->fileOwnerAddr; flushRecord.seqNum = pStreamData->seqNum; flushRecord.multicast = -1; flushRecord.recordSize = pHeader->recordSize; while( nFlushableRecords > 0 ) { nFlushedRecords = (nFlushableRecords > pSvrEoEntry->maxFlushLimit) ? pSvrEoEntry->maxFlushLimit : nFlushableRecords; rc = clLogFlusherRecordsGetMcast(pStreamData, nFlushedRecords, &flushRecord); if( CL_OK == rc ) { pHeader->update_status = CL_LOG_STREAM_HEADER_UPDATE_INPROGRESS; pHeader->startAck += nFlushedRecords; pHeader->startAck %= (pHeader->maxRecordCount); pStreamData->seqNum += nFlushedRecords; nFlushableRecords -= nFlushedRecords; CL_LOG_DEBUG_TRACE(("startAck: %u remaining: %u",pHeader->startAck, nFlushableRecords)); /* FIXME: put the number of overwritten records in log */ if( 0 != pHeader->numOverwrite ) { pHeader->numDroppedRecords = pHeader->numOverwrite; pHeader->numOverwrite = 0; CL_LOG_DEBUG_TRACE(("Log buffer full. [%d] records have been dropped", pHeader->numDroppedRecords)); } pHeader->update_status = CL_LOG_STREAM_HEADER_UPDATE_COMPLETE; } else { break; } } rc = clLogServerStreamMutexUnlock(pStreamData); if( CL_OK != rc ) { clLogError("SVR", "FLU", "Failed to unlock the stream"); } logRecordsFlush(&flushRecord); clLogServerStreamMutexLockFlusher(pStreamData); CL_LOG_DEBUG_TRACE(("Exit")); return CL_OK; }
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 clLogFlusherRecordsFlush(ClLogSvrStreamDataT *pStreamData) { ClRcT rc = CL_OK; ClLogStreamHeaderT *pHeader = pStreamData->pStreamHeader; ClLogSvrCommonEoDataT *pSvrCommonEoEntry = NULL; ClLogSvrEoDataT *pSvrEoEntry = NULL; ClUint32T nFlushableRecords = 0; ClUint32T nFlushedRecords = 0; CL_LOG_DEBUG_TRACE(("Enter")); if( (pStreamData->fileOwnerAddr != clIocLocalAddressGet()) && (0 == pStreamData->ackersCount + pStreamData->nonAckersCount) ) { clLogInfo("LOG", "FLS", "No one has registered for the Stream"); return CL_OK; } rc = clLogSvrEoEntryGet(&pSvrEoEntry, &pSvrCommonEoEntry); if( CL_OK != rc ) { return rc; } CL_LOG_DEBUG_TRACE((" recordIdx: %d startAck : %d \n", pHeader->recordIdx, pHeader->startAck)); if (pHeader->recordIdx < pHeader->startAck) { nFlushableRecords = (pHeader->recordIdx + pHeader->maxRecordCount) - pHeader->startAck; } else { nFlushableRecords = abs( pHeader->recordIdx - pHeader->startAck ); } while( nFlushableRecords > 0 ) { nFlushedRecords = (nFlushableRecords > pSvrEoEntry->maxFlushLimit) ? pSvrEoEntry->maxFlushLimit : nFlushableRecords; rc = clLogFlusherRecordsMcast(pStreamData, nFlushedRecords); if( CL_OK == rc ) { pHeader->startAck += nFlushedRecords; pHeader->startAck %= (pHeader->maxRecordCount); pStreamData->seqNum += nFlushedRecords; nFlushableRecords -= nFlushedRecords; CL_LOG_DEBUG_TRACE(("startAck: %u remaining: %u", pHeader->startAck, nFlushableRecords)); /* FIXME: put the number of overwritten records in log */ if( 0 != pHeader->numOverwrite ) { CL_LOG_DEBUG_TRACE((" %d records have been dropped", pHeader->numOverwrite)); } pHeader->numOverwrite = 0; } else { return CL_OK; } } CL_LOG_DEBUG_TRACE(("Exit")); return rc; }
/*----------------------------------------------------------------------------- * Initialize API *---------------------------------------------------------------------------*/ ClRcT clGmsInitialize( CL_OUT ClGmsHandleT* const gmsHandle, CL_IN const ClGmsCallbacksT* const gmsCallbacks, CL_INOUT ClVersionT* const version) { struct gms_instance *gms_instance_ptr = NULL; ClRcT rc = CL_OK; ClGmsClientInitRequestT req = {{0}}; ClGmsClientInitResponseT *res = NULL; /* Step 0: Check readiness of library */ rc = check_lib_init(); if (rc != CL_OK) { return CL_GMS_RC(CL_ERR_NOT_INITIALIZED); } /* Step 1: Checking inputs */ CL_ASSERT(gmsHandle != NULL); CL_ASSERT(version != NULL); #if 0 if ((gmsHandle == NULL) || (version == NULL)) { return CL_GMS_RC(CL_ERR_NULL_POINTER); } #endif *gmsHandle = CL_HANDLE_INVALID_VALUE; /* Step 2: Verifying version match */ rc = clVersionVerify (&version_database, version); if (rc != CL_OK) { return CL_GMS_RC(CL_ERR_VERSION_MISMATCH); } /* Step 3: Obtain unique handle */ rc = clHandleCreate(gmsHandleDb, sizeof(struct gms_instance), gmsHandle); CL_ASSERT(rc == CL_OK); #if 0 if (rc != CL_OK) { rc = CL_GMS_RC(CL_ERR_NO_RESOURCE); goto error_no_destroy; } #endif clLogInfo("GMS","CLT","GMS client handle is [%llX]",*gmsHandle); rc = clHandleCheckout(gmsHandleDb, *gmsHandle, (void **)&gms_instance_ptr); CL_ASSERT(rc == CL_OK); CL_ASSERT(gms_instance_ptr != NULL); #if 0 if(rc != CL_OK) { goto error_destroy; } if (gms_instance_ptr == NULL) { clHandleCheckin(gmsHandleDb, *gmsHandle); rc = CL_GMS_RC(CL_ERR_NULL_POINTER); goto error_destroy; } #endif rc = clGmsMutexCreate(&gms_instance_ptr->response_mutex); CL_ASSERT(rc == CL_OK); #if 0 if(rc != CL_OK) { clHandleCheckin(gmsHandleDb, *gmsHandle); goto error_destroy; } #endif /* Step 4: Negotiate version with the server */ req.clientVersion.releaseCode = version->releaseCode; req.clientVersion.majorVersion= version->majorVersion; req.clientVersion.minorVersion= version->minorVersion; rc = cl_gms_clientlib_initialize_rmd(&req, 0x0 ,&res ); if(rc != CL_OK ) { clLogError(GEN,NA,"cl_gms_clientlib_initialize_rmd failed with rc:0x%x ",rc); clGmsMutexDelete(gms_instance_ptr->response_mutex); gms_instance_ptr->response_mutex = 0; clHandleCheckin(gmsHandleDb, *gmsHandle); rc = CL_GMS_RC(rc); goto error_destroy; } /* Step 5: Initialize instance entry */ if (gmsCallbacks) { memcpy(&gms_instance_ptr->callbacks, gmsCallbacks, sizeof(ClGmsCallbacksT)); } else { memset(&gms_instance_ptr->callbacks, 0, sizeof(ClGmsCallbacksT)); } memset(&gms_instance_ptr->cluster_notification_buffer, 0, sizeof(ClGmsClusterNotificationBufferT)); memset(&gms_instance_ptr->group_notification_buffer, 0, sizeof(ClGmsGroupNotificationBufferT)); /* Step 6: Decrement handle use count and return */ if ((clHandleCheckin(gmsHandleDb, *gmsHandle)) != CL_OK) { clLogError(GEN,DB, "\nclHandleCheckin failed"); } clHeapFree(res); return CL_OK; error_destroy: clHandleDestroy(gmsHandleDb, *gmsHandle); *gmsHandle = CL_HANDLE_INVALID_VALUE; //error_no_destroy: return rc; }
/** * This is the agent initilaization API called during EO initialization. * * Agent acts as intermediate layer during an active transaction. It receives * job-definition and commands from transaction manager and takes specific * action. */ ClRcT clTxnAgentInitialize(CL_IN ClEoExecutionObjT *appEoObj, CL_IN ClVersionT *pTxnVersion) { ClRcT rc = CL_OK; CL_FUNC_ENTER(); if ( (NULL == appEoObj) || (NULL == pTxnVersion) ) { CL_FUNC_EXIT(); return CL_TXN_RC(CL_ERR_NULL_POINTER); } /* Do version negotiation (later part of RC-1 or RC-2) */ if (clTxnVersionVerify(pTxnVersion) != CL_OK) { CL_FUNC_EXIT(); return (CL_TXN_RC(CL_ERR_VERSION_MISMATCH)); } clTxnAgntCfg = (ClTxnAgentCfgT *) clHeapAllocate( sizeof(ClTxnAgentCfgT)); CL_TXN_NULL_CHECK_RETURN(clTxnAgntCfg, CL_ERR_NO_MEMORY, ("Failed to allocate memory\n")); memset(clTxnAgntCfg, 0, sizeof(ClTxnAgentCfgT)); /* If possible, instead of statically registring RMD functions, txn-agent could register EO client table here. */ /* Create hash-maps for active-txn component-services */ rc = clTxnDbInit( &(clTxnAgntCfg->activeTxnMap) ); CL_TXN_ERR_RET_ON_ERROR(rc, ("Failed to allocate hash-map for active-txn rc:0x%x\n", rc)); rc = clCntThreadSafeHashtblCreate(CL_TXN_NUM_BUCKETS, _clTxnCmpServiceKeyCompare, _clTxnCmpServiceHashFn, _clTxnCompServiceDelete, _clTxnCompServiceDelete, CL_CNT_UNIQUE_KEY, (ClCntHandleT *) &clTxnAgntCfg->compServiceMap); CL_TXN_ERR_RET_ON_ERROR(rc, ("Failed to allocate hash-map for comp-service rc:0x%x\n", rc)); clTxnMutexCreateAndLock(&clTxnAgntCfg->actMtx); /* No registered service */ clTxnAgntCfg->agentCapability = CL_TXN_AGENT_NO_SERVICE_REGD; clTxnMutexUnlock(clTxnAgntCfg->actMtx); clLogInfo("AGT", NULL, "Installing function table"); rc = clEoClientInstallTables(appEoObj, CL_EO_SERVER_SYM_MOD(gAspFuncTable, TXNAgent)); if (CL_OK == rc) { rc = clTxnCommIfcInit(&(clTxnMgmtVersionSupported[0])); if(CL_OK != rc) { clLogError("AGT", NULL, "Error in initiazing communication interface, rc [0x%x]", rc); clEoClientUninstallTables(appEoObj, CL_EO_SERVER_SYM_MOD(gAspFuncTable, TXNAgent)); return rc; } } if(CL_OK == rc) { rc = clTxnAgentTableRegister(appEoObj); if(CL_OK != rc) { clLogError("AGT", NULL, "Error in table registration, rc [0x%x]", rc); clEoClientUninstallTables(appEoObj, CL_EO_SERVER_SYM_MOD(gAspFuncTable, TXNAgent)); } } CL_FUNC_EXIT(); return (rc); }