Changeset 43870 in vbox for trunk/src/VBox/Main/src-server/MachineImpl.cpp
- Timestamp:
- Nov 14, 2012 6:04:07 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r43185 r43870 10241 10241 else 10242 10242 aProgress->SetNextOperation(BstrFmt(tr("Skipping medium '%s'"), 10243 10243 pMedium->getBase()->getName().c_str()).raw(), 10244 10244 aWeight); // weight 10245 10245 } … … 10287 10287 AssertComRCThrowRC(rc); 10288 10288 } 10289 rc = lockedMediaMap->Get(pAtt, pMediumLockList); 10290 AssertComRCThrowRC(rc); 10289 10291 10290 10292 /* release the locks before the potentially lengthy operation */ … … 10335 10337 catch (HRESULT aRC) { rc = aRC; } 10336 10338 10339 10337 10340 /* unlock all hard disks we locked */ 10338 10341 if (!aOnline) … … 10344 10347 } 10345 10348 10349 10346 10350 if (FAILED(rc)) 10347 10351 { … … 10349 10353 10350 10354 alock.release(); 10351 mrc = deleteImplicitDiffs(); 10352 } 10355 mrc = deleteImplicitDiffs(aOnline); 10356 } 10357 10358 if (aOnline) 10359 mData->mSession.mLockedMedia = *lockedMediaMap; 10360 else 10361 lockedMediaOffline = *lockedMediaMap; 10353 10362 10354 10363 return rc; … … 10364 10373 * @note Locks this object for writing. 10365 10374 */ 10366 HRESULT Machine::deleteImplicitDiffs() 10367 { 10375 // Tod - deal withh offline atts ..... 10376 HRESULT Machine::deleteImplicitDiffs(bool aOnline) 10377 { 10378 LogFlowThisFunc(("aOnline=%d\n", aOnline)); 10379 10368 10380 AutoCaller autoCaller(this); 10369 10381 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 10370 10382 10371 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 10372 LogFlowThisFuncEnter(); 10373 10383 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 10384 AutoMultiWriteLock2 alock2(this->lockHandle(), 10385 &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 10386 10387 /* Don't want backed up state. */ 10374 10388 AssertReturn(mMediaData.isBackedUp(), E_FAIL); 10375 10389 10376 10390 HRESULT rc = S_OK; 10391 MachineState_T oldState = mData->mMachineState; 10377 10392 10378 10393 MediaData::AttachmentList implicitAtts; 10379 10380 10394 const MediaData::AttachmentList &oldAtts = mMediaData.backedUpData()->mAttachments; 10381 10395 10382 /* enumerate new attachments */ 10383 for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin(); 10384 it != mMediaData->mAttachments.end(); 10385 ++it) 10386 { 10387 ComObjPtr<Medium> hd = (*it)->getMedium(); 10388 if (hd.isNull()) 10389 continue; 10390 10391 if ((*it)->isImplicit()) 10392 { 10393 /* deassociate and mark for deletion */ 10394 LogFlowThisFunc(("Detaching '%s', pending deletion\n", (*it)->getLogName())); 10395 rc = hd->removeBackReference(mData->mUuid); 10396 AssertComRC(rc); 10397 implicitAtts.push_back(*it); 10398 continue; 10399 } 10400 10401 /* was this hard disk attached before? */ 10402 if (!findAttachment(oldAtts, hd)) 10403 { 10404 /* no: de-associate */ 10405 LogFlowThisFunc(("Detaching '%s', no deletion\n", (*it)->getLogName())); 10406 rc = hd->removeBackReference(mData->mUuid); 10407 AssertComRC(rc); 10408 continue; 10409 } 10410 LogFlowThisFunc(("Not detaching '%s'\n", (*it)->getLogName())); 10411 } 10412 10413 /* rollback hard disk changes */ 10414 mMediaData.rollback(); 10415 10416 MultiResult mrc(S_OK); 10417 10418 /* delete unused implicit diffs */ 10419 if (implicitAtts.size() != 0) 10420 { 10421 /* will release the lock before the potentially lengthy 10422 * operation, so protect with the special state (unless already 10423 * protected) */ 10424 MachineState_T oldState = mData->mMachineState; 10425 if ( oldState != MachineState_Saving 10426 && oldState != MachineState_LiveSnapshotting 10427 && oldState != MachineState_RestoringSnapshot 10428 && oldState != MachineState_DeletingSnapshot 10429 && oldState != MachineState_DeletingSnapshotOnline 10430 && oldState != MachineState_DeletingSnapshotPaused 10431 ) 10432 setMachineState(MachineState_SettingUp); 10433 10434 alock.release(); 10435 10436 for (MediaData::AttachmentList::const_iterator it = implicitAtts.begin(); 10437 it != implicitAtts.end(); 10396 // Locked Media Map. 10397 MediumLockListMap lockedMediaOffline; 10398 MediumLockListMap *lockedMediaMap; 10399 if (aOnline) 10400 lockedMediaMap = &mData->mSession.mLockedMedia; 10401 else 10402 lockedMediaMap = &lockedMediaOffline; 10403 10404 try 10405 { 10406 // create Medium lock lists for offline atts as per createImplicitAtts. 10407 if (!aOnline) 10408 { 10409 /* lock all attached hard disks early to detect "in use" 10410 * situations before deleting actual diffs */ 10411 for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin(); 10412 it != mMediaData->mAttachments.end(); 10413 ++it) 10414 { 10415 MediumAttachment* pAtt = *it; 10416 if (pAtt->getType() == DeviceType_HardDisk) 10417 { 10418 Medium* pMedium = pAtt->getMedium(); 10419 Assert(pMedium); 10420 10421 MediumLockList *pMediumLockList(new MediumLockList()); 10422 alock.release(); 10423 rc = pMedium->createMediumLockList(true /* fFailIfInaccessible */, 10424 false /* fMediumLockWrite */, 10425 NULL, 10426 *pMediumLockList); 10427 alock.acquire(); 10428 10429 if (FAILED(rc)) 10430 { 10431 delete pMediumLockList; 10432 throw rc; 10433 } 10434 10435 rc = lockedMediaMap->Insert(pAtt, pMediumLockList); 10436 if (FAILED(rc)) 10437 throw rc; 10438 } 10439 } 10440 10441 if (FAILED(rc)) 10442 throw(rc); 10443 10444 } // end of offline 10445 10446 10447 /* Start from scratch */ 10448 10449 /* Go through remembered attachments and create diffs for normal hard 10450 * disks and attach them */ 10451 for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin(); 10452 it != mMediaData->mAttachments.end(); 10438 10453 ++it) 10439 10454 { 10440 LogFlowThisFunc(("Deleting '%s'\n", (*it)->getLogName())); 10441 ComObjPtr<Medium> hd = (*it)->getMedium(); 10442 10443 rc = hd->deleteStorage(NULL /*aProgress*/, true /*aWait*/); 10444 AssertMsg(SUCCEEDED(rc), ("rc=%Rhrc it=%s hd=%s\n", rc, (*it)->getLogName(), hd->getLocationFull().c_str() )); 10445 mrc = rc; 10446 } 10447 10448 alock.acquire(); 10449 10455 MediumAttachment* pAtt = *it; 10456 10457 // Ensure we get a hard disk. 10458 ComObjPtr<Medium> hd = pAtt->getMedium(); 10459 10460 if (hd.isNull()) 10461 continue; 10462 10463 // DeviceType_T devType = pAtt->getType(); 10464 10465 // Implicit atts go on the list of implicit atts for deletion and back reference gets removed. 10466 if (pAtt->isImplicit()) 10467 { 10468 /* Deassociate and mark for deletion */ 10469 LogFlowThisFunc(("Detaching '%s', pending deletion\n", pAtt->getLogName())); 10470 rc = hd->removeBackReference(mData->mUuid); 10471 if (FAILED(rc)) 10472 throw(rc); 10473 implicitAtts.push_back(pAtt); 10474 continue; 10475 } 10476 10477 /* Was this hard disk attached before? */ 10478 if (!findAttachment(oldAtts, hd)) 10479 { 10480 /* no: de-associate */ 10481 LogFlowThisFunc(("Detaching '%s', no deletion\n", pAtt->getLogName())); 10482 rc = hd->removeBackReference(mData->mUuid); 10483 if (FAILED(rc)) 10484 throw setError(rc); 10485 continue; 10486 } 10487 LogFlowThisFunc(("Not detaching '%s'\n", pAtt->getLogName())); 10488 } 10489 10490 /* rollback hard disk changes */ 10491 mMediaData.rollback(); 10492 10493 MultiResult mrc(S_OK); 10494 10495 // Delete unused implicit diffs. 10496 if(implicitAtts.size() != 0) 10497 { 10498 if ( oldState != MachineState_Saving 10499 && oldState != MachineState_LiveSnapshotting 10500 && oldState != MachineState_RestoringSnapshot 10501 && oldState != MachineState_DeletingSnapshot 10502 && oldState != MachineState_DeletingSnapshotOnline 10503 && oldState != MachineState_DeletingSnapshotPaused 10504 ) 10505 setMachineState(MachineState_SettingUp); 10506 10507 alock.release(); 10508 10509 // Loop round implicitatts 10510 // a) Remove medum lock list. 10511 // b) Delete HD storage from media list. 10512 // c) Remove medium lock list. 10513 MediaData::AttachmentList::const_iterator ittodelete; 10514 for (MediaData::AttachmentList::const_iterator it = implicitAtts.begin(); 10515 it != implicitAtts.end(); 10516 ++it) 10517 { 10518 // Remove attachment. 10519 MediumAttachment* pAtt = *it; 10520 Assert(pAtt); 10521 LogFlowThisFunc(("Deleting '%s'\n", (pAtt)->getLogName())); 10522 ComObjPtr<Medium> hd = pAtt->getMedium(); 10523 Assert(hd); 10524 mMediaData->mAttachments.remove(pAtt); 10525 rc = lockedMediaMap->Unlock(); 10526 10527 if (FAILED(rc)) 10528 throw(rc); 10529 10530 // Remove from locked media map. 10531 MediumLockList *pMediumLockList; 10532 rc = lockedMediaMap->Get(pAtt, pMediumLockList); 10533 10534 if (FAILED(rc)) 10535 throw(rc); 10536 rc = lockedMediaMap->Remove(pAtt); 10537 if (FAILED(rc)) 10538 throw(rc); 10539 rc = lockedMediaMap->Lock(); 10540 alock2.release(); 10541 rc = hd->deleteStorage(NULL /*aProgress*/, true /*aWait*/); 10542 10543 if (FAILED(rc)) 10544 throw(rc); 10545 AssertMsg(SUCCEEDED(rc), ("rc=%Rhrc it=%s hd=%s\n", rc, pAtt->getLogName(), hd->getLocationFull().c_str() )); 10546 10547 // Only way to delete lock list entry is 10548 // by iterator so find the iterator with this lock list entry. 10549 // Remove from Media Lock List. 10550 MediumLockList::Base::iterator lockListBegin = pMediumLockList->GetBegin(); 10551 MediumLockList::Base::iterator lockListEnd = pMediumLockList->GetEnd(); 10552 for (MediumLockList::Base::iterator it2 = lockListBegin; it2 != lockListEnd; ++it2 ) 10553 { 10554 MediumLock &mediumLock = *it2; 10555 const ComObjPtr<Medium> pMedium = mediumLock.GetMedium(); 10556 10557 if (pMedium == hd) 10558 { 10559 rc = pMediumLockList->RemoveByIterator(it2); 10560 if (FAILED(rc)) 10561 throw(rc); 10562 break; 10563 } 10564 } 10565 } 10566 } 10450 10567 if (mData->mMachineState == MachineState_SettingUp) 10451 10568 setMachineState(oldState); 10452 10569 } 10453 10570 10454 return mrc; 10455 } 10571 catch (HRESULT aRC) {rc = aRC;} 10572 10573 // Unlock all hard disks that we locked if offline). 10574 if (!aOnline) 10575 { 10576 ErrorInfoKeeper eik; 10577 rc = lockedMediaMap->Clear(); 10578 if (FAILED(rc)) 10579 throw (rc); 10580 } 10581 10582 10583 if (aOnline) 10584 mData->mSession.mLockedMedia = *lockedMediaMap; 10585 else 10586 lockedMediaOffline = *lockedMediaMap; 10587 10588 return rc; 10589 } 10590 10456 10591 10457 10592 /** … … 10884 11019 AssertComRCReturnVoid (autoCaller.rc()); 10885 11020 10886 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 10887 10888 LogFlowThisFunc(("Entering\n")); 11021 // AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 11022 LogFlowThisFunc(("Entering rollbackmedia\n")); 10889 11023 10890 11024 HRESULT rc = S_OK; … … 10928 11062 /** @todo convert all this Machine-based voodoo to MediumAttachment 10929 11063 * based rollback logic. */ 10930 deleteImplicitDiffs( );11064 deleteImplicitDiffs(true); 10931 11065 10932 11066 return;
Note:
See TracChangeset
for help on using the changeset viewer.