ClRcT clLogClientUninstall(void)
{
    ClEoExecutionObjT* pEoObj = NULL;
    ClRcT rc = CL_OK;

    rc = clEoMyEoObjectGet(&pEoObj);
    if (CL_OK != rc)
    {
        return rc;
    }
    rc = clOsalTaskKeyDelete(LogidlSyncKey);
    if (CL_OK != rc)
    {
        return rc;
    }
    rc = clHandleDatabaseDestroy(LogidlDatabaseHdl);
    if (CL_OK != rc)
    {
        return rc;
    }

    clEoClientUninstallTables(pEoObj,CL_EO_SERVER_SYM_MOD(gAspFuncTable,Log));

    return rc;
}
/**
 * This is a finalization API for transaction agent. This API must be called
 * during finalization of EO.
 */
ClRcT clTxnAgentFinalize()
{
    ClRcT rc = CL_OK;
    ClEoExecutionObjT   *pEOObj;


    CL_FUNC_ENTER();
    /* - Release all allocated memeory 
       FIXME: Check for active transaction, and try to consolidate
    */

    if (clTxnAgntCfg != NULL)
    {
        clTxnDbFini(clTxnAgntCfg->activeTxnMap);

        clCntDelete(clTxnAgntCfg->compServiceMap);
        clTxnMutexDelete(clTxnAgntCfg->actMtx);
        clHeapFree(clTxnAgntCfg);

        clTxnCommIfcFini();

        rc = clEoMyEoObjectGet(&pEOObj);
        clEoClientUninstallTables(pEOObj, 
                                 CL_EO_SERVER_SYM_MOD(gAspFuncTable, TXNAgent));

        clTxnAgntCfg = NULL;
    }
    CL_TXN_RETURN_RC(rc, ("Failed to finalize transaction-agent rc:0x%x\n", rc));
}
/*
 * This function clean up the information which is it has 
 * 1. Deregister with CPM. 
 * 2. Deregister with debug. 
 * 3. Deregister with CKPT
 * 4. Release the resources like Handle Databases, etc.
 */
ClRcT clEvtFinalize()
{
    ClRcT rc = CL_OK;


    CL_FUNC_ENTER();

    CL_EVT_INIT_DONE_VALIDATION();

    rc = clEoClientUninstallTables(gEvtHead.evtEOId, CL_EO_SERVER_SYM_MOD(gAspFuncTable, EVT));  
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: EO Client Uninstall failed [0x%X]\n\r", rc));
        CL_FUNC_EXIT();
        return rc;
    }

    rc = clEventDebugDeregister(gEvtHead.evtEOId);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Debug Deregister failed [0x%X]\n\r", rc));
        CL_FUNC_EXIT();
        return rc;
    }

    /*
     ** Handle Database Cleanup.
     */
    rc = clEvtHandleDatabaseExit();
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Handle Database Cleanup failed [0x%X]\n\r",
                        rc));
        CL_FUNC_EXIT();
        return rc;
    }

#ifdef CKPT_ENABLED
    /*
     ** Check Pointing Related Cleanup.
     */
    clEvtCkptExit();
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event Ckpt Exit failed [0x%X]\n\r", rc));
        CL_FUNC_EXIT();
        return rc;
    }
#endif

    CL_FUNC_EXIT();
    return CL_OK;
}
ClRcT clAmsTriggerRmdFinalize(void)
{
    ClRcT rc = CL_OK;
    rc = clEoClientUninstallTables(gAms.eoObject, 
                                   CL_EO_SERVER_SYM_MOD(gAspFuncTable, AMFTrigger));
    if(rc != CL_OK)
    {
        clLogError("TRIGGER", "RMD", "EO client uninstall returned [%#x]", rc);
        goto out;
    }
    out:
    return rc;
}
ClRcT clDebugLibFinalize(void)
{
    ClEoExecutionObjT  *pEoObj    = NULL; 
    ClDebugObjT        *pDebugObj = NULL;
    ClRcT              rc         = CL_OK;

    rc = clEoMyEoObjectGet(&pEoObj);
    if (CL_OK != rc)
    {
        return rc;
    }

    rc = clEoPrivateDataGet( pEoObj, CL_EO_DEBUG_OBJECT_COOKIE_ID,
                             (void**) &pDebugObj);
    if (CL_OK != rc)
    {
        return rc;
    }

    clEoDebugDeregister();

    if( CL_OK != (rc = clHandleDatabaseDestroy(pDebugObj->hDebugFnDB))) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clHandleDatabaseDestroy(): "
                       "rc[0x %x]", rc));
    }
    
    clDebugClientTableDeregister(pEoObj);

    if( CL_OK != (rc = clEoClientUninstallTables(pEoObj, CL_EO_SERVER_SYM_MOD(gAspFuncTable, DEBUGCli))) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clEoClientUninstall(): rc[0x %x]",
                    rc));
    }

    clHeapFree(pDebugObj);

    return rc;
}
ClRcT clEventClientUninstallTables(ClEoExecutionObjT *pEoObj)
{
    return clEoClientUninstallTables(pEoObj, CL_EO_SERVER_SYM_MOD(gAspCltFuncTable, EVT));
}
ClRcT initializeAmf(void)
{
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClRcT	        rc = CL_OK;

    clLogCompName = (ClCharT*)"GMS"; /* Override generated eo name with a short name for our server */
    /* this function overrides the default EO configuration */
    clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); 

    /*  Do the CPM client init/Register */
    version.releaseCode  = 'B';
    version.majorVersion = 0x01;
    version.minorVersion = 0x01;
    
    callbacks.saAmfHealthcheckCallback          = NULL; 
    callbacks.saAmfComponentTerminateCallback   = clGmsServerTerminate;
    callbacks.saAmfCSISetCallback               = NULL;
    callbacks.saAmfCSIRemoveCallback            = NULL;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;

    gmsGlobalInfo.opState = CL_GMS_STATE_STARTING_UP;

    clLog(INFO,GEN,NA,
            CL_GMS_SERVER_STARTED);
        
    /* Initialize AMF client library. */
    rc = saAmfInitialize(&amfHandle, &callbacks, &version);
    if(rc!= SA_AIS_OK)
    {
        clLog(EMER,GEN,NA,
                "Sa AMF initialization Failed with rc [0x%x]. Booting Aborted",rc);
        exit(0);
        
    }
    gmsGlobalInfo.cpmHandle=amfHandle;
    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    rc = saAmfComponentNameGet(amfHandle, &appName);
    if(rc != SA_AIS_OK)
    {
         clLog(EMER,GEN,NA,
                "saAmfomponentNameGet Failed with rc [0x%x]. Booting Aborted",rc);
        exit(0);
      
    }
    gmsGlobalInfo.gmsComponentName.length=appName.length;
    memcpy(gmsGlobalInfo.gmsComponentName.value,appName.value,appName.length);

    rc = clEoMyEoObjectGet(&gmsGlobalInfo.gmsEoObject);
    if (rc != CL_OK)
    {
        clLog(EMER,GEN,NA,
               "clEoMyEoObjectGet Failed with rc [0x%x]. Booting Aborted",rc);
        exit(0);
    }
    
    rc = clDebugPromptSet(GMS_COMMAND_PROMPT);
    if( CL_OK == rc )
    {
        clLog(NOTICE,GEN,NA,
            "GMS Server registering with debug service");
        rc = clDebugRegister(
                gmsCliCommandsList, 
                (int)(sizeof(gmsCliCommandsList)/sizeof(ClDebugFuncEntryT)), 
                &gGmsDebugReg);
    }
    if( rc != CL_OK )
    {
        clLog(ERROR,GEN,NA,
            "Failed to register with debug server, error [0x%x]. Debug shell access disabled",
            rc);
    }

    rc = clEoClientInstallTables (
            gmsGlobalInfo.gmsEoObject,
            CL_EO_SERVER_SYM_MOD(gAspFuncTable, GMS));

    if ( rc != CL_OK )
    {
        clLog (EMER,GEN,NA,
                "Eo client install failed with rc [0x%x]. Booting aborted",rc);
        exit(0);
    }

    /* This function never returns the exit is done by causing a signal from
     *  the Terminate function */
   return CL_OK;
    
}
void clGmsServerTerminate(SaInvocationT invocation, const SaNameT *compName)
{

    ClRcT   rc = CL_OK;

    gmsGlobalInfo.opState = CL_GMS_STATE_SHUTING_DOWN;

    clLog(CRITICAL,GEN,NA, "Got termination request for component [%.*s]. Started Shutting Down...", compName->length,compName->value);
    
    rc = clEoClientUninstallTables (gmsGlobalInfo.gmsEoObject, CL_EO_SERVER_SYM_MOD(gAspFuncTable, GMS));
    if (rc != CL_OK)
    {
        clLog(ERROR,GEN,NA, "clEoClientUninstall failed with rc = 0x%x", rc);
    }
    /*
     * Unregister with AMF and respond to AMF saying whether the
     * termination was successful or not.
     */
    

    rc = clDebugDeregister(gGmsDebugReg);
    if (rc != CL_OK)
    {
        clLog(ERROR,GEN,NA, "clDebugDeregister failed with rc = 0x%x", rc);
    }

    /* Close the leader election algorithm dl if open */
#ifndef VXWORKS_BUILD 
    if (pluginHandle != NULL)
    {
        dlclose(pluginHandle);
    }
#endif

    if(gClTotemRunning)
    {
        /* We need to invoke openais finalize function instead of signal
         * handler here */
        totempg_finalize();

        /* Waiting for 10ms before invoking exit() */
        usleep(10000);
    }
    clLog(CRITICAL,GEN,NA,
          "GMS server exiting");

    rc = clHandleDatabaseDestroy(contextHandleDatabase);
    if (rc != CL_OK)
    {
        clLog(ERROR,GEN,NA,
                "contextHandleDatabase destroy failed with Rc = 0x%x",rc);
    }
    rc = saAmfComponentUnregister(amfHandle, compName, NULL);
    
    if(rc != SA_AIS_OK) 
    {
        clLog(ERROR,GEN,NA,
              "saAmfComponentUnregister failed with rc = 0x%x", rc);     
    }

    rc = saAmfFinalize(amfHandle);

    if (rc != SA_AIS_OK)
    {
        clLog(ERROR,GEN,NA,
              "saAmfFinalize failed with rc = 0x%x", rc);
    }
    /* Ok tell SAFplus that we handled it properly */
    rc = saAmfResponse(amfHandle, invocation, SA_AIS_OK);
    
    if (rc != SA_AIS_OK)
    {
        clLog(ERROR,GEN,NA,
              "clCpmResponse failed with rc = 0x%x", rc);
    }
    unblockNow = CL_TRUE;
}
/**
 * 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);
}
ClRcT clDebugLibInitialize(void)
{
    ClEoExecutionObjT  *pEoObj     = NULL;
    ClDebugObjT        *pDebugObj  = NULL;
    ClRcT              rc          = CL_OK;
    ClNameT            compName    = {0};
    
    rc = clEoMyEoObjectGet(&pEoObj);
    if (CL_OK != rc)
    {
        return rc;
    }

    pDebugObj = clHeapCalloc(1, sizeof(ClDebugObjT));
    if (NULL == pDebugObj)
    {
        clLogWrite(CL_LOG_HANDLE_APP,CL_LOG_CRITICAL,CL_DEBUG_LIB_CLIENT,
                   CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
        return CL_DEBUG_RC(CL_ERR_NO_MEMORY);
    }

    rc = clOsalTaskKeyCreate(&pDebugObj->debugTaskKey, NULL);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Debug task key create returned with [%#x]\n", rc));
        clHeapFree(pDebugObj);
        return CL_DEBUG_RC(CL_GET_ERROR_CODE(rc));
    }

    rc = clHandleDatabaseCreate(NULL, &pDebugObj->hDebugFnDB);
    if( CL_OK != rc )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clHandleDatabaseCreate(): rc[0x %x]",
                rc));
        clHeapFree(pDebugObj);
        return CL_DEBUG_RC(CL_ERR_NO_MEMORY);
    }

    /* Getting the compName from CPM */
    rc = clCpmComponentNameGet(0, &compName);
    if( CL_OK != rc )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clCpmComponentNameGet(): rc[0x %x]",
                    rc));
        clLogWrite(CL_LOG_HANDLE_APP,CL_LOG_WARNING,CL_DEBUG_LIB_CLIENT,
                   CL_LOG_MESSAGE_1_INVALID_PARAMETER, 
                   "CompNameGet is not proper");
        return rc;
    }

    pDebugObj->numFunc       = 0;
    /* Assining the compName */
    memset(pDebugObj->compName, '\0', CL_DEBUG_COMP_NAME_LEN);
    if( compName.length < CL_DEBUG_COMP_NAME_LEN )
    {
        memcpy(pDebugObj->compName, compName.value, compName.length);
        pDebugObj->compName[compName.length] = '\0';
    }
    else
    {
        clLogWrite(CL_LOG_HANDLE_APP,CL_LOG_WARNING,CL_DEBUG_LIB_CLIENT,
                   CL_LOG_MESSAGE_1_INVALID_PARAMETER,"CompName is Invalid");
        return CL_DEBUG_RC(CL_ERR_INVALID_PARAMETER);
    }

    /* Assigning compPrompt to DEFAULT */
    memset(pDebugObj->compPrompt, '\0', CL_DEBUG_COMP_PROMPT_LEN);
    strcpy(pDebugObj->compPrompt, "DEFAULT");

    rc = clEoClientInstallTablesWithCookie( pEoObj, 
                                            CL_EO_SERVER_SYM_MOD(gAspFuncTable, DEBUGCli),
                                            pDebugObj);
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clEoClientInstall(): rc[0x %x]", rc));
        clHandleDatabaseDestroy(pDebugObj->hDebugFnDB);
        clHeapFree(pDebugObj);
        return rc;
    }
    rc = clDebugClientTableRegister(pEoObj);
    if(CL_OK != rc)
    {
        clEoClientUninstallTables(pEoObj, 
                                  CL_EO_SERVER_SYM_MOD(gAspFuncTable, DEBUGCli));
        clHandleDatabaseDestroy(pDebugObj->hDebugFnDB);
        clHeapFree(pDebugObj);
        return rc;
    }

    rc = clEoPrivateDataSet(pEoObj, CL_EO_DEBUG_OBJECT_COOKIE_ID, pDebugObj);
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clEoPrivateDataSet(): rc[0x %x]", rc));
        clEoClientUninstallTables(pEoObj, 
                                  CL_EO_SERVER_SYM_MOD(gAspFuncTable, DEBUGCli));
        clHandleDatabaseDestroy(pDebugObj->hDebugFnDB);
        clHeapFree(pDebugObj);
        return rc;
    }
    
    clEoDebugRegister();

    return rc;
}
/*
 * This function will do following steps 
 * 1. Create DB for ECH/G 
 * 2. Create DB for ECH/L 
 * 3. Create mutex to protect ECH/G DB 
 * 4. Create mutex to protect ECH/L DB 
 * 5. Register with CPM for component failure notification. 
 * 6. Intialize the global variable to indicate EM is done. 
 */
ClRcT clEvtInitialize(ClInt32T argc, ClCharT *argv[])
{

    ClRcT rc = CL_OK;

    rc = initializeAmf();
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Amf Initialization failed [0x%X]\n\r", rc));
        CL_FUNC_EXIT();
        return rc;
    }

    CL_FUNC_ENTER();

    rc = clEvtChannelDBInit();

    rc = clEoMyEoObjectGet(&gEvtHead.evtEOId);

    rc = clEoClientInstallTables(gEvtHead.evtEOId, CL_EO_SERVER_SYM_MOD(gAspFuncTable, EVT));
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Installing Native table failed [0x%X]\n\r",
                        rc));
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_1_FUNC_TABLE_INSTALL_FAILED, rc);
        clCntDelete(gEvtMasterECHHandle);
        clEvtChannelDBClean();
        CL_FUNC_EXIT();
        return rc;
    }

    rc = clEventLibTableInit(); 
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Installing Native Server to Server table failed [0x%X]\n\r",
                        rc));
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_1_FUNC_TABLE_INSTALL_FAILED, rc);
        clCntDelete(gEvtMasterECHHandle);
        clEvtChannelDBClean();
        CL_FUNC_EXIT();
        return rc;
    }


    rc = clEventDebugRegister(gEvtHead.evtEOId);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Debug Register failed [0x%X]\n\r", rc));
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_1_DBG_REGISTER_FAILED, rc);
        CL_FUNC_EXIT();
        return rc;
    }

    /*
     ** Initialize the Handle Database.
     */
    rc = clEvtHandleDatabaseInit();
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: Handle Database Init failed [0x%X]\n\r", rc));
        CL_FUNC_EXIT();
        return rc;
    }

#ifdef CKPT_ENABLED
    /*
     ** Initialize the Check Pointing Library.
     */
    rc = clEvtCkptInit();
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_CRITICAL,
                       ("Event: CKPT Init failed [0x%X]\n\r", rc));
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_2_LIBRARY_INIT_FAILED, "Checkpoint Library",
                   rc);
        CL_FUNC_EXIT();
        return rc;
    }
#endif


    gEvtInitDone = CL_EVT_TRUE;

    /*
     * CPM should be notified that Event Service is ready only after the
     * the initialization is complete. This _MUST_ be the last step.
     */
    

    CL_FUNC_EXIT();

    return CL_OK;
}