VirtualBox

Changeset 37531 in vbox


Ignore:
Timestamp:
Jun 17, 2011 12:12:29 PM (14 years ago)
Author:
vboxsync
Message:

Main;FE;CloneVM: add clone options; regenerate MACs of all network adapters dependent of the user option; docs

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r37449 r37531  
    392392                                                 trgMachine.asOutParam()),
    393393                    RTEXITCODE_FAILURE);
     394
     395    /* Clone options */
     396    com::SafeArray<CloneOptions_T> options;
     397    options.push_back(CloneOptions_KeepNATMACs);
     398
     399    /* Start the cloning */
    394400    ComPtr<IProgress> progress;
    395401    CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine,
    396402                                        mode,
    397                                         FALSE,
     403                                        ComSafeArrayAsInParam(options),
    398404                                        progress.asOutParam()),
    399405                    RTEXITCODE_FAILURE);
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp

    r37468 r37531  
    8080    }
    8181
     82    /* NAT network adapters should keep there MAC address to prevent any
     83     * reactivation. For the other modes they should be regenerated to prevent
     84     * address conflicts in the network. */
     85    QVector<KCloneOptions> options;
     86    options.append(KCloneOptions_KeepNATMACs);
     87
    8288    /* Start cloning. */
    83     CProgress progress = m_machine.CloneTo(cloneMachine, mode, false);
     89    CProgress progress = m_machine.CloneTo(cloneMachine, mode, options);
    8490    if (!m_machine.isOk())
    8591    {
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r37525 r37531  
    35293529
    35303530    <const name="MachineState"                 value="1">
    3531       <desc>Clone the state of the machine.</desc>
     3531      <desc>Clone the state of the selected machine.</desc>
    35323532    </const>
    35333533    <const name="MachineAndChildStates"        value="2">
    3534       <desc>Clone the state of the machine and if this machine object has child snapshots the state of this childs.</desc>
     3534      <desc>Clone the state of the selected machine and if this machine object has child snapshots the state of this childs.</desc>
    35353535    </const>
    35363536    <const name="AllStates"                    value="3">
     
    35403540  </enum>
    35413541
     3542  <enum
     3543    name="CloneOptions" extends="$unknown"
     3544    uuid="1be61ee1-c0ea-4942-b733-7496f27d4f28"
     3545    >
     3546
     3547    <desc>
     3548    Clone options, used with <link to="IMachine::cloneTo" />.
     3549    </desc>
     3550
     3551    <const name="Link"               value="1">
     3552      <desc>Create a clone VM where all virtual disks are linked to the original VM.</desc>
     3553    </const>
     3554    <const name="KeepAllMACs"        value="2">
     3555      <desc>Don't generate new MAC addresses of the attached network adapters.</desc>
     3556    </const>
     3557    <const name="KeepNATMACs"        value="3">
     3558      <desc>Don't generate new MAC addresses of the attached network adapters when they are using NAT.</desc>
     3559    </const>
     3560
     3561  </enum>
     3562
    35423563
    35433564  <interface
    35443565    name="IMachine" extends="$unknown"
    3545     uuid="5A398458-266D-4DCD-9745-0886AEBD761B"
     3566    uuid="54fd9a53-7c1b-4005-9247-9cf703edd4da"
    35463567    wsmap="managed"
    35473568    >
     
    59665987      <desc>
    59675988        Creates a clone of this machine, either as a full clone (which means
    5968         creating independent copies of the hard disk media), or as a linked
    5969         clone (which uses its own differencing media, sharing the parent media
    5970         with the source machine).
    5971 
    5972         The target machine object must have been created previously with
    5973         <link to="IVirtualBox::createMachine"/>, and all the settings will be
    5974         transferred except the VM name, hardware UUID and the network card
    5975         MAC addresses. These can be set after the clone operation if required.
    5976         The operation is performed asynchronously, so the machine object will
    5977         be not be usable until the @a progress object signals completion. If
    5978         any step of the machine clone operation fails this will abort the
    5979         operation. The result will be a machine which is not a complete clone.
    5980         It is the responsibility of the caller to delete this incomplete
    5981         machine if desired with <link to="#unregister"/> and/or
    5982         <link to="#delete"/>.
     5989        creating independent copies of the hard disk media, save states and so
     5990        on), or as a linked clone (which uses its own differencing media,
     5991        sharing the parent media with the source machine).
     5992
     5993        The target machine object must have been created previously with <link
     5994          to="IVirtualBox::createMachine"/>, and all the settings will be
     5995        transferred except the VM name and the hardware UUID. You can set the
     5996        VM name and the new hardware UUID when creating the target machine. The
     5997        network MAC addresses are newly created for all newtwork adapters. You
     5998        can change that behaviour with the options parameter. The operation is
     5999        performed asynchronously, so the machine object will be not be usable
     6000        until the @a progress object signals completion.
    59836001
    59846002        <result name="E_INVALIDARG">
     
    59936011        <desc>Which states should be cloned.</desc>
    59946012      </param>
    5995       <param name="fullClone" type="boolean" dir="in">
    5996         <desc>Selects whether a full or linked clone is created.</desc>
     6013      <param name="options" type="CloneOptions" dir="in" safearray="yes">
     6014        <desc>Options for the cloning operation.</desc>
    59976015      </param>
    59986016      <param name="progress" type="IProgress" dir="return">
     
    82058223      <desc>Don't show the started process according to the guest OS guidelines.</desc>
    82068224    </const>
    8207     <const name="NoProfile"               value="8">
    8208       <desc>Do not use the user's profile data when exeuting a process.</desc>
    8209     </const>
     8225    <const name="NoProfile"               value="8"> 
     8226      <desc>Do not use the user's profile data when exeuting a process.</desc> 
     8227    </const> 
    82108228  </enum>
    82118229
  • trunk/src/VBox/Main/include/MachineImpl.h

    r37492 r37531  
    529529    STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL tryToUnbind));
    530530    STDMETHOD(DetachHostPciDevice(LONG hostAddress));
    531     STDMETHOD(CloneTo(IMachine *aTarget, CloneMode_T mode, BOOL aFullClone, IProgress **aProgress));
     531    STDMETHOD(CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress));
    532532    // public methods only for internal purposes
    533533
  • trunk/src/VBox/Main/include/MachineImplCloneVM.h

    r37491 r37531  
    2727{
    2828public:
    29     MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, bool fFullClone);
     29    MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts);
    3030    ~MachineCloneVM();
    3131
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r37491 r37531  
    60746074}
    60756075
    6076 STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, BOOL fFullClone, IProgress **pProgress)
     6076STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress)
    60776077{
    60786078    LogFlowFuncEnter();
     
    60806080    CheckComArgNotNull(pTarget);
    60816081    CheckComArgOutPointerValid(pProgress);
    6082     AssertReturn(!fFullClone, E_NOTIMPL);
    6083 
    6084     AutoCaller autoCaller(this);
    6085     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    6086 
    6087     MachineCloneVM *pWorker = new MachineCloneVM(this, static_cast<Machine*>(pTarget), mode, fFullClone);
     6082
     6083    /* Convert the options. */
     6084    RTCList<CloneOptions_T> optList;
     6085    if (options != NULL)
     6086        optList = SafeArrayToRTCList(ComSafeArrayInArg(options));
     6087    AssertReturn(!optList.contains(CloneOptions_Link), E_NOTIMPL);
     6088    AssertReturn(!(optList.contains(CloneOptions_KeepAllMACs) && optList.contains(CloneOptions_KeepNATMACs)), E_FAIL);
     6089
     6090    AutoCaller autoCaller(this);
     6091    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     6092
     6093    MachineCloneVM *pWorker = new MachineCloneVM(this, static_cast<Machine*>(pTarget), mode, optList);
    60886094
    60896095    HRESULT rc = pWorker->start(pProgress);
  • trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp

    r37523 r37531  
    2020#include "VirtualBoxImpl.h"
    2121#include "MediumImpl.h"
     22#include "HostImpl.h"
    2223
    2324#include <iprt/path.h>
     
    5556struct MachineCloneVMPrivate
    5657{
    57     MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine, CloneMode_T a_mode, bool a_fFullClone)
     58    MachineCloneVMPrivate(MachineCloneVM *a_q, ComObjPtr<Machine> &a_pSrcMachine, ComObjPtr<Machine> &a_pTrgMachine, CloneMode_T a_mode, const RTCList<CloneOptions_T> &opts)
    5859      : q_ptr(a_q)
    5960      , p(a_pSrcMachine)
     
    6162      , pTrgMachine(a_pTrgMachine)
    6263      , mode(a_mode)
    63       , fLinkDisks(!a_fFullClone)
     64      , options(opts)
    6465    {}
    6566
     
    9192
    9293    /* Private helper methods */
    93     HRESULT cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
    94     settings::Snapshot cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const;
    95     void cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
    96     void cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
    97     void cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
    98     static int cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser);
     94    HRESULT createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const;
     95    settings::Snapshot findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const;
     96    void updateMACAddresses(settings::NetworkAdaptersList &nwl) const;
     97    void updateMACAddresses(settings::SnapshotsList &sl) const;
     98    void updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
     99    void updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const;
     100    void updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const;
     101    static int copyStateFileProgress(unsigned uPercentage, void *pvUser);
    99102
    100103    /* Private q and parent pointer */
     
    109112    Guid                        snapshotId;
    110113    CloneMode_T                 mode;
    111     bool                        fLinkDisks;
     114    RTCList<CloneOptions_T>     options;
    112115    RTCList<MEDIUMTASKCHAIN>    llMedias;
    113116    RTCList<SAVESTATETASK>      llSaveStateFiles; /* Snapshot UUID -> File path */
    114117};
    115118
    116 HRESULT MachineCloneVMPrivate::cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const
     119HRESULT MachineCloneVMPrivate::createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const
    117120{
    118121    HRESULT rc = S_OK;
     
    131134    for (size_t i = 0; i < sfaChilds.size(); ++i)
    132135    {
    133         rc = cloneCreateMachineList(sfaChilds[i], machineList);
     136        rc = createMachineList(sfaChilds[i], machineList);
    134137        if (FAILED(rc)) return rc;
    135138    }
     
    138141}
    139142
    140 settings::Snapshot MachineCloneVMPrivate::cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const
     143settings::Snapshot MachineCloneVMPrivate::findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const
    141144{
    142145    settings::SnapshotsList::const_iterator it;
     
    146149            return *it;
    147150        else if (!it->llChildSnapshots.empty())
    148             return cloneFindSnapshot(pMCF, it->llChildSnapshots, id);
     151            return findSnapshot(pMCF, it->llChildSnapshots, id);
    149152    }
    150153    return settings::Snapshot();
    151154}
    152155
    153 void MachineCloneVMPrivate::cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const
     156void MachineCloneVMPrivate::updateMACAddresses(settings::NetworkAdaptersList &nwl) const
     157{
     158    const bool fNotNAT = options.contains(CloneOptions_KeepNATMACs);
     159    settings::NetworkAdaptersList::iterator it;
     160    for (it = nwl.begin(); it != nwl.end(); ++it)
     161    {
     162        if (   fNotNAT
     163            && it->mode == NetworkAttachmentType_NAT)
     164            continue;
     165        Host::generateMACAddress(it->strMACAddress);
     166    }
     167}
     168
     169void MachineCloneVMPrivate::updateMACAddresses(settings::SnapshotsList &sl) const
     170{
     171    settings::SnapshotsList::iterator it;
     172    for (it = sl.begin(); it != sl.end(); ++it)
     173    {
     174        updateMACAddresses(it->hardware.llNetworkAdapters);
     175        if (!it->llChildSnapshots.empty())
     176            updateMACAddresses(it->llChildSnapshots);
     177    }
     178}
     179
     180void MachineCloneVMPrivate::updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const
    154181{
    155182    settings::StorageControllersList::iterator it3;
     
    173200}
    174201
    175 void MachineCloneVMPrivate::cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const
     202void MachineCloneVMPrivate::updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const
    176203{
    177204    settings::SnapshotsList::iterator it;
     
    180207         ++it)
    181208    {
    182         cloneUpdateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);
     209        updateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);
    183210        if (!it->llChildSnapshots.empty())
    184             cloneUpdateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId);
    185     }
    186 }
    187 
    188 void MachineCloneVMPrivate::cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
     211            updateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId);
     212    }
     213}
     214
     215void MachineCloneVMPrivate::updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const
    189216{
    190217    settings::SnapshotsList::iterator it;
     
    194221            it->strStateFile = strFile;
    195222        else if (!it->llChildSnapshots.empty())
    196             cloneUpdateStateFile(it->llChildSnapshots, id, strFile);
     223            updateStateFile(it->llChildSnapshots, id, strFile);
    197224    }
    198225}
    199226
    200227/* static */
    201 int MachineCloneVMPrivate::cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser)
     228int MachineCloneVMPrivate::copyStateFileProgress(unsigned uPercentage, void *pvUser)
    202229{
    203230    ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser);
     
    215242}
    216243
    217 
    218244// The public class
    219245/////////////////////////////////////////////////////////////////////////////
    220246
    221 MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, bool fFullClone)
    222     : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, fFullClone))
     247MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, const RTCList<CloneOptions_T> &opts)
     248    : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, opts))
    223249{
    224250}
     
    283309                rc = d->pSrcMachine->FindSnapshot(Bstr(id).raw(), pSnapshot.asOutParam());
    284310                if (FAILED(rc)) throw rc;
    285                 rc = d->cloneCreateMachineList(pSnapshot, machineList);
     311                rc = d->createMachineList(pSnapshot, machineList);
    286312                if (FAILED(rc)) throw rc;
    287313                if (d->mode == CloneMode_MachineAndChildStates)
     
    444470        settings::Snapshot sn;
    445471        if (!d->snapshotId.isEmpty())
    446             sn = d->cloneFindSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);
     472            sn = d->findSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);
    447473
    448474        if (d->mode == CloneMode_MachineState)
     
    469495            trgMCF.llFirstSnapshot.clear();
    470496            trgMCF.llFirstSnapshot.push_back(sn);
     497        }
     498
     499        /* Generate new MAC addresses for all machines when not forbidden. */
     500        if (!d->options.contains(CloneOptions_KeepAllMACs))
     501        {
     502            d->updateMACAddresses(trgMCF.hardwareMachine.llNetworkAdapters);
     503            d->updateMACAddresses(trgMCF.llFirstSnapshot);
    471504        }
    472505
     
    642675            /* We have to patch the configuration, so it contains the new
    643676             * medium uuid instead of the old one. */
    644             d->cloneUpdateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
    645             d->cloneUpdateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
     677            d->updateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId);
     678            d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);
    646679        }
    647680        /* Clone all save state files. */
     
    657690            if (!newFiles.contains(strTrgSaveState.c_str()))
    658691            {
    659                 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::cloneCopyStateFileProgress, &d->pProgress);
     692                int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::copyStateFileProgress, &d->pProgress);
    660693                if (RT_FAILURE(vrc))
    661694                    throw p->setError(VBOX_E_IPRT_ERROR,
     
    668701                trgMCF.strStateFile = strTrgSaveState;
    669702            else
    670                 d->cloneUpdateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
     703                d->updateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);
    671704        }
    672705
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