VirtualBox

Changeset 13405 in vbox for trunk/src


Ignore:
Timestamp:
Oct 20, 2008 7:49:09 PM (16 years ago)
Author:
vboxsync
Message:

Main: report unexpected failures when spawning a remote session

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

Legend:

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

    r13372 r13405  
    31143114
    31153115/**
     3116 *  Called from the client watcher thread to check for unexpected client
     3117 *  process death during Session_Spawning state.
     3118 *
     3119 *  @note On Win32 and on OS/2, this method is called only when we've got the
     3120 *  mutex (i.e. the client has either died or terminated normally). This
     3121 *  method always returns true.
     3122 *
     3123 *  @note On Linux, the method returns true if the client process has
     3124 *  terminated abnormally (and/or the session has been uninitialized) and
     3125 *  false if it is still alive.
     3126 *
     3127 *  @note Locks this object for writing.
     3128 */
     3129bool Machine::checkForSpawnFailure()
     3130{
     3131    AutoCaller autoCaller (this);
     3132    if (!autoCaller.isOk())
     3133    {
     3134        /* nothing to do */
     3135        LogFlowThisFunc (("Already uninitialized!"));
     3136        return true;
     3137    }
     3138
     3139    /* VirtualBox::addProcessToReap() needs a write lock */
     3140    AutoMultiWriteLock2 alock (mParent, this);
     3141
     3142    if (mData->mSession.mState != SessionState_Spawning)
     3143    {
     3144        /* nothing to do */
     3145        LogFlowThisFunc (("Not spawning any more!"));
     3146        return true;
     3147    }
     3148
     3149    HRESULT rc = S_OK;
     3150
     3151    RTPROCSTATUS status;
     3152    int vrc = ::RTProcWait (mData->mSession.mPid, RTPROCWAIT_FLAGS_NOBLOCK,
     3153                            &status);
     3154
     3155    if (vrc != VERR_PROCESS_RUNNING)
     3156        rc = setError (E_FAIL,
     3157                       tr ("The virtual machine '%ls' terminated unexpectedly during startup"),
     3158                       name().raw());
     3159
     3160    if (FAILED (rc))
     3161    {
     3162        /* Remove the remote control from the list on failure
     3163         * and reset session state to Closed. */
     3164        mData->mSession.mRemoteControls.clear();
     3165        mData->mSession.mState = SessionState_Closed;
     3166
     3167        /* finalize the progress after setting the state, for consistency */
     3168        mData->mSession.mProgress->notifyComplete (rc);
     3169        mData->mSession.mProgress.setNull();
     3170
     3171        mParent->addProcessToReap (mData->mSession.mPid);
     3172        mData->mSession.mPid = NIL_RTPROCESS;
     3173
     3174        mParent->onSessionStateChange (mData->mUuid, SessionState_Closed);
     3175        return true;
     3176    }
     3177
     3178    return false;
     3179}
     3180
     3181/**
    31163182 *  Saves the registry entry of this machine to the given configuration node.
    31173183 *
  • trunk/src/VBox/Main/VirtualBoxImpl.cpp

    r12284 r13405  
    21382138        progress.queryInterfaceTo (aProgress);
    21392139
     2140        /* signal the client watcher thread */
     2141        updateClientWatcher();
     2142
    21402143        /* fire an event */
    21412144        onSessionStateChange (aMachineId, SessionState_Spawning);
     
    29322935
    29332936    aVector = SessionMachineVector (list.begin(), list.end());
     2937    return;
     2938}
     2939
     2940/**
     2941 *  Returns the list of opened machines (i.e. machines having direct sessions
     2942 *  opened by client processes).
     2943 *
     2944 *  @note the returned list contains smart pointers. So, clear it as soon as
     2945 *  it becomes no more necessary to release instances.
     2946 *  @note it can be possible that a session machine from the list has been
     2947 *  already uninitialized, so a) lock the instance and b) chheck for
     2948 *  instance->isReady() return value before manipulating the object directly
     2949 *  (i.e. not through COM methods).
     2950 *
     2951 *  @note Locks objects for reading.
     2952 */
     2953void VirtualBox::getSpawnedMachines (MachineVector &aVector)
     2954{
     2955    AutoCaller autoCaller (this);
     2956    AssertComRCReturn (autoCaller.rc(), (void) 0);
     2957
     2958    std::list <ComObjPtr <Machine> > list;
     2959
     2960    {
     2961        AutoReadLock alock (this);
     2962
     2963        for (MachineList::iterator it = mData.mMachines.begin();
     2964             it != mData.mMachines.end();
     2965             ++ it)
     2966        {
     2967            ComObjPtr <Machine> m = (*it);
     2968            SessionState_T state;
     2969            m->COMGETTER(SessionState(&state));
     2970            if (state == SessionState_Spawning)
     2971                list.push_back (m);
     2972        }
     2973    }
     2974
     2975    aVector = MachineVector (list.begin(), list.end());
    29342976    return;
    29352977}
     
    46374679
    46384680    SessionMachineVector machines;
     4681    MachineVector spawnedMachines;
    46394682    size_t cnt = 0;
     4683    size_t cntSpawned = 0;
    46404684
    46414685#if defined(RT_OS_WINDOWS)
     
    47054749                for (size_t i = 0; i < cnt; ++ i)
    47064750                    handles [i + 1] = (machines [i])->ipcSem();
     4751
     4752#if 0 /* untested */
     4753                /* check for spawn errors */
     4754                that->getSpawnedMachines (spawnedMachines);
     4755                cntSpawned = spawnedMachines.size();
     4756                for (size_t i = 0; i < cntSpawned; ++ i)
     4757                    (spawnedMachines [i])->checkForSpawnFailure();
     4758#endif
    47074759            }
    47084760        }
     
    49054957            for (size_t i = 0; i < cnt; ++ i)
    49064958                need_update |= (machines [i])->checkForDeath();
     4959
     4960            that->getSpawnedMachines (spawnedMachines);
     4961            cntSpawned = spawnedMachines.size();
     4962
     4963            for (size_t i = 0; i < cntSpawned; ++ i)
     4964                (spawnedMachines [i])->checkForSpawnFailure();
    49074965
    49084966            /* reap child processes */
  • trunk/src/VBox/Main/include/MachineImpl.h

    r13356 r13405  
    552552    // public methods only for internal purposes
    553553
     554    //
     555    //  Called from the client watcher thread to check for unexpected client
     556    //  process death during Session_Spawning state.
     557    //
     558    bool checkForSpawnFailure();
     559
    554560    /// @todo (dmik) add lock and make non-inlined after revising classes
    555561    //  that use it. Note: they should enter Machine lock to keep the returned
     
    854860
    855861    bool checkForDeath();
     862    bool checkForSpawnFailure();
    856863
    857864#if defined (RT_OS_WINDOWS)
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r12284 r13405  
    230230
    231231    typedef std::vector <ComObjPtr <SessionMachine> > SessionMachineVector;
     232    typedef std::vector <ComObjPtr <Machine> > MachineVector;
    232233    void getOpenedMachines (SessionMachineVector &aVector);
     234    void getSpawnedMachines (MachineVector &aVector);
    233235
    234236    bool isMachineIdValid (const Guid &aId)
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