VirtualBox

Changeset 23441 in vbox for trunk/src


Ignore:
Timestamp:
Sep 30, 2009 12:52:22 PM (15 years ago)
Author:
vboxsync
Message:

Main/MachineImpl: fix subtly broken snapshot creation (attachments without medium were omitted, resulting in a broken VM config after saving state, and triggering consistency check assertions when reverting to current snapshot), and also fix ISO image locking when starting a VM

File:
1 edited

Legend:

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

    r23395 r23441  
    20792079    {
    20802080        return setError(VBOX_E_OBJECT_IN_USE,
    2081                         tr("Hard disk '%ls' is already attached to this virtual machine"),
     2081                        tr("Medium '%ls' is already attached to this virtual machine"),
    20822082                        medium->locationFull().raw());
    20832083    }
     
    23082308    if (associate && !medium.isNull())
    23092309    {
    2310         /* as the last step, associate the hard disk to the VM */
     2310        /* as the last step, associate the medium to the VM */
    23112311        rc = medium->attachTo(mData->mUuid);
    23122312        /* here we can fail because of Deleting, or being in process of
     
    54765476        }
    54775477
    5478         /* backup mHDData to let registeredInit() properly rollback on failure
     5478        /* backup mMediaData to let registeredInit() properly rollback on failure
    54795479         * (= limited accessibility) */
    54805480
     
    63296329 * Used when taking a snapshot or when discarding the current state.
    63306330 *
    6331  * This method assumes that mHDData contains the original hard disk attachments
     6331 * This method assumes that mMediaData contains the original hard disk attachments
    63326332 * it needs to create diffs for. On success, these attachments will be replaced
    63336333 * with the created diffs. On failure, #deleteImplicitDiffs() is implicitly
    6334  * called to delete created diffs which will also rollback mHDData and restore
     6334 * called to delete created diffs which will also rollback mMediaData and restore
    63356335 * whatever was backed up before calling this method.
    63366336 *
     
    63696369
    63706370    /* must be in a protective state because we leave the lock below */
    6371     AssertReturn(mData->mMachineState == MachineState_Saving ||
    6372                   mData->mMachineState == MachineState_Discarding, E_FAIL);
     6371    AssertReturn(   mData->mMachineState == MachineState_Saving
     6372                 || mData->mMachineState == MachineState_Discarding, E_FAIL);
    63736373
    63746374    HRESULT rc = S_OK;
     
    64006400
    64016401        /* remember the current list (note that we don't use backup() since
    6402          * mHDData may be already backed up) */
     6402         * mMediaData may be already backed up) */
    64036403        MediaData::AttachmentList atts = mMediaData->mAttachments;
    64046404
     
    64136413        {
    64146414            MediumAttachment* pAtt = *it;
    6415             if (pAtt->type() != DeviceType_HardDisk)
    6416                 continue;
    6417 
    6418             Medium* pHD = pAtt->medium();
    6419             Assert(pHD);
    6420             /* type cannot be changed while attached => no need to lock */
    6421             if (pHD->type() != MediumType_Normal)
     6415
     6416            DeviceType_T devType = pAtt->type();
     6417            Medium* medium = pAtt->medium();
     6418
     6419            if (   devType != DeviceType_HardDisk
     6420                || medium == NULL
     6421                || medium->type() != MediumType_Normal)
    64226422            {
    64236423                /* copy the attachment as is */
    6424                 Assert(pHD->type() == MediumType_Writethrough);
    6425                 aProgress->SetNextOperation(BstrFmt(tr("Skipping medium '%s'"),
    6426                                                     pHD->base()->name().raw()),
    6427                                             aWeight);        // weight
     6424
     6425                /** @todo the progress object created in Console::TakeSnaphot
     6426                 * only expects operations for hard disks. Later other
     6427                 * device types need to show up in the progress as well. */
     6428                if (devType == DeviceType_HardDisk)
     6429                {
     6430                    if (medium == NULL)
     6431                        aProgress->SetNextOperation(Bstr(tr("Skipping attachment without medium")),
     6432                                                    aWeight);        // weight
     6433                    else
     6434                        aProgress->SetNextOperation(BstrFmt(tr("Skipping medium '%s'"),
     6435                                                            medium->base()->name().raw()),
     6436                                                    aWeight);        // weight
     6437                }
    64286438
    64296439                mMediaData->mAttachments.push_back(pAtt);
     
    64336443            /* need a diff */
    64346444            aProgress->SetNextOperation(BstrFmt(tr("Creating differencing hard disk for '%s'"),
    6435                                                 pHD->base()->name().raw()),
     6445                                                medium->base()->name().raw()),
    64366446                                        aWeight);        // weight
    64376447
     
    64396449            diff.createObject();
    64406450            rc = diff->init(mParent,
    6441                             pHD->preferredDiffFormat().raw(),
     6451                            medium->preferredDiffFormat().raw(),
    64426452                            BstrFmt("%ls"RTPATH_SLASH_STR,
    64436453                                    mUserData->mSnapshotFolderFull.raw()).raw());
     
    64476457            alock.leave();
    64486458
    6449             rc = pHD->createDiffStorageAndWait(diff,
    6450                                                MediumVariant_Standard,
    6451                                                NULL);
     6459            rc = medium->createDiffStorageAndWait(diff,
     6460                                                  MediumVariant_Standard,
     6461                                                  NULL);
    64526462
    64536463            // at this point, the old image is still locked for writing, but instead
     
    64586468                diff->LockWrite(NULL);
    64596469                mData->mSession.mLockedMedia.push_back(Data::Session::LockedMedia::value_type(ComPtr<IMedium>(diff), true));
    6460                 pHD->UnlockWrite(NULL);
    6461                 pHD->LockRead(NULL);
    6462                 mData->mSession.mLockedMedia.push_back(Data::Session::LockedMedia::value_type(ComPtr<IMedium>(pHD), false));
     6470                medium->UnlockWrite(NULL);
     6471                medium->LockRead(NULL);
     6472                mData->mSession.mLockedMedia.push_back(Data::Session::LockedMedia::value_type(ComPtr<IMedium>(medium), false));
    64636473            }
    64646474
     
    65136523/**
    65146524 * Deletes implicit differencing hard disks created either by
    6515  * #createImplicitDiffs() or by #AttachMedium() and rolls back mHDData.
     6525 * #createImplicitDiffs() or by #AttachMedium() and rolls back mMediaData.
    65166526 *
    65176527 * Note that to delete hard disks created by #AttachMedium() this method is
     
    66886698 * created diffs on failure.
    66896699 *
    6690  * Does nothing if the hard disk attachment data (mHDData) is not changed (not
     6700 * Does nothing if the hard disk attachment data (mMediaData) is not changed (not
    66916701 * backed up).
    66926702 *
    6693  * When the data is backed up, this method will commit mHDData if @a aCommit is
     6703 * When the data is backed up, this method will commit mMediaData if @a aCommit is
    66946704 * @c true and rollback it otherwise before returning.
    66956705 *
     
    72577267        mPeer->mUserData.attach (mUserData);
    72587268        mPeer->mHWData.attach (mHWData);
    7259         /* mHDData is reshared by fixupMedia */
    7260         // mPeer->mHDData.attach (mHDData);
     7269        /* mMediaData is reshared by fixupMedia */
     7270        // mPeer->mMediaData.attach(mMediaData);
    72617271        Assert(mPeer->mMediaData.data() == mMediaData.data());
    72627272    }
     
    93409350    {
    93419351        /* delete all differencing hard disks created (this will also attach
    9342          * their parents back by rolling back mHDData) */
     9352         * their parents back by rolling back mMediaData) */
    93439353        fixupMedia(false /* aCommit */);
    93449354
     
    1003710047        HRESULT rc = S_OK;
    1003810048
    10039         /* lock hard disks */
     10049        /* lock all medium objects attached to the VM */
    1004010050        for (MediaData::AttachmentList::const_iterator it = mMediaData->mAttachments.begin();
    1004110051             it != mMediaData->mAttachments.end();
    1004210052             ++it)
    1004310053        {
     10054            DeviceType_T devType = (*it)->type();
    1004410055            ComObjPtr<Medium> hd = (*it)->medium();
    1004510056
     
    1005210063                if (first)
    1005310064                {
    10054                     rc = hd->LockWrite (&mediaState);
    10055                     CheckComRCThrowRC(rc);
     10065                    if (devType != DeviceType_DVD)
     10066                    {
     10067                        /* HardDisk and Floppy medium must be locked for writing */
     10068                        rc = hd->LockWrite(&mediaState);
     10069                        CheckComRCThrowRC(rc);
     10070                    }
     10071                    else
     10072                    {
     10073                        /* DVD medium must be locked for reading */
     10074                        rc = hd->LockRead(&mediaState);
     10075                        CheckComRCThrowRC(rc);
     10076                    }
    1005610077
    1005710078                    mData->mSession.mLockedMedia.push_back (
Note: See TracChangeset for help on using the changeset viewer.

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