- Timestamp:
- Jun 6, 2023 5:15:22 AM (21 months ago)
- svn:sync-xref-src-repo-rev:
- 157767
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vd.h
r99739 r100078 765 765 * 766 766 * @param pDiskFrom Pointer to source HDD container. 767 * @param nImage Image number, counts from 0. 0 is always base image 768 * of container. 767 * @param nImageFrom Image number to copy from, counts from 0. 0 is always base image of container. 769 768 * @param pDiskTo Pointer to destination HDD container. 769 * @param nImageTo Image number to copy to, counts from 0. 0 is always base image of container. 770 770 * @param pszBackend Name of the image file backend to use (may be NULL 771 771 * to use the same as the source, case insensitive). … … 822 822 * Setting both to 0 can suppress a lot of I/O. 823 823 */ 824 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImage , PVDISK pDiskTo,824 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImageFrom, PVDISK pDiskTo, unsigned nImageTo, 825 825 const char *pszBackend, const char *pszFilename, 826 826 bool fMoveByRename, uint64_t cbSize, … … 1842 1842 1843 1843 #endif /* !VBOX_INCLUDED_vd_h */ 1844 -
trunk/src/VBox/Main/src-server/MediumImpl.cpp
r99991 r100078 3169 3169 throw pTarget->i_setStateError(); 3170 3170 3171 /* Determine if cloning within the list */ 3172 bool cloningWithinList = false; 3173 ComObjPtr<Medium> pMedium = i_getParent(); 3174 while (!pMedium.isNull() && pMedium != pTarget) 3175 pMedium = pMedium->i_getParent(); 3176 if (pMedium == pTarget) 3177 cloningWithinList = true; 3178 3171 3179 /* Build the source lock list. */ 3172 3180 MediumLockList *pSourceMediumLockList(new MediumLockList()); 3173 3181 alock.release(); 3174 hrc = i_createMediumLockList(true /* fFailIfInaccessible */, 3175 NULL /* pToLockWrite */, 3176 false /* fMediumLockWriteAll */, 3177 NULL, 3178 *pSourceMediumLockList); 3182 if (!cloningWithinList) 3183 hrc = i_createMediumLockList(true /* fFailIfInaccessible */, 3184 NULL /* pToLockWrite */, 3185 false /* fMediumLockWriteAll */, 3186 NULL, 3187 *pSourceMediumLockList); 3188 else 3189 hrc = i_createMediumLockList(true /* fFailIfInaccessible */, 3190 pTarget /* pToLockWrite */, 3191 false /* fMediumLockWriteAll */, 3192 NULL, 3193 *pSourceMediumLockList); 3179 3194 alock.acquire(); 3180 3195 if (FAILED(hrc)) … … 3187 3202 MediumLockList *pTargetMediumLockList(new MediumLockList()); 3188 3203 alock.release(); 3189 hrc = pTarget->i_createMediumLockList(true /* fFailIfInaccessible */, 3190 pTarget /* pToLockWrite */, 3191 false /* fMediumLockWriteAll */, 3192 pParent, 3193 *pTargetMediumLockList); 3204 if (!cloningWithinList) 3205 hrc = pTarget->i_createMediumLockList(true /* fFailIfInaccessible */, 3206 pTarget /* pToLockWrite */, 3207 false /* fMediumLockWriteAll */, 3208 pParent, 3209 *pTargetMediumLockList); 3194 3210 alock.acquire(); 3195 3211 if (FAILED(hrc)) … … 9567 9583 9568 9584 bool fCreatingTarget = false; 9585 bool cloningWithinList = false; 9586 unsigned uTargetIdx = VD_LAST_IMAGE; 9569 9587 9570 9588 uint64_t size = 0, logicalSize = 0; … … 9616 9634 MediumLockList::Base::const_iterator sourceListEnd = 9617 9635 task.mpSourceMediumLockList->GetEnd(); 9636 unsigned i=0; 9618 9637 for (MediumLockList::Base::const_iterator it = sourceListBegin; 9619 9638 it != sourceListEnd; … … 9622 9641 const MediumLock &mediumLock = *it; 9623 9642 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 9624 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 9625 9626 /* sanity check */ 9627 Assert(pMedium->m->state == MediumState_LockedRead); 9628 9629 /** Open all media in read-only mode. */ 9630 vrc = VDOpen(hdd, 9631 pMedium->m->strFormat.c_str(), 9632 pMedium->m->strLocationFull.c_str(), 9633 VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef, 9634 pMedium->m->vdImageIfaces); 9635 if (RT_FAILURE(vrc)) 9636 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9637 tr("Could not open the medium storage unit '%s'%s"), 9638 pMedium->m->strLocationFull.c_str(), 9639 i_vdError(vrc).c_str()); 9640 } 9641 9642 Utf8Str targetFormat(pTarget->m->strFormat); 9643 Utf8Str targetLocation(pTarget->m->strLocationFull); 9644 uint64_t capabilities = pTarget->m->formatObj->i_getCapabilities(); 9645 9646 Assert( pTarget->m->state == MediumState_Creating 9647 || pTarget->m->state == MediumState_LockedWrite); 9648 Assert(m->state == MediumState_LockedRead); 9649 Assert( pParent.isNull() 9650 || pParent->m->state == MediumState_LockedRead); 9651 9652 /* unlock before the potentially lengthy operation */ 9653 thisLock.release(); 9654 9655 /* ensure the target directory exists */ 9656 if (capabilities & MediumFormatCapabilities_File) 9657 { 9658 HRESULT hrc = VirtualBox::i_ensureFilePathExists(targetLocation, 9659 !(task.mVariant & MediumVariant_NoCreateDir) /* fCreate */); 9660 if (FAILED(hrc)) 9661 throw hrc; 9662 } 9663 9664 PVDISK targetHdd; 9665 vrc = VDCreate(m->vdDiskIfaces, i_convertDeviceType(), &targetHdd); 9666 ComAssertRCThrow(vrc, E_FAIL); 9667 9668 try 9669 { 9670 /* Open all media in the target chain. */ 9671 MediumLockList::Base::const_iterator targetListBegin = 9672 task.mpTargetMediumLockList->GetBegin(); 9673 MediumLockList::Base::const_iterator targetListEnd = 9674 task.mpTargetMediumLockList->GetEnd(); 9675 for (MediumLockList::Base::const_iterator it = targetListBegin; 9676 it != targetListEnd; 9677 ++it) 9643 if (pMedium == pTarget) 9678 9644 { 9679 const MediumLock &mediumLock = *it; 9680 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 9681 9682 /* If the target medium is not created yet there's no 9683 * reason to open it. */ 9684 if (pMedium == pTarget && fCreatingTarget) 9685 continue; 9686 9645 cloningWithinList = true; 9646 uTargetIdx = i; 9687 9647 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 9688 9689 /* sanity check */ 9690 Assert( pMedium->m->state == MediumState_LockedRead 9691 || pMedium->m->state == MediumState_LockedWrite); 9692 9648 Assert(pMedium->m->state == MediumState_LockedWrite); 9693 9649 unsigned uOpenFlags = VD_OPEN_FLAGS_NORMAL; 9694 if (pMedium->m->state != MediumState_LockedWrite)9695 uOpenFlags = VD_OPEN_FLAGS_READONLY;9696 9650 if (pMedium->m->type == MediumType_Shareable) 9697 9651 uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; 9698 9699 /* Open all media in appropriate mode. */ 9700 vrc = VDOpen(targetHdd, 9652 /* Open target in appropriate mode. */ 9653 vrc = VDOpen(hdd, 9701 9654 pMedium->m->strFormat.c_str(), 9702 9655 pMedium->m->strLocationFull.c_str(), … … 9709 9662 i_vdError(vrc).c_str()); 9710 9663 } 9711 9712 /* target isn't locked, but no changing data is accessed */ 9713 if (task.midxSrcImageSame == UINT32_MAX) 9664 i++; 9665 if (!cloningWithinList || pMedium != pTarget) 9714 9666 { 9715 vrc = VDCopy(hdd, 9716 VD_LAST_IMAGE, 9717 targetHdd, 9718 targetFormat.c_str(), 9719 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9720 false /* fMoveByRename */, 9721 task.mTargetLogicalSize /* cbSize */, 9722 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9723 targetId.raw(), 9724 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9725 NULL /* pVDIfsOperation */, 9726 pTarget->m->vdImageIfaces, 9727 task.mVDOperationIfaces); 9667 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 9668 /* sanity check */ 9669 Assert(pMedium->m->state == MediumState_LockedRead); 9670 /** Open all media in read-only mode. */ 9671 vrc = VDOpen(hdd, 9672 pMedium->m->strFormat.c_str(), 9673 pMedium->m->strLocationFull.c_str(), 9674 VD_OPEN_FLAGS_READONLY | m->uOpenFlagsDef, 9675 pMedium->m->vdImageIfaces); 9676 if (RT_FAILURE(vrc)) 9677 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9678 tr("Could not open the medium storage unit '%s'%s"), 9679 pMedium->m->strLocationFull.c_str(), 9680 i_vdError(vrc).c_str()); 9728 9681 } 9729 else 9682 } 9683 9684 Utf8Str targetFormat(pTarget->m->strFormat); 9685 Utf8Str targetLocation(pTarget->m->strLocationFull); 9686 uint64_t capabilities = pTarget->m->formatObj->i_getCapabilities(); 9687 9688 Assert( pTarget->m->state == MediumState_Creating 9689 || pTarget->m->state == MediumState_LockedWrite); 9690 Assert(m->state == MediumState_LockedRead); 9691 Assert( pParent.isNull() 9692 || pParent->m->state == MediumState_LockedRead); 9693 9694 /* unlock before the potentially lengthy operation */ 9695 thisLock.release(); 9696 9697 /* ensure the target directory exists */ 9698 if (capabilities & MediumFormatCapabilities_File) 9699 { 9700 HRESULT hrc = VirtualBox::i_ensureFilePathExists(targetLocation, 9701 !(task.mVariant & MediumVariant_NoCreateDir) /* fCreate */); 9702 if (FAILED(hrc)) 9703 throw hrc; 9704 } 9705 9706 PVDISK targetHdd; 9707 vrc = VDCreate(m->vdDiskIfaces, i_convertDeviceType(), &targetHdd); 9708 ComAssertRCThrow(vrc, E_FAIL); 9709 9710 try 9711 { 9712 if (!cloningWithinList) 9730 9713 { 9731 vrc = VDCopyEx(hdd, 9732 VD_LAST_IMAGE, 9733 targetHdd, 9734 targetFormat.c_str(), 9735 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9736 false /* fMoveByRename */, 9737 task.mTargetLogicalSize /* cbSize */, 9738 task.midxSrcImageSame, 9739 task.midxDstImageSame, 9740 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9741 targetId.raw(), 9742 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9743 NULL /* pVDIfsOperation */, 9744 pTarget->m->vdImageIfaces, 9745 task.mVDOperationIfaces); 9714 /* Open all media in the target chain. */ 9715 MediumLockList::Base::const_iterator targetListBegin = 9716 task.mpTargetMediumLockList->GetBegin(); 9717 MediumLockList::Base::const_iterator targetListEnd = 9718 task.mpTargetMediumLockList->GetEnd(); 9719 for (MediumLockList::Base::const_iterator it = targetListBegin; 9720 it != targetListEnd; 9721 ++it) 9722 { 9723 const MediumLock &mediumLock = *it; 9724 const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); 9725 /* If the target medium is not created yet there's no 9726 * reason to open it. */ 9727 if (pMedium == pTarget && fCreatingTarget) 9728 continue; 9729 AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); 9730 /* sanity check */ 9731 Assert( pMedium->m->state == MediumState_LockedRead 9732 || pMedium->m->state == MediumState_LockedWrite); 9733 unsigned uOpenFlags = VD_OPEN_FLAGS_NORMAL; 9734 if (pMedium->m->state != MediumState_LockedWrite) 9735 uOpenFlags = VD_OPEN_FLAGS_READONLY; 9736 if (pMedium->m->type == MediumType_Shareable) 9737 uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; 9738 /* Open all media in appropriate mode. */ 9739 vrc = VDOpen(targetHdd, 9740 pMedium->m->strFormat.c_str(), 9741 pMedium->m->strLocationFull.c_str(), 9742 uOpenFlags | m->uOpenFlagsDef, 9743 pMedium->m->vdImageIfaces); 9744 if (RT_FAILURE(vrc)) 9745 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9746 tr("Could not open the medium storage unit '%s'%s"), 9747 pMedium->m->strLocationFull.c_str(), 9748 i_vdError(vrc).c_str()); 9749 } 9750 /* target isn't locked, but no changing data is accessed */ 9751 if (task.midxSrcImageSame == UINT32_MAX) 9752 { 9753 vrc = VDCopy(hdd, 9754 VD_LAST_IMAGE, 9755 targetHdd, 9756 targetFormat.c_str(), 9757 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9758 false /* fMoveByRename */, 9759 task.mTargetLogicalSize /* cbSize */, 9760 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9761 targetId.raw(), 9762 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9763 NULL /* pVDIfsOperation */, 9764 pTarget->m->vdImageIfaces, 9765 task.mVDOperationIfaces); 9766 } 9767 else 9768 { 9769 vrc = VDCopyEx(hdd, 9770 VD_LAST_IMAGE, 9771 targetHdd, 9772 VD_LAST_IMAGE, 9773 targetFormat.c_str(), 9774 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9775 false /* fMoveByRename */, 9776 task.mTargetLogicalSize /* cbSize */, 9777 task.midxSrcImageSame, 9778 task.midxDstImageSame, 9779 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9780 targetId.raw(), 9781 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9782 NULL /* pVDIfsOperation */, 9783 pTarget->m->vdImageIfaces, 9784 task.mVDOperationIfaces); 9785 } 9786 if (RT_FAILURE(vrc)) 9787 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9788 tr("Could not create the clone medium '%s'%s"), 9789 targetLocation.c_str(), i_vdError(vrc).c_str()); 9790 9791 size = VDGetFileSize(targetHdd, VD_LAST_IMAGE); 9792 logicalSize = VDGetSize(targetHdd, VD_LAST_IMAGE); 9793 unsigned uImageFlags; 9794 vrc = VDGetImageFlags(targetHdd, 0, &uImageFlags); 9795 if (RT_SUCCESS(vrc)) 9796 variant = (MediumVariant_T)uImageFlags; 9746 9797 } 9747 if (RT_FAILURE(vrc)) 9748 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9749 tr("Could not create the clone medium '%s'%s"), 9750 targetLocation.c_str(), i_vdError(vrc).c_str()); 9751 9752 size = VDGetFileSize(targetHdd, VD_LAST_IMAGE); 9753 logicalSize = VDGetSize(targetHdd, VD_LAST_IMAGE); 9754 unsigned uImageFlags; 9755 vrc = VDGetImageFlags(targetHdd, 0, &uImageFlags); 9756 if (RT_SUCCESS(vrc)) 9757 variant = (MediumVariant_T)uImageFlags; 9798 else //cloningWithinList - only use source chain 9799 { 9800 if (task.midxSrcImageSame == UINT32_MAX) 9801 { 9802 vrc = VDCopyEx(hdd, 9803 VD_LAST_IMAGE, 9804 hdd, 9805 uTargetIdx, 9806 targetFormat.c_str(), 9807 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9808 false /* fMoveByRename */, 9809 task.mTargetLogicalSize /* cbSize */, 9810 VD_IMAGE_CONTENT_UNKNOWN, 9811 VD_IMAGE_CONTENT_UNKNOWN, 9812 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9813 targetId.raw(), 9814 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9815 NULL /* pVDIfsOperation */, 9816 pTarget->m->vdImageIfaces, 9817 task.mVDOperationIfaces); 9818 } 9819 else 9820 { 9821 vrc = VDCopyEx(hdd, 9822 VD_LAST_IMAGE, 9823 hdd, 9824 uTargetIdx, 9825 targetFormat.c_str(), 9826 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL, 9827 false /* fMoveByRename */, 9828 task.mTargetLogicalSize /* cbSize */, 9829 task.midxSrcImageSame, 9830 task.midxDstImageSame, 9831 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk), 9832 targetId.raw(), 9833 VD_OPEN_FLAGS_NORMAL | m->uOpenFlagsDef, 9834 NULL /* pVDIfsOperation */, 9835 pTarget->m->vdImageIfaces, 9836 task.mVDOperationIfaces); 9837 } 9838 if (RT_FAILURE(vrc)) 9839 throw setErrorBoth(VBOX_E_FILE_ERROR, vrc, 9840 tr("Could not create the clone medium '%s'%s"), 9841 targetLocation.c_str(), i_vdError(vrc).c_str()); 9842 9843 size = VDGetFileSize(hdd, uTargetIdx); 9844 logicalSize = VDGetSize(hdd, uTargetIdx); 9845 unsigned uImageFlags; 9846 vrc = VDGetImageFlags(hdd, 0, &uImageFlags); 9847 if (RT_SUCCESS(vrc)) 9848 variant = (MediumVariant_T)uImageFlags; 9849 9850 } 9758 9851 } 9759 9852 catch (HRESULT hrcXcpt) { hrcTmp = hrcXcpt; } -
trunk/src/VBox/Storage/VD.cpp
r99739 r100078 2053 2053 * to speed up the copy process if possible. 2054 2054 */ 2055 static int vdCopyHelper(PVDISK pDiskFrom, PVDIMAGE pImageFrom, PVDISK pDiskTo, 2055 static int vdCopyHelper(PVDISK pDiskFrom, PVDIMAGE pImageFrom, PVDISK pDiskTo, PVDIMAGE pImageTo, 2056 2056 uint64_t cbSize, unsigned cImagesFromRead, unsigned cImagesToRead, 2057 2057 bool fSuppressRedundantIo, PVDINTERFACEPROGRESS pIfProgress, … … 2068 2068 unsigned uProgressOld = 0; 2069 2069 2070 LogFlowFunc(("pDiskFrom=%#p pImageFrom=%#p pDiskTo=%#p cbSize=%llu cImagesFromRead=%u cImagesToRead=%u fSuppressRedundantIo=%RTbool pIfProgress=%#p pDstIfProgress=%#p\n",2071 pDiskFrom, pImageFrom, pDiskTo, cbSize, cImagesFromRead, cImagesToRead, fSuppressRedundantIo, pDstIfProgress, pDstIfProgress));2070 LogFlowFunc(("pDiskFrom=%#p pImageFrom=%#p pDiskTo=%#p pImageTo=%#p cbSize=%llu cImagesFromRead=%u cImagesToRead=%u fSuppressRedundantIo=%RTbool pIfProgress=%#p pDstIfProgress=%#p\n", 2071 pDiskFrom, pImageFrom, pDiskTo, pImageTo, cbSize, cImagesFromRead, cImagesToRead, fSuppressRedundantIo, pDstIfProgress, pDstIfProgress)); 2072 2072 2073 2073 if ( (fSuppressRedundantIo || (cImagesFromRead > 0)) … … 2147 2147 2148 2148 /* Only do collapsed I/O if we are copying the data blockwise. */ 2149 rc = vdWriteHelperEx(pDiskTo, p DiskTo->pLast, NULL, uOffset, pvBuf,2149 rc = vdWriteHelperEx(pDiskTo, pImageTo, NULL, uOffset, pvBuf, 2150 2150 cbThisRead, VDIOCTX_FLAGS_DONT_SET_MODIFIED_FLAG /* fFlags */, 2151 2151 fBlockwiseCopy ? cImagesToRead : 0); … … 7183 7183 7184 7184 7185 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImage , PVDISK pDiskTo,7185 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImageFrom, PVDISK pDiskTo, unsigned nImageTo, 7186 7186 const char *pszBackend, const char *pszFilename, 7187 7187 bool fMoveByRename, uint64_t cbSize, … … 7197 7197 PVDIMAGE pImageTo = NULL; 7198 7198 7199 LogFlowFunc(("pDiskFrom=%#p nImage =%u pDiskTo=%#ppszBackend=\"%s\" pszFilename=\"%s\" fMoveByRename=%d cbSize=%llu nImageFromSame=%u nImageToSame=%u uImageFlags=%#x pDstUuid=%#p uOpenFlags=%#x pVDIfsOperation=%#p pDstVDIfsImage=%#p pDstVDIfsOperation=%#p\n",7200 pDiskFrom, nImage , pDiskTo, pszBackend, pszFilename, fMoveByRename, cbSize, nImageFromSame, nImageToSame, uImageFlags, pDstUuid, uOpenFlags, pVDIfsOperation, pDstVDIfsImage, pDstVDIfsOperation));7199 LogFlowFunc(("pDiskFrom=%#p nImageFrom=%u pDiskTo=%#p nImageTo=%u pszBackend=\"%s\" pszFilename=\"%s\" fMoveByRename=%d cbSize=%llu nImageFromSame=%u nImageToSame=%u uImageFlags=%#x pDstUuid=%#p uOpenFlags=%#x pVDIfsOperation=%#p pDstVDIfsImage=%#p pDstVDIfsOperation=%#p\n", 7200 pDiskFrom, nImageFrom, nImageTo, pDiskTo, pszBackend, pszFilename, fMoveByRename, cbSize, nImageFromSame, nImageToSame, uImageFlags, pDstUuid, uOpenFlags, pVDIfsOperation, pDstVDIfsImage, pDstVDIfsOperation)); 7201 7201 7202 7202 /* Check arguments. */ … … 7212 7212 AssertRC(rc2); 7213 7213 fLockReadFrom = true; 7214 PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImage );7214 PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImageFrom); 7215 7215 AssertPtrBreakStmt(pImageFrom, rc = VERR_VD_IMAGE_NOT_FOUND); 7216 7216 AssertPtrBreakStmt(pDiskTo, rc = VERR_INVALID_POINTER); 7217 7217 AssertMsg(pDiskTo->u32Signature == VDISK_SIGNATURE, 7218 7218 ("u32Signature=%08x\n", pDiskTo->u32Signature)); 7219 AssertMsgBreakStmt( (nImageFromSame < nImage || nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN)7219 AssertMsgBreakStmt( (nImageFromSame < nImageFrom || nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN) 7220 7220 && (nImageToSame < pDiskTo->cImages || nImageToSame == VD_IMAGE_CONTENT_UNKNOWN) 7221 7221 && ( (nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN && nImageToSame == VD_IMAGE_CONTENT_UNKNOWN) … … 7225 7225 7226 7226 /* Move the image. */ 7227 if ( pDiskFrom == pDiskTo)7227 if (fMoveByRename) 7228 7228 { 7229 7229 /* Rename only works when backends are the same, are file based … … 7345 7345 fLockWriteTo = true; 7346 7346 7347 pImageTo = vdGetImageByNumber(pDiskTo, nImageTo); 7348 AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND); 7347 7349 if (RT_SUCCESS(rc) && !RTUuidIsNull(&ImageUuid)) 7348 p DiskTo->pLast->Backend->pfnSetUuid(pDiskTo->pLast->pBackendData, &ImageUuid);7350 pImageTo->Backend->pfnSetUuid(pImageTo->pBackendData, &ImageUuid); 7349 7351 } 7350 7352 if (RT_FAILURE(rc)) 7351 7353 break; 7352 7354 7353 pImageTo = pDiskTo->pLast;7355 pImageTo = vdGetImageByNumber(pDiskTo, nImageTo); 7354 7356 AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND); 7355 7357 … … 7358 7360 else 7359 7361 { 7360 pImageTo = pDiskTo->pLast;7362 pImageTo = vdGetImageByNumber(pDiskTo, nImageTo); 7361 7363 AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND); 7362 7364 … … 7387 7389 * Don't optimize if the image existed or if it is a child image. */ 7388 7390 bool fSuppressRedundantIo = ( !(pszFilename == NULL || cImagesTo > 0) 7389 || (nImageToSame != VD_IMAGE_CONTENT_UNKNOWN)); 7391 || (nImageToSame != VD_IMAGE_CONTENT_UNKNOWN) 7392 || (pDiskTo == pDiskFrom)); 7390 7393 unsigned cImagesFromReadBack, cImagesToReadBack; 7391 7394 … … 7394 7397 else 7395 7398 { 7396 if (nImage == VD_LAST_IMAGE)7399 if (nImageFrom == VD_LAST_IMAGE) 7397 7400 cImagesFromReadBack = pDiskFrom->cImages - nImageFromSame - 1; 7398 7401 else 7399 cImagesFromReadBack = nImage - nImageFromSame;7402 cImagesFromReadBack = nImageFrom - nImageFromSame; 7400 7403 } 7401 7404 … … 7406 7409 7407 7410 /* Copy the data. */ 7408 rc = vdCopyHelper(pDiskFrom, pImageFrom, pDiskTo, cbSize,7411 rc = vdCopyHelper(pDiskFrom, pImageFrom, pDiskTo, pImageTo, cbSize, 7409 7412 cImagesFromReadBack, cImagesToReadBack, 7410 7413 fSuppressRedundantIo, pIfProgress, pDstIfProgress); … … 7492 7495 PVDINTERFACE pDstVDIfsOperation) 7493 7496 { 7494 return VDCopyEx(pDiskFrom, nImage, pDiskTo, pszBackend, pszFilename, fMoveByRename,7497 return VDCopyEx(pDiskFrom, nImage, pDiskTo, VD_IMAGE_CONTENT_UNKNOWN, pszBackend, pszFilename, fMoveByRename, 7495 7498 cbSize, VD_IMAGE_CONTENT_UNKNOWN, VD_IMAGE_CONTENT_UNKNOWN, 7496 7499 uImageFlags, pDstUuid, uOpenFlags, pVDIfsOperation, … … 9674 9677 return VINF_SUCCESS; 9675 9678 } 9676 -
trunk/src/VBox/ValidationKit/tests/api/tdCloneMedium1.py
r99235 r100078 246 246 return True 247 247 248 def testCloneToBase(self): 249 """ 250 Tests cloning diff to base 251 """ 252 253 reporter.testStart("testCloneToBase") 254 255 try: 256 oVBox = self.oTstDrv.oVBoxMgr.getVirtualBox() 257 oVM = self.oTstDrv.createTestVM('test-medium-clone-base', 1, None, 4) 258 assert oVM is not None 259 260 fRc = True 261 oSession = self.oTstDrv.openSession(oVM) 262 cImages = 10 263 reporter.log('Creating chain with %d disk images' % (cImages)) 264 sHddPath = os.path.join(self.oTstDrv.sScratchPath, 'CloneTest1.vdi') 265 hd1 = oSession.createBaseHd(sHddPath, cb=1024*1024) 266 if hd1 is None: 267 fRc = False 268 for i in range(2, cImages + 1): 269 sHddPath = os.path.join(self.oTstDrv.sScratchPath, 'CloneTest' + str(i) + '.vdi') 270 if i == 2: 271 oHd = oSession.createDiffHd(hd1, sHddPath) 272 hd2 = oHd 273 else: 274 oHd = oSession.createDiffHd(oHd, sHddPath) 275 if oHd is None: 276 fRc = False 277 break 278 279 280 # modify the VM config, attach HDD 281 sController='SATA Controller' 282 fRc = fRc and oSession.attachHd(sHddPath, sController, fImmutable=False, fForceResource=False) 283 fRc = fRc and oSession.saveSettings() 284 285 try: 286 oProgressCom = oHd.cloneTo(hd1, (vboxcon.MediumVariant_Standard, ), None); 287 except: 288 reporter.errorXcpt('failed to clone medium %s to %s' % (oHd.name, hd1.name)); 289 return False; 290 oProgress = vboxwrappers.ProgressWrapper(oProgressCom, self.oTstDrv.oVBoxMgr, self.oTstDrv, 291 'clone disk %s to base disk %s' % (oHd.name, hd1.name)); 292 oProgress.wait(cMsTimeout = 15*60*1000); # 15 min 293 oProgress.logResult(); 294 295 fRc = oSession.close() and fRc 296 self.deleteVM(oVM) 297 298 except: 299 reporter.errorXcpt() 300 301 return reporter.testDone()[1] == 0 302 248 303 def testAll(self): 249 return self.testCloneOnly() & self.testResizeAndClone() 304 return self.testCloneOnly() & self.testResizeAndClone() & self.testCloneToBase() 250 305 251 306 if __name__ == '__main__':
Note:
See TracChangeset
for help on using the changeset viewer.