diff options
Diffstat (limited to 'src/VBox/Main/src-server/HostPower.cpp')
-rw-r--r-- | src/VBox/Main/src-server/HostPower.cpp | 144 |
1 files changed, 82 insertions, 62 deletions
diff --git a/src/VBox/Main/src-server/HostPower.cpp b/src/VBox/Main/src-server/HostPower.cpp index 830729a0..3146a7ae 100644 --- a/src/VBox/Main/src-server/HostPower.cpp +++ b/src/VBox/Main/src-server/HostPower.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -26,10 +26,11 @@ #include <VBox/com/ptr.h> #include "VirtualBoxImpl.h" +#include "MachineImpl.h" #include <iprt/mem.h> -HostPowerService::HostPowerService (VirtualBox *aVirtualBox) +HostPowerService::HostPowerService(VirtualBox *aVirtualBox) { Assert(aVirtualBox != NULL); mVirtualBox = aVirtualBox; @@ -39,18 +40,18 @@ HostPowerService::~HostPowerService() { } -void HostPowerService::notify(HostPowerEvent aEvent) +void HostPowerService::notify(Reason_T aReason) { SessionMachinesList machines; VirtualBox::InternalControlList controls; HRESULT rc = S_OK; - switch (aEvent) + switch (aReason) { - case HostPowerEvent_Suspend: + case Reason_HostSuspend: { - LogFunc (("SUSPEND\n")); + LogFunc(("HOST SUSPEND\n")); #ifdef VBOX_WITH_RESOURCE_USAGE_API /* Suspend performance sampling to avoid unnecessary callbacks due to jumps in time. */ @@ -68,49 +69,41 @@ void HostPowerService::notify(HostPowerEvent aEvent) { ComPtr<IInternalSessionControl> pControl = *it; - /* get the remote console */ - ComPtr<IConsole> console; - rc = pControl->GetRemoteConsole(console.asOutParam()); - /* the VM could have been powered down and closed or whatever */ - if (FAILED(rc)) - continue; - - /* note that Pause() will simply return a failure if the VM is - * in an inappropriate state */ - rc = console->Pause(); + /* PauseWithReason() will simply return a failure if + * the VM is in an inappropriate state */ + rc = pControl->PauseWithReason(Reason_HostSuspend); if (FAILED(rc)) continue; /* save the control to un-pause the VM later */ - mConsoles.push_back(console); + mSessionControls.push_back(pControl); } - LogFunc (("Suspended %d VMs\n", mConsoles.size())); - + LogRel(("Host suspending: Paused %d VMs\n", mSessionControls.size())); break; } - case HostPowerEvent_Resume: + case Reason_HostResume: { - LogFunc (("RESUME\n")); + LogFunc(("HOST RESUME\n")); size_t resumed = 0; /* go through VMs we paused on Suspend */ - for (size_t i = 0; i < mConsoles.size(); ++i) + for (size_t i = 0; i < mSessionControls.size(); ++i) { /* note that Resume() will simply return a failure if the VM is * in an inappropriate state (it will also fail if the VM has * been somehow closed by this time already so that the * console reference we have is dead) */ - rc = mConsoles[i]->Resume(); + rc = mSessionControls[i]->ResumeWithReason(Reason_HostResume); if (FAILED(rc)) continue; - ++ resumed; + ++resumed; } - LogFunc (("Resumed %d VMs\n", resumed)); + LogRel(("Host resumed: Resumed %d VMs\n", resumed)); #ifdef VBOX_WITH_RESOURCE_USAGE_API /* Resume the performance sampling. */ @@ -120,60 +113,87 @@ void HostPowerService::notify(HostPowerEvent aEvent) perfcollector->resumeSampling(); #endif - mConsoles.clear(); - + mSessionControls.clear(); break; } - case HostPowerEvent_BatteryLow: + case Reason_HostBatteryLow: { - LogFunc (("BATTERY LOW\n")); + LogFunc(("BATTERY LOW\n")); - mVirtualBox->getOpenedMachines(machines, &controls); + Bstr value; + rc = mVirtualBox->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), + value.asOutParam()); + int fGlobal = 0; + if (SUCCEEDED(rc) && !value.isEmpty()) + { + if (value != "0") + fGlobal = 1; + else if (value == "0") + fGlobal = -1; + } + mVirtualBox->getOpenedMachines(machines, &controls); size_t saved = 0; /* save running VMs */ + SessionMachinesList::const_iterator it2 = machines.begin(); for (VirtualBox::InternalControlList::const_iterator it = controls.begin(); - it != controls.end(); - ++it) + it != controls.end() && it2 != machines.end(); + ++it, ++it2) { - ComPtr<IInternalSessionControl> pControl = *it; - /* get the remote console */ - ComPtr<IConsole> console; - rc = pControl->GetRemoteConsole (console.asOutParam()); - /* the VM could have been powered down and closed or whatever */ - if (FAILED(rc)) - continue; - - ComPtr<IProgress> progress; - - /* note that SaveState() will simply return a failure if the VM - * is in an inappropriate state */ - rc = console->SaveState (progress.asOutParam()); - if (FAILED(rc)) - continue; - - /* Wait until the operation has been completed. */ - rc = progress->WaitForCompletion(-1); - if (SUCCEEDED(rc)) + ComPtr<SessionMachine> pMachine = *it2; + rc = pMachine->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), + value.asOutParam()); + int fPerVM = 0; + if (SUCCEEDED(rc) && !value.isEmpty()) { - LONG iRc; - progress->COMGETTER(ResultCode)(&iRc); - rc = iRc; + /* per-VM overrides global */ + if (value != "0") + fPerVM = 2; + else if (value == "0") + fPerVM = -2; } - AssertMsg (SUCCEEDED(rc), ("SaveState WaitForCompletion " - "failed with %Rhrc (%#08X)\n", rc, rc)); - - if (SUCCEEDED(rc)) - ++ saved; + /* default is true */ + if (fGlobal + fPerVM >= 0) + { + ComPtr<IInternalSessionControl> pControl = *it; + ComPtr<IProgress> progress; + + /* note that SaveStateWithReason() will simply return a failure + * if the VM is in an inappropriate state */ + rc = pControl->SaveStateWithReason(Reason_HostBatteryLow, progress.asOutParam()); + if (FAILED(rc)) + { + LogRel(("SaveState '%s' failed with %Rhrc\n", pMachine->getName().c_str(), rc)); + continue; + } + + /* Wait until the operation has been completed. */ + rc = progress->WaitForCompletion(-1); + if (SUCCEEDED(rc)) + { + LONG iRc; + progress->COMGETTER(ResultCode)(&iRc); + rc = iRc; + } + + AssertMsg(SUCCEEDED(rc), ("SaveState WaitForCompletion failed with %Rhrc (%#08X)\n", rc, rc)); + + if (SUCCEEDED(rc)) + { + LogRel(("SaveState '%s' succeeded\n", pMachine->getName().c_str())); + ++saved; + } + } } - - LogFunc (("Saved %d VMs\n", saved)); - + LogRel(("Battery Low: saved %d VMs\n", saved)); break; } + + default: + /* nothing */; } } /* vi: set tabstop=4 shiftwidth=4 expandtab: */ |