Changeset 43915 in vbox for trunk/src/VBox/Main/src-server/MachineImpl.cpp
- Timestamp:
- Nov 19, 2012 7:07:10 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 82197
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r43908 r43915 1703 1703 1704 1704 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1705 if (strFile.isEmpty())1705 if (strFile.isEmpty()) 1706 1706 strFile = "VideoCap.webm"; 1707 1707 mHWData->mVideoCaptureFile = strFile; … … 8018 8018 } 8019 8019 8020 /* Deassociate hard disks(only when a real Machine or a SnapshotMachine8020 /* Deassociate media (only when a real Machine or a SnapshotMachine 8021 8021 * instance is uninitialized; SessionMachine instances refer to real 8022 * Machine hard disks). This is necessary for a clean re-initialization of8022 * Machine media). This is necessary for a clean re-initialization of 8023 8023 * the VM after successfully re-checking the accessibility state. Note 8024 8024 * that in case of normal Machine or SnapshotMachine uninitialization (as 8025 * a result of unregistering or deleting the snapshot), outdated hard8026 * diskattachments will already be uninitialized and deleted, so this8025 * a result of unregistering or deleting the snapshot), outdated media 8026 * attachments will already be uninitialized and deleted, so this 8027 8027 * code will not affect them. */ 8028 8028 if ( !!mMediaData … … 8034 8034 ++it) 8035 8035 { 8036 ComObjPtr<Medium> hd= (*it)->getMedium();8037 if ( hd.isNull())8036 ComObjPtr<Medium> pMedium = (*it)->getMedium(); 8037 if (pMedium.isNull()) 8038 8038 continue; 8039 HRESULT rc = hd->removeBackReference(mData->mUuid, getSnapshotId());8039 HRESULT rc = pMedium->removeBackReference(mData->mUuid, getSnapshotId()); 8040 8040 AssertComRC(rc); 8041 8041 } … … 10130 10130 * on failure. This is a responsibility of the caller. 10131 10131 * 10132 * @note Locks this object for writing.10132 * @note Locks this object and the media tree for writing. 10133 10133 */ 10134 10134 HRESULT Machine::createImplicitDiffs(IProgress *aProgress, … … 10153 10153 HRESULT rc = S_OK; 10154 10154 10155 // use appropriate locked media map (online or offline) 10155 10156 MediumLockListMap lockedMediaOffline; 10156 10157 MediumLockListMap *lockedMediaMap; … … 10242 10243 else 10243 10244 aProgress->SetNextOperation(BstrFmt(tr("Skipping medium '%s'"), 10244 pMedium->getBase()->getName().c_str()).raw(),10245 pMedium->getBase()->getName().c_str()).raw(), 10245 10246 aWeight); // weight 10246 10247 } … … 10284 10285 { 10285 10286 alock.release(); 10287 /* The currently attached medium will be read-only, change 10288 * the lock type to read. */ 10286 10289 rc = pMediumLockList->Update(pMedium, false); 10287 10290 alock.acquire(); 10288 10291 AssertComRCThrowRC(rc); 10289 10292 } 10290 rc = lockedMediaMap->Get(pAtt, pMediumLockList);10291 AssertComRCThrowRC(rc);10292 10293 10293 10294 /* release the locks before the potentially lengthy operation */ … … 10338 10339 catch (HRESULT aRC) { rc = aRC; } 10339 10340 10340 10341 /* unlock all hard disks we locked */ 10341 /* unlock all hard disks we locked when there is no VM */ 10342 10342 if (!aOnline) 10343 10343 { … … 10347 10347 AssertComRC(rc1); 10348 10348 } 10349 10350 10351 if (FAILED(rc))10352 {10353 MultiResult mrc = rc;10354 10355 alock.release();10356 mrc = deleteImplicitDiffs(aOnline);10357 }10358 10359 if (aOnline)10360 mData->mSession.mLockedMedia = *lockedMediaMap;10361 else10362 lockedMediaOffline = *lockedMediaMap;10363 10349 10364 10350 return rc; … … 10372 10358 * called from #fixupMedia() when the changes are rolled back. 10373 10359 * 10374 * @note Locks this object for writing.10360 * @note Locks this object and the media tree for writing. 10375 10361 */ 10376 // Tod - deal withh offline atts ..... 10377 HRESULT Machine::deleteImplicitDiffs(bool aOnline) 10362 HRESULT Machine::deleteImplicitDiffs(bool aOnline) 10378 10363 { 10379 10364 LogFlowThisFunc(("aOnline=%d\n", aOnline)); … … 10382 10367 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 10383 10368 10384 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 10385 AutoMultiWriteLock2 alock2(this->lockHandle(), 10369 AutoMultiWriteLock2 alock(this->lockHandle(), 10386 10370 &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 10387 10371 10388 /* Don't wantbacked up state. */10372 /* We absolutely must have backed up state. */ 10389 10373 AssertReturn(mMediaData.isBackedUp(), E_FAIL); 10390 10374 … … 10392 10376 MachineState_T oldState = mData->mMachineState; 10393 10377 10394 MediaData::AttachmentList implicitAtts; 10395 const MediaData::AttachmentList &oldAtts = mMediaData.backedUpData()->mAttachments; 10396 10397 // Locked Media Map. 10378 /* will release the lock before the potentially lengthy operation, 10379 * so protect with the special state (unless already protected) */ 10380 if ( oldState != MachineState_Saving 10381 && oldState != MachineState_LiveSnapshotting 10382 && oldState != MachineState_RestoringSnapshot 10383 && oldState != MachineState_DeletingSnapshot 10384 && oldState != MachineState_DeletingSnapshotOnline 10385 && oldState != MachineState_DeletingSnapshotPaused 10386 ) 10387 setMachineState(MachineState_SettingUp); 10388 10389 // use appropriate locked media map (online or offline) 10398 10390 MediumLockListMap lockedMediaOffline; 10399 10391 MediumLockListMap *lockedMediaMap; … … 10405 10397 try 10406 10398 { 10407 // create Medium lock lists for offline atts as per createImplicitAtts.10408 10399 if (!aOnline) 10409 10400 { … … 10441 10432 10442 10433 if (FAILED(rc)) 10443 throw(rc); 10444 10434 throw rc; 10445 10435 } // end of offline 10446 10436 10447 10448 /* Start from scratch */ 10449 10450 /* Go through remembered attachments and create diffs for normal hard 10451 * disks and attach them */ 10437 /* Lock lists are now up to date and include implicitly created media */ 10438 10439 /* Go through remembered attachments and delete all implicitly created 10440 * diffs and fix up the attachment information */ 10441 const MediaData::AttachmentList &oldAtts = mMediaData.backedUpData()->mAttachments; 10442 MediaData::AttachmentList implicitAtts; 10452 10443 for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin(); 10453 10444 it != mMediaData->mAttachments.end(); 10454 10445 ++it) 10455 10446 { 10456 MediumAttachment* pAtt = *it; 10457 10458 // Ensure we get a hard disk. 10459 ComObjPtr<Medium> hd = pAtt->getMedium(); 10460 10461 if (hd.isNull()) 10447 ComObjPtr<MediumAttachment> pAtt = *it; 10448 ComObjPtr<Medium> pMedium = pAtt->getMedium(); 10449 if (pMedium.isNull()) 10462 10450 continue; 10463 10451 10464 // DeviceType_T devType = pAtt->getType(); 10465 10466 // Implicit atts go on the list of implicit atts for deletion and back reference gets removed. 10452 // Implicit attachments go on the list for deletion and back references are removed. 10467 10453 if (pAtt->isImplicit()) 10468 10454 { 10469 10455 /* Deassociate and mark for deletion */ 10470 10456 LogFlowThisFunc(("Detaching '%s', pending deletion\n", pAtt->getLogName())); 10471 rc = hd->removeBackReference(mData->mUuid);10457 rc = pMedium->removeBackReference(mData->mUuid); 10472 10458 if (FAILED(rc)) 10473 throw (rc);10459 throw rc; 10474 10460 implicitAtts.push_back(pAtt); 10475 10461 continue; 10476 10462 } 10477 10463 10478 /* Was this hard diskattached before? */10479 if (!findAttachment(oldAtts, hd))10464 /* Was this medium attached before? */ 10465 if (!findAttachment(oldAtts, pMedium)) 10480 10466 { 10481 10467 /* no: de-associate */ 10482 10468 LogFlowThisFunc(("Detaching '%s', no deletion\n", pAtt->getLogName())); 10483 rc = hd->removeBackReference(mData->mUuid);10469 rc = pMedium->removeBackReference(mData->mUuid); 10484 10470 if (FAILED(rc)) 10485 throw setError(rc);10471 throw rc; 10486 10472 continue; 10487 10473 } … … 10489 10475 } 10490 10476 10477 /* If there are implicit attachments to delete, throw away the lock 10478 * map contents (which will unlock all media) since the medium 10479 * attachments will be rolled back. Below we need to completely 10480 * recreate the lock map anyway since it is infinitely complex to 10481 * do this incrementally (would need reconstructing each attachment 10482 * change, which would be extremely hairy). */ 10483 if (implicitAtts.size() != 0) 10484 { 10485 ErrorInfoKeeper eik; 10486 10487 HRESULT rc1 = lockedMediaMap->Clear(); 10488 AssertComRC(rc1); 10489 } 10490 10491 10491 /* rollback hard disk changes */ 10492 10492 mMediaData.rollback(); … … 10495 10495 10496 10496 // Delete unused implicit diffs. 10497 if(implicitAtts.size() != 0) 10498 { 10499 if ( oldState != MachineState_Saving 10500 && oldState != MachineState_LiveSnapshotting 10501 && oldState != MachineState_RestoringSnapshot 10502 && oldState != MachineState_DeletingSnapshot 10503 && oldState != MachineState_DeletingSnapshotOnline 10504 && oldState != MachineState_DeletingSnapshotPaused 10505 ) 10506 setMachineState(MachineState_SettingUp); 10507 10497 if (implicitAtts.size() != 0) 10498 { 10508 10499 alock.release(); 10509 10500 10510 // Loop round implicitatts10511 // a) Remove medum lock list.10512 // b) Delete HD storage from media list.10513 // c) Remove medium lock list.10514 MediaData::AttachmentList::const_iterator ittodelete;10515 10501 for (MediaData::AttachmentList::const_iterator it = implicitAtts.begin(); 10516 10502 it != implicitAtts.end(); 10517 10503 ++it) 10518 10504 { 10519 // Remove attachment.10520 MediumAttachment*pAtt = *it;10505 // Remove medium associated with this attachment. 10506 ComObjPtr<MediumAttachment> pAtt = *it; 10521 10507 Assert(pAtt); 10522 LogFlowThisFunc(("Deleting '%s'\n", (pAtt)->getLogName())); 10523 ComObjPtr<Medium> hd = pAtt->getMedium(); 10524 Assert(hd); 10525 mMediaData->mAttachments.remove(pAtt); 10526 rc = lockedMediaMap->Unlock(); 10527 10528 if (FAILED(rc)) 10529 throw(rc); 10530 10531 // Remove from locked media map. 10532 MediumLockList *pMediumLockList; 10533 rc = lockedMediaMap->Get(pAtt, pMediumLockList); 10534 10535 if (FAILED(rc)) 10536 throw(rc); 10537 rc = lockedMediaMap->Remove(pAtt); 10538 if (FAILED(rc)) 10539 throw(rc); 10540 rc = lockedMediaMap->Lock(); 10541 alock2.release(); 10542 rc = hd->deleteStorage(NULL /*aProgress*/, true /*aWait*/); 10543 10544 if (FAILED(rc)) 10545 throw(rc); 10546 AssertMsg(SUCCEEDED(rc), ("rc=%Rhrc it=%s hd=%s\n", rc, pAtt->getLogName(), hd->getLocationFull().c_str() )); 10547 10548 // Only way to delete lock list entry is 10549 // by iterator so find the iterator with this lock list entry. 10550 // Remove from Media Lock List. 10551 MediumLockList::Base::iterator lockListBegin = pMediumLockList->GetBegin(); 10552 MediumLockList::Base::iterator lockListEnd = pMediumLockList->GetEnd(); 10553 for (MediumLockList::Base::iterator it2 = lockListBegin; it2 != lockListEnd; ++it2 ) 10508 LogFlowThisFunc(("Deleting '%s'\n", pAtt->getLogName())); 10509 ComObjPtr<Medium> pMedium = pAtt->getMedium(); 10510 Assert(pMedium); 10511 10512 rc = pMedium->deleteStorage(NULL /*aProgress*/, true /*aWait*/); 10513 // continue on delete failure, just collect error messages 10514 AssertMsg(SUCCEEDED(rc), ("rc=%Rhrc it=%s hd=%s\n", rc, pAtt->getLogName(), pMedium->getLocationFull().c_str() )); 10515 mrc = rc; 10516 } 10517 10518 alock.acquire(); 10519 10520 /* if there is a VM recreate media lock map as mentioned above, 10521 * otherwise it is a waste of time and we leave things unlocked */ 10522 if (aOnline) 10523 { 10524 const ComObjPtr<SessionMachine> pMachine = mData->mSession.mMachine; 10525 /* must never be NULL, but better safe than sorry */ 10526 if (!pMachine.isNull()) 10554 10527 { 10555 MediumLock &mediumLock = *it2; 10556 const ComObjPtr<Medium> pMedium = mediumLock.GetMedium(); 10557 10558 if (pMedium == hd) 10559 { 10560 rc = pMediumLockList->RemoveByIterator(it2); 10561 if (FAILED(rc)) 10562 throw(rc); 10563 break; 10564 } 10528 alock.release(); 10529 rc = mData->mSession.mMachine->lockMedia(); 10530 alock.acquire(); 10531 if (FAILED(rc)) 10532 throw rc; 10565 10533 } 10566 10534 } 10567 10535 } 10568 if (mData->mMachineState == MachineState_SettingUp) 10569 setMachineState(oldState); 10570 } 10571 10536 } 10572 10537 catch (HRESULT aRC) {rc = aRC;} 10573 10538 10574 // Unlock all hard disks that we locked if offline). 10539 if (mData->mMachineState == MachineState_SettingUp) 10540 setMachineState(oldState); 10541 10542 /* unlock all hard disks we locked when there is no VM */ 10575 10543 if (!aOnline) 10576 10544 { 10577 10545 ErrorInfoKeeper eik; 10578 rc = lockedMediaMap->Clear(); 10579 if (FAILED(rc)) 10580 throw (rc); 10581 } 10582 10583 10584 if (aOnline) 10585 mData->mSession.mLockedMedia = *lockedMediaMap; 10586 else 10587 lockedMediaOffline = *lockedMediaMap; 10546 10547 HRESULT rc1 = lockedMediaMap->Clear(); 10548 AssertComRC(rc1); 10549 } 10588 10550 10589 10551 return rc; … … 11018 10980 { 11019 10981 AutoCaller autoCaller(this); 11020 AssertComRCReturnVoid 10982 AssertComRCReturnVoid(autoCaller.rc()); 11021 10983 11022 10984 // AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 11023 LogFlowThisFunc(("Entering rollback media\n"));10985 LogFlowThisFunc(("Entering rollbackMedia\n")); 11024 10986 11025 10987 HRESULT rc = S_OK; … … 11063 11025 /** @todo convert all this Machine-based voodoo to MediumAttachment 11064 11026 * based rollback logic. */ 11065 deleteImplicitDiffs( true);11027 deleteImplicitDiffs(Global::IsOnline(mData->mMachineState)); 11066 11028 11067 11029 return; … … 12888 12850 } 12889 12851 12852 STDMETHODIMP SessionMachine::LockMedia() 12853 { 12854 AutoCaller autoCaller(this); 12855 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 12856 12857 AutoMultiWriteLock2 alock(this->lockHandle(), 12858 &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 12859 12860 AssertReturn( mData->mMachineState == MachineState_Starting 12861 || mData->mMachineState == MachineState_Restoring 12862 || mData->mMachineState == MachineState_TeleportingIn, E_FAIL); 12863 12864 clearError(); 12865 alock.release(); 12866 return lockMedia(); 12867 } 12868 12869 STDMETHODIMP SessionMachine::UnlockMedia() 12870 { 12871 unlockMedia(); 12872 return S_OK; 12873 } 12874 12890 12875 STDMETHODIMP SessionMachine::EjectMedium(IMediumAttachment *aAttachment, 12891 12876 IMediumAttachment **aNewAttachment) … … 13207 13192 13208 13193 AutoCaller autoCaller(this); 13209 AssertComRCReturn 13194 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 13210 13195 13211 13196 ComPtr<IInternalSessionControl> directControl; … … 13227 13212 13228 13213 AutoCaller autoCaller(this); 13229 AssertComRCReturn 13214 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 13230 13215 13231 13216 ComPtr<IInternalSessionControl> directControl; … … 13365 13350 13366 13351 AutoCaller autoCaller(this); 13367 AssertComRCReturn 13352 AssertComRCReturn(autoCaller.rc(), autoCaller.rc()); 13368 13353 13369 13354 ComPtr<IInternalSessionControl> directControl; … … 13611 13596 * succeeded individual locks will be undone). 13612 13597 * 13613 * This method is intended to be called when the machine is in Starting or 13614 * Restoring state and asserts otherwise. 13598 * The caller is responsible for doing the necessary state sanity checks. 13615 13599 * 13616 13600 * The locks made by this method must be undone by calling #unlockMedia() when … … 13625 13609 &mParent->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 13626 13610 13627 AssertReturn( mData->mMachineState == MachineState_Starting13628 || mData->mMachineState == MachineState_Restoring13629 || mData->mMachineState == MachineState_TeleportingIn, E_FAIL);13630 13611 /* bail out if trying to lock things with already set up locking */ 13631 13612 AssertReturn(mData->mSession.mLockedMedia.IsEmpty(), E_FAIL); 13632 13613 13633 clearError();13634 13614 MultiResult mrc(S_OK); 13635 13615
Note:
See TracChangeset
for help on using the changeset viewer.