///////////////////////////////////////////////////////////////
//
// CDatabaseJobQueueManager::SetLogLevel
//
// Update all queues with new log level
//
///////////////////////////////////////////////////////////////
void CDatabaseJobQueueManager::SetLogLevel(EJobLogLevelType logLevel, const SString& strLogFilename)
{
    CDbOptionsMap argMap;
    argMap.Set("name", strLogFilename);
    argMap.Set("level", logLevel);
    for (const auto iter : m_QueueNameMap)
    {
        CDbJobData* pJobData = iter.second->AddCommand(EJobCommand::SETLOGLEVEL, 0, argMap.ToString());
        FreeCommand(pJobData);
    }
}
Beispiel #2
0
void
hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
{
    ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
    PCommand pCmd;
	UINT result;
	int needsync=0, retry=0, needdelete=0;
	void *buffer = NULL;

	_VBUS_INST(&pAdapter->VBus)

	if (pArray->u.array.rf_broken==1 ||
    	pArray->u.array.RebuildSectors>=capacity)
		return;

	mtx_lock(&pAdapter->lock);
	
	switch(flags)
	{
		case DUPLICATE:
		case REBUILD_PARITY:
			if(pArray->u.array.rf_rebuilding == 0)
			{
				pArray->u.array.rf_rebuilding = 1;
				hpt_printk(("Rebuilding started.\n"));
				ioctl_ReportEvent(ET_REBUILD_STARTED, pArray);
			}
			break;

		case INITIALIZE:
			if(pArray->u.array.rf_initializing == 0)
			{
				pArray->u.array.rf_initializing = 1;
				hpt_printk(("Initializing started.\n"));
				ioctl_ReportEvent(ET_INITIALIZE_STARTED, pArray);
			}
			break;

		case VERIFY:
			if(pArray->u.array.rf_verifying == 0)
			{
				pArray->u.array.rf_verifying = 1;
				hpt_printk(("Verifying started.\n"));
				ioctl_ReportEvent(ET_VERIFY_STARTED, pArray);
			}
			break;
	}
	
retry_cmd:
	pCmd = AllocateCommand(_VBUS_P0);
	HPT_ASSERT(pCmd);
	pCmd->cf_control = 1;
	End_Job = 0;

	if (pArray->VDeviceType==VD_RAID_1) 
	{
		#define MAX_REBUILD_SECTORS 0x40

		/* take care for discontinuous buffer in R1ControlSgl */
		buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
		if(!buffer) {
			FreeCommand(_VBUS_P pCmd);
			hpt_printk(("can't allocate rebuild buffer\n"));
			goto fail;
		}
		switch(flags) 
		{
			case DUPLICATE:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD;
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
				break;

			case VERIFY:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_VERIFY;
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS/2;
				break;

			case INITIALIZE:
				pCmd->uCmd.R1Control.Command = CTRL_CMD_REBUILD; 
				pCmd->uCmd.R1Control.nSectors = MAX_REBUILD_SECTORS;
				break;
		}

		pCmd->uCmd.R1Control.Lba = pArray->u.array.RebuildSectors;

		if (capacity - pArray->u.array.RebuildSectors < pCmd->uCmd.R1Control.nSectors)
			pCmd->uCmd.R1Control.nSectors = capacity - pArray->u.array.RebuildSectors;

		pCmd->uCmd.R1Control.Buffer = buffer;
		pCmd->pfnBuildSgl = R1ControlSgl;
	}
	else if (pArray->VDeviceType==VD_RAID_5)
	{
		switch(flags)
		{
			case DUPLICATE:
			case REBUILD_PARITY:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_REBUILD; break;
			case VERIFY:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_VERIFY; break;
			case INITIALIZE:
				pCmd->uCmd.R5Control.Command = CTRL_CMD_INIT; break;
		}
		pCmd->uCmd.R5Control.StripeLine=pArray->u.array.RebuildSectors>>pArray->u.array.bArBlockSizeShift;
	}
	else
///////////////////////////////////////////////////////////////
//
// CDatabaseJobQueueImpl::DoPulse
//
// Check if any callback functions are due
//
///////////////////////////////////////////////////////////////
void CDatabaseJobQueueImpl::DoPulse ( void )
{
    // Check if any connection needs a flush
    while ( m_PendingFlushMap.size () )
    {
        SConnectionHandle connectionHandle = *m_PendingFlushMap.begin ();
        MapRemove ( m_PendingFlushMap, connectionHandle );
        CDbJobData* pJobData = AddCommand ( EJobCommand::FLUSH, connectionHandle, "" );
        FreeCommand ( pJobData );
    }

    shared.m_Mutex.Lock ();

again:
    // Delete finished
    for ( std::set < CDbJobData* >::iterator iter = m_FinishedList.begin () ; iter != m_FinishedList.end () ; )
    {
        CDbJobData* pJobData = *iter;
        m_FinishedList.erase ( iter++ );
        // Check not refed
        dassert ( !ListContains ( shared.m_CommandQueue, pJobData ) );
        dassert ( !ListContains ( shared.m_ResultQueue, pJobData ) );
        dassert ( !MapContains ( m_FinishedList, pJobData ) );

        dassert ( MapContains ( m_ActiveJobHandles, pJobData->GetId () ) );
        MapRemove ( m_ActiveJobHandles, pJobData->GetId () );
        dassert ( !pJobData->HasCallback () );
        SAFE_DELETE( pJobData );
        g_pStats->iDbJobDataCount--;
    }

    // Do pending callbacks
    for ( CJobQueueType::iterator iter = shared.m_ResultQueue.begin () ; iter != shared.m_ResultQueue.end () ; )
    {
        CDbJobData* pJobData = *iter;

        if ( pJobData->result.bIgnoreResult )
        {
            // Ignored results won't be collected, so move to finished list here
            iter = shared.m_ResultQueue.erase ( iter );
            pJobData->stage = EJobStage::FINISHED;
            MapInsert ( m_FinishedList, pJobData );
            // Still allow callback incase any cleanup is needed
        }
        else
            ++iter;

        if ( pJobData->HasCallback () )
        {
            shared.m_Mutex.Unlock ();
            pJobData->ProcessCallback ();              
            shared.m_Mutex.Lock ();

            // Redo from the top ensure everything is consistent
            goto again;
        }
    }

    shared.m_Mutex.Unlock ();

    UpdateDebugData ();
}