VirtualBox

Changeset 35982 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 15, 2011 4:02:28 PM (14 years ago)
Author:
vboxsync
Message:

Main: further fix broken snapshots when disk images are shared between several machines: recurse into diff images as well

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

Legend:

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

    r35903 r35982  
    175175    Utf8Str getName();
    176176
    177     bool addRegistry(const Guid& id);
    178     bool removeRegistry(const Guid& id);
     177    bool addRegistry(const Guid& id, bool fRecurse);
     178private:
     179    void addRegistryImpl(const Guid& id, bool fRecurse);
     180public:
     181    bool removeRegistry(const Guid& id, bool fRecurse);
    179182    bool isInRegistry(const Guid& id);
    180183    bool getFirstRegistryMachineId(Guid &uuid) const;
     
    187190
    188191    const Guid* getFirstMachineBackrefId() const;
     192    const Guid* getAnyMachineBackref() const;
    189193    const Guid* getFirstMachineBackrefSnapshotId() const;
    190194
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r35903 r35982  
    77597759            if (puuidRegistry)
    77607760                // caller wants registry ID to be set on all attached media (OVF import case)
    7761                 medium->addRegistry(*puuidRegistry);
     7761                medium->addRegistry(*puuidRegistry, false /* fRecurse */);
    77627762        }
    77637763
     
    87848784    AutoWriteLock alock(pMedium COMMA_LOCKVAL_SRC_POS);
    87858785
    8786     if (pMedium->addRegistry(uuid))
     8786    if (pMedium->addRegistry(uuid, false /* fRecurse */))
    87878787        // registry actually changed:
    87888788        mParent->addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r35915 r35982  
    30793079 * Must have caller + locking!
    30803080 *
     3081 * If fRecurse == true, then additionally the media tree lock must be held for reading.
     3082 *
    30813083 * @param id
     3084 * @param fRecurse If true, recurses into child media to make sure the whole tree has registries in sync.
    30823085 * @return true if the registry was added; false if the given id was already on the list.
    30833086 */
    3084 bool Medium::addRegistry(const Guid& id)
     3087bool Medium::addRegistry(const Guid& id, bool fRecurse)
    30853088{
    30863089    // hard disks cannot be in more than one registry
     
    30993102    }
    31003103
     3104    addRegistryImpl(id, fRecurse);
     3105
     3106    return true;
     3107}
     3108
     3109/**
     3110 * Private implementation for addRegistry() so we can recurse more efficiently.
     3111 * @param id
     3112 * @param fRecurse
     3113 */
     3114void Medium::addRegistryImpl(const Guid& id, bool fRecurse)
     3115{
    31013116    m->llRegistryIDs.push_back(id);
    3102     return true;
     3117
     3118    if (fRecurse)
     3119    {
     3120        for (MediaList::iterator it = m->llChildren.begin();
     3121             it != m->llChildren.end();
     3122             ++it)
     3123        {
     3124            Medium *pChild = *it;
     3125            // recurse!
     3126            pChild->addRegistryImpl(id, fRecurse);
     3127        }
     3128    }
    31033129}
    31043130
     
    31093135 * Must have caller + locking!
    31103136 *
     3137 * If fRecurse == true, then additionally the media tree lock must be held for reading.
     3138 *
    31113139 * @param id
     3140 * @param fRecurse If true, recurses into child media to make sure the whole tree has registries in sync.
    31123141 * @return
    31133142 */
    3114 bool Medium::removeRegistry(const Guid& id)
     3143bool Medium::removeRegistry(const Guid& id, bool fRecurse)
    31153144{
    31163145    for (GuidList::iterator it = m->llRegistryIDs.begin();
     
    31213150        {
    31223151            m->llRegistryIDs.erase(it);
     3152
     3153            if (fRecurse)
     3154            {
     3155                for (MediaList::iterator it = m->llChildren.begin();
     3156                     it != m->llChildren.end();
     3157                     ++it)
     3158                {
     3159                    Medium *pChild = *it;
     3160                    pChild->removeRegistry(id, true);
     3161                }
     3162            }
     3163
    31233164            return true;
    31243165        }
     
    33593400
    33603401    return &m->backRefs.front().machineId;
     3402}
     3403
     3404/**
     3405 * Internal method which returns a machine that either this medium or one of its children
     3406 * is attached to. This is used for finding a replacement media registry when an existing
     3407 * media registry is about to be deleted in VirtualBox::unregisterMachine().
     3408 *
     3409 * Must have caller + locking, *and* caller must hold the media tree lock!
     3410 * @return
     3411 */
     3412const Guid* Medium::getAnyMachineBackref() const
     3413{
     3414    if (m->backRefs.size())
     3415        return &m->backRefs.front().machineId;
     3416
     3417    for (MediaList::iterator it = m->llChildren.begin();
     3418         it != m->llChildren.end();
     3419         ++it)
     3420    {
     3421        Medium *pChild = *it;
     3422        // recurse for this child
     3423        const Guid* puuid;
     3424        if ((puuid = pChild->getAnyMachineBackref()))
     3425            return puuid;
     3426    }
     3427
     3428    return NULL;
    33613429}
    33623430
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r35903 r35982  
    37163716    GuidList llRegistriesThatNeedSaving;
    37173717    {
    3718         AutoWriteLock tlock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
     3718        AutoReadLock tlock(getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
     3719        // iterate over the list of *base* images
    37193720        for (MediaOList::iterator it = m->allHardDisks.getList().begin();
    37203721             it != m->allHardDisks.getList().end();
     
    37263727            AutoWriteLock mlock(pMedium COMMA_LOCKVAL_SRC_POS);
    37273728
    3728             if (pMedium->removeRegistry(id))
     3729            if (pMedium->removeRegistry(id, true /* fRecurse */))
    37293730            {
    3730                 // ID was found in medium's registry list:
    3731                 // add a new one then
    3732                 const Guid *puuidBetter = pMedium->getFirstMachineBackrefId();
     3731                // machine ID was found in base medium's registry list:
     3732                // move this base image and all its children to another registry then
     3733                // 1) first, find a better registry to add things to
     3734                const Guid *puuidBetter = pMedium->getAnyMachineBackref();
    37333735                if (puuidBetter)
    37343736                {
    3735                     pMedium->addRegistry(*puuidBetter);
     3737                    // 2) better registry found: then use that
     3738                    pMedium->addRegistry(*puuidBetter, true /* fRecurse */);
     3739                    // 3) and make sure the registry is saved below
    37363740                    addGuidToListUniquely(llRegistriesThatNeedSaving, *puuidBetter);
    37373741                }
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