Changeset 36673 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Apr 14, 2011 3:22:37 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r36664 r36673 3044 3044 // this machine is awaiting for a spawning session to be opened: 3045 3045 // then the calling process must be the one that got started by 3046 // launchVMProcess()3046 // LaunchVMProcess() 3047 3047 3048 3048 LogFlowThisFunc(("mSession.mPid=%d(0x%x)\n", mData->mSession.mPid, mData->mSession.mPid)); … … 3052 3052 return setError(E_ACCESSDENIED, 3053 3053 tr("An unexpected process (PID=0x%08X) has tried to lock the " 3054 "machine '%s', while only the process started by launchVMProcess (PID=0x%08X) is allowed"),3054 "machine '%s', while only the process started by LaunchVMProcess (PID=0x%08X) is allowed"), 3055 3055 pid, mUserData->s.strName.c_str(), mData->mSession.mPid); 3056 3056 } … … 3081 3081 * Leave the lock before calling the client process -- it will call 3082 3082 * Machine/SessionMachine methods. Leaving the lock here is quite safe 3083 * because the state is Spawning, so that openRemotesession() and3084 * openExistingSession() calls will fail. This method, called before we3083 * because the state is Spawning, so that LaunchVMProcess() and 3084 * LockMachine() calls will fail. This method, called before we 3085 3085 * enter the lock again, will fail because of the wrong PID. 3086 3086 * … … 3120 3120 { 3121 3121 /* 3122 * after openRemoteSession(), the first and the only3122 * after LaunchVMProcess(), the first and the only 3123 3123 * entry in remoteControls is that remote session 3124 3124 */ … … 3227 3227 IProgress **aProgress) 3228 3228 { 3229 CheckComArgNotNull(aSession); 3229 Utf8Str strType(aType); 3230 Utf8Str strEnvironment(aEnvironment); 3231 3232 /* "emergencystop" doesn't need the session, so skip the checks/interface 3233 * retrieval. This code doesn't quite fit in here, but introducing a 3234 * special API method would be even more effort, and would require explicit 3235 * support by every API client. It's better to hide the feature a bit. */ 3236 if (strType != "emergencystop") 3237 CheckComArgNotNull(aSession); 3230 3238 CheckComArgStrNotEmptyOrNull(aType); 3231 3239 CheckComArgOutPointerValid(aProgress); … … 3234 3242 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 3235 3243 3236 /* check the session state */ 3237 SessionState_T state; 3238 HRESULT rc = aSession->COMGETTER(State)(&state); 3239 if (FAILED(rc)) return rc; 3240 3241 if (state != SessionState_Unlocked) 3242 return setError(VBOX_E_INVALID_OBJECT_STATE, 3243 tr("The given session is busy")); 3244 3245 /* get the IInternalSessionControl interface */ 3246 ComPtr<IInternalSessionControl> control = aSession; 3247 ComAssertMsgRet(!!control, ("No IInternalSessionControl interface"), 3248 E_INVALIDARG); 3244 ComPtr<IInternalSessionControl> control; 3245 HRESULT rc = S_OK; 3246 3247 if (strType != "emergencystop") 3248 { 3249 /* check the session state */ 3250 SessionState_T state; 3251 rc = aSession->COMGETTER(State)(&state); 3252 if (FAILED(rc)) 3253 return rc; 3254 3255 if (state != SessionState_Unlocked) 3256 return setError(VBOX_E_INVALID_OBJECT_STATE, 3257 tr("The given session is busy")); 3258 3259 /* get the IInternalSessionControl interface */ 3260 control = aSession; 3261 ComAssertMsgRet(!control.isNull(), 3262 ("No IInternalSessionControl interface"), 3263 E_INVALIDARG); 3264 } 3249 3265 3250 3266 /* get the teleporter enable state for the progress object init. */ … … 3255 3271 3256 3272 /* create a progress object */ 3257 ComObjPtr<ProgressProxy> progress;3258 progress.createObject();3259 rc = progress->init(mParent,3260 static_cast<IMachine*>(this),3261 Bstr(tr("Spawning session")).raw(),3262 TRUE /* aCancelable */,3263 fTeleporterEnabled ? 20 : 10 /* uTotalOperationsWeight */,3264 Bstr(tr("Spawning session")).raw(),3265 2 /* uFirstOperationWeight */,3266 fTeleporterEnabled ? 3 : 1 /* cOtherProgressObjectOperations */);3267 if (SUCCEEDED(rc))3268 {3269 rc = openRemoteSession(control, aType, aEnvironment, progress); 3273 if (strType != "emergencystop") 3274 { 3275 ComObjPtr<ProgressProxy> progress; 3276 progress.createObject(); 3277 rc = progress->init(mParent, 3278 static_cast<IMachine*>(this), 3279 BstrFmt(tr("Starting VM \"%s\" (%s)"), aType).raw(), 3280 TRUE /* aCancelable */, 3281 fTeleporterEnabled ? 20 : 10 /* uTotalOperationsWeight */, 3282 Bstr(tr("Spawning session")).raw(), 3283 2 /* uFirstOperationWeight */, 3284 fTeleporterEnabled ? 3 : 1 /* cOtherProgressObjectOperations */); 3285 3270 3286 if (SUCCEEDED(rc)) 3271 3287 { 3272 progress.queryInterfaceTo(aProgress); 3273 3274 /* signal the client watcher thread */ 3275 mParent->updateClientWatcher(); 3276 3277 /* fire an event */ 3278 mParent->onSessionStateChange(getId(), SessionState_Spawning); 3279 } 3288 rc = launchVMProcess(control, strType, strEnvironment, progress); 3289 if (SUCCEEDED(rc)) 3290 { 3291 progress.queryInterfaceTo(aProgress); 3292 3293 /* signal the client watcher thread */ 3294 mParent->updateClientWatcher(); 3295 3296 /* fire an event */ 3297 mParent->onSessionStateChange(getId(), SessionState_Spawning); 3298 } 3299 } 3300 } 3301 else 3302 { 3303 /* no progress object - either instant success or failure */ 3304 *aProgress = NULL; 3305 3306 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 3307 3308 if (mData->mSession.mState != SessionState_Locked) 3309 return setError(VBOX_E_INVALID_OBJECT_STATE, 3310 tr("The machine '%s' is not locked by a session"), 3311 mUserData->s.strName.c_str()); 3312 3313 /* must have a VM process associated - do not kill normal API clients 3314 * with an open session */ 3315 if (!Global::IsOnline(mData->mMachineState)) 3316 return setError(VBOX_E_INVALID_OBJECT_STATE, 3317 tr("The machine '%s' does not have a VM process"), 3318 mUserData->s.strName.c_str()); 3319 3320 /* forcibly terminate the VM process */ 3321 if (mData->mSession.mPid != NIL_RTPROCESS) 3322 RTProcTerminate(mData->mSession.mPid); 3323 3324 /* signal the client watcher thread, as most likely the client has 3325 * been terminated */ 3326 mParent->updateClientWatcher(); 3280 3327 } 3281 3328 … … 5947 5994 fireHostPciDevicePlugEvent(es, mid.raw(), false /* unplugged */, true /* success */, pAttach, NULL); 5948 5995 } 5949 5996 5950 5997 return fRemoved ? S_OK : setError(VBOX_E_OBJECT_NOT_FOUND, 5951 5998 tr("No host PCI device %08x attached"), … … 6169 6216 * (inside the lock). 6170 6217 */ 6171 HRESULT Machine:: openRemoteSession(IInternalSessionControl *aControl,6172 IN_BSTR aType,6173 IN_BSTR aEnvironment,6174 6218 HRESULT Machine::launchVMProcess(IInternalSessionControl *aControl, 6219 const Utf8Str &strType, 6220 const Utf8Str &strEnvironment, 6221 ProgressProxy *aProgress) 6175 6222 { 6176 6223 LogFlowThisFuncEnter(); … … 6215 6262 RTENV env = RTENV_DEFAULT; 6216 6263 6217 if ( aEnvironment != NULL && *aEnvironment)6264 if (!strEnvironment.isEmpty()) 6218 6265 { 6219 6266 char *newEnvStr = NULL; … … 6225 6272 AssertRCBreakStmt(vrc2, vrc = vrc2); 6226 6273 6227 newEnvStr = RTStrDup( Utf8Str(aEnvironment).c_str());6274 newEnvStr = RTStrDup(strEnvironment.c_str()); 6228 6275 AssertPtrBreakStmt(newEnvStr, vrc = vrc2); 6229 6276 … … 6263 6310 RTStrFree(newEnvStr); 6264 6311 } 6265 6266 Utf8Str strType(aType);6267 6312 6268 6313 /* Qt is default */ … … 10569 10614 { 10570 10615 /* mType is not null when this machine's process has been started by 10571 * Machine:: launchVMProcess(), therefore it is our child. We10616 * Machine::LaunchVMProcess(), therefore it is our child. We 10572 10617 * need to queue the PID to reap the process (and avoid zombies on 10573 10618 * Linux). */ … … 10793 10838 return VBOX_E_INVALID_OBJECT_STATE; 10794 10839 10795 /* Finalize the openRemoteSessionprogress object. */10840 /* Finalize the LaunchVMProcess progress object. */ 10796 10841 if (mData->mSession.mProgress) 10797 10842 { … … 11096 11141 * it releases the IPC semaphore. 11097 11142 * Note! Because we're "reusing" mProgress here, this must be a proxy 11098 * object just like for openRemoteSession. */11143 * object just like for LaunchVMProcess. */ 11099 11144 Assert(mData->mSession.mProgress.isNull()); 11100 11145 ComObjPtr<ProgressProxy> progress;
Note:
See TracChangeset
for help on using the changeset viewer.