Example #1
0
void CLanUnitDiskObject::MarkAllBitmap(BOOL bMarkDirty)
{
	// For write operation, session must be
	// created in advance.
	ATLASSERT( m_session.IsLoggedIn(TRUE) != FALSE );
	// TODO : We need to check whether the DISK_INFOMRATION_BLOCK is version 2
	CBitmapSector bitmap;

	::FillMemory( 
		bitmap.GetData(), 
		bitmap.GetCount() * LANSCSI_BLOCK_SIZE, 
		(bMarkDirty)? 0xff : 0x00 
		);
	try{
		bitmap.WriteAccept( &m_session );
	}
	catch( CNDASException &e )
	{
		NDAS_THROW_EXCEPTION_CHAIN_STR(
			CDiskException,
			CDiskException::ERROR_FAIL_TO_MARK_BITMAP,
			_T("Fail to write bitmap"),
			e);
	}
	
	// Mark the disk as dirty
	m_pHandler->SetDirty(bMarkDirty);
	try { 
	m_pHandler->CommitDiskInfo( &m_session );
	}
	catch( CNDASException &e )
	{
		NDAS_THROW_EXCEPTION_CHAIN_STR(
			CDiskException,
			CDiskException::ERROR_FAIL_TO_MARK_BITMAP,
			_T("Fail to update NDAS_DIB"),
			e);
	}
}
Example #2
0
void CMirrorWorkThread::Run()
{
	::ZeroMemory( &m_report, sizeof(NBSYNC_REPORT) );
	m_report.nSize = sizeof(NBSYNC_REPORT);
	if ( m_nWorkType == NBSYNC_TYPE_REMIRROR && !m_bRebound )
	{
		try{
			Notify( NBSYNC_PHASE_REBIND );
			RebindMirror();
		}
		catch( CNDASException &e )
		{
			e.PrintStackTrace();
			// TODO : We need more detail... the reason.
			Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_MARK_BITMAP );
			return;
		}
	}

	if ( m_nWorkType == NBSYNC_TYPE_ADDMIRROR && !m_bAdded )
	{
		try {
			Notify( NBSYNC_PHASE_BIND );
			AddMirror();
		}
		catch( CNDASException &e )
		{
			e.PrintStackTrace();
			// TODO : We need more detail... the reason.
			Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_ADDMIRROR );
			return;
		}
	}

	CSession sSource, sDest;
	CBitmapSector bitmapSector;
	const UNIT_DISK_LOCATION *pSourceLocation, *pDestLocation;

	pSourceLocation = m_pSource->GetLocation()->GetUnitDiskLocation();
	pDestLocation	= m_pDest->GetLocation()->GetUnitDiskLocation();

	Notify( NBSYNC_PHASE_CONNECT );
	try{
		sSource.Connect( pSourceLocation->MACAddr );
		sDest.Connect( pDestLocation->MACAddr );
	}
	catch( CNDASException &e )
	{
		e.PrintStackTrace();
		Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_CONNECT );
		return;
	}

	try{
		sSource.Login( pSourceLocation->UnitNumber, TRUE );
		sDest.Login( pSourceLocation->UnitNumber, TRUE );
	}
	catch( CNDASException &e )
	{
		e.PrintStackTrace();
		Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_CONNECT );
		return;
	}

	Notify( NBSYNC_PHASE_RETRIVE_BITMAP );
	//
	// Get bitmap from the disk
	//
	try{
		bitmapSector.ReadAccept( &sSource );
	}
	catch( CNDASException &e )
	{
		e.PrintStackTrace();
		Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_READ_BITMAP );
		return;
	}

	Notify( NBSYNC_PHASE_SYNCHRONIZE );

	//
	// Copying blocks
	//
	CHDDDiskInfoHandler *pHandler;

	pHandler = dynamic_cast<CHDDDiskInfoHandler*>(m_pSource->GetInfoHandler().get());
	ATLASSERT( pHandler != NULL );

	int			i, j, k;
	_int8		bitFlag;
	_int16		nBitmapSecCount;
	_int32		nSectorPerBit, nSectorPerByte;
	_int8		*pbBitmap;
	_int64		nTotalDirtySize;
	_int64		nProcessedDirtySize;
	CDataSector dataSector, bitmapUpdateSector;

	pbBitmap = bitmapSector.GetData();
	nSectorPerBit = pHandler->GetSectorsPerBit();
	nSectorPerByte = nSectorPerBit*8;
	nBitmapSecCount = 
		static_cast<_int16>(
			pHandler->GetUserSectorCount() / (nSectorPerBit*BLOCK_SIZE*8)
			);
	ATLASSERT( nBitmapSecCount <= bitmapSector.GetCount() );
	dataSector.Resize(nSectorPerBit);
	::ZeroMemory( 
		bitmapUpdateSector.GetData(), 
		bitmapUpdateSector.GetCount() * BLOCK_SIZE 
		);
	// Calculate total amount of sectors to copy
	nTotalDirtySize = 0;
	nProcessedDirtySize = 0;
	for ( i=0; i < nBitmapSecCount; i++ )
	{
		for ( j=0; j < BLOCK_SIZE; j++ )
		{
			bitFlag = pbBitmap[i*BLOCK_SIZE + j];
			if ( bitFlag == 0x00 )	// flag is clean(since most flags can be clean, this can improve efficiency)
			{
				continue;
			}
			for ( k=0; k < sizeof(_int8)* 8; k++ )
			{
				if ( (bitFlag & ( 0x01 << k )) != 0 )
					nTotalDirtySize += nSectorPerBit;
			}
		}
	}
	NotifyTotalSize( 
		pHandler->GetUserSectorCount(),
		nTotalDirtySize );
	for ( i=0; i < nBitmapSecCount; i++ )
	{
		for ( j=0; j < BLOCK_SIZE; j++ )
		{
			bitFlag = pbBitmap[i*BLOCK_SIZE + j];
			if ( bitFlag == 0x00 )	// flag is clean(since most flags can be clean, this can improve efficiency)
			{
				continue;
			}

			for ( k=0; k < sizeof(_int8)* 8; k++ )
			{
				if ( IsStopped() )
				{
					goto out;
				}
				// Sectors are mapped from LSB to MSB
				if ( (bitFlag & ( 0x01 << k )) != 0 )
				{
					dataSector.SetLocation(
						(static_cast<_int64>(i*BLOCK_SIZE + j)*sizeof(_int8) + k)*nSectorPerBit
						);
					try {
						dataSector.ReadAccept( &sSource );
						dataSector.WriteAccept( &sDest );
					}
					catch( CNDASException &e )
					{
						e.PrintStackTrace();
						Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_COPY );
						return;
					}
					nProcessedDirtySize += nSectorPerBit;
				}
				NotifyProgressDirty( nProcessedDirtySize );
			} // for ( k=0; ...
		}	// for ( j=0; ...
		// Clean up bitmap
		if ( IsStopped() )
		{
			goto out;
		}
		bitmapUpdateSector.SetLocation( 
			bitmapSector.GetLocation() + static_cast<_int64>(i) 
			);
		try{
			bitmapUpdateSector.WriteAccept( &sSource );
		}
		catch( CNDASException &e )
		{
			e.PrintStackTrace();
			Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_UPDATE_BITMAP );
			return;
		}
		NotifyProgress( static_cast<_int64>(i*BLOCK_SIZE + j) * 8 * nSectorPerBit );
	}	// for ( i=0; ...

	// In case the bitmap does not fit into sectors exactly.
	_int64 nProcessedSize = 
		static_cast<_int64>(nBitmapSecCount) * BLOCK_SIZE * 8 * nSectorPerBit;
	if ( nProcessedSize < pHandler->GetUserSectorCount() )
	{
		int nLeftSize = 
			static_cast<int>(pHandler->GetUserSectorCount()-nProcessedSize);
		for ( i=0; i < nLeftSize; i++ )
		{
			bitFlag = pbBitmap[nBitmapSecCount*BLOCK_SIZE + i/nSectorPerByte];
			if ( IsStopped() )
			{
				goto out;
			}
			if ( (bitFlag & (0x01 << (i%8))) != 0 )
			{
				dataSector.SetLocation(
					static_cast<_int64>(nBitmapSecCount*BLOCK_SIZE + i)*nSectorPerBit
					);
				try {
					dataSector.ReadAccept( &sSource );
					dataSector.WriteAccept( &sDest );
				}
				catch( CNDASException &e )
				{
					e.PrintStackTrace();
					Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_COPY );
					return;
				}
				nProcessedDirtySize += nSectorPerBit;
				NotifyProgressDirty( nProcessedDirtySize );
			}
		}
		bitmapUpdateSector.SetLocation( 
			bitmapSector.GetLocation() + nBitmapSecCount
			);
		try{
			bitmapUpdateSector.WriteAccept( &sSource );
		}
		catch( CNDASException &e )
		{
			e.PrintStackTrace();
			Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_UPDATE_BITMAP );
			return;
		}
		NotifyProgress( pHandler->GetUserSectorCount() );
	}

	sSource.Logout();
	sDest.Logout();
	sSource.Disconnect();
	sDest.Disconnect();

	try{
		m_pSource->OpenExclusive();
		m_pSource->SetDirty(FALSE);
		m_pSource->CommitDiskInfo( TRUE );
	}
	catch( CNDASException &e )
	{
		e.PrintStackTrace();
		Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_FAIL_TO_CLEAR_DIRTYFLAG );
		return;
	}

	Notify( NBSYNC_PHASE_FINISHED );
	return;

out:
	sSource.Logout();
	sDest.Logout();
	sSource.Disconnect();
	sDest.Disconnect();
	
	if ( IsStopped() )
		Notify( NBSYNC_PHASE_FAILED, NBSYNC_ERRORCODE_STOPPED );
	else
		Notify( NBSYNC_PHASE_FINISHED );
}