Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
// CUnitDiskUIHandler
///////////////////////////////////////////////////////////////////////////////
UINT CUnitDiskUIHandler::GetIconID(CDiskObjectPtr obj) const
{
	ATLASSERT(dynamic_cast<CUnitDiskObject*>(obj.get()) != NULL);
	CUnitDiskObjectPtr unitDisk = 
		boost::dynamic_pointer_cast<CUnitDiskObject>(obj);
	CUnitDiskInfoHandlerPtr handler = unitDisk->GetInfoHandler();

	if ( !obj->IsUsable() )
		return IDI_ND_BADKEY;

	if ( handler->IsHDD() )
	{
		if ( handler->IsBound() )
		{
			if ( handler->IsMaster() )
			{
				return IDI_ND_INUSE;
			}
			else
			{
				return IDI_ND_SLAVE;
			}
		}
		else
		{
			return IDI_ND_INUSE;
		}
	}
	else
	{
		// TODO : We need a new icon for this type(DVD, FLASH, MO.. ETC)
		return IDI_ND_INUSE;	
	}
}
Beispiel #2
0
PropertyList CUnitDiskUIHandler::GetPropertyList(CDiskObjectPtr obj) const
{
	PropertyList propList;
	PropertyListItem propItem;
	WTL::CString strBuffer;
	CUnitDiskObjectPtr unitDisk = 
		boost::dynamic_pointer_cast<CUnitDiskObject>(obj);
	CUnitDiskInfoHandlerPtr handler = unitDisk->GetInfoHandler();
	CHDDDiskInfoHandler *pHDDHandler = 
		dynamic_cast<CHDDDiskInfoHandler*>(handler.get());
	if ( pHDDHandler != NULL )
	{
		// TODO : String resources
		propItem.strName.LoadString( IDS_UIHANDLER_PROPERTY_MODEL );
		propItem.strValue = pHDDHandler->GetModelName();
		propItem.strToolTip.LoadString( IDS_UIHANDLER_PROPERTY_MODEL_TOOLTIP );
		propList.push_back( propItem );

		propItem.strName.LoadString( IDS_UIHANDLER_PROPERTY_SERIALNO );
		propItem.strValue = pHDDHandler->GetSerialNo();
		propItem.strToolTip.LoadString( IDS_UIHANDLER_PROPERTY_SERIALNO_TOOLTIP );
		propList.push_back( propItem );
	}
	return propList;
}
Beispiel #3
0
const CObjectUIHandler *CObjectUIHandler::GetUIHandler(CDiskObjectPtr obj)
{
	// TODO : More sophisticated way of determining uihandler based on the
	//		  status of the disks is necessary.
	static CAggrDiskUIHandler aggrUIHandler;
	static CMirDiskUIHandler mirUIHandler;
	static CEmptyDiskUIHandler emptyUIHandler;
	static CRAID4DiskUIHandler raid4UIHandler;
	static CUnitDiskUIHandler unitDiskUIHandler;
	static CUnsupportedDiskUIHandler unsupportedDiskUIHandler;

	if ( dynamic_cast<const CAggrDiskObject*>(obj.get()) != NULL )
		return &aggrUIHandler;
	if ( dynamic_cast<const CMirDiskObject*>(obj.get()) != NULL )
		return &mirUIHandler;
	if ( dynamic_cast<const CRAID4DiskObject*>(obj.get()) != NULL )
		return &raid4UIHandler;
	if ( dynamic_cast<const CEmptyDiskObject*>(obj.get()) != NULL )
		return &emptyUIHandler;
	if ( dynamic_cast<const CUnitDiskObject*>(obj.get()) != NULL )
	{
		CUnitDiskObjectPtr unitDisk =
			boost::dynamic_pointer_cast<CUnitDiskObject>(obj);
		CUnitDiskInfoHandlerPtr infoHandler = unitDisk->GetInfoHandler();
		if ( infoHandler->HasValidInfo() )
			return &unitDiskUIHandler;
		else
			return &unsupportedDiskUIHandler;
	}
	return &unitDiskUIHandler;		
}
Beispiel #4
0
UINT32
CMirDiskObject::GetNDASMediaType() const
{
	if(::IsEmptyDisk(FirstDisk()))
	{
		if(::IsEmptyDisk(SecondDisk()))
			return NMT_INVALID;
		else
		{
			CUnitDiskObjectPtr unitDisk = 
				boost::dynamic_pointer_cast<CUnitDiskObject>(SecondDisk());
			CUnitDiskInfoHandlerPtr unitHandler = unitDisk->GetInfoHandler();

			return unitHandler->GetNDASMediaType();
		}
	}
	else
	{
		CUnitDiskObjectPtr unitDisk = 
			boost::dynamic_pointer_cast<CUnitDiskObject>(FirstDisk());
		CUnitDiskInfoHandlerPtr unitHandler = unitDisk->GetInfoHandler();

		return unitHandler->GetNDASMediaType();
	}
}
Beispiel #5
0
void CMirrorWorkThread::RebindMirror()
{
	// Get list of disks involved in the previous mirroring.
	// NOTE : Because disks aggregated can also be mirrored,
	//	there can be more than two disks involved in the mirroring.
	CDiskObjectPtr aggregationRoot;
	aggregationRoot = m_pSource->GetParent();
	while ( !aggregationRoot->GetParent()->IsRoot() )
	{
		aggregationRoot = aggregationRoot->GetParent();
	}

	// Mark all the bitmaps dirty.
	m_pSource->OpenExclusive();
	m_pDest->OpenExclusive();
	m_pSource->MarkAllBitmap();

	CUnitDiskInfoHandlerPtr pHandler = m_pSource->GetInfoHandler();
	aggregationRoot->Rebind( 
						m_pDest, 
						pHandler->GetPosInBind() ^ 0x01
						);
	aggregationRoot->CommitDiskInfo(TRUE);


	// Write binding information to the destination disk
	m_pDest->Mirror(m_pSource);
	m_pDest->CommitDiskInfo(TRUE);
	m_bRebound = TRUE;

	m_pSource->Close();
	m_pDest->Close();
}
Beispiel #6
0
CUnitDiskObjectPtr 
FindMirrorDisk(CUnitDiskObjectPtr src, CUnitDiskObjectList disks)
{
	CUnitDiskInfoHandlerPtr handler = src->GetInfoHandler();
	ATLASSERT( handler->IsMirrored() );
	CUnitDiskObjectList::const_iterator found;

	found = std::find_if ( disks.begin(), disks.end(),
		std::bind1st( CDiskLocationEqual(), handler->GetPeerLocation() )
		);
	if ( found == disks.end() )
	{
		return CUnitDiskObjectPtr();
	}
	return *found;
}
Beispiel #7
0
UINT32
CRAID4DiskObject::GetNDASMediaType() const
{
	CUnitDiskObjectPtr pUnitDisk;
	std::list<CDiskObjectPtr>::iterator it;

	for(it = begin(); it != end(); ++it)
	{
		pUnitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*it);
		if(!::IsEmptyDisk(pUnitDisk))
		{
			CUnitDiskInfoHandlerPtr unitHandler = pUnitDisk->GetInfoHandler();

			return unitHandler->GetNDASMediaType();
		}
	}	

	return NMT_INVALID;
}
Beispiel #8
0
UINT32 CDiskObjectComposite::GetNDASMediaType() const
{
	UINT32 iMediaType = NMT_INVALID;

	// return the first NDAS Media type of unit disk which is not NMT_INVALID
	const_iterator itr;
	for ( itr = begin(); itr != end(); ++itr )
	{
		if(::IsEmptyDisk(*itr))
			continue;

		if(!(*itr)->IsUnitDisk())
		{
			CMirDiskObjectPtr mirDisk = 
				boost::dynamic_pointer_cast<CMirDiskObject>(*itr);

			if(mirDisk)
			{
				iMediaType = mirDisk->GetNDASMediaType();
				if(NMT_INVALID != iMediaType)
					return iMediaType;
			}
			else
			{
				return NMT_INVALID;
			}
		}

		if(0 == (*itr)->GetDiskCount()) // skip empty one
			continue;

		CUnitDiskObjectPtr unitDisk = 
			boost::dynamic_pointer_cast<CUnitDiskObject>(*itr);
		CUnitDiskInfoHandlerPtr unitHandler = unitDisk->GetInfoHandler();
		
		iMediaType = unitHandler->GetNDASMediaType();
		if(NMT_INVALID != iMediaType)
			return iMediaType;
	}
	return iMediaType;
}
Beispiel #9
0
BOOL CMirDiskObject::GetDirtyDiskStatus(BOOL *pbFirstDefected, BOOL *pbSecondDefected) const
{
	BOOL bResults;
	LAST_WRITTEN_SECTOR FirstLWS, SecondLWS;

	*pbFirstDefected = FALSE;
	*pbSecondDefected = FALSE;

	if(::IsEmptyDisk(FirstDisk()) || ::IsEmptyDisk(SecondDisk()))
		return 0;

	CUnitDiskInfoHandlerPtr Firsthandler = FirstDisk()->GetInfoHandler();
	CUnitDiskInfoHandlerPtr Secondhandler = SecondDisk()->GetInfoHandler();

	bResults = Firsthandler->GetLastWrittenSectorInfo(&FirstLWS);
	if(!bResults) return FALSE;
	bResults = Secondhandler->GetLastWrittenSectorInfo(&SecondLWS);
	if(!bResults) return FALSE;

	if ( Firsthandler->IsPeerDirty() || FirstLWS.timeStamp > SecondLWS.timeStamp)
	{
		*pbSecondDefected = TRUE;
	}
	else
	{
		*pbSecondDefected = FALSE;
	}

	if ( Secondhandler->IsPeerDirty() || SecondLWS.timeStamp > SecondLWS.timeStamp)
	{
		*pbFirstDefected = TRUE;
	}
	else
	{
		*pbFirstDefected = FALSE;
	}

	return TRUE;
}
Beispiel #10
0
CCommandSet CUnitDiskUIHandler::GetCommandSet(CDiskObjectPtr obj) const
{
	ATLASSERT( dynamic_cast<CUnitDiskObject*>(obj.get()) != NULL);
	CCommandSet setCommand;
	CUnitDiskObjectPtr unitDisk =
		boost::dynamic_pointer_cast<CUnitDiskObject>(obj);
	CUnitDiskInfoHandlerPtr handler = unitDisk->GetInfoHandler();
	BOOL bCanWrite;

	if ( handler->IsBound() )
	{
		CDiskObjectPtr aggrRoot = unitDisk->GetParent();
		if ( aggrRoot->IsRoot() )
		{
			// This can occur when the tree is updated just after
			// the disk is bound.
			// This additional if code prevents error.
			setCommand.push_back( CCommand(IDM_TOOL_UNBIND) ); 
		}
		else
		{
			while ( !aggrRoot->GetParent()->IsRoot() )
				aggrRoot = aggrRoot->GetParent();
			// To Unbind, we should have write privilege to all the disks in bind
			setCommand.push_back( CCommand(IDM_TOOL_UNBIND, 
				aggrRoot->GetAccessMask() & GENERIC_WRITE) );
		}
	}
	else
	{
		bCanWrite =  unitDisk->GetAccessMask() & GENERIC_WRITE;
		setCommand.push_back( CCommand(IDM_TOOL_ADDMIRROR, bCanWrite) );
	}

	if ( handler->IsMirrored() )
	{
		CMirDiskObjectPtr parent = 
			boost::dynamic_pointer_cast<CMirDiskObject>(unitDisk->GetParent());
		if ( parent.get() != NULL )
		{
			// To synchronize, we have write privilege to the two disks in mirroring
			setCommand.push_back( CCommand(IDM_TOOL_SYNCHRONIZE, 
									(parent->GetAccessMask() & GENERIC_WRITE) &&
									parent->IsDirty() && !parent->IsBroken() &&
									parent->HasWriteAccess()
									) 
								);
		}
		CDiskObjectPtr aggrRoot = unitDisk->GetParent();
		if ( aggrRoot->IsRoot() )
		{
			// This can occur when the tree is updated just after
			// the disk is bound.
			// This additional if code prevents error.
			setCommand.push_back( CCommand(IDM_TOOL_UNBIND) ); 
		}
		else
		{
			while ( !aggrRoot->GetParent()->IsRoot() )
				aggrRoot = aggrRoot->GetParent();
		}
	}
	else if(NMT_RAID4 == handler->GetNDASMediaType())
	{
		CRAID4DiskObjectPtr parent = 
			boost::dynamic_pointer_cast<CRAID4DiskObject>(unitDisk->GetParent());

		if ( parent.get() != NULL )
		{
			// To synchronize, we have write privilege to the two disks in mirroring
			setCommand.push_back( CCommand(IDM_TOOL_SYNCHRONIZE, 
				(parent->GetAccessMask() & GENERIC_WRITE)
				&& parent->IsDirty() && !parent->IsBroken() 
				) 
				);
		}
	}

	if(unitDisk->IsUnitDisk())
	{
		setCommand.push_back( CCommand(IDM_TOOL_SINGLE) );
	}
	return setCommand;
}
Beispiel #11
0
INT32 CRAID4DiskObject::GetDirtyDisk() const
{
	LAST_WRITTEN_SECTORS Base, Compare;
	BOOL bIsDirty;
	INT32 iDirtyDisk, i;

	if(size() < 3)
		return -1;

	CUnitDiskObjectPtr pUnitDisk;
	CUnitDiskInfoHandlerPtr pUnitDiskHandler;
	std::list<CDiskObjectPtr>::iterator it;

	bIsDirty = FALSE;
	i = 0;
	iDirtyDisk = -2;

	// checking bitmaps
	for(it = begin(); it != end(); ++it, i++)
	{
		pUnitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*it);
		if(::IsEmptyDisk(pUnitDisk))
			return -1;

		pUnitDiskHandler = pUnitDisk->GetInfoHandler();
		if(pUnitDiskHandler->IsPeerDirty())
		{
#ifdef RAID_CRITICAL_CHECK
			if(bIsDirty)
				return -1;
#endif
			bIsDirty = TRUE;
			
			iDirtyDisk = (i == 0) ? size() -1 : i -1; // previous device is dirty
		}
	}

	// checking LWS
	// 1 pass
	INT32 iSuspect;
	INT32 nFailCnt;
	i = 0;
	nFailCnt = 0;
	for(it = begin(); it != end(); ++it, i++)
	{
		pUnitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*it);
		if(::IsEmptyDisk(pUnitDisk))
		{
			return -1;
		}

		pUnitDiskHandler = pUnitDisk->GetInfoHandler();

		if(!i)
		{
			if(!pUnitDiskHandler->GetLastWrittenSectorsInfo(&Base))
				return -1;

			continue;
		}

		if(!pUnitDiskHandler->GetLastWrittenSectorsInfo(&Compare))
			return -1;

		if(memcmp(&Base, &Compare, sizeof(Base)))
		{
			nFailCnt++;
			iSuspect = i;
		}
	}

	if(0 == nFailCnt) // all are same
	{
		return iDirtyDisk;
	}
	else if(1 == nFailCnt)
	{
		if(bIsDirty && iSuspect != iDirtyDisk)
#ifdef RAID_CRITICAL_CHECK
			return -1;
#else
			return iDirtyDisk;
#endif
		return iSuspect;
	}
	else if(size() -1 == nFailCnt) // 1st device(0) is the suspect
	{
		iSuspect = 0;
		i = 1;

		for(it = begin(), ++it; it != end(); ++it)
		{
			pUnitDisk = boost::dynamic_pointer_cast<CUnitDiskObject>(*it);
			if(::IsEmptyDisk(pUnitDisk))
			{
				return -1;
			}

			pUnitDiskHandler = pUnitDisk->GetInfoHandler();

			if(1 == i)
			{
				if(!pUnitDiskHandler->GetLastWrittenSectorsInfo(&Base))
					return -1;

				continue;
			}

			if(!pUnitDiskHandler->GetLastWrittenSectorsInfo(&Compare))
				return -1;

			if(memcmp(&Base, &Compare, sizeof(Base)))
			{
#ifdef RAID_CRITICAL_CHECK
				return -1;
#else
				return (-2 == iDirtyDisk) ? iSuspect : iDirtyDisk;
#endif
			}

			i++;
		}

		// all the others are same
		if(bIsDirty && iSuspect != iDirtyDisk)
#ifdef RAID_CRITICAL_CHECK
			return -1;
#else
			return (-2 == iDirtyDisk) ? iSuspect : iDirtyDisk;
#endif
		
		return iSuspect;
	}
	else // 2 or more devices are not same
	{
#ifdef RAID_CRITICAL_CHECK
		return -1;
#else
		return (-2 == iDirtyDisk) ? iSuspect : iDirtyDisk;
#endif
	}
}
CDiskObjectPtr 
CDiskObjectBuilder::Build(const CDeviceInfoList listDevice, LPREFRESH_STATUS pFuncRefreshStatus, void *context)
{
	CUnitDiskObjectList listDiskObj;
	CDiskObjectCompositePtr root;
	CUnitDiskObjectList::const_iterator found;

	//
	// Build list of unit disks from the device list
	//
	listDiskObj = BuildDiskObjectList(listDevice, pFuncRefreshStatus, context);

	//
	// Construct structure of disks including aggregation and mirroring
	//
	root = CDiskObjectCompositePtr(new CRootDiskObject());

	while ( !listDiskObj.empty() )
	{
		CUnitDiskObjectPtr disk;
		disk = listDiskObj.front();

		CUnitDiskInfoHandlerPtr pInfoHandler = disk->GetInfoHandler();
			
		if ( !pInfoHandler->IsHDD() )
		{
			listDiskObj.pop_front();
			continue; // Only HDD type disk is supported.(This may be changed later)
		}
		if ( pInfoHandler->IsBound() )
		{
			CDiskLocationVector vtLocation =
				pInfoHandler->GetBoundDiskLocations(disk->GetLocation());

			if(NMT_RAID4 == pInfoHandler->GetNDASMediaType())
			{
				CDiskObjectCompositePtr raid4Disks = 
					CDiskObjectCompositePtr(new CRAID4DiskObject());

				for(UINT i = 0; i < vtLocation.size(); i++)
				{
					found = std::find_if(
						listDiskObj.begin(),
						listDiskObj.end(),
						std::bind1st(CDiskLocationEqual(), vtLocation[i]));

					if(found != listDiskObj.end() && 
						::HasSameBoundDiskList(*found, disk))
					{
						raid4Disks->AddChild(raid4Disks, *found);
						listDiskObj.erase(found);
					}
					else
					{
						raid4Disks->AddChild(raid4Disks,
							::CreateEmptyDiskObject());
					}
				}
				root->AddChild(root, raid4Disks);
			}
			else if ( pInfoHandler->IsBoundAndNotSingleMirrored() )
			{
				CDiskObjectCompositePtr aggrDisks = 
					CDiskObjectCompositePtr(new CAggrDiskObject());

				if ( pInfoHandler->IsMirrored() ) // double tree
				{
					for ( UINT i=0; i < vtLocation.size(); i+= 2 )
					{
						CMirDiskObjectPtr mirDisks =
							CMirDiskObjectPtr( new CMirDiskObject() );

						int emptydisk = 0;

						// find first of the pair
						found = std::find_if( 
								listDiskObj.begin(), 
								listDiskObj.end(),
								std::bind1st(CDiskLocationEqual(), vtLocation[i])
								);
						if ( found != listDiskObj.end() 
							&& ::HasSameBoundDiskList(*found, disk) )
						{
							mirDisks->AddChild( mirDisks, *found );
							listDiskObj.erase(found);
						}
						else
						{
							// create empty unit disk
							emptydisk++;
						}

						// find second of the pair
						found = std::find_if( 
							listDiskObj.begin(), 
							listDiskObj.end(),
							std::bind1st(CDiskLocationEqual(), vtLocation[i+1])
							);

						if ( found != listDiskObj.end() 
							&& ::HasSameBoundDiskList(*found, disk) )
						{
							mirDisks->AddChild( mirDisks, *found );
							listDiskObj.erase(found);
						}
						else
						{
							// create empty unit disk
							emptydisk++;
						}

						if(0 == emptydisk)
						{
						}
						else if(1 == emptydisk)
						{
							mirDisks->AddChild( mirDisks, ::CreateEmptyDiskObject());
						}
						else
						{
							listDiskObj.pop_front();
							root->AddChild( root, disk );
							break;
						}

						if ( mirDisks->size() != 0 ) // always 2 including empty disks
							aggrDisks->AddChild( aggrDisks, mirDisks );
					}
				}
				else
				{
					BOOL bFound = FALSE, bFoundSelf = FALSE;
					for ( UINT i=0; i < vtLocation.size(); i++ )
					{
						CDiskLocationPtr p = vtLocation[i];
						found = std::find_if( 
							listDiskObj.begin(), 
							listDiskObj.end(),
							std::bind1st(CDiskLocationEqual(), vtLocation[i])
							);
						if ( found != listDiskObj.end()
							&& ::HasSameBoundDiskList(*found, disk) )
						{
							bFound = TRUE;

							if(*found == disk)
								bFoundSelf = TRUE;

							aggrDisks->AddChild( aggrDisks, *found );
							listDiskObj.erase(found);
						}
						else
						{
							// create empty unit disk
							aggrDisks->AddChild( aggrDisks, ::CreateEmptyDiskObject());
						}

					}

					if(!bFound)
					{
						listDiskObj.pop_front();
						root->AddChild( root, disk );
						break;
					}

					if(!bFoundSelf)
					{
						listDiskObj.pop_front();
						root->AddChild( root, disk );
					}
				}
				root->AddChild( root, aggrDisks );
			}
			else if ( pInfoHandler->IsMirrored() )
			{
				CMirDiskObjectPtr mirDisks =
					CMirDiskObjectPtr( new CMirDiskObject() );

				UINT i = 0;
				int emptydisk = 0;

				// find first of the pair
				found = std::find_if( 
					listDiskObj.begin(), 
					listDiskObj.end(),
					std::bind1st(CDiskLocationEqual(), vtLocation[i])
					);
				if ( found != listDiskObj.end() 
					&& ::HasSameBoundDiskList(*found, disk) )
				{
					mirDisks->AddChild( mirDisks, *found );
					listDiskObj.erase(found);
				}
				else
				{
					// create empty unit disk
					emptydisk++;
				}

				// find second of the pair
				found = std::find_if( 
					listDiskObj.begin(), 
					listDiskObj.end(),
					std::bind1st(CDiskLocationEqual(), vtLocation[i+1])
					);
				if ( found != listDiskObj.end() 
					&& ::HasSameBoundDiskList(*found, disk) )
				{
					mirDisks->AddChild( mirDisks, *found );
					listDiskObj.erase(found);
				}
				else
				{
					// create empty unit disk
					emptydisk++;
				}

				if(0 == emptydisk)
				{
				}
				else if(1 == emptydisk)
				{
					mirDisks->AddChild( mirDisks, ::CreateEmptyDiskObject());
				}
				else
				{
					listDiskObj.pop_front();
					root->AddChild( root, disk );
					break;
				}

				root->AddChild(root, mirDisks);
			}
			else
			{
				listDiskObj.pop_front();
				root->AddChild( root, disk );
			}
		}
		else // pDiskInfoHander->IsBound()
		{
			listDiskObj.pop_front();
			root->AddChild( root, disk );
		}
	}	// while ( !listDiskObj.empty() )
	return root;
}