VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/HostPower.cpp

Last change on this file was 98288, checked in by vboxsync, 15 months ago

Main/src-server: rc -> hrc/vrc (partial). bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
RevLine 
[55401]1/* $Id: HostPower.cpp 98288 2023-01-24 15:32:43Z vboxsync $ */
[15454]2/** @file
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[15454]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[15454]26 */
27
28
[57358]29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[76592]32#define LOG_GROUP LOG_GROUP_MAIN_HOST
[15454]33#include "HostPower.h"
[76592]34#include "LoggingNew.h"
[15454]35
36#include <VBox/com/ptr.h>
37
[23223]38#include "VirtualBoxImpl.h"
[46775]39#include "MachineImpl.h"
[23223]40
[15454]41#include <iprt/mem.h>
[50174]42#include <iprt/cpp/utils.h>
[15454]43
[46775]44HostPowerService::HostPowerService(VirtualBox *aVirtualBox)
[15454]45{
[50174]46 AssertPtr(aVirtualBox);
[15454]47 mVirtualBox = aVirtualBox;
48}
49
50HostPowerService::~HostPowerService()
51{
52}
53
[46775]54void HostPowerService::notify(Reason_T aReason)
[15454]55{
[27796]56 SessionMachinesList machines;
[23327]57 VirtualBox::InternalControlList controls;
[15454]58
[98288]59 HRESULT hrc = S_OK;
[15454]60
[46775]61 switch (aReason)
[15454]62 {
[46775]63 case Reason_HostSuspend:
[15454]64 {
[50220]65 LogFunc(("HOST SUSPEND\n"));
[15454]66
[21395]67#ifdef VBOX_WITH_RESOURCE_USAGE_API
68 /* Suspend performance sampling to avoid unnecessary callbacks due to jumps in time. */
[50355]69 PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector();
[21395]70
71 if (perfcollector)
72 perfcollector->suspendSampling();
73#endif
[50355]74 mVirtualBox->i_getOpenedMachines(machines, &controls);
[15454]75
76 /* pause running VMs */
[23327]77 for (VirtualBox::InternalControlList::const_iterator it = controls.begin();
78 it != controls.end();
79 ++it)
[15454]80 {
[23327]81 ComPtr<IInternalSessionControl> pControl = *it;
82
[46775]83 /* PauseWithReason() will simply return a failure if
84 * the VM is in an inappropriate state */
[98288]85 hrc = pControl->PauseWithReason(Reason_HostSuspend);
86 if (FAILED(hrc))
[15454]87 continue;
88
89 /* save the control to un-pause the VM later */
[46775]90 mSessionControls.push_back(pControl);
[15454]91 }
92
[50220]93 LogRel(("Host suspending: Paused %d VMs\n", mSessionControls.size()));
[15454]94 break;
95 }
96
[46775]97 case Reason_HostResume:
[15454]98 {
[50220]99 LogFunc(("HOST RESUME\n"));
[15454]100
101 size_t resumed = 0;
102
103 /* go through VMs we paused on Suspend */
[46775]104 for (size_t i = 0; i < mSessionControls.size(); ++i)
[15454]105 {
106 /* note that Resume() will simply return a failure if the VM is
107 * in an inappropriate state (it will also fail if the VM has
108 * been somehow closed by this time already so that the
109 * console reference we have is dead) */
[98288]110 hrc = mSessionControls[i]->ResumeWithReason(Reason_HostResume);
111 if (FAILED(hrc))
[15454]112 continue;
113
[46775]114 ++resumed;
[15454]115 }
116
[50220]117 LogRel(("Host resumed: Resumed %d VMs\n", resumed));
[15454]118
[21395]119#ifdef VBOX_WITH_RESOURCE_USAGE_API
120 /* Resume the performance sampling. */
[50355]121 PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector();
[21395]122
123 if (perfcollector)
124 perfcollector->resumeSampling();
125#endif
126
[46775]127 mSessionControls.clear();
[15454]128 break;
129 }
130
[46775]131 case Reason_HostBatteryLow:
[15454]132 {
[50220]133 LogFunc(("BATTERY LOW\n"));
134
[50216]135 Bstr value;
[98288]136 hrc = mVirtualBox->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), value.asOutParam());
[50220]137 int fGlobal = 0;
[98288]138 if (SUCCEEDED(hrc) && !value.isEmpty())
[50175]139 {
[50220]140 if (value != "0")
141 fGlobal = 1;
142 else if (value == "0")
143 fGlobal = -1;
144 }
[15454]145
[50355]146 mVirtualBox->i_getOpenedMachines(machines, &controls);
[50220]147 size_t saved = 0;
[15454]148
[50220]149 /* save running VMs */
[55214]150 for (SessionMachinesList::const_iterator it = machines.begin();
151 it != machines.end();
152 ++it)
[50220]153 {
[55214]154 ComPtr<SessionMachine> pMachine = *it;
[98288]155 hrc = pMachine->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(), value.asOutParam());
[50220]156 int fPerVM = 0;
[98288]157 if (SUCCEEDED(hrc) && !value.isEmpty())
[50175]158 {
[50220]159 /* per-VM overrides global */
160 if (value != "0")
161 fPerVM = 2;
162 else if (value == "0")
163 fPerVM = -2;
164 }
165
166 /* default is true */
167 if (fGlobal + fPerVM >= 0)
168 {
[50175]169 ComPtr<IProgress> progress;
[15454]170
[55214]171 /* SessionMachine::i_saveStateWithReason() will return
172 * a failure if the VM is in an inappropriate state */
[98288]173 hrc = pMachine->i_saveStateWithReason(Reason_HostBatteryLow, progress);
174 if (FAILED(hrc))
[50220]175 {
[98288]176 LogRel(("SaveState '%s' failed with %Rhrc\n", pMachine->i_getName().c_str(), hrc));
[50175]177 continue;
[50220]178 }
[15454]179
[50175]180 /* Wait until the operation has been completed. */
[98288]181 hrc = progress->WaitForCompletion(-1);
182 if (SUCCEEDED(hrc))
[50175]183 {
184 LONG iRc;
185 progress->COMGETTER(ResultCode)(&iRc);
[98288]186 hrc = (HRESULT)iRc;
[50175]187 }
[15454]188
[98288]189 AssertMsg(SUCCEEDED(hrc), ("SaveState WaitForCompletion failed with %Rhrc (%#08X)\n", hrc, hrc));
[15454]190
[98288]191 if (SUCCEEDED(hrc))
[50220]192 {
[51498]193 LogRel(("SaveState '%s' succeeded\n", pMachine->i_getName().c_str()));
[50175]194 ++saved;
[50220]195 }
[36433]196 }
[15454]197 }
[50227]198 LogRel(("Battery Low: saved %d VMs\n", saved));
[15454]199 break;
200 }
[46775]201
202 default:
203 /* nothing */;
[15454]204 }
205}
[14772]206/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use