VirtualBox

Changeset 102614 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Dec 15, 2023 4:10:30 PM (12 months ago)
Author:
vboxsync
Message:

Guest Control: Keep a COM object reference to the guest and console objects, so that we can easier access those when needed. Also added a IGuestSession::i_isReady() function that checks the current VM state. This should help wrt closing a guest sessions when the VM already is in a transient state, for instance while a guest session is left open and a VM snapshot is being taken. Should fix the guest session re-connection issues after a VM shutdown + saved state has been taken with FE/Qt's file manager.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r102533 r102614  
    221221     * Initialize our data members from the input.
    222222     */
    223     mParent = pGuest;
     223    mParent  = pGuest;
     224    mConsole = pGuest->i_getConsole();
    224225
    225226    /* Copy over startup info. */
     
    14401441    alock.release();
    14411442
    1442     Console *pConsole = mParent->i_getConsole();
    1443     AssertPtr(pConsole);
    1444 
    1445     vrc = pDirectory->init(pConsole, this /* Parent */, idObject, openInfo);
     1443    vrc = pDirectory->init(mConsole, this /* Parent */, idObject, openInfo);
    14461444    if (RT_SUCCESS(vrc))
    14471445        vrc = pDirectory->i_open(pvrcGuest);
     
    19231921    }
    19241922
    1925     Console *pConsole = mParent->i_getConsole();
    1926     AssertPtr(pConsole);
    1927 
    1928     vrc = pFile->init(pConsole, this /* GuestSession */, idObject, openInfo);
     1923    vrc = pFile->init(mConsole, this /* GuestSession */, idObject, openInfo);
    19291924    if (RT_FAILURE(vrc))
    19301925        return vrc;
     
    23082303
    23092304/**
    2310  * Checks if this session is ready state where it can handle
     2305 * Checks if this session is in a ready state where it can handle
    23112306 * all session-bound actions (like guest processes, guest files).
    2312  * Only used by official API methods. Will set an external
    2313  * error when not ready.
     2307 *
     2308 * Only used by official API methods.
     2309 * Takes the read lock.
     2310 *
     2311 * @returns S_OK if ready, E_FAIL if not.
     2312 * @note    Will set an external error when not ready.
    23142313 */
    23152314HRESULT GuestSession::i_isStartedExternal(void)
     
    23172316    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    23182317
    2319     /** @todo Be a bit more informative. */
    23202318    if (!i_isStarted())
    2321         return setError(E_UNEXPECTED, tr("Session is not in started state"));
    2322 
     2319        return setError(E_FAIL, tr("Session is not in started state (state is '%s')",
     2320                                   Global::stringifyGuestSessionStatus(mData.mStatus)));
    23232321    return S_OK;
     2322}
     2323
     2324/**
     2325 * Returns if this session is in a ready-to-use state or not.
     2326 *
     2327 * @returns \c true if ready, or \c false if not.
     2328 */
     2329bool GuestSession::i_isReady(void)
     2330{
     2331    /* Check if the VM has the right machine state we can operate with. Also make sure that
     2332     * the VM is in an online *and* non-transient state while at it.
     2333     *
     2334     * This for instance is required if we want to close a guest session while the VM state is being saved or
     2335     * is doing some other lenghtly operations we can't operate with the guest.
     2336     */
     2337    MachineState_T enmMachineState = MachineState_Null;
     2338    HRESULT hrc = mConsole->COMGETTER(State)(&enmMachineState);
     2339    ComAssertComRCRet(hrc, false);
     2340    if (   !Global::IsOnline(enmMachineState)
     2341        ||  Global::IsTransient(enmMachineState))
     2342        return false;
     2343
     2344    return true;
    23242345}
    23252346
     
    32773298    }
    32783299
    3279     vrc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, idObject, procInfo, mData.mpBaseEnvironment);
     3300    vrc = pProcess->init(mConsole, this /* Session */, idObject, procInfo, mData.mpBaseEnvironment);
    32803301    if (RT_FAILURE(vrc))
    32813302        return vrc;
     
    33633384 *
    33643385 * @returns VBox status code.
     3386 * @retval  VERR_VM_INVALID_VM_STATE if the VM is in a state where can't send message to the guest (anymore).
    33653387 * @param   uMessage            Message ID to send.
    33663388 * @param   uParms              Number of parameters in \a paParms to send.
     
    33743396
    33753397#ifndef VBOX_GUESTCTRL_TEST_CASE
    3376     AutoCaller autoCallerParent(mParent);
    3377     if (FAILED(autoCallerParent.hrc()))
    3378         return VERR_STATE_CHANGED;
    3379 
    3380     ComObjPtr<Console> pConsole = mParent->i_getConsole();
    3381     Assert(!pConsole.isNull());
     3398    VMMDev *pVMMDev = mConsole->i_getVMMDev();
     3399    AssertPtrReturn(pVMMDev, VERR_VM_INVALID_VM_STATE);
    33823400
    33833401    /* Forward the information to the VMM device. */
    3384     VMMDev *pVMMDev = pConsole->i_getVMMDev();
    3385     if (!pVMMDev)
    3386         return VERR_STATE_CHANGED;
    3387 
    33883402    LogFlowThisFunc(("uMessage=%RU32 (%s), uParms=%RU32\n", uMessage, GstCtrlHostMsgtoStr((guestControl::eHostMsg)uMessage), uParms));
    33893403
     
    34933507    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    34943508
    3495     AssertPtrReturn(mParent, VERR_INVALID_POINTER);
    34963509    if (!(mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_SHUTDOWN))
    34973510        return VERR_NOT_SUPPORTED;
     
    38613874    LogFlowThisFuncEnter();
    38623875
     3876    HRESULT hrc = i_isStartedExternal();
     3877    if (FAILED(hrc))
     3878        return hrc;
     3879
     3880    int vrc = VINF_SUCCESS; /* Shut up MSVC. */
     3881
     3882    /* If the guest session is not in an unsable state (anymore), do the cleanup stuff ourselves. */
     3883    if (!i_isReady())
     3884    {
     3885        i_onRemove();
     3886        return S_OK;
     3887    }
     3888
    38633889    /* Note: Don't check if the session is ready via i_isStartedExternal() here;
    38643890     *       the session (already) could be in a stopped / aborted state. */
    38653891
    3866     int vrc      = VINF_SUCCESS; /* Shut up MSVC. */
    38673892    int vrcGuest = VINF_SUCCESS;
    38683893
     
    38893914    /* We have to make sure that our parent (IGuest) still is alive and in a working shapee.
    38903915     * If not, skip removing the session from it. */
    3891     AutoCaller autoCallerParent(mParent);
    3892     if (SUCCEEDED(autoCallerParent.hrc()))
    3893     {
    3894         LogFlowThisFunc(("Removing session '%s' from parent ...", mData.mSession.mName.c_str()));
    3895 
    3896         /* Remove ourselves from the session list. */
    3897         AssertPtr(mParent);
    3898         int vrc2 = mParent->i_sessionRemove(mData.mSession.mID);
    3899         if (vrc2 == VERR_NOT_FOUND) /* Not finding the session anymore isn't critical. */
    3900             vrc2 = VINF_SUCCESS;
    3901 
    3902         if (RT_SUCCESS(vrc))
    3903             vrc = vrc2;
    3904     }
    3905     else /* Do the session remove stuff ourselves. */
    3906         vrc = i_onRemove();
     3916    LogFlowThisFunc(("Removing session '%s' from parent ...", mData.mSession.mName.c_str()));
     3917
     3918    /* Remove ourselves from the session list. */
     3919    int vrc2 = mParent->i_sessionRemove(mData.mSession.mID);
     3920    if (vrc2 == VERR_NOT_FOUND) /* Not finding the session anymore isn't critical. */
     3921        vrc2 = VINF_SUCCESS;
     3922
     3923    if (RT_SUCCESS(vrc))
     3924        vrc = vrc2;
    39073925
    39083926    LogFlowThisFunc(("Returning vrc=%Rrc, vrcGuest=%Rrc\n", vrc, vrcGuest));
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