VirtualBox

Changeset 38499 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
Aug 19, 2011 12:02:55 PM (13 years ago)
Author:
vboxsync
Message:

Main/Machine+Medium: fix medium registry association when attaching a device or mounting a medium, when there is a chain of parent images which are not associated with any media registry, including the necessary locking adjustments

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

Legend:

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

    r38494 r38499  
    37333733            // creating the diff image for the immutable, and the parent is not yet registered);
    37343734            // put the parent in the machine registry then
     3735            mediumLock.release();
    37353736            addMediumToRegistry(medium, llRegistriesThatNeedSaving, &uuidRegistryParent);
     3737            mediumLock.acquire();
    37363738        }
    37373739        rc = diff->init(mParent,
     
    38163818        if (FAILED(rc)) return rc;
    38173819
     3820        mediumLock.release();
    38183821        addMediumToRegistry(medium,
    38193822                            llRegistriesThatNeedSaving,
    38203823                            NULL /* Guid *puuid */);
     3824        mediumLock.acquire();
    38213825    }
    38223826
     
    41904194            pMedium->addBackReference(mData->mUuid);
    41914195
     4196            mediumLock.release();
    41924197            addMediumToRegistry(pMedium, llRegistriesThatNeedSaving, NULL /* Guid *puuid */ );
     4198            mediumLock.acquire();
    41934199        }
    41944200
     
    92009206 * registry.
    92019207 *
    9202  * Caller must hold machine read lock!
     9208 * Caller must hold machine read lock and at least media tree read lock!
     9209 * Caller must NOT hold any medium locks.
    92039210 *
    92049211 * @param pMedium
     
    92109217                                  Guid *puuid)
    92119218{
     9219    ComObjPtr<Medium> pBase = pMedium->getBase();
     9220    /* Paranoia checks: do not hold medium locks. */
     9221    AssertReturnVoid(!pMedium->isWriteLockOnCurrentThread());
     9222    AssertReturnVoid(!pBase->isWriteLockOnCurrentThread());
     9223
    92129224    // decide which medium registry to use now that the medium is attached:
    92139225    Guid uuid;
     
    92189230        uuid = mParent->getGlobalRegistryId(); // VirtualBox global registry UUID
    92199231
    9220     AutoCaller autoCaller(pMedium);
    9221     if (FAILED(autoCaller.rc())) return;
    9222     AutoWriteLock alock(pMedium COMMA_LOCKVAL_SRC_POS);
    9223 
     9232    bool fAdd = false;
    92249233    if (pMedium->addRegistry(uuid, false /* fRecurse */))
     9234    {
    92259235        // registry actually changed:
    92269236        VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
     9237        fAdd = true;
     9238    }
     9239
     9240    /* For more complex hard disk structures it can happen that the base
     9241     * medium isn't yet associated with any medium registry. Do that now. */
     9242    if (pMedium != pBase)
     9243    {
     9244        if (   pBase->addRegistry(uuid, true /* fRecurse */)
     9245            && !fAdd)
     9246        {
     9247            VirtualBox::addGuidToListUniquely(llRegistriesThatNeedSaving, uuid);
     9248            fAdd = true;
     9249        }
     9250    }
    92279251
    92289252    if (puuid)
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r38475 r38499  
    31223122 * See getFirstRegistryMachineId() for details.
    31233123 *
    3124  * Must have caller + locking!
    3125  *
    3126  * If fRecurse == true, then additionally the media tree lock must be held for reading.
     3124 * If fRecurse == true, then the media tree lock must be held for reading.
    31273125 *
    31283126 * @param id
     
    31323130bool Medium::addRegistry(const Guid& id, bool fRecurse)
    31333131{
     3132    AutoCaller autoCaller(this);
     3133    if (FAILED(autoCaller.rc()))
     3134        return false;
     3135    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3136
     3137    bool fAdd = true;
     3138
    31343139    // hard disks cannot be in more than one registry
    3135     if (    m->devType == DeviceType_HardDisk
    3136          && m->llRegistryIDs.size() > 0
    3137        )
    3138         return false;
     3140    if (   m->devType == DeviceType_HardDisk
     3141        && m->llRegistryIDs.size() > 0)
     3142        fAdd = false;
    31393143
    31403144    // no need to add the UUID twice
    3141     for (GuidList::const_iterator it = m->llRegistryIDs.begin();
    3142          it != m->llRegistryIDs.end();
    3143          ++it)
    3144     {
    3145         if ((*it) == id)
    3146             return false;
    3147     }
    3148 
    3149     addRegistryImpl(id, fRecurse);
    3150 
    3151     return true;
    3152 }
    3153 
    3154 /**
    3155  * Private implementation for addRegistry() so we can recurse more efficiently.
    3156  * @param id
    3157  * @param fRecurse
    3158  */
    3159 void Medium::addRegistryImpl(const Guid& id, bool fRecurse)
    3160 {
    3161     m->llRegistryIDs.push_back(id);
     3145    if (fAdd)
     3146    {
     3147        for (GuidList::const_iterator it = m->llRegistryIDs.begin();
     3148             it != m->llRegistryIDs.end();
     3149             ++it)
     3150        {
     3151            if ((*it) == id)
     3152            {
     3153                fAdd = false;
     3154                break;
     3155            }
     3156        }
     3157    }
     3158
     3159    if (fAdd)
     3160        m->llRegistryIDs.push_back(id);
    31623161
    31633162    if (fRecurse)
    31643163    {
    3165         for (MediaList::iterator it = m->llChildren.begin();
    3166              it != m->llChildren.end();
     3164        // Get private list of children and release medium lock straight away.
     3165        MediaList llChildren(m->llChildren);
     3166        alock.release();
     3167
     3168        for (MediaList::iterator it = llChildren.begin();
     3169             it != llChildren.end();
    31673170             ++it)
    31683171        {
    31693172            Medium *pChild = *it;
    3170             // recurse!
    3171             pChild->addRegistryImpl(id, fRecurse);
    3172         }
    3173     }
     3173            fAdd |= pChild->addRegistry(id, true);
     3174        }
     3175    }
     3176
     3177    return fAdd;
    31743178}
    31753179
     
    31783182 * if found or false if not.
    31793183 *
    3180  * Must have caller + locking!
    3181  *
    3182  * If fRecurse == true, then additionally the media tree lock must be held for reading.
     3184 * If fRecurse == true, then the media tree lock must be held for reading.
    31833185 *
    31843186 * @param id
     
    31883190bool Medium::removeRegistry(const Guid& id, bool fRecurse)
    31893191{
     3192    AutoCaller autoCaller(this);
     3193    if (FAILED(autoCaller.rc()))
     3194        return false;
     3195    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     3196
     3197    bool fRemove = false;
     3198
    31903199    for (GuidList::iterator it = m->llRegistryIDs.begin();
    31913200         it != m->llRegistryIDs.end();
     
    31953204        {
    31963205            m->llRegistryIDs.erase(it);
    3197 
    3198             if (fRecurse)
    3199             {
    3200                 for (MediaList::iterator it2 = m->llChildren.begin();
    3201                      it2 != m->llChildren.end();
    3202                      ++it2)
    3203                 {
    3204                     Medium *pChild = *it2;
    3205                     pChild->removeRegistry(id, true);
    3206                 }
    3207             }
    3208 
    3209             return true;
    3210         }
    3211     }
    3212 
    3213     return false;
     3206            fRemove = true;
     3207            break;
     3208        }
     3209    }
     3210
     3211    if (fRecurse)
     3212    {
     3213        // Get private list of children and release medium lock straight away.
     3214        MediaList llChildren(m->llChildren);
     3215        alock.release();
     3216
     3217        for (MediaList::iterator it = llChildren.begin();
     3218             it != llChildren.end();
     3219             ++it)
     3220        {
     3221            Medium *pChild = *it;
     3222            fRemove |= pChild->removeRegistry(id, true);
     3223        }
     3224    }
     3225
     3226    return fRemove;
    32143227}
    32153228
     
    32173230 * Returns true if id is in the list of media registries for this medium.
    32183231 *
    3219  * Must have caller + locking!
     3232 * Must have caller + read locking!
    32203233 *
    32213234 * @param id
     
    32243237bool Medium::isInRegistry(const Guid& id)
    32253238{
    3226     AutoCaller autoCaller(this);
    3227     if (FAILED(autoCaller.rc())) return false;
    3228 
    3229     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    3230 
    32313239    for (GuidList::const_iterator it = m->llRegistryIDs.begin();
    32323240         it != m->llRegistryIDs.end();
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