VirtualBox

Changeset 41231 in vbox for trunk


Ignore:
Timestamp:
May 10, 2012 11:27:52 AM (13 years ago)
Author:
vboxsync
Message:

Main/VirtualBox: very tricky fix for renaming linked clones (media registry needs saving) which avoids locking problems by using a separate thread

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

Legend:

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

    r40466 r41231  
    182182    bool isInRegistry(const Guid& id);
    183183    bool getFirstRegistryMachineId(Guid &uuid) const;
     184    void markRegistriesModified();
    184185
    185186    HRESULT addBackReference(const Guid &aMachineId,
     
    268269    HRESULT canClose();
    269270    HRESULT unregisterWithVirtualBox();
    270     void markRegistriesModified();
    271271
    272272    HRESULT setStateError();
  • trunk/src/VBox/Main/src-server/MediumImpl.cpp

    r41003 r41231  
    36003600
    36013601        LogFlowThisFunc(("locationFull.after='%s'\n", m->strLocationFull.c_str()));
    3602     }
    3603 
    3604     return S_OK;
     3602        // we changed something
     3603        return S_OK;
     3604    }
     3605
     3606    // no change was necessary, signal error which the caller needs to interpret
     3607    return VBOX_E_FILE_ERROR;
    36053608}
    36063609
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r41214 r41231  
    32643264}
    32653265
     3266struct SaveMediaRegistriesDesc
     3267{
     3268    MediaList llMedia;
     3269    ComObjPtr<VirtualBox> pVirtualBox;
     3270};
     3271
     3272static int fntSaveMediaRegistries(RTTHREAD ThreadSelf, void *pvUser)
     3273{
     3274    NOREF(ThreadSelf);
     3275    SaveMediaRegistriesDesc *pDesc = (SaveMediaRegistriesDesc *)pvUser;
     3276    if (!pDesc)
     3277    {
     3278        LogRelFunc(("Thread for saving media registries lacks parameters\n"));
     3279        return VERR_INVALID_PARAMETER;
     3280    }
     3281
     3282    for (MediaList::const_iterator it = pDesc->llMedia.begin();
     3283         it != pDesc->llMedia.end();
     3284         ++it)
     3285    {
     3286        Medium *pMedium = *it;
     3287        pMedium->markRegistriesModified();
     3288    }
     3289
     3290    pDesc->pVirtualBox->saveModifiedRegistries();
     3291
     3292    pDesc->llMedia.clear();
     3293    pDesc->pVirtualBox.setNull();
     3294    delete pDesc;
     3295
     3296    return VINF_SUCCESS;
     3297}
     3298
    32663299/**
    32673300 * Goes through all known media (hard disks, floppies and DVDs) and saves
     
    32913324 * @param mediaRegistry Settings structure to fill.
    32923325 * @param uuidRegistry The UUID of the media registry; either a machine UUID (if machine registry) or the UUID of the global registry.
    3293  * @param hardDiskFolder The machine folder for relative paths, if machine registry, or an empty string otherwise.
     3326 * @param strMachineFolder The machine folder for relative paths, if machine registry, or an empty string otherwise.
    32943327 */
    32953328void VirtualBox::saveMediaRegistry(settings::MediaRegistry &mediaRegistry,
     
    33143347            llAllMedia.push_back(*it);
    33153348
     3349        SaveMediaRegistriesDesc *pDesc = new SaveMediaRegistriesDesc();
    33163350        for (MediaList::iterator it = llAllMedia.begin();
    33173351             it != llAllMedia.end();
     
    33243358            {
    33253359                const Data::PendingMachineRename &pmr = *it2;
    3326                 pMedium->updatePath(pmr.strConfigDirOld,
    3327                                     pmr.strConfigDirNew);
     3360                HRESULT rc = pMedium->updatePath(pmr.strConfigDirOld,
     3361                                                 pmr.strConfigDirNew);
     3362                if (SUCCEEDED(rc))
     3363                {
     3364                    // Remember which medium objects has been changed,
     3365                    // to trigger saving their registries later.
     3366                    pDesc->llMedia.push_back(pMedium);
     3367                } else if (rc == VBOX_E_FILE_ERROR)
     3368                    /* nothing */;
     3369                else
     3370                    AssertComRC(rc);
    33283371            }
    33293372        }
    33303373        // done, don't do it again until we have more machine renames
    33313374        m->llPendingMachineRenames.clear();
     3375
     3376        if (pDesc->llMedia.size())
     3377        {
     3378            // Handle the media registry saving in a separate thread, to
     3379            // avoid giant locking problems and passing up the list many
     3380            // levels up to whoever triggered saveSettings, as there are
     3381            // lots of places which would need to handle saving more settings.
     3382            pDesc->pVirtualBox = this;
     3383            int vrc = RTThreadCreate(NULL,
     3384                                     fntSaveMediaRegistries,
     3385                                     (void *)pDesc,
     3386                                     0,     // cbStack (default)
     3387                                     RTTHREADTYPE_MAIN_WORKER,
     3388                                     0,     // flags
     3389                                     "SaveMediaReg");
     3390            ComAssertRC(vrc);
     3391            // failure means that settings aren't saved, but there isn't
     3392            // much we can do besides avoiding memory leaks
     3393            if (RT_FAILURE(vrc))
     3394            {
     3395                LogRelFunc(("Failed to create thread for saving media registries (%Rrc)\n", vrc));
     3396                delete pDesc;
     3397            }
     3398        }
     3399        else
     3400            delete pDesc;
    33323401    }
    33333402
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