Changeset 33848 in vbox for trunk/src/VBox
- Timestamp:
- Nov 8, 2010 2:29:13 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r33842 r33848 240 240 struct VMSaveTask : public VMProgressTask 241 241 { 242 VMSaveTask(Console *aConsole, Progress *aProgress )242 VMSaveTask(Console *aConsole, Progress *aProgress, const ComPtr<IProgress> &aServerProgress) 243 243 : VMProgressTask(aConsole, aProgress, true /* aUsesVMPtr */), 244 mLastMachineState(MachineState_Null) 244 mLastMachineState(MachineState_Null), 245 mServerProgress(aServerProgress) 245 246 {} 246 247 … … 2318 2319 2319 2320 HRESULT rc = S_OK; 2320 2321 /* create a progress object to track operation completion */2322 ComObjPtr<Progress> progress;2323 progress.createObject();2324 progress->init(static_cast<IConsole *>(this),2325 Bstr(tr("Saving the execution state of the virtual machine")).raw(),2326 FALSE /* aCancelable */);2327 2328 2321 bool fBeganSavingState = false; 2329 2322 bool fTaskCreationFailed = false; … … 2331 2324 do 2332 2325 { 2326 ComPtr<IProgress> pProgress; 2327 Bstr stateFilePath; 2328 2329 /* 2330 * request a saved state file path from the server 2331 * (this will set the machine state to Saving on the server to block 2332 * others from accessing this machine) 2333 */ 2334 rc = mControl->BeginSavingState(pProgress.asOutParam(), 2335 stateFilePath.asOutParam()); 2336 if (FAILED(rc)) break; 2337 2338 fBeganSavingState = true; 2339 2340 /* sync the state with the server */ 2341 setMachineStateLocally(MachineState_Saving); 2342 2333 2343 /* create a task object early to ensure mpVM protection is successful */ 2334 std::auto_ptr <VMSaveTask> task(new VMSaveTask(this, progress));2344 std::auto_ptr <VMSaveTask> task(new VMSaveTask(this, NULL, pProgress)); 2335 2345 rc = task->rc(); 2336 2346 /* … … 2345 2355 break; 2346 2356 } 2347 2348 Bstr stateFilePath;2349 2350 /*2351 * request a saved state file path from the server2352 * (this will set the machine state to Saving on the server to block2353 * others from accessing this machine)2354 */2355 rc = mControl->BeginSavingState(progress, stateFilePath.asOutParam());2356 if (FAILED(rc)) break;2357 2358 fBeganSavingState = true;2359 2360 /* sync the state with the server */2361 setMachineStateLocally(MachineState_Saving);2362 2357 2363 2358 /* ensure the directory for the saved state file exists */ … … 2396 2391 2397 2392 /* return the progress to the caller */ 2398 p rogress.queryInterfaceTo(aProgress);2393 pProgress.queryInterfaceTo(aProgress); 2399 2394 } 2400 2395 while (0); … … 2412 2407 * before calling mControl->BeginSavingState(). 2413 2408 */ 2414 mControl->EndSavingState( FALSE);2409 mControl->EndSavingState(eik.getResultCode(), eik.getText().raw()); 2415 2410 } 2416 2411 … … 3505 3500 * @note Locks this object for writing. 3506 3501 */ 3507 HRESULT Console::onNATRedirectRuleChange(INetworkAdapter *aNetworkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName, 3502 HRESULT Console::onNATRedirectRuleChange(INetworkAdapter *aNetworkAdapter, BOOL aNatRuleRemove, IN_BSTR aRuleName, 3508 3503 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort) 3509 3504 { … … 3554 3549 vrc = aNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType); 3555 3550 3556 if ( RT_FAILURE(vrc) 3551 if ( RT_FAILURE(vrc) 3557 3552 || attachmentType != NetworkAttachmentType_NAT) 3558 3553 { … … 3560 3555 goto done; 3561 3556 } 3562 3557 3563 3558 /* look down for PDMINETWORKNATCONFIG interface */ 3564 3559 while (pBase) … … 3572 3567 goto done; 3573 3568 bool fUdp = (aProto == NATProtocol_UDP); 3574 vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, Utf8Str(aRuleName).c_str(), fUdp, 3575 Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(), 3569 vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, Utf8Str(aRuleName).c_str(), fUdp, 3570 Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(), 3576 3571 aGuestPort); 3577 3572 if (RT_FAILURE(vrc)) … … 6368 6363 break; 6369 6364 case MachineState_Saving: 6370 /* successfully saved (note that the machine is already in 6371 * the Saved state on the server due to EndSavingState() 6372 * called from saveStateThread(), so only change the local 6373 * state) */ 6374 that->setMachineStateLocally(MachineState_Saved); 6365 /* successfully saved */ 6366 that->setMachineState(MachineState_Saved); 6375 6367 break; 6376 6368 case MachineState_Starting: … … 7069 7061 * @param pVM The VM handle. 7070 7062 * @param uPercent Completion percentage (0-100). 7071 * @param pvUser Pointer to the VMProgressTask structure.7063 * @param pvUser Pointer to an IProgress instance. 7072 7064 * @return VINF_SUCCESS. 7073 7065 */ … … 7075 7067 DECLCALLBACK(int) Console::stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser) 7076 7068 { 7077 VMProgressTask *task = static_cast<VMProgressTask *>(pvUser); 7078 AssertReturn(task, VERR_INVALID_PARAMETER); 7069 IProgress *pProgress = static_cast<IProgress *>(pvUser); 7079 7070 7080 7071 /* update the progress object */ 7081 if ( task->mProgress)7082 task->mProgress->SetCurrentOperationProgress(uPercent);7072 if (pProgress) 7073 pProgress->SetCurrentOperationProgress(uPercent); 7083 7074 7084 7075 return VINF_SUCCESS; … … 7613 7604 task->mSavedStateFile.c_str(), 7614 7605 Console::stateProgressCallback, 7615 static_cast< VMProgressTask*>(task.get()));7606 static_cast<IProgress *>(task->mProgress)); 7616 7607 7617 7608 if (RT_SUCCESS(vrc)) … … 8005 7996 true /*fContinueAfterwards*/, 8006 7997 Console::stateProgressCallback, 8007 (void*)pTask,7998 static_cast<IProgress *>(pTask->mProgress), 8008 7999 &fSuspenededBySave); 8009 8000 alock.enter(); … … 8251 8242 8252 8243 Assert(task->mSavedStateFile.length()); 8253 Assert(!task->mProgress.isNull()); 8244 Assert(task->mProgress.isNull()); 8245 Assert(!task->mServerProgress.isNull()); 8254 8246 8255 8247 const ComObjPtr<Console> &that = task->mConsole; … … 8264 8256 false, /*fContinueAfterwards*/ 8265 8257 Console::stateProgressCallback, 8266 static_cast< VMProgressTask*>(task.get()),8258 static_cast<IProgress *>(task->mServerProgress), 8267 8259 &fSuspenededBySave); 8268 8260 if (RT_FAILURE(vrc)) … … 8277 8269 AutoWriteLock thatLock(that COMMA_LOCKVAL_SRC_POS); 8278 8270 8279 /*8280 * finalize the requested save state procedure.8281 * In case of success, the server will set the machine state to Saved;8282 * in case of failure it will reset the it to the state it had right8283 * before calling mControl->BeginSavingState().8284 */8285 that->mControl->EndSavingState(SUCCEEDED(rc));8286 8287 8271 /* synchronize the state with the server */ 8288 if ( !FAILED(rc))8272 if (SUCCEEDED(rc)) 8289 8273 { 8290 8274 /* … … 8295 8279 */ 8296 8280 task->releaseVMCaller(); 8297 8298 8281 rc = that->powerDown(); 8299 8282 } 8300 8283 8301 /* notify the progress object about operation completion */ 8302 if (SUCCEEDED(rc)) 8303 task->mProgress->notifyComplete(S_OK); 8304 else 8305 { 8306 if (errMsg.length()) 8307 task->mProgress->notifyComplete(rc, 8308 COM_IIDOF(IConsole), 8309 Console::getStaticComponentName(), 8310 errMsg.c_str()); 8311 else 8312 task->mProgress->notifyComplete(rc); 8313 } 8284 /* 8285 * Finalize the requested save state procedure. In case of failure it will 8286 * reset the machine state to the state it had right before calling 8287 * mControl->BeginSavingState(). This must be the last thing because it 8288 * will set the progress to completed, and that means that the frontend 8289 * can immediately uninit the associated console object. 8290 */ 8291 that->mControl->EndSavingState(rc, Bstr(errMsg).raw()); 8314 8292 8315 8293 LogFlowFuncLeave(); -
trunk/src/VBox/Main/MachineImpl.cpp
r33825 r33848 3216 3216 CheckComArgNotNull(aSession); 3217 3217 CheckComArgStrNotEmptyOrNull(aType); 3218 CheckComArgOut SafeArrayPointerValid(aProgress);3218 CheckComArgOutPointerValid(aProgress); 3219 3219 3220 3220 AutoCaller autoCaller(this); … … 10035 10035 { 10036 10036 LogWarningThisFunc(("canceling failed save state request!\n")); 10037 endSavingState( FALSE /* aSuccess */);10037 endSavingState(E_FAIL, tr("Machine terminated with pending save state!")); 10038 10038 } 10039 10039 else if (!mSnapshotData.mSnapshot.isNull()) … … 10528 10528 * @note Locks this object for writing. 10529 10529 */ 10530 STDMETHODIMP SessionMachine::BeginSavingState(IProgress * aProgress, BSTR *aStateFilePath)10530 STDMETHODIMP SessionMachine::BeginSavingState(IProgress **aProgress, BSTR *aStateFilePath) 10531 10531 { 10532 10532 LogFlowThisFuncEnter(); 10533 10533 10534 AssertReturn(aProgress, E_INVALIDARG);10535 AssertReturn(aStateFilePath, E_POINTER);10534 CheckComArgOutPointerValid(aProgress); 10535 CheckComArgOutPointerValid(aStateFilePath); 10536 10536 10537 10537 AutoCaller autoCaller(this); … … 10542 10542 AssertReturn( mData->mMachineState == MachineState_Paused 10543 10543 && mSnapshotData.mLastState == MachineState_Null 10544 && mSnapshotData.mProgressId.isEmpty()10545 10544 && mSnapshotData.mStateFilePath.isEmpty(), 10546 10545 E_FAIL); 10547 10546 10548 /* memorize the progress ID and add it to the global collection */ 10549 Bstr progressId; 10550 HRESULT rc = aProgress->COMGETTER(Id)(progressId.asOutParam()); 10551 AssertComRCReturn(rc, rc); 10552 rc = mParent->addProgress(aProgress); 10553 AssertComRCReturn(rc, rc); 10547 /* create a progress object to track operation completion */ 10548 ComObjPtr<Progress> pProgress; 10549 pProgress.createObject(); 10550 pProgress->init(getVirtualBox(), 10551 static_cast<IMachine *>(this) /* aInitiator */, 10552 Bstr(tr("Saving the execution state of the virtual machine")).raw(), 10553 FALSE /* aCancelable */); 10554 10554 10555 10555 Bstr stateFilePath; … … 10564 10564 /* fill in the snapshot data */ 10565 10565 mSnapshotData.mLastState = mData->mMachineState; 10566 mSnapshotData.mProgressId = Guid(progressId);10567 10566 mSnapshotData.mStateFilePath = stateFilePath; 10567 mSnapshotData.mProgress = pProgress; 10568 10568 10569 10569 /* set the state to Saving (this is expected by Console::SaveState()) */ … … 10571 10571 10572 10572 stateFilePath.cloneTo(aStateFilePath); 10573 pProgress.queryInterfaceTo(aProgress); 10573 10574 10574 10575 return S_OK; … … 10578 10579 * @note Locks mParent + this object for writing. 10579 10580 */ 10580 STDMETHODIMP SessionMachine::EndSavingState( BOOL aSuccess)10581 STDMETHODIMP SessionMachine::EndSavingState(LONG iResult, IN_BSTR aErrMsg) 10581 10582 { 10582 10583 LogFlowThisFunc(("\n")); … … 10588 10589 AutoMultiWriteLock2 alock(mParent, this COMMA_LOCKVAL_SRC_POS); 10589 10590 10590 AssertReturn( mData->mMachineState == MachineState_Saving 10591 AssertReturn( ( (SUCCEEDED(iResult) && mData->mMachineState == MachineState_Saved) 10592 || (FAILED(iResult) && mData->mMachineState == MachineState_Saving)) 10591 10593 && mSnapshotData.mLastState != MachineState_Null 10592 && !mSnapshotData.mProgressId.isEmpty()10593 10594 && !mSnapshotData.mStateFilePath.isEmpty(), 10594 10595 E_FAIL); 10595 10596 10596 10597 /* 10597 * on success, set the state to Saved;10598 * on failure, set the state to the state we had when BeginSavingState() was10599 * called (this is expected by Console::SaveState() and10600 * Console::saveStateThread())10598 * On failure, set the state to the state we had when BeginSavingState() 10599 * was called (this is expected by Console::SaveState() and the associated 10600 * task). On success the VM process already changed the state to 10601 * MachineState_Saved, so no need to do anything. 10601 10602 */ 10602 if (aSuccess) 10603 setMachineState(MachineState_Saved); 10604 else 10603 if (FAILED(iResult)) 10605 10604 setMachineState(mSnapshotData.mLastState); 10606 10605 10607 return endSavingState( aSuccess);10606 return endSavingState(iResult, aErrMsg); 10608 10607 } 10609 10608 … … 11259 11258 * @note Must be called from under this object's lock. 11260 11259 * 11261 * @param aSuccess TRUE if the snapshot has been taken successfully 11260 * @param aRc S_OK if the snapshot has been taken successfully 11261 * @param aErrMsg human readable error message for failure 11262 11262 * 11263 11263 * @note Locks mParent + this objects for writing. 11264 11264 */ 11265 HRESULT SessionMachine::endSavingState( BOOL aSuccess)11265 HRESULT SessionMachine::endSavingState(HRESULT aRc, const Utf8Str &aErrMsg) 11266 11266 { 11267 11267 LogFlowThisFuncEnter(); … … 11274 11274 HRESULT rc = S_OK; 11275 11275 11276 if ( aSuccess)11276 if (SUCCEEDED(aRc)) 11277 11277 { 11278 11278 mSSData->mStateFilePath = mSnapshotData.mStateFilePath; … … 11289 11289 } 11290 11290 11291 /* remove the completed progress object */ 11292 mParent->removeProgress(mSnapshotData.mProgressId.ref()); 11291 /* notify the progress object about operation completion */ 11292 Assert(mSnapshotData.mProgress); 11293 if (SUCCEEDED(aRc)) 11294 mSnapshotData.mProgress->notifyComplete(S_OK); 11295 else 11296 { 11297 if (aErrMsg.length()) 11298 mSnapshotData.mProgress->notifyComplete(aRc, 11299 COM_IIDOF(ISession), 11300 getComponentName(), 11301 aErrMsg.c_str()); 11302 else 11303 mSnapshotData.mProgress->notifyComplete(aRc); 11304 } 11293 11305 11294 11306 /* clear out the temporary saved state data */ 11295 11307 mSnapshotData.mLastState = MachineState_Null; 11296 mSnapshotData.mProgressId.clear();11297 11308 mSnapshotData.mStateFilePath.setNull(); 11309 mSnapshotData.mProgress.setNull(); 11298 11310 11299 11311 LogFlowThisFuncLeave(); -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r33825 r33848 2945 2945 <interface 2946 2946 name="IInternalMachineControl" extends="$unknown" 2947 uuid=" e2da8b1a-2ad1-490e-b29e-c33a144791b6"2947 uuid="476126af-e223-4490-a8a0-b1f1575be013" 2948 2948 internal="yes" 2949 2949 wsmap="suppress" … … 3087 3087 save the current state and stop the VM execution. 3088 3088 </desc> 3089 <param name="progress" type="IProgress" dir=" in">3090 <desc> 3091 Progress object created by the VM processto wait until3089 <param name="progress" type="IProgress" dir="out"> 3090 <desc> 3091 Progress object created by VBoxSVC to wait until 3092 3092 the state is saved. 3093 3093 </desc> … … 3115 3115 </desc> 3116 3116 3117 <param name="success" type="boolean" dir="in"> 3118 <desc>@c true to indicate success and @c false otherwise. 3117 <param name="result" type="long" dir="in"> 3118 <desc>@c S_OK to indicate success. 3119 </desc> 3120 </param> 3121 <param name="errMsg" type="wstring" dir="in"> 3122 <desc>@c human readable error message in case of failure. 3119 3123 </desc> 3120 3124 </param> -
trunk/src/VBox/Main/include/MachineImpl.h
r33825 r33848 21 21 #include "VirtualBoxBase.h" 22 22 #include "SnapshotImpl.h" 23 #include "ProgressImpl.h" 23 24 #include "VRDEServerImpl.h" 24 25 #include "MediumAttachmentImpl.h" … … 918 919 STDMETHOD(DetachAllUSBDevices)(BOOL aDone); 919 920 STDMETHOD(OnSessionEnd)(ISession *aSession, IProgress **aProgress); 920 STDMETHOD(BeginSavingState)(IProgress * aProgress, BSTR *aStateFilePath);921 STDMETHOD(EndSavingState)( BOOL aSuccess);921 STDMETHOD(BeginSavingState)(IProgress **aProgress, BSTR *aStateFilePath); 922 STDMETHOD(EndSavingState)(LONG aResult, IN_BSTR aErrMsg); 922 923 STDMETHOD(AdoptSavedState)(IN_BSTR aSavedStateFile); 923 924 STDMETHOD(BeginTakingSnapshot)(IConsole *aInitiator, … … 987 988 988 989 // used when saving state 989 Guid mProgressId;990 990 Utf8Str mStateFilePath; 991 ComObjPtr<Progress> mProgress; 991 992 }; 992 993 … … 1005 1006 void uninit(Uninit::Reason aReason); 1006 1007 1007 HRESULT endSavingState( BOOL aSuccess);1008 HRESULT endSavingState(HRESULT aRC, const Utf8Str &aErrMsg); 1008 1009 1009 1010 void deleteSnapshotHandler(DeleteSnapshotTask &aTask);
Note:
See TracChangeset
for help on using the changeset viewer.