VirtualBox

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

Last change on this file since 53390 was 51498, checked in by vboxsync, 11 years ago

6813 - MachineImpl use of server side wrappers + misc mods on other classes

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