Changeset 38308 in vbox
- Timestamp:
- Aug 4, 2011 9:29:51 AM (13 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/MediumImpl.h
r37900 r38308 263 263 const ComObjPtr<Progress> &aProgress); 264 264 265 HRESULT cloneToEx(const ComObjPtr<Medium> &aTarget, ULONG aVariant, 266 const ComObjPtr<Medium> &aParent, const ComObjPtr<Progress> &aProgress, 267 uint32_t idxSrcImageSame, uint32_t idxDstImageSame); 268 265 269 private: 266 270 -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r37985 r38308 341 341 MediumVariant_T aVariant, 342 342 Medium *aParent, 343 uint32_t idxSrcImageSame, 344 uint32_t idxDstImageSame, 343 345 MediumLockList *aSourceMediumLockList, 344 346 MediumLockList *aTargetMediumLockList, … … 351 353 mpTargetMediumLockList(aTargetMediumLockList), 352 354 mVariant(aVariant), 355 midxSrcImageSame(idxSrcImageSame), 356 midxDstImageSame(idxDstImageSame), 353 357 mTargetCaller(aTarget), 354 358 mParentCaller(aParent), … … 381 385 MediumLockList *mpTargetMediumLockList; 382 386 MediumVariant_T mVariant; 387 uint32_t midxSrcImageSame; 388 uint32_t midxDstImageSame; 383 389 384 390 private: … … 2697 2703 pTask = new Medium::CloneTask(this, pProgress, pTarget, 2698 2704 (MediumVariant_T)aVariant, 2699 pParent, pSourceMediumLockList,2700 p TargetMediumLockList);2705 pParent, UINT32_MAX, UINT32_MAX, 2706 pSourceMediumLockList, pTargetMediumLockList); 2701 2707 rc = pTask->rc(); 2702 2708 AssertComRC(rc); … … 5061 5067 if (m->state == MediumState_NotCreated) 5062 5068 m->state = MediumState_Creating; 5069 } 5070 catch (HRESULT aRC) { rc = aRC; } 5071 5072 if (SUCCEEDED(rc)) 5073 rc = startThread(pTask); 5074 else if (pTask != NULL) 5075 delete pTask; 5076 5077 return rc; 5078 } 5079 5080 /** 5081 * Internal version of the public CloneTo API which allows to enable certain 5082 * optimizations to improve speed during VM cloning. 5083 * 5084 * @param aTarget Target medium 5085 * @param aVariant Which exact image format variant to use 5086 * for the destination image. 5087 * @param aParent Parent medium. May be NULL. 5088 * @param aProgress Progress object to use. 5089 * @param idxSrcImageSame The last image in the source chain which has the 5090 * same content as the given image in the destination 5091 * chain. Use UINT32_MAX to disable this optimization. 5092 * @param idxDstImageSame The last image in the destination chain which has the 5093 * same content as the given image in the source chain. 5094 * Use UINT32_MAX to disable this optimization. 5095 * @return 5096 */ 5097 HRESULT Medium::cloneToEx(const ComObjPtr<Medium> &aTarget, ULONG aVariant, 5098 const ComObjPtr<Medium> &aParent, const ComObjPtr<Progress> &aProgress, 5099 uint32_t idxSrcImageSame, uint32_t idxDstImageSame) 5100 { 5101 CheckComArgNotNull(aTarget); 5102 AssertReturn(!aProgress.isNull(), E_INVALIDARG); 5103 ComAssertRet(aTarget != this, E_INVALIDARG); 5104 5105 AutoCaller autoCaller(this); 5106 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 5107 5108 HRESULT rc = S_OK; 5109 ComObjPtr<Progress> pProgress; 5110 Medium::Task *pTask = NULL; 5111 5112 try 5113 { 5114 // locking: we need the tree lock first because we access parent pointers 5115 AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); 5116 // and we need to write-lock the media involved 5117 AutoMultiWriteLock3 alock(this, aTarget, aParent COMMA_LOCKVAL_SRC_POS); 5118 5119 if ( aTarget->m->state != MediumState_NotCreated 5120 && aTarget->m->state != MediumState_Created) 5121 throw aTarget->setStateError(); 5122 5123 /* Build the source lock list. */ 5124 MediumLockList *pSourceMediumLockList(new MediumLockList()); 5125 rc = createMediumLockList(true /* fFailIfInaccessible */, 5126 false /* fMediumLockWrite */, 5127 NULL, 5128 *pSourceMediumLockList); 5129 if (FAILED(rc)) 5130 { 5131 delete pSourceMediumLockList; 5132 throw rc; 5133 } 5134 5135 /* Build the target lock list (including the to-be parent chain). */ 5136 MediumLockList *pTargetMediumLockList(new MediumLockList()); 5137 rc = aTarget->createMediumLockList(true /* fFailIfInaccessible */, 5138 true /* fMediumLockWrite */, 5139 aParent, 5140 *pTargetMediumLockList); 5141 if (FAILED(rc)) 5142 { 5143 delete pSourceMediumLockList; 5144 delete pTargetMediumLockList; 5145 throw rc; 5146 } 5147 5148 rc = pSourceMediumLockList->Lock(); 5149 if (FAILED(rc)) 5150 { 5151 delete pSourceMediumLockList; 5152 delete pTargetMediumLockList; 5153 throw setError(rc, 5154 tr("Failed to lock source media '%s'"), 5155 getLocationFull().c_str()); 5156 } 5157 rc = pTargetMediumLockList->Lock(); 5158 if (FAILED(rc)) 5159 { 5160 delete pSourceMediumLockList; 5161 delete pTargetMediumLockList; 5162 throw setError(rc, 5163 tr("Failed to lock target media '%s'"), 5164 aTarget->getLocationFull().c_str()); 5165 } 5166 5167 pProgress.createObject(); 5168 rc = pProgress->init(m->pVirtualBox, 5169 static_cast <IMedium *>(this), 5170 BstrFmt(tr("Creating clone medium '%s'"), aTarget->m->strLocationFull.c_str()).raw(), 5171 TRUE /* aCancelable */); 5172 if (FAILED(rc)) 5173 { 5174 delete pSourceMediumLockList; 5175 delete pTargetMediumLockList; 5176 throw rc; 5177 } 5178 5179 /* setup task object to carry out the operation asynchronously */ 5180 pTask = new Medium::CloneTask(this, aProgress, aTarget, 5181 (MediumVariant_T)aVariant, 5182 aParent, idxSrcImageSame, 5183 idxDstImageSame, pSourceMediumLockList, 5184 pTargetMediumLockList); 5185 rc = pTask->rc(); 5186 AssertComRC(rc); 5187 if (FAILED(rc)) 5188 throw rc; 5189 5190 if (aTarget->m->state == MediumState_NotCreated) 5191 aTarget->m->state = MediumState_Creating; 5063 5192 } 5064 5193 catch (HRESULT aRC) { rc = aRC; } … … 6971 7100 6972 7101 /** @todo r=klaus target isn't locked, race getting the state */ 6973 vrc = VDCopy(hdd, 6974 VD_LAST_IMAGE, 6975 targetHdd, 6976 targetFormat.c_str(), 6977 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 6978 false /* fMoveByRename */, 6979 0 /* cbSize */, 6980 task.mVariant, 6981 targetId.raw(), 6982 VD_OPEN_FLAGS_NORMAL, 6983 NULL /* pVDIfsOperation */, 6984 pTarget->m->vdImageIfaces, 6985 task.mVDOperationIfaces); 7102 if (task.midxSrcImageSame == UINT32_MAX) 7103 { 7104 vrc = VDCopy(hdd, 7105 VD_LAST_IMAGE, 7106 targetHdd, 7107 targetFormat.c_str(), 7108 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 7109 false /* fMoveByRename */, 7110 0 /* cbSize */, 7111 task.mVariant, 7112 targetId.raw(), 7113 VD_OPEN_FLAGS_NORMAL, 7114 NULL /* pVDIfsOperation */, 7115 pTarget->m->vdImageIfaces, 7116 task.mVDOperationIfaces); 7117 } 7118 else 7119 { 7120 vrc = VDCopyEx(hdd, 7121 VD_LAST_IMAGE, 7122 targetHdd, 7123 targetFormat.c_str(), 7124 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 7125 false /* fMoveByRename */, 7126 0 /* cbSize */, 7127 task.midxSrcImageSame, 7128 task.midxDstImageSame, 7129 task.mVariant, 7130 targetId.raw(), 7131 VD_OPEN_FLAGS_NORMAL, 7132 NULL /* pVDIfsOperation */, 7133 pTarget->m->vdImageIfaces, 7134 task.mVDOperationIfaces); 7135 } 6986 7136 if (RT_FAILURE(vrc)) 6987 7137 throw setError(VBOX_E_FILE_ERROR,
Note:
See TracChangeset
for help on using the changeset viewer.