VirtualBox

Changeset 100078 in vbox for trunk


Ignore:
Timestamp:
Jun 6, 2023 5:15:22 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
157767
Message:

Main/src-server and Storage: Immutable media handling flexibility added bugref:5995

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vd.h

    r99739 r100078  
    765765 *
    766766 * @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.
    769768 * @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.
    770770 * @param   pszBackend      Name of the image file backend to use (may be NULL
    771771 *                          to use the same as the source, case insensitive).
     
    822822 *          Setting both to 0 can suppress a lot of I/O.
    823823 */
    824 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImage, PVDISK pDiskTo,
     824VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImageFrom, PVDISK pDiskTo, unsigned nImageTo,
    825825                           const char *pszBackend, const char *pszFilename,
    826826                           bool fMoveByRename, uint64_t cbSize,
     
    18421842
    18431843#endif /* !VBOX_INCLUDED_vd_h */
    1844 
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r99991 r100078  
    31693169            throw pTarget->i_setStateError();
    31703170
     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
    31713179        /* Build the source lock list. */
    31723180        MediumLockList *pSourceMediumLockList(new MediumLockList());
    31733181        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);
    31793194        alock.acquire();
    31803195        if (FAILED(hrc))
     
    31873202        MediumLockList *pTargetMediumLockList(new MediumLockList());
    31883203        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);
    31943210        alock.acquire();
    31953211        if (FAILED(hrc))
     
    95679583
    95689584    bool fCreatingTarget = false;
     9585    bool cloningWithinList = false;
     9586    unsigned uTargetIdx = VD_LAST_IMAGE;
    95699587
    95709588    uint64_t size = 0, logicalSize = 0;
     
    96169634            MediumLockList::Base::const_iterator sourceListEnd =
    96179635                task.mpSourceMediumLockList->GetEnd();
     9636            unsigned i=0;
    96189637            for (MediumLockList::Base::const_iterator it = sourceListBegin;
    96199638                 it != sourceListEnd;
     
    96229641                const MediumLock &mediumLock = *it;
    96239642                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)
    96789644                {
    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;
    96879647                    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);
    96939649                    unsigned uOpenFlags = VD_OPEN_FLAGS_NORMAL;
    9694                     if (pMedium->m->state != MediumState_LockedWrite)
    9695                         uOpenFlags = VD_OPEN_FLAGS_READONLY;
    96969650                    if (pMedium->m->type == MediumType_Shareable)
    96979651                        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,
    97019654                                 pMedium->m->strFormat.c_str(),
    97029655                                 pMedium->m->strLocationFull.c_str(),
     
    97099662                                           i_vdError(vrc).c_str());
    97109663                }
    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)
    97149666                {
    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());
    97289681                }
    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)
    97309713                {
    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;
    97469797                }
    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                }
    97589851            }
    97599852            catch (HRESULT hrcXcpt) { hrcTmp = hrcXcpt; }
  • trunk/src/VBox/Storage/VD.cpp

    r99739 r100078  
    20532053 * to speed up the copy process if possible.
    20542054 */
    2055 static int vdCopyHelper(PVDISK pDiskFrom, PVDIMAGE pImageFrom, PVDISK pDiskTo,
     2055static int vdCopyHelper(PVDISK pDiskFrom, PVDIMAGE pImageFrom, PVDISK pDiskTo, PVDIMAGE pImageTo,
    20562056                        uint64_t cbSize, unsigned cImagesFromRead, unsigned cImagesToRead,
    20572057                        bool fSuppressRedundantIo, PVDINTERFACEPROGRESS pIfProgress,
     
    20682068    unsigned uProgressOld = 0;
    20692069
    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));
    20722072
    20732073    if (   (fSuppressRedundantIo || (cImagesFromRead > 0))
     
    21472147
    21482148            /* Only do collapsed I/O if we are copying the data blockwise. */
    2149             rc = vdWriteHelperEx(pDiskTo, pDiskTo->pLast, NULL, uOffset, pvBuf,
     2149            rc = vdWriteHelperEx(pDiskTo, pImageTo, NULL, uOffset, pvBuf,
    21502150                                 cbThisRead, VDIOCTX_FLAGS_DONT_SET_MODIFIED_FLAG /* fFlags */,
    21512151                                 fBlockwiseCopy ? cImagesToRead : 0);
     
    71837183
    71847184
    7185 VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImage, PVDISK pDiskTo,
     7185VBOXDDU_DECL(int) VDCopyEx(PVDISK pDiskFrom, unsigned nImageFrom, PVDISK pDiskTo, unsigned nImageTo,
    71867186                           const char *pszBackend, const char *pszFilename,
    71877187                           bool fMoveByRename, uint64_t cbSize,
     
    71977197    PVDIMAGE pImageTo = NULL;
    71987198
    7199     LogFlowFunc(("pDiskFrom=%#p nImage=%u pDiskTo=%#p 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, 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));
    72017201
    72027202    /* Check arguments. */
     
    72127212        AssertRC(rc2);
    72137213        fLockReadFrom = true;
    7214         PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImage);
     7214        PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImageFrom);
    72157215        AssertPtrBreakStmt(pImageFrom, rc = VERR_VD_IMAGE_NOT_FOUND);
    72167216        AssertPtrBreakStmt(pDiskTo, rc = VERR_INVALID_POINTER);
    72177217        AssertMsg(pDiskTo->u32Signature == VDISK_SIGNATURE,
    72187218                  ("u32Signature=%08x\n", pDiskTo->u32Signature));
    7219         AssertMsgBreakStmt(   (nImageFromSame < nImage || nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN)
     7219        AssertMsgBreakStmt(   (nImageFromSame < nImageFrom || nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN)
    72207220                           && (nImageToSame < pDiskTo->cImages || nImageToSame == VD_IMAGE_CONTENT_UNKNOWN)
    72217221                           && (   (nImageFromSame == VD_IMAGE_CONTENT_UNKNOWN && nImageToSame == VD_IMAGE_CONTENT_UNKNOWN)
     
    72257225
    72267226        /* Move the image. */
    7227         if (pDiskFrom == pDiskTo)
     7227        if (fMoveByRename)
    72287228        {
    72297229            /* Rename only works when backends are the same, are file based
     
    73457345                fLockWriteTo = true;
    73467346
     7347                pImageTo = vdGetImageByNumber(pDiskTo, nImageTo);
     7348                AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND);
    73477349                if (RT_SUCCESS(rc) && !RTUuidIsNull(&ImageUuid))
    7348                      pDiskTo->pLast->Backend->pfnSetUuid(pDiskTo->pLast->pBackendData, &ImageUuid);
     7350                     pImageTo->Backend->pfnSetUuid(pImageTo->pBackendData, &ImageUuid);
    73497351            }
    73507352            if (RT_FAILURE(rc))
    73517353                break;
    73527354
    7353             pImageTo = pDiskTo->pLast;
     7355            pImageTo = vdGetImageByNumber(pDiskTo, nImageTo);
    73547356            AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND);
    73557357
     
    73587360        else
    73597361        {
    7360             pImageTo = pDiskTo->pLast;
     7362            pImageTo = vdGetImageByNumber(pDiskTo, nImageTo);
    73617363            AssertPtrBreakStmt(pImageTo, rc = VERR_VD_IMAGE_NOT_FOUND);
    73627364
     
    73877389         * Don't optimize if the image existed or if it is a child image. */
    73887390        bool fSuppressRedundantIo = (   !(pszFilename == NULL || cImagesTo > 0)
    7389                                      || (nImageToSame != VD_IMAGE_CONTENT_UNKNOWN));
     7391                                     || (nImageToSame != VD_IMAGE_CONTENT_UNKNOWN)
     7392                                     || (pDiskTo == pDiskFrom));
    73907393        unsigned cImagesFromReadBack, cImagesToReadBack;
    73917394
     
    73947397        else
    73957398        {
    7396             if (nImage == VD_LAST_IMAGE)
     7399            if (nImageFrom == VD_LAST_IMAGE)
    73977400                cImagesFromReadBack = pDiskFrom->cImages - nImageFromSame - 1;
    73987401            else
    7399                 cImagesFromReadBack = nImage - nImageFromSame;
     7402                cImagesFromReadBack = nImageFrom - nImageFromSame;
    74007403        }
    74017404
     
    74067409
    74077410        /* Copy the data. */
    7408         rc = vdCopyHelper(pDiskFrom, pImageFrom, pDiskTo, cbSize,
     7411        rc = vdCopyHelper(pDiskFrom, pImageFrom, pDiskTo, pImageTo, cbSize,
    74097412                          cImagesFromReadBack, cImagesToReadBack,
    74107413                          fSuppressRedundantIo, pIfProgress, pDstIfProgress);
     
    74927495                         PVDINTERFACE pDstVDIfsOperation)
    74937496{
    7494     return VDCopyEx(pDiskFrom, nImage, pDiskTo, pszBackend, pszFilename, fMoveByRename,
     7497    return VDCopyEx(pDiskFrom, nImage, pDiskTo, VD_IMAGE_CONTENT_UNKNOWN, pszBackend, pszFilename, fMoveByRename,
    74957498                    cbSize, VD_IMAGE_CONTENT_UNKNOWN, VD_IMAGE_CONTENT_UNKNOWN,
    74967499                    uImageFlags, pDstUuid, uOpenFlags, pVDIfsOperation,
     
    96749677    return VINF_SUCCESS;
    96759678}
    9676 
  • trunk/src/VBox/ValidationKit/tests/api/tdCloneMedium1.py

    r99235 r100078  
    246246        return True
    247247
     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
    248303    def testAll(self):
    249         return self.testCloneOnly() & self.testResizeAndClone()
     304        return self.testCloneOnly() & self.testResizeAndClone() & self.testCloneToBase()
    250305
    251306if __name__ == '__main__':
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette