Changeset 31228 in vbox
- Timestamp:
- Jul 29, 2010 7:44:50 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MachineImpl.cpp
r31225 r31228 3589 3589 aDevice, aControllerPort, aControllerName); 3590 3590 3591 rc = detachDevice(pAttach, alock, &fNeedsSaveSettings);3591 rc = detachDevice(pAttach, alock, NULL /* pSnapshot */, &fNeedsSaveSettings); 3592 3592 3593 3593 if (fNeedsSaveSettings) … … 4080 4080 // this list collects the files that should be reported 4081 4081 // as to be deleted to the caller in aFiles 4082 std::list< Bstr> llFilesForCaller;4082 std::list<Utf8Str> llFilesForCaller; 4083 4083 4084 4084 // discard saved state … … 4087 4087 // add the saved state file to the list of files the caller should delete 4088 4088 Assert(!mSSData->mStateFilePath.isEmpty()); 4089 llFilesForCaller.push_back( Bstr(mSSData->mStateFilePath));4089 llFilesForCaller.push_back(mSSData->mStateFilePath); 4090 4090 4091 4091 mSSData->mStateFilePath.setNull(); … … 4096 4096 } 4097 4097 4098 // @todo optionally nuke snapshots4099 4098 size_t snapshotCount = 0; 4100 4099 if (mData->mFirstSnapshot) 4101 4100 snapshotCount = mData->mFirstSnapshot->getAllChildrenCount() + 1; 4102 4101 if (snapshotCount) 4103 return setError(VBOX_E_INVALID_OBJECT_STATE, 4104 tr("Cannot unregister the machine '%ls' because it has %d snapshots"), 4105 mUserData->mName.raw(), snapshotCount); 4102 { 4103 if (fAutoCleanup) 4104 { 4105 // caller wants automatic detachment: then do that and report all media to the array 4106 4107 // Snapshot::beginDeletingSnapshot() needs the machine state to be this 4108 MachineState_T oldState = mData->mMachineState; 4109 mData->mMachineState = MachineState_DeletingSnapshot; 4110 4111 // make a copy of the first snapshot so the refcount does not drop to 0 4112 // in beginDeletingSnapshot, which sets pFirstSnapshot to 0 (that hangs 4113 // because of the AutoCaller voodoo) 4114 ComObjPtr<Snapshot> pFirstSnapshot = mData->mFirstSnapshot; 4115 4116 // go! 4117 pFirstSnapshot->uninitRecursively(alock, llMedia, llFilesForCaller); 4118 4119 mData->mMachineState = oldState; 4120 } 4121 else 4122 return setError(VBOX_E_INVALID_OBJECT_STATE, 4123 tr("Cannot unregister the machine '%ls' because it has %d snapshots"), 4124 mUserData->mName.raw(), snapshotCount); 4125 } 4106 4126 4107 4127 if ( !mMediaData.isNull() // can be NULL if machine is inaccessible … … 4109 4129 ) 4110 4130 { 4111 // we have media attachments: 4131 // we have media attachments: detach them all and add the Medium objects to our list 4112 4132 if (fAutoCleanup) 4113 { 4114 // caller wants automatic detachment: then do that and report all media to the array 4115 4116 // make a temporary list because detachDevice invalidates iterators into 4117 // mMediaData->mAttachments 4118 MediaData::AttachmentList llAttachments2 = mMediaData->mAttachments; 4119 4120 for (MediaData::AttachmentList::iterator it = llAttachments2.begin(); 4121 it != llAttachments2.end(); 4122 ++it) 4123 { 4124 ComObjPtr<MediumAttachment> pAttach = *it; 4125 ComObjPtr<Medium> pMedium = pAttach->getMedium(); 4126 4127 if (!pMedium.isNull()) 4128 llMedia.push_back(pMedium); 4129 4130 rc = detachDevice(pAttach, 4131 alock, 4132 NULL /* pfNeedsSaveSettings */); 4133 if (FAILED(rc)) 4134 break; 4135 }; 4136 } 4133 detachAllMedia(alock, NULL /* pSnapshot */, llMedia); 4137 4134 else 4138 4135 return setError(VBOX_E_INVALID_OBJECT_STATE, … … 4163 4160 { 4164 4161 ComObjPtr<Medium> pMedium = *it; 4165 Bstr bstrFile = pMedium->getLocationFull();4162 Utf8Str strFile = pMedium->getLocationFull(); 4166 4163 4167 4164 AutoCaller autoCaller2(pMedium); … … 4172 4169 autoCaller2); 4173 4170 // this uninitializes the medium 4171 4172 LogFlowThisFunc(("Medium::close() on %s yielded rc (%Rhra)\n", strFile.c_str(), rc)); 4174 4173 4175 4174 if (rc == VBOX_E_OBJECT_IN_USE) … … 4180 4179 else if (SUCCEEDED(rc)) 4181 4180 // report the path to the caller 4182 llFilesForCaller.push_back( bstrFile);4181 llFilesForCaller.push_back(strFile); 4183 4182 } 4184 4183 } … … 4187 4186 SafeArray<BSTR> sfaFiles(llFilesForCaller.size()); 4188 4187 size_t i = 0; 4189 for (std::list< Bstr>::iterator it = llFilesForCaller.begin();4188 for (std::list<Utf8Str>::iterator it = llFilesForCaller.begin(); 4190 4189 it != llFilesForCaller.end(); 4191 4190 ++it) 4192 it->detachTo(&sfaFiles[i++]);4191 Bstr(*it).detachTo(&sfaFiles[i++]); 4193 4192 sfaFiles.detachTo(ComSafeArrayOutArg(aFiles)); 4194 4193 … … 8710 8709 * @param pAttach Medium attachment to detach. 8711 8710 * @param writeLock Machine write lock which the caller must have locked once. This may be released temporarily in here. 8711 * @param pSnapshot If NULL, then the detachment is for the current machine. Otherwise this is for a SnapshotMachine, and this must be its snapshot. 8712 8712 * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true 8713 8713 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. … … 8716 8716 HRESULT Machine::detachDevice(MediumAttachment *pAttach, 8717 8717 AutoWriteLock &writeLock, 8718 Snapshot *pSnapshot, 8718 8719 bool *pfNeedsSaveSettings) 8719 8720 { … … 8751 8752 mMediaData.backup(); 8752 8753 8753 / *we cannot use erase (it) below because backup() above will create8754 *a copy of the list and make this copy active, but the iterator8755 * still refers to the original and is not valid for the copy */8754 // we cannot use erase (it) below because backup() above will create 8755 // a copy of the list and make this copy active, but the iterator 8756 // still refers to the original and is not valid for the copy 8756 8757 mMediaData->mAttachments.remove(pAttach); 8757 8758 8758 /* For non-hard disk media, detach straight away. */ 8759 if (mediumType != DeviceType_HardDisk && !oldmedium.isNull()) 8760 oldmedium->detachFrom(mData->mUuid); 8759 if (!oldmedium.isNull()) 8760 { 8761 // if this is from a snapshot, do not defer detachment to commitMedia() 8762 if (pSnapshot) 8763 oldmedium->detachFrom(mData->mUuid, pSnapshot->getId()); 8764 // else if non-hard disk media, do not defer detachment to commitMedia() either 8765 else if (mediumType != DeviceType_HardDisk) 8766 oldmedium->detachFrom(mData->mUuid); 8767 } 8768 8769 return S_OK; 8770 } 8771 8772 /** 8773 * Goes thru all medium attachments of the list and calls detachDevice() on each 8774 * of them and attaches all Medium objects found in the process to the given list. 8775 * 8776 * This gets called from Machine::Unregister, both for the actual Machine and 8777 * the SnapshotMachine objects that might be found in the snapshots. 8778 * 8779 * Requires caller and locking. 8780 * 8781 * @param writeLock Machine lock from top-level caller; this gets passed to detachDevice. 8782 * @param llMedia Caller's list to receive Medium objects which got detached so caller can close() them. 8783 * @param pSnapshot Must be NULL when called for a "real" Machine or a snapshot object if called for a SnapshotMachine. 8784 * @return 8785 */ 8786 HRESULT Machine::detachAllMedia(AutoWriteLock &writeLock, 8787 Snapshot *pSnapshot, 8788 MediaList &llMedia) 8789 { 8790 Assert(isWriteLockOnCurrentThread()); 8791 8792 HRESULT rc; 8793 8794 // make a temporary list because detachDevice invalidates iterators into 8795 // mMediaData->mAttachments 8796 MediaData::AttachmentList llAttachments2 = mMediaData->mAttachments; 8797 8798 for (MediaData::AttachmentList::iterator it = llAttachments2.begin(); 8799 it != llAttachments2.end(); 8800 ++it) 8801 { 8802 ComObjPtr<MediumAttachment> pAttach = *it; 8803 ComObjPtr<Medium> pMedium = pAttach->getMedium(); 8804 8805 if (!pMedium.isNull()) 8806 llMedia.push_back(pMedium); 8807 8808 // real machine: then we need to use the proper method 8809 rc = detachDevice(pAttach, 8810 writeLock, 8811 pSnapshot, 8812 NULL /* pfNeedsSaveSettings */); 8813 8814 if (FAILED(rc)) 8815 return rc; 8816 } 8761 8817 8762 8818 return S_OK; -
trunk/src/VBox/Main/SnapshotImpl.cpp
r31224 r31228 251 251 252 252 /* we've changed the base of the current state so mark it as 253 253 * modified as it no longer guaranteed to be its copy */ 254 254 m->pMachine->mData->mCurrentStateModified = TRUE; 255 255 } … … 809 809 810 810 return saveSnapshotImpl(data, aAttrsOnly); 811 } 812 813 /** 814 * Part of the cleanup engine of Machine::Unregister(). 815 * 816 * This recursively removes all medium attachments from the snapshot's machine 817 * and returns the snapshot's saved state file name, if any, and then calls 818 * uninit() on "this" itself. 819 * 820 * This recurses into children first, so the given MediaList receives child 821 * media first before their parents. If the caller wants to close all media, 822 * they should go thru the list from the beginning to the end because media 823 * cannot be closed if they have children. 824 * 825 * This calls uninit() on itself, so the snapshots tree becomes invalid after this. 826 * It does not alter the main machine's snapshot pointers (pFirstSnapshot, pCurrentSnapshot). 827 * 828 * Caller must hold the machine write lock (which protects the snapshots tree!) 829 * 830 * @param llFilenames 831 * @return 832 */ 833 HRESULT Snapshot::uninitRecursively(AutoWriteLock &writeLock, 834 MediaList &llMedia, 835 std::list<Utf8Str> &llFilenames) 836 { 837 Assert(m->pMachine->isWriteLockOnCurrentThread()); 838 839 HRESULT rc = S_OK; 840 841 // recurse into children first so that the child media appear on 842 // the list first; this way caller can close the media from the 843 // beginning to the end because parent media can't be closed if 844 // they have children 845 846 // make a copy of the children list since uninit() modifies it 847 SnapshotsList llChildrenCopy(m->llChildren); 848 for (SnapshotsList::iterator it = llChildrenCopy.begin(); 849 it != llChildrenCopy.end(); 850 ++it) 851 { 852 Snapshot *pChild = *it; 853 rc = pChild->uninitRecursively(writeLock, llMedia, llFilenames); 854 if (FAILED(rc)) 855 return rc; 856 } 857 858 // now call detachAllMedia on the snapshot machine 859 rc = m->pMachine->detachAllMedia(writeLock, 860 this /* pSnapshot */, 861 llMedia); 862 if (FAILED(rc)) 863 return rc; 864 865 // now report the saved state file 866 if (!m->pMachine->mSSData->mStateFilePath.isEmpty()) 867 llFilenames.push_back(m->pMachine->mSSData->mStateFilePath); 868 869 this->beginSnapshotDelete(); 870 this->uninit(); 871 872 return S_OK; 811 873 } 812 874 -
trunk/src/VBox/Main/include/MachineImpl.h
r31218 r31228 778 778 HRESULT detachDevice(MediumAttachment *pAttach, 779 779 AutoWriteLock &writeLock, 780 Snapshot *pSnapshot, 780 781 bool *pfNeedsSaveSettings); 782 HRESULT detachAllMedia(AutoWriteLock &writeLock, 783 Snapshot *pSnapshot, 784 MediaList &llMedia); 781 785 782 786 void commitMedia(bool aOnline = false); -
trunk/src/VBox/Main/include/SnapshotImpl.h
r30764 r31228 33 33 34 34 class ATL_NO_VTABLE Snapshot : 35 public VirtualBoxBase, // WithTypedChildren<Snapshot>,35 public VirtualBoxBase, 36 36 VBOX_SCRIPTABLE_IMPL(ISnapshot) 37 37 { … … 124 124 HRESULT saveSnapshotImpl(settings::Snapshot &data, bool aAttrsOnly); 125 125 126 HRESULT uninitRecursively(AutoWriteLock &writeLock, 127 MediaList &llMedia, 128 std::list<Utf8Str> &llFilenames); 129 126 130 private: 127 131 struct Data; // opaque, defined in SnapshotImpl.cpp
Note:
See TracChangeset
for help on using the changeset viewer.