Example #1
0
DWORD WINAPI moveFileWorker (VOID* data)
{
	Task* task = (Task*) data;
	int result = 0;
	WIN32_FIND_DATA findData;
	TCHAR* tmpDst = (TCHAR*) fmAlloc (FM_MAX_PATH);
	TCHAR* tmpSrc = (TCHAR*) fmAlloc (FM_MAX_PATH);
	while (task->nextPath())
	{
		lstrcpy (tmpDst, task->getDstFolder());
		lstrcpy (tmpSrc, task->getCurSrcPath());
		result = recurseOperation
			(&findData,
			tmpSrc,
			tmpDst,
			progressRoutine,
			(void*)task->getProgress(),
			MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING,
			FM_OPERATION_MOVE, NULL);
	}
	SendMessage (task->getProgress()->hDlg, FM_MOVE_FINISHED, 0, (LPARAM) data);
	fmFree ((HLOCAL*)&tmpSrc);
	fmFree ((HLOCAL*)&tmpDst);
	return result;
}
Example #2
0
/**
 * assumes the list is already sorted, and the key function is defined as:
 *
 * key(d1, d2) >  0 => d1 > d2
 * key(d1, d2) == 0 => d1 == d2
 * key(d1, d2) <  0 => d1 < d2
 *
 * the new node is inserted prior to the node T such that T_data > data
 */
int fmDListInsertSorted(fm_dlist *list,
                        int (*key)(void *, void *),
                        void *data)
{
    fm_dlist_node *p, *nnode;

    nnode = (fm_dlist_node *) fmAlloc( sizeof(fm_dlist_node) );

    if (!nnode)
    {
        return FM_ERR_NO_MEM;
    }

    nnode->data = data;

    for (p = list->head ;
         p && (key(p->data, nnode->data) <= 0) ;
         p = p->nextPtr)
    {
        ;
    }

    /* p is now at a node that is "greater" than the new one */
    FM_DLL_INSERT_BEFORE(list, head, tail, p, nextPtr, prev, nnode);

    return FM_OK;

}   /* end fmDListInsertSorted */
Example #3
0
fm_status fmDListInsertBegin(fm_dlist *list, void *data)
{
    fm_dlist_node *nnode = (fm_dlist_node *) fmAlloc( sizeof(fm_dlist_node) );

    if (!nnode)
    {
        return FM_ERR_NO_MEM;
    }

    nnode->data = data;

    FM_DLL_INSERT_FIRST(list, head, tail, nnode, nextPtr, prev);

    return FM_OK;

}   /* end fmDListInsertBegin */
Example #4
0
/** fmDListInsertEndV2
 * \ingroup intList
 *
 * \desc            Insert item at the end of the list and return the inserted
 *                  node.
 *
 * \param[in]       list is the dlist on which to add the item at the end.
 *
 * \param[in]       data is pointer to the item to be added. 
 *
 * \param[out]      node is the pointer to the node that is added in the list.
 *
 * \return          None
 *
 *****************************************************************************/
fm_status fmDListInsertEndV2(fm_dlist *list, void *data, fm_dlist_node **node)
{
    fm_dlist_node *nnode = (fm_dlist_node *) fmAlloc( sizeof(fm_dlist_node) );

    if (!nnode)
    {
        return FM_ERR_NO_MEM;
    }

    nnode->data = data;

    FM_DLL_INSERT_LAST(list, head, tail, nnode, nextPtr, prev);

    *node = nnode;

    return FM_OK;

}   /* end fmDListInsertEnd */
Example #5
0
INT_PTR onMovePauseToggle (HWND hDlg, WPARAM wParam, LPARAM lParam)
{
	UINT buttonStrId = 0;
	if (isOperationThreadSuspended (hDlg))
	{
		resumeOperationThread (hDlg);
		buttonStrId = IDS_COPY_PAUSE;
	}
	else
	{	
		suspendOperationThread (hDlg);
		buttonStrId = IDS_COPY_RESUME;
	}
	TCHAR* str = (TCHAR*) fmAlloc (MAX_PATH);
	loadStringFromResource (hDlg, buttonStrId, str, MAX_PATH);
	SendDlgItemMessage (hDlg, IDC_PAUSE_TOGGLE, WM_SETTEXT, 0, (LPARAM) str);
	fmFree ((HLOCAL*)&str);
	return 0;
}
Example #6
0
/** fm10000CreateForwardingRule
 * \ingroup intStacking
 *
 * \desc            Creates a forwarding rule.
 *
 * \param[in]       sw is the switch number to operate on.
 *
 * \param[in]       ruleId points to caller allocated storage where the handle
 *                  of the new rule is written to.
 *
 * \param[in]       rule points to caller allocated storage containing the
 *                  rule to create.
 *
 * \return          FM_OK if successful.
 * \return          FM_ERR_NO_FREE_RESOURCES if there are no hardware resources
 *                  to accommodate the new forwarding rule.
 * \return          FM_ERR_NO_MEM if there is not enough memory to store
 *                  the forwarding rule data structure.
 *
 *****************************************************************************/
fm_status fm10000CreateForwardingRule(fm_int sw,
                                      fm_int *ruleId,
                                      fm_forwardRule *rule)
{
    fm_status                    err;
    fm_int                       camIndex;
    fm_glortCamEntry *           camEntry;
    fm_switch *                  switchPtr;
    fm_logicalPortInfo *         lportInfo;
    fm_forwardRuleInternal *     internalRule;
    fm10000_forwardRuleInternal *fwdExt;
    fm_stackingInfo *            stackingInfo;
    fm_port *                    portPtr;

    FM_LOG_ENTRY( FM_LOG_CAT_STACKING,
                  "sw=%d, ruleId=%p, rule=%p\n",
                  sw,
                  (void *) ruleId,
                  (void *) rule );

    switchPtr = GET_SWITCH_PTR(sw);
    lportInfo = &switchPtr->logicalPortInfo;
    portPtr   = GET_PORT_PTR(sw, rule->logicalPort);
    fwdExt    = NULL;

    if (portPtr == NULL)
    {
        err = FM_ERR_INVALID_PORT;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_STACKING, err);
    }

    stackingInfo = &switchPtr->stackingInfo;

    /***************************************************
     * Find an unused CAM entry.
     **************************************************/
    camIndex = fmFindUnusedCamEntry(sw);
    if (camIndex < 0)
    {
        err = FM_ERR_NO_FREE_RESOURCES;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_STACKING, err);
    }

    camEntry = &lportInfo->camEntries[camIndex];

    /***************************************************
     * Create an FM10000 forwarding rule extension.
     **************************************************/
    fwdExt = (fm10000_forwardRuleInternal *) fmAlloc( sizeof(fm10000_forwardRuleInternal) );

    if (fwdExt == NULL)
    {
        err = FM_ERR_NO_MEM;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_STACKING, err);
    }

    fwdExt->camEntry = camEntry;

    /***************************************************
     * Initialize the CAM entry.
     **************************************************/
    FM_MEMSET_S( camEntry, sizeof(fm_glortCamEntry), 0, sizeof(fm_glortCamEntry) );

    camEntry->camIndex = camIndex;
    camEntry->camKey   = rule->glort;
    camEntry->camMask  = ~rule->mask;   /* Hardware stores mask inverted from rule mask */

    if ( fmIsCardinalPort(sw, rule->logicalPort) )
    {
        camEntry->strict = FM_GLORT_ENTRY_TYPE_STRICT;
    }
    else
    {
        /* Needs to be hashed to support LAG on internal port for traffic
         * to be hashed across the internal LAG link. Especially
         * CPU traffic, since FTYPE is special delivery and won't
         * be hashed if set to ISL */
        camEntry->strict = FM_GLORT_ENTRY_TYPE_HASHED;
    }

    /***************************************************
     * This makes the assumption that the rule points
     * to a physical port that is not going to have its
     * dest table entry changing.
     **************************************************/
    camEntry->destIndex    = portPtr->destEntry->destIndex;
    camEntry->destCount    = 1;
    camEntry->useCount     = 1;

    /***************************************************
     * Write CAM entry to hardware.
     **************************************************/
    err = fm10000WriteGlortCamEntry(sw, camEntry, FM_UPDATE_CAM_AND_RAM);
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_STACKING, err);

    FM_LOG_DEBUG(FM_LOG_CAT_STACKING, "Wrote to CAM entry 0x%x\n", camIndex);

    /***************************************************
     * Get the underlying forwarding rule object.
     **************************************************/
    err = fmTreeFind( &stackingInfo->fwdRules,
                      *ruleId,
                      (void **) &internalRule );
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_STACKING, err);

    /***************************************************
     * Store pointer to extension.
     **************************************************/
    internalRule->extension = fwdExt;
    err                     = FM_OK;


ABORT:

    if (err != FM_OK)
    {
        if (fwdExt != NULL)
        {
            fmFree(fwdExt);
        }
    }

    FM_LOG_EXIT(FM_LOG_CAT_STACKING, err);

}   /* end fm10000CreateForwardingRule */
Example #7
0
/** fm10000CreateLogicalPortForMailboxGlort
 * \ingroup intStacking
 *
 * \desc            Creates a logical port for the given mailbox glort.  
 *                  This occurs only if the glort is not local 
 *                  to the current switch.
 *
 * \param[in]       sw is the switch number to operate on.
 *
 * \param[in]       glort is the glort for which a logical port is to be created
 *
 * \param[out]      logicalPort is a pointer to an integer into which the
 *                  new logical port will be written.
 *
 * \return          FM_OK if successful.
 * \return          FM_ERR_GLORT_IN_USE if the specified is already being used
 *                  by others.
 * \return          FM_ERR_NO_FREE_RESOURCES if logical port numbers available
 *                  for allocation.
 * \return          FM_ERR_NO_MEM if no memory available to store logical
 *                  port data structure.
 *
 *****************************************************************************/
fm_status fm10000CreateLogicalPortForMailboxGlort(fm_int    sw,
                                                  fm_uint32 glort,
                                                  fm_int *  logicalPort)
{
    fm_status        err;
    fm_switch *      switchPtr;
    fm_stackingInfo *stackingInfo;
    fm_port *        portPtr;
    fm10000_port *   portExt;
    fm_bool          found;


    FM_LOG_ENTRY( FM_LOG_CAT_STACKING,
                  "sw=%d, glort=%d, logicalPort=%p\n",
                  sw,
                  glort,
                  (void *) logicalPort );

    switchPtr    = GET_SWITCH_PTR(sw);
    stackingInfo = &switchPtr->stackingInfo;
    found        = FALSE;

    /* If there is an existing entry already, then return the existing one */
    err = fmGetGlortLogicalPort(sw, glort, logicalPort);
    if (err == FM_OK)
    {
        /* The port already exists, see if it is the same type */
        portPtr = GET_PORT_PTR(sw, *logicalPort);

        if (portPtr->portType == FM_PORT_TYPE_REMOTE)
        {
            /* Yes, return the existing port */
            FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_OK);
        }
        else
        {
            /* The glort is being used for something else */
            FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_GLORT_IN_USE);
        }
    }

    err = FM_OK;

    /***************************************************
     * Find an unused logical port number.
     **************************************************/
    *logicalPort = fmFindUnusedLogicalPorts(sw, 1);
    if (*logicalPort == -1)
    {
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_FREE_RESOURCES);
    }

    /***************************************************
     * Create an entry for the remote logical port.
     **************************************************/
    portPtr = (fm_port *) fmAlloc(sizeof(fm_port));
    if (portPtr == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_MEM);
    }

    FM_MEMSET_S( portPtr, sizeof(fm_port), 0, sizeof(fm_port) );

    portExt = (fm10000_port *) fmAlloc( sizeof(fm10000_port) );
    if (portExt == NULL)
    {
        fmFree(portPtr);
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_MEM);
    }

    FM_MEMSET_S( portExt, sizeof(fm10000_port), 0, sizeof(fm10000_port) );

    portPtr->switchPtr   = switchPtr;
    portPtr->portNumber  = *logicalPort;
    portPtr->portType    = FM_PORT_TYPE_REMOTE;
    portPtr->extension   = portExt;
    portPtr->lagIndex    = -1;
    portPtr->memberIndex = -1;
    portPtr->glort       = glort;
    portPtr->swagPort    = -1;

    /* Remote port structures created for mailbox purpose does not have 
       CAM entries assigned, as these entries are not created dynamically.
       Mailbox CAM entries are created at the mailbox init stage to optimise
       GLORT_CAM/GLORT_RAM entries usage. */
    portPtr->camEntry    = NULL;

    /* Initialize multicast group membership list */
    fmTreeInit(&portPtr->mcastGroupList);

    /***************************************************
     * Add it to the logical port table.
     **************************************************/
    switchPtr->portTable[*logicalPort] = portPtr;

    FM_LOG_EXIT(FM_LOG_CAT_STACKING, err);

}   /* end fm10000CreateLogicalPortForMailboxGlort */
Example #8
0
/** fm10000CreateLogicalPortForGlort
 * \ingroup intStacking
 *
 * \desc            Creates a logical port for the given glort.  This occurs
 *                  only if the glort is not local to the current switch and
 *                  a forwarding rule exists for the glort, otherwise an
 *                  error is returned.
 *
 * \param[in]       sw is the switch number to operate on.
 *
 * \param[in]       glort is the glort for which a logical port is to be created
 *
 * \param[out]      logicalPort is a pointer to an integer into which the
 *                  new logical port will be written.
 *
 * \return          FM_OK if successful.
 * \return          FM_ERR_GLORT_IN_USE if the specified is already being used
 *                  by others.
 * \return          FM_ERR_NO_FORWARDING_RULES if no forwarding rule associated
 *                  with glort.
 * \return          FM_ERR_NO_FREE_RESOURCES if logical port numbers available
 *                  for allocation.
 * \return          FM_ERR_NO_MEM if no memory available to store logical
 *                  port data structure.
 *
 *****************************************************************************/
fm_status fm10000CreateLogicalPortForGlort(fm_int    sw,
                                           fm_uint32 glort,
                                           fm_int *  logicalPort)
{
    fm_status               err;
    fm_switch *             switchPtr;
    fm_stackingInfo *       stackingInfo;
    fm_port *               portPtr;
    fm_glortCamEntry *      camEntry;
    fm10000_port *          portExt;
    fm_treeIterator         iter;
    fm_forwardRuleInternal *tmpRule;
    fm_uint64               tmpId;
    fm_bool                 found;

    FM_LOG_ENTRY( FM_LOG_CAT_STACKING,
                  "sw=%d, glort=%d, logicalPort=%p\n",
                  sw,
                  glort,
                  (void *) logicalPort );

    switchPtr    = GET_SWITCH_PTR(sw);
    stackingInfo = &switchPtr->stackingInfo;
    found        = FALSE;

    /* If there is an existing entry already, then return the existing one */
    err = fmGetGlortLogicalPort(sw, glort, logicalPort);
    if (err == FM_OK)
    {
        /* The port already exists, see if it is the same type */
        portPtr = GET_PORT_PTR(sw, *logicalPort);

        if (portPtr->portType == FM_PORT_TYPE_REMOTE)
        {
            /* Yes, return the existing port */
            FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_OK);
        }
        else
        {
            /* The glort is being used for something else */
            FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_GLORT_IN_USE);
        }
    }

    /***************************************************
     * Search the tree for a forwarding rule with a
     * matching glort.
     **************************************************/
    fmTreeIterInit(&iter, &stackingInfo->fwdRules);

    err = fmTreeIterNext( &iter, &tmpId, (void **) &tmpRule );

    while (err != FM_ERR_NO_MORE)
    {
        if ( ( ~tmpRule->rule.mask & tmpRule->rule.glort ) ==
             ( ~tmpRule->rule.mask & glort ) )
        {
            found = TRUE;
            break;
        }

        err = fmTreeIterNext( &iter, &tmpId, (void **) &tmpRule );
    }

    if ( !found )
    {
        FM_LOG_DEBUG(FM_LOG_CAT_STACKING,
                     "Glort 0x%x was not matched to a forwarding rule\n",
                     glort);

        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_FORWARDING_RULES);
    }

    FM_LOG_DEBUG(FM_LOG_CAT_STACKING,
                 "Glort 0x%x was matched to forwarding rule #%lld\n",
                 glort,
                 tmpId);

    camEntry = ( (fm10000_forwardRuleInternal *) tmpRule->extension )->camEntry;

    /***************************************************
     * Find an unused logical port number.
     **************************************************/
    *logicalPort = fmFindUnusedLogicalPorts(sw, 1);
    if (*logicalPort == -1)
    {
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_FREE_RESOURCES);
    }

    /***************************************************
     * Create an entry for the remote logical port.
     **************************************************/
    portPtr = (fm_port *) fmAlloc(sizeof(fm_port));
    if (portPtr == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_MEM);
    }

    FM_MEMSET_S( portPtr, sizeof(fm_port), 0, sizeof(fm_port) );

    portExt = (fm10000_port *) fmAlloc( sizeof(fm10000_port) );
    if (portExt == NULL)
    {
        fmFree(portPtr);
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_ERR_NO_MEM);
    }

    FM_MEMSET_S( portExt, sizeof(fm10000_port), 0, sizeof(fm10000_port) );

    portPtr->switchPtr   = switchPtr;
    portPtr->portNumber  = *logicalPort;
    portPtr->portType    = FM_PORT_TYPE_REMOTE;
    portPtr->extension   = portExt;
    portPtr->lagIndex    = -1;
    portPtr->memberIndex = -1;
    portPtr->glort       = glort;
    portPtr->swagPort    = -1;
    portPtr->camEntry    = camEntry;

    /* Increase the CAM reference use count */
    portPtr->camEntry->useCount++;

    portPtr->destEntry  = NULL;
    portPtr->numDestEntries = 0;

    /* Initialize multicast group membership list */
    fmTreeInit(&portPtr->mcastGroupList);

    /* Set the default to down, the application must
     * bring it up, similar to physical port. */
    portPtr->mode = FM_PORT_STATE_DOWN;

    /***************************************************
     * Add it to the logical port table.
     **************************************************/
    switchPtr->portTable[*logicalPort] = portPtr;

    FM_LOG_EXIT(FM_LOG_CAT_STACKING, err);

}   /* end fm10000CreateLogicalPortForGlort */
Example #9
0
/** fmOpenDynamicLoadLibs
 * \ingroup alosDynLoadLib
 *
 * \desc            Open a Dynamic Load Library.
 *
 * \param[in]       filePath points to the string containing the library path.
 *
 * \param[out]      handle points to caller-provided memory into which the
 *                  dynamic-load-library's handle will be written.
 *
 * \return          FM_ERR_UNINITIALIZED if the ALOS subsystem has not been
 *                  properly initialized.
 * \return          FM_ERR_INVALID_ARGUMENT if one of the arguments is invalid.
 * \return          FM_OK if successful.
 * \return          FM_ERR_NO_MEM if unable to allocate memory.
 * \return          FM_ERR_TABLE_FULL if the dynamic-load library table is full.
 * \return          FM_ERR_NOT_FOUND if the dynamic-load library open failed.
 *
 *****************************************************************************/
fm_status fmOpenDynamicLoadLibrary(fm_text filePath, fm_int *handle)
{
    fm_status      err;
    fm_int         index;
    fm_dynLoadLib *lib;
    fm_int         availIndex;
    fm_int         pathLen;
    fm_bool        lockTaken;
    fm_bool        libAllocated;
    void *         libHandle;

    FM_LOG_ENTRY( FM_LOG_CAT_ALOS_DLLIB,
                  "filePath = %p (%s), handle = %p\n",
                  (void *) filePath,
                  (filePath != NULL) ? filePath : "<NULL>",
                  (void *) handle );

    lib          = NULL;
    availIndex   = -1;
    lockTaken    = FALSE;
    libAllocated = FALSE;

    if (fmRootAlos == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_ALOS_DLLIB, FM_ERR_UNINITIALIZED);
    }

    if (filePath == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_ALOS_DLLIB, FM_ERR_INVALID_ARGUMENT);
    }

    if (handle == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_ALOS_DLLIB, FM_ERR_INVALID_ARGUMENT);
    }

    pathLen = strlen(filePath);

    if (pathLen <= 0)
    {
        FM_LOG_EXIT(FM_LOG_CAT_ALOS_DLLIB, FM_ERR_INVALID_ARGUMENT);
    }

    err = fmCaptureLock(&fmRootAlos->dlAccessLock, FM_WAIT_FOREVER);

    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_DLLIB, err);

    lockTaken = TRUE;

    for (index = 0 ; index < FM_ALOS_INTERNAL_DYN_LOAD_LIBS ; index++)
    {
        if (fmRootAlos->dlLibs[index] == NULL)
        {
            if (availIndex < 0)
            {
                availIndex = index;
            }
        }
        else
        {
            lib = fmRootAlos->dlLibs[index];

            if ( strcmp(filePath, lib->filePath) == 0 )
            {
                break;
            }
        }
    }

    if (index >= FM_ALOS_INTERNAL_DYN_LOAD_LIBS)
    {
        index = availIndex;
    }

    if (index < 0)
    {
        err = FM_ERR_TABLE_FULL;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_DLLIB, err);
    }

    lib = fmRootAlos->dlLibs[index];

    if (lib == NULL)
    {
        lib = fmAlloc( sizeof(fm_dynLoadLib) );

        if (lib == NULL)
        {
            err = FM_ERR_NO_MEM;
            FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_DLLIB, err);
        }

        libAllocated = TRUE;

        FM_CLEAR(*lib);

        lib->filePath = fmAlloc( pathLen + 1 );

        if (lib->filePath == NULL)
        {
            err = FM_ERR_NO_MEM;
            FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_DLLIB, err);
        }

        FM_STRNCPY_S(lib->filePath, pathLen + 1, filePath, pathLen + 1 );

        lib->useCount = 0;

        fmRootAlos->dlLibs[index] = lib;
    }

    if ( ( fmProcessDynLoadLibStatus & (1 << index) ) == 0 )
    {
        libHandle = dlopen(filePath, RTLD_NOW | RTLD_GLOBAL);

        if (libHandle == NULL)
        {
            char *errMsg = dlerror();
            FM_LOG_ERROR(FM_LOG_CAT_ALOS_DLLIB,
                         "Error opening library %s: %s\n",
                         filePath,
                         errMsg);

            err = FM_ERR_NOT_FOUND;
            FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_DLLIB, err);
        }

        ProcessHandles[index] = libHandle;

        lib->useCount++;
        
        fmProcessDynLoadLibStatus |= FM_LITERAL_U64(1) << index;
    }

    *handle = index;
    err     = FM_OK;


ABORT:

    if ( (err != FM_OK) && libAllocated )
    {
        if (lib->filePath != NULL)
        {
            fmFree(lib->filePath);
        }

        fmFree(lib);
    }

    if (lockTaken)
    {
        fmReleaseLock(&fmRootAlos->dlAccessLock);
    }

    FM_LOG_EXIT(FM_LOG_CAT_ALOS_DLLIB, err);

}   /* end fmOpenDynamicLoadLibrary */
Example #10
0
/** fmAlosRootInit
 * \ingroup intAlosInit
 *
 * \desc            Initialize ALOS state.
 *
 * \param[in]       None.
 *
 * \return          FM_OK if successful. 
 * \return          FM_ERR_NO_MEM if unable to allocate memory.
 *
 *****************************************************************************/
static fm_status fmAlosRootInit(void)
{
    fm_status           err;
    int                 ret;
    pthread_mutexattr_t attr;

    FM_LOG_ENTRY(FM_LOG_CAT_ALOS, "(no arguments)\n");

    /* Allocate memory for ALOS state. */
    fmRootAlos = fmAlloc( sizeof(fm_rootAlos) );

    if (fmRootAlos == NULL)
    {
        /* Could not get memory. */
        FM_LOG_EXIT(FM_LOG_CAT_ALOS, FM_ERR_NO_MEM);
    }

    err = fmAlosLockInit();
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_ALOS, err);

    if ( pthread_mutexattr_init(&attr) != 0 )
    {
        FM_LOG_EXIT(FM_LOG_CAT_ALOS_SEM, FM_ERR_LOCK_INIT);
    }

    /*
     * From this point on, attr has been initialized, and we may ABORT.
     */

    if ( pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0 )
    {
        err = FM_ERR_LOCK_INIT;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS_SEM, err);
    }

    ret = pthread_mutex_init(&fmRootAlos->treeTreeLock, &attr);
    if (ret != 0)
    {
        err = FM_ERR_LOCK_INIT;
        FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_DEBUG, err);
    }

    /* Initialize the tree of trees */
    fmTreeInit(&fmRootAlos->treeTree);

    err = fmAlosRwlockInit();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmAlosSemInit();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmAlosLoggingInit();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmInitializeApiProperties();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmInitDynamicLoadLibs();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmAlosRandInit();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

    err = fmAlosTimeInit();
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_ALOS, err);

ABORT:
    pthread_mutexattr_destroy(&attr);

    FM_LOG_EXIT(FM_LOG_CAT_ALOS, err);

}   /* end fmAlosRootInit */
Example #11
0
/** fmCreatePolicer
 * \ingroup policer
 *
 * \chips           FM3000, FM4000, FM6000, FM10000
 *
 * \desc            Create a policer. Policers are used to manage
 *                  ingress bandwidth usage based on traffic flows
 *                  characterized by an ACL rule. Once created, a policer is
 *                  associated with an ACL rule in a call to ''fmAddACLRuleExt''.
 *                                                                      \lb\lb
 *                  Policers can be used to manage the bandwidth of a traffic
 *                  flow, or merely count frames and octets for a flow.
 *                                                                      \lb\lb
 *                  Policers are organized into "banks." Multiple ACLs can
 *                  simultaneously "hit" multiple policers, as long as they
 *                  are in different banks. The application need not be
 *                  concerned with the selection of which policers are placed
 *                  in which banks; the ACL compiler (''fmCompileACL'') will
 *                  make the placements automatically. However, not all
 *                  combinations of policer attributes are possible in hardware
 *                  (some attributes are per-bank). The user may want to
 *                  control the arrangement of policers in banks to better
 *                  understand which attribute combinations are foiling the
 *                  compiler. Whether bank selection is performed by the
 *                  application or by the ACL compiler, the choice should be
 *                  consistent for all policers created.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       bank is the bank in which to create the policer.
 *                  Set to FM_POLICER_BANK_AUTOMATIC to have the ACL compiler
 *                  (''fmCompileACL'') automatically assign the policer to a
 *                  bank.
 *
 * \param[in]       policer is the policer number to create. Policer numbers
 *                  are unique across all banks.
 *
 * \param[in]       config points to a structure of type ''fm_policerConfig''
 *                  that contains the initial configuration of the policer.
 *                  Alternatively, config can be NULL and the policer
 *                  configuration can be set with calls to
 *                  ''fmSetPolicerAttribute''
 *
 * \return          FM_OK if successful.
 * \return          FM_ERR_INVALID_SWITCH if sw is invalid.
 * \return          FM_ERR_INVALID_POLICER if policer already created.
 * \return          FM_ERR_INVALID_ARGUMENT if bank or policer values are
 *                  out of range.
 *
 *****************************************************************************/
fm_status fmCreatePolicer(fm_int                  sw,
                          fm_int                  bank,
                          fm_int                  policer,
                          const fm_policerConfig *config)
{
    fm_policerInfo *      info;
    fm_individualPolicer *entry;
    fm_switch *           switchPtr;

    FM_API_PREAMBLE("sw = %d, bank = %d, policer = %d, config = %p\n",
                    sw,
                    bank,
                    policer,
                    (void *) config);

    FM_API_REQUIRE(POLICER_VALID(policer) && BANK_VALID(sw, bank),
                   FM_ERR_INVALID_ARGUMENT);

    switchPtr = GET_SWITCH_PTR(sw);

    info  = &switchPtr->policerInfo;
    entry = (fm_individualPolicer *) fmAlloc( sizeof(fm_individualPolicer) );
    FM_API_REQUIRE(entry != NULL, FM_ERR_NO_MEM);

    entry->bank = bank;

    if (config == NULL)
    {
        /* default attribute values */
        entry->attributes.mkdnDscp    = FM_DISABLED;
        entry->attributes.mkdnSwPri   = FM_DISABLED;
        entry->attributes.colorSource = FM_POLICER_COLOR_SRC_GREEN;
        entry->attributes.cirAction   = FM_POLICER_ACTION_DROP;
        entry->attributes.cirCapacity = 0;
        entry->attributes.cirRate     = 0;
        entry->attributes.eirAction   = FM_POLICER_ACTION_DROP;
        entry->attributes.eirCapacity = 0;
        entry->attributes.eirRate     = 0;
        entry->attributes.cirActionData.dscp = 0;
        entry->attributes.cirActionData.swPri = 0;
        entry->attributes.cirActionData.vPri = 0;
        entry->attributes.eirActionData.dscp = 0;
        entry->attributes.eirActionData.swPri = 0;
        entry->attributes.eirActionData.vPri = 0;
    }
    else
    {
        entry->attributes = *config;
    }

    err = fmTreeInsert(&info->policers, policer, entry);

    if (err != FM_OK)
    {
        fmFree(entry);

        if (err == FM_ERR_ALREADY_EXISTS)
        {
            err = FM_ERR_INVALID_POLICER;
        }
    }

    if ( (err == FM_OK) && (switchPtr->CreatePolicer != NULL) )
    {
        /* for SWAG */
        err = switchPtr->CreatePolicer(sw, bank, policer, config);

        /* Try to return a clean state by removing the policer from switches that
         * actually created it (if some). Sorting order of creation and deletion
         * should be the same. */
        if (err != FM_OK)
        {
            switchPtr->DeletePolicer(sw, policer);
            fmTreeRemoveCertain(&info->policers, policer, fmFree);
        }
    }

    FM_API_POSTAMBLE;

}   /* end fmCreatePolicer */