Changeset 37485 in vbox for trunk/src/VBox
- Timestamp:
- Jun 16, 2011 8:37:49 AM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/MachineImpl.h
r37449 r37485 841 841 842 842 struct CloneVMTask; 843 HRESULT cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< Com Ptr<IMachine> > &machineList) const;843 HRESULT cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const; 844 844 settings::Snapshot cloneFindSnapshot(settings::MachineConfigFile *pMCF, const settings::SnapshotsList &snl, const Guid &id) const; 845 845 void cloneUpdateStorageLists(settings::StorageControllersList &sc, const Bstr &bstrOldId, const Bstr &bstrNewId) const; 846 846 void cloneUpdateSnapshotStorageLists(settings::SnapshotsList &sl, const Bstr &bstrOldId, const Bstr &bstrNewId) const; 847 void cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const; 848 static int cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser); 847 849 848 850 static DECLCALLBACK(int) cloneVMThread(RTTHREAD Thread, void *pvUser); -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r37449 r37485 6093 6093 }MediumTaskChain; 6094 6094 RTCList<MediumTaskChain> llMedias; 6095 RTCList< std::pair<Utf8Str, Utf8Str> > llSaveStateFiles; /* Snapshot UUID -> File path */ 6095 typedef struct 6096 { 6097 Guid snapshotUuid; 6098 Utf8Str strSaveStateFile; 6099 uint64_t cbSize; 6100 }SaveStateTask; 6101 RTCList<SaveStateTask> llSaveStateFiles; /* Snapshot UUID -> File path */ 6096 6102 }; 6097 6103 … … 6123 6129 6124 6130 if (pTask->pSrcMachine->isSnapshotMachine()) 6125 pTask->snapshotId = static_cast<SnapshotMachine*>((Machine*)pTask->pSrcMachine)->getSnapshotId();6131 pTask->snapshotId = pTask->pSrcMachine->getSnapshotId(); 6126 6132 6127 6133 /* Add the current machine and all snapshot machines below this machine 6128 6134 * in a list for further processing. */ 6129 RTCList< Com Ptr<IMachine> > machineList;6135 RTCList< ComObjPtr<Machine> > machineList; 6130 6136 6131 6137 /* Include current state? */ 6132 if ( pTask->mode == CloneMode_MachineState 6133 || pTask->mode == CloneMode_AllStates)6134 machineList.append( static_cast< ComPtr<IMachine> >(pTask->pSrcMachine));6138 if ( pTask->mode == CloneMode_MachineState) 6139 // || pTask->mode == CloneMode_AllStates) 6140 machineList.append(pTask->pSrcMachine); 6135 6141 /* Should be done a depth copy with all child snapshots? */ 6136 6142 if ( pTask->mode == CloneMode_MachineAndChildStates … … 6161 6167 for (size_t i = 0; i < machineList.size(); ++i) 6162 6168 { 6169 ComObjPtr<Machine> machine = machineList.at(i); 6163 6170 /* If this is the Snapshot Machine we want to clone, we need to 6164 6171 * create a new diff file for the new "current state". */ 6165 6172 bool fCreateDiffs = false; 6166 if (machine List.at(i)== pTask->pOldMachineState)6173 if (machine == pTask->pOldMachineState) 6167 6174 fCreateDiffs = true; 6168 6175 SafeIfaceArray<IMediumAttachment> sfaAttachments; 6169 rc = machine List.at(i)->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(sfaAttachments));6176 rc = machine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(sfaAttachments)); 6170 6177 if (FAILED(rc)) throw rc; 6171 6178 /* Add all attachments (and there parents) of the different … … 6220 6227 pTask->llMedias.append(mtc); 6221 6228 } 6222 /* Todo: If this machine has save state files, they have to be copied as well. */ 6223 // Bstr bstrSrcSaveStatePath; 6224 // rc = machineList.at(i)->COMGETTER(StateFilePath)(bstrSrcSaveStatePath.asOutParam()); 6225 // if (FAILED(rc)) throw rc; 6226 // if (!bstrSrcSaveStatePath.isEmpty()) 6227 // pTask->llSaveStates.append(bstrSrcSaveStatePath); 6229 Bstr bstrSrcSaveStatePath; 6230 rc = machine->COMGETTER(StateFilePath)(bstrSrcSaveStatePath.asOutParam()); 6231 if (FAILED(rc)) throw rc; 6232 if (!bstrSrcSaveStatePath.isEmpty()) 6233 { 6234 Machine::CloneVMTask::SaveStateTask sst; 6235 sst.snapshotUuid = machine->getSnapshotId(); 6236 sst.strSaveStateFile = bstrSrcSaveStatePath; 6237 int vrc = RTFileQuerySize(sst.strSaveStateFile.c_str(), &sst.cbSize); 6238 if (RT_FAILURE(vrc)) 6239 throw setError(VBOX_E_IPRT_ERROR, tr("Could not query file size of '%s' (%Rrc)"), sst.strSaveStateFile.c_str(), vrc); 6240 pTask->llSaveStateFiles.append(sst); 6241 ++uCount; 6242 uTotalWeight += sst.cbSize; 6243 } 6228 6244 } 6229 6245 … … 6248 6264 "MachineClone"); 6249 6265 if (RT_FAILURE(vrc)) 6250 throw setError( E_FAIL, "Could not create Machine clone thread (%Rrc)", vrc);6266 throw setError(VBOX_E_IPRT_ERROR, "Could not create machine clone thread (%Rrc)", vrc); 6251 6267 } 6252 6268 catch (HRESULT rc2) … … 6293 6309 } 6294 6310 6295 HRESULT Machine::cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< Com Ptr<IMachine> > &machineList) const6311 HRESULT Machine::cloneCreateMachineList(const ComPtr<ISnapshot> &pSnapshot, RTCList< ComObjPtr<Machine> > &machineList) const 6296 6312 { 6297 6313 HRESULT rc = S_OK; … … 6303 6319 rc = pSnapshot->COMGETTER(Machine)(pMachine.asOutParam()); 6304 6320 if (FAILED(rc)) return rc; 6305 machineList.append( pMachine);6321 machineList.append((Machine*)(IMachine*)pMachine); 6306 6322 6307 6323 SafeIfaceArray<ISnapshot> sfaChilds; … … 6363 6379 cloneUpdateSnapshotStorageLists(it->llChildSnapshots, bstrOldId, bstrNewId); 6364 6380 } 6381 } 6382 6383 void Machine::cloneUpdateStateFile(settings::SnapshotsList &snl, const Guid &id, const Utf8Str &strFile) const 6384 { 6385 settings::SnapshotsList::iterator it; 6386 for (it = snl.begin(); it != snl.end(); ++it) 6387 { 6388 if (it->uuid == id) 6389 it->strStateFile = strFile; 6390 else if (!it->llChildSnapshots.empty()) 6391 cloneUpdateStateFile(it->llChildSnapshots, id, strFile); 6392 } 6393 } 6394 6395 /* static */ 6396 int Machine::cloneCopyStateFileProgress(unsigned uPercentage, void *pvUser) 6397 { 6398 ComObjPtr<Progress> pProgress = *static_cast< ComObjPtr<Progress>* >(pvUser); 6399 6400 BOOL fCanceled = false; 6401 HRESULT rc = pProgress->COMGETTER(Canceled)(&fCanceled); 6402 if (FAILED(rc)) return VERR_GENERAL_FAILURE; 6403 /* If canceled by the user tell it to the copy operation. */ 6404 if (fCanceled) return VERR_CANCELLED; 6405 /* Set the new process. */ 6406 RTPrintf("stat %d %%\n", uPercentage); 6407 rc = pProgress->SetCurrentOperationProgress(uPercentage); 6408 if (FAILED(rc)) return VERR_GENERAL_FAILURE; 6409 6410 return VINF_SUCCESS; 6365 6411 } 6366 6412 … … 6378 6424 AutoWriteLock trgLock(pTask->pTrgMachine COMMA_LOCKVAL_SRC_POS); 6379 6425 6380 HRESULTrc = S_OK;6426 MultiResult rc = S_OK; 6381 6427 6382 6428 /* … … 6396 6442 6397 6443 RTCList< ComObjPtr<Medium> > newMedias; /* All created images */ 6444 RTCList<Utf8Str> newFiles; /* All extra created files (save states, ...) */ 6398 6445 try 6399 6446 { … … 6436 6483 } 6437 6484 6438 /* Reset the snapshot folder to 'Snapshots' within the target directory. 6439 * Todo: Not sure if this is what we want. */ 6440 pTrgMCF->machineUserData.strSnapshotFolder = "Snapshots"; 6485 /* When the current snapshot folder is absolute we reset it to the 6486 * default relative folder. */ 6487 if (RTPathStartsWithRoot(pTrgMCF->machineUserData.strSnapshotFolder.c_str())) 6488 pTrgMCF->machineUserData.strSnapshotFolder = "Snapshots"; 6441 6489 pTrgMCF->strStateFile = ""; 6442 6490 /* Force writing of setting file. */ … … 6446 6494 pTrgMCF->uuid = pTask->pTrgMachine->mData->mUuid; 6447 6495 6496 Bstr bstrSrcSnapshotFolder; 6497 rc = pTask->pSrcMachine->COMGETTER(SnapshotFolder)(bstrSrcSnapshotFolder.asOutParam()); 6498 if (FAILED(rc)) throw rc; 6448 6499 /* The absolute name of the snapshot folder. */ 6449 6500 Utf8Str strTrgSnapshotFolder = Utf8StrFmt("%s%c%s%c", strTrgMachineFolder.c_str(), RTPATH_DELIMITER, pTrgMCF->machineUserData.strSnapshotFolder.c_str(), RTPATH_DELIMITER); … … 6593 6644 cloneUpdateSnapshotStorageLists(pTrgMCF->llFirstSnapshot, bstrSrcId, bstrTrgId); 6594 6645 } 6595 /* Todo: Clone all save state files. */ 6596 // for (size_t i = 0; i < pTask->llSaveStates.size(); ++i) 6597 // { 6598 // RTPrintf("save state: %s\n", pTask->llSaveStates.at(i).c_str()); 6599 // RTFileCopy(llSaveStates.at(i).c_str(),); 6600 // } 6646 /* Clone all save state files. */ 6647 for (size_t i = 0; i < pTask->llSaveStateFiles.size(); ++i) 6648 { 6649 Machine::CloneVMTask::SaveStateTask sst = pTask->llSaveStateFiles.at(i); 6650 const Utf8Str &strTrgSaveState = Utf8StrFmt("%s%s", strTrgSnapshotFolder.c_str(), RTPathFilename(sst.strSaveStateFile.c_str())); 6651 6652 /* Move to next sub-operation. */ 6653 rc = pTask->pProgress->SetNextOperation(BstrFmt(tr("Copy save state file '%s' ..."), RTPathFilename(sst.strSaveStateFile.c_str())).raw(), sst.cbSize); 6654 if (FAILED(rc)) throw rc; 6655 /* Copy the file only if it was not copied already. */ 6656 if (!newFiles.contains(strTrgSaveState.c_str())) 6657 { 6658 int vrc = RTFileCopyEx(sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), 0, cloneCopyStateFileProgress, &pTask->pProgress); 6659 if (RT_FAILURE(vrc)) 6660 throw setError(VBOX_E_IPRT_ERROR, 6661 tr("Could not copy state file '%s' to '%s' (%Rrc)"), sst.strSaveStateFile.c_str(), strTrgSaveState.c_str(), vrc); 6662 newFiles.append(strTrgSaveState); 6663 } 6664 /* Update the path in the configuration either for the current 6665 * machine state or the snapshots. */ 6666 if (sst.snapshotUuid.isEmpty()) 6667 pTrgMCF->strStateFile = strTrgSaveState; 6668 else 6669 cloneUpdateStateFile(pTrgMCF->llFirstSnapshot, sst.snapshotUuid, strTrgSaveState); 6670 } 6601 6671 6602 6672 if (false) … … 6691 6761 if (FAILED(rc)) 6692 6762 { 6763 int vrc = VINF_SUCCESS; 6764 /* Delete all created files. */ 6765 for (size_t i = 0; i < newFiles.size(); ++i) 6766 { 6767 vrc = RTFileDelete(newFiles.at(i).c_str()); 6768 if (RT_FAILURE(vrc)) 6769 rc = setError(VBOX_E_IPRT_ERROR, tr("Could not delete file '%s' (%Rrc)"), newFiles.at(i).c_str(), vrc); 6770 } 6693 6771 /* Delete all already created medias. (Reverse, cause there could be 6694 6772 * parent->child relations.) */ … … 6697 6775 ComObjPtr<Medium> &pMedium = newMedias.at(i - 1); 6698 6776 AutoCaller mac(pMedium); 6699 if (FAILED(mac.rc())) return mac.rc();6777 if (FAILED(mac.rc())) { continue; rc = mac.rc(); } 6700 6778 AutoReadLock mlock(pMedium COMMA_LOCKVAL_SRC_POS); 6701 6779 bool fFile = pMedium->isMediumFormatFile(); … … 6704 6782 /* Close the medium. If this succeed, delete it finally from the 6705 6783 * disk. */ 6706 HRESULT rc1 = pMedium->close(NULL, mac); 6707 if ( SUCCEEDED(rc1) 6708 && fFile) 6709 RTFileDelete(strLoc.c_str()); 6784 rc = pMedium->close(NULL, mac); 6785 if (FAILED(rc)) continue; 6786 if (fFile) 6787 { 6788 vrc = RTFileDelete(strLoc.c_str()); 6789 if (RT_FAILURE(vrc)) 6790 rc = setError(VBOX_E_IPRT_ERROR, tr("Could not delete file '%s' (%Rrc)"), strLoc.c_str(), vrc); 6791 } 6710 6792 } 6711 6793 /* Delete the machine folder when not empty. */
Note:
See TracChangeset
for help on using the changeset viewer.