VirtualBox

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

Last change on this file since 98103 was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: HostPower.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
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
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_MAIN_HOST
33#include "HostPower.h"
34#include "LoggingNew.h"
35
36#include <VBox/com/ptr.h>
37
38#include "VirtualBoxImpl.h"
39#include "MachineImpl.h"
40
41#include <iprt/mem.h>
42#include <iprt/cpp/utils.h>
43
44HostPowerService::HostPowerService(VirtualBox *aVirtualBox)
45{
46 AssertPtr(aVirtualBox);
47 mVirtualBox = aVirtualBox;
48}
49
50HostPowerService::~HostPowerService()
51{
52}
53
54void HostPowerService::notify(Reason_T aReason)
55{
56 SessionMachinesList machines;
57 VirtualBox::InternalControlList controls;
58
59 HRESULT rc = S_OK;
60
61 switch (aReason)
62 {
63 case Reason_HostSuspend:
64 {
65 LogFunc(("HOST SUSPEND\n"));
66
67#ifdef VBOX_WITH_RESOURCE_USAGE_API
68 /* Suspend performance sampling to avoid unnecessary callbacks due to jumps in time. */
69 PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector();
70
71 if (perfcollector)
72 perfcollector->suspendSampling();
73#endif
74 mVirtualBox->i_getOpenedMachines(machines, &controls);
75
76 /* pause running VMs */
77 for (VirtualBox::InternalControlList::const_iterator it = controls.begin();
78 it != controls.end();
79 ++it)
80 {
81 ComPtr<IInternalSessionControl> pControl = *it;
82
83 /* PauseWithReason() will simply return a failure if
84 * the VM is in an inappropriate state */
85 rc = pControl->PauseWithReason(Reason_HostSuspend);
86 if (FAILED(rc))
87 continue;
88
89 /* save the control to un-pause the VM later */
90 mSessionControls.push_back(pControl);
91 }
92
93 LogRel(("Host suspending: Paused %d VMs\n", mSessionControls.size()));
94 break;
95 }
96
97 case Reason_HostResume:
98 {
99 LogFunc(("HOST RESUME\n"));
100
101 size_t resumed = 0;
102
103 /* go through VMs we paused on Suspend */
104 for (size_t i = 0; i < mSessionControls.size(); ++i)
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) */
110 rc = mSessionControls[i]->ResumeWithReason(Reason_HostResume);
111 if (FAILED(rc))
112 continue;
113
114 ++resumed;
115 }
116
117 LogRel(("Host resumed: Resumed %d VMs\n", resumed));
118
119#ifdef VBOX_WITH_RESOURCE_USAGE_API
120 /* Resume the performance sampling. */
121 PerformanceCollector *perfcollector = mVirtualBox->i_performanceCollector();
122
123 if (perfcollector)
124 perfcollector->resumeSampling();
125#endif
126
127 mSessionControls.clear();
128 break;
129 }
130
131 case Reason_HostBatteryLow:
132 {
133 LogFunc(("BATTERY LOW\n"));
134
135 Bstr value;
136 rc = mVirtualBox->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(),
137 value.asOutParam());
138 int fGlobal = 0;
139 if (SUCCEEDED(rc) && !value.isEmpty())
140 {
141 if (value != "0")
142 fGlobal = 1;
143 else if (value == "0")
144 fGlobal = -1;
145 }
146
147 mVirtualBox->i_getOpenedMachines(machines, &controls);
148 size_t saved = 0;
149
150 /* save running VMs */
151 for (SessionMachinesList::const_iterator it = machines.begin();
152 it != machines.end();
153 ++it)
154 {
155 ComPtr<SessionMachine> pMachine = *it;
156 rc = pMachine->GetExtraData(Bstr("VBoxInternal2/SavestateOnBatteryLow").raw(),
157 value.asOutParam());
158 int fPerVM = 0;
159 if (SUCCEEDED(rc) && !value.isEmpty())
160 {
161 /* per-VM overrides global */
162 if (value != "0")
163 fPerVM = 2;
164 else if (value == "0")
165 fPerVM = -2;
166 }
167
168 /* default is true */
169 if (fGlobal + fPerVM >= 0)
170 {
171 ComPtr<IProgress> progress;
172
173 /* SessionMachine::i_saveStateWithReason() will return
174 * a failure if the VM is in an inappropriate state */
175 rc = pMachine->i_saveStateWithReason(Reason_HostBatteryLow, progress);
176 if (FAILED(rc))
177 {
178 LogRel(("SaveState '%s' failed with %Rhrc\n", pMachine->i_getName().c_str(), rc));
179 continue;
180 }
181
182 /* Wait until the operation has been completed. */
183 rc = progress->WaitForCompletion(-1);
184 if (SUCCEEDED(rc))
185 {
186 LONG iRc;
187 progress->COMGETTER(ResultCode)(&iRc);
188 rc = (HRESULT)iRc;
189 }
190
191 AssertMsg(SUCCEEDED(rc), ("SaveState WaitForCompletion failed with %Rhrc (%#08X)\n", rc, rc));
192
193 if (SUCCEEDED(rc))
194 {
195 LogRel(("SaveState '%s' succeeded\n", pMachine->i_getName().c_str()));
196 ++saved;
197 }
198 }
199 }
200 LogRel(("Battery Low: saved %d VMs\n", saved));
201 break;
202 }
203
204 default:
205 /* nothing */;
206 }
207}
208/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use