|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] xenagent: re-register shutdown watch after resume from S4
When xenagent resumes in a VM that was put into S4 it needs to re-
register the watch on control/shutdown and re-advertise all
control/feature-XXX flags.
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
src/xenagent/devicelist.cpp | 22 +++++++++++++
src/xenagent/devicelist.h | 3 ++
src/xenagent/service.cpp | 80 ++++++++++++++++++++++++++++++++-------------
src/xenagent/service.h | 5 +++
4 files changed, 88 insertions(+), 22 deletions(-)
diff --git a/src/xenagent/devicelist.cpp b/src/xenagent/devicelist.cpp
index 6b379e2..7053a96 100644
--- a/src/xenagent/devicelist.cpp
+++ b/src/xenagent/devicelist.cpp
@@ -237,6 +237,28 @@ void CDeviceList::OnDeviceEvent(DWORD evt, LPVOID data)
}
}
+void CDeviceList::OnPowerEvent(DWORD evt, LPVOID data)
+{
+ switch (evt) {
+ case PBT_APMRESUMESUSPEND:
+ for (DeviceMap::iterator it = m_devs.begin();
+ it != m_devs.end();
+ ++it)
+ m_impl->OnDeviceResume(it->second);
+ break;
+
+ case PBT_APMSUSPEND:
+ for (DeviceMap::iterator it = m_devs.begin();
+ it != m_devs.end();
+ ++it)
+ m_impl->OnDeviceSuspend(it->second);
+ break;
+
+ default:
+ break;
+ }
+}
+
CDevice* CDeviceList::GetFirstDevice()
{
DeviceMap::iterator it = m_devs.begin();
diff --git a/src/xenagent/devicelist.h b/src/xenagent/devicelist.h
index ee1d8ab..893bd43 100644
--- a/src/xenagent/devicelist.h
+++ b/src/xenagent/devicelist.h
@@ -63,6 +63,8 @@ public:
virtual CDevice* Create(const wchar_t* path) = 0;
virtual void OnDeviceAdded(CDevice* dev) = 0;
virtual void OnDeviceRemoved(CDevice* dev) = 0;
+ virtual void OnDeviceSuspend(CDevice* dev) = 0;
+ virtual void OnDeviceResume(CDevice* dev) = 0;
};
class CDeviceList
@@ -74,6 +76,7 @@ public:
bool Start(HANDLE svc, IDeviceCreator* impl);
void Stop();
void OnDeviceEvent(DWORD evt, LPVOID data);
+ void OnPowerEvent(DWORD evt, LPVOID data);
CDevice* GetFirstDevice();
private:
diff --git a/src/xenagent/service.cpp b/src/xenagent/service.cpp
index 6132fe0..2d06008 100644
--- a/src/xenagent/service.cpp
+++ b/src/xenagent/service.cpp
@@ -187,7 +187,9 @@ CXenAgent::CXenAgent() : m_handle(NULL), m_evtlog(NULL),
{
m_status.dwServiceType = SERVICE_WIN32;
m_status.dwCurrentState = SERVICE_START_PENDING;
- m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
+ m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
+ SERVICE_ACCEPT_SHUTDOWN |
+ SERVICE_ACCEPT_POWEREVENT;
m_status.dwWin32ExitCode = 0;
m_status.dwServiceSpecificExitCode = 0;
m_status.dwCheckPoint = 0;
@@ -214,6 +216,34 @@ CXenAgent::~CXenAgent()
return new CXenIfaceDevice(path);
}
+void CXenAgent::StartShutdownWatch()
+{
+ if (m_ctxt_shutdown)
+ return;
+
+ m_device->StoreAddWatch("control/shutdown", m_evt_shutdown,
&m_ctxt_shutdown);
+
+ m_device->StoreWrite("control/feature-poweroff", "1");
+ m_device->StoreWrite("control/feature-reboot", "1");
+ m_device->StoreWrite("control/feature-s3", "1");
+ m_device->StoreWrite("control/feature-s4", "1");
+}
+
+void CXenAgent::StopShutdownWatch()
+{
+ if (!m_ctxt_shutdown)
+ return;
+
+ m_device->StoreRemove("control/feature-poweroff");
+ m_device->StoreRemove("control/feature-reboot");
+ m_device->StoreRemove("control/feature-s3");
+ m_device->StoreRemove("control/feature-s4");
+
+ m_device->StoreRemoveWatch(m_ctxt_shutdown);
+ m_ctxt_shutdown = NULL;
+}
+
+
/*virtual*/ void CXenAgent::OnDeviceAdded(CDevice* dev)
{
CXenAgent::Log("OnDeviceAdded(%ws)\n", dev->Path());
@@ -222,16 +252,8 @@ CXenAgent::~CXenAgent()
if (m_device == NULL) {
m_device = (CXenIfaceDevice*)dev;
- // shutdown
- m_device->StoreAddWatch("control/shutdown", m_evt_shutdown,
&m_ctxt_shutdown);
- m_device->StoreWrite("control/feature-poweroff", "1");
- m_device->StoreWrite("control/feature-reboot", "1");
- m_device->StoreWrite("control/feature-s3", "1");
- m_device->StoreWrite("control/feature-s4", "1");
-
- // suspend
m_device->SuspendRegister(m_evt_suspend, &m_ctxt_suspend);
-
+ StartShutdownWatch();
SetXenTime();
}
}
@@ -242,24 +264,28 @@ CXenAgent::~CXenAgent()
CCritSec crit(&m_crit);
if (m_device == dev) {
- // suspend
- if (m_ctxt_suspend)
+ if (m_ctxt_suspend) {
m_device->SuspendDeregister(m_ctxt_suspend);
- m_ctxt_suspend = NULL;
-
- // shutdown
- m_device->StoreRemove("control/feature-poweroff");
- m_device->StoreRemove("control/feature-reboot");
- m_device->StoreRemove("control/feature-s3");
- m_device->StoreRemove("control/feature-s4");
- if (m_ctxt_shutdown)
- m_device->StoreRemoveWatch(m_ctxt_shutdown);
- m_ctxt_shutdown = NULL;
+ m_ctxt_suspend = NULL;
+ }
+ StopShutdownWatch();
m_device = NULL;
}
}
+/*virtual*/ void CXenAgent::OnDeviceSuspend(CDevice* dev)
+{
+ CXenAgent::Log("OnDeviceSuspend(%ws)\n", dev->Path());
+ StopShutdownWatch();
+}
+
+/*virtual*/ void CXenAgent::OnDeviceResume(CDevice* dev)
+{
+ CXenAgent::Log("OnDeviceResume(%ws)\n", dev->Path());
+ StartShutdownWatch();
+}
+
void CXenAgent::OnServiceStart()
{
CXenAgent::Log("OnServiceStart()\n");
@@ -277,6 +303,11 @@ void CXenAgent::OnDeviceEvent(DWORD evt, LPVOID data)
m_devlist.OnDeviceEvent(evt, data);
}
+void CXenAgent::OnPowerEvent(DWORD evt, LPVOID data)
+{
+ m_devlist.OnPowerEvent(evt, data);
+}
+
bool CXenAgent::ServiceMainLoop()
{
HANDLE events[3] = { m_svc_stop, m_evt_shutdown, m_evt_suspend };
@@ -577,6 +608,11 @@ DWORD WINAPI CXenAgent::__ServiceControlHandlerEx(DWORD
req, DWORD evt, LPVOID d
OnDeviceEvent(evt, data);
return NO_ERROR;
+ case SERVICE_CONTROL_POWEREVENT:
+ SetServiceStatus(SERVICE_RUNNING);
+ OnPowerEvent(evt, data);
+ return NO_ERROR;
+
case SERVICE_CONTROL_INTERROGATE:
SetServiceStatus(SERVICE_RUNNING);
return NO_ERROR;
diff --git a/src/xenagent/service.h b/src/xenagent/service.h
index 975662b..77a11d7 100644
--- a/src/xenagent/service.h
+++ b/src/xenagent/service.h
@@ -60,14 +60,19 @@ public: // IDeviceCreator
virtual CDevice* Create(const wchar_t* path);
virtual void OnDeviceAdded(CDevice* dev);
virtual void OnDeviceRemoved(CDevice* dev);
+ virtual void OnDeviceSuspend(CDevice* dev);
+ virtual void OnDeviceResume(CDevice* dev);
private: // service events
void OnServiceStart();
void OnServiceStop();
void OnDeviceEvent(DWORD, LPVOID);
+ void OnPowerEvent(DWORD, LPVOID);
bool ServiceMainLoop();
private: // helpers
+ void StartShutdownWatch();
+ void StopShutdownWatch();
void AcquireShutdownPrivilege();
void EventLog(DWORD evt);
bool IsHostTimeUTC();
--
2.1.1
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |