VirtualBox

Changeset 30940 in vbox for trunk/src


Ignore:
Timestamp:
Jul 20, 2010 6:07:30 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63812
Message:

Main: fix medium detachment quirks during machine register

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MachineImpl.cpp

    r30939 r30940  
    32153215                        aDevice, aControllerPort, aControllerName);
    32163216
    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);
    32583218
    32593219    if (fNeedsSaveSettings)
     
    60215981                        mUserData->mName.raw(), snapshotCount);
    60225982
    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
    60546012            return setError(VBOX_E_INVALID_OBJECT_STATE,
    60556013                            tr("Cannot unregister the machine '%ls' because it has %d media attachments"),
    60566014                               mMediaData->mAttachments.size());
     6015    }
     6016
     6017    // commit all the media changes made above
     6018    commitMedia();
    60576019
    60586020    mData->mRegistered = false;
     
    85488510{
    85498511   for (MediaData::AttachmentList::const_iterator it = ll.begin();
    8550          it != ll.end();
    8551          ++it)
     8512        it != ll.end();
     8513        ++it)
    85528514    {
    85538515        MediumAttachment *pAttach = *it;
     
    85748536{
    85758537   for (MediaData::AttachmentList::const_iterator it = ll.begin();
    8576          it != ll.end();
    8577          ++it)
     8538        it != ll.end();
     8539        ++it)
    85788540    {
    85798541        MediumAttachment *pAttach = *it;
     
    86148576
    86158577/**
     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 */
     8587HRESULT 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/**
    86168637 * Perform deferred hard disk detachments.
    86178638 *
     
    86478668    /* enumerate new attachments */
    86488669    for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin();
    8649             it != mMediaData->mAttachments.end();
    8650             ++it)
     8670         it != mMediaData->mAttachments.end();
     8671         ++it)
    86518672    {
    86528673        MediumAttachment *pAttach = *it;
     
    86698690
    86708691            if (    aOnline
    8671                     && pMedium
    8672                     && pAttach->getType() == DeviceType_HardDisk
    8673                 )
     8692                 && pMedium
     8693                 && pAttach->getType() == DeviceType_HardDisk
     8694               )
    86748695            {
    86758696                ComObjPtr<Medium> parent = pMedium->getParent();
     
    87038724            /* was this medium attached before? */
    87048725            for (MediaData::AttachmentList::iterator oldIt = oldAtts.begin();
    8705                     oldIt != oldAtts.end();
    8706                     ++oldIt)
     8726                 oldIt != oldAtts.end();
     8727                 ++oldIt)
    87078728            {
    87088729                MediumAttachment *pOldAttach = *oldIt;
  • trunk/src/VBox/Main/include/MachineImpl.h

    r30929 r30940  
    775775                                     Guid &id);
    776776
     777    HRESULT detachDevice(MediumAttachment *pAttach,
     778                         AutoWriteLock &writeLock,
     779                         bool *pfNeedsSaveSettings);
     780
    777781    void commitMedia(bool aOnline = false);
    778782    void rollbackMedia();
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette