[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.