Changeset 37531 in vbox
- Timestamp:
- Jun 17, 2011 12:12:29 PM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
r37449 r37531 392 392 trgMachine.asOutParam()), 393 393 RTEXITCODE_FAILURE); 394 395 /* Clone options */ 396 com::SafeArray<CloneOptions_T> options; 397 options.push_back(CloneOptions_KeepNATMACs); 398 399 /* Start the cloning */ 394 400 ComPtr<IProgress> progress; 395 401 CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine, 396 402 mode, 397 FALSE,403 ComSafeArrayAsInParam(options), 398 404 progress.asOutParam()), 399 405 RTEXITCODE_FAILURE); -
trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UICloneVMWizard.cpp
r37468 r37531 80 80 } 81 81 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 82 88 /* Start cloning. */ 83 CProgress progress = m_machine.CloneTo(cloneMachine, mode, false);89 CProgress progress = m_machine.CloneTo(cloneMachine, mode, options); 84 90 if (!m_machine.isOk()) 85 91 { -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r37525 r37531 3529 3529 3530 3530 <const name="MachineState" value="1"> 3531 <desc>Clone the state of the machine.</desc>3531 <desc>Clone the state of the selected machine.</desc> 3532 3532 </const> 3533 3533 <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> 3535 3535 </const> 3536 3536 <const name="AllStates" value="3"> … … 3540 3540 </enum> 3541 3541 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 3542 3563 3543 3564 <interface 3544 3565 name="IMachine" extends="$unknown" 3545 uuid="5 A398458-266D-4DCD-9745-0886AEBD761B"3566 uuid="54fd9a53-7c1b-4005-9247-9cf703edd4da" 3546 3567 wsmap="managed" 3547 3568 > … … 5966 5987 <desc> 5967 5988 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. 5983 6001 5984 6002 <result name="E_INVALIDARG"> … … 5993 6011 <desc>Which states should be cloned.</desc> 5994 6012 </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> 5997 6015 </param> 5998 6016 <param name="progress" type="IProgress" dir="return"> … … 8205 8223 <desc>Don't show the started process according to the guest OS guidelines.</desc> 8206 8224 </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> 8210 8228 </enum> 8211 8229 -
trunk/src/VBox/Main/include/MachineImpl.h
r37492 r37531 529 529 STDMETHOD(AttachHostPciDevice(LONG hostAddress, LONG desiredGuestAddress, BOOL tryToUnbind)); 530 530 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)); 532 532 // public methods only for internal purposes 533 533 -
trunk/src/VBox/Main/include/MachineImplCloneVM.h
r37491 r37531 27 27 { 28 28 public: 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); 30 30 ~MachineCloneVM(); 31 31 -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r37491 r37531 6074 6074 } 6075 6075 6076 STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, BOOL fFullClone, IProgress **pProgress)6076 STDMETHODIMP Machine::CloneTo(IMachine *pTarget, CloneMode_T mode, ComSafeArrayIn(CloneOptions_T, options), IProgress **pProgress) 6077 6077 { 6078 6078 LogFlowFuncEnter(); … … 6080 6080 CheckComArgNotNull(pTarget); 6081 6081 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); 6088 6094 6089 6095 HRESULT rc = pWorker->start(pProgress); -
trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
r37523 r37531 20 20 #include "VirtualBoxImpl.h" 21 21 #include "MediumImpl.h" 22 #include "HostImpl.h" 22 23 23 24 #include <iprt/path.h> … … 55 56 struct MachineCloneVMPrivate 56 57 { 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) 58 59 : q_ptr(a_q) 59 60 , p(a_pSrcMachine) … … 61 62 , pTrgMachine(a_pTrgMachine) 62 63 , mode(a_mode) 63 , fLinkDisks(!a_fFullClone)64 , options(opts) 64 65 {} 65 66 … … 91 92 92 93 /* 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); 99 102 100 103 /* Private q and parent pointer */ … … 109 112 Guid snapshotId; 110 113 CloneMode_T mode; 111 bool fLinkDisks;114 RTCList<CloneOptions_T> options; 112 115 RTCList<MEDIUMTASKCHAIN> llMedias; 113 116 RTCList<SAVESTATETASK> llSaveStateFiles; /* Snapshot UUID -> File path */ 114 117 }; 115 118 116 HRESULT MachineCloneVMPrivate::c loneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const119 HRESULT MachineCloneVMPrivate::createMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const 117 120 { 118 121 HRESULT rc = S_OK; … … 131 134 for (size_t i = 0; i < sfaChilds.size(); ++i) 132 135 { 133 rc = c loneCreateMachineList(sfaChilds[i], machineList);136 rc = createMachineList(sfaChilds[i], machineList); 134 137 if (FAILED(rc)) return rc; 135 138 } … … 138 141 } 139 142 140 settings::Snapshot MachineCloneVMPrivate:: cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const143 settings::Snapshot MachineCloneVMPrivate::findSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const 141 144 { 142 145 settings::SnapshotsList::const_iterator it; … … 146 149 return *it; 147 150 else if (!it->llChildSnapshots.empty()) 148 return cloneFindSnapshot(pMCF, it->llChildSnapshots, id);151 return findSnapshot(pMCF, it->llChildSnapshots, id); 149 152 } 150 153 return settings::Snapshot(); 151 154 } 152 155 153 void MachineCloneVMPrivate::cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const 156 void 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 169 void 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 180 void MachineCloneVMPrivate::updateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const 154 181 { 155 182 settings::StorageControllersList::iterator it3; … … 173 200 } 174 201 175 void MachineCloneVMPrivate:: cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const202 void MachineCloneVMPrivate::updateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const 176 203 { 177 204 settings::SnapshotsList::iterator it; … … 180 207 ++it) 181 208 { 182 cloneUpdateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId);209 updateStorageLists(it->storage.llStorageControllers, bstrOldId, bstrNewId); 183 210 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) const211 updateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId); 212 } 213 } 214 215 void MachineCloneVMPrivate::updateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const 189 216 { 190 217 settings::SnapshotsList::iterator it; … … 194 221 it->strStateFile = strFile; 195 222 else if (!it->llChildSnapshots.empty()) 196 cloneUpdateStateFile(it->llChildSnapshots, id, strFile);223 updateStateFile(it->llChildSnapshots, id, strFile); 197 224 } 198 225 } 199 226 200 227 /* static */ 201 int MachineCloneVMPrivate::c loneCopyStateFileProgress(unsigned uPercentage, void *pvUser)228 int MachineCloneVMPrivate::copyStateFileProgress(unsigned uPercentage, void *pvUser) 202 229 { 203 230 ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser); … … 215 242 } 216 243 217 218 244 // The public class 219 245 ///////////////////////////////////////////////////////////////////////////// 220 246 221 MachineCloneVM::MachineCloneVM(ComObjPtr<Machine> pSrcMachine, ComObjPtr<Machine> pTrgMachine, CloneMode_T mode, bool fFullClone)222 : d_ptr(new MachineCloneVMPrivate(this, pSrcMachine, pTrgMachine, mode, fFullClone))247 MachineCloneVM::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)) 223 249 { 224 250 } … … 283 309 rc = d->pSrcMachine->FindSnapshot(Bstr(id).raw(), pSnapshot.asOutParam()); 284 310 if (FAILED(rc)) throw rc; 285 rc = d->c loneCreateMachineList(pSnapshot, machineList);311 rc = d->createMachineList(pSnapshot, machineList); 286 312 if (FAILED(rc)) throw rc; 287 313 if (d->mode == CloneMode_MachineAndChildStates) … … 444 470 settings::Snapshot sn; 445 471 if (!d->snapshotId.isEmpty()) 446 sn = d-> cloneFindSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId);472 sn = d->findSnapshot(&trgMCF, trgMCF.llFirstSnapshot, d->snapshotId); 447 473 448 474 if (d->mode == CloneMode_MachineState) … … 469 495 trgMCF.llFirstSnapshot.clear(); 470 496 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); 471 504 } 472 505 … … 642 675 /* We have to patch the configuration, so it contains the new 643 676 * 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); 646 679 } 647 680 /* Clone all save state files. */ … … 657 690 if (!newFiles.contains(strTrgSaveState.c_str())) 658 691 { 659 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::c loneCopyStateFileProgress, &d->pProgress);692 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, MachineCloneVMPrivate::copyStateFileProgress, &d->pProgress); 660 693 if (RT_FAILURE(vrc)) 661 694 throw p->setError(VBOX_E_IPRT_ERROR, … … 668 701 trgMCF.strStateFile = strTrgSaveState; 669 702 else 670 d-> cloneUpdateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState);703 d->updateStateFile(trgMCF.llFirstSnapshot, sst.snapshotUuid, strTrgSaveState); 671 704 } 672 705
Note:
See TracChangeset
for help on using the changeset viewer.