VirtualBox

Changeset 56563 in vbox


Ignore:
Timestamp:
Jun 19, 2015 2:39:16 PM (10 years ago)
Author:
vboxsync
Message:

Main/Main/src-server/MachineImplCloneVM: fix a collection of bugs around losing saved state during cloning (file was copied, but not used in "current state" as it should be) and incorrect value of the "current state modified" flag of the clone.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp

    r54948 r56563  
    103103    HRESULT createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
    104104    inline void updateProgressStats(MEDIUMTASKCHAIN &mtc, bool fAttachLinked, ULONG &uCount, ULONG &uTotalWeight) const;
    105     inline HRESULT addSaveState(const ComObjPtr<Machine> &machine, ULONG &uCount, ULONG &uTotalWeight);
     105    inline HRESULT addSaveState(const ComObjPtr<Machine> &machine, bool fAttachCurrent, ULONG &uCount, ULONG &uTotalWeight);
    106106    inline HRESULT queryBaseName(const ComPtr<IMedium> &pMedium, Utf8Str &strBaseName) const;
    107107    HRESULT queryMediasForMachineState(const RTCList<ComObjPtr<Machine> > &machineList,
     
    200200}
    201201
    202 HRESULT MachineCloneVMPrivate::addSaveState(const ComObjPtr<Machine> &machine, ULONG &uCount, ULONG &uTotalWeight)
     202HRESULT MachineCloneVMPrivate::addSaveState(const ComObjPtr<Machine> &machine, bool fAttachCurrent, ULONG &uCount, ULONG &uTotalWeight)
    203203{
    204204    Bstr bstrSrcSaveStatePath;
     
    208208    {
    209209        SAVESTATETASK sst;
    210         sst.snapshotUuid     = machine->i_getSnapshotId();
     210        if (fAttachCurrent)
     211        {
     212            /* Make this saved state part of "current state" of the target
     213             * machine, whether it is part of a snapshot or not. */
     214            sst.snapshotUuid.clear();
     215        }
     216        else
     217            sst.snapshotUuid = machine->i_getSnapshotId();
    211218        sst.strSaveStateFile = bstrSrcSaveStatePath;
    212219        uint64_t cbSize;
     
    241248{
    242249    /* This mode is pretty straightforward. We didn't need to know about any
    243      * parent/children relationship and therefor simply adding all directly
     250     * parent/children relationship and therefore simply adding all directly
    244251     * attached images of the source VM as cloning targets. The IMedium code
    245252     * take than care to merge any (possibly) existing parents into the new
     
    309316        }
    310317        /* Add the save state files of this machine if there is one. */
    311         rc = addSaveState(machine, uCount, uTotalWeight);
     318        rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
    312319        if (FAILED(rc)) return rc;
    313320    }
     
    346353     *
    347354     * Note: This still leads to media chains which can have the same medium
    348      * included. This case is handled in "run" and therefor not critical, but
     355     * included. This case is handled in "run" and therefore not critical, but
    349356     * it leads to wrong progress infos which isn't nice. */
    350357
     358    Assert(!fAttachLinked);
    351359    HRESULT rc = S_OK;
    352360    std::map<ComPtr<IMedium>, uint32_t> mediaHist; /* Our usage histogram for the medias */
     
    412420        }
    413421        /* Add the save state files of this machine if there is one. */
    414         rc = addSaveState(machine, uCount, uTotalWeight);
     422        rc = addSaveState(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
    415423        if (FAILED(rc)) return rc;
     424        /* If this is the newly created current state, make sure that the
     425         * saved state is also attached to it. */
     426        if (fCreateDiffs)
     427        {
     428            rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
     429            if (FAILED(rc)) return rc;
     430        }
    416431    }
    417432    /* Build up the index list of the image chain. Unfortunately we can't do
     
    485500     * adding all directly and indirectly attached disk images to the worker
    486501     * list. */
     502    Assert(!fAttachLinked);
    487503    HRESULT rc = S_OK;
    488504    for (size_t i = 0; i < machineList.size(); ++i)
     
    549565        }
    550566        /* Add the save state files of this machine if there is one. */
    551         rc = addSaveState(machine, uCount, uTotalWeight);
     567        rc = addSaveState(machine, false /*fAttachCurrent*/, uCount, uTotalWeight);
    552568        if (FAILED(rc)) return rc;
     569        /* If this is the newly created current state, make sure that the
     570         * saved state is also attached to it. */
     571        if (fCreateDiffs)
     572        {
     573            rc = addSaveState(machine, true /*fAttachCurrent*/, uCount, uTotalWeight);
     574            if (FAILED(rc)) return rc;
     575        }
    553576    }
    554577    /* Build up the index list of the image chain. Unfortunately we can't do
     
    9821005                                  p->tr("Could not find data to snapshots '%s'"), d->snapshotId.toString().c_str());
    9831006
    984 
    985 
    9861007        if (d->mode == CloneMode_MachineState)
    9871008        {
     
    10081029                /* Current state is under root snapshot. */
    10091030                trgMCF.uuidCurrentSnapshot = sn.uuid;
    1010                 /* There will be created a new differencing image based on this
    1011                  * snapshot. So reset the modified state. */
    1012                 trgMCF.fCurrentStateModified = false;
    10131031            }
    10141032            /* The snapshot will be the root one. */
     
    13961414            rc = d->pTrgMachine->i_loadMachineDataFromSettings(trgMCF, &d->pTrgMachine->mData->mUuid);
    13971415            if (FAILED(rc)) throw rc;
     1416
     1417            /* Fix up the "current state modified" flag to what it should be,
     1418             * as the value guessed in i_loadMachineDataFromSettings can be
     1419             * quite far off the logical value for the cloned VM. */
     1420            if (d->mode == CloneMode_MachineState)
     1421                d->pTrgMachine->mData->mCurrentStateModified = FALSE;
     1422            else if (   d->mode == CloneMode_MachineAndChildStates
     1423                && sn.uuid.isValid()
     1424                && !sn.uuid.isZero())
     1425            {
     1426                if (!d->pOldMachineState.isNull())
     1427                {
     1428                    /* There will be created a new differencing image based on
     1429                     * this snapshot. So reset the modified state. */
     1430                    d->pTrgMachine->mData->mCurrentStateModified = FALSE;
     1431                }
     1432                else
     1433                    d->pTrgMachine->mData->mCurrentStateModified = p->mData->mCurrentStateModified;
     1434            }
     1435            else if (d->mode == CloneMode_AllStates)
     1436                d->pTrgMachine->mData->mCurrentStateModified = p->mData->mCurrentStateModified;
     1437
     1438            /* If the target machine has saved state we MUST adjust the machine
     1439             * state, otherwise saving settings will drop the information. */
     1440            if (trgMCF.strStateFile.isNotEmpty())
     1441                d->pTrgMachine->i_setMachineState(MachineState_Saved);
     1442
    13981443            /* save all VM data */
    13991444            bool fNeedsGlobalSaveSettings = false;
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