VirtualBox

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


Ignore:
Timestamp:
Sep 18, 2013 8:39:01 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
89057
Message:

Change implementation for turning a reset into a power off to prevent the VM from executing while the power down thread is not running

Location:
trunk/src/VBox/Main/src-client
Files:
2 edited

Legend:

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

    r48406 r48528  
    381381    , mfSnapshotFolderDiskTypeShown(false)
    382382    , mfVMHasUsbController(false)
     383    , mfPowerOffCausedByReset(false)
    383384    , mpVmm2UserMethods(NULL)
    384385    , m_pVMMDev(NULL)
     
    421422    pVmm2UserMethods->pfnNotifyPdmtInit = Console::vmm2User_NotifyPdmtInit;
    422423    pVmm2UserMethods->pfnNotifyPdmtTerm = Console::vmm2User_NotifyPdmtTerm;
     424    pVmm2UserMethods->pfnNotifyResetTurnedIntoPowerOff = Console::vmm2User_NotifyResetTurnedIntoPowerOff;
    423425    pVmm2UserMethods->u32EndMagic       = VMM2USERMETHODS_MAGIC;
    424426    pVmm2UserMethods->pConsole          = this;
     
    21822184        ComPtr<IProgress> pProgress;
    21832185
     2186#ifdef VBOX_WITH_GUEST_PROPS
    21842187        alock.release();
    21852188
    2186 #ifdef VBOX_WITH_GUEST_PROPS
    2187     if (isResetTurnedIntoPowerOff())
    2188     {
    2189         mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw());
    2190         mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw(),
    2191                                    Bstr("PowerOff").raw(), Bstr("RDONLYGUEST").raw());
    2192         mMachine->SaveSettings();
    2193     }
     2189        if (isResetTurnedIntoPowerOff())
     2190        {
     2191            mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw());
     2192            mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw(),
     2193                                       Bstr("PowerOff").raw(), Bstr("RDONLYGUEST").raw());
     2194            mMachine->SaveSettings();
     2195        }
     2196
     2197        alock.acquire();
    21942198#endif
    2195 
    2196         alock.acquire();
    21972199
    21982200        /*
     
    77087710}
    77097711
    7710 /**
    7711  * Internal VM power off worker.
    7712  *
    7713  * @return nothing.
    7714  * @param  that   Console object.
    7715  * @param  fCalledFromReset Flag whether the worker was called from the reset state change.
    7716  */
    7717 void Console::vmstateChangePowerOff(bool fCalledFromReset = false)
    7718 {
    7719 #ifdef VBOX_WITH_GUEST_PROPS
    7720     if (isResetTurnedIntoPowerOff())
    7721     {
    7722         Bstr strPowerOffReason;
    7723 
    7724         if (fCalledFromReset)
    7725             strPowerOffReason = Bstr("Reset");
    7726         else
    7727             strPowerOffReason = Bstr("PowerOff");
    7728 
    7729         mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw());
    7730         mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw(),
    7731                                    strPowerOffReason.raw(), Bstr("RDONLYGUEST").raw());
    7732         mMachine->SaveSettings();
    7733     }
    7734 #endif
    7735 
    7736     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    7737 
    7738     if (mVMStateChangeCallbackDisabled)
    7739         return;
    7740 
    7741     /* Do we still think that it is running? It may happen if this is a
    7742      * VM-(guest-)initiated shutdown/poweroff.
    7743      */
    7744     if (   mMachineState != MachineState_Stopping
    7745         && mMachineState != MachineState_Saving
    7746         && mMachineState != MachineState_Restoring
    7747         && mMachineState != MachineState_TeleportingIn
    7748         && mMachineState != MachineState_FaultTolerantSyncing
    7749         && mMachineState != MachineState_TeleportingPausedVM
    7750         && !mVMIsAlreadyPoweringOff
    7751        )
    7752     {
    7753         LogFlowFunc(("VM has powered itself off but Console still thinks it is running. Notifying.\n"));
    7754 
    7755         /*
    7756          * Prevent powerDown() from calling VMR3PowerOff() again if this was called from
    7757          * the power off state change.
    7758          * When called from the Reset state make sure to call VMR3PowerOff() first.
    7759          */
    7760         Assert(mVMPoweredOff == false);
    7761         mVMPoweredOff = !fCalledFromReset;
    7762 
    7763         /*
    7764          * request a progress object from the server
    7765          * (this will set the machine state to Stopping on the server
    7766          * to block others from accessing this machine)
    7767          */
    7768         ComPtr<IProgress> pProgress;
    7769         HRESULT rc = mControl->BeginPoweringDown(pProgress.asOutParam());
    7770         AssertComRC(rc);
    7771 
    7772         /* sync the state with the server */
    7773         setMachineStateLocally(MachineState_Stopping);
    7774 
    7775         /* Setup task object and thread to carry out the operation
    7776          * asynchronously (if we call powerDown() right here but there
    7777          * is one or more mpUVM callers (added with addVMCaller()) we'll
    7778          * deadlock).
    7779          */
    7780         std::auto_ptr<VMPowerDownTask> task(new VMPowerDownTask(this, pProgress));
    7781 
    7782          /* If creating a task failed, this can currently mean one of
    7783           * two: either Console::uninit() has been called just a ms
    7784           * before (so a powerDown() call is already on the way), or
    7785           * powerDown() itself is being already executed. Just do
    7786           * nothing.
    7787           */
    7788         if (!task->isOk())
    7789         {
    7790             LogFlowFunc(("Console is already being uninitialized.\n"));
    7791             return;
    7792         }
    7793 
    7794         int vrc = RTThreadCreate(NULL, Console::powerDownThread,
    7795                                  (void *)task.get(), 0,
    7796                                  RTTHREADTYPE_MAIN_WORKER, 0,
    7797                                  "VMPwrDwn");
    7798         AssertMsgRCReturnVoid(vrc, ("Could not create VMPowerDown thread (%Rrc)\n", vrc));
    7799 
    7800         /* task is now owned by powerDownThread(), so release it */
    7801         task.release();
    7802     }
    7803 }
    7804 
    78057712/** @callback_method_impl{FNVMATSTATE}
    78067713 *
     
    78337740        case VMSTATE_OFF:
    78347741        {
    7835             that->vmstateChangePowerOff();
     7742#ifdef VBOX_WITH_GUEST_PROPS
     7743            if (that->isResetTurnedIntoPowerOff())
     7744            {
     7745                Bstr strPowerOffReason;
     7746
     7747                if (that->mfPowerOffCausedByReset)
     7748                    strPowerOffReason = Bstr("Reset");
     7749                else
     7750                    strPowerOffReason = Bstr("PowerOff");
     7751
     7752                that->mMachine->DeleteGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw());
     7753                that->mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VMPowerOffReason").raw(),
     7754                                                 strPowerOffReason.raw(), Bstr("RDONLYGUEST").raw());
     7755                that->mMachine->SaveSettings();
     7756            }
     7757#endif
     7758
     7759            AutoWriteLock alock(that COMMA_LOCKVAL_SRC_POS);
     7760
     7761            if (that->mVMStateChangeCallbackDisabled)
     7762                return;
     7763
     7764            /* Do we still think that it is running? It may happen if this is a
     7765             * VM-(guest-)initiated shutdown/poweroff.
     7766             */
     7767            if (   that->mMachineState != MachineState_Stopping
     7768                && that->mMachineState != MachineState_Saving
     7769                && that->mMachineState != MachineState_Restoring
     7770                && that->mMachineState != MachineState_TeleportingIn
     7771                && that->mMachineState != MachineState_FaultTolerantSyncing
     7772                && that->mMachineState != MachineState_TeleportingPausedVM
     7773                && !that->mVMIsAlreadyPoweringOff
     7774               )
     7775            {
     7776                LogFlowFunc(("VM has powered itself off but Console still thinks it is running. Notifying.\n"));
     7777
     7778                /*
     7779                 * Prevent powerDown() from calling VMR3PowerOff() again if this was called from
     7780                 * the power off state change.
     7781                 * When called from the Reset state make sure to call VMR3PowerOff() first.
     7782                 */
     7783                Assert(that->mVMPoweredOff == false);
     7784                that->mVMPoweredOff = true;
     7785
     7786                /*
     7787                 * request a progress object from the server
     7788                 * (this will set the machine state to Stopping on the server
     7789                 * to block others from accessing this machine)
     7790                 */
     7791                ComPtr<IProgress> pProgress;
     7792                HRESULT rc = that->mControl->BeginPoweringDown(pProgress.asOutParam());
     7793                AssertComRC(rc);
     7794
     7795                /* sync the state with the server */
     7796                that->setMachineStateLocally(MachineState_Stopping);
     7797
     7798                /* Setup task object and thread to carry out the operation
     7799                 * asynchronously (if we call powerDown() right here but there
     7800                 * is one or more mpUVM callers (added with addVMCaller()) we'll
     7801                 * deadlock).
     7802                 */
     7803                std::auto_ptr<VMPowerDownTask> task(new VMPowerDownTask(that, pProgress));
     7804
     7805                 /* If creating a task failed, this can currently mean one of
     7806                  * two: either Console::uninit() has been called just a ms
     7807                  * before (so a powerDown() call is already on the way), or
     7808                  * powerDown() itself is being already executed. Just do
     7809                  * nothing.
     7810                  */
     7811                if (!task->isOk())
     7812                {
     7813                    LogFlowFunc(("Console is already being uninitialized.\n"));
     7814                    return;
     7815                }
     7816
     7817                int vrc = RTThreadCreate(NULL, Console::powerDownThread,
     7818                                         (void *)task.get(), 0,
     7819                                         RTTHREADTYPE_MAIN_WORKER, 0,
     7820                                         "VMPwrDwn");
     7821                AssertMsgRCReturnVoid(vrc, ("Could not create VMPowerDown thread (%Rrc)\n", vrc));
     7822
     7823                /* task is now owned by powerDownThread(), so release it */
     7824                task.release();
     7825            }
    78367826            break;
    78377827        }
     
    79037893        case VMSTATE_RESETTING:
    79047894        {
    7905             if (!that->isResetTurnedIntoPowerOff())
    7906             {
    79077895#ifdef VBOX_WITH_GUEST_PROPS
    7908                 /* Do not take any read/write locks here! */
    7909                 that->guestPropertiesHandleVMReset();
     7896            /* Do not take any read/write locks here! */
     7897            that->guestPropertiesHandleVMReset();
    79107898#endif
    7911             }
    7912             else
    7913                 that->vmstateChangePowerOff(true /* fCalledFromReset*/);
    79147899            break;
    79157900        }
     
    1001610001    NOREF(pThis); NOREF(pUVM);
    1001710002    VirtualBoxBase::uninitializeComForThread();
     10003}
     10004
     10005/**
     10006 * @interface_method_impl{VMM2USERMETHODS,pfnNotifyResetTurnedIntoPowerOff}
     10007 */
     10008/*static*/ DECLCALLBACK(void)
     10009Console::vmm2User_NotifyResetTurnedIntoPowerOff(PCVMM2USERMETHODS pThis, PUVM pUVM)
     10010{
     10011    Console *pConsole = ((MYVMM2USERMETHODS *)pThis)->pConsole;
     10012    NOREF(pUVM);
     10013
     10014    pConsole->mfPowerOffCausedByReset = true;
    1001810015}
    1001910016
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r48406 r48528  
    10101010        hrc = pMachine->GetHWVirtExProperty(HWVirtExPropertyType_UnrestrictedExecution, &fEnableUX); H();
    10111011        InsertConfigInteger(pHM, "EnableUX", fEnableUX);
     1012
     1013        /* Reset overwrite. */
     1014        if (isResetTurnedIntoPowerOff())
     1015            InsertConfigInteger(pRoot, "PowerOffInsteadOfReset", 1);
     1016
    10121017
    10131018        /*
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette