VirtualBox

Changeset 8388 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 25, 2008 2:27:15 PM (17 years ago)
Author:
vboxsync
Message:

Main: Fixed very old regression: Failure to lock the machine settings file was not properly reported which led to assertions in debug build or to misbehavior in release builds. Examples of such failure were renaming the settings file manually or moving the machine directory w/o unregistering.

File:
1 edited

Legend:

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

    r8311 r8388  
    121121{
    122122    mRegistered = FALSE;
     123    mAccessible = FALSE;
    123124    /* mUuid is initialized in Machine::init() */
    124125
     
    400401    mData->mConfigFileFull = configFileFull;
    401402
    402     /* start with accessible */
    403     mData->mAccessible = TRUE;
    404 
    405     if (aMode != Init_New)
    406     {
    407         /* lock the settings file */
    408         rc = lockConfig();
    409 
    410         if (aMode == Init_Registered && FAILED (rc))
    411         {
    412             /* If the machine is registered, then, instead of returning a
    413              * failure, we mark it as inaccessible and set the result to
    414              * success to give it a try later */
    415             mData->mAccessible = FALSE;
    416             /* fetch the current error info */
    417             mData->mAccessError = com::ErrorInfo();
    418             LogWarning (("Machine {%Vuuid} is inaccessible! [%ls]\n",
    419                          mData->mUuid.raw(),
    420                          mData->mAccessError.getText().raw()));
    421             rc = S_OK;
    422         }
    423     }
    424     else
    425     {
    426         /* check for the file existence */
    427         RTFILE f = NIL_RTFILE;
    428         int vrc = RTFileOpen (&f, configFileFull, RTFILE_O_READ);
    429         if (VBOX_SUCCESS (vrc) || vrc == VERR_SHARING_VIOLATION)
    430         {
    431             rc = setError (E_FAIL,
    432                 tr ("Settings file '%s' already exists"), configFileFull);
    433             if (VBOX_SUCCESS (vrc))
    434                 RTFileClose (f);
    435         }
    436         else
    437         {
    438             if (vrc != VERR_FILE_NOT_FOUND && vrc != VERR_PATH_NOT_FOUND)
    439                 rc = setError (E_FAIL,
    440                     tr ("Invalid settings file name: '%ls' (%Vrc)"),
    441                         mData->mConfigFileFull.raw(), vrc);
    442         }
    443 
    444         /* reset mAccessible to make sure uninit() called by the AutoInitSpan
    445          * destructor will not call uninitDataAndChildObjects() (we haven't
    446          * initialized anything yet) */
    447         if (FAILED (rc))
    448             mData->mAccessible = FALSE;
    449     }
    450 
    451     CheckComRCReturnRC (rc);
    452 
    453403    if (aMode == Init_Registered)
    454404    {
     405        mData->mRegistered = TRUE;
     406
    455407        /* store the supplied UUID (will be used to check for UUID consistency
    456408         * in loadSettings() */
    457409        unconst (mData->mUuid) = *aId;
    458         /* try to  load settings only if the settings file is accessible */
    459         if (mData->mAccessible)
    460             rc = registeredInit();
     410        rc = registeredInit();
    461411    }
    462412    else
    463413    {
    464         rc = initDataAndChildObjects();
     414        if (aMode == Init_Existing)
     415        {
     416            /* lock the settings file */
     417            rc = lockConfig();
     418        }
     419        else if (aMode == Init_New)
     420        {
     421            /* check for the file existence */
     422            RTFILE f = NIL_RTFILE;
     423            int vrc = RTFileOpen (&f, configFileFull, RTFILE_O_READ);
     424            if (VBOX_SUCCESS (vrc) || vrc == VERR_SHARING_VIOLATION)
     425            {
     426                rc = setError (E_FAIL,
     427                    tr ("Settings file '%s' already exists"), configFileFull);
     428                if (VBOX_SUCCESS (vrc))
     429                    RTFileClose (f);
     430            }
     431            else
     432            {
     433                if (vrc != VERR_FILE_NOT_FOUND && vrc != VERR_PATH_NOT_FOUND)
     434                    rc = setError (E_FAIL,
     435                        tr ("Invalid settings file name: '%ls' (%Vrc)"),
     436                            mData->mConfigFileFull.raw(), vrc);
     437            }
     438        }
     439        else
     440            AssertFailed();
    465441
    466442        if (SUCCEEDED (rc))
    467         {
     443            rc = initDataAndChildObjects();
     444
     445        if (SUCCEEDED (rc))
     446        {
     447            /* set to true now to cause uninit() to call
     448             * uninitDataAndChildObjects() on failure */
     449            mData->mAccessible = TRUE;
     450
    468451            if (aMode != Init_New)
    469452            {
     
    529512    AssertReturn (mType == IsMachine, E_FAIL);
    530513    AssertReturn (!mData->mUuid.isEmpty(), E_FAIL);
    531 
    532     HRESULT rc = initDataAndChildObjects();
    533     CheckComRCReturnRC (rc);
    534 
    535     if (!mData->mAccessible)
    536         rc = lockConfig();
    537 
    538     /* Temporarily reset the registered flag in order to let setters potentially
    539      * called from loadSettings() succeed (isMutable() used in all setters
    540      * will return FALSE for a Machine instance if mRegistered is TRUE). */
    541     mData->mRegistered = FALSE;
     514    AssertReturn (!mData->mAccessible, E_FAIL);
     515
     516    HRESULT rc = lockConfig();
    542517
    543518    if (SUCCEEDED (rc))
    544     {
     519        rc = initDataAndChildObjects();
     520
     521    if (SUCCEEDED (rc))
     522    {
     523        /* Temporarily reset the registered flag in order to let setters
     524         * potentially called from loadSettings() succeed (isMutable() used in
     525         * all setters will return FALSE for a Machine instance if mRegistered
     526         * is TRUE). */
     527        mData->mRegistered = FALSE;
     528
    545529        rc = loadSettings (true /* aRegistered */);
     530
     531        /* Restore the registered flag (even on failure) */
     532        mData->mRegistered = TRUE;
    546533
    547534        if (FAILED (rc))
     
    551538    if (SUCCEEDED (rc))
    552539    {
     540        /* Set mAccessible to TRUE only if we successfully locked and loaded
     541         * the settings file */
    553542        mData->mAccessible = TRUE;
    554543
     
    565554         * failure, we mark it as inaccessible and set the result to
    566555         * success to give it a try later */
    567         mData->mAccessible = FALSE;
     556
    568557        /* fetch the current error info */
    569558        mData->mAccessError = com::ErrorInfo();
     
    581570        rc = S_OK;
    582571    }
    583 
    584     /* Restore the registered flag (even on failure) */
    585     mData->mRegistered = TRUE;
    586572
    587573    return rc;
     
    36703656
    36713657/**
    3672  *  Helper to initialize all associated child objects
    3673  *  and allocate data structures.
    3674  *
    3675  *  This method must be called as a part of the object's initialization
    3676  *  procedure (usually done in the #init() method).
    3677  *
    3678  *  @note Must be called only from #init() or from #registeredInit().
     3658 * Helper to initialize all associated child objects and allocate data
     3659 * structures.
     3660 *
     3661 * This method must be called as a part of the object's initialization procedure
     3662 * (usually done in the #init() method).
     3663 *
     3664 * @note Must be called only from #init() or from #registeredInit().
    36793665 */
    36803666HRESULT Machine::initDataAndChildObjects()
     
    36843670    AssertComRCReturn (autoCaller.state() == InInit ||
    36853671                       autoCaller.state() == Limited, E_FAIL);
     3672
     3673    AssertReturn (!mData->mAccessible, E_FAIL);
    36863674
    36873675    /* allocate data structures */
     
    37493737
    37503738/**
    3751  *  Helper to uninitialize all associated child objects
    3752  *  and to free all data structures.
    3753  *
    3754  *  This method must be called as a part of the object's uninitialization
    3755  *  procedure (usually done in the #uninit() method).
    3756  *
    3757  *  @note Must be called only from #uninit() or from #registeredInit().
     3739 * Helper to uninitialize all associated child objects and to free all data
     3740 * structures.
     3741 *
     3742 * This method must be called as a part of the object's uninitialization
     3743 * procedure (usually done in the #uninit() method).
     3744 *
     3745 * @note Must be called only from #uninit() or from #registeredInit().
    37583746 */
    37593747void Machine::uninitDataAndChildObjects()
     
    67006688                              RTFILE_O_DENY_WRITE);
    67016689        if (VBOX_FAILURE (vrc))
     6690        {
    67026691            mData->mHandleCfgFile = NIL_RTFILE;
     6692
     6693            rc = setError (E_FAIL,
     6694                tr ("Could not lock the settings file '%ls' (%Vrc)"),
     6695                mData->mConfigFileFull.raw(), vrc);
     6696        }
    67036697    }
    67046698
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