VirtualBox

Changeset 23881 in vbox


Ignore:
Timestamp:
Oct 19, 2009 6:07:38 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53661
Message:

Main: make restoreSnapshot() work on snapshots other than the current one (untested)

File:
1 edited

Legend:

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

    r23880 r23881  
    75967596    : public SessionMachine::Task
    75977597{
    7598     RestoreSnapshotTask(SessionMachine *m, Progress *p, bool discardCurSnapshot)
     7598    RestoreSnapshotTask(SessionMachine *m, ComObjPtr<Snapshot> &aSnapshot, Progress *p)
    75997599        : Task(m, p),
    7600           discardCurrentSnapshot(discardCurSnapshot)
     7600          pSnapshot(aSnapshot)
    76017601    {}
    76027602
     
    76067606    }
    76077607
    7608     const bool discardCurrentSnapshot;
     7608    ComObjPtr<Snapshot> pSnapshot;
    76097609};
    76107610
     
    87008700
    87018701    AssertReturn(aInitiator, E_INVALIDARG);
    8702     AssertReturn(aMachineState && aProgress, E_POINTER);
     8702    AssertReturn(aSnapshot && aMachineState && aProgress, E_POINTER);
    87038703
    87048704    AutoCaller autoCaller(this);
     
    87108710                 E_FAIL);
    87118711
    8712     if (mData->mCurrentSnapshot.isNull())
    8713         return setError(VBOX_E_INVALID_OBJECT_STATE,
    8714                         tr("Could not discard the current state of the machine '%ls' because it doesn't have any snapshots"),
    8715                         mUserData->mName.raw());
     8712    ComObjPtr<Snapshot> pSnapshot(static_cast<Snapshot*>(aSnapshot));
    87168713
    87178714    /* create a progress object. The number of operations is: 1 (preparing) + #
     
    87208717    progress.createObject();
    87218718    {
    8722         ULONG opCount = 1 + (ULONG)mData->mCurrentSnapshot->getSnapshotMachine()->mMediaData->mAttachments.size();
    8723         if (mData->mCurrentSnapshot->stateFilePath())
    8724             ++opCount;
    8725         progress->init (mParent, aInitiator,
    8726                         Bstr (tr ("Discarding current machine state")),
    8727                         FALSE /* aCancelable */, opCount,
    8728                         Bstr (tr ("Preparing to discard current state")));
     8719        ULONG opCount =   1     // preparing
     8720                        + (ULONG)pSnapshot->getSnapshotMachine()->mMediaData->mAttachments.size();  // one for each attachment @todo only for HDs!
     8721        if (pSnapshot->stateFilePath())
     8722            ++opCount;      // one for the saved state
     8723        progress->init(mParent, aInitiator,
     8724                       Bstr(tr("Restoring snapshot")),
     8725                       FALSE /* aCancelable */, opCount,
     8726                       Bstr(tr("Preparing to restore machine state from snapshot")));
    87298727    }
    87308728
    87318729    /* create and start the task on a separate thread (note that it will not
    87328730     * start working until we release alock) */
    8733     RestoreSnapshotTask *task = new RestoreSnapshotTask(this, progress, false /* discardCurSnapshot */);
     8731    RestoreSnapshotTask *task = new RestoreSnapshotTask(this, pSnapshot, progress);
    87348732    int vrc = RTThreadCreate(NULL,
    87358733                             taskHandler,
     
    97899787
    97909788    /* saveSettings() needs mParent lock */
    9791     AutoWriteLock vboxLock (mParent);
     9789    AutoWriteLock vboxLock(mParent);
    97929790
    97939791    /* @todo We don't need mParent lock so far so unlock() it. Better is to
     
    98099807    bool stateRestored = false;
    98109808
    9811     const bool isLastSnapshot = mData->mCurrentSnapshot->parent().isNull();
    9812 
    98139809    try
    98149810    {
     
    98179813        if (aTask.state == MachineState_Saved)
    98189814        {
    9819             Assert (!mSSData->mStateFilePath.isEmpty());
     9815            Assert(!mSSData->mStateFilePath.isEmpty());
    98209816            RTFileDelete(Utf8Str(mSSData->mStateFilePath).c_str());
    98219817            mSSData->mStateFilePath.setNull();
    9822             aTask.modifyLastState (MachineState_PoweredOff);
    9823             rc = saveStateSettings (SaveSTS_StateFilePath);
     9818            aTask.modifyLastState(MachineState_PoweredOff);
     9819            rc = saveStateSettings(SaveSTS_StateFilePath);
    98249820            CheckComRCThrowRC(rc);
    98259821        }
    98269822
    9827         if (aTask.discardCurrentSnapshot && !isLastSnapshot)
    9828         {
    9829             /* the "discard current snapshot and state" task is in action, the
    9830              * current snapshot is not the last one. Discard the current
    9831              * snapshot first */
    9832 
    9833             DeleteSnapshotTask subTask (aTask, mData->mCurrentSnapshot);
    9834             subTask.subTask = true;
    9835             discardSnapshotHandler (subTask);
    9836 
    9837             AutoCaller progressCaller (aTask.progress);
    9838             AutoReadLock progressLock (aTask.progress);
    9839             if (aTask.progress->completed())
    9840             {
    9841                 /* the progress can be completed by a subtask only if there was
    9842                  * a failure */
    9843                 rc = aTask.progress->resultCode();
    9844                 Assert (FAILED(rc));
    9845                 errorInSubtask = true;
    9846                 throw rc;
    9847             }
    9848         }
    9849 
    98509823        RTTIMESPEC snapshotTimeStamp;
    9851         RTTimeSpecSetMilli (&snapshotTimeStamp, 0);
    9852 
    9853         {
    9854             ComObjPtr<Snapshot> curSnapshot = mData->mCurrentSnapshot;
    9855             AutoReadLock snapshotLock (curSnapshot);
     9824        RTTimeSpecSetMilli(&snapshotTimeStamp, 0);
     9825
     9826        {
     9827            AutoReadLock snapshotLock(aTask.pSnapshot);
    98569828
    98579829            /* remember the timestamp of the snapshot we're restoring from */
    9858             snapshotTimeStamp = curSnapshot->getTimeStamp();
    9859 
    9860             ComPtr<SnapshotMachine> pSnapshotMachine(curSnapshot->getSnapshotMachine());
    9861 
    9862             /* copy all hardware data from the current snapshot */
     9830            snapshotTimeStamp = aTask.pSnapshot->getTimeStamp();
     9831
     9832            ComPtr<SnapshotMachine> pSnapshotMachine(aTask.pSnapshot->getSnapshotMachine());
     9833
     9834            /* copy all hardware data from the snapshot */
    98639835            copyFrom(pSnapshotMachine);
    98649836
    98659837            LogFlowThisFunc(("Restoring hard disks from the snapshot...\n"));
    98669838
    9867             /* restore the attachmends from the snapshot */
     9839            /* restore the attachments from the snapshot */
    98689840            mMediaData.backup();
    98699841            mMediaData->mAttachments = pSnapshotMachine->mMediaData->mAttachments;
     
    98899861
    98909862            /* should not have a saved state file associated at this point */
    9891             Assert (mSSData->mStateFilePath.isNull());
    9892 
    9893             if (curSnapshot->stateFilePath())
     9863            Assert(mSSData->mStateFilePath.isNull());
     9864
     9865            if (aTask.pSnapshot->stateFilePath())
    98949866            {
    9895                 Utf8Str snapStateFilePath = curSnapshot->stateFilePath();
    9896 
    9897                 Utf8Str stateFilePath = Utf8StrFmt ("%ls%c{%RTuuid}.sav",
    9898                     mUserData->mSnapshotFolderFull.raw(),
    9899                     RTPATH_DELIMITER, mData->mUuid.raw());
     9867                Utf8Str snapStateFilePath = aTask.pSnapshot->stateFilePath();
     9868
     9869                Utf8Str stateFilePath = Utf8StrFmt("%ls%c{%RTuuid}.sav",
     9870                                                   mUserData->mSnapshotFolderFull.raw(),
     9871                                                   RTPATH_DELIMITER,
     9872                                                   mData->mUuid.raw());
    99009873
    99019874                LogFlowThisFunc(("Copying saved state file from '%s' to '%s'...\n",
     
    99539926        int saveFlags = 0;
    99549927
    9955         if (aTask.discardCurrentSnapshot && isLastSnapshot)
    9956         {
    9957             /* commit changes to have unused diffs deassociated from this
    9958              * machine before deletion (see below) */
    9959             commit();
    9960 
    9961             /* delete the unused diffs now (and uninit them) because discard
    9962              * may fail otherwise (too many children of the hard disk to be
    9963              * discarded) */
    9964             for (std::list< ComObjPtr<Medium> >::const_iterator
    9965                  it = diffs.begin(); it != diffs.end(); ++it)
    9966             {
    9967                 /// @todo for now, we ignore errors since we've already
    9968                 /// and therefore cannot fail. Later, we may want to report a
    9969                 /// warning through the Progress object
    9970                 HRESULT rc2 = (*it)->deleteStorageAndWait();
    9971                 if (SUCCEEDED(rc2))
    9972                     (*it)->uninit();
    9973             }
    9974 
    9975             /* prevent further deletion */
    9976             diffs.clear();
    9977 
    9978             /* discard the current snapshot and state task is in action, the
    9979              * current snapshot is the last one. Discard the current snapshot
    9980              * after discarding the current state. */
    9981 
    9982             DeleteSnapshotTask subTask (aTask, mData->mCurrentSnapshot);
    9983             subTask.subTask = true;
    9984             discardSnapshotHandler (subTask);
    9985 
    9986             AutoCaller progressCaller (aTask.progress);
    9987             AutoReadLock progressLock (aTask.progress);
    9988             if (aTask.progress->completed())
    9989             {
    9990                 /* the progress can be completed by a subtask only if there
    9991                  * was a failure */
    9992                 rc = aTask.progress->resultCode();
    9993                 Assert (FAILED(rc));
    9994                 errorInSubtask = true;
    9995             }
    9996 
    9997             /* we've committed already, so inform callbacks anyway to ensure
    9998              * they don't miss some change */
    9999             /// @todo NEWMEDIA check if we need this informCallbacks at all
    10000             /// after updating discardCurrentSnapshot functionality
    10001             saveFlags |= SaveS_InformCallbacksAnyway;
    10002         }
    10003 
    100049928        /* @todo saveSettings() below needs a VirtualBox write lock and we need
    100059929         * to leave this object's lock to do this to follow the {parent-child}
     
    100139937         * state accordingly no matter of the discard snapshot result */
    100149938        if (mSSData->mStateFilePath)
    10015             setMachineState (MachineState_Saved);
     9939            setMachineState(MachineState_Saved);
    100169940        else
    10017             setMachineState (MachineState_PoweredOff);
     9941            setMachineState(MachineState_PoweredOff);
    100189942
    100199943        updateMachineStateOnClient();
     
    100219945
    100229946        /* assign the timestamp from the snapshot */
    10023         Assert (RTTimeSpecGetMilli (&snapshotTimeStamp) != 0);
     9947        Assert(RTTimeSpecGetMilli (&snapshotTimeStamp) != 0);
    100249948        mData->mLastStateChange = snapshotTimeStamp;
    100259949
     
    100279951         * do so even if the subtask failed (errorInSubtask=true) because we've
    100289952         * already committed machine data and deleted old diffs before
    10029          * discarding the current snapshot so there is no way to rollback */
     9953         * discarding the snapshot so there is no way to rollback */
    100309954        HRESULT rc2 = saveSettings(SaveS_ResetCurStateModified | saveFlags);
    100319955
     
    100399963        {
    100409964            /* now, delete the unused diffs (only on success!) and uninit them*/
    10041             for (std::list< ComObjPtr<Medium> >::const_iterator
    10042                  it = diffs.begin(); it != diffs.end(); ++it)
     9965            for (std::list< ComObjPtr<Medium> >::const_iterator it = diffs.begin();
     9966                 it != diffs.end();
     9967                 ++it)
    100439968            {
    100449969                /// @todo for now, we ignore errors since we've already
     
    100679992        {
    100689993            /* restore the machine state */
    10069             setMachineState (aTask.state);
     9994            setMachineState(aTask.state);
    100709995            updateMachineStateOnClient();
    100719996        }
     
    1007910004
    1008010005    if (SUCCEEDED(rc))
    10081         mParent->onSnapshotDiscarded (mData->mUuid, Guid());
    10082 
    10083     LogFlowThisFunc(("Done discarding current state (rc=%08X)\n", rc));
     10006        mParent->onSnapshotDiscarded(mData->mUuid, Guid());
     10007
     10008    LogFlowThisFunc(("Done restoring snapshot (rc=%08X)\n", rc));
    1008410009
    1008510010    LogFlowThisFuncLeave();
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