VirtualBox

Changeset 55167 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 9, 2015 5:25:33 PM (10 years ago)
Author:
vboxsync
Message:

Main/Machine: Add support for launching separate UI/VM setups. Technically speaking the launch of the UI part is outside the scope of IMachine::launchVMProcess, but overall it fits there rather well as the overall result is that a VM process gets started.

File:
1 edited

Legend:

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

    r55120 r55167  
    73667366    LogFlowThisFunc(("mSession.mState=%s\n", Global::stringifySessionState(mData->mSession.mState)));
    73677367
    7368     if (    mData->mSession.mState == SessionState_Locked
    7369          || mData->mSession.mState == SessionState_Spawning
    7370          || mData->mSession.mState == SessionState_Unlocking)
    7371         return setError(VBOX_E_INVALID_OBJECT_STATE,
    7372                         tr("The machine '%s' is already locked by a session (or being locked or unlocked)"),
    7373                         mUserData->s.strName.c_str());
    7374 
    7375     /* may not be busy */
    7376     AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
     7368    /* The process started when launching a VM with separate UI/VM processes is always
     7369     * the UI process, i.e. needs special handling as it won't claim the session. */
     7370    bool fSeparate = strFrontend.endsWith("separate", Utf8Str::CaseInsensitive);
     7371
     7372    if (fSeparate)
     7373    {
     7374        if (mData->mSession.mState != SessionState_Unlocked && mData->mSession.mType != "headless")
     7375            return setError(VBOX_E_INVALID_OBJECT_STATE,
     7376                            tr("The machine '%s' is in a state which is incompatible with launching a separate UI process"),
     7377                            mUserData->s.strName.c_str());
     7378    }
     7379    else
     7380    {
     7381        if (    mData->mSession.mState == SessionState_Locked
     7382             || mData->mSession.mState == SessionState_Spawning
     7383             || mData->mSession.mState == SessionState_Unlocking)
     7384            return setError(VBOX_E_INVALID_OBJECT_STATE,
     7385                            tr("The machine '%s' is already locked by a session (or being locked or unlocked)"),
     7386                            mUserData->s.strName.c_str());
     7387
     7388        /* may not be busy */
     7389        AssertReturn(!Global::IsOnlineOrTransient(mData->mMachineState), E_FAIL);
     7390    }
    73777391
    73787392    /* get the path to the executable */
     
    74617475
    74627476#ifdef VBOX_WITH_QTGUI
    7463     if (strFrontend == "gui" || strFrontend == "GUI/Qt")
     7477    if (   !strFrontend.compare("gui", Utf8Str::CaseInsensitive)
     7478        || !strFrontend.compare("GUI/Qt", Utf8Str::CaseInsensitive)
     7479        || !strFrontend.compare("separate", Utf8Str::CaseInsensitive)
     7480        || !strFrontend.compare("gui/separate", Utf8Str::CaseInsensitive)
     7481        || !strFrontend.compare("GUI/Qt/separate", Utf8Str::CaseInsensitive))
    74647482    {
    74657483# ifdef RT_OS_DARWIN /* Avoid Launch Services confusing this with the selector by using a helper app. */
     
    75077525            "--startvm", idStr.c_str(),
    75087526            "--no-startvm-errormsgbox",
    7509             pszSupStartupLogArg,
     7527            NULL, /* For "--separate". */
     7528            NULL, /* For "--sup-startup-log". */
    75107529            NULL
    75117530        };
     7531        unsigned iArg = 6;
     7532        if (fSeparate)
     7533            apszArgs[iArg++] = "--separate";
     7534        apszArgs[iArg++] = pszSupStartupLogArg;
     7535
    75127536        vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid);
    75137537    }
     
    75207544
    75217545#ifdef VBOX_WITH_VBOXSDL
    7522     if (strFrontend == "sdl" || strFrontend == "GUI/SDL")
     7546    if (   !strFrontend.compare("sdl", Utf8Str::CaseInsensitive)
     7547        || !strFrontend.compare("GUI/SDL", Utf8Str::CaseInsensitive)
     7548        || !strFrontend.compare("sdl/separate", Utf8Str::CaseInsensitive)
     7549        || !strFrontend.compare("GUI/SDL/separate", Utf8Str::CaseInsensitive))
    75237550    {
    75247551        static const char s_szVBoxSDL_exe[] = "VBoxSDL" HOSTSUFF_EXE;
     
    75327559            "--comment", mUserData->s.strName.c_str(),
    75337560            "--startvm", idStr.c_str(),
    7534             pszSupStartupLogArg,
     7561            NULL, /* For "--separate". */
     7562            NULL, /* For "--sup-startup-log". */
    75357563            NULL
    75367564        };
     7565        unsigned iArg = 5;
     7566        if (fSeparate)
     7567            apszArgs[iArg++] = "--separate";
     7568        apszArgs[iArg++] = pszSupStartupLogArg;
     7569
    75377570        vrc = RTProcCreate(szPath, apszArgs, env, 0, &pid);
    75387571    }
     
    75457578
    75467579#ifdef VBOX_WITH_HEADLESS
    7547     if (   strFrontend == "headless"
    7548         || strFrontend == "capture"
    7549         || strFrontend == "vrdp" /* Deprecated. Same as headless. */
     7580    if (   !strFrontend.compare("headless", Utf8Str::CaseInsensitive)
     7581        || !strFrontend.compare("capture", Utf8Str::CaseInsensitive)
     7582        || !strFrontend.compare("vrdp", Utf8Str::CaseInsensitive) /* Deprecated. Same as headless. */
    75507583       )
    75517584    {
     
    75687601            "--startvm", idStr.c_str(),
    75697602            "--vrde", "config",
    7570             0, /* For "--capture". */
    7571             0, /* For "--sup-startup-log". */
    7572             0
     7603            NULL, /* For "--capture". */
     7604            NULL, /* For "--sup-startup-log". */
     7605            NULL
    75737606        };
    75747607        unsigned iArg = 7;
    7575         if (strFrontend == "capture")
     7608        if (!strFrontend.compare("capture", Utf8Str::CaseInsensitive))
    75767609            apszArgs[iArg++] = "--capture";
    75777610        apszArgs[iArg++] = pszSupStartupLogArg;
     
    76047637    LogFlowThisFunc(("launched.pid=%d(0x%x)\n", pid, pid));
    76057638
    7606     /*
    7607      *  Note that we don't release the lock here before calling the client,
    7608      *  because it doesn't need to call us back if called with a NULL argument.
    7609      *  Releasing the lock here is dangerous because we didn't prepare the
    7610      *  launch data yet, but the client we've just started may happen to be
    7611      *  too fast and call LockMachine() that will fail (because of PID, etc.),
    7612      *  so that the Machine will never get out of the Spawning session state.
    7613      */
    7614 
    7615     /* inform the session that it will be a remote one */
    7616     LogFlowThisFunc(("Calling AssignMachine (NULL)...\n"));
     7639    if (!fSeparate)
     7640    {
     7641        /*
     7642         *  Note that we don't release the lock here before calling the client,
     7643         *  because it doesn't need to call us back if called with a NULL argument.
     7644         *  Releasing the lock here is dangerous because we didn't prepare the
     7645         *  launch data yet, but the client we've just started may happen to be
     7646         *  too fast and call LockMachine() that will fail (because of PID, etc.),
     7647         *  so that the Machine will never get out of the Spawning session state.
     7648         */
     7649
     7650        /* inform the session that it will be a remote one */
     7651        LogFlowThisFunc(("Calling AssignMachine (NULL)...\n"));
    76177652#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
    7618     HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, Bstr::Empty.raw());
     7653        HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, Bstr::Empty.raw());
    76197654#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
    7620     HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, NULL);
     7655        HRESULT rc = aControl->AssignMachine(NULL, LockType_Write, NULL);
    76217656#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
    7622     LogFlowThisFunc(("AssignMachine (NULL) returned %08X\n", rc));
    7623 
    7624     if (FAILED(rc))
    7625     {
    7626         /* restore the session state */
    7627         mData->mSession.mState = SessionState_Unlocked;
    7628         alock.release();
    7629         mParent->i_addProcessToReap(pid);
    7630         /* The failure may occur w/o any error info (from RPC), so provide one */
    7631         return setError(VBOX_E_VM_ERROR,
    7632                         tr("Failed to assign the machine to the session (%Rhrc)"), rc);
    7633     }
    7634 
    7635     /* attach launch data to the machine */
    7636     Assert(mData->mSession.mPID == NIL_RTPROCESS);
    7637     mData->mSession.mRemoteControls.push_back(aControl);
    7638     mData->mSession.mProgress = aProgress;
    7639     mData->mSession.mPID = pid;
    7640     mData->mSession.mState = SessionState_Spawning;
    7641     mData->mSession.mType = strFrontend;
     7657        LogFlowThisFunc(("AssignMachine (NULL) returned %08X\n", rc));
     7658
     7659        if (FAILED(rc))
     7660        {
     7661            /* restore the session state */
     7662            mData->mSession.mState = SessionState_Unlocked;
     7663            alock.release();
     7664            mParent->i_addProcessToReap(pid);
     7665            /* The failure may occur w/o any error info (from RPC), so provide one */
     7666            return setError(VBOX_E_VM_ERROR,
     7667                            tr("Failed to assign the machine to the session (%Rhrc)"), rc);
     7668        }
     7669
     7670        /* attach launch data to the machine */
     7671        Assert(mData->mSession.mPID == NIL_RTPROCESS);
     7672        mData->mSession.mRemoteControls.push_back(aControl);
     7673        mData->mSession.mProgress = aProgress;
     7674        mData->mSession.mPID = pid;
     7675        mData->mSession.mState = SessionState_Spawning;
     7676        mData->mSession.mType = strFrontend;
     7677    }
     7678    else
     7679    {
     7680        /* For separate UI process we declare the launch as completed instantly, as the
     7681         * actual headless VM start may or may not come. No point in remembering anything
     7682         * yet, as what matters for us is when the headless VM gets started. */
     7683        aProgress->i_notifyComplete(S_OK);
     7684    }
    76427685
    76437686    alock.release();
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