ClRcT clCkptMasterAddressesSet()
{
    ClRcT rc = CL_OK;
#ifdef CL_CKPT_GMS 
    /*
     * GMS available.
     */
     
    /* 
     * Contact GMS to get master and backup master addresses.
     */
    ClGmsClusterNotificationBufferT notBuffer;
    memset((void*)&notBuffer , 0, sizeof(notBuffer));
    memset( &notBuffer , '\0' ,sizeof(ClGmsClusterNotificationBufferT));
    
    /*
     * Initialize the gms client library.
     */
    rc = clGmsInitialize(&gCkptSvr->gmsHdl, &ckptGmsCallbacks,
                        &gVersion);
    CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR,
    (" clCkptMasterAddressesSet failed rc[0x %x]\n",rc),
        rc);
        
    /* 
     * Register for current track and track changes.
     */
    rc = clGmsClusterTrack(gCkptSvr->gmsHdl, 
                           CL_GMS_TRACK_CHANGES|CL_GMS_TRACK_CURRENT, 
                           &notBuffer);
                           
    /*
     * Call the track change callback function. This is needed for getting
     * current track information.
     */
    if(rc == CL_OK && notBuffer.leader &&
       notBuffer.leader != CL_GMS_INVALID_NODE_ID)
    {
        _clCkptAddressesUpdate(&notBuffer);
    }

    if (notBuffer.notification != NULL)
      clHeapFree(notBuffer.notification);

#else
    /*
     * GMS unavailable.
     */

     /*
      * Select cpm master as ckpt master. Deputy will be unspecified.
      */
    clCpmMasterAddressGet(&gCkptSvr->masterInfo.masterAddr);
    gCkptSvr->masterInfo.deputyAddr = -1;

    /*
     * Update the TL with ckpt master address.
     */
    if(gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr )
    {
        ClIocTLInfoT tlInfo = {0};
        ClUint32T    compId = 0; 
        SaNameT      name   = {0};
 
        clCpmComponentNameGet(gCkptSvr->amfHdl, &name);
        clCpmComponentIdGet(gCkptSvr->amfHdl, &name, &compId);
        tlInfo.compId                   = compId;
        gCkptSvr->masterInfo.compId     = compId;
        ckptOwnLogicalAddressGet(&tlInfo.logicalAddr);
        tlInfo.contextType              = CL_IOC_TL_GLOBAL_SCOPE;
        tlInfo.physicalAddr.nodeAddress = clIocLocalAddressGet();
        tlInfo.physicalAddr.portId      = CL_IOC_CKPT_PORT;
        tlInfo.haState                  = CL_IOC_TL_ACTIVE;
        rc = clIocTransparencyRegister(&tlInfo);
    }
#endif
#ifdef CL_CKPT_GMS 
exitOnError:
#endif
    {
        return rc;
    }
}
ClRcT clCpmCompGet(ClUint32T argc, ClCharT *argv[], ClCharT **retStr)
{
    ClRcT rc = CL_OK;
    ClNameT compName = { 0 };
    ClIocAddressT compAddress;
    ClUint32T compId = 0;
    ClCharT buffer[2048] = "\0";
    ClUint32T length = 0;
    ClIocNodeAddressT nodeAddress;

    if (!strcasecmp("compAddressGet", argv[0]))
    {
        if (argc != THREE_ARGUMENT)
        {
            sprintf(buffer, "%s",
                    "Usage: compAddressGet <CompName> <nodeIocAddress>\n"
                    "\tcompName[STRING] - component Name\n"
                    "\tnodeIocAddress[DEC] - node ioc Address, where the component exist\n");
            rc = CL_CPM_RC(CL_ERR_INVALID_PARAMETER);
            goto done;
        }
        strcpy(compName.value, argv[1]);
        compName.length = strlen(argv[1]);
        nodeAddress = (ClIocNodeAddressT) cpmCliStrToInt(argv[2]);
        rc = clCpmComponentAddressGet(nodeAddress, &compName, &compAddress);
        if (rc == CL_OK)
            sprintf(buffer, "Address %d Port %x\n",
                    compAddress.iocPhyAddress.nodeAddress,
                    compAddress.iocPhyAddress.portId);
        else
            sprintf(buffer, "Failed get component Address, rc = 0x%x", rc);
    }
    else if (!strcasecmp("compIdGet", argv[0]))
    {
        if (argc != TWO_ARGUMENT)
        {
            sprintf(buffer, "%s",
                    "Usage: compIdGet <CompName> \n"
                    "\tcompName[STRING] - component Name\n");
            rc = CL_CPM_RC(CL_ERR_INVALID_PARAMETER);
           goto done;
        }
        strcpy(compName.value, argv[1]);
        compName.length = strlen(argv[1]);
        rc = clCpmComponentIdGet(0, &compName, &compId);
        if (rc == CL_OK)
            sprintf(buffer, "compId is %d\n", compId);
        else
            sprintf(buffer, "Failed get component Id, rc = 0x%x", rc);
    }
    else if (!strcasecmp("compPIDGet", argv[0]))
    {
        if (argc != TWO_ARGUMENT)
        {
            sprintf(buffer, "%s",
                    "Usage: compPidGet <CompName> \n"
                    "\tcompName[STRING] - component Name\n");
            rc = CL_CPM_RC(CL_ERR_INVALID_PARAMETER);
            goto done;
        }
        strcpy(compName.value, argv[1]);
        compName.length = strlen(argv[1]);
        rc = clCpmComponentPIDGet(&compName, &compId);
        if (rc == CL_OK)
            sprintf(buffer, "compPId is %d\n", compId);
        else
            sprintf(buffer, "Failed get component PID, rc = 0x%x", rc);
    }
    else if (!strcasecmp("compTraceGet", argv[0]))
    {
        ClPtrT ppOutMem = NULL;
        ClUint32T segmentSize = 0;
        ClFdT fd = 0;
#ifndef POSIX_BUILD
        ClCharT compShmSegment[CL_MAX_NAME_LENGTH];
        segmentSize = getpagesize();
        if (argc != TWO_ARGUMENT)
        {
            sprintf(buffer, "%s",
                    "Usage: compTraceGet <CompName> \n"
                    "\tcompName[STRING] - component Name \n");
            rc = CL_CPM_RC(CL_ERR_INVALID_PARAMETER);
            goto done;
        }
        strcpy(compName.value, argv[1]);
        snprintf(compShmSegment, sizeof(compShmSegment), "/CL_%s_exception_%d", compName.value, clIocLocalAddressGet());
        rc = clOsalShmOpen(compShmSegment, O_RDONLY, 0777, &fd);
        if(rc == CL_OK)
        {
            rc = clOsalMmap(0, segmentSize, PROT_READ, MAP_PRIVATE, fd, 0, &ppOutMem);
        }
#endif
        if (ppOutMem)
        {
            sprintf(buffer, "%s\n", (ClCharT*)ppOutMem);
            clOsalMunmap(ppOutMem, segmentSize);
            close(fd);
        }
        else
            sprintf(buffer, "%s\n", "Unable to get the component Stack Trace");
    }
  done:
    length = strlen(buffer) + 1;
    *retStr = (ClCharT *) clHeapAllocate(length);
    if (*retStr != NULL)
        strcpy(*retStr, buffer);
    else
        rc = CL_CPM_RC(CL_ERR_NO_MEMORY);

    return rc;
}
/*
 * This function will be called either from GMS track callback or 
 * IOC notification, it receives the master address & deputy and 
 * process the same
 */
ClRcT
clCkptMasterAddressUpdate(ClIocNodeAddressT  leader, 
                          ClIocNodeAddressT  deputy)
{
    ClIocTLInfoT tlInfo    = {0};
    SaNameT      name      = {0};
    ClRcT        rc        = CL_OK;
    ClBoolT      updateReq = CL_FALSE;

    /*
     * Check whether master or deputy address has changed.
     */
    if(gCkptSvr->masterInfo.masterAddr != leader)
    {
        /*
         * Master address changed.
         */
        updateReq = CL_TRUE;
        gCkptSvr->masterInfo.prevMasterAddr = gCkptSvr->masterInfo.masterAddr;    
        gCkptSvr->masterInfo.masterAddr     = leader;    
        
        /*
         * Deregister the old TL entry.
         */
        if(gCkptSvr->masterInfo.compId != CL_CKPT_UNINIT_VALUE)
        {
            rc = clIocTransparencyDeregister(gCkptSvr->masterInfo.compId);
        }
        else
        {
            clCpmComponentNameGet(gCkptSvr->amfHdl, &name);
            clCpmComponentIdGet(gCkptSvr->amfHdl, &name, 
                                &gCkptSvr->compId);
            gCkptSvr->masterInfo.compId = gCkptSvr->compId;
        }

        /*
         * Update the TL.
         */
        if(gCkptSvr->masterInfo.masterAddr == clIocLocalAddressGet())
        {
            ckptOwnLogicalAddressGet(&tlInfo.logicalAddr);
            tlInfo.compId                   = gCkptSvr->compId;
            gCkptSvr->masterInfo.compId     = gCkptSvr->compId;
            tlInfo.contextType              = CL_IOC_TL_GLOBAL_SCOPE;
            tlInfo.physicalAddr.nodeAddress = clIocLocalAddressGet();
            tlInfo.physicalAddr.portId      = CL_IOC_CKPT_PORT;
            tlInfo.haState                  = CL_IOC_TL_ACTIVE;
            rc = clIocTransparencyRegister(&tlInfo);
        }
        /*
         * update the ioc notify callbacks for the new master address 
         * Once address update is over, then we have uninstall the registered
         * callback and reregistered to new master address
         */
        clCkptIocCallbackUpdate();
    }
    
    if(gCkptSvr->masterInfo.deputyAddr != deputy)
    {
        /*
         * Deputy address has changed.
         */
        updateReq = CL_TRUE;
        gCkptSvr->masterInfo.deputyAddr = deputy ;    
    }

    /*
     * Signal the receipt of master and deputy addresses. 
     */
    clOsalMutexLock(gCkptSvr->mutexVar);
    if(gCkptSvr->condVarWaiting == CL_TRUE)
    {
        gCkptSvr->condVarWaiting = CL_FALSE;
        clOsalCondSignal(gCkptSvr->condVar);
    }
    clOsalMutexUnlock(gCkptSvr->mutexVar);

    /* 
     * Update the old master(if existing) with the new leader addresses.
     */
    if((updateReq == CL_TRUE) && 
       (((ClInt32T) gCkptSvr->masterInfo.prevMasterAddr != -1) &&
       (gCkptSvr->masterInfo.prevMasterAddr != CL_CKPT_UNINIT_ADDR)))
    {
        rc = ckptIdlHandleUpdate(gCkptSvr->masterInfo.prevMasterAddr,
                                 gCkptSvr->ckptIdlHdl,0);
        rc = VDECL_VER(clCkptLeaderAddrUpdateClientAsync, 4, 0, 0)(gCkptSvr->ckptIdlHdl,
                                    gCkptSvr->masterInfo.masterAddr,
                                    gCkptSvr->masterInfo.deputyAddr,
                                    NULL,0);
    }
    clLogNotice("ADDR", "UPDATE", "CKPT master [%d], deputy [%d]",
                gCkptSvr->masterInfo.masterAddr, gCkptSvr->masterInfo.deputyAddr);
    return rc;
}