VirtualBox

Ignore:
Timestamp:
Jan 10, 2023 8:01:32 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155144
Message:

Main: Added redundancy pending release. Fixed minor issues with resizeAndCloneTo. bugref:10090

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r98042 r98044  
    498498              bool fKeepTargetMediumLockList = false,
    499499              bool fNotifyAboutChanges = true,
    500               LONG64 aTargetLogicalSize = 0)
     500              uint64_t aTargetLogicalSize = 0)
    501501        : Medium::Task(aMedium, aProgress, fNotifyAboutChanges),
    502502          mTarget(aTarget),
     
    512512          mfKeepSourceMediumLockList(fKeepSourceMediumLockList),
    513513          mfKeepTargetMediumLockList(fKeepTargetMediumLockList)
    514 
    515514    {
    516515        AssertReturnVoidStmt(aTarget != NULL, mRC = E_FAIL);
     
    537536    const ComObjPtr<Medium> mTarget;
    538537    const ComObjPtr<Medium> mParent;
    539     LONG64 mTargetLogicalSize;
     538    uint64_t mTargetLogicalSize;
    540539    MediumLockList *mpSourceMediumLockList;
    541540    MediumLockList *mpTargetMediumLockList;
     
    30253024                        ComPtr<IProgress> &aProgress)
    30263025{
    3027     return resizeAndCloneTo(aTarget, 0, aVariant, aParent, aProgress);
     3026    /** @todo r=jack: Remove redundancy. Call Medium::resizeAndCloneTo. */
     3027
     3028    /** @todo r=klaus The code below needs to be double checked with regard
     3029     * to lock order violations, it probably causes lock order issues related
     3030     * to the AutoCaller usage. */
     3031    ComAssertRet(aTarget != this, E_INVALIDARG);
     3032
     3033    IMedium *aT = aTarget;
     3034    ComObjPtr<Medium> pTarget = static_cast<Medium*>(aT);
     3035    ComObjPtr<Medium> pParent;
     3036    if (aParent)
     3037    {
     3038        IMedium *aP = aParent;
     3039        pParent = static_cast<Medium*>(aP);
     3040    }
     3041
     3042    HRESULT rc = S_OK;
     3043    ComObjPtr<Progress> pProgress;
     3044    Medium::Task *pTask = NULL;
     3045
     3046    try
     3047    {
     3048        // locking: we need the tree lock first because we access parent pointers
     3049        // and we need to write-lock the media involved
     3050        uint32_t    cHandles    = 3;
     3051        LockHandle* pHandles[4] = { &m->pVirtualBox->i_getMediaTreeLockHandle(),
     3052                                    this->lockHandle(),
     3053                                    pTarget->lockHandle() };
     3054        /* Only add parent to the lock if it is not null */
     3055        if (!pParent.isNull())
     3056            pHandles[cHandles++] = pParent->lockHandle();
     3057        AutoWriteLock alock(cHandles,
     3058                            pHandles
     3059                            COMMA_LOCKVAL_SRC_POS);
     3060
     3061        if (    pTarget->m->state != MediumState_NotCreated
     3062            &&  pTarget->m->state != MediumState_Created)
     3063            throw pTarget->i_setStateError();
     3064
     3065        /* Build the source lock list. */
     3066        MediumLockList *pSourceMediumLockList(new MediumLockList());
     3067        alock.release();
     3068        rc = i_createMediumLockList(true /* fFailIfInaccessible */,
     3069                                    NULL /* pToLockWrite */,
     3070                                    false /* fMediumLockWriteAll */,
     3071                                    NULL,
     3072                                    *pSourceMediumLockList);
     3073        alock.acquire();
     3074        if (FAILED(rc))
     3075        {
     3076            delete pSourceMediumLockList;
     3077            throw rc;
     3078        }
     3079
     3080        /* Build the target lock list (including the to-be parent chain). */
     3081        MediumLockList *pTargetMediumLockList(new MediumLockList());
     3082        alock.release();
     3083        rc = pTarget->i_createMediumLockList(true /* fFailIfInaccessible */,
     3084                                             pTarget /* pToLockWrite */,
     3085                                             false /* fMediumLockWriteAll */,
     3086                                             pParent,
     3087                                             *pTargetMediumLockList);
     3088        alock.acquire();
     3089        if (FAILED(rc))
     3090        {
     3091            delete pSourceMediumLockList;
     3092            delete pTargetMediumLockList;
     3093            throw rc;
     3094        }
     3095
     3096        alock.release();
     3097        rc = pSourceMediumLockList->Lock();
     3098        alock.acquire();
     3099        if (FAILED(rc))
     3100        {
     3101            delete pSourceMediumLockList;
     3102            delete pTargetMediumLockList;
     3103            throw setError(rc,
     3104                           tr("Failed to lock source media '%s'"),
     3105                           i_getLocationFull().c_str());
     3106        }
     3107        alock.release();
     3108        rc = pTargetMediumLockList->Lock();
     3109        alock.acquire();
     3110        if (FAILED(rc))
     3111        {
     3112            delete pSourceMediumLockList;
     3113            delete pTargetMediumLockList;
     3114            throw setError(rc,
     3115                           tr("Failed to lock target media '%s'"),
     3116                           pTarget->i_getLocationFull().c_str());
     3117        }
     3118
     3119        pProgress.createObject();
     3120        rc = pProgress->init(m->pVirtualBox,
     3121                             static_cast <IMedium *>(this),
     3122                             BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.c_str()).raw(),
     3123                             TRUE /* aCancelable */);
     3124        if (FAILED(rc))
     3125        {
     3126            delete pSourceMediumLockList;
     3127            delete pTargetMediumLockList;
     3128            throw rc;
     3129        }
     3130
     3131        ULONG mediumVariantFlags = 0;
     3132
     3133        if (aVariant.size())
     3134        {
     3135            for (size_t i = 0; i < aVariant.size(); i++)
     3136                mediumVariantFlags |= (ULONG)aVariant[i];
     3137        }
     3138
     3139        if (mediumVariantFlags & MediumVariant_Formatted)
     3140        {
     3141            delete pSourceMediumLockList;
     3142            delete pTargetMediumLockList;
     3143            throw setError(VBOX_E_NOT_SUPPORTED,
     3144                           tr("Medium variant 'formatted' applies to floppy images only"));
     3145        }
     3146
     3147        /* setup task object to carry out the operation asynchronously */
     3148        pTask = new Medium::CloneTask(this, pProgress, pTarget,
     3149                                      (MediumVariant_T)mediumVariantFlags,
     3150                                      pParent, UINT32_MAX, UINT32_MAX,
     3151                                      pSourceMediumLockList, pTargetMediumLockList);
     3152        rc = pTask->rc();
     3153        AssertComRC(rc);
     3154        if (FAILED(rc))
     3155            throw rc;
     3156
     3157        if (pTarget->m->state == MediumState_NotCreated)
     3158            pTarget->m->state = MediumState_Creating;
     3159    }
     3160    catch (HRESULT aRC) { rc = aRC; }
     3161
     3162    if (SUCCEEDED(rc))
     3163    {
     3164        rc = pTask->createThread();
     3165        pTask = NULL;
     3166        if (SUCCEEDED(rc))
     3167            pProgress.queryInterfaceTo(aProgress.asOutParam());
     3168    }
     3169    else if (pTask != NULL)
     3170        delete pTask;
     3171
     3172    return rc;
    30283173}
    30293174
     
    30623207    /* Set up variables. Fetch needed data in lockable blocks */
    30633208    HRESULT rc = S_OK;
    3064     ComObjPtr<Progress> pTmpProgress;
    30653209    Medium::Task *pTask = NULL;
    30663210
     
    30913235
    30923236    if (FAILED(rc))
    3093         throw rc;
     3237        return rc;
    30943238
    30953239    /* If target does not exist, handle resize. */
     
    30993243            if (!i_isMediumFormatFile())
    31003244            {
    3101                 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    31023245                rc = setError(VBOX_E_NOT_SUPPORTED,
    31033246                              tr("Sizes of '%s' and '%s' are different and \
    31043247                                 medium format does not support resing"),
    31053248                              strSourceName.c_str(), strTargetName.c_str());
    3106                 throw rc;
     3249                return rc;
    31073250            }
    31083251
     
    31153258            rc = pTarget->LockWrite(pToken.asOutParam());
    31163259
    3117             if (FAILED(rc)) throw rc;
     3260            if (FAILED(rc)) return rc;
    31183261
    31193262            /**
     
    31343277                                strTargetName.c_str());
    31353278                delete pMediumLockListForResize;
    3136                 throw rc;
     3279                return rc;
    31373280            }
    31383281
     
    31453288                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    31463289                delete pMediumLockListForResize;
    3147                 throw rc;
     3290                return rc;
    31483291            }
    31493292
     
    32683411                                          pParent, UINT32_MAX, UINT32_MAX,
    32693412                                          pSourceMediumLockList, pTargetMediumLockList,
    3270                                           false, false, true, aLogicalSize);
     3413                                          false, false, true, (uint64_t)aLogicalSize);
    32713414        }
    32723415
     
    32883431            pProgress.queryInterfaceTo(aProgress.asOutParam());
    32893432    }
    3290     else if (pTask != NULL) {
     3433    else if (pTask != NULL)
    32913434        delete pTask;
    3292         throw rc;
    3293     }
    32943435
    32953436    return rc;
     
    97769917                                 (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL,
    97779918                                 false /* fMoveByRename */,
    9778                                  (uint64_t) task.mTargetLogicalSize /* cbSize */,
     9919                                 task.mTargetLogicalSize /* cbSize */,
    97799920                                 task.mVariant & ~(MediumVariant_NoCreateDir | MediumVariant_Formatted | MediumVariant_VmdkESX | MediumVariant_VmdkRawDisk),
    97809921                                 targetId.raw(),
     
    97929933                                   (fCreatingTarget) ? targetLocation.c_str() : (char *)NULL,
    97939934                                   false /* fMoveByRename */,
    9794                                    (uint64_t) task.mTargetLogicalSize /* cbSize */,
     9935                                   task.mTargetLogicalSize /* cbSize */,
    97959936                                   task.midxSrcImageSame,
    97969937                                   task.midxDstImageSame,
Note: See TracChangeset for help on using the changeset viewer.

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