void removeNode(const char* safName)
{
  ClRcT rc;
  ClAmsEntityConfigT entity;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&entity,safName,CL_AMS_ENTITY_TYPE_NODE);

  entityStop(entity);

  ClCpmSlotInfoT slotInfo;  
  saNameSet(&slotInfo.nodeName,safName);
  if ((rc = clCpmSlotGet(CL_CPM_NODENAME, &slotInfo))  != CL_OK) checkError("Get node address",rc);
  
  if ((rc = clCpmNodeShutDown(slotInfo.nodeIocAddress))  != CL_OK) checkError("shutdown ASP on node",rc);

  ClAmsNodeStatusT* ns;

  bool done = false;
  do
    {
      ns = clAmsMgmtNodeGetStatus( mgmtHandle ,safName);
      sleep(1);
      if (!ns) done = true;
      else
        {
          if (ns->isClusterMember == CL_AMS_NODE_IS_NOT_CLUSTER_MEMBER) done=true;
          clHeapFree(ns);
        }
    } while (!done);

  if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&entity))  != CL_OK) checkError("Delete node",rc);      
  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of node", rc);
}
    // Stop this app container from running on these nodes (1+N redundancy)
void acRetract(const char* appCnt, const char* nodeNames[], int numNodes,const char* nameModifier)
{
  ClRcT rc;
  ClAmsEntityConfigT su;
  ClAmsEntityConfigT comp;
  char eName[SA_MAX_NAME_LENGTH];

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();

  strncpy(eName,appCnt,SA_MAX_NAME_LENGTH-1);
  eName[SA_MAX_NAME_LENGTH-1] = 0;
  if (nameModifier != NULL)
    {
      strncat(eName,nameModifier,SA_MAX_NAME_LENGTH-1);
      eName[SA_MAX_NAME_LENGTH-1] = 0;
    }

  
  for (int i=0;i<numNodes;i++)
    {
      initEntity(&su,eName,CL_AMS_ENTITY_TYPE_SU,nodeNames[i]);
      entityStop(su);
      initEntity(&comp,eName,CL_AMS_ENTITY_TYPE_COMP,nodeNames[i]);
      // comps are implicitly started/stopped when SU is
      //entityStop(comp);

      if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&comp))  != CL_OK) checkError("Delete COMP",rc);
      if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&su))  != CL_OK) checkError("Delete SU",rc);      
    }

  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of COMP/SU", rc);
}
void removeAppCnt(const char* name)
{
  ClRcT rc;
  ClAmsEntityConfigT sg;

  // Create the SG object
  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&sg,name,CL_AMS_ENTITY_TYPE_SG);
  entityStop(sg);
    
  if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&sg))  != CL_OK) checkError("Delete SG",rc);
  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of SG", rc);
}
    // Remove an application from this container.
    // The effect of this is to delete the SAF Service Instance that represents this
    // application
void acRemoveApp(const char* appCnt, const char* appName)
{
  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);

  entityStop(si);
  entityStop(csi);
  
  if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&csi))  != CL_OK) checkError("Delete CSI",rc);
  if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&si))  != CL_OK) checkError("Delete SI",rc);      
  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of SI/CSI", rc);
}
Beispiel #5
0
eventNotify_t::eventNotify_t(QObject* p) : QObject(p), m_handle(nullptr), m_notify(nullptr), m_dll(nullptr), m_stop(false)
{
	DWORD status = ERROR_SUCCESS;

	qRegisterMetaType< eventLogEntry_t::log_ptr_t >();

	if (false == initHandles()) {
		emit errorMessage("Error in eventNotify_t::eventNotify_t()", "Error while initializing event log handles", true);
		throw std::runtime_error("eventNotify_t::eventNotify_t(): Error while initializing event log handles");
	}

	status = seekToLastRecord();

	if (ERROR_SUCCESS != status) {
		emit errorMessage("Error in eventNotify_t::eventNotify_t()", "Error while seeking to the end of the event log stream", true);
		throw std::runtime_error("eventNotify_t::eventNotify_t(): Error while seeking to the end of the event log stream");
	}
	
	return;
}
    // Stop this app container from running on these nodes (1+N redundancy)
void acRetract(const char* appCnt, const char* nodeName,const char* compName)
{
  ClRcT rc;
  ClAmsEntityConfigT su;
  ClAmsEntityConfigT comp;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  
  if (1)
    {
      initEntity(&su,compName,CL_AMS_ENTITY_TYPE_SU);
      entityStop(su);
      initEntity(&comp,compName,CL_AMS_ENTITY_TYPE_COMP);
      // Comps are implicitly stopped when SU is stopped
      //entityStop(comp);

      if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&comp))  != CL_OK) checkError("Delete COMP",rc);
      if ((rc = clAmsMgmtCCBEntityDelete(ccbHandle,&su))  != CL_OK) checkError("Delete SU",rc);      
    }

  if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK) checkError("Committing deletion of COMP/SU", rc);
}
// Create a new Node in the AMF
void addNode(const char* safName)
{
  ClRcT rc;
  ClAmsEntityConfigT entity;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&entity,safName,CL_AMS_ENTITY_TYPE_NODE);
  

  if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&entity)) != CL_OK)
    {
      checkError("Create node",rc);
    }
  
  
  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Commit create node",rc);
    }

  entityStart(entity);  
}
Beispiel #8
0
bool GFXGLShader::_init()
{
   // Don't initialize empty shaders.
   if ( mVertexFile.isEmpty() && mPixelFile.isEmpty() )
      return false;

   clearShaders();

   mProgram = glCreateProgram();
   
   // Set the macros and add the global ones.
   Vector<GFXShaderMacro> macros;
   macros.merge( mMacros );
   macros.merge( smGlobalMacros );

   // Add the shader version to the macros.
   const U32 mjVer = (U32)mFloor( mPixVersion );
   const U32 mnVer = (U32)( ( mPixVersion - F32( mjVer ) ) * 10.01f );
   macros.increment();
   macros.last().name = "TORQUE_SM";
   macros.last().value = String::ToString( mjVer * 10 + mnVer );

   // Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
   bool compiledVertexShader = true;
   bool compiledPixelShader = true;
   
   // Compile the vertex and pixel shaders if specified.
   if(!mVertexFile.isEmpty())
      compiledVertexShader = initShader(mVertexFile, true, macros);
   if(!mPixelFile.isEmpty())
      compiledPixelShader = initShader(mPixelFile, false, macros);
      
   // If either shader was present and failed to compile, bail.
   if(!compiledVertexShader || !compiledPixelShader)
      return false;

   // Link it!
   glLinkProgram( mProgram );

   GLint linkStatus;
   glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus );
   
   // Dump the info log to the console
   U32 logLength = 0;
   glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
   if ( logLength )
   {
      FrameAllocatorMarker fam;
      char* log = (char*)fam.alloc( logLength );
      glGetProgramInfoLog( mProgram, logLength, NULL, log );

      if ( linkStatus == GL_FALSE )
      {
         if ( smLogErrors )
         {
            Con::errorf( "GFXGLShader::init - Error linking shader!" );
            Con::errorf( "Program %s / %s: %s", 
                mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
         }
      }
      else if ( smLogWarnings )
      {
         Con::warnf( "Program %s / %s: %s", 
             mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
      }
   }

   // If we failed to link, bail.
   if ( linkStatus == GL_FALSE )
      return false;

   initConstantDescs();   
   initHandles();
   
   // Notify Buffers we might have changed in size. 
   // If this was our first init then we won't have any activeBuffers 
   // to worry about unnecessarily calling.
   Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
   for ( ; biter != mActiveBuffers.end(); biter++ )   
      ((GFXGLShaderConstBuffer*)(*biter))->onShaderReload( this );
   
   return true;
}
Beispiel #9
0
bool GFXGLShader::_init()
{
   PROFILE_SCOPE(GFXGLShader_Init);
   // Don't initialize empty shaders.
   if ( mVertexFile.isEmpty() && mPixelFile.isEmpty() )
      return false;

   clearShaders();

   mProgram = glCreateProgram();
   
   // Set the macros and add the global ones.
   Vector<GFXShaderMacro> macros;
   macros.merge( mMacros );
   macros.merge( smGlobalMacros );

   // Add the shader version to the macros.
   const U32 mjVer = (U32)mFloor( mPixVersion );
   const U32 mnVer = (U32)( ( mPixVersion - F32( mjVer ) ) * 10.01f );
   macros.increment();
   macros.last().name = "TORQUE_SM";
   macros.last().value = String::ToString( mjVer * 10 + mnVer );
   macros.increment();
   macros.last().name = "TORQUE_VERTEX_SHADER";
   macros.last().value = "";   

   // Default to true so we're "successful" if a vertex/pixel shader wasn't specified.
   bool compiledVertexShader = true;
   bool compiledPixelShader = true;
   
   // Compile the vertex and pixel shaders if specified.
   if(!mVertexFile.isEmpty())
      compiledVertexShader = initShader(mVertexFile, true, macros);

   macros.last().name = "TORQUE_PIXEL_SHADER";
   if(!mPixelFile.isEmpty())
      compiledPixelShader = initShader(mPixelFile, false, macros);
      
   // If either shader was present and failed to compile, bail.
   if(!compiledVertexShader || !compiledPixelShader)
      return false;

   //bind vertex attributes
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Position,    "vPosition");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Normal,      "vNormal");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Color,       "vColor");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Tangent,     "vTangent");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TangentW,    "vTangentW");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_Binormal,    "vBinormal");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord0,   "vTexCoord0");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord1,   "vTexCoord1");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord2,   "vTexCoord2");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord3,   "vTexCoord3");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord4,   "vTexCoord4");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord5,   "vTexCoord5");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord6,   "vTexCoord6");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord7,   "vTexCoord7");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord8,   "vTexCoord8");
   glBindAttribLocation(mProgram, Torque::GL_VertexAttrib_TexCoord9,   "vTexCoord9");

   //bind fragment out color
   glBindFragDataLocation(mProgram, 0, "OUT_col");
   glBindFragDataLocation(mProgram, 1, "OUT_col1");
   glBindFragDataLocation(mProgram, 2, "OUT_col2");
   glBindFragDataLocation(mProgram, 3, "OUT_col3");

   // Link it!
   glLinkProgram( mProgram );

   GLint linkStatus;
   glGetProgramiv( mProgram, GL_LINK_STATUS, &linkStatus );
   
   // Dump the info log to the console
   U32 logLength = 0;
   glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, (GLint*)&logLength);
   if ( logLength )
   {
      FrameAllocatorMarker fam;
      char* log = (char*)fam.alloc( logLength );
      glGetProgramInfoLog( mProgram, logLength, NULL, log );

      if ( linkStatus == GL_FALSE )
      {
         if ( smLogErrors )
         {
            Con::errorf( "GFXGLShader::init - Error linking shader!" );
            Con::errorf( "Program %s / %s: %s", 
                mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
         }
      }
      else if ( smLogWarnings )
      {
         Con::warnf( "Program %s / %s: %s", 
             mVertexFile.getFullPath().c_str(), mPixelFile.getFullPath().c_str(), log);
      }
   }

   // If we failed to link, bail.
   if ( linkStatus == GL_FALSE )
      return false;

   initConstantDescs();   
   initHandles();
   
   // Notify Buffers we might have changed in size. 
   // If this was our first init then we won't have any activeBuffers 
   // to worry about unnecessarily calling.
   Vector<GFXShaderConstBuffer*>::iterator biter = mActiveBuffers.begin();
   for ( ; biter != mActiveBuffers.end(); biter++ )   
      ((GFXGLShaderConstBuffer*)(*biter))->onShaderReload( this );
   
   return true;
}
// 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);
}
// 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);
    }
}