Beispiel #1
0
void CMainFrame::OnRepair(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/)
{
#ifdef __NEVER_DEFINED__
	BOOL bResults;
	BOOL bReturn = FALSE;

	int iItemSelected = m_viewTreeList.GetSelectedItemData();
	if (-1 == iItemSelected)
	{
		
		return;
	}
	
	CDiskObjectPtr obj = m_mapObject[iItemSelected];


	if( dynamic_cast<CDiskObjectComposite *>(obj.get()) == NULL )
	{
		
		return;
	}

	CDiskObjectCompositePtr DiskObjectComposite =
		boost::dynamic_pointer_cast<CDiskObjectComposite>(obj);

	if(!((NMT_RAID1 == DiskObjectComposite->GetNDASMediaType() ||
		NMT_RAID4 == DiskObjectComposite->GetNDASMediaType()) &&
		1 == DiskObjectComposite->GetMissingMemberCount()))
	{
		
		// TODO : No disk is available
		WTL::CString strMsg;
		strMsg.LoadString( IDS_MAINFRAME_NOT_READY_REPAIR );
		WTL::CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox(
			strMsg,
			strTitle, 
			MB_OK | MB_ICONERROR
			);
		return;
	}		


	CSelectDiskDlg dlgSelect(IDD_REPAIR);
	CDiskObjectList singleDisks;
	CFindIfVisitor<FALSE> singleDiskFinder;
	singleDisks = singleDiskFinder.FindIf(m_pRoot, IsWritableUnitDisk);

	if ( singleDisks.size() == 0 )
	{
		
		// TODO : No disk is available
		WTL::CString strMsg;
		strMsg.LoadString( IDS_MAINFRAME_NO_DISK_REPAIR );
		WTL::CString strTitle;
		strTitle.LoadString(IDS_APPLICATION);
		MessageBox(
			strMsg,
			strTitle, 
			MB_OK | MB_ICONWARNING
			);
		return;
	}

	dlgSelect.SetSingleDisks(singleDisks);

	if ( dlgSelect.DoModal() != IDOK )
		return;

	CUnitDiskObjectPtr replaceDisk, sourceDisk;
	sourceDisk = DiskObjectComposite->GetAvailableUnitDisk();
	replaceDisk = dlgSelect.GetSelectedDisk();

	if(NULL == sourceDisk.get())
		return;
	
	NDASCOMM_CONNECTION_INFO ci, ciReplace;

	ZeroMemory(&ci, sizeof(NDASCOMM_CONNECTION_INFO));
	ci.address_type = NDASCOMM_CONNECTION_INFO_TYPE_ADDR_LPX;
	ci.login_type = NDASCOMM_LOGIN_TYPE_NORMAL;
	ci.UnitNo = sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
	ci.bWriteAccess = TRUE;
	ci.ui64OEMCode = NULL;
	ci.bSupervisor = FALSE;
	ci.protocol = NDASCOMM_TRANSPORT_LPX;
	CopyMemory(ci.AddressLPX, 
		sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
		LPXADDR_NODE_LENGTH);

	ZeroMemory(&ciReplace, sizeof(NDASCOMM_CONNECTION_INFO));
	ciReplace.address_type = NDASCOMM_CONNECTION_INFO_TYPE_ADDR_LPX;
	ciReplace.login_type = NDASCOMM_LOGIN_TYPE_NORMAL;
	ciReplace.UnitNo = replaceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
	ciReplace.bWriteAccess = TRUE;
	ciReplace.ui64OEMCode = NULL;
	ciReplace.bSupervisor = FALSE;
	ciReplace.protocol = NDASCOMM_TRANSPORT_LPX;
	CopyMemory(ciReplace.AddressLPX, 
		replaceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr,
		LPXADDR_NODE_LENGTH);

	AutoCursor l_auto_cursor(IDC_WAIT);
	bResults = NdasOpRepair(&ci, &ciReplace);
	l_auto_cursor.Release();

	if(!bResults)
	{
		

		WTL :: CString strMsg;

		DWORD dwLastError = ::GetLastError();
		strMsg.LoadString(IDS_REPAIR_FAIL);

		ShowErrorMessageBox(strMsg);

		return;
	}

	CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid());
	bResults = HixChangeNotify.Initialize();
	if(bResults)
	{
		CUnitDiskObjectPtr UnitDiskObjectPtr;
		NDAS_UNITDEVICE_ID unitDeviceId;

		CDiskObjectComposite::const_iterator itr;
		for ( itr = DiskObjectComposite->begin(); itr != DiskObjectComposite->end(); ++itr )
		{
			if((dynamic_cast<CEmptyDiskObject*>((*itr).get()) != NULL))
				continue;

			UnitDiskObjectPtr = 
				boost::dynamic_pointer_cast<CUnitDiskObject>(*itr);

			CopyMemory(unitDeviceId.DeviceId.Node, 
				UnitDiskObjectPtr->GetLocation()->GetUnitDiskLocation()->MACAddr, 
				sizeof(unitDeviceId.DeviceId.Node));
			unitDeviceId.UnitNo = 
				UnitDiskObjectPtr->GetLocation()->GetUnitDiskLocation()->UnitNumber;
			HixChangeNotify.Notify(unitDeviceId);
		}

		CopyMemory(unitDeviceId.DeviceId.Node, 
			replaceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, 
			sizeof(unitDeviceId.DeviceId.Node));
		unitDeviceId.UnitNo = 
			replaceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber;
		HixChangeNotify.Notify(unitDeviceId);
	}


	CRecoverDlg dlgRecover(
		TRUE, 
        (NMT_RAID1 == DiskObjectComposite->GetNDASMediaType()) ?
		IDS_LOGDEV_TYPE_DISK_RAID1 : IDS_LOGDEV_TYPE_DISK_RAID4,
		IDS_RECOVERDLG_TASK_REPAIR);

	dlgRecover.SetMemberDevice(sourceDisk);
	dlgRecover.DoModal();

	OnRefreshStatus(NULL, NULL, NULL);
#endif
	
	return;
}
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;
}