VirtualBox

Changeset 38048 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 19, 2011 8:01:59 AM (13 years ago)
Author:
vboxsync
Message:

Machine: fix snapshot and current state updating in the "machine and child states" case of full cloning

File:
1 edited

Legend:

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

    r38041 r38048  
    265265    try
    266266    {
     267        /** @todo r=klaus this code cannot deal with someone crazy specifying
     268         * IMachine corresponding to a mutable machine as d->pSrcMachine */
     269        if (d->pSrcMachine->isSessionMachine())
     270            throw E_FAIL;
     271
    267272        /* Handle the special case that someone is requesting a _full_ clone
    268273         * with all snapshots (and the current state), but uses a snapshot
     
    279284            if (FAILED(rc)) throw rc;
    280285            d->pSrcMachine = (Machine*)(IMachine*)newSrcMachine;
     286        }
     287
     288        bool fSubtreeIncludesCurrent = false;
     289        ComObjPtr<Machine> pCurrState;
     290        if (d->mode == CloneMode_MachineAndChildStates)
     291        {
     292            if (d->pSrcMachine->isSnapshotMachine())
     293            {
     294                /* find machine object for current snapshot of current state */
     295                Bstr bstrSrcMachineId;
     296                rc = d->pSrcMachine->COMGETTER(Id)(bstrSrcMachineId.asOutParam());
     297                if (FAILED(rc)) throw rc;
     298                ComPtr<IMachine> pCurr;
     299                rc = d->pSrcMachine->getVirtualBox()->FindMachine(bstrSrcMachineId.raw(), pCurr.asOutParam());
     300                if (FAILED(rc)) throw rc;
     301                if (pCurr.isNull())
     302                    throw E_FAIL;
     303                pCurrState = (Machine *)(IMachine *)pCurr;
     304                ComPtr<ISnapshot> pSnapshot;
     305                rc = pCurrState->COMGETTER(CurrentSnapshot)(pSnapshot.asOutParam());
     306                if (FAILED(rc)) throw rc;
     307                if (pSnapshot.isNull())
     308                    throw E_FAIL;
     309                ComPtr<IMachine> pCurrSnapMachine;
     310                rc = pSnapshot->COMGETTER(Machine)(pCurrSnapMachine.asOutParam());
     311                if (FAILED(rc)) throw rc;
     312                if (pCurrSnapMachine.isNull())
     313                    throw E_FAIL;
     314
     315                /* now check if there is a parent chain which leads to the
     316                 * snapshot machine defining the subtree. */
     317                while (!pSnapshot.isNull())
     318                {
     319                    ComPtr<IMachine> pSnapMachine;
     320                    rc = pSnapshot->COMGETTER(Machine)(pSnapMachine.asOutParam());
     321                    if (FAILED(rc)) throw rc;
     322                    if (pSnapMachine.isNull())
     323                        throw E_FAIL;
     324                    if (pSnapMachine == d->pSrcMachine)
     325                    {
     326                        fSubtreeIncludesCurrent = true;
     327                        break;
     328                    }
     329                    rc = pSnapshot->COMGETTER(Parent)(pSnapshot.asOutParam());
     330                }
     331            }
     332            else
     333            {
     334                /* If the subtree is only the Current State simply use the
     335                 * 'machine' case for cloning. It is easier to understand. */
     336                d->mode = CloneMode_MachineState;
     337            }
    281338        }
    282339
     
    305362            {
    306363                Utf8Str id;
    307                 if (    d->mode == CloneMode_MachineAndChildStates
    308                     && !d->snapshotId.isEmpty())
     364                if (d->mode == CloneMode_MachineAndChildStates)
    309365                    id = d->snapshotId.toString();
    310366                ComPtr<ISnapshot> pSnapshot;
     
    315371                if (d->mode == CloneMode_MachineAndChildStates)
    316372                {
    317                     rc = pSnapshot->COMGETTER(Machine)(d->pOldMachineState.asOutParam());
    318                     if (FAILED(rc)) throw rc;
     373                    if (fSubtreeIncludesCurrent)
     374                    {
     375                        /* zap d->snapshotId because there is no need to
     376                         * create a new current state. */
     377                        d->snapshotId.clear();
     378                        if (pCurrState.isNull())
     379                            throw E_FAIL;
     380                        machineList.append(pCurrState);
     381                    }
     382                    else
     383                    {
     384                        rc = pSnapshot->COMGETTER(Machine)(d->pOldMachineState.asOutParam());
     385                        if (FAILED(rc)) throw rc;
     386                    }
    319387                }
    320388            }
     
    797865            }
    798866
    799             /* Create diffs for the last image chain. */
     867            Bstr bstrSrcId;
     868            rc = mtc.chain.first().pMedium->COMGETTER(Id)(bstrSrcId.asOutParam());
     869            if (FAILED(rc)) throw rc;
     870            Bstr bstrTrgId;
     871            rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam());
     872            if (FAILED(rc)) throw rc;
     873            /* update snapshot configuration */
     874            d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
     875
     876            /* create new 'Current State' diff for caller defined place */
    800877            if (mtc.fCreateDiffs)
    801878            {
     
    822899                    newMedia.append(pNewParent);
    823900                }
     901
     902                rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam());
     903                if (FAILED(rc)) throw rc;
    824904            }
    825             Bstr bstrSrcId;
    826             rc = mtc.chain.first().pMedium->COMGETTER(Id)(bstrSrcId.asOutParam());
    827             if (FAILED(rc)) throw rc;
    828             Bstr bstrTrgId;
    829             rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam());
    830             if (FAILED(rc)) throw rc;
    831             /* We have to patch the configuration, so it contains the new
    832              * medium uuid instead of the old one. */
     905            /* update 'Current State' configuration */
    833906            d->updateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
    834             d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
    835907        }
    836908        /* Make sure all disks know of the new machine uuid. We do this last to
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