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; }
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; }