Changeset 97864 in vbox
- Timestamp:
- Dec 23, 2022 9:25:48 PM (21 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
-
doc/manual/en_US/man_VBoxManage-clonemedium.xml (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp (modified) (4 diffs)
-
src/VBox/Main/idl/VirtualBox.xidl (modified) (2 diffs)
-
src/VBox/Main/include/MediumImpl.h (modified) (1 diff)
-
src/VBox/Main/src-server/MediumImpl.cpp (modified) (10 diffs)
-
src/VBox/ValidationKit/tests/api/tdApi1.py (modified) (1 diff)
-
src/VBox/ValidationKit/tests/api/tdCloneMedium1.py (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/manual/en_US/man_VBoxManage-clonemedium.xml
r97033 r97864 64 64 </group> 65 65 <arg>--existing</arg> 66 <arg>--resize=<replaceable>size-in-MB</replaceable></arg> 66 67 <arg>--format=<group choice="plain"> 67 68 <arg choice="plain">VDI</arg> … … 134 135 </varlistentry> 135 136 <varlistentry> 137 <term><option>--resize=<replaceable>size-in-MB</replaceable></option></term> 138 <listitem><para> 139 Performs a resize of the target medium to the specified 140 size before performing the clone operation. 141 </para></listitem> 142 </varlistentry> 143 <varlistentry> 136 144 <term><option>--format</option></term> 137 145 <listitem><para> -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
r97313 r97864 1005 1005 { "--variant", 'm', RTGETOPT_REQ_STRING }, 1006 1006 { "-variant", 'm', RTGETOPT_REQ_STRING }, 1007 { "--resize", 'r', RTGETOPT_REQ_UINT64 }, 1007 1008 }; 1008 1009 … … 1022 1023 MediumVariant_T enmMediumVariant = MediumVariant_Standard; 1023 1024 bool fExisting = false; 1025 bool fNeedResize = false; 1026 uint64_t cbResize = 0; 1024 1027 1025 1028 int c; … … 1071 1074 if (RT_FAILURE(vrc)) 1072 1075 return errorArgument(Disk::tr("Invalid medium variant '%s'"), ValueUnion.psz); 1076 break; 1077 1078 case 'r': // --resize 1079 fNeedResize = true; 1080 cbResize = ValueUnion.u64 * _1M; 1073 1081 break; 1074 1082 … … 1191 1199 } 1192 1200 1193 CHECK_ERROR_BREAK(pSrcMedium, CloneTo(pDstMedium, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam())); 1201 if (fNeedResize) 1202 { 1203 CHECK_ERROR_BREAK(pSrcMedium, ResizeAndCloneTo(pDstMedium, cbResize, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam())); 1204 } 1205 else 1206 { 1207 CHECK_ERROR_BREAK(pSrcMedium, CloneTo(pDstMedium, ComSafeArrayAsInParam(l_variants), NULL, pProgress.asOutParam())); 1208 } 1209 1194 1210 1195 1211 hrc = showProgress(pProgress); -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r97719 r97864 18126 18126 <interface 18127 18127 name="IMedium" extends="$unknown" 18128 uuid=" ad47ad09-787b-44ab-b343-a082a3f2dfb1"18128 uuid="dbe1d807-5fa1-482f-9121-37b8fd855348" 18129 18129 wsmap="managed" 18130 18130 rest="managed" … … 19212 19212 <param name="target" type="IMedium" dir="in"> 19213 19213 <desc>Target medium.</desc> 19214 </param> 19215 <param name="variant" type="MediumVariant" safearray="yes" dir="in"> 19216 <desc>Exact image variant which should be created (as a combination of 19217 <link to="MediumVariant" /> flags).</desc> 19218 </param> 19219 <param name="parent" type="IMedium" dir="in"> 19220 <desc>Parent of the cloned medium.</desc> 19221 </param> 19222 <param name="progress" type="IProgress" dir="return"> 19223 <desc>Progress object to track the operation completion.</desc> 19224 </param> 19225 </method> 19226 19227 <method name="resizeAndCloneTo"> 19228 <rest request="post" path="/mediums/{mediumid}/actions/"/> 19229 19230 <desc> 19231 This is a helper function that combines the functionality of 19232 <link to="IMedium::cloneTo"/> and <link to="IMedium::resize"/>. The target medium will take the 19233 contents of the calling medium. 19234 <result name="E_NOTIMPL"> 19235 The specified cloning variant is not supported at the moment. 19236 </result> 19237 </desc> 19238 19239 <param name="target" type="IMedium" dir="in"> 19240 <desc>Target medium.</desc> 19241 </param> 19242 <param name="logicalSize" type="long long" dir="in"> 19243 <desc>New nominal capacity of the medium in bytes.</desc> 19214 19244 </param> 19215 19245 <param name="variant" type="MediumVariant" safearray="yes" dir="in"> -
trunk/src/VBox/Main/include/MediumImpl.h
r96407 r97864 317 317 const ComPtr<IMedium> &aParent, 318 318 ComPtr<IProgress> &aProgress); 319 HRESULT resizeAndCloneTo(const ComPtr<IMedium> &aTarget, 320 const LONG64 aLogicalSize, 321 const std::vector<MediumVariant_T> &aVariant, 322 const ComPtr<IMedium> &aParent, 323 ComPtr<IProgress> &aProgress); 319 324 HRESULT cloneToBase(const ComPtr<IMedium> &aTarget, 320 325 const std::vector<MediumVariant_T> &aVariant, -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r97367 r97864 497 497 bool fKeepSourceMediumLockList = false, 498 498 bool fKeepTargetMediumLockList = false, 499 bool fNotifyAboutChanges = true) 499 bool fNotifyAboutChanges = true, 500 LONG64 aTargetLogicalSize = 0) 500 501 : Medium::Task(aMedium, aProgress, fNotifyAboutChanges), 501 502 mTarget(aTarget), 502 503 mParent(aParent), 504 mTargetLogicalSize(aTargetLogicalSize), 503 505 mpSourceMediumLockList(aSourceMediumLockList), 504 506 mpTargetMediumLockList(aTargetMediumLockList), … … 510 512 mfKeepSourceMediumLockList(fKeepSourceMediumLockList), 511 513 mfKeepTargetMediumLockList(fKeepTargetMediumLockList) 514 512 515 { 513 516 AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL); … … 534 537 const ComObjPtr<Medium> mTarget; 535 538 const ComObjPtr<Medium> mParent; 539 LONG64 mTargetLogicalSize; 536 540 MediumLockList *mpSourceMediumLockList; 537 541 MediumLockList *mpTargetMediumLockList; … … 3020 3024 ComPtr<IProgress> &aProgress) 3021 3025 { 3022 /** @todo r=klaus The code below needs to be double checked with regard 3023 * to lock order violations, it probably causes lock order issues related 3024 * to the AutoCaller usage. */ 3026 return resizeAndCloneTo(aTarget, 0, aVariant, aParent, aProgress); 3027 } 3028 3029 /** 3030 * This is a helper function that combines the functionality of 3031 * Medium::cloneTo() and Medium::resize(). The target medium will take the 3032 * contents of the calling medium. 3033 * 3034 * @param aTarget Medium to resize and clone to 3035 * @param aLogicalSize Desired size for targer medium 3036 * @param aVariant 3037 * @param aParent 3038 * @param aProgress 3039 * @return HRESULT 3040 */ 3041 HRESULT Medium::resizeAndCloneTo(const ComPtr<IMedium> &aTarget, 3042 const LONG64 aLogicalSize, 3043 const std::vector<MediumVariant_T> &aVariant, 3044 const ComPtr<IMedium> &aParent, 3045 ComPtr<IProgress> &aProgress) 3046 { 3047 /* Check for valid args */ 3025 3048 ComAssertRet(aTarget != this, E_INVALIDARG); 3026 3049 CheckComArgExpr(aLogicalSize, aLogicalSize >= 0); 3050 3051 /* Convert args to usable/needed types */ 3027 3052 IMedium *aT = aTarget; 3028 3053 ComObjPtr<Medium> pTarget = static_cast<Medium*>(aT); … … 3034 3059 } 3035 3060 3061 /* Set up variables. Fetch needed data in lockable blocks */ 3036 3062 HRESULT rc = S_OK; 3063 ComObjPtr<Progress> pTmpProgress; 3064 Medium::Task *pTask = NULL; 3065 3066 Utf8Str strSourceName; 3067 { 3068 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 3069 strSourceName = i_getName(); 3070 } 3071 3072 uint64_t uTargetExistingSize = 0; 3073 Utf8Str strTargetName; 3074 { 3075 AutoReadLock alock(pTarget COMMA_LOCKVAL_SRC_POS); 3076 uTargetExistingSize = pTarget->i_getLogicalSize(); 3077 strTargetName = pTarget->i_getName(); 3078 } 3079 3080 /* Set up internal multi-subprocess progress object */ 3037 3081 ComObjPtr<Progress> pProgress; 3038 Medium::Task *pTask = NULL; 3082 pProgress.createObject(); 3083 rc = pProgress->init(m->pVirtualBox, 3084 static_cast<IMedium*>(this), 3085 BstrFmt(tr("Resizing medium and cloning into it")).raw(), 3086 TRUE, /* aCancelable */ 3087 2, /* Number of opearations */ 3088 BstrFmt(tr("Resizing medium before clone")).raw() 3089 ); 3090 3091 if (FAILED(rc)) 3092 throw rc; 3093 3094 /* If target does not exist, handle resize. */ 3095 if (pTarget->m->state != MediumState_NotCreated && aLogicalSize > 0) 3096 { 3097 if ((LONG64)uTargetExistingSize != aLogicalSize) { 3098 if (!i_isMediumFormatFile()) 3099 { 3100 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3101 rc = setError(VBOX_E_NOT_SUPPORTED, 3102 tr("Sizes of '%s' and '%s' are different and \ 3103 medium format does not support resing"), 3104 strSourceName.c_str(), strTargetName.c_str()); 3105 throw rc; 3106 } 3107 3108 /** 3109 * Need to lock the target medium as i_resize does do so 3110 * automatically. 3111 */ 3112 3113 ComPtr<IToken> pToken; 3114 rc = pTarget->LockWrite(pToken.asOutParam()); 3115 3116 if (FAILED(rc)) throw rc; 3117 3118 /** 3119 * Have to make own lock list, because "resize" method resizes only 3120 * last image in the lock chain. 3121 */ 3122 3123 MediumLockList* pMediumLockListForResize = new MediumLockList(); 3124 pMediumLockListForResize->Append(pTarget, pTarget->m->state == MediumState_LockedWrite); 3125 3126 rc = pMediumLockListForResize->Lock(true /* fSkipOverLockedMedia */); 3127 3128 if (FAILED(rc)) 3129 { 3130 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3131 rc = setError(rc, 3132 tr("Failed to lock the medium '%s' to resize before merge"), 3133 strTargetName.c_str()); 3134 delete pMediumLockListForResize; 3135 throw rc; 3136 } 3137 3138 3139 rc = pTarget->i_resize((uint64_t)aLogicalSize, pMediumLockListForResize, &pProgress, true, false); 3140 3141 if (FAILED(rc)) 3142 { 3143 /* No need to setError becasue i_resize and i_taskResizeHandler handle this automatically. */ 3144 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3145 delete pMediumLockListForResize; 3146 throw rc; 3147 } 3148 3149 delete pMediumLockListForResize; 3150 3151 pTarget->m->logicalSize = aLogicalSize; 3152 3153 pToken->Abandon(); 3154 pToken.setNull(); 3155 } 3156 } 3157 3158 /* Report progress to supplied progress argument */ 3159 if (SUCCEEDED(rc)) 3160 { 3161 pProgress.queryInterfaceTo(aProgress.asOutParam()); 3162 } 3039 3163 3040 3164 try … … 3111 3235 } 3112 3236 3113 pProgress.createObject();3114 rc = pProgress->init(m->pVirtualBox,3115 static_cast <IMedium *>(this),3116 BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.c_str()).raw(),3117 TRUE /* aCancelable */);3118 if (FAILED(rc))3119 {3120 delete pSourceMediumLockList;3121 delete pTargetMediumLockList;3122 throw rc;3123 }3124 3125 3237 ULONG mediumVariantFlags = 0; 3126 3238 … … 3139 3251 } 3140 3252 3141 /* setup task object to carry out the operation asynchronously */ 3142 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3143 (MediumVariant_T)mediumVariantFlags, 3144 pParent, UINT32_MAX, UINT32_MAX, 3145 pSourceMediumLockList, pTargetMediumLockList); 3253 if (pTarget->m->state != MediumState_NotCreated || aLogicalSize == 0) 3254 { 3255 /* setup task object to carry out the operation asynchronously */ 3256 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3257 (MediumVariant_T)mediumVariantFlags, 3258 pParent, UINT32_MAX, UINT32_MAX, 3259 pSourceMediumLockList, pTargetMediumLockList, 3260 false, false, true, 0); 3261 } 3262 else 3263 { 3264 /* setup task object to carry out the operation asynchronously */ 3265 pTask = new Medium::CloneTask(this, pProgress, pTarget, 3266 (MediumVariant_T)mediumVariantFlags, 3267 pParent, UINT32_MAX, UINT32_MAX, 3268 pSourceMediumLockList, pTargetMediumLockList, 3269 false, false, true, aLogicalSize); 3270 } 3271 3146 3272 rc = pTask->rc(); 3147 3273 AssertComRC(rc); … … 3161 3287 pProgress.queryInterfaceTo(aProgress.asOutParam()); 3162 3288 } 3163 else if (pTask != NULL) 3289 else if (pTask != NULL) { 3164 3290 delete pTask; 3291 throw rc; 3292 } 3165 3293 3166 3294 return rc; … … 9647 9775 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9648 9776 false /* fMoveByRename */, 9649 0/* cbSize */,9777 (uint64_t) task.mTargetLogicalSize /* cbSize */, 9650 9778 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted), 9651 9779 targetId.raw(), … … 9663 9791 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9664 9792 false /* fMoveByRename */, 9665 0/* cbSize */,9793 (uint64_t) task.mTargetLogicalSize /* cbSize */, 9666 9794 task.midxSrcImageSame, 9667 9795 task.midxDstImageSame, -
trunk/src/VBox/ValidationKit/tests/api/tdApi1.py
r96407 r97864 95 95 from tdTreeDepth1 import SubTstDrvTreeDepth1; # pylint: disable=relative-import 96 96 from tdMoveVm1 import SubTstDrvMoveVm1; # pylint: disable=relative-import 97 from tdCloneMedium1 import SubTstDrvCloneMedium1;# pylint: disable=relative-import 97 98 sys.exit(tdApi1([SubTstDrvPython1, SubTstDrvAppliance1, SubTstDrvMoveMedium1, 98 SubTstDrvTreeDepth1, SubTstDrvMoveVm1]).main(sys.argv)) 99 99 SubTstDrvTreeDepth1, SubTstDrvMoveVm1, SubTstDrvCloneMedium1]).main(sys.argv))
Note:
See TracChangeset
for help on using the changeset viewer.

