Changeset 38048 in vbox for trunk/src/VBox
- Timestamp:
- Jul 19, 2011 8:01:59 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
r38041 r38048 265 265 try 266 266 { 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 267 272 /* Handle the special case that someone is requesting a _full_ clone 268 273 * with all snapshots (and the current state), but uses a snapshot … … 279 284 if (FAILED(rc)) throw rc; 280 285 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 } 281 338 } 282 339 … … 305 362 { 306 363 Utf8Str id; 307 if ( d->mode == CloneMode_MachineAndChildStates 308 && !d->snapshotId.isEmpty()) 364 if (d->mode == CloneMode_MachineAndChildStates) 309 365 id = d->snapshotId.toString(); 310 366 ComPtr<ISnapshot> pSnapshot; … … 315 371 if (d->mode == CloneMode_MachineAndChildStates) 316 372 { 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 } 319 387 } 320 388 } … … 797 865 } 798 866 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 */ 800 877 if (mtc.fCreateDiffs) 801 878 { … … 822 899 newMedia.append(pNewParent); 823 900 } 901 902 rc = pNewParent->COMGETTER(Id)(bstrTrgId.asOutParam()); 903 if (FAILED(rc)) throw rc; 824 904 } 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 */ 833 906 d->updateStorageLists(trgMCF.storageMachine.llStorageControllers, bstrSrcId, bstrTrgId); 834 d->updateSnapshotStorageLists(trgMCF.llFirstSnapshot, bstrSrcId, bstrTrgId);835 907 } 836 908 /* 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.