VirtualBox

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

Last change on this file since 69731 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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

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