VirtualBox

Changeset 38308 in vbox


Ignore:
Timestamp:
Aug 4, 2011 9:29:51 AM (13 years ago)
Author:
vboxsync
Message:

Main/Medium: public cloneToEx API for internal use which makes it possible to control certain optimizations during VM cloning

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/MediumImpl.h

    r37900 r38308  
    263263                       const ComObjPtr<Progress> &aProgress);
    264264
     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
    265269private:
    266270
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r37985 r38308  
    341341              MediumVariant_T aVariant,
    342342              Medium *aParent,
     343              uint32_t idxSrcImageSame,
     344              uint32_t idxDstImageSame,
    343345              MediumLockList *aSourceMediumLockList,
    344346              MediumLockList *aTargetMediumLockList,
     
    351353          mpTargetMediumLockList(aTargetMediumLockList),
    352354          mVariant(aVariant),
     355          midxSrcImageSame(idxSrcImageSame),
     356          midxDstImageSame(idxDstImageSame),
    353357          mTargetCaller(aTarget),
    354358          mParentCaller(aParent),
     
    381385    MediumLockList *mpTargetMediumLockList;
    382386    MediumVariant_T mVariant;
     387    uint32_t midxSrcImageSame;
     388    uint32_t midxDstImageSame;
    383389
    384390private:
     
    26972703        pTask = new Medium::CloneTask(this, pProgress, pTarget,
    26982704                                      (MediumVariant_T)aVariant,
    2699                                       pParent, pSourceMediumLockList,
    2700                                       pTargetMediumLockList);
     2705                                      pParent, UINT32_MAX, UINT32_MAX,
     2706                                      pSourceMediumLockList, pTargetMediumLockList);
    27012707        rc = pTask->rc();
    27022708        AssertComRC(rc);
     
    50615067        if (m->state == MediumState_NotCreated)
    50625068            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 */
     5097HRESULT 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;
    50635192    }
    50645193    catch (HRESULT aRC) { rc = aRC; }
     
    69717100
    69727101                /** @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                }
    69867136                if (RT_FAILURE(vrc))
    69877137                    throw setError(VBOX_E_FILE_ERROR,
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