Пример #1
0
ClRcT clRmdObjInit(ClRmdObjHandleT *p)
{
    ClRcT retCode = CL_OK;
    ClRmdObjT *pRmdObject = NULL;
    //unsigned long timeStamp = 0;
    struct timeval tm1;

#ifdef DEBUG
    static ClUint8T rmdAddedTodbgComp = CL_FALSE;

    if (CL_FALSE == rmdAddedTodbgComp)
    {
        retCode = dbgAddComponent(COMP_PREFIX, COMP_NAME, COMP_DEBUG_VAR_PTR);
        rmdAddedTodbgComp = CL_TRUE;
        if (CL_OK != retCode)
        {
            clLogError("OBG","INI","dbgAddComponent FAILED ");
            CL_FUNC_EXIT();
            return retCode;
        }
    }
#endif
    CL_FUNC_ENTER();

    if (NULL == p)
    {
        RMD_DBG1((" RMD Invalid Object handle passed\n"));
        CL_FUNC_EXIT();
        return ((CL_RMD_RC(CL_ERR_INVALID_PARAMETER)));
    }

    retCode = clOsalInitialize(NULL);

    retCode = clTimerInitialize(NULL);
    pRmdObject = (ClRmdObjT *) clHeapAllocate(sizeof(ClRmdObjT));

    if (NULL == pRmdObject)
    {
        RMD_DBG1((" RMD No Memory\n"));
        CL_FUNC_EXIT();
        return ((CL_RMD_RC(CL_ERR_NO_MEMORY)));
    }

    gettimeofday(&tm1, NULL);
    //timeStamp = tm1.tv_sec * 1000000 + tm1.tv_usec;
    pRmdObject->msgId = 1;
    retCode = clOsalMutexCreate(&pRmdObject->semaForSendHashTable);

    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD send Mutex creation failed\n"));
        CL_FUNC_EXIT();
        return (retCode);
    }
    retCode = clOsalMutexCreate(&pRmdObject->semaForRecvHashTable);

    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  recv Mutex creation failed\n"));

        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }

    retCode =
        clCntHashtblCreate(NUMBER_OF_RECV_BUCKETS, recvKeyCompare,
                           recvHashFunction, recvHashDeleteCallBack,
                           recvHashDeleteCallBack, CL_CNT_UNIQUE_KEY,
                           &pRmdObject->rcvRecContainerHandle);
    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  send Hash table creation failed\n"));

        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }
    retCode =
        clCntHashtblCreate(NUMBER_OF_SEND_BUCKETS, sendKeyCompare,
                           sendHashFunction, sendHashDeleteCallBack,
                           sendHashDestroyCallBack, CL_CNT_UNIQUE_KEY,
                           &pRmdObject->sndRecContainerHandle);
    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  recv Hash table creation failed\n"));

        IGNORE_RETURN(clCntDelete(pRmdObject->rcvRecContainerHandle));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }

    pRmdObject->responseCntxtDbHdl = 0;
    retCode = clHandleDatabaseCreate(NULL, &pRmdObject->responseCntxtDbHdl);
    if (retCode != CL_OK)
    {
        RMD_DBG1((" RMD  Sync Handle Database create failed\n"));
        IGNORE_RETURN(clCntDelete(pRmdObject->sndRecContainerHandle));
        IGNORE_RETURN(clCntDelete(pRmdObject->rcvRecContainerHandle));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));

        CL_FUNC_EXIT();
        return retCode;
    }

    pRmdObject->numAtmostOnceEntry = 0;
    pRmdObject->lastAtmostOnceCleanupTime = clOsalStopWatchTimeGet();
    pRmdObject->rmdStats.nRmdCalls = 0;
    pRmdObject->rmdStats.nFailedCalls = 0;
    pRmdObject->rmdStats.nResendRequests = 0;
    pRmdObject->rmdStats.nRmdReplies = 0;
    pRmdObject->rmdStats.nBadReplies = 0;
    pRmdObject->rmdStats.nRmdRequests = 0;
    pRmdObject->rmdStats.nBadRequests = 0;
    pRmdObject->rmdStats.nCallTimeouts = 0;
    pRmdObject->rmdStats.nDupRequests = 0;
    pRmdObject->rmdStats.nAtmostOnceCalls = 0;
    pRmdObject->rmdStats.nResendReplies = 0;
    pRmdObject->rmdStats.nReplySend = 0;
    pRmdObject->rmdStats.nRmdCallOptimized = 0;
    *p = (ClRmdObjHandleT) pRmdObject;
    CL_FUNC_EXIT();
    return (CL_OK);
}
static ClRcT cpmNodeRmv(ClCharT *nodeName)
{
    ClRcT rc = CL_OK;
    ClUint16T nodeKey = 0;
    ClCntNodeHandleT hNode = 0;
    ClUint32T numNode = 0;
    ClCpmLT *cpm = NULL;
    ClBoolT done = CL_NO;
    if (!nodeName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "NULL pointer passed.");
        goto failure;
    }

    rc = clCksm16bitCompute((ClUint8T *)nodeName,
                            strlen(nodeName),
                            &nodeKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for node, "
                   "error [%#x]",
                   rc);
        goto failure;
    }

    clOsalMutexLock(gpClCpm->cpmTableMutex);

    rc = clCntNodeFind(gpClCpm->cpmTable,
                       (ClCntKeyHandleT)(ClWordT)nodeKey,
                       &hNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to find node [%s], error [%#x]",
                   nodeName,
                   rc);
        goto unlock;
    }

    rc = clCntKeySizeGet(gpClCpm->cpmTable,
                         (ClCntKeyHandleT)(ClWordT)nodeKey,
                         &numNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Unable to get key size, error [%#x]",
                   rc);
        goto unlock;
    }

    while (numNode > 0)
    {
        rc = clCntNodeUserDataGet(gpClCpm->cpmTable,
                                  hNode,
                                  (ClCntNodeHandleT *) &cpm);
        if (CL_OK != rc)
        {
            clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                       "Unable to get user data, error [%#x]",
                       rc);
            goto unlock;
        }

        if (!strncmp(nodeName, cpm->nodeName, CL_MAX_NAME_LENGTH-1))
        {
            clCntNodeDelete(gpClCpm->cpmTable, hNode);
            done = CL_YES;
            break;
        }

        if (--numNode)
        {
            rc = clCntNextNodeGet(gpClCpm->cpmTable, hNode, &hNode);
            if (CL_OK != rc)
            {
                break;
            }
        }
    }

    if (!done)
    {
        rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST);
        goto unlock;
    }

    --gpClCpm->noOfCpm;

    clOsalMutexUnlock(gpClCpm->cpmTableMutex);

    /*
     * Delete from slot table
     */
    clOsalMutexLock(&gpClCpm->cpmMutex);
    if(cpmSlotClassDelete(nodeName) != CL_OK)
    {
        clLogWarning("CPM", "MGMT", "Slot class delete failed for node [%s]", nodeName);
    }
    clOsalMutexUnlock(&gpClCpm->cpmMutex);

    return CL_OK;

unlock:
    clOsalMutexUnlock(gpClCpm->cpmTableMutex);
failure:
    return rc;
}
static ClRcT cpmComponentAdd(ClCharT *compName)
{
    ClRcT rc = CL_CPM_RC(CL_ERR_NULL_POINTER);
    ClCpmCompConfigT compConfig = 
    {
        "",
        CL_FALSE,
        CL_AMS_COMP_PROPERTY_SA_AWARE,
        CL_CPM_COMP_SINGLE_PROCESS,
        "invalid",
        {(ClCharT*) "invalid", NULL},
        {NULL},
        "",
        "",
        0,
        0,
        0,
        0,
        0,
        {
            CL_CPM_COMPONENT_DEFAULT_HC_TIMEOUT,
            2 * CL_CPM_COMPONENT_DEFAULT_HC_TIMEOUT,
            CL_AMS_RECOVERY_NO_RECOMMENDATION
        }
    };
    ClCpmComponentT *comp = NULL;
    ClUint16T compKey = 0;
    const ClCharT *config = NULL;
    ClCharT cleanupCMD[CL_MAX_NAME_LENGTH];
        
    if (!compName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "NULL pointer passed.");
        goto failure;
    }

    cleanupCMD[0] = 0;
    if( (config = getenv("ASP_CONFIG")) )
    {
        snprintf(cleanupCMD, sizeof(cleanupCMD), "%s/%s", config, CL_CPM_COMP_CLEANUP_SCRIPT);
        if(access(cleanupCMD, R_OK | X_OK))
            cleanupCMD[0] = 0;
    }
    rc = cpmCompFind((SaUint8T *)compName, gpClCpm->compTable, &comp);
    if (comp)
    {
        clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                     "Component [%s] already exists on this node",
                     compName);
        rc = CL_CPM_RC(CL_ERR_ALREADY_EXIST);
        goto failure;
    }

    strncpy(compConfig.compName, compName, CL_MAX_NAME_LENGTH-1);
    if(cleanupCMD[0])
        strncpy(compConfig.cleanupCMD, cleanupCMD, sizeof(compConfig.cleanupCMD)-1);

    rc = cpmCompConfigure(&compConfig, &comp);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to configure component, error [%#x]",
                   rc);
        goto failure;
    }

    rc = clCksm16bitCompute((ClUint8T *) comp->compConfig->compName,
                            strlen(comp->compConfig->compName),
                            &compKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for component, "
                   "error [%#x]",
                   rc);
        goto failure;
    }

    clOsalMutexLock(gpClCpm->compTableMutex);
    rc = clCntNodeAdd(gpClCpm->compTable,
                      (ClCntKeyHandleT)(ClWordT)compKey,
                      (ClCntDataHandleT) comp,
                      NULL);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to add node to the CPM component table, "
                   "error [%#x]",
                   rc);
        clOsalMutexUnlock(gpClCpm->compTableMutex);
        goto failure;
    }
    ++gpClCpm->noOfComponent;
    clOsalMutexUnlock(gpClCpm->compTableMutex);

    return CL_OK;

failure:
    return rc;
}
ClRcT 
clFaultHistoryInit(ClUint32T binNumbers){

   ClRcT          rc = CL_OK;
   ClTimerTimeOutT      timeOut;


   /* fault history containers can be accessed by FM thread, timer thread
    * etc .. So before accessing the containers, the threads shd take the
    * mutex
    */
    rc = clOsalMutexCreateAndLock(&shfaultHistoryMutex);
    if (rc != CL_OK)
    {
        clLogWrite(CL_LOG_HANDLE_APP, 
               CL_LOG_ERROR,   
               CL_FAULT_SERVER_LIB,
               CL_FAULT_LOG_1_MUTEX,
               "Fault History data base");
      return CL_FAULT_ERR_HISTORY_MUTEX_CREATE_ERROR;
    }

   /* 
    * Create a circular queue with number of nodes = binNumbers
    * Each node is a linked list of fault recovery/history record 
       sorted by key composed of category and severity
    */
   /*
    * Create a repetitive timer at frequency interval = binInterval
    */

   rc = clClistCreate( MAX_FAULT_BUCKETS,
                          CL_DROP_FIRST,
                           (ClClistDeleteCallbackT) clFaultHis2MinBucketDelete,
                           (ClClistDeleteCallbackT) clFaultHis2MinBucketDelete,
                           &sfaultHistoryList);

   if (rc != CL_OK ) 
   {
      clLogError("FLT", NULL, "Error in creating Clist, rc [0x%x]", 
              rc);
      goto unlock_exit;
   }


   /* start a 2 minute timer */
    timeOut.tsSec = binNumbers;
    timeOut.tsMilliSec = 0; 

    if ((rc = clTimerCreate(timeOut,
                              CL_TIMER_REPETITIVE,
                              CL_TIMER_SEPARATE_CONTEXT, 
                              (ClTimerCallBackT) clFault2MinHistoryCallback,
                              NULL, 
                              &sFaultMan2MinHistoryTimerH)
                            ) != CL_OK)
   {
     clLogError("FLT", NULL, "Failed to create repetitive timer for \
                            fault manager's 2 min history");
      goto unlock_exit;
    }
static ClRcT cpmComponentRmv(ClCharT *compName)
{
    ClRcT rc = CL_OK;
    ClUint16T compKey = 0;
    ClCntNodeHandleT hNode = 0;
    ClUint32T numNode = 0;
    ClCpmComponentT *comp = NULL;
    ClBoolT done = CL_NO;
    SaNameT entity = {0};

    if (!compName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "NULL pointer passed.");
        goto failure;
    }

    rc = clCksm16bitCompute((ClUint8T *)compName,
                            strlen(compName),
                            &compKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for component, "
                   "error [%#x]",
                   rc);
        goto failure;
    }
    saNameSet(&entity, compName);
    /*
     * Clear pending invocations for the component being removed.
     */
    (void)cpmInvocationClearCompInvocation(&entity);
    clOsalMutexLock(gpClCpm->compTableMutex);
    clOsalMutexLock(&gpClCpm->compTerminateMutex);

    rc = clCntNodeFind(gpClCpm->compTable,
                       (ClCntKeyHandleT)(ClWordT)compKey,
                       &hNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to find component [%s], error [%#x]",
                   compName,
                   rc);
        goto unlock;
    }

    rc = clCntKeySizeGet(gpClCpm->compTable,
                         (ClCntKeyHandleT)(ClWordT)compKey,
                         &numNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Unable to get key size, error [%#x]",
                   rc);
        goto unlock;
    }

    while (numNode > 0)
    {
        rc = clCntNodeUserDataGet(gpClCpm->compTable,
                                  hNode,
                                  (ClCntNodeHandleT *) &comp);
        if (CL_OK != rc)
        {
            clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                       "Unable to get user data, error [%#x]",
                       rc);
            goto unlock;
        }

        if (!strncmp(compName,
                     comp->compConfig->compName,
                     CL_MAX_NAME_LENGTH-1))
        {
            clCntNodeDelete(gpClCpm->compTable, hNode);
            done = CL_YES;
            break;
        }

        if (--numNode)
        {
            rc = clCntNextNodeGet(gpClCpm->compTable, hNode, &hNode);
            if (CL_OK != rc)
            {
                break;
            }
        }
    }

    if (!done)
    {
        rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST);
        goto unlock;
    }
    
    --gpClCpm->noOfComponent;

    clOsalMutexUnlock(&gpClCpm->compTerminateMutex);
    clOsalMutexUnlock(gpClCpm->compTableMutex);

    return CL_OK;

unlock:
    clOsalMutexUnlock(&gpClCpm->compTerminateMutex);
    clOsalMutexUnlock(gpClCpm->compTableMutex);
failure:
    return rc;
}
Пример #6
0
ClRcT
clHandleMove(
    ClHandleDatabaseHandleT databaseHandle,
    ClHandleT oldHandle,
    ClHandleT newHandle)
{
	void           *instance = NULL;
    ClRcT          rc        = CL_OK;
    ClHdlDatabaseT *hdbp     = (ClHdlDatabaseT*) databaseHandle;
    ClRcT          ec        = CL_OK;

    hdlDbValidityChk(hdbp);
    /* We allow handles to be created that are pointing to some other handle DB and node hdlValidityChk(handle,hdbp); */
    oldHandle = CL_HDL_IDX(oldHandle); /* once we've verified it, we only care about the index */
    newHandle = CL_HDL_IDX(newHandle);
    
    if (CL_HANDLE_INVALID_VALUE == oldHandle 
        ||
        CL_HANDLE_INVALID_VALUE == newHandle)
    {
        clLogError("HDL", "MOVE",
                   "Passed [%s] handle is invalid",
                   oldHandle ? "new" : "old");
        clDbgPause();
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */
    }
    /*
     * Decrementing handle to ensure the non-zero handle interface.
     */
    --oldHandle;
    --newHandle;
    ec = pthread_mutex_lock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR);
    }

    if(oldHandle >= hdbp->n_handles)
    {
        pthread_mutex_unlock(&hdbp->mutex);
        clLogError("HDL", "MOVE", "Old handle [%#llx] passed is invalid", oldHandle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE);
    }

    if(hdbp->handles[oldHandle].ref_count != 1)
    {
        pthread_mutex_unlock(&hdbp->mutex);
        clLogError("HDL", "MOVE", "Old handle [%#llx] is %s", 
                   oldHandle, hdbp->handles[oldHandle].ref_count < 1 ? "invalid" : "in use");
        return CL_HANDLE_RC(CL_ERR_INVALID_STATE);
    }
    
    if(newHandle < hdbp->n_handles && hdbp->handles[newHandle].ref_count > 0)
    {
        pthread_mutex_unlock(&hdbp->mutex);
        clLogError("HDL", "MOVE", "New handle [%#llx] is in use", newHandle);
        return CL_HANDLE_RC(CL_ERR_ALREADY_EXIST);
    }

    instance = hdbp->handles[oldHandle].instance;
    if(!instance)
    {
        pthread_mutex_unlock(&hdbp->mutex);
        clLogError("HDL", "MOVE", "Old handle [%#llx] instance is NULL", oldHandle);
        return CL_HANDLE_RC(CL_ERR_INVALID_STATE);
    }

    if(newHandle >= hdbp->n_handles)
    {
        /*
         * Allocating space in Excess of to accomodate the value specified by the user.
         * NOTE: User should ensure that a sane value is supplied for handle.
         */
        ClHandleT excess_handles = newHandle - hdbp->n_handles + 1;

		ClHdlEntryT *new_handles = (ClHdlEntryT *)realloc (hdbp->handles,
                                                           sizeof (ClHdlEntryT) * (hdbp->n_handles+excess_handles));
		if (new_handles == NULL) 
        {
			ec = pthread_mutex_unlock (&hdbp->mutex);
            if (ec != 0)
            {
                return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be very bad */
            }
			return CL_HANDLE_RC(CL_ERR_NO_MEMORY);
		}

        /* 
         * Initialize the excess space. HANDLE_STATE_EMPTY will remain 0 
         * is assumed else need to set the excess entries explicitly in a 
         * loop. 
         */
        memset(&new_handles[hdbp->n_handles], 0, sizeof (ClHdlEntryT) * excess_handles);

        /* Update the values if success */
		hdbp->n_handles += excess_handles;
		hdbp->handles = new_handles;
	}
    /*
     * Reset the old handle
     */
    memset(&hdbp->handles[oldHandle], 0, sizeof(hdbp->handles[oldHandle]));
	hdbp->handles[newHandle].state = HANDLE_STATE_USED;
	hdbp->handles[newHandle].instance = instance;
	hdbp->handles[newHandle].ref_count = 1;
	hdbp->handles[newHandle].handle = CL_HDL_MAKE_ADDR(ASP_NODEADDR, gEOIocPort, hdbp->id, newHandle + 1);;

    clDbgResourceNotify(clDbgHandleResource, clDbgAllocate, hdbp, newHandle+1, ("Specific handle [%p:%#llx] allocated", (ClPtrT) hdbp, newHandle+1));

	ec = pthread_mutex_unlock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
    }
	return rc;
}
Пример #7
0
ClRcT
clHandleCheckin(
                ClHandleDatabaseHandleT databaseHandle,
                ClHandleT handle)
{
    ClRcT          rc        = CL_OK;
    void           *instance = NULL;
    ClHdlDatabaseT *hdbp     = (ClHdlDatabaseT*) databaseHandle;
    ClRcT          ec        = CL_OK;
    ClInt32T       refcount  = 0;

    hdlDbValidityChk(hdbp);
    /* sometimes people want to create the same handle across multiple nodes hdlValidityChk(handle,hdbp); */
    handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */
    /*
     * Decrementing handle to ensure the non-zero handle interface.
     */
    if (CL_HANDLE_INVALID_VALUE == handle--)
    {
        clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN, "Passed handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */
    }

    ec = pthread_mutex_lock(&hdbp->mutex);
    if (ec != 0)
    {
        clDbgCodeError(CL_HANDLE_RC(CL_ERR_MUTEX_ERROR), ("Handle database mutex lock failed error: %s (%d)", strerror(errno), errno) );
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR);
    }

    if (handle >= (ClHandleT)hdbp->n_handles)
    {
        pthread_mutex_unlock( &hdbp->mutex);
        clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN,"Passed handle [%p:%#llX] is invalid handle", (ClPtrT) hdbp, handle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE);
    }
    refcount = hdbp->handles[handle].ref_count;
    if( (--refcount <= 0) && (hdbp->handles[handle].state != HANDLE_STATE_PENDINGREMOVAL) )
    {
        pthread_mutex_unlock( &hdbp->mutex);
        clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN,  
                "There is no balance between checkout, checkin for handle [%p:%#llX]", 
                (ClPtrT) hdbp, (handle + 1));
        return CL_HANDLE_RC(CL_ERR_INVALID_STATE);
    }

    CL_ASSERT(hdbp->handles[handle].ref_count > 0); // unsigned compare (CID 196 on #1780)
    hdbp->handles[handle].ref_count -= 1;

    if (hdbp->handles[handle].ref_count == 0)
    {
        instance = (hdbp->handles[handle].instance);
        if (hdbp->handle_instance_destructor != NULL)
        {
            hdbp->handle_instance_destructor(instance);
        }
        if (hdbp->handles[handle].flags & HANDLE_ALLOC_FLAG)  /* Clean up the handle if we allocated it */
          clHeapFree(instance);
        
        memset(&hdbp->handles[handle], 0,    /* This also makes entry EMPTY */
                sizeof(ClHdlEntryT));
        CL_ASSERT(hdbp->n_handles_used > 0); //  unsigned compare (CID 196 on #1780)
        hdbp->n_handles_used--;
    }

    ec = pthread_mutex_unlock(&hdbp->mutex);
    if (ec != 0)
    {
        clDbgCodeError(CL_HANDLE_RC(CL_ERR_MUTEX_ERROR), ("Handle database mutex unlock failed error: %s (%d)", strerror(errno), errno) );
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
    }
    /* This check to avoid recursive call from LogClient */
    if( refcount > 0 )
    {
#if 0
        clLogTrace(CL_HDL_AREA, CL_HDL_CTX_CHECKIN, 
                "Checkin for handle [%p:%#llX]", 
                (ClPtrT) hdbp, (handle + 1));
#endif
    }

    return rc;
}
ClRcT cpmGmsInitialize(void)
{
    ClRcT rc = CL_OK;
    ClTimerTimeOutT timeOut = {0, 0};

    ClGmsCallbacksT cpmGmsCallbacks = { NULL, cpmClusterTrackCallBack, NULL, NULL };
    
    gpClCpm->version.releaseCode = 'B';
    gpClCpm->version.majorVersion = 0x01;
    gpClCpm->version.minorVersion = 0x01;
    rc = clGmsInitialize(&gpClCpm->cpmGmsHdl,
                         &cpmGmsCallbacks,
                         &gpClCpm->version);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                   "Failed to do GMS initialization, error [%#x]",
                   rc);
        gpClCpm->cpmGmsHdl = CL_HANDLE_INVALID_VALUE;
        goto failure;
    }

    rc = clOsalMutexLock(&gpClCpm->cpmGmsMutex);
    CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_OSAL_MUTEX_LOCK_ERR, rc, rc,
                   CL_LOG_HANDLE_APP);

    rc = clGmsClusterTrack(gpClCpm->cpmGmsHdl, CL_GMS_TRACK_CHANGES_ONLY | CL_GMS_TRACK_CURRENT, NULL);
    if (CL_OK != rc)
    {
        clOsalMutexUnlock(&gpClCpm->cpmGmsMutex);
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                   "The GMS cluster track function failed, error [%#x]",
                   rc);
        goto failure;
    }

    /*
     * Wait for the GMS callback
     */
    retry:
#ifdef VXWORKS_BUILD
    timeOut.tsSec = gpClCpm->cpmGmsTimeout + 20;
#else
    timeOut.tsSec = gpClCpm->cpmGmsTimeout + 60;  /* There is no reason to not wait for a long time.  100% cpu could cause GMS to come up slowly */
#endif
    timeOut.tsMilliSec = 0;

    clLogInfo(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
              "Node [%s] waiting for GMS cluster track callback for [%d.%d] secs",
              gpClCpm->pCpmLocalInfo->nodeName, timeOut.tsSec, timeOut.tsMilliSec);

    rc = clOsalCondWait(&gpClCpm->cpmGmsCondVar,
                        &gpClCpm->cpmGmsMutex,
                        timeOut);
    if (CL_OK != rc)
    {
        if(gpClCpm->trackCallbackInProgress)
        {
            clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                         "GMS cluster track callback in progress. Waiting for it to complete ...");
            goto retry;
        }
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_GMS,
                   "Failed to receive GMS cluster track callback, "
                   "error [%#x].",
                   rc);
        clOsalMutexUnlock(&gpClCpm->cpmGmsMutex);
        goto failure;
    }

    rc = clOsalMutexUnlock(&gpClCpm->cpmGmsMutex);
    CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_OSAL_MUTEX_UNLOCK_ERR, rc,
                   rc, CL_LOG_HANDLE_APP);

    return CL_OK;

    failure:
    return rc;
}
static ClRcT initializeAmf(void)
{
    SaAisErrorT         rc = SA_AIS_OK; 
    SaAisErrorT         retCode;
    ClIocPhysicalAddressT notificationForComp = { CL_IOC_BROADCAST_ADDRESS, 0};
    
    clAppConfigure(&clEoConfig,clEoBasicLibs,clEoClientLibs);
  
    clMsgRegisterWithCpm();
     
    if(gClMsgInit == CL_TRUE)
    {
        rc = CL_MSG_RC(CL_ERR_INITIALIZED);
        clLogError("MSG", "INI", "The Message Service is already initialized. error code [0x%x].", rc);
        goto error_out;
    }
    
    gLocalAddress = clIocLocalAddressGet();
    gLocalPortId = CL_IOC_MSG_PORT;

    /* Initializing a database to maintain client information */
    rc = clHandleDatabaseCreate((void (*)(void*))NULL, &gMsgClientHandleDb);
     
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to initialize the handle database. error code [0x%x].", rc);
        goto error_out;
    }
    
    /* Initializing IDL for server to server and server to client communication. */
    rc = clMsgCommIdlInitialize();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to initialize the IDL. error code [0x%x].", rc);
        goto error_out_2;
    }
    
    /* Initializing a database for maintaining queues. */
    rc = clMsgQueueInitialize();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to initialize the queue databases. error code [0x%x].", rc);
        goto error_out_3;
    }
   
    rc = clMsgReceiverDatabaseInit();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to initialize \"receiver database\". error code [0x%x].", rc);
        goto error_out_4;
    }

    rc = clOsalMutexInit(&gClMsgFinalizeLock);
    CL_ASSERT(rc == CL_OK);
    
    rc = clOsalCondInit(&gClMsgFinalizeCond);
    CL_ASSERT(rc == CL_OK);

    /* Initializing the Group-Information */
    rc = clOsalMutexInit(&gClGroupDbLock);
    CL_ASSERT(rc == CL_OK);

    rc = clCpmNotificationCallbackInstall(notificationForComp, &clMsgNotificationReceiveCallback, NULL, &gMsgNotificationHandle);
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to install the notification callback function. error code [0x%x].", rc);
        goto error_out_5;
    }
   
    /* Initializing the IDL generated code. */
    rc = clMsgIdlClientInstall();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to install Server Table. error code [0x%x].", rc);
        goto error_out_6;
    }

    rc = clMsgIdlClientTableRegister(CL_IOC_MSG_PORT);
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to register Server Table. error code [0x%x].", rc);
        goto error_out_7;
    }

    rc = clMsgCltClientTableRegister(CL_IOC_MSG_PORT);
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to register Client Table. error code [0x%x].", rc);
        goto error_out_8;
    }

    rc = clMsgCltSrvClientInstall();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to install Client Server Table. error code [0x%x].", rc);
        goto error_out_9;
    }
  
    rc = clMsgCltSrvClientTableRegister(CL_IOC_MSG_PORT);
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to register Client Server Table. error code [0x%x].", rc);
        goto error_out_10;
    }

    rc = clMsgFinalizeBlockInit();
    if(rc != CL_OK)
    {
        clLogError("MSG", "INI", "Failed to initialize the msg-finalize blocker. error code [0x%x].", rc);
        goto error_out_11;
    }
   
    clMsgDebugCliRegister();

    rc = clOsalTaskCreateDetached("MsgCkptInitAsync", CL_OSAL_SCHED_OTHER, CL_OSAL_THREAD_PRI_NOT_APPLICABLE, 0,
                                 clMsgCachedCkptInitAsync, NULL);
    CL_ASSERT(rc == CL_OK);

    goto out;
error_out_11:
    retCode = clMsgCltSrvClientTableDeregister();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to deregister Client Table. error code [0x%x].", retCode);
error_out_10:
    retCode = clMsgCltSrvClientUninstall();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the just opened handle database. error code [0x%x].", retCode);
error_out_9:
    retCode = clMsgCltClientTableDeregister();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to deregister Client Table. error code [0x%x].", retCode);
error_out_8:
    retCode = clMsgIdlClientTableDeregister();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to deregister Server Table. error code [0x%x].", retCode);
error_out_7:
    retCode = clMsgIdlClientUninstall();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the just opened handle database. error code [0x%x].", retCode);
error_out_6:
    retCode = clCpmNotificationCallbackUninstall(&gMsgNotificationHandle);
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to uninstall the notification callback function. error code [0x%x].", retCode);
error_out_5:
    retCode = clOsalMutexDestroy(&gClGroupDbLock);
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the group db mutex. error code [0x%x].", retCode);

    retCode = clOsalCondDestroy(&gClMsgFinalizeCond);
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the finalization condition. error code [0x%x].", retCode);

    retCode = clOsalMutexDestroy(&gClMsgFinalizeLock);
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the finalization mutex. error code [0x%x].", retCode);

    clMsgReceiverDatabaseFin();

error_out_4:
    retCode = clMsgQueueFinalize();
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to finalize the queue databases. error code [0x%x].", retCode);
error_out_3:
    clMsgCommIdlFinalize();
error_out_2:
    retCode = clHandleDatabaseDestroy(gMsgClientHandleDb);
    if(retCode != CL_OK)
        clLogError("MSG", "INI", "Failed to destroy the handle database. error code [0x%x].", retCode);
error_out:
out:
    return rc;  
    
}//end of intializeAmf
/**
 * The mode end function which is called after every mode is finished.
 * This is used currently to do bulk get. When the vbcount of the requests
 * is equal to the varcount.
 */
int
clSnmpModeEndCallback(
        netsnmp_mib_handler               *handler,
        netsnmp_handler_registration      *reginfo,
        netsnmp_agent_request_info        *reqinfo,
        netsnmp_request_info              *requests)
{
    ClRcT   rc = CL_SNMP_ERR_NOERROR;
    netsnmp_request_info * request = NULL;
    static ClUint16T noOfOps = 0;

    clLogDebug("SNM","OPE", "Inside MODE-END callback [%s] ...mode [%d]", 
            __FUNCTION__, reqinfo->mode );
    
        switch (reqinfo->mode)
    {
        case MODE_GETBULK:
            clLogDebug("SNM","OPE", "Inside mode BULK-GET");
            break;
        case MODE_GETNEXT:
        case MODE_GET:
            {
                for (request = requests; request != NULL; request = request->next)
                {
                    noOfOps++;
                }

                clLogDebug("SNM","OPE", "Inside mode [%s] vbC[%d] noOfOps [%d]",
                        reqinfo->mode == MODE_GET ? "GET": "GET-NEXT", reqinfo->asp->vbcount, noOfOps);

                if (gErrorHappened == CL_TRUE)
                {
                    noOfOps = 0;
                    clSnmpDataReset();
                    gErrorHappened = CL_FALSE;
                    clLogNotice("SNM","OPE", "Error happened in the validating the request.");
                    netsnmp_request_set_error(requests, CL_SNMP_ERR_NOSUCHNAME);
                    return CL_SNMP_ERR_NOSUCHNAME;
                }
                        
                if (reqinfo->asp->vbcount == noOfOps)
                {
                    clLogDebug("SNP","OPE", "Sending the get request now as the vbCount and varCount are equal.");
                    rc = clSnmpProcessRequest(requests);
                    if (CL_OK != rc)
                        clLogError("SNP","OPE", "Failed while processing the GET request. rc[0x%x]", rc);
  		            noOfOps = 0;
                }
            }
            break;
        case MODE_SET_RESERVE1:
            clLogDebug("SNM","OPE", "Inside mode RESERVE1");
            break;
        case MODE_SET_RESERVE2:
            clLogDebug("SNM","OPE", "Inside mode RESERVE2");
            break;
        case MODE_SET_ACTION:
            clLogDebug("SNM","OPE", "Inside mode ACTION");
            break;
        case MODE_SET_COMMIT:
            clLogDebug("SNM","OPE", "Inside mode COMMIT");
            break;
        case MODE_SET_UNDO:
            clLogDebug("SNM","OPE", "Inside mode UNDO");
            break;
        case MODE_SET_FREE:
            clLogDebug("SNM","OPE", "Inside mode FREE");
            break;
        default:
            clLogDebug("SNM","OPE", "Inside default case");
    }

   return rc;
}
ClRcT
clLogStreamOwnerGlobalEntryRecover(ClLogSOEoDataT            *pSoEoEntry,
                                   ClCkptSectionDescriptorT  *pSecDescriptor)
{
    ClRcT                   rc     = CL_OK;
    ClCkptIOVectorElementT  ioVector       = {{0}};
    ClUint32T               errIndex       = 0;
    ClLogSvrCommonEoDataT   *pCommonEoData = NULL;
    ClUint32T               versionCode = 0;

    CL_LOG_DEBUG_TRACE(("Enter"));

    rc = clLogStreamOwnerEoEntryGet(NULL, &pCommonEoData);
    if( CL_OK != rc )
    {
        return rc;
    }
    
    ioVector.sectionId  = pSecDescriptor->sectionId; 
    ioVector.dataBuffer = NULL;
    ioVector.dataSize   = 0;
    ioVector.readSize   = 0;
    ioVector.dataOffset = 0;
    rc = clCkptCheckpointRead(pSoEoEntry->hCkpt, &ioVector, 1, &errIndex);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clCkptCheckpointRead(): rc[0x %x]", rc));
        return rc;
    }

    if(ioVector.readSize <= sizeof(versionCode))
    {
        CL_LOG_DEBUG_ERROR(("Global stream recovery failed because of inconsistent ckpt "
                            "data of size [%lld]",
                            ioVector.readSize));
        clHeapFree(ioVector.dataBuffer);
        return CL_LOG_RC(CL_ERR_INVALID_STATE);
    }

    ioVector.readSize -= sizeof(versionCode);
    versionCode = ntohl(*(ClUint32T*)ioVector.dataBuffer);
    switch(versionCode)
    {
    case CL_VERSION_CODE(CL_RELEASE_VERSION, CL_MAJOR_VERSION, CL_MINOR_VERSION):
        {
            rc = clLogSOStreamEntryRecreate(0, 
                                            (ClAddrT)( (ClUint8T*)ioVector.dataBuffer + sizeof(versionCode)),
                                            ioVector.readSize,
                                            CL_HANDLE_INVALID_VALUE);
        }
        break;
    default:
        rc = CL_LOG_RC(CL_ERR_VERSION_MISMATCH);
        clLogError("GLOBAL", "RECOVER", "Version unsupported [%d.%d.%d]",
                   CL_VERSION_RELEASE(versionCode), CL_VERSION_MAJOR(versionCode),
                   CL_VERSION_MINOR(versionCode));
        break;
    }

    clHeapFree(ioVector.dataBuffer);

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}    
/**
 * Process the get request. This is called in the mode end callback.
 */
int 
clSnmpProcessRequest(netsnmp_request_info *requests)
{
    ClRcT               rc = CL_SNMP_ERR_NOERROR;
    ClUint32T           i = 0;
    ClMedErrorListT     medErrList = {0};
    _ClSnmpGetReqInfoT  *pReqInfo = NULL;

    clLogDebug("SNP","OPE", "Calling the snmpCommit now.");

    rc = clSnmpCommit (&medErrList);
    if (CL_OK != rc)
    {
        clSnmpDataReset();
        clLogError("SNP","OPE", "Failed while committing the get request. rc[0x%x]", rc);
        if (CL_ERR_NO_MEMORY == rc)
            rc = CL_SNMP_ERR_NOCREATION;
        else
            rc = CL_SNMP_ERR_GENERR;
        netsnmp_request_set_error(requests, rc);
        return rc;
    }

    for (i = 0 ; i < gOper.opInfo.varCount ; i++)
    {
        pReqInfo = ((_ClSnmpGetReqInfoT *)(gOper.pOpAddData) + i);
        clLogDebug("SNP","OPE", "Processing the agentId [%s]", gOper.opInfo.varInfo[i].attrId.id);

        if (gOper.opInfo.varInfo[i].errId == CL_OK)
        {
            if (pReqInfo->columnType == ASN_COUNTER64)
            {
                ClUint64T val;

                val = *(ClUint64T *) gOper.opInfo.varInfo[i].pVal;
                val = CL_BIT_WORD_SWAP(val);
                *(ClUint64T *) gOper.opInfo.varInfo[i].pVal = val;
            }
            else if (pReqInfo->columnType == ASN_UNSIGNED64)
            {
                ClUint64T val;

                val = *(ClUint64T *) gOper.opInfo.varInfo[i].pVal;
                val = CL_BIT_WORD_SWAP(val);
                *(ClUint64T *) gOper.opInfo.varInfo[i].pVal = val;
            }
            else if (pReqInfo->columnType == ASN_INTEGER64)
            {
                ClInt64T val;

                val = *(ClInt64T *) gOper.opInfo.varInfo[i].pVal;
                val = CL_BIT_WORD_SWAP(val);
                *(ClInt64T *) gOper.opInfo.varInfo[i].pVal = val;
            }

            snmp_set_var_typed_value(pReqInfo->pRequest->requestvb, pReqInfo->columnType, 
                    (const u_char*)gOper.opInfo.varInfo[i].pVal, gOper.opInfo.varInfo[i].len);
        }
        else
        {
            clLogDebug("SNP","OPE", "Job failed with error [0x%x]", gOper.opInfo.varInfo[i].errId);
            netsnmp_request_set_error(pReqInfo->pRequest, gOper.opInfo.varInfo[i].errId);
        }
    }

    clSnmpDataReset();
    return rc;
}
ClRcT clSnmpCommit(
        ClMedErrorListT *pMedErrList)
{
    ClMedOpT    opInfo = {0};
    ClRcT       errorCode = CL_OK;
    ClUint32T   count = 0;

    clSnmpMutexLock(gOper.mtx); /* Might as well check if the operation is complete before locking */
    if(!gOper.cmtd) /* CL_FALSE means not committed */ 
    {
        opInfo = gOper.opInfo;
        gOper.cmtd = CL_TRUE; /* Indicates that the request is executed */

        clLogDebug("SNP","OPE",
                "Calling med to execute operation, no of ops[%d]", opInfo.varCount);
        errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);
        if(CL_OK != errorCode)
        {
            clLogError("SNM","OPE",
                    "Failed to execute operation, rc=[0x%x]", errorCode);
            for(count = 0; count < opInfo.varCount; count++)
            {
                if(opInfo.varInfo[count].errId != CL_OK)
                {
                    clLogError("SNM","OPE",
                            "Setting errorCode [0x%x] to OID [%s]", 
                            opInfo.varInfo[count].errId, 
                            opInfo.varInfo[count].attrId.id);
                    /*pErrCode = opInfo.varInfo[count].errId;*/

                    /* Construct error list here */ 
                    gOper.medErrList.pErrorList = (ClMedErrorIdT *)clHeapRealloc(gOper.medErrList.pErrorList, 
                            (gOper.medErrList.count + 1)*sizeof(ClMedErrorIdT));
                    if(!gOper.medErrList.pErrorList)
                    {
                        errorCode = CL_ERR_NO_MEMORY;
                        goto exitOnError;
                    }

                    gOper.medErrList.pErrorList[gOper.medErrList.count].errId = opInfo.varInfo[count].errId;

                    gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id = 
                        (ClUint8T*)clHeapAllocate(opInfo.varInfo[count].attrId.len);
                    if(!gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id)
                    {
                        errorCode = CL_ERR_NO_MEMORY;
                        goto exitOnError;   
                    }

                    memcpy(gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id, 
                        opInfo.varInfo[count].attrId.id, opInfo.varInfo[count].attrId.len);
                    gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.len = opInfo.varInfo[count].attrId.len;
                    gOper.medErrList.count++;
                }
            }
            *pMedErrList = gOper.medErrList; /* Copy the error list, this is freed at clSnmpUndo() */

        }
#if 0
        for(arrIndex = 0; arrIndex < opInfo.varCount; arrIndex++)
        {
            clHeapFree(opInfo.varInfo[arrIndex].pVal);
            clHeapFree(opInfo.varInfo[arrIndex].pInst);
        }
        gOper.opInfo.varCount = 0; 
        clHeapFree (gOper.opInfo.varInfo);
        gOper.opInfo.varInfo = NULL; /* Next operation would see this and return */
#endif
    }
    else if (gOper.medErrList.count)
    {
        clLogDebug("SNM","OPE", 
                "Already committed, return error list");
        *pMedErrList = gOper.medErrList; /* Copy the error list, this is freed at clSnmpUndo() */
        errorCode = CL_SNMP_ERR_GENERR; /* Return a general error, this is not set to the varbin var */

    }
exitOnError:
    clSnmpMutexUnlock(gOper.mtx);
    return errorCode; /* Return error code */ 
}
/*
ClUint32T clSetTableAttr(  ClSnmpReqInfoT* reqInfo,
        void* data,
        ClInt32T *pOpNum,
        ClInt32T *pErrCode)
{
    ClMedOpT opInfo;
    static ClMedVarBindT *tempVarInfo = NULL;
    static ClInt32T arrIndex = 0;
    ClInt32T count = 0;
    ClInt32T errorCode = CL_OK;

    if(NULL == tempVarInfo)
    {
        tempVarInfo = (ClMedVarBindT *) clHeapCalloc(1,*pOpNum * sizeof (ClMedVarBindT));
        if(NULL == tempVarInfo)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Bulk set for %d objects", *pOpNum) );
            return CL_SNMP_ERR_NOCREATION;
        }
    }
    opInfo.varInfo = tempVarInfo;
    if(arrIndex < *pOpNum)
    {
        opInfo.varInfo[arrIndex].errId = CL_OK;
        opInfo.varInfo[arrIndex].attrId.len = (ClUint32T)strlen(reqInfo->oid) + 1;
        opInfo.varInfo[arrIndex].attrId.id = (ClUint8T *)clHeapCalloc(1,opInfo.varInfo[arrIndex].attrId.len);
        if(NULL == opInfo.varInfo[arrIndex].attrId.id)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %d", opInfo.varInfo[arrIndex].attrId.len) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].attrId.id, reqInfo->oid, opInfo.varInfo[arrIndex].attrId.len);
        opInfo.varInfo[arrIndex].len = reqInfo->dataLen;
        opInfo.varInfo[arrIndex].pVal = clHeapCalloc(1,reqInfo->dataLen);
        if(NULL == opInfo.varInfo[arrIndex].pVal)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %d",reqInfo->dataLen) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].pVal, data, reqInfo->dataLen);
        opInfo.varInfo[arrIndex].pInst = (ClSnmpReqInfoT *)clHeapCalloc(1,sizeof(ClSnmpReqInfoT) );
        if(NULL == opInfo.varInfo[arrIndex].pInst)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %u", (ClUint32T)sizeof(ClSnmpReqInfoT) ) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].pInst, reqInfo, sizeof(ClSnmpReqInfoT) );

        if(arrIndex == (*pOpNum - 1) )
        {
            opInfo.opCode = reqInfo->opCode;
            opInfo.varCount = *pOpNum;
            errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);
            if(CL_OK != errorCode)
            {
                for(count = 0; count <= arrIndex; count++)
                {
                    if(opInfo.varInfo[count].errId != CL_OK)
                    {
                        *pErrCode = opInfo.varInfo[count].errId;
                        *pOpNum = count;
                        break;
                    }
                }

            }
            arrIndex = 0;
            for(arrIndex = 0; arrIndex < *pOpNum; arrIndex++)
            {
                clHeapFree(opInfo.varInfo[arrIndex].pVal);
                clHeapFree(opInfo.varInfo[arrIndex].pInst);
            }
            arrIndex = 0;
            clHeapFree (tempVarInfo);
            tempVarInfo = NULL;
            return errorCode;
        }
        arrIndex++;
        return CL_OK;
    }
    return errorCode;
}
*/
ClUint32T clSnmpJobTableAttrAdd(  
        ClSnmpReqInfoT* reqInfo,
        void* data,
        ClInt32T *pOpNum,
        ClInt32T *pErrCode, 
        ClPtrT pReqAddInfo)
{
    ClInt32T arrIndex = 0;
    ClRcT    rc = CL_OK;

    clSnmpMutexLock(gOper.mtx);
    
    gOper.opInfo.varInfo = (ClMedVarBindT *) clHeapRealloc(gOper.opInfo.varInfo, 
    (gOper.opInfo.varCount+1) * sizeof (ClMedVarBindT));
    if(NULL == gOper.opInfo.varInfo)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Bulk set for [%d] objects", *pOpNum) ;
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    arrIndex = gOper.opInfo.varCount;
    clLogDebug("SNP","OPE",
            "Adding request[%d] into store", arrIndex);
    gOper.opInfo.varInfo[arrIndex].errId = CL_OK;
    gOper.opInfo.varInfo[arrIndex].attrId.len = (ClUint32T)strlen(reqInfo->oid) + 1;
    gOper.opInfo.varInfo[arrIndex].attrId.id = (ClUint8T *)clHeapCalloc(1, gOper.opInfo.varInfo[arrIndex].attrId.len);
    if(NULL == gOper.opInfo.varInfo[arrIndex].attrId.id)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%d]", 
                gOper.opInfo.varInfo[arrIndex].attrId.len);
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memcpy(gOper.opInfo.varInfo[arrIndex].attrId.id, reqInfo->oid, gOper.opInfo.varInfo[arrIndex].attrId.len);
    gOper.opInfo.varInfo[arrIndex].len = reqInfo->dataLen;
    gOper.opInfo.varInfo[arrIndex].pVal = clHeapAllocate(reqInfo->dataLen);
    if(NULL == gOper.opInfo.varInfo[arrIndex].pVal)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%d]",
                reqInfo->dataLen);
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memset(gOper.opInfo.varInfo[arrIndex].pVal, 0, reqInfo->dataLen);
    if (data)
    {
        memcpy(gOper.opInfo.varInfo[arrIndex].pVal, data, reqInfo->dataLen);
    }
    gOper.opInfo.varInfo[arrIndex].pInst = (ClSnmpReqInfoT *)clHeapCalloc(1,sizeof(ClSnmpReqInfoT) );
    if(NULL == gOper.opInfo.varInfo[arrIndex].pInst)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%u]", 
                (ClUint32T)sizeof(ClSnmpReqInfoT) );
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memcpy(gOper.opInfo.varInfo[arrIndex].pInst, reqInfo, sizeof(ClSnmpReqInfoT) );

    gOper.opInfo.opCode = reqInfo->opCode; /* This could be a problem if a SET and a CREATE comes */

    /* Validate here */
    clLogDebug("SNP","OPE",
            "Validating instance, tableType [%d],oid [%s], oidLen[%d], opCode [%d]",
            reqInfo->tableType, reqInfo->oid, reqInfo->oidLen, reqInfo->opCode); 
    if(CL_SNMP_CREATE != reqInfo->opCode) /* Dont validate instance for CREATE as it wont be there */
    {
        rc = clMedInstValidate(gSubAgentInfo.medHdl, &gOper.opInfo.varInfo[arrIndex]);
        if(CL_OK != rc)
        {
            clLogError("SNM","OPE",
                    "Failed to validate instance information, rc=[0x%x], errorCode=[0x%x]",
                    rc, gOper.opInfo.varInfo[arrIndex].errId);
            *pErrCode = gOper.opInfo.varInfo[arrIndex].errId;
            gErrorHappened = CL_TRUE;
        }
        
        if (reqInfo->opCode == CL_SNMP_GET)
        {
            clLogDebug("SNM","OPE", "Adding the get job.");
            gOper.pOpAddData = (_ClSnmpGetReqInfoT *) clHeapRealloc (gOper.pOpAddData, 
                                        (arrIndex + 1)* sizeof(_ClSnmpGetReqInfoT));
            if (NULL == gOper.pOpAddData)
            {
                clLogError("SNP","OPE",
                        "Could not allocate memory for the get info object. ");
                clSnmpMutexUnlock(gOper.mtx);
                return CL_SNMP_ERR_NOCREATION;
            }

            (((_ClSnmpGetReqInfoT *)gOper.pOpAddData) + arrIndex)->pRequest = 
                                ((_ClSnmpGetReqInfoT *)pReqAddInfo)->pRequest;
            (((_ClSnmpGetReqInfoT *)gOper.pOpAddData) + arrIndex)->columnType = 
                                ((_ClSnmpGetReqInfoT *)pReqAddInfo)->columnType;
        }
    }

    arrIndex++; /* Should this be incremented when inst validation failed? */
    gOper.opInfo.varCount = arrIndex;
    gOper.cmtd = CL_FALSE; /* Not committed */
    gOper.refCount = arrIndex; /* Ref count to delete this global structure */
    clLogDebug("SNP","OPE",
            "No of operations in store [%d]", gOper.opInfo.varCount);

    clSnmpMutexUnlock(gOper.mtx);
    return rc;
}
ClRcT _clTxnAgentProcessMgrCmd(
        CL_IN   ClBufferHandleT     inMsgHandle,
        CL_IN   ClBufferHandleT     outMsgHandle,
        CL_IN   ClTxnMessageHeaderT *pMsgHdr)
{
    ClRcT   rc  = CL_OK;
    ClTxnCmdT   tCmd = {.resp = CL_OK };
    ClTxnCommHandleT commHandle = NULL;
    ClUint32T   mCount = pMsgHdr->msgCount;
    ClTimeT t1, t2;

    
    CL_FUNC_ENTER();

    clLogDebug("AGT", NULL,
            "Received processing cmd from TM. Message count [%d]", 
            pMsgHdr->msgCount);
    t1 = clOsalStopWatchTimeGet();

    while ( (CL_OK == tCmd.resp) && (pMsgHdr->msgCount > 0) )
    {

        pMsgHdr->msgCount--;

        rc = VDECL_VER(clXdrUnmarshallClTxnCmdT, 4, 0, 0)(inMsgHandle, &tCmd);
        switch (tCmd.cmd)
        {
            case CL_TXN_CMD_INIT:
                rc = clTxnAgentTxnDefnReceive(tCmd, inMsgHandle); 
                if(CL_OK != rc)
                {
                    clLogError("AGT", "MTA",
                            "Failed to process init command from manager, rc=[0x%x]",
                            rc);
                    /* Construct payload to send response back to server */
                    clTxnMutexLock(clTxnAgntCfg->actMtx);
                    
                   /* tCmd.resp = rc; */

                    rc = clTxnCommIfcNewSessionCreate(CL_TXN_MSG_AGNT_RESP, 
                                                      pMsgHdr->srcAddr, 
                                                      CL_TXN_SERVICE_AGENT_RESP_RECV, 
                                                      NULL, CL_TXN_RMD_DFLT_TIMEOUT,  
                                                      CL_TXN_COMMON_ID, /* Value is 0x1 */
                                                      &commHandle);
                    if (CL_OK == rc)
                    {
                        rc = clTxnCommIfcSessionAppendTxnCmd(commHandle, &tCmd);

                        if (CL_OK != rc)
                        {
                            clLogError("AGT", NULL,
                                    "Failed to append cmd in the response with error [0x%x]",
                                    rc); 
                            clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                            break;
                        }
                        rc = clTxnCommIfcSessionRelease(commHandle);
                        if (CL_OK != rc)
                        {
                            clLogError("AGT", NULL,
                                    "Failed to release session with error[0x%x]",
                                    rc); 
                            clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                            break;
                        }
                        clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                    }
                    else
                        clLogError("AGT", "ATM", 
                                "Failed to create new session for key [Node:0x%x,Port:0x%x]", 
                                pMsgHdr->srcAddr.nodeAddress, pMsgHdr->srcAddr.portId);
                    break;

                }
                /* Request for the first time */
                if(mCount == (pMsgHdr->msgCount + 1) )
                {
                    rc = _clTxnAgentTxnStart(tCmd);
                    if(CL_OK != rc)
                    {
                        /*tCmd.resp = rc; */
                        clLogError("AGT", "MTA",
                                "Failed to start transaction[0x%x:0x%x], rc=[0x%x]",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId,
                                rc);
                        break;
                    }
                    clLogDebug("AGT", "MTA",
                            "Transaction[0x%x:0x%x] started",
                            tCmd.txnId.txnMgrNodeAddress,
                            tCmd.txnId.txnId);
                }
                break;

            case CL_TXN_CMD_PREPARE:
            case CL_TXN_CMD_1PC_COMMIT:
            case CL_TXN_CMD_2PC_COMMIT:
            case CL_TXN_CMD_ROLLBACK:
                rc = clTxnAgentProcessJob(pMsgHdr, tCmd, outMsgHandle, &commHandle);
                if(CL_OK != rc)
                {
                  /*  tCmd.resp = rc; */
                    clLog(CL_LOG_ERROR, "AGT", NULL,
                            "Error in processing cmd [%s] from server. rc [0x%x]", 
                            _clTxnCmdNameGet(tCmd.cmd), rc);
                }
                if(!pMsgHdr->msgCount && 
                    ( (tCmd.cmd == CL_TXN_CMD_ROLLBACK) || 
                      (tCmd.cmd == CL_TXN_CMD_2PC_COMMIT) ) 
                  )
                {
                    rc = _clTxnAgentTxnStop(tCmd);
                    if(CL_OK != rc)
                    {
                       /* tCmd.resp = rc; */
                        clLogError("AGT", "MTA",
                                "Failed to stop transaction[0x%x:0x%x], rc=[0x%x]",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId, rc);
                    }
                    else
                        clLogDebug("AGT", "MTA",
                                "Transaction[0x%x:0x%x] stopped",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId);
                }
                
                /* Remove the joblist when ROLLBACK or COMMIT is complete */
                if( (tCmd.cmd == CL_TXN_CMD_ROLLBACK) || 
                    (tCmd.cmd == CL_TXN_CMD_2PC_COMMIT) ) 
                {
                    ClTxnDefnPtrT pTxnDefn = NULL;
                    clLogDebug("AGT", NULL,
                            "Received remove cmd from server");
                    rc = clTxnDbTxnDefnGet(clTxnAgntCfg->activeTxnMap, 
                                    tCmd.txnId, &pTxnDefn);
                    if(CL_OK == rc)
                    {
                        if(1 < pTxnDefn->jobCount)
                        {
                            rc = clTxnAppJobRemove(pTxnDefn, tCmd.jobId);
                            if(CL_OK != rc)
                            {
                                ClNameT name = {0};
                                clCpmComponentNameGet(0, &name);
                                clLog(CL_LOG_ERROR, "AGT", NULL,
                                     "REMOVE cmd received. Error in removing the job information for component [%s] rc [0x%x]", 
                                     name.value, rc);
                                return rc;
                            }

                        }
                        else if(1 == pTxnDefn->jobCount) /* This is the last job, delete the entire txn list */
                        {
                            ClCntNodeHandleT nodeHandle;
                            rc  = clCntNodeFind(
                                    clTxnAgntCfg->activeTxnMap, 
                                    (ClCntKeyHandleT )&(tCmd.txnId), 
                                    &nodeHandle);
                            if(rc == CL_OK)
                            {
                                rc = clCntNodeDelete(clTxnAgntCfg->activeTxnMap, nodeHandle);
                                if(CL_OK != rc)
                                {
                                    clLog(CL_LOG_ERROR, "AGT", NULL, 
                                         "REMOVE cmd received. Error in deleting txn defn for txnId [0x%x] rc [0x%x]", 
                                         tCmd.txnId.txnId, rc);
                                    return rc;
                                }
                            }

                        }
                        else
                        {
                            clLog(CL_LOG_ERROR, "AGT", NULL,
                            "Remove cmd received. There is no txndefn corresponding to txnId [0x%x]. Jobcount [%d]\n",
                             tCmd.txnId.txnId, pTxnDefn->jobCount);
                        }
                    }
                }
                
                break;
                default:
                    clLog(CL_LOG_ERROR, "AGT", NULL, 
                        "Invalid command received from TM [0x%x]", tCmd.cmd);
                    rc = CL_ERR_INVALID_PARAMETER;
                    break;
        }
    }
    if((tCmd.cmd != CL_TXN_CMD_REMOVE_JOB) && commHandle)
    {
        rc = clTxnCommIfcReadMessage(commHandle, outMsgHandle);
        if(CL_OK != rc)
        {
            clLogError("AGT", NULL,
                    "Failed to write the response with error [0x%x]",
                    rc);
        }
        else
            clLogDebug("AGT", "ATM",
                    "Successfully sent response back");
        t2 = clOsalStopWatchTimeGet();
        clLogDebug("AGT", NULL,
                "Time taken to complete command[%d], [%lld]usecs",
                tCmd.cmd, (t2-t1) );
    }

    if (CL_OK != rc)
    {
            rc = CL_GET_ERROR_CODE(rc);
    }

    CL_FUNC_EXIT();
    return (rc);
}
/*
 * Called with the msg finalize lock held.
 */
static int safMsgFinalize(ClBoolT *pLockStatus)
{
    SaAisErrorT rc = SA_AIS_OK;
    if(pLockStatus && !*pLockStatus) 
        return CL_MSG_RC(CL_ERR_INVALID_STATE);

    CL_MSG_INIT_CHECK;

    gClMsgInit = CL_FALSE;

    if(pLockStatus)
    {
        *pLockStatus = CL_FALSE;
        clOsalMutexUnlock(&gClMsgFinalizeLock);
    }

    clMsgFinalizeBlocker();

    rc = clMsgFinalizeBlockFin();
    if(rc != CL_OK)
        clLogError("MSG", "INI", "Failed to cleanup the msg-finalize blocker. error code [0x%x].", rc);

    clMsgDebugCliDeregister();

    clMsgCommIdlFinalize();

    /* Finalize the IDL generated code. */
    rc = clMsgCltClientTableDeregister();
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to deregister Client Table. error code [0x%x].", rc);

    rc = clMsgIdlClientTableDeregister();
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to deregister Server Table. error code [0x%x].", rc);

    clMsgIdlClientUninstall();

    rc = clMsgCltSrvClientTableDeregister();
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to deregister Client Server Table. error code [0x%x].", rc);

    clMsgCltSrvClientUninstall();

    /* Finalize cached ckpt for MSG queue & MSG queue group */
    rc = clMsgQCkptFinalize();
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "clMsgQCkptFinalize(): error code [0x%x].", rc);

    /* Finalize database for maintaining queues. */
    clMsgReceiverDatabaseFin();

    rc = clMsgQueueFinalize();
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to finalize queue databases. error code [0x%x].", rc);

    rc = clCpmNotificationCallbackUninstall(&gMsgNotificationHandle);
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to uninstall the notification callback function. error code [0x%x].", rc);

    rc = clOsalMutexDestroy(&gClGroupDbLock);
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to destroy the group db lock. error code [0x%x].", rc);

    rc = clHandleDatabaseDestroy(gMsgClientHandleDb);
    if(rc != CL_OK)
        clLogError("MSG", "FIN", "Failed to destroy the client handle database. error code [0x%x].", rc);

    goto out;

out:
    return rc;
}
Пример #17
0
ClRcT
clHandleCreateSpecifiedHandle (
    ClHandleDatabaseHandleT databaseHandle,
	ClInt32T instance_size,
    ClHandleT handle)
{
	void           *instance = NULL;
    ClRcT          rc        = CL_OK;
    ClHdlDatabaseT *hdbp     = (ClHdlDatabaseT*) databaseHandle;
    ClRcT          ec        = CL_OK;
    ClHandleT      orgHandle = handle;

    hdlDbValidityChk(hdbp);
    /* We allow handles to be created that are pointing to some other handle DB and node hdlValidityChk(handle,hdbp); */
    handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */

    if (CL_HANDLE_INVALID_VALUE == handle)
    {
        clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, 
                   "Passed handle [%p:%#llX] is an invalid handle",
                   (ClPtrT) hdbp, handle);
        clDbgPause();
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */
    }
    /*
     * Decrementing handle to ensure the non-zero handle interface.
     */
    handle--;

    ec = pthread_mutex_lock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR);
    }
    if(handle >= hdbp->n_handles)
    {
        /*
         * Allocating space in Excess of to accomodate the value specified by the user.
         * NOTE: User should ensure that a sane value is supplied for handle.
         */
        ClHandleT excess_handles = handle - hdbp->n_handles + 1;

		ClHdlEntryT *new_handles = (ClHdlEntryT *)realloc (hdbp->handles,
			sizeof (ClHdlEntryT) * (hdbp->n_handles+excess_handles));
		if (new_handles == 0) 
        {
			ec = pthread_mutex_unlock (&hdbp->mutex);
            if (ec != 0)
            {
                return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be very bad */
            }
			return CL_HANDLE_RC(CL_ERR_NO_MEMORY);
		}

        /* 
         * Initialize the excess space. HANDLE_STATE_EMPTY will remain 0 
         * is assumed else need to set the excess entries explicitly in a 
         * loop. 
         */
        memset(&new_handles[hdbp->n_handles], 0, sizeof (ClHdlEntryT) * excess_handles);

        /* Update the values if success */
		hdbp->n_handles += excess_handles;
		hdbp->handles = new_handles;
	}

    if (hdbp->handles[handle].state != HANDLE_STATE_EMPTY) {
        /*
         * The specified handle already in use so return the specific error.
         */
        rc = CL_HANDLE_RC(CL_ERR_ALREADY_EXIST);
        goto error_exit;
    }

	instance = clHeapCalloc (1, instance_size);
	if (instance == 0) {
		rc = CL_HANDLE_RC(CL_ERR_NO_MEMORY);
        goto error_exit;
	}
	memset (instance, 0, instance_size);
	hdbp->handles[handle].state = HANDLE_STATE_USED;
	hdbp->handles[handle].instance = instance;
	hdbp->handles[handle].ref_count = 1;
	hdbp->handles[handle].handle = orgHandle;

    clDbgResourceNotify(clDbgHandleResource, clDbgAllocate, hdbp, handle+1, ("Specific handle [%p:%#llX] allocated", (ClPtrT) hdbp, handle+1));
    hdbp->n_handles_used++;
error_exit:

	ec = pthread_mutex_unlock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
    }
	return rc;
}
int clCreateCsiPython(char* s, int maxLen, const SaNameT* compName, SaAmfCSIDescriptorT* csiDescriptor, SaAmfHAStateT haState)
{
  //  #define maxLen 2048
  //  char s[maxLen];
  int curlen = 0;

  //snprintf(s+curlen,maxLen-curlen,"csi = { 'flags':'0' }\n"); 

  curlen += snprintf (s+curlen,maxLen-curlen, "{ 'csiFlags':'%s'",STRING_CSI_FLAGS(csiDescriptor->csiFlags));

  curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiHaState':'%s' ",STRING_HA_STATE(haState));

  if (CL_AMS_CSI_FLAG_TARGET_ALL != csiDescriptor->csiFlags)
    {
      curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiName':'%s' ", csiDescriptor->csiName.value);
    }

  if ((CL_AMS_CSI_FLAG_ADD_ONE == csiDescriptor->csiFlags) || (CL_AMS_CSI_FLAG_TARGET_ONE == csiDescriptor->csiFlags))
    {
      ClUint32T i = 0;
        
      clprintf (CL_LOG_SEV_INFO, " %d Name Value Pairs:",csiDescriptor->csiAttr.number);
      for (i = 0; i < csiDescriptor->csiAttr.number; i++)
        {
          clprintf (CL_LOG_SEV_INFO, ", '%s':'%s' ", csiDescriptor->csiAttr.attr[i].attrName, csiDescriptor->csiAttr.attr[i].attrValue);          
          curlen += snprintf (s+curlen,maxLen-curlen, ", '%s':'%s' ", csiDescriptor->csiAttr.attr[i].attrName, csiDescriptor->csiAttr.attr[i].attrValue);
        }

      if (0)  
        {
          ClRcT rc;
          ClCpmCompCSIRefT csiRef = { 0 };
          unsigned int i,j;
          SaNameT clcName;
          
          clprintf(CL_LOG_SEV_INFO,"New CODE");

          strncpy (clcName.value, (ClCharT*) compName->value,compName->length);
          clcName.length = compName->length;
          clcName.value[clcName.length]=0;

          rc = clCpmCompCSIList(&clcName, &csiRef);
          if(rc != CL_OK)
            {
              clLogError("APP", "CSISET", "Comp CSI get returned [%#x]", rc);
            }
          else
            {
              for(i = 0; i < csiRef.numCSIs; ++i)
                {
                  ClCpmCompCSIT *pCSI = &csiRef.pCSIList[i];
                  clprintf(CL_LOG_SEV_INFO,"me: [%.*s] compared: [%.*s]",csiDescriptor->csiName.length,csiDescriptor->csiName.value, pCSI->csiDescriptor.csiName.length, pCSI->csiDescriptor.csiName.value);
                  if (strncmp((char*)csiDescriptor->csiName.value,(char*)pCSI->csiDescriptor.csiName.value,csiDescriptor->csiName.length)==0)
                    {
                      ClAmsCSIDescriptorT* cd = &pCSI->csiDescriptor;
                      for (j = 0; j < cd->csiAttributeList.numAttributes; j++)
                        {
                          curlen += snprintf (s+curlen,maxLen-curlen, ", '%s':'%s' ", cd->csiAttributeList.attribute[j].attributeName, cd->csiAttributeList.attribute[j].attributeValue);
                          clprintf(CL_LOG_SEV_INFO,s);
                        }
                   }
                }
              if(csiRef.pCSIList)
                clHeapFree(csiRef.pCSIList);
            }
        }
    }
    

  if (SA_AMF_HA_ACTIVE == haState)
    {
      curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiTransitionDescriptor':'%d' ", (int) csiDescriptor->csiStateDescriptor.activeDescriptor.transitionDescriptor);
      curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiActiveComponent':'%s' ", csiDescriptor->csiStateDescriptor.activeDescriptor.activeCompName.value);
    }
  else if (SA_AMF_HA_STANDBY == haState)
    {
      curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiStandbyRank':'%d' ", (int) csiDescriptor->csiStateDescriptor.standbyDescriptor.standbyRank);
      curlen += snprintf (s+curlen,maxLen-curlen, ", 'csiActiveComponent':'%s' ", csiDescriptor->csiStateDescriptor.activeDescriptor.activeCompName.value);
    }


  curlen += snprintf (s+curlen,maxLen-curlen, "}");

  //clprintf (CL_LOG_SEV_INFO, "%s",s);
  //clRunPython(s);

  return curlen;

}
Пример #19
0
ClRcT
clHandleDestroy (
    ClHandleDatabaseHandleT databaseHandle,
    ClHandleT handle)
{
    ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*) databaseHandle;
    ClRcT          ec    = CL_OK;

    hdlDbValidityChk(hdbp);
    handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */

    clLogDebug("HDL", "DEL", "Deleting [%p:%#llX]", (ClPtrT) hdbp, handle);
   
    /*
     * Decrementing handle to ensure the non-zero handle interface.
     */
    if (CL_HANDLE_INVALID_VALUE == handle--)
    {
        clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, 
                "Passed handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */
    }
    /* Verify this particular handle has been already created */
    if( (NULL == hdbp->handles) || (0 == hdbp->n_handles_used) )
    {
        clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, 
                "Invalid attempt to delete the non exiting handle [%p:%#llX]", 
                (ClPtrT) hdbp, handle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE);
    }

    ec = pthread_mutex_lock (&hdbp->mutex); // Do not log inside here because log uses handles
    CL_ASSERT(ec == 0);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR);
    }
    if (handle >= (ClHandleT)hdbp->n_handles)
    {
        ec = pthread_mutex_unlock (&hdbp->mutex);
        if (ec != 0)
        {
            return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
        }
        clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, 
                "Passed handle [%p:%#llX] has not been created", 
                (ClPtrT) hdbp, handle);
        return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE);
    }

    if (HANDLE_STATE_USED == hdbp->handles[handle].state)
    {
        hdbp->handles[handle].state = HANDLE_STATE_PENDINGREMOVAL;

        ec = pthread_mutex_unlock (&hdbp->mutex);
        if (ec != 0)
        {
            return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
        }
        /*
         * Adding 1 to handle to ensure the non-zero handle interface.
         */
        ec = clHandleCheckin (databaseHandle, handle+1);
        clDbgResourceNotify(clDbgHandleResource, clDbgRelease, hdbp, handle+1, ("Handle [%p:%#llX] (state: %d, ref: %d) released", (ClPtrT)hdbp, handle+1,hdbp->handles[handle].state,hdbp->handles[handle].ref_count));
        return ec;
    }
    else if (HANDLE_STATE_EMPTY == hdbp->handles[handle].state)
    {
        ec = CL_HANDLE_RC(CL_ERR_INVALID_HANDLE);
    }
    else if (HANDLE_STATE_PENDINGREMOVAL == hdbp->handles[handle].state)
    {
        ec = pthread_mutex_unlock( &hdbp->mutex);
        if( ec != 0 )
        {
            return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
        }
        clLogWarning(CL_HDL_AREA, CL_HDL_CTX_DESTROY,  "Destroy has been called for this handle [%p:%#llX] returning CL_OK", (ClPtrT) hdbp, (handle + 1));
        return CL_OK;
    }
    else
    {
        clDbgCodeError(CL_ERR_INVALID_HANDLE, ("Passed handle [%p:%#llX] doesn't have any proper state, corrupted code", (ClPtrT) hdbp, (handle + 1)));
        /*
         * Invalid state - this musn't happen!
         */
    }
    if(pthread_mutex_unlock (&hdbp->mutex) != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
    }

#if 0
    clLogTrace(CL_HDL_AREA, CL_HDL_CTX_DESTROY, 
               "Handle [%p:%#llX] has been deleted successfully", 
               (ClPtrT) hdbp, (handle + 1));
#endif
    return ec;
}
ClRcT _clTxnAgentProcessClientCmd(
        CL_IN   ClBufferHandleT  inMsgHandle,
        CL_OUT   ClBufferHandleT  outMsgHandle,
        CL_IN   ClTxnMessageHeaderT     *pMsgHdr)
{
    ClRcT               rc  = CL_OK;
    ClUint32T           mCount = pMsgHdr->msgCount;
    ClTxnStartStopT     startstop = CL_TXN_DEFAULT;
    ClTxnCommHandleT    commHandle;
    
    CL_FUNC_ENTER();

    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("To processing %d messages", pMsgHdr->msgCount));
        
    rc = clTxnCommIfcNewSessionCreate(CL_TXN_MSG_AGNT_RESP_TO_CLIENT, 
                                      pMsgHdr->srcAddr, 
                                      CL_TXN_CLIENT_MGR_RESP_RECV, 
                                      NULL, CL_TXN_RMD_DFLT_TIMEOUT, 
                                      CL_TXN_COMMON_ID,
                                      &commHandle);
    clLogTrace("AGT", "RDT", 
            "[%d] Message(s) received from client [0x%x:0x%x]", 
            pMsgHdr->msgCount,
            pMsgHdr->srcAddr.nodeAddress,
            pMsgHdr->srcAddr.portId);
    while ( (CL_OK == rc) && (pMsgHdr->msgCount > 0) )
    {
        ClTxnCmdT   tCmd;

        pMsgHdr->msgCount--;

        rc = VDECL_VER(clXdrUnmarshallClTxnCmdT, 4, 0, 0)(inMsgHandle, &tCmd);
        switch (tCmd.cmd)
        {
            case CL_TXN_CMD_READ_JOB:
                if(mCount == (pMsgHdr->msgCount + 1) )
                {
                    startstop = CL_TXN_START;
                }
                if(!pMsgHdr->msgCount)
                {
                    startstop |= CL_TXN_STOP;
                }
                clLogDebug("AGT", NULL,
                        "Processing stop, startstop[%d], mCount[%d], msgCount[%d]",
                        startstop, mCount, pMsgHdr->msgCount);
                rc = clTxnAgentReadJob(tCmd, inMsgHandle, commHandle, startstop);
                if(CL_OK != rc)
                {
                    clLogError("AGT", NULL,
                            "Failed to process read job, rc=[0x%x]", rc);
                }
                startstop = CL_TXN_PHASE;

                break;
            
            default:
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid comamnd received 0x%x", tCmd.cmd));
                rc = CL_ERR_INVALID_PARAMETER;
                break;
        }
    }

    rc = clTxnCommIfcSessionRelease(commHandle);
    rc = clTxnCommIfcReadMessage(commHandle, outMsgHandle);

    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to process all txn-cmds. rc:0x%x", rc));
        rc = CL_GET_ERROR_CODE(rc);
    }
    CL_FUNC_EXIT();
    return (rc);
}
Пример #21
0
/*
 * The following API was added to walk through the existing handle database
 * and execute the user specified callback for each handle in use.
 */
ClRcT
clHandleWalk (ClHandleDatabaseHandleT databaseHandle,
	ClHandleDbWalkCallbackT fpUserWalkCallback,
    void *pCookie)
{
	ClHandleT      handle  = CL_HANDLE_INVALID_VALUE;
    ClHdlDatabaseT *hdbp   = (ClHdlDatabaseT*)databaseHandle;
    ClRcT          ec      = CL_OK;
    ClRcT          rc      = CL_OK;

    hdlDbValidityChk(hdbp);
    if (NULL == fpUserWalkCallback)
    {
        clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "fpUserWalkCallback is NULL");
        return CL_HANDLE_RC(CL_ERR_NULL_POINTER);
    }
    ec = pthread_mutex_lock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR);
    }

    for (handle = 0; handle < hdbp->n_handles; handle++) {
        
        ClHandleT tempHandle = 0;
        /*
         * Ignore the handle if not used.
         */
        if (hdbp->handles[handle].state != HANDLE_STATE_USED) {
            continue;
        }

        /*
         * Unlock the database since the user needs to checkout the
         * handle in the callback.
         */
        ec = pthread_mutex_unlock (&hdbp->mutex);
        if (ec != 0)
        {
            return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* Disastrous */
        }

        /*
         * Adding 1 to handle to ensure the non-zero handle interface.
         */
        tempHandle = hdbp->handles[handle].handle;
        rc = fpUserWalkCallback(databaseHandle, tempHandle, pCookie);
        if(rc != CL_OK) {
            goto exit;  /* Already unlocked */
        }

        /*
         * Lock the database again to test check remaining handles.
         */
        ec = pthread_mutex_lock (&hdbp->mutex);
        if (ec != 0)
        {
            return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* Disastrous */
        }
    }

    ec = pthread_mutex_unlock (&hdbp->mutex);
    if (ec != 0)
    {
        return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */
    }
exit:
    return rc;
}
/**
 * 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);
}
/**
 * NOT AN EXTERNAL API. PLEASE DO NOT DOCUMENT.
 *
 * This routine creates an object instance in the calling context, and
 * sets the object type the one specified as the argument. Also, the
 * object instance is added to the object manager database.
 */
void *
omCommonCreateObj(ClOmClassTypeT classId, ClUint32T numInstances,
                  ClHandleT *handle, void *pExtObj, int flag, ClRcT *rc,
                  void *pUsrData, ClUint32T usrDataLen)
{
    int 		  idx;
    char         *pObjPtr = NULL;
    ClUint32T **pInst;
    ClUint32T   instIdx = 0;
    ClOmClassControlBlockT *      pTab;
    char         *tmpPtr;
    ClUint32T	instBlkLen = 0;

    CL_FUNC_ENTER();

    if (NULL == rc)
    {
        clLogError("OMG", "OMC", "Null value passed for return code");
        return (NULL);
    }

    if(NULL == handle || ( (flag == CL_OM_ADD_FLAG) && (NULL == pExtObj) ) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("NULL handle is passed."));
        *rc = CL_OM_SET_RC(CL_OM_ERR_NULL_PTR);
        return (NULL);
    }

    *rc = 0;
    /* validate the input arguments */
    if (omClassTypeValidate(classId) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid input classId arguments"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INVALID_CLASS);
        return (NULL);
    }
    pTab = clOmClassEntryGet(classId);
    CL_ASSERT(pTab);

    if (!numInstances)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid input numInstances arguments"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INVALID_OBJ_INSTANCE);
        return (NULL);
    }

    /* Get obj memory block length */
    instBlkLen = pTab->size * numInstances;

Reallocate:
    /*
     * Check if the class control structure is initalized with the instance
     * table. This is done during the initialization of the class table.
     */
    if (!(pInst = pTab->pInstTab))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Instance table for the class does not exist"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_NOT_EXISTS);
        return (NULL);
    }

    /* Find the first empty slot in the instance table */
    *rc = omGetFreeInstSlot(pInst, pTab->maxObjInst, &instIdx);
    if (CL_GET_ERROR_CODE(*rc) == CL_ERR_NOT_EXIST)
    {
        ClUint32T **tmp_ptr = NULL;
        ClUint32T  tmp_size = 0;

        clLogDebug("OMC", "OBC", "No free slot found in the OM class [0x%x] buffer for this object. "
                   "Reallocating the class buffer size.", classId);

        /* No free slot found. Need to allocate maInstances number of slots more */
        pTab->maxObjInst = pTab->maxObjInst * 2 ; /* Double the size of max instances */
        tmp_size = (pTab->maxObjInst * sizeof(ClUint32T *));

        tmp_ptr = pTab->pInstTab;

        tmp_ptr = (ClUint32T **) clHeapRealloc(tmp_ptr, tmp_size);

        if (NULL == tmp_ptr)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to allocate memory for Instance Table"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_NO_MEMORY);
            return (NULL);
        }

        pTab->pInstTab = tmp_ptr;

        goto Reallocate;
    }

    clLogTrace("OMC", "OBC", "Allocating the index [%u] in the OM class [0x%x] buffer.",
               instIdx, classId);

    /* Check if we have room for the contiguous instance available to
     * allocate the object instances requested by the user.
     * NOTE: We could enhance this later to allow dis-contiguous slots
     */
    for (idx = instIdx; idx < (instIdx + numInstances); idx++)
    {
        if (mGET_REAL_ADDR(pInst[idx]))
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Unable to fit requested num instances"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_NOSLOTS);
            return (NULL);
        }
    }

    /* Allocate the memory for the object instances */
    if (flag == CL_OM_CREATE_FLAG)
    {
        pObjPtr = (char*)clHeapAllocate(instBlkLen);

        if(NULL == pObjPtr)
        {
            /*
             * TODO: To check if we have to go a free the instances
             *       that were allocated when (numInstances > 1) req.
             */
#if (CW_PROFILER == YES)
            /* TODO: lockId = osLock(); */
            /* TODO: pOM->perfStat.memoryAllocFail++; */
            /* TODO: osUnLock(lockId); */
#endif
            CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, ("unable to allocate memory from heap!!"));
            CL_FUNC_EXIT();
            *rc = CL_ERR_NO_MEMORY;
            return (NULL);
        }
        /* Reset object block contents to 0 */
        memset(pObjPtr, 0, instBlkLen);

        tmpPtr = pObjPtr;
    }
    else if (flag == CL_OM_ADD_FLAG)
    {
        tmpPtr = pExtObj;
    }
    else
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Unknown flag argument passed"));
        *rc = CL_ERR_INVALID_PARAMETER;
        return (NULL);
    }

    /* Now, add it to the instance table */
    for (idx = instIdx; idx < (instIdx + numInstances); idx++)
    {
        /*
         * Cautionary check, if the address is *NOT* aligned on a four
         * byte boundry
         */
        if ((ClWordT)tmpPtr & INST_BITS_MASK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, ("Allocated buffer not on word aligned boundry"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_ALOC_BUF_NOT_ALIGNED);
            return (NULL);
        }

        /* Start adding the object to the instance table */
        ((struct CL_OM_BASE_CLASS *)tmpPtr)->__objType = CL_OM_FORM_HANDLE(classId, instIdx);

        /* TODO: lockId = osLock(); */
        if (flag == CL_OM_CREATE_FLAG)
            pInst[idx] = (ClUint32T *)mSET_ALLOC_BY_OM(tmpPtr);
        else
            pInst[idx] = (ClUint32T *)tmpPtr;
        pTab->curObjCount++;

#if (CW_PROFILER == YES)
        /* pOM->perfStat.objectCreated++; */
#endif
        /* TODO: osUnLock(lockId); */

        /* Now, start calling the initializer method for the class hierarchy */
        *rc = omInitObjHierarchy(pTab, classId, (void *)tmpPtr, pUsrData, usrDataLen);
        tmpPtr += pTab->size;
    }

    /* return the handle argument */
    *handle = CL_OM_FORM_HANDLE(classId, instIdx);
    CL_FUNC_EXIT();

    if (flag == CL_OM_CREATE_FLAG)
        return((void *)pObjPtr);
    else
        return(NULL);
}
/**
 * API to un-register a service with transaction-agent
 */
ClRcT clTxnAgentServiceUnRegister(CL_IN ClTxnAgentServiceHandleT tHandle)
{
    ClRcT                       rc = CL_OK;
    ClUint8T                    twoPC = 0;
    ClTxnAgentCompServiceInfoT  *pCompService = NULL;


    CL_FUNC_ENTER();

    if (tHandle == 0x0)
    {
        CL_FUNC_EXIT();
        return CL_TXN_RC(CL_ERR_INVALID_HANDLE);
    }
    /*
       This is a request from service hosted in the component to unregister
       from the transaction-management.
       Remove the entry from the data-structure and invalidate the handle

       FIXME: Before actually deleting it, check to see if this service is 
              part of any active txn or not
    */

    rc = clCntDataForKeyGet(clTxnAgntCfg->compServiceMap, 
                            (ClCntKeyHandleT) &(((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType),
                            (ClCntDataHandleT *)&pCompService);
    if (CL_OK == rc)
    {
        ClUint32T   srvCount;
        if (pCompService->serviceCapability == CL_TXN_AGENT_SERVICE_1PC)
        {
            twoPC = 0;
            clTxnAgntCfg->agentCapability &= ~(CL_TXN_AGENT_SERVICE_1PC);
        }
        else if(pCompService->serviceCapability == CL_TXN_AGENT_SERVICE_2PC)
        {
            twoPC = 1;
        }

        rc = clCntAllNodesForKeyDelete(clTxnAgntCfg->compServiceMap,
                                      (ClCntKeyHandleT) &(((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType));
        if(CL_OK != rc)
        {
            clLogError("AGT", NULL,
                    "Failed to delete node from compServiceMap corresponding to service[%d]", 
                    ((ClTxnAgentCompServiceInfoT *)tHandle)->serviceType);
            return rc;
        }
                                        
        /* Reset agent capability, if necessary */
        rc = clCntSizeGet(clTxnAgntCfg->compServiceMap, &srvCount);
        if ( (CL_OK == rc) && (srvCount == 0x0) )
        {
            clTxnAgntCfg->agentCapability = CL_TXN_AGENT_NO_SERVICE_REGD;
        } 
        else if ( (CL_OK == rc) && (srvCount == 0x1) && 
                  ( (clTxnAgntCfg->agentCapability & CL_TXN_AGENT_SERVICE_1PC) == CL_TXN_AGENT_SERVICE_1PC) )
        {
            clTxnAgntCfg->agentCapability = CL_TXN_AGENT_SERVICE_1PC;
        }
        else if ( CL_OK != rc )
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Error while reading number of service registered. rc:0x%x", rc));
        }
    }
    if(CL_OK == rc)
        clLogNotice("AGT", "FIN",
                "Unregistering [%s] service successfull", twoPC ? "2PC":"READ"); 
    CL_TXN_RETURN_RC(rc, ("Failed to unregister component-service rc:0x%x\n", rc));
}
ClRcT cpmNodeAdd(ClCharT *nodeName)
{
    ClRcT rc = CL_OK;
    ClCpmLT *cpm = NULL;
    ClUint16T nodeKey = 0;
    ClCpmSlotInfoT slotInfo = {0};

    if (!nodeName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "NULL pointer passed.");
        goto failure;
    }

    clOsalMutexLock(gpClCpm->cpmTableMutex);
    rc = cpmNodeFindLocked((SaUint8T *)nodeName, &cpm);
    clOsalMutexUnlock(gpClCpm->cpmTableMutex);
    if (cpm)
    {
        clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "Node [%s] already exists on this node.", nodeName);
        rc = CL_CPM_RC(CL_ERR_ALREADY_EXIST);
        goto failure;
    }

    cpm = (ClCpmLT*) clHeapAllocate(sizeof(ClCpmLT));
    if (!cpm)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Unable to allocate memory");
        goto failure;
    }

    memset(cpm, 0, sizeof(ClCpmLT));
    
    strncpy(cpm->nodeName, nodeName, strlen(nodeName));
    
    rc = clCksm16bitCompute((ClUint8T *)cpm->nodeName,
                            strlen(cpm->nodeName),
                            &nodeKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for node, "
                   "error [%#x]",
                   rc);
        goto failure;
    }

    /* 
     * Filling the CPML with defaults.  
     */

    saNameSet(&cpm->nodeType, nodeName);
    saNameSet(&cpm->nodeIdentifier, nodeName);
    /*
     * Set the class type to CLASS_C.
     */
    strncpy(cpm->classType, "CL_AMS_NODE_CLASS_C", sizeof(cpm->classType)-1);
    /*
     * Get the MOID of the master node. Assuming that node add is
     * only invoked on the master.
     */
    slotInfo.slotId = clIocLocalAddressGet();

    rc = clCpmSlotInfoGet(CL_CPM_SLOT_ID, &slotInfo);
    if(rc == CL_OK)
    {
        rc = cpmCorMoIdToMoIdNameGet(&slotInfo.nodeMoId, &cpm->nodeMoIdStr);
    }
    if(rc != CL_OK)
    {
        if((CL_GET_ERROR_CODE(rc) != CL_IOC_ERR_COMP_UNREACHABLE) && (CL_GET_ERROR_CODE(rc) != CL_ERR_NOT_EXIST))
        {
            goto failure;
        }
        else
        {
            rc = CL_OK;
            clLogWarning(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM, "COR server not running so cannot discover the Node's MoId");
        }
    }

    clOsalMutexLock(gpClCpm->cpmTableMutex);

    rc = clCntNodeAdd(gpClCpm->cpmTable,
                      (ClCntKeyHandleT)(ClWordT)nodeKey,
                      (ClCntDataHandleT) cpm,
                      NULL);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to add node to the CPM node table, "
                   "error [%#x]",
                   rc);
        clOsalMutexUnlock(gpClCpm->cpmTableMutex);
        goto failure;
    }

    ++gpClCpm->noOfCpm;

    clOsalMutexUnlock(gpClCpm->cpmTableMutex);

    /*
     * Add this to the slotinfo.
     */

    clOsalMutexLock(&gpClCpm->cpmMutex);
    rc = cpmSlotClassAdd(&cpm->nodeType, &cpm->nodeIdentifier, 0);
    clOsalMutexUnlock(&gpClCpm->cpmMutex);

    if(rc != CL_OK)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Node [%s] class add returned [%#x]", cpm->nodeType.value, rc);
    }

    clLogNotice("DYN", "NODE", "Node [%s] added to the cpm table with identity [%.*s]",
                cpm->nodeName, cpm->nodeIdentifier.length, cpm->nodeIdentifier.value);
                
    return CL_OK;

    failure:
    return rc;
}
/**
  This function recieves the debug CLI command through the transaction manager
  and send back the job status and registered service details. 
*/
static ClRcT 
VDECL(clTxnAgentDebugMsgReceive)(
        CL_IN   ClEoDataT               eoArg, 
        CL_IN   ClBufferHandleT  inMsg, 
        CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;

    CL_FUNC_ENTER();
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *) CL_TXN_AGT_CLI_DISP_JOB_LIST_HEADER,
                                        CL_TXN_AGT_CLI_DISP_JOB_LIST_HEADER_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = _clTxnAgentAppendActiveJob(outMsg);
    if(CL_OK != rc)
    {
        clLogError("AGT", "CLI",
                "Appending active job failed with error [0x%x]. Failed to handle Txn Mgr debug cmd", rc);
        return rc;
    }
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *) CL_TXN_AGT_CLI_DISP_SRC_INFO_HEADER,
                                        CL_TXN_AGT_CLI_DISP_SRC_INFO_HEADER_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);

    rc = _clTxnAgentAppendServices(outMsg);
    if(CL_OK != rc)
    {
        clLogError("AGT", "CLI",
                "Appending services failed with error [0x%x]. Failed to handle Txn Mgr debug cmd", rc);
        return rc;
    }
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    CL_FUNC_EXIT();
    return(rc);
}    
ClRcT cpmCompParseArgs(ClCpmCompConfigT *compConfig, ClCharT *cmd, ClUint32T *pArgIndex)
{
    ClCharT tmp[CL_MAX_NAME_LENGTH] = {0};
    ClCharT imageName[CL_MAX_NAME_LENGTH];
    ClCharT *c = NULL;
    ClCharT *saveptr = NULL;
    ClUint32T i = 0;
    ClUint32T argIndex = 0;
    ClRcT rc = CL_OK;

    if(pArgIndex) *pArgIndex = 0;

    strncpy(tmp, cmd, CL_MAX_NAME_LENGTH-1);

    for(i = 0; compConfig->argv[i]; ++i)
    {
        clHeapFree(compConfig->argv[i]);
        compConfig->argv[i] = NULL;
    }

    i = 0;

    if(cpmIsValgrindBuild(cmd)) 
    { 
        cpmModifyCompArgs(compConfig, &i);
    }
    argIndex = i;
    c = strtok_r(tmp, " ", &saveptr);
    while (c && (i < CPM_MAX_ARGS - 1))
    {
        ClUint32T len = strlen(c);
        if(i == argIndex && *c != '/')
        {
            ClCharT *binPath = getenv(CL_ASP_BINDIR_PATH);
            snprintf(imageName, sizeof(imageName)-1, "%s%s%s", 
                     binPath ? binPath : "", binPath ? "/" : "", c);
            len = strlen(imageName);
            c = imageName;
        }
        compConfig->argv[i] = (ClCharT*) clHeapAllocate(len + 1);
        if (!compConfig->argv[i])
        {
            clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                       "Unable to allocate memory");
            rc = CL_CPM_RC(CL_ERR_NO_MEMORY);
            goto failure;
        }

        strcpy(compConfig->argv[i], c);
        ++i;

        c = strtok_r(NULL, " ", &saveptr);
    }
    compConfig->argv[i] = NULL;

    if(compConfig->argv[argIndex])
    {
        strncpy(compConfig->instantiationCMD,
                compConfig->argv[argIndex],
                CL_MAX_NAME_LENGTH-1);
    }

    if(pArgIndex) *pArgIndex = i;

    return CL_OK;
    
failure:
    return rc;
}
/**
 * This function receives control message from transaction-manager for coordinating
 * for a given transaction-job. Parameters identify transaction-job and the control
 * information necessary to execute the next step.
 */
ClRcT 
VDECL(clTxnAgentCntrlMsgReceive)(
        CL_IN   ClEoDataT               eoArg, 
        CL_IN   ClBufferHandleT  inMsg, 
        CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;
    ClTxnMessageHeaderT     msgHeader = {{0}};
    ClTxnMessageHeaderIDLT  msgHeadIDL = {{0}};
    
    CL_FUNC_ENTER();

    rc = VDECL_VER(clXdrUnmarshallClTxnMessageHeaderIDLT, 4, 0, 0)(inMsg, &msgHeadIDL);
    if(CL_OK != rc)
    {
        clLogError("AGT", NULL,
                "Error in unmarshalling msgHeadIDL, rc [0x%x]", rc);
        return rc;
    }

    _clTxnCopyIDLToMsgHead(&msgHeader, &msgHeadIDL);
    CL_ASSERT(msgHeader.msgCount);

    /* Check/Validate server version */
    rc = clVersionVerify (&clTxnMgmtVersionDb, &(msgHeader.version));
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Un-supported version. rc:0x%x\n", rc));
        CL_FUNC_EXIT();
        return (CL_GET_ERROR_CODE(rc));
    }

    clLogDebug("AGT", NULL, "Receiving control-msg from txn-manager");

    /* 
       Based on msg-type, 
       - If this is TXN_DEFN, then extract the txn and job-defn and do initialize.
         Respond CL_OK, if everything is fine.

       - If this is TXN_CMD, then for each txn and job (if mentioned), execute 
         and intended operation

       - If TXN_STATUS_CHANGE, take action accordingly
    */

    switch (msgHeader.msgType)
    {
        case CL_TXN_MSG_MGR_CMD:
            rc = _clTxnAgentProcessMgrCmd(inMsg, outMsg, &msgHeader);
            break;

        case CL_TXN_MSG_CLIENT_REQ_TO_AGNT:
            rc = _clTxnAgentProcessClientCmd(inMsg, outMsg, &msgHeader);
            break;
        
        case CL_TXN_MSG_COMP_STATUS_UPDATE:
            rc = CL_ERR_NOT_IMPLEMENTED;
            break;

        default:
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                ("Invalid msg-type received 0x%x\n", msgHeader.msgType));
            rc = CL_ERR_INVALID_PARAMETER;
            break;
    }
/* This is to be replaced by clTxnCommIfcReadMessage(). clTxnCommIfcReadMessage()
 * writes to the outMsgHdl which is either received by the client or server depending
 * on where the async request came from 
 */
#if 0
    rc = clTxnCommIfcAllSessionClose();

    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to process received msg. rc:0x%x\n", rc));
        /* FIXME: Do logging */
        rc = CL_GET_ERROR_CODE(rc);
    }
#endif

    CL_FUNC_EXIT();
    return (rc);
}
ClRcT clCkptMasterPeerUpdateNoLock(ClIocPortT        portId, 
                                   ClUint32T         flag, 
                                   ClIocNodeAddressT localAddr,
                                   ClUint8T          credential) 
{
    ClRcT              rc           = CL_OK;
    CkptPeerInfoT      *pPeerInfo   = NULL;
    CkptNodeListInfoT  *pPeerInfoDH = NULL;
    ClCntNodeHandleT   nodeHdl      = 0;
    ClCntNodeHandleT   tempHdl      = 0;
    ClHandleT         *pMasterHandle  = NULL;
    
    /*
     * Check whether node/component is coming up or going down.
     */
    if(flag == CL_CKPT_SERVER_UP)
    {
        /*
         * Checkpoint server up scenario.
         */
         clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_ANNOUNCE,
                   "Received welcome message from master, updating the peerlist for [%d]",
                    localAddr);

         /* Reset the replica list for peer being welcomed without knowing the peer is available or not */
         if(localAddr != gCkptSvr->localAddr)
         {
             clLogNotice("PEER", "UPDATE",
                         "Resetting the replica list for the peer [%#x] being welcomed", localAddr);
             clCkptMasterReplicaListUpdateNoLock(localAddr);
         }

        /* 
         * Add an entry to the peer list if not existing.
         * Mark the node as "available" i.e. available for checkpoint 
         * operations like storing replicas etc..
         */
        rc = clCntDataForKeyGet( gCkptSvr->masterInfo.peerList,
                                 (ClPtrT)(ClWordT)localAddr,
                                 (ClCntDataHandleT *)&pPeerInfo);
        if( rc == CL_OK && pPeerInfo != NULL)
        {
            CL_ASSERT(pPeerInfo->ckptList != 0);
            pPeerInfo->credential = credential;
            pPeerInfo->available  = CL_CKPT_NODE_AVAIL;

            if(localAddr != gCkptSvr->localAddr)
            {
                pPeerInfo->replicaCount = 0;
            }
        }
        else
        {
            if( CL_OK !=( rc = _ckptMasterPeerListInfoCreate(localAddr, 
                            credential,0)))
            {
                return rc;
            }
        }        
    }
    else
    {
        /*
         * Node/component down scenario.
         */
        clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, 
                   "Updating the peerAddr [%d] for down notification",
                   localAddr);
        /* 
         * Find the corresponding entry from the peer list.
         */
        if( CL_OK != (rc = clCntDataForKeyGet(gCkptSvr->masterInfo.peerList,
                                             (ClCntKeyHandleT)(ClWordT)localAddr,
                                             (ClCntDataHandleT *) &pPeerInfo)))
        {
            rc = CL_OK;
            goto exitOnError;
        }

        if( flag != CL_CKPT_COMP_DOWN)
        {
            clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN,
                       "Either ckpt server or node down, "
                       "changing active address");
                    
            clCntFirstNodeGet(pPeerInfo->mastHdlList,&nodeHdl);
            tempHdl = 0;
            while(nodeHdl != 0)
            {
                rc = clCntNodeUserKeyGet(pPeerInfo->mastHdlList,nodeHdl,
                                    (ClCntKeyHandleT *)&pMasterHandle);
                if( CL_OK != rc )
                {
                    clLogError(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, 
                            "Not able get the data for node handle rc[0x %x]",
                            rc);
                    goto exitOnError;
                }
                rc = clCntNextNodeGet(pPeerInfo->mastHdlList, nodeHdl, 
                                      &tempHdl);
                /*
                 * Update the active address and inform the clients.
                 */
                if( CL_OK != (rc = _clCkpMastertReplicaAddressUpdate(*pMasterHandle, 
                                                                 localAddr)))
                {
                    return rc;
                }
                nodeHdl = tempHdl;
                tempHdl = 0;
            }
        }
        
        if (flag != CL_CKPT_SVR_DOWN)
        {
            /* 
             * Component down/ node down case.
             * In case of component down close the associated client Hdl.
             * Incase of node down close all client Hdl.
             * Delete the ckpt Hdls from the client handle List.
             */
            clLogDebug(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, 
                  "Closing the opened handles from this slot id [%d]...", 
                   localAddr);
            clCntFirstNodeGet(pPeerInfo->ckptList,&nodeHdl);
            while(nodeHdl != 0)
            {
                rc = clCntNodeUserDataGet(pPeerInfo->ckptList,nodeHdl,
                        (ClCntDataHandleT *)&pPeerInfoDH);
                if( CL_OK != rc )
                {
                    clLogError(CL_CKPT_AREA_MAS_DEP, CL_CKPT_CTX_PEER_DOWN, 
                            "Not able get the data for node handle rc[0x %x]",
                            rc);
                    goto exitOnError;
                }
                clCntNextNodeGet(pPeerInfo->ckptList,nodeHdl,&tempHdl);
                if ( (flag == CL_CKPT_COMP_DOWN && 
                     pPeerInfoDH->appPortNum == portId) || 
                     (flag == CL_CKPT_NODE_DOWN) )
                {
                    /*
                     * Close the checkpoint hdl but dont delete the entry from
                     * masterHdl list.
                     */
                    if(gCkptSvr->masterInfo.masterAddr == 
                                    gCkptSvr->localAddr) 
                    {                                    
                        clLogInfo(CL_CKPT_AREA_MAS_DEP,
                                  CL_CKPT_CTX_PEER_DOWN, 
                                  "Closing the handle [%#llX]...", 
                                  pPeerInfoDH->clientHdl);
                        _clCkptMasterCloseNoLock(pPeerInfoDH->clientHdl, 
                        localAddr, !CL_CKPT_MASTER_HDL); 
                    }    
                }
                nodeHdl = tempHdl;
                tempHdl = 0; 
            }
        }
        else if (flag == CL_CKPT_SVR_DOWN)
        {
            /*
             * Mark the availability of checkpoint server as UNAVAILABLE.
             */
            if(pPeerInfo->credential == CL_CKPT_CREDENTIAL_POSITIVE)
                gCkptSvr->masterInfo.availPeerCount--;
            pPeerInfo->available = CL_CKPT_NODE_UNAVAIL;
        }   

        if(flag == CL_CKPT_NODE_DOWN
           ||
           flag == CL_CKPT_SVR_DOWN)
        {
            
            /*
             * Node down case, delete the entry from master's peer list.
             */
            rc = clCntAllNodesForKeyDelete(gCkptSvr->masterInfo.peerList,
                                (ClPtrT)(ClWordT)localAddr);
             CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR,
             (" MasterPeerUpdate failed rc[0x %x]\n",rc),
             rc);

        }
        
        if( flag != CL_CKPT_COMP_DOWN)
        {
            /*
             * Find other nodes to store the replicas of checkpoints for whom
             * this node was storing the replicas.
             */
             if(gCkptSvr->masterInfo.masterAddr == gCkptSvr->localAddr)
             {
                 _ckptCheckpointLoadBalancing();
             }
        }
    }
exitOnError:
    {
        return rc;
    }
}  
/*
 *  This function used to generate the OM for MOID and store it in OM db
 *  1. Get the OM class type from MOID.
 *  2. Get the OM class from the OM class type.
 *  3. Create the OM object for given MOID
 *  4. Then add OM object handle to prov OM db.
 *  5. Insert the OM object into MoId and OM Object table.
 */
ClRcT
clProvOmObjectPrepare( ClCorMOIdPtrT pFullMoId)
{
    ClCorClassTypeT moClassType = 0;
    ClOmClassTypeT  omClass     = 0;    
    ClHandleT       handle;
    void*           pOmObj      = NULL;
    ClRcT           rc          = CL_OK;
    ClProvTxnDataT  provTxnData = {0};
    ClRcT           retCode     = CL_OK;
    ClCorObjectHandleT corObjHandle = NULL;

    CL_FUNC_ENTER();

    rc = clCorMoIdToClassGet( pFullMoId, CL_COR_MO_CLASS_GET, &moClassType );
    CL_PROV_CHECK_RC1_LOG1( rc, CL_OK, CL_PROV_RC(CL_PROV_INTERNAL_ERROR), CL_LOG_ERROR,
                            CL_PROV_LOG_1_MO_CLASS_GET, rc );

    rc = clOmClassFromInfoModelGet( moClassType, CL_COR_SVC_ID_PROVISIONING_MANAGEMENT,
                                    &omClass );

    CL_PROV_CHECK_RC1_LOG1( rc, CL_OK, CL_PROV_RC(CL_PROV_INTERNAL_ERROR), CL_LOG_ERROR,
                            CL_PROV_LOG_1_GET_OM_CLASS, rc );

    retCode = clOmObjectCreate( omClass, 1, &handle, &pOmObj, ( void* )pFullMoId, sizeof( ClCorMOIdT ) );
    if (NULL == pOmObj)
    {
        CL_PROV_CHECK_RC1_EAQUAL_LOG0( pOmObj, NULL, retCode, CL_LOG_ERROR,
                                       CL_PROV_LOG_1_OM_OBJ_CREATE );
        CL_FUNC_EXIT();
        return retCode;
    }

    clOsalMutexLock( gClProvMutex );
    rc = clCntNodeAdd( gClProvOmHandleInfo, ( ClCntKeyHandleT )(ClWordT)handle, 0, NULL );
    clOsalMutexUnlock( gClProvMutex );
    CL_PROV_CHECK_RC1_LOG1( rc, CL_OK, CL_PROV_RC(CL_PROV_INTERNAL_ERROR), CL_LOG_INFORMATIONAL,
                            CL_PROV_LOG_1_CONTAINER_ADD, rc );

    rc = clOmMoIdToOmIdMapInsert( pFullMoId, handle );
    CL_PROV_CHECK_RC1_LOG1( rc, CL_OK, CL_PROV_RC(CL_PROV_INTERNAL_ERROR), CL_LOG_ERROR,
                            CL_PROV_LOG_1_MAP_MOID_OM, rc );

    provTxnData.provCmd    = CL_COR_OP_CREATE;
    provTxnData.pMoId      = pFullMoId;
    provTxnData.attrId     = CL_COR_INVALID_ATTR_ID;

    /* Call the application's Object Start callback function */

    if ((((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectStart) != NULL)
    {
        (void) (((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectStart(
                                                                  pFullMoId, 0));
    }

    /* Call the Validate callback */
    if( ( (CL_OM_PROV_CLASS *)pOmObj)->clProvObjectValidate )
    {
        retCode = ( (CL_OM_PROV_CLASS *)pOmObj)->clProvObjectValidate(pOmObj, 0, &provTxnData, 1);
    }
    else if( ( (CL_OM_PROV_CLASS *)pOmObj)->clProvValidate )
    {
        retCode = ((CL_OM_PROV_CLASS *) pOmObj)->clProvValidate(pOmObj, 0, &provTxnData);
    }
    else
    {
        retCode = CL_OK;
    }

    if (retCode != CL_OK)
    {
        clLogError("PRV", "VAL", CL_PROV_LOG_1_CREATE_VALIDATE, retCode);

        /* Call the rollback callback */
        if( ( (CL_OM_PROV_CLASS * )pOmObj )->clProvObjectRollback )
        {
            retCode =  ( (CL_OM_PROV_CLASS *)pOmObj)->clProvObjectRollback( pOmObj, 0, &provTxnData, 1);
        }
        else if ( ( (CL_OM_PROV_CLASS *)pOmObj)->clProvRollback )
        {
            retCode = ( ( CL_OM_PROV_CLASS * ) pOmObj )->clProvRollback( pOmObj, 0, &provTxnData );
        }
        else
        {
            retCode = CL_OK;
        }

        if (retCode != CL_OK)
        {
            clLogError("PRV", "VAL", CL_PROV_LOG_1_CREATE_ROLLBACK, retCode);
        }

        /* Call the application's Object End callback function */
        if (((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectEnd != NULL)
        {
            (((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectEnd(
                                                             pFullMoId, 0));
        }

        /* Remove the OM object */
        if ((rc = clOmObjectByReferenceDelete(pOmObj)) != CL_OK)
        {
            clLogError("OMC", "PRE", "Failed to delete the OM object. rc [0x%x]", rc);
        }

        /* Remove the MoId to OM Id mapping */
        if ((rc = clOmMoIdToOmIdMapRemove(pFullMoId)) != CL_OK)
        {
            clLogError("PRV", "PRE", "Failed to remove the MoId to OM Id mapping. rc [0x%x]", rc);
            CL_FUNC_EXIT();
            return rc;
        }

        CL_FUNC_EXIT();
        return (CL_OK);
    }

    /* Validate is successful, call the update callback function */
    if( ( (CL_OM_PROV_CLASS * )pOmObj)->clProvObjectUpdate )
    {
        retCode =  ( (CL_OM_PROV_CLASS *)pOmObj )->clProvObjectUpdate( pOmObj, 0, &provTxnData, 1);
    }
    else if ( ( (CL_OM_PROV_CLASS *)pOmObj)->clProvUpdate )
    {
        retCode = ( ( CL_OM_PROV_CLASS * ) pOmObj )->clProvUpdate( pOmObj, 0, &provTxnData );
    }
    else
    {
        retCode = CL_OK;
    }

    if (retCode != CL_OK)
    {
        clLogError("PRV", "PRE", CL_PROV_LOG_1_CREATE_UPDATE, rc);
    }

    /* Get the object handle */
    rc = clCorMoIdToObjectHandleGet(pFullMoId, &corObjHandle);
    if (rc != CL_OK)
    {
        clLogError("PRV", "PRE", "Failed to get Object Handle from MoId. rc [0x%x]", rc);
        return rc;
    }

    /* Do pre-provisioning for the attributes present in the object */
    if( ( (CL_OM_PROV_CLASS*)pOmObj)->clProvObjectValidate
        &&
        ( (CL_OM_PROV_CLASS *)pOmObj)->clProvObjectUpdate)
    {
        ClProvObjAttrArgsT provObjAttrArgs = {0};
        provObjAttrArgs.pMoId = pFullMoId;
        rc = clCorObjectAttributeWalk( corObjHandle, NULL, clProvObjAttrWalk, &provObjAttrArgs);
        if(rc == CL_OK && provObjAttrArgs.txnDataEntries > 0)
        {
            rc = ((CL_OM_PROV_CLASS*)pOmObj)->clProvObjectValidate(pOmObj, 0, 
                                                                   provObjAttrArgs.pProvTxnData,
                                                                   provObjAttrArgs.txnDataEntries);
            if(rc == CL_OK)
            {
                rc = ((CL_OM_PROV_CLASS*)pOmObj)->clProvObjectUpdate(pOmObj, 0,
                                                                     provObjAttrArgs.pProvTxnData,
                                                                     provObjAttrArgs.txnDataEntries);
            }
            else
            {
                if( ( (CL_OM_PROV_CLASS*)pOmObj)->clProvObjectRollback != NULL)
                {
                    rc =  ( (CL_OM_PROV_CLASS*)pOmObj)->clProvObjectRollback(pOmObj, 0,
                                                                             provObjAttrArgs.pProvTxnData,
                                                                             provObjAttrArgs.txnDataEntries);
                }
            }
        }
        clProvObjAttrFree(&provObjAttrArgs);
    }
    else
    {
        rc = clCorObjectAttributeWalk( corObjHandle, NULL, clProvAttrWalk, pFullMoId );
    }

    /* Calling Object-End callback function */
    if (((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectEnd != NULL)
    {
        (((CL_OM_PROV_CLASS *) pOmObj )->clProvObjectEnd(
                                                         pFullMoId, 0));
    }

    clCorObjectHandleFree(&corObjHandle);

    CL_FUNC_EXIT();
    return (CL_OK);
}