/******************************************************************************
 * Application Life Cycle Management Functions
 *****************************************************************************/
ClRcT clCompAlarmEvtCallbackFunc(const ClAlarmHandleInfoT* pAlarmInfo)
{
    ClRcT rc = CL_OK;
    ClNameT moIdName = {0};
    ClCorMOIdT moId ;
    ClIocAddressT iocAddress = {{0}};

    memcpy(&moId, &pAlarmInfo->alarmInfo.moId, sizeof(ClCorMOIdT));

    rc = clCorMoIdToMoIdNameGet(&moId, &moIdName);
    if(CL_OK == rc)
        clOsalPrintf(" The MSO for which the alarm is raised [%s]. ", moIdName.value);
    clOsalPrintf(" The component which has raised the alarm [%s] ", pAlarmInfo->alarmInfo.compName.value);
    clOsalPrintf("Probable Cause:%d\n",pAlarmInfo->alarmInfo.probCause);
    clOsalPrintf("Alarm Handle :%d\n",pAlarmInfo->alarmHandle);
    clOsalPrintf("Alarm State:%d\n",pAlarmInfo->alarmInfo.alarmState);
    if(pAlarmInfo->alarmInfo.len != 0)
        clOsalPrintf("Alarm payload :%s\n",pAlarmInfo->alarmInfo.buff);

    iocAddress.iocPhyAddress.nodeAddress = 2;
    clEoMyEoIocPortGet(&iocAddress.iocPhyAddress.portId);

    rc = clFaultRepairAction(iocAddress, pAlarmInfo->alarmHandle, SA_AMF_COMPONENT_RESTART);
    if (CL_OK != rc)
    {
        clOsalPrintf("Failed while reporting the alarm to the fault..... . rc[0x%x] \n", rc);
        return rc;
    }

    clOsalPrintf("################ Successfully reported the alarm to the fault. ..... \n");

    return rc;
}
ClRcT clEvtCpmInit()
{
    ClNameT appName;
    ClCpmCallbacksT callbacks;
    ClVersionT version;
    ClIocPortT iocPort;
    ClRcT rc = CL_OK;

    version.releaseCode = 'B';
    version.majorVersion = 0x1;
    version.minorVersion = 0x1;

    callbacks.appHealthCheck = NULL;
    callbacks.appTerminate = clEventTerminate;
    callbacks.appCSISet = NULL;
    callbacks.appCSIRmv = NULL;
    callbacks.appProtectionGroupTrack = NULL;
    callbacks.appProxiedComponentInstantiate = NULL;
    callbacks.appProxiedComponentCleanup = NULL;

    clEoMyEoIocPortGet(&iocPort);

    rc = clCpmClientInitialize(&gClEvtCpmHandle, &callbacks, &version);
    if (CL_OK != rc)
    {
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_2_LIBRARY_INIT_FAILED, "CPM Library", rc);
    }

    rc = clCpmComponentNameGet(gClEvtCpmHandle, &appName);
    rc = clCpmComponentRegister(gClEvtCpmHandle, &appName, NULL);

    return CL_OK;
}
ClRcT clEvtCpmInit()
{
    ClNameT appName;
    ClCpmCallbacksT callbacks;
    ClVersionT version;
    ClIocPortT iocPort;
    ClRcT rc = CL_OK;

    /******************************************************************
                        CPM Related stuff
    ******************************************************************/
    /*
     * Do the CPM client init/Register
     */
    version.releaseCode = 'B';
    version.majorVersion = 0x1;
    version.minorVersion = 0x1;

    callbacks.appHealthCheck = NULL;
    callbacks.appTerminate = clEventTerminate;
    callbacks.appCSISet = NULL;
    callbacks.appCSIRmv = NULL;
    callbacks.appProtectionGroupTrack = NULL;
    callbacks.appProxiedComponentInstantiate = NULL;
    callbacks.appProxiedComponentCleanup = NULL;

    clEoMyEoIocPortGet(&iocPort);
    rc = clCpmClientInitialize(&gClEvtTestContCpmHandle, &callbacks, &version);
    rc = clCpmComponentNameGet(gClEvtTestContCpmHandle, &appName);
    rc = clCpmComponentRegister(gClEvtTestContCpmHandle, &appName, NULL);

    return CL_OK;
}
void initializeAmf(void)
{
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    /* Get the pid for the process and store it in global variable. */
    mypid = getpid();

    /* SAFplus is fully API compatible with SA-Forum (SAF) definitions.

       This optional call customizes OpenClovis SAFplus Platform extensions
       to the basic SAF services (to use, you would define the parameters as globals).  
       
       If this call is removed, standard SAF services will work just fine. */

    /* clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); */

    
    /*
     * Initialize and register with SAFplus AMF. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */
    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL; /* rarely necessary because SAFplus monitors the process */
    callbacks.saAmfComponentTerminateCallback   = safTerminate;
    callbacks.saAmfCSISetCallback               = safAssignWork;
    callbacks.saAmfCSIRemoveCallback            = safRemoveWork;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /* Initialize AMF client library. */
    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK)
        errorExit(rc);

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        errorExit(rc);
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        errorExit(rc);

    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);
}
/*-----------------------------------------------------------------------------
 * Cluster Member Get Async API
 *---------------------------------------------------------------------------*/
ClRcT clGmsClusterMemberGetAsync(
    CL_IN const ClGmsHandleT   gmsHandle,
    CL_IN const ClInvocationT  invocation,
    CL_IN const ClGmsNodeIdT   nodeId)
{
    ClRcT                                rc = CL_OK;
    struct gms_instance                 *gms_instance_ptr = NULL;
    ClGmsClusterMemberGetAsyncRequestT   req = {0};
    ClGmsClusterMemberGetAsyncResponseT *res = NULL;
        
    CL_GMS_SET_CLIENT_VERSION( req );
    rc = clHandleCheckout(gmsHandleDb, gmsHandle, (void**)&gms_instance_ptr);
    if (rc != CL_OK)
    {
        return rc;
    }
    if (gms_instance_ptr == NULL)
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }

    if (gms_instance_ptr->callbacks.clGmsClusterMemberGetCallback == NULL)
    {
        rc = CL_GMS_RC(CL_ERR_NO_CALLBACK);
        goto error_checkin;
    }
    
    req.gmsHandle  = gmsHandle;
    req.nodeId     = nodeId;
    req.invocation = invocation;
    req.address.iocPhyAddress.nodeAddress = clIocLocalAddressGet();
    rc = clEoMyEoIocPortGet(&(req.address.iocPhyAddress.portId));
    if (rc != CL_OK)
    {
        goto error_checkin;
    }
    
    clGmsMutexLock(gms_instance_ptr->response_mutex);
    
    rc = cl_gms_cluster_member_get_async_rmd(&req, 0 /* use def. timeout */,
                                             &res);
    if (rc != CL_OK) /* If there was an error, res isn't allocated */
    {
        goto error_unlock_checkin;
    }

error_unlock_checkin:
    clGmsMutexUnlock(gms_instance_ptr->response_mutex);
    
error_checkin:
    if (clHandleCheckin(gmsHandleDb, gmsHandle) != CL_OK)
    {
        clLogError(CLM,NA,
                    "\nclHandleCheckin failed");
    }
    
    return rc;
}
/*-----------------------------------------------------------------------------
 * Cluster Track Stop API
 *---------------------------------------------------------------------------*/
ClRcT clGmsClusterTrackStop(
    CL_IN const ClGmsHandleT gmsHandle)
{
    ClRcT                           rc = CL_OK;
    struct gms_instance            *gms_instance_ptr = NULL;
    ClGmsClusterTrackStopRequestT   req = {0};
    ClGmsClusterTrackStopResponseT *res = NULL;
    
    CL_GMS_SET_CLIENT_VERSION( req );
    rc = clHandleCheckout(gmsHandleDb, gmsHandle, (void**)&gms_instance_ptr);
    if (rc != CL_OK)
    {
        return CL_GMS_RC(CL_ERR_INVALID_HANDLE);
    }
    
    if (gms_instance_ptr == NULL)
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }

    req.gmsHandle = gmsHandle;
    req.address.iocPhyAddress.nodeAddress = clIocLocalAddressGet();
    rc = clEoMyEoIocPortGet(&(req.address.iocPhyAddress.portId));
    
    CL_ASSERT(rc == CL_OK); /* Should really never happen */
    
    clGmsMutexLock(gms_instance_ptr->response_mutex);
    
    rc = cl_gms_cluster_track_stop_rmd(&req, 0 /* use def. timeout */, &res);
    if ((rc != CL_OK) || (res == NULL)) /* If there was an error, res isn't allocated */
    {
        goto error_exit;
    }
    
    rc = res->rc;
    
    clHeapFree((void*)res);

error_exit:
    clGmsMutexUnlock(gms_instance_ptr->response_mutex);

    if (clHandleCheckin(gmsHandleDb, gmsHandle) != CL_OK)
    {
        clLogError(CLM,NA,
                   "\nclHandleCheckin failed");
    }

    
    return CL_GMS_RC(rc);
}
/* - clLogClntCompInfoGet
 * - Gets the component name and id
 */
ClRcT
clLogClntCompInfoGet(ClLogCompInfoT  *pCompInfo)
{
    ClRcT  rc = CL_OK;

    CL_LOG_DEBUG_TRACE(("Enter"));

    CL_LOG_PARAM_CHK((NULL == pCompInfo), CL_LOG_RC(CL_ERR_NULL_POINTER));

    rc = clCpmComponentNameGet(0, &pCompInfo->compName);
    if( CL_OK != rc)
    {
        CL_LOG_DEBUG_ERROR(("clCpmComponentNameGet(): rc[0x %x]", rc));
        return rc;
    }

    clEoMyEoIocPortGet(&pCompInfo->compId);

    CL_LOG_DEBUG_TRACE(("Exit: %.*s %u", pCompInfo->compName.length,
                        pCompInfo->compName.value, pCompInfo->compId));
    return rc;
}
ClRcT initializeAmf()
{
   
    SaNameT             appName;      
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    
    version.releaseCode  = 'B';
    version.majorVersion = 0x01;
    version.minorVersion = 0x01;
    
    callbacks.saAmfHealthcheckCallback          = NULL; /* rarely necessary because SAFplus monitors the process */
    callbacks.saAmfComponentTerminateCallback   = clEventTerminate;
    callbacks.saAmfCSISetCallback               = NULL;
    callbacks.saAmfCSIRemoveCallback            = NULL;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
    callbacks.saAmfProxiedComponentInstantiateCallback = NULL;
    callbacks.saAmfProxiedComponentCleanupCallback = NULL;

    clEoMyEoIocPortGet(&iocPort);
   
    rc = saAmfInitialize(&gClEvtAmfHandle, &callbacks, &version);
    if(rc != SA_AIS_OK)
    {
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_CRITICAL, NULL,
                   CL_LOG_MESSAGE_2_LIBRARY_INIT_FAILED, "CPM Library", rc);
        return clSafToClovisError(rc);
    }

    rc = saAmfComponentNameGet(gClEvtAmfHandle, &appName);
    rc = saAmfComponentRegister(gClEvtAmfHandle, &appName, NULL);

    return CL_OK;
    
}
ClRcT
clProvObjectCreate(ClCorMOIdPtrT pMoId, ClCorAttributeValueListPtrT attrList, ClCorObjectHandleT* pHandle)
{
    ClRcT rc = CL_OK;
    ClCorMOIdPtrT pTempMoId = NULL;
    ClCorObjectHandleT moHandle = NULL;
    ClCorObjectHandleT msoHandle = NULL;
    ClCorTxnSessionIdT tid = 0;
    ClCorAddrT provAddr = {0};

    CL_FUNC_ENTER();
    
    /* Create the MO object */
    if(NULL == pMoId)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("\nNULL parameter passed\n"));
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }

    rc = clCorMoIdClone(pMoId, &pTempMoId);
    if(CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed while cloning the MoId. rc[0x%x]", rc));
        CL_FUNC_EXIT();
        return rc;
    }

    rc = clCorMoIdServiceSet(pTempMoId, CL_COR_INVALID_SRVC_ID);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to set the service id of the MoId. rc [0x%x]", rc));
        clCorMoIdFree(pTempMoId);
        CL_FUNC_EXIT();
        return rc;
    }
    
    tid = 0;
    
    if (CL_OK != clCorObjectHandleGet(pTempMoId, &moHandle))
    {
        rc = clCorObjectCreate(&tid, pTempMoId, NULL);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to add MO object creation in txn. rc [0x%x]", rc));
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }        
    }
    else
        clCorObjectHandleFree(&moHandle);

    rc = clCorMoIdServiceSet(pTempMoId, CL_COR_SVC_ID_PROVISIONING_MANAGEMENT);
    if (rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to set the service id of the MoId. rc [0x%x]\n", rc));
        clCorMoIdFree(pTempMoId);
        clCorTxnSessionFinalize(tid);
        CL_FUNC_EXIT();
        return rc;
    }

    if (CL_OK != clCorObjectHandleGet(pTempMoId, &msoHandle))
    {
        rc = clCorObjectCreateAndSet(&tid, pTempMoId, attrList, &msoHandle);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                ("Failed to add create and set for the MSO object in txn. rc [0x%x]", rc));
            clCorMoIdFree(pTempMoId);
            clCorTxnSessionFinalize(tid);
            CL_FUNC_EXIT();
            return (rc);
        }

        rc = clCorTxnSessionCommit(tid);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to commit the transaction. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            clCorTxnSessionFinalize(tid);
            CL_FUNC_EXIT();
            return rc;            
        }

        provAddr.nodeAddress = clIocLocalAddressGet();
        rc = clEoMyEoIocPortGet(&provAddr.portId);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to get the IOC port. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }
        
        rc = clCorOIRegister(pTempMoId, &provAddr);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to register the OI with COR. rc [0x%x]", rc));
            clCorObjectHandleFree(&msoHandle);
            clCorMoIdFree(pTempMoId);
            CL_FUNC_EXIT();
            return rc;
        }
    }
    
    clCorMoIdFree(pTempMoId);

    /* Assign the prov mso handle */
    *pHandle = msoHandle;

    CL_FUNC_EXIT();
    return (CL_OK);
}
/*-----------------------------------------------------------------------------
 * Cluster Join API
 *---------------------------------------------------------------------------*/
ClRcT clGmsClusterJoin(
    CL_IN const ClGmsHandleT                        gmsHandle,
    CL_IN const ClGmsClusterManageCallbacksT* const clusterManageCallbacks,
    CL_IN const ClGmsLeadershipCredentialsT         credentials,
    CL_IN const ClTimeT                             timeout,
    CL_IN const ClGmsNodeIdT                        nodeId,
    CL_IN const SaNameT*                      const nodeName)
{
    ClRcT                                rc = CL_OK;
    struct gms_instance                 *gms_instance_ptr = NULL;
    ClGmsClusterJoinRequestT             req = {0};
    ClGmsClusterJoinResponseT           *res = NULL;
    
    clLog(INFO,CLM,NA, "clGmsClusterJoin API is being invoked");
    CL_GMS_SET_CLIENT_VERSION( req );

    if ((nodeName == (const void*)NULL) ||
        (clusterManageCallbacks == (const void*)NULL) ||
        (clusterManageCallbacks->clGmsMemberEjectCallback == NULL))
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }
    
    rc = clHandleCheckout(gmsHandleDb, gmsHandle, (void**)&gms_instance_ptr);
    if (rc != CL_OK)
    {
        return rc;
    }

    if (gms_instance_ptr == NULL)
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }
    
    memcpy(&(gms_instance_ptr->cluster_manage_callbacks),
           clusterManageCallbacks,
           sizeof(ClGmsClusterManageCallbacksT));
    
    req.gmsHandle   = gmsHandle;
    req.credentials = credentials;
    req.nodeId      = nodeId;
    memcpy(&req.nodeName,nodeName, sizeof(SaNameT));
    req.sync        = CL_TRUE;
    req.address.iocPhyAddress.nodeAddress = clIocLocalAddressGet();
    if (clEoMyEoIocPortGet(&(req.address.iocPhyAddress.portId)) != CL_OK)
    {
        clLogError(CLM,NA,
                   "\nclEoMyEoIocPortGet failed");
    }
    
    clGmsMutexLock(gms_instance_ptr->response_mutex);
    
    clLog(TRACE,CLM,NA, "Sending RMD to GMS server for cluster join");
    rc = cl_gms_cluster_join_rmd(&req, (ClUint32T)(timeout/NS_IN_MS), &res);
    clLog(TRACE,CLM,NA, "clGmsClusterJoin RMD returned");

    
    if( res ) 
    clHeapFree((void*)res);
    
    clGmsMutexUnlock(gms_instance_ptr->response_mutex);
    if (clHandleCheckin(gmsHandleDb, gmsHandle) != CL_OK)
    {
        clLogError(CLM,NA,
                   "\nclHandleCheckin failed");
    }
    return rc;
}
/*-----------------------------------------------------------------------------
 * Cluster Track API
 *---------------------------------------------------------------------------*/
ClRcT clGmsClusterTrack(
    CL_IN    const ClGmsHandleT               gmsHandle,
    CL_IN    const ClUint8T                   trackFlags,
    CL_INOUT ClGmsClusterNotificationBufferT* const notificationBuffer)
{    
    ClRcT                       rc = CL_OK;
    struct gms_instance        *gms_instance_ptr = NULL;
    ClGmsClusterTrackRequestT   req = {0};
    ClGmsClusterTrackResponseT *res = NULL;
    const ClUint8T validFlag = CL_GMS_TRACK_CURRENT | CL_GMS_TRACK_CHANGES |
                            CL_GMS_TRACK_CHANGES_ONLY;
    ClBoolT shouldFreeNotification = CL_TRUE;

    clLog(TRACE,CLM,NA,"clGmsClusterTrack API is invoked");
    if (((trackFlags | validFlag) ^ validFlag) != 0) {
        return CL_GMS_RC(CL_ERR_BAD_FLAG);
    }

    CL_GMS_SET_CLIENT_VERSION( req );
    
    if (((trackFlags & CL_GMS_TRACK_CURRENT) == CL_GMS_TRACK_CURRENT) && /* If current view is requested */
        (notificationBuffer != NULL) &&        /* Buffer is provided */
        (notificationBuffer->notification != NULL) && /* Caller provides array */
        (notificationBuffer->numberOfItems == 0)) /* then size must be given */
    {
        return CL_GMS_RC(CL_ERR_INVALID_PARAMETER);
    }
    
    if (trackFlags == 0) /* at least one flag should be specified */
    {
        return CL_GMS_RC(CL_ERR_BAD_FLAG);
    }
    
    if (((trackFlags & CL_GMS_TRACK_CHANGES) == CL_GMS_TRACK_CHANGES) &&
        ((trackFlags & CL_GMS_TRACK_CHANGES_ONLY) == CL_GMS_TRACK_CHANGES_ONLY)) /* mutually exclusive flags */
    {
        return CL_GMS_RC(CL_ERR_BAD_FLAG);
    }
    
    rc = clHandleCheckout(gmsHandleDb, gmsHandle, (void**)&gms_instance_ptr);
    if (rc != CL_OK)
    {
        return CL_GMS_RC(CL_ERR_INVALID_HANDLE);
    }

    if (gms_instance_ptr == NULL)
    {
        return CL_GMS_RC(CL_ERR_NULL_POINTER);
    }
    
    /* If not a sync call, then clGmsClusterTrackCallbackHandler must be given */
    if (((trackFlags & (CL_GMS_TRACK_CHANGES|CL_GMS_TRACK_CHANGES_ONLY)) != 0) ||
        (((trackFlags & CL_GMS_TRACK_CURRENT) == CL_GMS_TRACK_CURRENT) &&
         (notificationBuffer == NULL)))
    {
        if (gms_instance_ptr->callbacks.clGmsClusterTrackCallback == NULL)
        {
            rc = CL_GMS_RC(CL_ERR_NO_CALLBACK);
            goto error_checkin;
        }
    }
    
    req.gmsHandle  = gmsHandle;
    req.trackFlags = trackFlags;
    req.sync       = CL_FALSE;
    req.address.iocPhyAddress.nodeAddress = clIocLocalAddressGet();
    rc = clEoMyEoIocPortGet(&(req.address.iocPhyAddress.portId));
    
    CL_ASSERT(rc == CL_OK); /* Should really never happen */
    
    clGmsMutexLock(gms_instance_ptr->response_mutex);
    
    if (((trackFlags & CL_GMS_TRACK_CURRENT) == CL_GMS_TRACK_CURRENT) &&
        (notificationBuffer != NULL)) /* Sync response requested */
    {
        /*
         * We need to call the extended track() request which returns with
         * a notification buffer allocated by the XDR layer.
         */
        clLogMultiline(TRACE,CLM,NA,
                "Sending RMD to GMS server for Cluster track with"
                " track flags CL_GMS_TRACK_CURRENT");
        req.sync = CL_TRUE;
        rc = cl_gms_cluster_track_rmd(&req, 0 /* use def. timeout */, &res);
        clLog(TRACE,CLM,NA,"Returned from cluster track RMD");
        if ((rc != CL_OK) || (res == NULL)) /* If there was an error, res isn't allocated */
        {
            switch (CL_GET_ERROR_CODE(rc))
            {
                case CL_ERR_TIMEOUT:    rc = CL_GMS_RC(CL_ERR_TIMEOUT); break;
                case CL_ERR_TRY_AGAIN:  rc = CL_GMS_RC(CL_ERR_TRY_AGAIN); break;
                default:                rc = CL_GMS_RC(CL_ERR_UNSPECIFIED);
            }
            /* FIXME: Need to get back to this! Based on consensus among
             *  engineers.
             */
            goto error_unlock_checkin;
        }

        if (res->rc != CL_OK) /* If other side indicated error, we need
                               * to free the buffer.
                               */
        {
            rc = res->rc;
            goto error_exit;
        }

        /* All fine, need to copy buffer */
        if (notificationBuffer->notification == NULL) /* we provide array */
        {
            memcpy(notificationBuffer, &res->buffer,
                   sizeof(*notificationBuffer)); /* This takes care of array */
            shouldFreeNotification = CL_FALSE;
        }
        else
        { /* caller provided array with fixed given size; we need to copy if
           * there is enough space.
           */
            if (notificationBuffer->numberOfItems >=
                res->buffer.numberOfItems)
            {
                /* Copy array, as much as we can */
                memcpy((void*)notificationBuffer->notification,
                       (void*)res->buffer.notification,
                       res->buffer.numberOfItems *
                          sizeof(ClGmsClusterNotificationT));
            }
            /*
             * Instead of copying the rest of the fields in buffer one-by-one,
             * we do a trick: relink the above array and than copy the entire
             * struck over.  This will keep working even if the buffer struct
             * grows in the future; without change here.
             */
            clHeapFree((void*)res->buffer.notification);
            res->buffer.notification = notificationBuffer->notification;
            memcpy((void*)notificationBuffer, (void*)&res->buffer,
                   sizeof(*notificationBuffer));
            shouldFreeNotification = CL_FALSE;
        }
    }
    else
    {
        clLog(TRACE,CLM,NA, "Sending Async RMD to GMS server for cluster track"); 
        /* No sync response requested, so we call the simple rmd call */
        rc = cl_gms_cluster_track_rmd(&req, 0 /* use def. timeout */, &res);
        clLog(TRACE,CLM,NA, "Cluster track RMD returned");
        /* No sync response requested, so we call the simple rmd call */
        if ((rc != CL_OK) || (res == NULL)) /* If there was an error, res isn't allocated */
        {
            goto error_unlock_checkin;
        }
        
        rc = res->rc;
    }     

error_exit:
    if(shouldFreeNotification == CL_TRUE )
    {
        if (res->buffer.notification != NULL)
          clHeapFree((void*)res->buffer.notification);
    }
    clHeapFree((void*)res);
    
error_unlock_checkin:
    clGmsMutexUnlock(gms_instance_ptr->response_mutex);
    
error_checkin:
    if (clHandleCheckin(gmsHandleDb, gmsHandle) != CL_OK)
    {
        clLog(ERROR,CLM,NA,"clHandleCheckin Failed");
    }
    
    return rc;
}
SaAisErrorT initializeAmf(void)
{
    SaAmfCallbacksT     callbacks;
   
    ClIocPortT          iocPort=0;
    SaAisErrorT         rc = SA_AIS_OK;
    /*This function overrides the default EO Configuaration */
    clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs);
    /*
     * Initialize and register with SAFplus AMF. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */
     /*
     * Set the supported version.
     */
     gVersion.releaseCode = 'B';
     gVersion.majorVersion = 0x01;
     gVersion.minorVersion = 0x01;
   
     /*
     * Fill the AMS's callback structure.
     */
     callbacks.saAmfHealthcheckCallback          = NULL; /* rarely necessary because SAFplus monitors the process */
     callbacks.saAmfComponentTerminateCallback   = ckptTerminate;
     callbacks.saAmfCSISetCallback               = NULL;
     callbacks.saAmfCSIRemoveCallback            = NULL;
     callbacks.saAmfProtectionGroupTrackCallback = NULL;
     
     /*
     * Get the port Id from IOC.
     */
     clEoMyEoIocPortGet(&iocPort);

     
        
     /* Initialize AMF client library. */
     rc = saAmfInitialize(&amfHandle, &callbacks, &gVersion);
       
     /*
     * Get the component name from AMF.
     */

     rc = saAmfComponentNameGet(amfHandle, &appName);
      /*
     * Initialize ckpt server.
     */

     clCkptLeakyBucketInitialize();

     clCkptSvrInitialize();
     

     rc = saAmfComponentRegister(amfHandle, &appName, NULL);
    
     gCkptSvr->amfHdl = amfHandle;

     /*
     * Obtain the component id from cpm. This will be used while registering
     * ckpt master address with TL.
     */
     clAmfGetComponentId(gCkptSvr->amfHdl, &appName, &gCkptSvr->compId);

     /*
     * Register with debug server.
     */
     ckptDebugRegister(gCkptSvr->eoHdl);
    
     return rc;
}
ClRcT
clCompAppInitialize(
    ClUint32T argc,
    ClCharT *argv[])
{
    SaNameT             appName;
    ClCpmCallbacksT     callbacks;
    ClVersionT          version;
    ClIocPortT          iocPort;
    ClRcT               rc = CL_OK;

    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the version of
     * AMF with which this application would like to interface. 'callbacks'
     * is used to register the callbacks this component expects to receive.
     */

    version.releaseCode                         = 'B';
    version.majorVersion                        = 01;
    version.minorVersion                        = 01;
    
    callbacks.appHealthCheck                    = NULL;
    callbacks.appTerminate                      = clCompAppTerminate;
    callbacks.appCSISet                         = clCompAppAMFCSISet;
    callbacks.appCSIRmv                         = clCompAppAMFCSIRemove;
    callbacks.appProtectionGroupTrack           = NULL;
        
    /*
     * Get IOC Address, Port and Name. Register with AMF.
     */

    clEoMyEoIocPortGet(&iocPort);

    if ( (rc = clCpmClientInitialize(&cpmHandle, &callbacks, &version)) ) 
        goto errorexit;

    /*
     * If this component will provide a service, register it now.
     */

#if HAS_EO_SERVICES


    rc = clSAFComponent0EO0ClientInstall();

#endif

    /*
     * Do the application specific initialization here.
     */

    /*
     * ---BEGIN_APPLICATION_CODE---
     */

    // ...

    /*
     * ---END_APPLICATION_CODE---
     */

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = clCpmComponentNameGet(cpmHandle, &appName)) ) 
        goto errorexit;
    if ( (rc = clCpmComponentRegister(cpmHandle, &appName, NULL)) ) 
        goto errorexit;

    /*
     * Print out standard information for this component.
     */

    clprintf ("Component [%s] : PID [%d]. Initializing\n", appName.value, mypid);
    clprintf ("   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf ("   IOC Port                : 0x%x\n", iocPort);

    /*
     * This is where the application code starts. If the main thread usage
     * policy is CL_EO_USE_THREAD_FOR_APP, then return from this fn only 
     * after the application terminates. If the main thread usage policy is
     * CL_EO_USE_THREAD_FOR_RECV, then return from this fn after doing the
     * application specific initialization and registration.
     */

    /*
     * ---BEGIN_APPLICATION_CODE---
     */

    // ...

    /*
     * ---END_APPLICATION_CODE---
     */

    return rc;

errorexit:

    clprintf ("Component [%s] : PID [%d]. Initialization error [0x%x]\n",
              appName.value, mypid, rc);

    return rc;
}
ClRcT clCkptSvrInitialize(void)
{
    ClRcT             rc         = CL_OK;
    /* Variable related ckptDataBackup feature thats not supported
       ClUint8T          ckptRead   = 0;
    */
    ClTimerTimeOutT   timeOut    = {0}; 
    ClIocNodeAddressT deputy = 0;
    ClIocNodeAddressT master = 0;
    ClBoolT           addressUpdate = CL_FALSE;
    SaNameT           appName    = {0};   
 
    /*
     * Allocate the memory for server control block.
     */
    rc = ckptSvrCbAlloc(&gCkptSvr);
    CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, 
                   ("Checkpoint service CB create failed rc[0x %x]\n", rc), rc); 

    /*
     * Mark server as not ready.
     */
    gCkptSvr->serverUp        = CL_FALSE;
    gCkptSvr->condVarWaiting  = CL_TRUE;    

    /*
     * Create condition variable that indicate the receipt
     * of master and deputy ckpt addresses from gms.
     */
    clOsalCondCreate(&gCkptSvr->condVar);
    clOsalMutexCreate(&gCkptSvr->mutexVar);
    
    gCkptSvr->masterInfo.masterAddr = CL_CKPT_UNINIT_ADDR;
    gCkptSvr->masterInfo.deputyAddr = CL_CKPT_UNINIT_ADDR;
    gCkptSvr->masterInfo.compId     = CL_CKPT_UNINIT_VALUE; 
    gCkptSvr->masterInfo.clientHdlCount = 0;
    gCkptSvr->masterInfo.masterHdlCount = 0; 

    /*
     * Initialize gms to get the master and deputy addresses.
     */
    clOsalMutexLock(&gCkptSvr->ckptClusterSem);
    rc = clCkptMasterAddressesSet();
    master = gCkptSvr->masterInfo.masterAddr;
    deputy = gCkptSvr->masterInfo.deputyAddr;
    clOsalMutexUnlock(&gCkptSvr->ckptClusterSem);

    rc = clEoMyEoObjectGet(&gCkptSvr->eoHdl);
    rc = clEoMyEoIocPortGet(&gCkptSvr->eoPort);
   
    /*
     * Install the ckpt native table.
     */
    rc = clCkptEoClientInstall();
    CL_ASSERT(rc == CL_OK);
    
    rc = clCkptEoClientTableRegister(CL_IOC_CKPT_PORT);
    CL_ASSERT(rc == CL_OK);

    /*
     * Initialize the event client library.
     */
    ckptEventSvcInitialize();
    
    /* 
     * Initialize ckpt lib for persistent memory.
     * Obtain ckptRead flag that will tell whether ckpt server needs to 
     * read data from persistent memory or not.
     */

    /*
      Feature not yet supported see bug 6017 -- Do not forget to uncomment ckptDataBackupFinalize
      rc = ckptDataBackupInitialize(&ckptRead);
    */

    if(rc != CL_OK)
    {
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_WARNING, NULL,
                   CL_LOG_MESSAGE_2_LIBRARY_INIT_FAILED, "ckpt", rc);
    }

    if( gCkptSvr->localAddr == master )
    {
        /*
         * The node coming up is master. If deputy exists, syncup with deputy
         * else syncup with persistant memory (if existing).
         */
        rc = clCpmComponentNameGet(gCkptSvr->amfHdl, &appName);
        if(clCpmIsCompRestarted(appName))
        {
            if((deputy != CL_CKPT_UNINIT_ADDR) && ( (ClInt32T) deputy != -1))
            {
                rc = ckptMasterDatabaseSyncup(deputy);
                /*
                 * If deputy server is not reachable then pull info from the 
                 * persistent memory.
                 */
                if(CL_RMD_TIMEOUT_UNREACHABLE_CHECK(rc))
                {
                    clLogNotice(CL_CKPT_AREA_ACTIVE, "DBS", 
                                "Database Syncup with ckpt master failed with RMD timeout error. rc 0x%x",rc);
                    /* This is dead code as the feature is not supported
                       if(ckptRead == 1)
                       {
                       rc = ckptPersistentMemoryRead();
                       }
                    */
                }
            }
        }
        /* This is dead code as the feature is not supported
           else
           {
           if(ckptRead == 1)
           {
           rc = ckptPersistentMemoryRead();
           }
           }
        */
    }
    
    /*TODO:This check is only for seleting the deputy or for what */
    clOsalMutexLock(gCkptSvr->mutexVar);    
    if( (clIocLocalAddressGet() != master) &&
        (gCkptSvr->condVarWaiting == CL_TRUE)     )
    {
        /*
         * Ensure that the node gets the master and deputy addresses before
         * proceeding further.
         */
        timeOut.tsSec            = 5;
        timeOut.tsMilliSec       = 0;
        clOsalCondWait(gCkptSvr->condVar, gCkptSvr->mutexVar, timeOut);
        gCkptSvr->condVarWaiting = CL_FALSE;
        addressUpdate = CL_TRUE;
    }
    clOsalMutexUnlock(gCkptSvr->mutexVar);    

    /*  
     * We double check again incase we had waited for the gms cluster track.
     * but with the right lock sequence below instead of shoving it in the
     * condwait above.
     */
    if(addressUpdate == CL_TRUE)
    {
        clOsalMutexLock(&gCkptSvr->ckptClusterSem);
        master = gCkptSvr->masterInfo.masterAddr;
        deputy = gCkptSvr->masterInfo.deputyAddr;
        clOsalMutexUnlock(&gCkptSvr->ckptClusterSem);
    }
    /* 
     * Announce the arrival to peer in the n/w. Master server announces to 
     * all and other servers announce to master server.
     */
    ckptSvrArrvlAnnounce();
    
    /*
     * If the node coming up is deputy, syncup the metadata and ckpt info 
     * from the master. Treat all SC capable nodes except the master as deputy.
     */
    if(  gCkptSvr->localAddr != master && clCpmIsSCCapable())
    {
        /*
         * Just freezing the deputy till syncup, not to receive any master
         * related calls, this is to ensure that deputy is in full synup with
         * master and any calls from master to update deputy will sleep on the
         * lock.
         */
        CKPT_LOCK(gCkptSvr->masterInfo.ckptMasterDBSem);
        ckptMasterDatabaseSyncup(gCkptSvr->masterInfo.masterAddr);
        CKPT_UNLOCK(gCkptSvr->masterInfo.ckptMasterDBSem);
    }
    
    /* 
     * Server is up.
     */
    gCkptSvr->serverUp = CL_TRUE;
    return rc;
    exitOnError:
    {
        return rc;
    }
}
ClRcT clAmsMgmtOIInitialize(ClAmsMgmtHandleT *pHandle, 
                            ClRcT (*pClAmsMgmtOIConfigAttributesGet)
                            (ClAmsEntityConfigT*, ClCorAttributeValueListPtrT pAttrList),
                            ClRcT (*pClAmsMgmtOIExtendedConfigAttributesGet)
                            (ClAmsMgmtOIExtendedClassTypeT type, 
                             ClAmsMgmtOIExtendedEntityConfigT *pConfig,
                             ClCorClassTypeT *pClassType,
                             ClCorAttributeValueListT *pAttrList))
{
    ClRcT rc = CL_OK;
    ClAmsMgmtHandleT handle = 0;
    ClAmsEntityBufferT buffer[CL_AMS_ENTITY_TYPE_MAX+2] = {{0}};
    ClVersionT version = {'B', 0x1, 0x1};
    ClCorTxnSessionIdT txnSession = 0;
    ClUint32T i;
    ClCorAddrT appAddress = {0};
    SaNameT chassisInstance = {0};
    ClUint32T chassisId = 0;

    if(!pClAmsMgmtOIConfigAttributesGet)
        return CL_AMS_RC(CL_ERR_INVALID_PARAMETER);

    rc = clOsalMutexInit(&gClAmsMgmtOICacheMutex);
    CL_ASSERT(rc == CL_OK);

    rc = clEoMyEoIocPortGet(&appAddress.portId);
    if(rc != CL_OK) 
        return rc;
    appAddress.nodeAddress = clIocLocalAddressGet();

    rc = clAmsMgmtInitialize(&handle, NULL, &version);
    if(rc != CL_OK)
    {
        return rc;
    }
    snprintf(chassisInstance.value, sizeof(chassisInstance.value),
             "%s:%d", "\\Chassis", chassisId);
    chassisInstance.length = strlen(chassisInstance.value);
    rc = clCorMoIdNameToMoIdGet(&chassisInstance, &gClChassisMoid);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "COR moid get for [%s] returned [%#x]",
                   chassisInstance.value, rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSGList(handle, &buffer[CL_AMS_ENTITY_TYPE_SG]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SG list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSIList(handle, &buffer[CL_AMS_ENTITY_TYPE_SI]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SI list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetCSIList(handle, &buffer[CL_AMS_ENTITY_TYPE_CSI]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get CSI list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetNodeList(handle, &buffer[CL_AMS_ENTITY_TYPE_NODE]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get NODE list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetSUList(handle, &buffer[CL_AMS_ENTITY_TYPE_SU]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get SU list returned [%#x]", rc);
        goto out_free;
    }
    rc = clAmsMgmtGetCompList(handle, &buffer[CL_AMS_ENTITY_TYPE_COMP]);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "Get COMP list returned [%#x]", rc);
        goto out_free;
    }
    /*
     * Now fetch the moid for each of the entities and build the cache.
     */
    for(i = 0; i <= CL_AMS_ENTITY_TYPE_MAX; ++i)
    {
        ClAmsEntityBufferT *pBuffer = &buffer[i];
        ClUint32T j;
        if(!pBuffer->count || !pBuffer->entity)
            continue;
        gClAmsMgmtOIIndexTable[i] = pBuffer->count;
        for(j = 0; j < pBuffer->count; ++j)
        {
            ClCorMOIdT moid = {{{0}}};
            rc = clAmsMgmtOIMoIdGet(handle, pBuffer->entity+j, &moid);
            if(rc != CL_OK)
            {
                continue;
            }
            clAmsMgmtOICacheAdd(clCorMoIdToInstanceGet(&moid), pBuffer->entity+j);
            /*
             * Required for instances exceeding the pre-configured limit.
             */
             rc = clCorOIRegister(&moid, &appAddress);
             if(rc != CL_OK)
             {
                 continue;
             }
            rc = clCorPrimaryOISet(&moid, &appAddress);
            if(rc != CL_OK)
            {
                /*
                 * Ignore as it could be already set by the active.
                 */
                continue;
            }
            clAmsMgmtOIConfigAttributeSet(handle, &txnSession, &moid, pBuffer->entity+j, pClAmsMgmtOIConfigAttributesGet);
            clAmsMgmtOIExtendedConfigAttributeSet(handle, &txnSession, pBuffer->entity+j,
                                                  pClAmsMgmtOIExtendedConfigAttributesGet);
        }
    }
    rc = clCorTxnSessionCommit(txnSession);
    if(rc != CL_OK)
    {
        clLogError("AMF", "MGMT", "AMF OI config commit returned [%#x]", rc);
    }
    else
    {
        clLogNotice("AMF", "MGMT", "Entity cache successfully initialized");
        gClAmsMgmtOIInitialized = CL_TRUE;
    }

    out_free:
    for(i = 0; i <= CL_AMS_ENTITY_TYPE_MAX; ++i)
    {
        if(buffer[i].entity) clHeapFree(buffer[i].entity);
        if(rc != CL_OK) clAmsMgmtOICacheDestroy(i);
    }
    if(rc != CL_OK)
    {
        for(i = 0; i < CL_AMS_MGMT_OI_EXTENDED_CLASS_MAX; ++i)
            clAmsMgmtOIExtendedCacheDestroy(i);
    }
    if(rc == CL_OK && pHandle)
        *pHandle = handle;
    else 
        clAmsMgmtFinalize(handle);

    return rc;
}
void initializeAmf(void)
{
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    /* Get the pid for the process and store it in global variable. */
    mypid = getpid();

    /* SAFplus is fully API compatible with SA-Forum (SAF) definitions.

       This optional call customizes OpenClovis SAFplus Platform extensions
       to the basic SAF services (to use, you would define the parameters as globals).  
       
       If this call is removed, standard SAF services will work just fine. */

    /* clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); */

    
    /*
     * Initialize and register with SAFplus AMF. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */
    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL; /* rarely necessary because SAFplus monitors the process */
    callbacks.saAmfComponentTerminateCallback   = safTerminate;
    callbacks.saAmfCSISetCallback               = safAssignWork;
    callbacks.saAmfCSIRemoveCallback            = safRemoveWork;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /* Initialize AMF client library. */
    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK)
        errorExit(rc);

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        errorExit(rc);
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        errorExit(rc);
    /* Open the log stream as soon as I've registered with AMF */
    clEvalAppLogStreamOpen((ClCharT *)appName.value, &gEvalLogStream);

    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    /* csa112: initialize the event client library, open the event channel and subscribe to events */
    if (1)
    {
        const SaEvtCallbacksT evtCallbacks =
        {
            NULL,  /* Event open callback */
            csa112Comp_appEventCallback  /* Event delivery callback */
        };
        SaVersionT  evtVersion = {(ClUint8T)'B', 0x1, 0x1};
        
        rc = saEvtInitialize(&evtLibHandle, &evtCallbacks, &evtVersion);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_SEV_ERROR, "Failed to init event mechanism [0x%x]\n", rc);
            return ;
        }
            // Open an event chanel so that we can subscribe to events on that channel
        rc = saEvtChannelOpen(evtLibHandle, &evtChannelName, (SA_EVT_CHANNEL_PUBLISHER | SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE), (SaTimeT)SA_TIME_END, &evtChannelHandle);
        if (rc != SA_AIS_OK)
          {
          clprintf(CL_LOG_SEV_ERROR, "Failure opening event channel [0x%x] at %ld", rc, time(0L));
          errorExit(rc);
          }
        
      rc = saEvtEventSubscribe(evtChannelHandle, NULL, 1);
      if (rc != SA_AIS_OK)
      {
        clprintf(CL_LOG_SEV_ERROR, "Failed to subscribe to event channel [0x%x]",rc);
         errorExit(rc);
      }
    }

    /*csa113: create an event definition to be published */
    if (1)
    {
        SaNameT publisherName;
        saNameSet((SaNameT*) &publisherName,PUBLISHER_NAME);
        
        rc = saEvtEventAllocate(evtChannelHandle, &eventHandle);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_SEV_ERROR, "Failed to allocate event [0x%x]\n", rc);
            assert(0);
        }

        rc = saEvtEventAttributesSet(eventHandle, NULL, 1, 0, &publisherName);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_SEV_ERROR, "Failed to set event attributes [0x%x]\n",rc);
            assert(0);            
        }
    }
}
static PyObject* initializeAmf(PyObject *self, PyObject *args)
{
    SaNameT             appName = {0};
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    ClRcT               rc = SA_AIS_OK;    

    PyEval_InitThreads();    
    PyThreadState* pts = PyThreadState_Get();
    thePythonInterpreter = pts->interp;

    /* Put the EO name received from the environment in the appropriate variable */
    //strncpy(clEoConfig.EOname,getenv("ASP_COMPNAME"),CL_EO_MAX_NAME_LEN-1);
    
    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */

    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL;
    callbacks.saAmfComponentTerminateCallback   = clCompAppTerminate;
    callbacks.saAmfCSISetCallback               = clCompAppAMFCSISet;
    callbacks.saAmfCSIRemoveCallback            = clCompAppAMFCSIRemove;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /*
     * Initialize AMF client library.
     */

    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK) 
        goto errorexit;

    clprintf (CL_LOG_SEV_INFO, "AmfInitialize successful");

    if (1)
    {
        
    SaSelectionObjectT dispatch_fd;
    fd_set read_fds;

    FD_ZERO(&read_fds);

    /*
     * Get the AMF dispatch FD for the callbacks
     */
    if ( (rc = saAmfSelectionObjectGet(amfHandle, &dispatch_fd)) != SA_AIS_OK)
    {
        clprintf (CL_LOG_SEV_ERROR, "Error getting selection object -- unable to dispatch AMF events");
        return NULL;        
    }
    }
    
    /*
     * Do the application specific initialization here.
     */

    /*
     * ---BEGIN_APPLICATION_CODE---
     */

#if 0
    if (1)
      {
      void (*extensions[])(void) = { init_asp, initasppycustom, 0 };
      clPyGlueInit("clusterMgrApp",extensions);
      }
#endif

    /*
     * ---END_APPLICATION_CODE---
     */

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        goto errorexit;
    clprintf (CL_LOG_SEV_INFO, "component name get successful");

    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        goto errorexit;
    clprintf (CL_LOG_SEV_INFO, "component register successful");

    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%d]. Initializing\n", appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    /*
     * ---BEGIN_APPLICATION_CODE---
     */
    //clPyGlueStart();
    /*
     * ---END_APPLICATION_CODE---
     */
    rc = clOsalTaskCreateDetached("AmfDispatcher",CL_OSAL_SCHED_OTHER, CL_OSAL_THREAD_PRI_NOT_APPLICABLE, 0, amfDispatcher,NULL);
    

errorexit:

    if (rc != CL_OK)
      {
        char str[256];
        snprintf(str,255,"Component [%s] : PID [%d]. Initialization error [0x%x]\n", appName.value, mypid, rc);
        clprintf (CL_LOG_SEV_ERROR, str);
        //return PyInt_FromLong(rc);
        PyObject* errData = Py_BuildValue("is",rc,str);
        PyErr_SetObject(PyExc_SystemError,errData);
        return NULL;     
      }
    Py_RETURN_NONE;
    }
ClRcT
clCompAppInitialize(
    ClUint32T argc,
    ClCharT *argv[])
{
    ClNameT             appName;
    ClCpmCallbacksT     callbacks;
    ClVersionT          version;
    ClIocPortT          iocPort;
    ClRcT               rc = CL_OK;

    /*
     * ---BEGIN_APPLICATION_CODE---
     */

    /*
     * Declare other local variables here.
     */

    /*
     * ---END_APPLICATION_CODE---
     */

    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the version of
     * AMF with which this application would like to interface. 'callbacks'
     * is used to register the callbacks this component expects to receive.
     */

    version.releaseCode                         = 'B';
    version.majorVersion                        = 01;
    version.minorVersion                        = 01;
    
    callbacks.appHealthCheck                    = NULL;
    callbacks.appTerminate                      = clCompAppTerminate;
    callbacks.appCSISet                         = clCompAppAMFCSISet;
    callbacks.appCSIRmv                         = clCompAppAMFCSIRemove;
    callbacks.appProtectionGroupTrack           = NULL;
        
    /*
     * Get IOC Address, Port and Name. Register with AMF.
     */

    clEoMyEoIocPortGet(&iocPort);

    if ( (rc = clCpmClientInitialize(&cpmHandle, &callbacks, &version)) ) 
        goto errorexit;

    /*
     * If this component will provide a service, register it now.
     */

#if HAS_EO_SERVICES

    /* Uncomment the following line if the EO is providing services and the 
       method implementations are available for all the methods defined for this EO.

    rc = clcsa102CompEOClientInstall(void);

    */
#endif

    /*
     * Do the application specific initialization here.
     */

    /*
     * ---BEGIN_APPLICATION_CODE---
     */

    clprintf(CL_LOG_SEV_INFO,"csa102: Initializing and registering with CPM...");

    /*
     * ---END_APPLICATION_CODE---
     */

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = clCpmComponentNameGet(cpmHandle, &appName)) ) 
        goto errorexit;
    if ( (rc = clCpmComponentRegister(cpmHandle, &appName, NULL)) ) 
        goto errorexit;

    /*
     * Initialize the log stream
     */
    clEvalAppLogStreamOpen(appName.value, &gEvalLogStream);
    /*
     * Print out standard information for this component.
     */
    clprintf (CL_LOG_SEV_INFO, "Component [%s] : PID [%ld]. Initializing", appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x", iocPort);

    /*
     * This is where the application code starts. If the main thread usage
     * policy is CL_EO_USE_THREAD_FOR_APP, then return from this fn only 
     * after the application terminates. If the main thread usage policy is
     * CL_EO_USE_THREAD_FOR_RECV, then return from this fn after doing the
     * application specific initialization and registration. Main thread usage
     * policy can be set through IDE from Component porperty -> Eo properties.
     */

    /*
     * ---BEGIN_APPLICATION_CODE---
     */
    clprintf(CL_LOG_SEV_INFO,"csa102: Instantiated as component instance %s.", appName.value);

    clprintf(CL_LOG_SEV_INFO,"%s: Waiting for CSI assignment...", appName.value);

    while (!exiting)
    {
        if (running)
        {
            clprintf(CL_LOG_SEV_INFO,"csa102: Hello World! %s", show_progress());
        }
        sleep(1);
    }


    /*
     * ---END_APPLICATION_CODE---
     */

    return rc;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%s] : PID [%ld]. Initialization error [0x%x]",
              appName.value, mypid, rc);

    return rc;
}
void initializeAmf(void)
{
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    /* Get the pid for the process and store it in global variable. */
    mypid = getpid();

    /* SAFplus is fully API compatible with SA-Forum (SAF) definitions.

       This optional call customizes OpenClovis SAFplus Platform extensions
       to the basic SAF services (to use, you would define the parameters as globals).  
       
       If this call is removed, standard SAF services will work just fine. */

    /* clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs); */

    
    /*
     * Initialize and register with SAFplus AMF. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */
    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL; /* rarely necessary because SAFplus monitors the process */
    callbacks.saAmfComponentTerminateCallback   = safTerminate;
    callbacks.saAmfCSISetCallback               = safAssignWork;
    callbacks.saAmfCSIRemoveCallback            = safRemoveWork;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /* Initialize AMF client library. */
    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK)
        errorExit(rc);

    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        errorExit(rc);
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        errorExit(rc);

    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    strncpy(appname, (ClCharT*)appName.value, sizeof(appname)-1);
 
    
    if ((rc = checkpoint_initialize()) != SA_AIS_OK)
    {
        clprintf(CL_LOG_SEV_ERROR,"%s: Failed [0x%x] to initialize checkpoint\n",appname, rc);
        errorExit(rc);
    }
    if ((rc = checkpoint_read_seq(&seq)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_SEV_ERROR,"%s: Failed [0x%x] to read checkpoint\n", appname, rc);
        checkpoint_finalize();
        errorExit(rc);
    }
#ifdef CL_INST
    if ((rc = clDataTapInit(DATA_TAP_DEFAULT_FLAGS, 203)) != CL_OK)
    {
        clprintf(CL_LOG_SEV_ERROR,"%s: Failed [0x%x] to initialize data tap\n", appname, rc);
    }
#endif
    clOsalTaskCreateDetached("testCkpMainLoop", CL_OSAL_SCHED_OTHER, CL_OSAL_THREAD_PRI_NOT_APPLICABLE, 65536, testCkpMainLoop, (void*)appname);
}
int main(int argc, char *argv[])
{
    SaNameT             appName = {0};
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    SaSelectionObjectT dispatch_fd = 0;
    fd_set read_fds;
    
    /*
     * Declare other local variables here.
     */

    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */

    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL;
    callbacks.saAmfComponentTerminateCallback   = clCompAppTerminate;
    callbacks.saAmfCSISetCallback               = clCompAppAMFCSISet;
    callbacks.saAmfCSIRemoveCallback            = clCompAppAMFCSIRemove;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /*
     * Initialize AMF client library.
     */

    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK) 
        goto errorexit;


    /*
     * Do the application specific initialization here.
     */
    
    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        goto errorexit;
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        goto errorexit;

    /*
     * Initialize the log stream
     */
    clEvalAppLogStreamOpen((ClCharT*)appName.value, &gEvalLogStream);

    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);


    /*
     * Block on AMF dispatch file descriptor for callbacks
     */
    do
    {
        struct timeval timeout;
        timeout.tv_sec = 2; timeout.tv_usec = 0;

        FD_ZERO(&read_fds);
        FD_SET(dispatch_fd, &read_fds);

        if( select(dispatch_fd + 1, &read_fds, NULL, NULL, &timeout) < 0)
        {
            if (EINTR == errno)
            {
                continue;
            }
		    clprintf (CL_LOG_SEV_ERROR, "Error in select()");
			perror("");
            break;
        }
        if (FD_ISSET(dispatch_fd,&read_fds)) saAmfDispatch(amfHandle, SA_DISPATCH_ALL);
        
        if (running) clprintf(CL_LOG_SEV_INFO,"csa102: Unthreaded Hello World! %s", show_progress());
        else clprintf(CL_LOG_SEV_INFO,"csa102: idle");        
    }while(!unblockNow);      

    /*
     * Do the application specific finalization here.
     */


    if((rc = saAmfFinalize(amfHandle)) != SA_AIS_OK)
	{
        clprintf (CL_LOG_SEV_ERROR, "AMF finalization error[0x%X]", rc);
	}

    clprintf (CL_LOG_SEV_INFO, "AMF Finalized");
    
    return 0;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%.*s] : PID [%d]. Initialization error [0x%x]\n",
              appName.length, appName.value, mypid, rc);

    return -1;
}
int main(int argc, char *argv[])
{
    SaNameT             appName = {0};
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    SaSelectionObjectT dispatch_fd;
    fd_set read_fds;

    /*
     * Declare other local variables here.
     */


    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the version of
     * AMF with which this application would like to interface. 'callbacks'
     * is used to register the callbacks this component expects to receive.
     */

    version.releaseCode                         = 'B';
    version.majorVersion                        = 01;
    version.minorVersion                        = 01;

    callbacks.saAmfHealthcheckCallback                    = NULL;
    callbacks.saAmfComponentTerminateCallback             = clCompAppTerminate;
    callbacks.saAmfCSISetCallback                         = clCompAppAMFCSISet;
    callbacks.saAmfCSIRemoveCallback                      = clCompAppAMFCSIRemove;
    callbacks.saAmfProtectionGroupTrackCallback           = NULL;
    callbacks.saAmfProxiedComponentInstantiateCallback    = clProxiedCompInstantiate;
    callbacks.saAmfProxiedComponentCleanupCallback        = clProxiedCompCleanup;

    /*
     * Get IOC Address, Port and Name. Register with AMF.
     */

    clEoMyEoIocPortGet(&iocPort);

    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK)
        goto errorexit;

    FD_ZERO(&read_fds);

    /*
     * Get the AMF dispatch FD for the callbacks
     */
    if ( (rc = saAmfSelectionObjectGet(amfHandle, &dispatch_fd)) != SA_AIS_OK)
        goto errorexit;

    FD_SET(dispatch_fd, &read_fds);

    /*
     * Do the application specific initialization here.
     */


    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK)
        goto errorexit;
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK)
        goto errorexit;

    /*
     * Print out standard information for this component.
     */

    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    /*
     * Block on AMF dispatch file descriptor for callbacks
     */
    do
    {
        if( select(dispatch_fd + 1, &read_fds, NULL, NULL, NULL) < 0)
        {
            clprintf (CL_LOG_SEV_ERROR, "Error in select()");
            perror("");
            break;
        }
        saAmfDispatch(amfHandle, SA_DISPATCH_ALL);
    } while(!unblockNow);

    /*
     * Do the application specific finalization here.
     */


    if((rc = saAmfFinalize(amfHandle)) != SA_AIS_OK)
    {
        clprintf (CL_LOG_SEV_ERROR, "AMF finalization error[0x%X]", rc);
    }

    clprintf (CL_LOG_SEV_INFO, "AMF Finalized");

    return 0;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%.*s] : PID [%d]. Initialization error [0x%x]\n",
              appName.length, appName.value, mypid, rc);

    return -1;
}
int main(int argc, char *argv[])
{
    SaNameT             appName = {0};
    SaAmfCallbacksT     callbacks;
    SaVersionT          version;
    ClIocPortT          iocPort;
    SaAisErrorT         rc = SA_AIS_OK;

    SaSelectionObjectT dispatch_fd;
    fd_set read_fds;
    
    /*
     * Declare other local variables here.
     */

    /*
     * Get the pid for the process and store it in global variable.
     */

    mypid = getpid();

    /*
     * Initialize and register with CPM. 'version' specifies the
     * version of AMF with which this application would like to
     * interface. 'callbacks' is used to register the callbacks this
     * component expects to receive.
     */

    version.releaseCode  = 'B';
    version.majorVersion = 01;
    version.minorVersion = 01;
    
    callbacks.saAmfHealthcheckCallback          = NULL;
    callbacks.saAmfComponentTerminateCallback   = clCompAppTerminate;
    callbacks.saAmfCSISetCallback               = clCompAppAMFCSISet;
    callbacks.saAmfCSIRemoveCallback            = clCompAppAMFCSIRemove;
    callbacks.saAmfProtectionGroupTrackCallback = NULL;
        
    /*
     * Initialize AMF client library.
     */

    if ( (rc = saAmfInitialize(&amfHandle, &callbacks, &version)) != SA_AIS_OK) 
        goto errorexit;

    FD_ZERO(&read_fds);

    /*
     * Get the AMF dispatch FD for the callbacks
     */
    if ( (rc = saAmfSelectionObjectGet(amfHandle, &dispatch_fd)) != SA_AIS_OK)
        goto errorexit;
    
    FD_SET(dispatch_fd, &read_fds);


    /*
     * Do the application specific initialization here.
     */


    /*
     * Now register the component with AMF. At this point it is
     * ready to provide service, i.e. take work assignments.
     */

    if ( (rc = saAmfComponentNameGet(amfHandle, &appName)) != SA_AIS_OK) 
        goto errorexit;
    if ( (rc = saAmfComponentRegister(amfHandle, &appName, NULL)) != SA_AIS_OK) 
        goto errorexit;

    /* Open the log stream as soon as I've registered with AMF */
    clEvalAppLogStreamOpen((ClCharT *)appName.value, &gEvalLogStream);

    /* Handle the AMF dispatch loop by spawning a thread that does it */
    rc = clOsalTaskCreateDetached("DISPATCH-THREAD", CL_OSAL_SCHED_OTHER, 0, 0, saAmfDispatchThread, NULL);
    if(rc != CL_OK)
    {
        clprintf(CL_LOG_SEV_ERROR, "Dispatch task create failed with rc 0x%x",rc);
        return rc;
    }
    
    /*
     * Print out standard information for this component.
     */

    clEoMyEoIocPortGet(&iocPort);
    
    clprintf (CL_LOG_SEV_INFO, "Component [%.*s] : PID [%d]. Initializing\n", appName.length, appName.value, mypid);
    clprintf (CL_LOG_SEV_INFO, "   IOC Address             : 0x%x\n", clIocLocalAddressGet());
    clprintf (CL_LOG_SEV_INFO, "   IOC Port                : 0x%x\n", iocPort);

    /* csa112: initialize the event client library, open the event channel and subscribe to events */
    if (1)
    {
        const SaEvtCallbacksT evtCallbacks =
        {
            NULL,  /* Event open callback */
            csa112Comp_appEventCallback  /* Event delivery callback */
        };
        SaVersionT  evtVersion = {(ClUint8T)'B', 0x1, 0x1};
        
        rc = saEvtInitialize(&evtLibHandle, &evtCallbacks, &evtVersion);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_ERROR, "Failed to init event mechanism [0x%x]\n", rc);
            return rc;
        }
            // Open an event chanel so that we can subscribe to events on that channel
        rc = saEvtChannelOpen(evtLibHandle, &evtChannelName, (SA_EVT_CHANNEL_PUBLISHER | SA_EVT_CHANNEL_SUBSCRIBER | SA_EVT_CHANNEL_CREATE), (SaTimeT)SA_TIME_END, &evtChannelHandle);
        if (rc != SA_AIS_OK)
          {
          clprintf(CL_LOG_SEV_ERROR, "Failure opening event channel [0x%x] at %ld", rc, time(0L));
          goto errorexit;
          }
        
      rc = saEvtEventSubscribe(evtChannelHandle, NULL, 1);
      if (rc != SA_AIS_OK)
      {
        clprintf(CL_LOG_SEV_ERROR, "Failed to subscribe to event channel [0x%x]",rc);
        goto errorexit;
      }
    }

    /*csa113: create an event definition to be published */
    if (1)
    {
        SaNameT publisherName;
        clNameSet((ClNameT*) &publisherName,PUBLISHER_NAME);
        
        rc = saEvtEventAllocate(evtChannelHandle, &eventHandle);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_SEV_ERROR, "Failed to allocate event [0x%x]\n", rc);
            assert(0);
        }

        rc = saEvtEventAttributesSet(eventHandle, NULL, 1, 0, &publisherName);
        if (rc != SA_AIS_OK)
        {
            clprintf(CL_LOG_ERROR, "Failed to set event attributes [0x%x]\n",rc);
            assert(0);            
        }
    }
    
    
    while (!exiting)
    {
        /* csa112: If I am active then I'll publish an event.
           Note, any application can publish and event regardless of
           HA state.  This tutorial simply uses HA state so only
           one of the two processes are publishing.
        */
        
    if (running && ha_state == SA_AMF_HA_ACTIVE)
    {
        csa113Comp_PublishEvent();
    }
    
    sleep(1);  /* Keep the event publish rate reasonable for this tutorial*/
    }
    
    /*
     * Do the application specific finalization here.
     */

    /* csa112: close the event channel, finalize the event client library */
    if ((rc = saEvtChannelClose(evtChannelHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_ERROR, "Failed [0x%x] to close event channel", rc);
    }

    if ((rc = saEvtFinalize(evtLibHandle)) != SA_AIS_OK)
    {
        clprintf(CL_LOG_ERROR, "Failed [0x%x] to finalize event library", rc);
    }

    if((rc = saAmfFinalize(amfHandle)) != SA_AIS_OK)
	{
        clprintf (CL_LOG_SEV_ERROR, "AMF finalization error[0x%X]", rc);
	}

    clprintf (CL_LOG_SEV_INFO, "AMF Finalized");
    
    return 0;

errorexit:

    clprintf (CL_LOG_SEV_ERROR, "Component [%.*s] : PID [%d]. Initialization error [0x%x]\n",
              appName.length, appName.value, mypid, rc);

    return -1;
}