Changeset 35903 in vbox
- Timestamp:
- Feb 8, 2011 4:46:25 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r35893 r35903 5230 5230 <method name="unregister"> 5231 5231 <desc> 5232 Unregisters the machine, which must have been previously registered using5233 <link to="IVirtualBox::registerMachine"/> ,and optionally do additional5232 Unregisters a machine previously registered with 5233 <link to="IVirtualBox::registerMachine"/> and optionally do additional 5234 5234 cleanup before the machine is unregistered. 5235 5235 … … 5246 5246 <li>With "UnregisterOnly", the machine will only be unregistered, but no additional 5247 5247 cleanup will be performed. The call will fail if the machine is in "Saved" state 5248 or has any snapshots or any media attached (see <link to="IMediumAttachment" /> .5248 or has any snapshots or any media attached (see <link to="IMediumAttachment" />). 5249 5249 It is the responsibility of the caller to delete all such configuration in this mode. 5250 5250 In this mode, the API behaves like the former @c IVirtualBox::unregisterMachine() API … … 5252 5252 <li>With "DetachAllReturnNone", the call will succeed even if the machine is in "Saved" 5253 5253 state or if it has snapshots or media attached. All media attached to the current machine 5254 state or in snapshots will be detached. No medium objects will be returned; all of the 5255 machine's media will remain open.</li> 5254 state or in snapshots will be detached. For machines created with VirtualBox 4.0 or 5255 later, media which are registered in this machine's media registry which are still 5256 attached to another machine besides this machine will be moved a another machine's 5257 registry. No medium objects will be returned; all of the machine's media will remain open.</li> 5256 5258 <li>With "DetachAllReturnHardDisksOnly", the call will behave like with "DetachAllReturnNone", 5257 5259 except that all the hard disk medium objects which were detached from the machine will -
trunk/src/VBox/Main/include/MediumImpl.h
r35836 r35903 176 176 177 177 bool addRegistry(const Guid& id); 178 bool removeRegistry(const Guid& id); 178 179 bool isInRegistry(const Guid& id); 179 180 bool getFirstRegistryMachineId(Guid &uuid) const; -
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r35638 r35903 275 275 HRESULT saveSettings(); 276 276 277 void addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving, Guiduuid);277 void addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving, const Guid &uuid); 278 278 HRESULT saveRegistries(const GuidList &llRegistriesThatNeedSaving); 279 279 -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r35885 r35903 4316 4316 mUserData->s.strName.c_str(), cSnapshots); 4317 4317 4318 // this list collects the medium objects from all medium attachments 4319 // which got detached from the machine and its snapshots, in the following 4320 // order: 4321 // 1) media from machine attachments (these have the "leaf" attachments with snapshots 4322 // and must be closed first, or closing the parents will fail because they will 4323 // children); 4318 // This list collects the medium objects from all medium attachments 4319 // which we will detach from the machine and its snapshots, in a specific 4320 // order which allows for closing all media without getting "media in use" 4321 // errors, simply by going through the list from the front to the back: 4322 // 1) first media from machine attachments (these have the "leaf" attachments with snapshots 4323 // and must be closed before the parent media from the snapshots, or closing the parents 4324 // will fail because they still have children); 4324 4325 // 2) media from the youngest snapshots followed by those from the parent snapshots until 4325 // the root ("first") snapshot of the machine 4326 // This order allows for closing the media on this list from the beginning to the end 4327 // without getting "media in use" errors. 4326 // the root ("first") snapshot of the machine. 4328 4327 MediaList llMedia; 4329 4328 … … 7749 7748 if (!medium.isNull()) 7750 7749 { 7750 AutoCaller medCaller(medium); 7751 if (FAILED(medCaller.rc())) return medCaller.rc(); 7752 AutoWriteLock mlock(medium COMMA_LOCKVAL_SRC_POS); 7753 7751 7754 if (isSnapshotMachine()) 7752 7755 rc = medium->addBackReference(mData->mUuid, *puuidSnapshot); … … 8777 8780 uuid = mParent->getGlobalRegistryId(); // VirtualBox global registry UUID 8778 8781 8782 AutoCaller autoCaller(pMedium); 8783 if (FAILED(autoCaller.rc())) return; 8784 AutoWriteLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 8785 8779 8786 if (pMedium->addRegistry(uuid)) 8780 8787 // registry actually changed: … … 9034 9041 * called from #fixupMedia() when the changes are rolled back. 9035 9042 * 9036 * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true 9037 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. 9043 * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs to receive the registry IDs that need saving 9038 9044 * 9039 9045 * @note Locks this object for writing. … … 9220 9226 * @param writeLock Machine write lock which the caller must have locked once. This may be released temporarily in here. 9221 9227 * @param pSnapshot If NULL, then the detachment is for the current machine. Otherwise this is for a SnapshotMachine, and this must be its snapshot. 9222 * @param pfNeedsSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true 9223 * by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed. 9228 * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs to receive the registry IDs that need saving 9224 9229 * @return 9225 9230 */ … … 9251 9256 writeLock.release(); 9252 9257 9253 HRESULT rc = oldmedium->deleteStorage(NULL /*aProgress*/, true /*aWait*/, 9258 HRESULT rc = oldmedium->deleteStorage(NULL /*aProgress*/, 9259 true /*aWait*/, 9254 9260 pllRegistriesThatNeedSaving); 9255 9261 … … 9283 9289 9284 9290 /** 9285 * Goes thru all medium attachments of the list and calls detachDevice() on each 9286 * of them and attaches all Medium objects found in the process to the given list, 9287 * depending on cleanupMode. 9291 * Goes thru all media of the given list and 9292 * 9293 * 1) calls detachDevice() on each of them for this machine and 9294 * 2) adds all Medium objects found in the process to the given list, 9295 * depending on cleanupMode. 9296 * 9297 * If cleanupMode is CleanupMode_DetachAllReturnHardDisksOnly, this only 9298 * adds hard disks to the list. If it is CleanupMode_Full, this adds all 9299 * media to the list. 9288 9300 * 9289 9301 * This gets called from Machine::Unregister, both for the actual Machine and 9290 9302 * the SnapshotMachine objects that might be found in the snapshots. 9291 9303 * 9292 * Requires caller and locking. 9304 * Requires caller and locking. The machine lock must be passed in because it 9305 * will be passed on to detachDevice which needs it for temporary unlocking. 9293 9306 * 9294 9307 * @param writeLock Machine lock from top-level caller; this gets passed to detachDevice. … … 9316 9329 ++it) 9317 9330 { 9318 ComObjPtr<MediumAttachment> pAttach = *it;9331 ComObjPtr<MediumAttachment> &pAttach = *it; 9319 9332 ComObjPtr<Medium> pMedium = pAttach->getMedium(); 9320 9333 -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r35836 r35903 1626 1626 1627 1627 // we access mParent and members 1628 AutoMultiWriteLock2 mlock(&m->pVirtualBox->getMediaTreeLockHandle(), this->lockHandle() COMMA_LOCKVAL_SRC_POS); 1628 AutoMultiWriteLock2 mlock(&m->pVirtualBox->getMediaTreeLockHandle(), 1629 this->lockHandle() COMMA_LOCKVAL_SRC_POS); 1629 1630 1630 1631 switch (m->state) … … 3076 3077 * See getFirstRegistryMachineId() for details. 3077 3078 * 3079 * Must have caller + locking! 3080 * 3078 3081 * @param id 3079 3082 * @return true if the registry was added; false if the given id was already on the list. … … 3081 3084 bool Medium::addRegistry(const Guid& id) 3082 3085 { 3083 AutoCaller autoCaller(this); 3084 if (FAILED(autoCaller.rc())) return false; 3085 3086 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3087 3086 // hard disks cannot be in more than one registry 3088 3087 if ( m->devType == DeviceType_HardDisk 3089 3088 && m->llRegistryIDs.size() > 0 … … 3105 3104 3106 3105 /** 3106 * Removes the given UUID from the list of media registry UUIDs. Returns true 3107 * if found or false if not. 3108 * 3109 * Must have caller + locking! 3110 * 3111 * @param id 3112 * @return 3113 */ 3114 bool Medium::removeRegistry(const Guid& id) 3115 { 3116 for (GuidList::iterator it = m->llRegistryIDs.begin(); 3117 it != m->llRegistryIDs.end(); 3118 ++it) 3119 { 3120 if ((*it) == id) 3121 { 3122 m->llRegistryIDs.erase(it); 3123 return true; 3124 } 3125 } 3126 3127 return false; 3128 } 3129 3130 /** 3107 3131 * Returns true if id is in the list of media registries for this medium. 3132 * 3133 * Must have caller + locking! 3134 * 3108 3135 * @param id 3109 3136 * @return -
trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
r35638 r35903 812 812 * cannot be closed if they have children. 813 813 * 814 * This calls uninit() on itself, so the snapshots tree becomes invalid after this.814 * This calls uninit() on itself, so the snapshots tree (beginning with a machine's pFirstSnapshot) becomes invalid after this. 815 815 * It does not alter the main machine's snapshot pointers (pFirstSnapshot, pCurrentSnapshot). 816 816 * … … 898 898 899 899 uninit(); 900 900 901 901 BaseFinalRelease(); 902 902 } -
trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
r35812 r35903 345 345 346 346 HRESULT rc = init(); 347 347 348 348 BaseFinalConstruct(); 349 349 … … 3192 3192 } 3193 3193 3194 struct { 3195 MediaOList &llSource; 3196 settings::MediaList &llTarget; 3197 } s[] = 3198 { 3199 // hard disks 3200 { m->allHardDisks, mediaRegistry.llHardDisks }, 3201 // CD/DVD images 3202 { m->allDVDImages, mediaRegistry.llDvdImages }, 3203 // floppy images 3204 { m->allFloppyImages, mediaRegistry.llFloppyImages } 3205 }; 3206 3194 3207 HRESULT rc; 3195 // hard disks 3196 mediaRegistry.llHardDisks.clear(); 3197 for (MediaList::const_iterator it = m->allHardDisks.begin(); 3198 it != m->allHardDisks.end(); 3199 ++it) 3200 { 3201 Medium *pMedium = *it; 3202 if (pMedium->isInRegistry(uuidRegistry)) 3203 { 3204 settings::Medium med; 3205 rc = pMedium->saveSettings(med, strMachineFolder); // this recurses into its children 3206 if (FAILED(rc)) throw rc; 3207 mediaRegistry.llHardDisks.push_back(med); 3208 } 3209 } 3210 3211 // CD/DVD images 3212 mediaRegistry.llDvdImages.clear(); 3213 for (MediaList::const_iterator it = m->allDVDImages.begin(); 3214 it != m->allDVDImages.end(); 3215 ++it) 3216 { 3217 Medium *pMedium = *it; 3218 if (pMedium->isInRegistry(uuidRegistry)) 3219 { 3220 settings::Medium med; 3221 rc = pMedium->saveSettings(med, strMachineFolder); 3222 if (FAILED(rc)) throw rc; 3223 mediaRegistry.llDvdImages.push_back(med); 3224 } 3225 } 3226 3227 // floppy images 3228 mediaRegistry.llFloppyImages.clear(); 3229 for (MediaList::const_iterator it = m->allFloppyImages.begin(); 3230 it != m->allFloppyImages.end(); 3231 ++it) 3232 { 3233 Medium *pMedium = *it; 3234 if (pMedium->isInRegistry(uuidRegistry)) 3235 { 3236 settings::Medium med; 3237 rc = pMedium->saveSettings(med, strMachineFolder); 3238 if (FAILED(rc)) throw rc; 3239 mediaRegistry.llFloppyImages.push_back(med); 3208 3209 for (size_t i = 0; i < RT_ELEMENTS(s); ++i) 3210 { 3211 MediaOList &llSource = s[i].llSource; 3212 settings::MediaList &llTarget = s[i].llTarget; 3213 llTarget.clear(); 3214 for (MediaList::const_iterator it = llSource.begin(); 3215 it != llSource.end(); 3216 ++it) 3217 { 3218 Medium *pMedium = *it; 3219 AutoCaller autoCaller(pMedium); 3220 if (FAILED(autoCaller.rc())) throw autoCaller.rc(); 3221 AutoReadLock mlock(pMedium COMMA_LOCKVAL_SRC_POS); 3222 3223 if (pMedium->isInRegistry(uuidRegistry)) 3224 { 3225 settings::Medium med; 3226 rc = pMedium->saveSettings(med, strMachineFolder); // this recurses into child hard disks 3227 if (FAILED(rc)) throw rc; 3228 llTarget.push_back(med); 3229 } 3240 3230 } 3241 3231 } … … 3664 3654 3665 3655 { 3666 AutoWriteLock mlock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 3656 AutoWriteLock tlock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 3657 3667 3658 for (MediaOList::iterator it = m->allHardDisks.getList().begin(); 3668 3659 it != m->allHardDisks.getList().end(); … … 3670 3661 { 3671 3662 ComObjPtr<Medium> pMedium = *it; 3663 AutoCaller medCaller(pMedium); 3664 if (FAILED(medCaller.rc())) return medCaller.rc(); 3665 AutoReadLock medlock(pMedium COMMA_LOCKVAL_SRC_POS); 3672 3666 3673 3667 if (pMedium->isInRegistry(uuidMachine)) … … 3702 3696 const Guid &id) 3703 3697 { 3698 // remove from the collection of registered machines 3704 3699 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3705 3706 // remove from the collection of registered machines3707 3700 m->allMachines.removeChild(pMachine); 3708 3709 3701 // save the global registry 3710 3702 HRESULT rc = saveSettings(); 3711 3712 3703 alock.release(); 3704 3705 /* 3706 * Now go over all known media and checks if they were registered in the 3707 * media registry of the given machine. Each such medium is then moved to 3708 * a different media registry to make sure it doesn't get lost since its 3709 * media registry is about to go away. 3710 * 3711 * This fixes the following use case: Image A.vdi of machine A is also used 3712 * by machine B, but registered in the media registry of machine A. If machine 3713 * A is deleted, A.vdi must be moved to the registry of B, or else B will 3714 * become inaccessible. 3715 */ 3716 GuidList llRegistriesThatNeedSaving; 3717 { 3718 AutoWriteLock tlock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 3719 for (MediaOList::iterator it = m->allHardDisks.getList().begin(); 3720 it != m->allHardDisks.getList().end(); 3721 ++it) 3722 { 3723 ComObjPtr<Medium> &pMedium = *it; 3724 AutoCaller medCaller(pMedium); 3725 if (FAILED(medCaller.rc())) return medCaller.rc(); 3726 AutoWriteLock mlock(pMedium COMMA_LOCKVAL_SRC_POS); 3727 3728 if (pMedium->removeRegistry(id)) 3729 { 3730 // ID was found in medium's registry list: 3731 // add a new one then 3732 const Guid *puuidBetter = pMedium->getFirstMachineBackrefId(); 3733 if (puuidBetter) 3734 { 3735 pMedium->addRegistry(*puuidBetter); 3736 addGuidToListUniquely(llRegistriesThatNeedSaving, *puuidBetter); 3737 } 3738 } 3739 } 3740 } 3741 3742 saveRegistries(llRegistriesThatNeedSaving); 3713 3743 3714 3744 /* fire an event */ … … 3727 3757 */ 3728 3758 void VirtualBox::addGuidToListUniquely(GuidList &llRegistriesThatNeedSaving, 3729 Guiduuid)3759 const Guid &uuid) 3730 3760 { 3731 3761 for (GuidList::const_iterator it = llRegistriesThatNeedSaving.begin(); … … 4392 4422 4393 4423 AssertReturn(pvUser, VERR_INVALID_POINTER); 4394 4424 4395 4425 com::Initialize(); 4396 4426
Note:
See TracChangeset
for help on using the changeset viewer.