- Timestamp:
- Jul 20, 2010 6:07:30 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 63812
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MachineImpl.cpp
r30939 r30940 3215 3215 aDevice, aControllerPort, aControllerName); 3216 3216 3217 ComObjPtr<Medium> oldmedium = pAttach->getMedium(); 3218 DeviceType_T mediumType = pAttach->getType(); 3219 3220 if (pAttach->isImplicit()) 3221 { 3222 /* attempt to implicitly delete the implicitly created diff */ 3223 3224 /// @todo move the implicit flag from MediumAttachment to Medium 3225 /// and forbid any hard disk operation when it is implicit. Or maybe 3226 /// a special media state for it to make it even more simple. 3227 3228 Assert(mMediaData.isBackedUp()); 3229 3230 /* will leave the lock before the potentially lengthy operation, so 3231 * protect with the special state */ 3232 MachineState_T oldState = mData->mMachineState; 3233 setMachineState(MachineState_SettingUp); 3234 3235 alock.leave(); 3236 3237 rc = oldmedium->deleteStorage(NULL /*aProgress*/, true /*aWait*/, 3238 &fNeedsSaveSettings); 3239 3240 alock.enter(); 3241 3242 setMachineState(oldState); 3243 3244 if (FAILED(rc)) return rc; 3245 } 3246 3247 setModified(IsModified_Storage); 3248 mMediaData.backup(); 3249 3250 /* we cannot use erase (it) below because backup() above will create 3251 * a copy of the list and make this copy active, but the iterator 3252 * still refers to the original and is not valid for the copy */ 3253 mMediaData->mAttachments.remove(pAttach); 3254 3255 /* For non-hard disk media, detach straight away. */ 3256 if (mediumType != DeviceType_HardDisk && !oldmedium.isNull()) 3257 oldmedium->detachFrom(mData->mUuid); 3217 rc = detachDevice(pAttach, alock, &fNeedsSaveSettings); 3258 3218 3259 3219 if (fNeedsSaveSettings) … … 6021 5981 mUserData->mName.raw(), snapshotCount); 6022 5982 6023 if (fCloseMedia) 6024 { 6025 // call backup before iterating over the media, because backup WILL change 6026 // the pointers and invalidate iterators (grrrrr) 6027 setModified(IsModified_Storage); 6028 mMediaData.backup(); // do not call this or iterators will be invalidated 6029 6030 // caller wants automatic detachment: then do that and report all media to the array 6031 MediaData::AttachmentList::iterator it = mMediaData->mAttachments.begin(); 6032 while (it != mMediaData->mAttachments.end()) 6033 { 6034 ComObjPtr<MediumAttachment> pAttach = *it; 6035 ComObjPtr<Medium> pMedium = pAttach->getMedium(); 6036 6037 if (!pMedium.isNull()) 6038 llMedia.push_back(pMedium); 6039 6040 // for non-hard disk media, detach straight away 6041 // (same logic as in DetachDevice()) 6042 if (!pMedium.isNull()) 6043 pMedium->detachFrom(mData->mUuid); 6044 6045 // remove this attachment; erase() returns the iterator behind the thing that got deleted 6046 it = mMediaData->mAttachments.erase(it); 6047 }; 6048 } 6049 else 6050 // caller wants no automatic detachment: then fail if there are any 6051 if ( !mMediaData.isNull() // can be NULL if machine is inaccessible 6052 && mMediaData->mAttachments.size() 6053 ) 5983 if ( !mMediaData.isNull() // can be NULL if machine is inaccessible 5984 && mMediaData->mAttachments.size() 5985 ) 5986 { 5987 // we have media attachments: 5988 if (fCloseMedia) 5989 { 5990 // caller wants automatic detachment: then do that and report all media to the array 5991 5992 // make a temporary list because detachDevice invalidates iterators into 5993 // mMediaData->mAttachments 5994 MediaData::AttachmentList llAttachments2 = mMediaData->mAttachments; 5995 5996 for (MediaData::AttachmentList::iterator it = llAttachments2.begin(); 5997 it != llAttachments2.end(); 5998 ++it) 5999 { 6000 ComObjPtr<MediumAttachment> pAttach = *it; 6001 ComObjPtr<Medium> pMedium = pAttach->getMedium(); 6002 6003 if (!pMedium.isNull()) 6004 llMedia.push_back(pMedium); 6005 6006 detachDevice(pAttach, 6007 alock, 6008 NULL /* pfNeedsSaveSettings */); 6009 }; 6010 } 6011 else 6054 6012 return setError(VBOX_E_INVALID_OBJECT_STATE, 6055 6013 tr("Cannot unregister the machine '%ls' because it has %d media attachments"), 6056 6014 mMediaData->mAttachments.size()); 6015 } 6016 6017 // commit all the media changes made above 6018 commitMedia(); 6057 6019 6058 6020 mData->mRegistered = false; … … 8548 8510 { 8549 8511 for (MediaData::AttachmentList::const_iterator it = ll.begin(); 8550 8551 8512 it != ll.end(); 8513 ++it) 8552 8514 { 8553 8515 MediumAttachment *pAttach = *it; … … 8574 8536 { 8575 8537 for (MediaData::AttachmentList::const_iterator it = ll.begin(); 8576 8577 8538 it != ll.end(); 8539 ++it) 8578 8540 { 8579 8541 MediumAttachment *pAttach = *it; … … 8614 8576 8615 8577 /** 8578 * Main implementation for Machine::DetachDevice. This also gets called 8579 * from Machine::prepareUnregister() so it has been taken out for simplicity. 8580 * 8581 * @param pAttach Medium attachment to detach. 8582 * @param writeLock Machine write lock which the caller must have locked once. This may be released temporarily in here. 8583 * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true 8584 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. 8585 * @return 8586 */ 8587 HRESULT Machine::detachDevice(MediumAttachment *pAttach, 8588 AutoWriteLock &writeLock, 8589 bool *pfNeedsSaveSettings) 8590 { 8591 ComObjPtr<Medium> oldmedium = pAttach->getMedium(); 8592 DeviceType_T mediumType = pAttach->getType(); 8593 8594 if (pAttach->isImplicit()) 8595 { 8596 /* attempt to implicitly delete the implicitly created diff */ 8597 8598 /// @todo move the implicit flag from MediumAttachment to Medium 8599 /// and forbid any hard disk operation when it is implicit. Or maybe 8600 /// a special media state for it to make it even more simple. 8601 8602 Assert(mMediaData.isBackedUp()); 8603 8604 /* will leave the lock before the potentially lengthy operation, so 8605 * protect with the special state */ 8606 MachineState_T oldState = mData->mMachineState; 8607 setMachineState(MachineState_SettingUp); 8608 8609 writeLock.release(); 8610 8611 HRESULT rc = oldmedium->deleteStorage(NULL /*aProgress*/, true /*aWait*/, 8612 pfNeedsSaveSettings); 8613 8614 writeLock.acquire(); 8615 8616 setMachineState(oldState); 8617 8618 if (FAILED(rc)) return rc; 8619 } 8620 8621 setModified(IsModified_Storage); 8622 mMediaData.backup(); 8623 8624 /* we cannot use erase (it) below because backup() above will create 8625 * a copy of the list and make this copy active, but the iterator 8626 * still refers to the original and is not valid for the copy */ 8627 mMediaData->mAttachments.remove(pAttach); 8628 8629 /* For non-hard disk media, detach straight away. */ 8630 if (mediumType != DeviceType_HardDisk && !oldmedium.isNull()) 8631 oldmedium->detachFrom(mData->mUuid); 8632 8633 return S_OK; 8634 } 8635 8636 /** 8616 8637 * Perform deferred hard disk detachments. 8617 8638 * … … 8647 8668 /* enumerate new attachments */ 8648 8669 for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin(); 8649 8650 8670 it != mMediaData->mAttachments.end(); 8671 ++it) 8651 8672 { 8652 8673 MediumAttachment *pAttach = *it; … … 8669 8690 8670 8691 if ( aOnline 8671 8672 8673 8692 && pMedium 8693 && pAttach->getType() == DeviceType_HardDisk 8694 ) 8674 8695 { 8675 8696 ComObjPtr<Medium> parent = pMedium->getParent(); … … 8703 8724 /* was this medium attached before? */ 8704 8725 for (MediaData::AttachmentList::iterator oldIt = oldAtts.begin(); 8705 8706 8726 oldIt != oldAtts.end(); 8727 ++oldIt) 8707 8728 { 8708 8729 MediumAttachment *pOldAttach = *oldIt; -
trunk/src/VBox/Main/include/MachineImpl.h
r30929 r30940 775 775 Guid &id); 776 776 777 HRESULT detachDevice(MediumAttachment *pAttach, 778 AutoWriteLock &writeLock, 779 bool *pfNeedsSaveSettings); 780 777 781 void commitMedia(bool aOnline = false); 778 782 void rollbackMedia();
Note:
See TracChangeset
for help on using the changeset viewer.