static ClRcT clAmsEntityLocate(ClAmsEntityT *pEntity) { ClRcT rc = CL_OK; register ClInt32T i; for(i = CL_AMS_ENTITY_TYPE_ENTITY + 1; i < CL_AMS_ENTITY_TYPE_MAX + 1; ++i) { ClAmsEntityConfigT *pEntityConfig = NULL; pEntity->type = (ClAmsEntityTypeT) i; rc = clAmsMgmtEntityGetConfig(gClAmsEntityTriggerMgmtHandle, pEntity, &pEntityConfig); if(rc != CL_OK) { if(pEntityConfig) clHeapFree(pEntityConfig); continue; } memcpy(pEntity, pEntityConfig, sizeof(*pEntity)); clHeapFree(pEntityConfig); return CL_OK; } return CL_AMS_RC(CL_ERR_NOT_EXIST); }
static ClRcT clAmsMgmtOIConfigAttributeSet(ClAmsMgmtHandleT handle, ClCorTxnSessionIdT *pSession, ClCorMOIdT *pMoId, ClAmsEntityT *pEntity, ClRcT (*pClAmsMgmtOIConfigAttributesGet) (ClAmsEntityConfigT*, ClCorAttributeValueListPtrT )) { ClCorObjectHandleT objHandle = 0; ClRcT rc = CL_OK; ClCorAttributeValueListT attrList = {0}; ClAmsEntityConfigT *pEntityConfig = NULL; if(!handle || !pSession || !pMoId || !pEntity || !pClAmsMgmtOIConfigAttributesGet) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); rc = clAmsMgmtEntityGetConfig(handle, pEntity, &pEntityConfig); if(rc != CL_OK || !pEntityConfig) { clLogError("AMF", "MGMT", "Entity [%s] config get returned [%#x]", pEntity->name.value, rc); return rc; } rc = clCorMoIdToObjectHandleGet(pMoId, &objHandle); if(rc != CL_OK) { goto out_free; } rc = (*pClAmsMgmtOIConfigAttributesGet)(pEntityConfig, &attrList); if(rc != CL_OK) { goto out_free; } rc = clAmsMgmtOIAttributeSet(pEntity, pSession, objHandle, &attrList); out_free: if(pEntityConfig) clHeapFree(pEntityConfig); if(objHandle) clCorObjectHandleFree(&objHandle); if(attrList.pAttributeValue) clHeapFree(attrList.pAttributeValue); return rc; }
ClRcT clAmfNodeSet(ClAmsMgmtHandleT mgmtHandle, const ClProvTxnDataT *pProvTxnData) { ClAmsEntityT entity = {0}; ClRcT rc = CL_OK; if(!mgmtHandle) return CL_OK; if(!pProvTxnData || !pProvTxnData->pProvData || !pProvTxnData->pMoId) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); entity.type = CL_AMS_ENTITY_TYPE_NODE; rc = clAmsMgmtOIGet(pProvTxnData->pMoId, &entity); if(rc != CL_OK) { SaNameT moidName = {0}; if(clCorMoIdToMoIdNameGet(pProvTxnData->pMoId, &moidName) == CL_OK) clLogError("OI", "READ", "AMF entity not found for moid [%.*s]", moidName.length, moidName.value); return rc; } switch (pProvTxnData->attrId) { case SAAMFNODETABLE_SAAMFNODEADMINSTATETRIGGER: { ClAmsNodeConfigT *pNodeConfig = NULL; ClInt32T adminState = *(ClInt32T *)pProvTxnData->pProvData; rc = clAmsMgmtEntityGetConfig(mgmtHandle, &entity, (ClAmsEntityConfigT**)&pNodeConfig); if (rc != CL_OK) { clLogError("OI", "WRITE", "Node [%s] config returned [%#x]", entity.name.value, rc); return rc; } if (pProvTxnData->size != (ClUint32T)sizeof(pNodeConfig->adminState)) { clLogError("OI", "WRITE", "Read size [%d] doesnt match expected size [%d]", pProvTxnData->size, (ClUint32T)pNodeConfig->adminState); clHeapFree(pNodeConfig); return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); } switch (adminState) { case SAAMFNODEADMINSTATETRIGGER_STABLE: { return CL_OK; } case SAAMFNODEADMINSTATETRIGGER_UNLOCKINSTANTIATION: case SAAMFNODEADMINSTATETRIGGER_LOCK: { rc = clAmsMgmtEntityLockAssignment(mgmtHandle, &entity); break; } case SAAMFNODEADMINSTATETRIGGER_UNLOCK: { if(clAmsMgmtEntityLockAssignment(mgmtHandle, &entity) == CL_OK) sleep(1); rc = clAmsMgmtEntityUnlock(mgmtHandle, &entity); break; } case SAAMFNODEADMINSTATETRIGGER_LOCKINSTANTIATION: { /* * Careful. If snmp subagent is running on only 1 node * and is not redundant, then the snmp query would timeout * as it would take down the subagent as well. */ if(clAmsMgmtEntityLockAssignment(mgmtHandle, &entity) == CL_OK) sleep(1); rc = clAmsMgmtEntityLockInstantiation(mgmtHandle, &entity); break; } } clHeapFree(pNodeConfig); break; } case SAAMFNODETABLE_SAAMFNODEAUTOREPAIROPTION: { break; } case SAAMFNODETABLE_SAAMFNODECLMNODE: { break; } case SAAMFNODETABLE_SAAMFNODENAME: { break; } case SAAMFNODETABLE_SAAMFNODEREPAIR: { break; } case SAAMFNODETABLE_SAAMFNODESUFAILOVERPROB: { break; } default: { break; } } return rc; }
/** * This function is called to perform a get operation on the transient attribute * which is owned by the primary object implementer (OI). As the COR doesn't have * the latest value of the transient attribute, it is obtained from the OI. This * function is called in the OI's context which it can use to fill the latest * value of the runtime or transient attribute. * * The pThis is pointer to the provisioning class. * The txnHandle is used to identify the jobs which are part of same bundle request. * For single request this field is of not much significance, but for a multiple job * request, this feild is used to identify all the jobs which are part of same * bundle request sent by COR. * * The pProvTxnData contains the information about the attribute jobs. It contains * the MOId of the managed resource, the attribute identifier, its type (array or * simple), its basic type (data type), index (in case it is array attriubte), * size and the pointer (allocated by the library) to the memory on which the * data can be copied. * * For a request containing only single job, this function is called only once. But * for a multiple job request, this is called for all the attributes one at a time. * * ** Note : This function is being deprecated, if clProvObjectRead() callback is filled * in the constructor, then that callback function will be called instead of this * to group read all the requests. */ ClRcT clamfMgmtSAAMFSITABLEProvRead(CL_OM_PROV_CLASS* pThis, ClHandleT txnHandle, ClProvTxnDataT* pProvTxnData) { ClRcT rc = CL_OK; /* * ---BEGIN_APPLICATION_CODE--- */ ClAmsEntityT entity = {0}; clprintf(CL_LOG_SEV_INFO, "Inside the function %s", __FUNCTION__); if(!gClAmsMgmtHandle) return CL_AMS_RC(CL_ERR_NOT_INITIALIZED); if(!pProvTxnData || !pProvTxnData->pProvData || !pProvTxnData->pMoId) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); entity.type = CL_AMS_ENTITY_TYPE_SI; rc = clAmsMgmtOIGet(pProvTxnData->pMoId, &entity); if(rc != CL_OK) { ClNameT moidName = {0}; if(clCorMoIdToMoIdNameGet(pProvTxnData->pMoId, &moidName) == CL_OK) clLogError("OI", "READ", "AMF entity not found for moid [%.*s]", moidName.length, moidName.value); return rc; } switch(pProvTxnData->attrId) { case SAAMFSITABLE_SAAMFSIADMINSTATE: { ClAmsSIConfigT *pSIConfig = NULL; rc = clAmsMgmtEntityGetConfig(gClAmsMgmtHandle, &entity, (ClAmsEntityConfigT**)&pSIConfig); if(rc != CL_OK) { clLogError("OI", "READ", "SI [%s] config get returned [%#x]", entity.name.value, rc); return rc; } if(pProvTxnData->size != (ClUint32T)sizeof(pSIConfig->adminState)) { clLogError("OI", "READ", "Read size [%d] doesnt match expected size [%d]", pProvTxnData->size, (ClUint32T)sizeof(pSIConfig->adminState)); clHeapFree(pSIConfig); return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); } memcpy(pProvTxnData->pProvData, &pSIConfig->adminState, pProvTxnData->size); clHeapFree(pSIConfig); } break; case SAAMFSITABLE_SAAMFSINUMCURRACTIVEASSIGNMENTS: case SAAMFSITABLE_SAAMFSINUMCURRSTANDBYASSIGNMENTS: { ClAmsSIStatusT *pSIStatus = NULL; rc = clAmsMgmtEntityGetStatus(gClAmsMgmtHandle, &entity, (ClAmsEntityStatusT**)&pSIStatus); if(rc != CL_OK) { clLogError("OI", "READ", "SI [%s] status returned [%#x]", entity.name.value, rc); return rc; } if(pProvTxnData->size != (ClUint32T)sizeof(pSIStatus->numActiveAssignments)) { clLogError("OI", "READ", "Read size [%d] doesnt match expected size [%d]", pProvTxnData->size, (ClUint32T)sizeof(pSIStatus->numActiveAssignments)); clHeapFree(pSIStatus); return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); } if(pProvTxnData->attrId == SAAMFSITABLE_SAAMFSINUMCURRACTIVEASSIGNMENTS) memcpy(pProvTxnData->pProvData, &pSIStatus->numActiveAssignments, pProvTxnData->size); else memcpy(pProvTxnData->pProvData, &pSIStatus->numStandbyAssignments, pProvTxnData->size); clHeapFree(pSIStatus); } break; default: return CL_AMS_RC(CL_ERR_NOT_SUPPORTED); } /* * ---END_APPLICATION_CODE--- */ return rc; }
// Start this app container running on these nodes (1+N redundancy). This will // start a SAF-aware process on each node specified. // Create SU and Comp void acExtend(const char* appCnt, const char* nodeName, const char* compName,SafConfig* cfg) { ClRcT rc; ClAmsEntityConfigT sg; ClAmsEntityConfigT comp; ClAmsEntityConfigT su; ClUint64T changeMask = 0; ClAmsSGConfigT sgConfig; ClAmsEntityConfigT* pEntityConfig = NULL; if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles(); initEntity(&sg,appCnt,CL_AMS_ENTITY_TYPE_SG); if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&sg,&pEntityConfig)) != CL_OK) { checkError("Get SG configuration", rc); } memcpy(&sgConfig, pEntityConfig, sizeof(sgConfig)); clHeapFree(pEntityConfig); //Fix bug: recovery policy if (cfg && cfg->compRestartCountMax > 0 && cfg->compRestartDuration > 0) { sgConfig.compRestartCountMax = cfg->compRestartCountMax; sgConfig.compRestartDuration = cfg->compRestartDuration; changeMask |= SG_CONFIG_COMP_RESTART_DURATION | SG_CONFIG_COMP_RESTART_COUNT_MAX; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&sgConfig.entity,changeMask) ) != CL_OK) { checkError("Set SG config", rc); } } // Create SU and component per node if (1) { initEntity(&su,compName,CL_AMS_ENTITY_TYPE_SU); if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&su)) != CL_OK) { checkError("Create SU", rc); } initEntity(&comp,compName,CL_AMS_ENTITY_TYPE_COMP); if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&comp)) != CL_OK) { checkError("Create Comp", rc); } } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit creation of SU and Component", rc); } SaNameT supportedCSIType; saNameSet(&supportedCSIType, CSI_TYPE_APP); supportedCSIType.length += 1; // Configure components if (1) { ClAmsCompConfigT compConfig; ClUint64T bitMask = 0; if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&comp,&pEntityConfig)) != CL_OK) { checkError("Retrieve component config", rc); } memcpy(&compConfig, pEntityConfig, sizeof(compConfig)); clHeapFree(pEntityConfig); bitMask |= COMP_CONFIG_CAPABILITY_MODEL | COMP_CONFIG_TIMEOUTS; compConfig.capabilityModel = CL_AMS_COMP_CAP_X_ACTIVE_OR_Y_STANDBY; compConfig.timeouts.instantiate = 30000; compConfig.timeouts.terminate = 30000; compConfig.timeouts.cleanup = 30000; compConfig.timeouts.quiescingComplete = 30000; compConfig.timeouts.csiSet = 30000; compConfig.timeouts.csiRemove = 30000; compConfig.timeouts.instantiateDelay = 1000; if (!strncmp(nodeName, "sc", 2)) { if (cfg && cfg->compRestartCountMax == 0) { bitMask |= COMP_CONFIG_IS_RESTARTABLE | COMP_CONFIG_RECOVERY_ON_TIMEOUT; compConfig.isRestartable = false; compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NODE_FAILOVER; } else { bitMask |= COMP_CONFIG_RECOVERY_ON_TIMEOUT; compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NO_RECOMMENDATION; } } else { if (cfg && cfg->compRestartCountMax == 0) { bitMask |= COMP_CONFIG_IS_RESTARTABLE | COMP_CONFIG_RECOVERY_ON_TIMEOUT; compConfig.isRestartable = false; compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_COMP_FAILOVER; } else { bitMask |= COMP_CONFIG_RECOVERY_ON_TIMEOUT; compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NO_RECOMMENDATION; } } if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK) { checkError("Set component config", rc); } bitMask = COMP_CONFIG_INSTANTIATE_COMMAND; if (cfg&&cfg->binName) { snprintf(compConfig.instantiateCommand, sizeof(compConfig.instantiateCommand), cfg->binName); } else { snprintf(compConfig.instantiateCommand, sizeof(compConfig.instantiateCommand), APP_CNT_CMD); } if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK) { checkError("Set component instantiate command", rc); } } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit configure of components", rc); } // Configure components if (1) { ClAmsCompConfigT compConfig; ClUint64T bitMask = 0; if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&comp,&pEntityConfig)) != CL_OK) { checkError("Retrieve component config", rc); } memcpy(&compConfig, pEntityConfig, sizeof(compConfig)); clHeapFree(pEntityConfig); bitMask |= COMP_CONFIG_SUPPORTED_CSI_TYPE | COMP_CONFIG_NUM_MAX_ACTIVE_CSIS | COMP_CONFIG_NUM_MAX_STANDBY_CSIS; if(compConfig.pSupportedCSITypes) clHeapFree(compConfig.pSupportedCSITypes); compConfig.numSupportedCSITypes = 1; compConfig.pSupportedCSITypes = &supportedCSIType; compConfig.numMaxActiveCSIs = 10000; compConfig.numMaxStandbyCSIs = 10000; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK) { checkError("Setting supported CSI types", rc); } } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Configuring components supported CSI type", rc); } // Configure SUs if (1) { ClUint64T bitMask = 0; ClAmsSUConfigT suConfig; if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&su,&pEntityConfig)) != CL_OK) { checkError("Get SU", rc); } memcpy(&suConfig, pEntityConfig, sizeof(suConfig)); clHeapFree(pEntityConfig); bitMask |= SU_CONFIG_NUM_COMPONENTS | SU_CONFIG_ADMIN_STATE; // set number of components (processes) per SU to 1 suConfig.numComponents = 1; //suConfig.adminState = CL_AMS_ADMIN_STATE_UNLOCKED; suConfig.adminState = CL_AMS_ADMIN_STATE_LOCKED_I; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&suConfig.entity,bitMask)) != CL_OK) { checkError("Configure SU", rc); } // attach the comp to the su if ((rc = clAmsMgmtCCBSetSUCompList(ccbHandle,&su,&comp)) != CL_OK) { checkError("Link COMP to SU", rc); } } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit SU configuration", rc); } // Add the SU to SG's and Node's list if (1) { ClAmsEntityConfigT node; initEntity(&node,nodeName,CL_AMS_ENTITY_TYPE_NODE); if ((rc = clAmsMgmtCCBSetSGSUList(ccbHandle,&sg,&su)) != CL_OK) { checkError("Add SU to SG", rc); } if ((rc = clAmsMgmtCCBSetNodeSUList(ccbHandle,&node,&su)) != CL_OK) { checkError("Add SU to Node", rc); } /* if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) { checkError("Committing addition of SU to node and SG", rc); } */ if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) { checkError("Committing addition of SU to node and SG", rc); } } // Now that all is configured, start them up entityStart(su); }
static void initHandles(void) { ClRcT rc; rc = clAmsMgmtInitialize(&mgmtHandle, NULL, &amfApiVersion); if(rc != CL_OK) { checkError("AMS mgmt handle init",rc); } if ((rc = clAmsMgmtCCBInitialize(mgmtHandle, &ccbHandle)) != CL_OK) { checkError("AMS mgmt config change handle init",rc); } // Create the CSI type by creating an unused CSI. ClAmsEntityConfigT csi; memset(&csi,0,sizeof(csi)); saNameSet(&csi.name,"unusedCSI"); csi.type = CL_AMS_ENTITY_TYPE_CSI; if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&csi)) != CL_OK) { checkError("Create CSI",rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit SI/CSI creation", rc); } if(rc == CL_OK) { ClAmsEntityConfigT *pEntityConfig = NULL; ClUint64T changeMask = 0; ClAmsCSIConfigT csiConfig; // Grab the CSI object if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&csi,&pEntityConfig)) != CL_OK) { checkError("Get CSI configuration", rc); } memcpy(&csiConfig, pEntityConfig, sizeof(csiConfig)); clHeapFree(pEntityConfig); // Specify a unique CSI type changeMask |= CSI_CONFIG_TYPE; saNameSet(&csiConfig.type, CSI_TYPE_APP); csiConfig.type.length += 1; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&csiConfig.entity,changeMask)) != CL_OK) { checkError("Set CSI type", rc); } // Commit CSI if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit CSI",rc); } } }
// Create a new application container in the AMF void addAppCnt(const char* safName,SafConfig* cfg) { ClRcT rc; ClAmsEntityConfigT sg; // Create the SG object if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles(); initEntity(&sg,safName,CL_AMS_ENTITY_TYPE_SG); if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&sg)) != CL_OK) { checkError("Create SG",rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit create SG",rc); } // Now configure it -- for now just use the defaults if (1) { ClAmsSGConfigT sgConfig; ClAmsEntityConfigT* pEntityConfig = NULL; ClUint64T changeMask = 0; if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&sg,&pEntityConfig)) != CL_OK) { checkError("Get SG config",rc); } memcpy(&sgConfig, pEntityConfig, sizeof(sgConfig)); clHeapFree(pEntityConfig); changeMask |= SG_CONFIG_REDUNDANCY_MODEL | SG_CONFIG_NUM_PREF_ACTIVE_SUS | SG_CONFIG_NUM_PREF_STANDBY_SUS | SG_CONFIG_NUM_PREF_INSERVICE_SUS | SG_CONFIG_MAX_ACTIVE_SIS_PER_SU | SG_CONFIG_MAX_STANDBY_SIS_PER_SU | SG_CONFIG_INSTANTIATE_DURATION; sgConfig.redundancyModel = CL_AMS_SG_REDUNDANCY_MODEL_TWO_N; sgConfig.numPrefActiveSUs = 1; // Just a very large number, so the check does not occur in the custom model sgConfig.numPrefStandbySUs = 1; sgConfig.numPrefInserviceSUs = 2; sgConfig.maxActiveSIsPerSU = 1; sgConfig.maxStandbySIsPerSU = 1; sgConfig.instantiateDuration = 1000; //Recovery policy if (cfg && cfg->compRestartCountMax > 0 && cfg->compRestartDuration > 0) { sgConfig.compRestartCountMax = cfg->compRestartCountMax; sgConfig.compRestartDuration = cfg->compRestartDuration; changeMask |= SG_CONFIG_COMP_RESTART_DURATION | SG_CONFIG_COMP_RESTART_COUNT_MAX; } if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&sgConfig.entity,changeMask) ) != CL_OK) { checkError("Set SG config", rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) { checkError("Commit change SG config",rc); } } // Add the scheduler application in. // In particular this defines the CSI TYPE in the SG so it will work when used during component addition. //acAddApp(safName,"scheduler",""); }
// Add an application to this app container. // The effect of this is to create a new SAF Service Instance (SI) and CSI // This SI will be assigned to the SG and therefore a process running on the cluster // This process shall use the information in the SI to start the appropriate // application running. void acAddApp(const char* appCnt,const char* appName, const char* activeXml, const char* standbyXml) { ClRcT rc; ClAmsEntityConfigT sg; ClAmsEntityConfigT si; ClAmsEntityConfigT csi; if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles(); initEntity(&sg,appCnt,CL_AMS_ENTITY_TYPE_SG); initEntity(&si,appName,CL_AMS_ENTITY_TYPE_SI); initEntity(&csi,appName,CL_AMS_ENTITY_TYPE_CSI); // Create the new entities if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&si)) != CL_OK) { checkError("Create SI",rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit SI creation", rc); } if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&csi)) != CL_OK) { checkError("Create CSI",rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit CSI creation", rc); } // Configure the new entities if (1) // configure the SI { ClUint64T changeMask = 0; ClAmsEntityConfigT *pEntityConfig = NULL; ClAmsSIConfigT siConfig; // Grab the SI object if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&si,&pEntityConfig)) != CL_OK) { checkError("Get SI config", rc); } memcpy(&siConfig, pEntityConfig, sizeof(siConfig)); clHeapFree(pEntityConfig); // Configure SI state siConfig.numCSIs = 1; siConfig.numStandbyAssignments = 1; changeMask |= SI_CONFIG_NUM_CSIS | SI_CONFIG_NUM_STANDBY_ASSIGNMENTS; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&siConfig.entity,changeMask)) != CL_OK) { checkError("Set SI config", rc); } // Link SI to the CSI if ((rc = clAmsMgmtCCBSetSICSIList(ccbHandle,&si,&csi)) != CL_OK) { checkError("Change SI config", rc); } // Commit SI if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit SI configuration", rc); } } if (1) // configure the CSI { ClAmsEntityConfigT *pEntityConfig = NULL; ClUint64T changeMask = 0; ClAmsCSIConfigT csiConfig; ClAmsCSINVPT nvp; // Grab the CSI object if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&csi,&pEntityConfig)) != CL_OK) { checkError("Get CSI configuration", rc); } memcpy(&csiConfig, pEntityConfig, sizeof(csiConfig)); clHeapFree(pEntityConfig); // Specify a unique CSI type changeMask |= CSI_CONFIG_TYPE; saNameSet(&csiConfig.type, CSI_TYPE_APP); csiConfig.type.length += 1; if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&csiConfig.entity,changeMask)) != CL_OK) { checkError("Set CSI type", rc); } // Set the name/value pairs saNameSet(&nvp.paramName,"activexml"); saNameSet(&nvp.paramValue,activeXml); if ((rc = clAmsMgmtCCBCSISetNVP(ccbHandle,&csi,&nvp)) != CL_OK) { checkError("Set CSI NVP", rc); } // Set the name/value pairs saNameSet(&nvp.paramName,"standbyxml"); saNameSet(&nvp.paramValue,standbyXml); if ((rc = clAmsMgmtCCBCSISetNVP(ccbHandle,&csi,&nvp)) != CL_OK) { checkError("Set CSI NVP", rc); } // Commit CSI if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK) { checkError("Commit CSI",rc); } } if (1) // Link the SI to the SG { if ((rc = clAmsMgmtCCBSetSGSIList(ccbHandle,&sg,&si)) != CL_OK) { checkError("Add SI to SG", rc); } if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) { checkError("Commit adding SI to SG", rc); } } /* * Unlock or start the SI */ if((rc = clAmsMgmtEntityUnlock(mgmtHandle, &si)) != CL_OK && CL_GET_ERROR_CODE(rc) != CL_ERR_NO_OP) { checkError("SI unlock failed", rc); } }
static ClRcT clAmsMgmtSGRedundancyModelEstimate(ClAmsSGRedundancyModelT model, ClAmsEntityT *sgName, ClUint32T numActiveSUs, ClUint32T numStandbySUs, ClInt32T *extraSIs, ClInt32T *extraSUs, ClInt32T *extraNodes) { ClRcT rc = CL_OK; ClAmsEntityConfigT *entityConfig = NULL; ClAmsSGConfigT sgConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClAmsEntityBufferT suBuffer = {0}; ClAmsEntityBufferT nodeBuffer = {0}; ClAmsEntityBufferT siBuffer = {0}; if(!sgName || !extraSIs || !extraSUs || !extraNodes) return CL_AMS_RC(CL_ERR_INVALID_PARAMETER); *extraSIs = 0, *extraSUs = 0, *extraNodes = 0; rc = clAmsMgmtEntityGetConfig(gHandle, sgName, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SG redundancy estimate -get config returned [%#x]", rc); goto out; } memcpy(&sgConfig, entityConfig, sizeof(sgConfig)); clHeapFree(entityConfig); if(sgConfig.numPrefActiveSUs < numActiveSUs) { rc = clAmsMgmtGetSGSIList(gHandle, sgName, &siBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg si list returned [%#x]", rc); goto out_free; } if(siBuffer.count < numActiveSUs) { *extraSIs = numActiveSUs - siBuffer.count; } } rc = clAmsMgmtGetSGSUList(gHandle, sgName, &suBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg su list returned [%#x]", rc); goto out_free; } if(suBuffer.count < numStandbySUs + numActiveSUs) { *extraSUs = (numStandbySUs + numActiveSUs)-suBuffer.count; *extraSIs *= sgConfig.maxActiveSIsPerSU; rc = clAmsMgmtGetNodeList(gHandle, &nodeBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS get node list returned [%#x]", rc); goto out_free; } if(nodeBuffer.count < numActiveSUs + numStandbySUs) { *extraNodes = (numActiveSUs + numStandbySUs) - nodeBuffer.count; } } rc = CL_OK; out_free: if(suBuffer.entity) clHeapFree(suBuffer.entity); if(nodeBuffer.entity) clHeapFree(nodeBuffer.entity); if(siBuffer.entity) clHeapFree(siBuffer.entity); out: return rc; }
static ClRcT clAmsMgmtSGMigrateMPlusN(ClAmsSGRedundancyModelT model, ClAmsEntityT *sgName, const ClCharT *prefix, ClUint32T numActiveSUs, ClUint32T numStandbySUs, ClAmsMgmtMigrateListT *migrateList) { ClUint32T i; ClRcT rc = CL_OK; ClAmsEntityBufferT siBuffer = {0}; ClAmsEntityBufferT suBuffer = {0}; ClAmsEntityBufferT nodeBuffer = {0}; ClInt32T extraSIs = 0; ClInt32T extraSUs = 0; ClInt32T extraNodes = 0; ClAmsEntityT *nodeList = NULL; ClAmsEntityT *nodes = NULL; ClAmsEntityT *sus = NULL; ClAmsEntityT *comps = NULL; ClAmsEntityT *sis = NULL; ClAmsEntityT *csis = NULL; ClInt32T numNodes = 0; ClAmsEntityConfigT *pSURefComp = NULL; ClAmsEntityConfigT *pSGRefSI = NULL; ClAmsEntityConfigT *pSIRefCSI = NULL; ClAmsEntityConfigT *pSGConfig = NULL; ClAmsSGConfigT sgConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClUint32T numSupportedCSITypes = 0; SaNameT *pNumSupportedCSITypes = NULL; ClAmsMgmtCCBHandleT ccbHandle = 0; ClAmsMgmtMigrateListT *unlockList = NULL; rc = clAmsMgmtEntityGetConfig(gHandle, sgName, &pSGConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SG [%.*s] config get returned [%#x]", sgName->name.length-1, sgName->name.value, rc); goto out; } memcpy(&sgConfig, pSGConfig, sizeof(sgConfig)); clHeapFree(pSGConfig); /* * If scaling down actives, ensure that those many service units are locked. */ if(numActiveSUs < sgConfig.numPrefActiveSUs) { ClInt32T numShrinkSUs = sgConfig.numPrefActiveSUs - numActiveSUs; ClAmsEntityBufferT suList = {0}; ClInt32T numOutOfServiceSUs = 0; rc = clAmsMgmtGetSGSUList(gHandle, sgName, &suList); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SG [%.*s] su list returned [%#x]", sgName->name.length-1, sgName->name.value, rc); goto out; } for(i = 0; i < suList.count; ++i) { ClAmsSUConfigT *pSUConfig = NULL; rc = clAmsMgmtEntityGetConfig(gHandle, suList.entity+i, (ClAmsEntityConfigT**)&pSUConfig); if(rc != CL_OK) { clHeapFree(suList.entity); clLogError("AMS", "MIGRATE", "SU [%.*s] get config returned [%#x]", suList.entity[i].name.length-1, suList.entity[i].name.value, rc); goto out; } if(pSUConfig->adminState == CL_AMS_ADMIN_STATE_LOCKED_A || pSUConfig->adminState == CL_AMS_ADMIN_STATE_LOCKED_I) { ++numOutOfServiceSUs; } clHeapFree(pSUConfig); } clHeapFree(suList.entity); if(numOutOfServiceSUs < numShrinkSUs) { clLogError("AMS", "MIGRATE", "Expected a minimum of [%d] SUs to be out of service to satisfy SG. " "redundancy model shrink. Got [%d] out of service", numShrinkSUs, numOutOfServiceSUs); rc = CL_AMS_RC(CL_AMS_ERR_INVALID_ENTITY_STATE); goto out; } } rc = clAmsMgmtSGRedundancyModelEstimate(model, sgName, numActiveSUs, numStandbySUs, &extraSIs, &extraSUs, &extraNodes); if(rc != CL_OK) { goto out; } rc = clAmsMgmtCCBInitialize(gHandle, &ccbHandle); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS ccb initialize returned [%#x]", rc); goto out; } /* * Add the existing SI CSI list to the supported list. */ rc = clAmsMgmtGetSGSIList(gHandle, sgName, &siBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg si list returned [%#x]", rc); goto out; } if(siBuffer.count) { rc = clAmsMgmtEntityGetConfig(gHandle, siBuffer.entity, &pSGRefSI); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS reference si get config returned [%#x]", rc); goto out_free; } } for(i = 0; i < siBuffer.count; ++i) { ClUint32T j; ClAmsEntityBufferT csiBuffer = {CL_AMS_ENTITY_TYPE_ENTITY}; ClAmsSIConfigT siConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClUint64T mask = 0; memcpy(&siConfig.entity, siBuffer.entity+i, sizeof(siConfig.entity)); mask |= SI_CONFIG_NUM_STANDBY_ASSIGNMENTS; siConfig.numStandbyAssignments = numStandbySUs; if(numActiveSUs > 1) siConfig.numStandbyAssignments = (numStandbySUs+1)&~1; siConfig.numStandbyAssignments = CL_MAX(1, siConfig.numStandbyAssignments/ (numActiveSUs?numActiveSUs:1)); /* * Update the num standby assignments. */ rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &siConfig.entity, mask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SI [%.*s] num standby set returned [%#x]", siConfig.entity.name.length-1, siConfig.entity.name.value, rc); } rc = clAmsMgmtGetSICSIList(gHandle, siBuffer.entity+i, &csiBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS get si csi list returned [%#x]", rc); goto out_free; } pNumSupportedCSITypes = (SaNameT*) clHeapRealloc(pNumSupportedCSITypes, (numSupportedCSITypes+csiBuffer.count)*sizeof(SaNameT)); for(j = 0; j < csiBuffer.count ; ++j) { ClAmsEntityConfigT *entityConfig = NULL; ClAmsCSIConfigT csiConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClUint32T k; rc = clAmsMgmtEntityGetConfig(gHandle, csiBuffer.entity+j, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS csi get config returned [%#x]", rc); goto out_free; } memcpy(&csiConfig, entityConfig, sizeof(csiConfig)); if(!pSIRefCSI) { pSIRefCSI = entityConfig; } else { clHeapFree(entityConfig); } /* * Search for this csi type in the list to see if its * already present */ for(k = 0; k < numSupportedCSITypes; ++k) { if(!memcmp(pNumSupportedCSITypes[k].value, csiConfig.type.value, pNumSupportedCSITypes[k].length)) break; } if(k == numSupportedCSITypes) { memcpy(pNumSupportedCSITypes+numSupportedCSITypes, &csiConfig.type, sizeof(csiConfig.type)); ++numSupportedCSITypes; } } clHeapFree(csiBuffer.entity); } if(extraSIs) { sis = (ClAmsEntityT*) clHeapCalloc(extraSIs, sizeof(ClAmsEntityT)); CL_ASSERT(sis != NULL); csis = (ClAmsEntityT*) clHeapCalloc(extraSIs, sizeof(ClAmsEntityT)); for(i = siBuffer.count; i < siBuffer.count + extraSIs; ++i) { ClAmsEntityT si ={CL_AMS_ENTITY_TYPE_ENTITY}; ClAmsEntityT csi = {CL_AMS_ENTITY_TYPE_ENTITY}; ClUint64T bitMask = 0; ClAmsSIConfigT siConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClAmsCSIConfigT csiConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; si.type = CL_AMS_ENTITY_TYPE_SI; snprintf((ClCharT*)si.name.value, sizeof(si.name.value)-1, "%s_%.*s_SI%d", prefix, sgName->name.length-1, (const ClCharT*)sgName->name.value, i); clLogNotice("AMS", "MIGRATE", "Creating SI [%s]", si.name.value); si.name.length = strlen((const ClCharT*)si.name.value)+1; rc = clAmsMgmtCCBEntityCreate(ccbHandle, &si); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS entity create returned [%#x]", rc); goto out_free; } memcpy(&sis[i-siBuffer.count], &si, sizeof(si)); rc = clAmsMgmtCCBSetSGSIList(ccbHandle, sgName, &si); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS set sg silist returned [%#x]", rc); goto out_free; } if(pSGRefSI) { /* * Set config to the base SI. */ bitMask = CL_AMS_CONFIG_ATTR_ALL; memcpy(&siConfig, pSGRefSI, sizeof(siConfig)); memcpy(&siConfig.entity, &si, sizeof(siConfig.entity)); siConfig.numStandbyAssignments = numStandbySUs; if(numActiveSUs > 1 ) siConfig.numStandbyAssignments = (numStandbySUs+1)&~1; siConfig.numStandbyAssignments = CL_MAX(1,siConfig.numStandbyAssignments/ (numActiveSUs?numActiveSUs:1)); siConfig.numCSIs = 1; siConfig.adminState = CL_AMS_ADMIN_STATE_LOCKED_A; rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &siConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS entity set config returned [%#x]", rc); goto out_free; } } csi.type = CL_AMS_ENTITY_TYPE_CSI; snprintf((ClCharT*)csi.name.value, sizeof(csi.name.value), "%s_CSI%d", (const ClCharT*)si.name.value, i-siBuffer.count); csi.name.length = strlen((const ClCharT*)csi.name.value)+1; clLogNotice("AMS", "MIGRATE", "Creating CSI [%s]", csi.name.value); rc = clAmsMgmtCCBEntityCreate(ccbHandle, &csi); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS csi create returned [%#x]", rc); goto out_free; } memcpy(&csis[i-siBuffer.count], &csi, sizeof(csi)); rc = clAmsMgmtCCBSetSICSIList(ccbHandle, &si, &csi); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SET si csi list returned [%#x]", rc); goto out_free; } if(pSIRefCSI) { /* * Load the config. for the base csi type. */ memcpy(&csiConfig, pSIRefCSI, sizeof(csiConfig)); memcpy(&csiConfig.entity, &csi, sizeof(csiConfig.entity)); csiConfig.isProxyCSI = CL_FALSE; memcpy(&csiConfig.type, &csiConfig.entity.name, sizeof(csiConfig.type)); bitMask = CL_AMS_CONFIG_ATTR_ALL; rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &csiConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS ref csi set config returned [%#x]", rc); goto out_free; } } /* * Add this to the supported list. */ pNumSupportedCSITypes = (SaNameT*) clHeapRealloc(pNumSupportedCSITypes, (numSupportedCSITypes+1)*sizeof(SaNameT)); CL_ASSERT(pNumSupportedCSITypes != NULL); memcpy(pNumSupportedCSITypes+numSupportedCSITypes, &csi.name, sizeof(SaNameT)); ++numSupportedCSITypes; } } if(extraNodes) { nodes = (ClAmsEntityT*) clHeapCalloc(extraNodes, sizeof(ClAmsEntityT)); CL_ASSERT(nodes != NULL); rc = clAmsMgmtGetNodeList(gHandle, &nodeBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS get node list returned [%#x]", rc); goto out_free; } for(i = nodeBuffer.count ; i < nodeBuffer.count + extraNodes; ++i) { ClAmsEntityT node = {CL_AMS_ENTITY_TYPE_ENTITY}; node.type = CL_AMS_ENTITY_TYPE_NODE; snprintf((ClCharT*) node.name.value, sizeof(node.name.value), "%s_Node%d", prefix, i); node.name.length = strlen((const ClCharT*) node.name.value) + 1; clLogNotice("AMS", "MIGRATE", "Creating node [%s]", node.name.value); rc = clAmsMgmtCCBEntityCreate(ccbHandle, &node); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS ccb create returned [%#x]", rc); goto out_free; } memcpy(&nodes[i-nodeBuffer.count], &node, sizeof(node)); } } rc = clAmsMgmtGetSGSUList(gHandle, sgName, &suBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Get SG su list returned [%#x]", rc); goto out_free; } for(i = 0 ; i < suBuffer.count; ++i) { ClUint32T j; ClAmsEntityBufferT compBuffer= { 0 } ; rc = clAmsMgmtGetSUCompList(gHandle, &suBuffer.entity[i], &compBuffer); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Get SU comp list returned [%#x]", rc); goto out_free; } /* * Get the first component properties. */ if(!pSURefComp) { rc = clAmsMgmtEntityGetConfig(gHandle, compBuffer.entity, &pSURefComp); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS base comp get config returned [%#x]", rc); goto out_free; } } /* * Update all config. with supported csi types. * and correct comp config whereever appropriate */ for(j = 0; j < compBuffer.count; ++j) { ClAmsEntityConfigT *entityConfig =NULL; ClAmsCompConfigT compConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClUint64T bitMask = 0; ClUint32T k ; rc = clAmsMgmtEntityGetConfig(gHandle, compBuffer.entity+j, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS comp get config returned [%#x]", rc); goto out_free; } memcpy(&compConfig, entityConfig, sizeof(compConfig)); clHeapFree(entityConfig); /* * update supported CSI type incase of SI additions. */ if(extraSIs) { bitMask |= COMP_CONFIG_SUPPORTED_CSI_TYPE; compConfig.pSupportedCSITypes = (SaNameT*) clHeapRealloc(compConfig.pSupportedCSITypes, (compConfig.numSupportedCSITypes + extraSIs)* sizeof(SaNameT)); CL_ASSERT(compConfig.pSupportedCSITypes); for(k = compConfig.numSupportedCSITypes; k < compConfig.numSupportedCSITypes + extraSIs; ++k) { memcpy(compConfig.pSupportedCSITypes+k, &csis[k-compConfig.numSupportedCSITypes].name, sizeof(SaNameT)); } compConfig.numSupportedCSITypes += extraSIs; } bitMask |= COMP_CONFIG_NUM_MAX_STANDBY_CSIS; /* * take active to standby ratio */ compConfig.numMaxStandbyCSIs = numActiveSUs; if(numStandbySUs > 1 ) compConfig.numMaxStandbyCSIs = (numActiveSUs+1)&~1; compConfig.numMaxStandbyCSIs = CL_MAX(1, compConfig.numMaxStandbyCSIs/ (numStandbySUs?numStandbySUs:1)); rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &compConfig.entity, bitMask); clHeapFree(compConfig.pSupportedCSITypes); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS entity set config returned [%#x]", rc); goto out_free; } } clHeapFree(compBuffer.entity); } if(extraSUs) { sus = (ClAmsEntityT*) clHeapCalloc(extraSUs, sizeof(ClAmsEntityT)); CL_ASSERT(sus != NULL); comps = (ClAmsEntityT*) clHeapCalloc(extraSUs, sizeof(ClAmsEntityT)); CL_ASSERT(comps != NULL); nodeList = (ClAmsEntityT*) clHeapCalloc(extraSUs + extraNodes, sizeof(ClAmsEntityT)); CL_ASSERT(nodeList != NULL); rc = clAmsMgmtGetSUFreeNodes(sgName, prefix, extraSUs, extraNodes, nodeList, &numNodes); for(i = suBuffer.count; i < suBuffer.count + extraSUs; ++i) { ClAmsEntityT su = {CL_AMS_ENTITY_TYPE_ENTITY}; ClAmsEntityT comp = {CL_AMS_ENTITY_TYPE_ENTITY}; ClAmsSUConfigT suConfig = { { CL_AMS_ENTITY_TYPE_ENTITY } } ; ClAmsCompConfigT compConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClUint64T bitMask = 0; su.type = CL_AMS_ENTITY_TYPE_SU; snprintf((ClCharT*)su.name.value, sizeof(su.name.value), "%s_%s_SU%d", prefix, (const ClCharT*)nodeList[i-suBuffer.count].name.value, i); su.name.length = strlen((const ClCharT*)su.name.value)+1; clLogNotice("AMS", "MIGRATE", "Creating SU [%s]", su.name.value); rc = clAmsMgmtCCBEntityCreate(ccbHandle, &su); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SU create returned [%#x]", rc); goto out_free; } memcpy(&sus[i-suBuffer.count], &su, sizeof(su)); /* * Assign this SU under the parent node and SG */ rc = clAmsMgmtCCBSetNodeSUList(ccbHandle, &nodeList[i-suBuffer.count], &su); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Node su list set returned [%#x]", rc); goto out_free; } /* * Give the parent SG. for this SU */ rc = clAmsMgmtCCBSetSGSUList(ccbHandle, sgName, &su); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Set SG su list returned [%#x]", rc); goto out_free; } bitMask = SU_CONFIG_NUM_COMPONENTS; memcpy(&suConfig.entity, &su, sizeof(suConfig.entity)); suConfig.numComponents = 1; rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &suConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "SU set config returned [%#x]", rc); goto out_free; } comp.type = CL_AMS_ENTITY_TYPE_COMP; snprintf((ClCharT*) comp.name.value, sizeof(comp.name.value), "%s_Comp%d", su.name.value, i - suBuffer.count); comp.name.length = strlen((const ClCharT*) comp.name.value) + 1; clLogNotice("AMS", "MIGRATE", "Creating component [%s]", comp.name.value); rc = clAmsMgmtCCBEntityCreate(ccbHandle, &comp); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "Comp create returned [%#x]", rc); goto out_free; } memcpy(&comps[i-suBuffer.count], &comp, sizeof(comp)); rc = clAmsMgmtCCBSetSUCompList(ccbHandle, &su, &comp); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS set su comp list returned [%#x]", rc); goto out_free; } if(pSURefComp) { /* * At this stage, we have created the hierarchy. * Set the comp property to the base component type and * add the num supported CSI types to be part of every component * added to the SU. */ bitMask = CL_AMS_CONFIG_ATTR_ALL; memcpy(&compConfig, pSURefComp, sizeof(compConfig)); memcpy(&compConfig.entity, &comp, sizeof(compConfig.entity)); compConfig.numSupportedCSITypes = numSupportedCSITypes; compConfig.pSupportedCSITypes = pNumSupportedCSITypes; memcpy(&compConfig.parentSU.entity, &su, sizeof(compConfig.parentSU.entity)); /* * Distribute the standbys based on the active/standby ratio. */ compConfig.numMaxStandbyCSIs = numActiveSUs; if(numStandbySUs > 1 ) compConfig.numMaxStandbyCSIs = (numActiveSUs+1)&~1; compConfig.numMaxStandbyCSIs = CL_MAX(1, compConfig.numMaxStandbyCSIs/ (numStandbySUs?numStandbySUs:1)); rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &compConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS set config returned [%#x]", rc); goto out_free; } } } } /* * At this stage, we are all set to commit. after updating SG config. */ { ClUint64T bitMask = 0; bitMask |= SG_CONFIG_REDUNDANCY_MODEL; sgConfig.redundancyModel = model; sgConfig.numPrefActiveSUs = numActiveSUs; bitMask |= SG_CONFIG_NUM_PREF_ACTIVE_SUS; sgConfig.numPrefStandbySUs = numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_STANDBY_SUS; if(sgConfig.numPrefInserviceSUs < numActiveSUs + numStandbySUs) { sgConfig.numPrefInserviceSUs = numActiveSUs + numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_INSERVICE_SUS; } sgConfig.numPrefAssignedSUs = numActiveSUs + numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_ASSIGNED_SUS; /* * Active standby ratio. */ sgConfig.maxStandbySIsPerSU = numActiveSUs; if(numStandbySUs > 1 ) sgConfig.maxStandbySIsPerSU = (numActiveSUs+1)&~1; sgConfig.maxStandbySIsPerSU = CL_MAX(1,sgConfig.maxStandbySIsPerSU/ (numStandbySUs?numStandbySUs:1)); bitMask |= SG_CONFIG_MAX_STANDBY_SIS_PER_SU; rc = clAmsMgmtCCBEntitySetConfig(ccbHandle, &sgConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg set config returned [%#x]", rc); goto out_free; } } rc = clAmsMgmtCCBCommit(ccbHandle); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS database commit returned [%#x]", rc); } /* * Okay, the commit is successful. Now unlock all added entities * except SU so that other attributes could be updated before unlocking * Do that in a separate thread as there could be pending invocations. */ unlockList = (ClAmsMgmtMigrateListT*) clHeapCalloc(1, sizeof(*unlockList)); CL_ASSERT(unlockList != NULL); unlockList->si.count = extraSIs; unlockList->node.count = extraNodes; unlockList->su.count = extraSUs; unlockList->si.entity = (ClAmsEntityT*) clHeapCalloc(extraSIs, sizeof(*sis)); unlockList->node.entity = (ClAmsEntityT*) clHeapCalloc(extraNodes, sizeof(*nodes)); unlockList->su.entity = (ClAmsEntityT*) clHeapCalloc(extraSUs, sizeof(*sus)); CL_ASSERT(unlockList->si.entity && unlockList->node.entity && unlockList->su.entity); memcpy(unlockList->si.entity, sis, sizeof(*sis)*extraSIs); memcpy(unlockList->node.entity, nodes, sizeof(*nodes)*extraNodes); memcpy(unlockList->su.entity, sus, sizeof(*sus) * extraSUs); clOsalTaskCreateDetached("MIGRATE-UNLOCK-THREAD", CL_OSAL_SCHED_OTHER, 0, 0, clAmsMgmtMigrateListUnlock, (void*)unlockList); /* * Return the newly created info. in the migrated list. */ if(migrateList) { if(extraSIs) { migrateList->si.count = extraSIs; migrateList->si.entity = sis; migrateList->csi.count = extraSIs; migrateList->csi.entity = csis; sis = csis = NULL; } if(extraNodes) { migrateList->node.count = extraNodes; migrateList->node.entity = nodes; nodes = NULL; } if(extraSUs) { migrateList->su.count = extraSUs; migrateList->su.entity = sus; migrateList->comp.count = extraSUs; migrateList->comp.entity = comps; sus = comps = NULL; } } out_free: clAmsMgmtCCBFinalize(ccbHandle); if(siBuffer.entity) clHeapFree(siBuffer.entity); if(nodeBuffer.entity) clHeapFree(nodeBuffer.entity); if(suBuffer.entity) clHeapFree(suBuffer.entity); if(nodeList) clHeapFree(nodeList); if(nodes) clHeapFree(nodes); if(sus) clHeapFree(sus); if(comps) clHeapFree(comps); if(sis) clHeapFree(sis); if(csis) clHeapFree(csis); if(pSGRefSI) clHeapFree(pSGRefSI); if(pSIRefCSI) clHeapFree(pSIRefCSI); if(pSURefComp) clHeapFree(pSURefComp); if(pNumSupportedCSITypes) clHeapFree(pNumSupportedCSITypes); out: return rc; }
static ClRcT clAmsMgmtSGRedundancyModelNoRedundancy(ClAmsSGRedundancyModelT model, const ClCharT *sg, const ClCharT *prefix, ClUint32T numActiveSUs, ClUint32T numStandbySUs, ClAmsMgmtMigrateListT *migrateList) { ClAmsSGConfigT sgConfig = {{CL_AMS_ENTITY_TYPE_ENTITY}}; ClAmsEntityConfigT *entityConfig = NULL; ClRcT rc = CL_OK; ClAmsEntityT sgName = {CL_AMS_ENTITY_TYPE_ENTITY}; ClUint64T bitMask = 0; sgName.type = CL_AMS_ENTITY_TYPE_SG; saNameSet(&sgName.name, sg); ++sgName.name.length; rc = clAmsMgmtEntityGetConfig(gHandle, &sgName, &entityConfig); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS entity get config returned [%#x]", rc); goto out; } memcpy(&sgConfig, entityConfig, sizeof(sgConfig)); clHeapFree(entityConfig); if(sgConfig.redundancyModel == CL_AMS_SG_REDUNDANCY_MODEL_NONE) { clLogWarning("AMS", "MIGRATE", "Redundancy model is already no redundancy"); goto out; } bitMask |= SG_CONFIG_REDUNDANCY_MODEL; sgConfig.redundancyModel = CL_AMS_SG_REDUNDANCY_MODEL_NONE; bitMask |= SG_CONFIG_NUM_PREF_ACTIVE_SUS_PER_SI; sgConfig.numPrefActiveSUsPerSI = 1; bitMask |= SG_CONFIG_NUM_PREF_ACTIVE_SUS; sgConfig.numPrefActiveSUs = numActiveSUs; bitMask |= SG_CONFIG_NUM_PREF_STANDBY_SUS; sgConfig.numPrefStandbySUs = numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_INSERVICE_SUS; sgConfig.numPrefInserviceSUs = numActiveSUs + numStandbySUs; bitMask |= SG_CONFIG_NUM_PREF_ASSIGNED_SUS; sgConfig.numPrefAssignedSUs = numActiveSUs + numStandbySUs; rc = clAmsMgmtCCBEntitySetConfig(gCcbHandle, &sgConfig.entity, bitMask); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS sg set config returned [%#x]", rc); goto out; } rc = clAmsMgmtCCBCommit(gCcbHandle); if(rc != CL_OK) { clLogError("AMS", "MIGRATE", "AMS database commit returned [%#x]", rc); goto out; } out: return rc; }
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 ClRcT clAmsCSIRecovery(ClAmsEntityT *pEntity, ClAmsThresholdT *pThreshold) { ClRcT rc= CL_OK; ClAmsEntityConfigT *pEntityConfig = NULL; ClAmsCSIConfigT *pCSIConfig = NULL; clLogNotice("TRIGGER", "RECOVERY", "Getting CSI config for [%.*s]", pEntity->name.length-1, pEntity->name.value); rc = clAmsMgmtEntityGetConfig(gClAmsEntityTriggerMgmtHandle, pEntity, &pEntityConfig); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Entity get config for CSI returned [%#x]", rc); goto out; } pCSIConfig = (ClAmsCSIConfigT*)pEntityConfig; if(pThreshold->recoveryReset == CL_TRUE) { clLogNotice("RECOVERY", "RESET", "Unlocking SI [%.*s]", pCSIConfig->parentSI.entity.name.length-1, pCSIConfig->parentSI.entity.name.value); rc = clAmsMgmtEntityUnlock(gClAmsEntityTriggerMgmtHandle, &pCSIConfig->parentSI.entity); if(rc != CL_OK) { clLogError("RECOVERY", "RESET", "Unlock returned [%#x]", rc); } goto out_free; } switch(pThreshold->recovery) { case CL_AMS_ENTITY_RECOVERY_FAILOVER: case CL_AMS_ENTITY_RECOVERY_LOCK: clLogNotice("TRIGGER", "RECOVERY", "Switching over work for SI [%.*s] as part of [%s] threshold recovery", pCSIConfig->parentSI.entity.name.length-1, pCSIConfig->parentSI.entity.name.value, CL_METRIC_STR(pThreshold->metric.id)); rc = clAmsMgmtEntityLockAssignment(gClAmsEntityTriggerMgmtHandle, &pCSIConfig->parentSI.entity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Switching over SI returned [%#x]", rc); goto out_free; } break; default: break; } out_free: clHeapFree(pEntityConfig); out: return rc; }
static ClRcT clAmsCompRecovery(ClAmsEntityT *pEntity, ClAmsThresholdT *pThreshold) { ClAmsEntityConfigT *pEntityConfig = NULL; ClAmsCompConfigT *pCompConfig = NULL; ClRcT rc = CL_OK; if(pEntity->type == CL_AMS_ENTITY_TYPE_SU) { ClAmsEntityBufferT compBuffer = {0}; rc = clAmsMgmtGetSUCompList(gClAmsEntityTriggerMgmtHandle, pEntity, &compBuffer); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "SU [%.*s] get comp list returned [%#x]", pEntity->name.length-1, pEntity->name.value, rc); goto out; } if(!compBuffer.count) { clLogNotice("TRIGGER", "RECOVERY", "SU doesnt have components. Locking SU"); rc = clAmsMgmtEntityLockAssignment(gClAmsEntityTriggerMgmtHandle, pEntity); if(compBuffer.entity) clHeapFree(compBuffer.entity); goto out_free; } /* * Now overwrite the entity with first comp. */ memcpy(pEntity, &compBuffer.entity[0], sizeof(*pEntity)); clHeapFree(compBuffer.entity); } clLogNotice("TRIGGER", "RECOVERY", "Getting comp config for [%.*s]", pEntity->name.length-1, pEntity->name.value); rc = clAmsMgmtEntityGetConfig(gClAmsEntityTriggerMgmtHandle, pEntity, &pEntityConfig); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Entity get config returned [%#x]", rc); goto out; } pCompConfig = (ClAmsCompConfigT*)pEntityConfig; if(pThreshold->recoveryReset == CL_TRUE) { if(pThreshold->recovery == CL_AMS_ENTITY_RECOVERY_FAILOVER) { /* *Try repairing. */ rc = clAmsMgmtEntityRepaired(gClAmsEntityTriggerMgmtHandle, &pCompConfig->parentSU.entity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Repair didn't work. Trying lock assignment first"); rc = clAmsMgmtEntityLockAssignment(gClAmsEntityTriggerMgmtHandle, &pCompConfig->parentSU.entity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Lockassignment didn't work. Trying unlock as a last resort"); } } } clLogNotice("TRIGGER", "RECOVERY", "Recoverying SU [%.*s] through unlock", pCompConfig->parentSU.entity.name.length-1, pCompConfig->parentSU.entity.name.value); rc = clAmsMgmtEntityUnlock(gClAmsEntityTriggerMgmtHandle, &pCompConfig->parentSU.entity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY RESET", "Unlock for entity [%.*s] returned [%#x]", pCompConfig->parentSU.entity.name.length-1, pCompConfig->parentSU.entity.name.value, rc); } goto out_free; } switch(pThreshold->recovery) { case CL_AMS_ENTITY_RECOVERY_RESTART: clLogNotice("TRIGGER", "RECOVERY", "Restarting comp [%.*s] as part of [%s] recovery", pEntity->name.length-1, pEntity->name.value, CL_METRIC_STR(pThreshold->metric.id)); rc = clAmsMgmtEntityRestart(gClAmsEntityTriggerMgmtHandle, pEntity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "Comp restart returned with [%#x]", rc); goto out_free; } break; case CL_AMS_ENTITY_RECOVERY_FAILOVER: /* * We trigger a fault to AMS with a recommended recovery. */ clAmsTriggerFault(pEntity, CL_AMS_RECOVERY_COMP_FAILOVER); break; case CL_AMS_ENTITY_RECOVERY_LOCK: /* * Graceful lock of the SU */ clLogNotice("TRIGGER", "RECOVERY", "Locking work for parent SU [%.*s] as part of [%s] recovery", pCompConfig->parentSU.entity.name.length-1, pCompConfig->parentSU.entity.name.value, CL_METRIC_STR(pThreshold->metric.id)); rc = clAmsMgmtEntityLockAssignment(gClAmsEntityTriggerMgmtHandle, &pCompConfig->parentSU.entity); if(rc != CL_OK) { clLogError("TRIGGER", "RECOVERY", "SU work switchover returned [%#x]", rc); goto out_free; } break; default: break; } out_free: if(pCompConfig->pSupportedCSITypes) clHeapFree(pCompConfig->pSupportedCSITypes); clHeapFree(pCompConfig); out: return rc; }