VirtualBox

Changeset 31712 in vbox


Ignore:
Timestamp:
Aug 16, 2010 5:16:33 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
64860
Message:

Main/Medium: automatically repair base images with a non-zero parent UUID

File:
1 edited

Legend:

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

    r31698 r31712  
    35783578    uint64_t mediumLogicalSize = 0;
    35793579
     3580    /* Flag whether a base image has a non-zero parent UUID and thus
     3581     * need repairing after it was closed again. */
     3582    bool fRepairImageZeroParentUuid = false;
     3583
    35803584    /* leave the lock before a lengthy operation */
    35813585    vrc = RTSemEventMultiReset(m->queryInfoSem);
     
    37283732                    if (m->pParent.isNull())
    37293733                    {
     3734                        /* Due to a bug in VDCopy() in VirtualBox 3.0.0-3.0.14
     3735                         * and 3.1.0-3.1.8 there are base images out there
     3736                         * which have a non-zero parent UUID. No point in
     3737                         * complaining about them, instead automatically
     3738                         * repair the problem. Later we can bring back the
     3739                         * error message, but we should wait until really
     3740                         * most users have repaired their images, either with
     3741                         * VBoxFixHdd or this way. */
     3742#if 1
     3743                        fRepairImageZeroParentUuid = true;
     3744#else /* 0 */
    37303745                        lastAccessError = Utf8StrFmt(
    37313746                                tr("Medium type of '%s' is differencing but it is not associated with any parent medium in the media registry ('%s')"),
     
    37333748                                m->pVirtualBox->settingsFilePath().c_str());
    37343749                        throw S_OK;
     3750#endif /* 0 */
    37353751                    }
    37363752
    37373753                    AutoReadLock parentLock(m->pParent COMMA_LOCKVAL_SRC_POS);
    3738                     if (    m->pParent->getState() != MediumState_Inaccessible
    3739                          && m->pParent->getId() != parentId)
     3754                    if (   !fRepairImageZeroParentUuid
     3755                        && m->pParent->getState() != MediumState_Inaccessible
     3756                        && m->pParent->getId() != parentId)
    37403757                    {
    37413758                        lastAccessError = Utf8StrFmt(
     
    37643781
    37653782        VDDestroy(hdd);
    3766 
    37673783    }
    37683784    catch (HRESULT aRC)
     
    38003816        m->preLockState = MediumState_Inaccessible;
    38013817
     3818    HRESULT rc2;
    38023819    if (uOpenFlags & (VD_OPEN_FLAGS_READONLY || VD_OPEN_FLAGS_SHAREABLE))
    3803         rc = UnlockRead(NULL);
     3820        rc2 = UnlockRead(NULL);
    38043821    else
     3822        rc2 = UnlockWrite(NULL);
     3823    if (SUCCEEDED(rc) && FAILED(rc2))
     3824        rc = rc2;
     3825    if (FAILED(rc)) return rc;
     3826
     3827    /* If this is a base image which incorrectly has a parent UUID set,
     3828     * repair the image now by zeroing the parent UUID. This is only done
     3829     * when we have structural information from a config file, on import
     3830     * this is not possible. If someone would accidentally call openMedium
     3831     * with a diff image before the base is registered this would destroy
     3832     * the diff. Not acceptable. */
     3833    if (fRepairImageZeroParentUuid)
     3834    {
     3835        rc = LockWrite(NULL);
     3836        if (FAILED(rc)) return rc;
     3837
     3838        alock.leave();
     3839
     3840        try
     3841        {
     3842            PVBOXHDD hdd;
     3843            vrc = VDCreate(m->vdDiskIfaces, &hdd);
     3844            ComAssertRCThrow(vrc, E_FAIL);
     3845
     3846            try
     3847            {
     3848                vrc = VDOpen(hdd,
     3849                             format.c_str(),
     3850                             location.c_str(),
     3851                             uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
     3852                             m->vdDiskIfaces);
     3853                if (RT_FAILURE(vrc))
     3854                    throw S_OK;
     3855
     3856                RTUUID zeroParentUuid;
     3857                RTUuidClear(&zeroParentUuid);
     3858                vrc = VDSetParentUuid(hdd, 0, &zeroParentUuid);
     3859                ComAssertRCThrow(vrc, E_FAIL);
     3860            }
     3861            catch (HRESULT aRC)
     3862            {
     3863                rc = aRC;
     3864            }
     3865
     3866            VDDestroy(hdd);
     3867        }
     3868        catch (HRESULT aRC)
     3869        {
     3870            rc = aRC;
     3871        }
     3872
     3873        alock.enter();
     3874
    38053875        rc = UnlockWrite(NULL);
    3806     if (FAILED(rc)) return rc;
     3876        if (SUCCEEDED(rc) && FAILED(rc2))
     3877            rc = rc2;
     3878        if (FAILED(rc)) return rc;
     3879    }
    38073880
    38083881    return rc;
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