[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 6/6] Set VM's time based on host's time exposed by Xen



Sets the VM's time when XenIface starts and on resume from suspend.
Uses the underlying host's time, accessed via Xen. Provide an option
for the guest to treat Xen's time as UTC or the current timezone.
This option adds 2 new brandable variables that specify a partial 
registry path and value in the VM that determines how the time offset
is modified. These values are REG_TOOLS_PATH and REG_UTC_NAME which
should be specified in the build environment if the values need to
be different.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 build.py                 |  10 ++++
 src/xenagent/service.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++
 src/xenagent/service.h   |   4 ++
 3 files changed, 133 insertions(+)

diff --git a/build.py b/build.py
index f49374c..df30ee6 100755
--- a/build.py
+++ b/build.py
@@ -70,6 +70,10 @@ def make_header():
     file.write('#define DAY_STR\t\t\t"' + str(now.day) + '"\n')
     file.write('\n')
 
+    file.write('#define REG_TOOLS_PATH\t\t\t"' + os.environ['REG_TOOLS_PATH'] 
+ '"\n')
+    file.write('#define REG_UTC_NAME\t\t\t"' + os.environ['REG_UTC_NAME'] + 
'"\n')
+    file.write('\n')
+
     file.close()
 
 
@@ -426,6 +430,12 @@ if __name__ == '__main__':
     if 'OBJECT_PREFIX' not in os.environ.keys():
         os.environ['OBJECT_PREFIX'] = 'XenProject'
 
+    if 'REG_TOOLS_PATH' not in os.environ.keys():
+        os.environ['REG_TOOLS_PATH'] = 'XenTools'
+
+    if 'REG_UTC_NAME' not in os.environ.keys():
+        os.environ['REG_UTC_NAME'] = 'HostTime'
+
     os.environ['MAJOR_VERSION'] = '8'
     os.environ['MINOR_VERSION'] = '2'
     os.environ['MICRO_VERSION'] = '0'
diff --git a/src/xenagent/service.cpp b/src/xenagent/service.cpp
index 3e621eb..a4d9297 100644
--- a/src/xenagent/service.cpp
+++ b/src/xenagent/service.cpp
@@ -218,6 +218,8 @@ CXenAgent::~CXenAgent()
 
         // suspend
         m_device->SuspendRegister(m_evt_suspend, &m_ctxt_suspend);
+
+        SetXenTime();
     }
 }
 
@@ -317,6 +319,121 @@ void CXenAgent::EventLog(DWORD evt)
     }
 }
 
+bool CXenAgent::IsHostTimeUTC()
+{
+#ifdef _WIN64
+    // Check SOFTWARE\Wow6432Node\$(VENDOR_NAME_STR)\$(REG_TOOLS_PATH) 
$(REG_UTC_NAME) == UTC
+    if (RegCheckIsUTC("SOFTWARE\\Wow6432Node"))
+        return true;
+#endif
+    // Check SOFTWARE\$(VENDOR_NAME_STR)\$(REG_TOOLS_PATH) $(REG_UTC_NAME) == 
UTC
+    if (RegCheckIsUTC("SOFTWARE"))
+        return true;
+
+    return false;
+}
+
+void CXenAgent::AdjustXenTimeToUTC(FILETIME* now)
+{
+    std::string vm;
+    if (!m_device->StoreRead("vm", vm))
+        return;
+
+    std::string offs;
+    if (!m_device->StoreRead(vm + "/rtc/timeoffset", offs))
+        return;
+
+    long offset = (long)atoi(offs.c_str());
+
+    ULARGE_INTEGER lnow;
+    lnow.LowPart  = now->dwLowDateTime;
+    lnow.HighPart = now->dwHighDateTime;
+
+    lnow.QuadPart -= ((LONGLONG)offset * 1000000);
+
+    now->dwLowDateTime  = lnow.LowPart;
+    now->dwHighDateTime = lnow.HighPart;
+}
+
+bool CXenAgent::RegCheckIsUTC(const char* rootpath)
+{
+    HKEY    key;
+    LRESULT lr;
+    std::string path;
+    bool    match = false;
+
+    path = rootpath;
+    path += "\\";
+    path += VENDOR_NAME_STR;
+    path += "\\";
+    path += REG_TOOLS_PATH;
+
+    lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
+    if (lr != ERROR_SUCCESS)
+        goto fail1;
+
+    long size = 32;
+    DWORD length;
+    char* buffer = NULL;
+
+    do {
+        length = size;
+        if (buffer)
+            delete [] buffer;
+
+        buffer = new char[size];
+        if (buffer == NULL)
+            goto fail2;
+
+        lr = RegQueryValueEx(key, REG_UTC_NAME, NULL, NULL, (LPBYTE)buffer, 
&length);
+        size *= 2;
+    } while (lr == ERROR_MORE_DATA);
+    if (lr != ERROR_SUCCESS)
+        goto fail3;
+
+    if (!_strnicoll("UTC", buffer, length))
+        match = true;
+
+fail3:
+    delete [] buffer;
+fail2:
+    RegCloseKey(key);
+fail1:
+
+    return match;
+}
+
+void CXenAgent::SetXenTime()
+{
+    // Set VM's time to Xen's time (adjust for UTC settings of VM and guest)
+    FILETIME now = { 0 };
+    if (!m_device->SharedInfoGetTime(&now))
+        return;
+
+    bool IsUTC = IsHostTimeUTC();
+    if (IsUTC)
+        AdjustXenTimeToUTC(&now);
+
+    SYSTEMTIME sys = { 0 };
+    if (!FileTimeToSystemTime(&now, &sys))
+        return;
+
+    SYSTEMTIME cur = { 0 };
+    GetLocalTime(&cur);
+
+    CXenAgent::Log("Time Now = %d/%d/%d %d:%02d:%02d.%d\n",
+                   cur.wYear, cur.wMonth, cur.wDay,
+                   cur.wHour, cur.wMinute, cur.wSecond, cur.wMilliseconds);
+    CXenAgent::Log("New Time = %d/%d/%d %d:%02d:%02d.%d\n",
+                   sys.wYear, sys.wMonth, sys.wDay,
+                   sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
+
+    if (IsUTC)
+        SetSystemTime(&sys);
+    else
+        SetLocalTime(&sys);
+}
+
 void CXenAgent::OnShutdown()
 {
     CCritSec crit(&m_crit);
@@ -379,6 +496,8 @@ void CXenAgent::OnSuspend()
     EventLog(EVENT_XENUSER_UNSUSPENDED);
 
     m_device->StoreWrite("control/feature-shutdown", "1");
+
+    SetXenTime();
 }
 
 void CXenAgent::SetServiceStatus(DWORD state, DWORD exit /*= 0*/, DWORD hint 
/*= 0*/)
diff --git a/src/xenagent/service.h b/src/xenagent/service.h
index fb8a1ee..bf5cc76 100644
--- a/src/xenagent/service.h
+++ b/src/xenagent/service.h
@@ -71,6 +71,10 @@ private: // service events
 private: // helpers
     void AcquireShutdownPrivilege();
     void EventLog(DWORD evt);
+    bool IsHostTimeUTC();
+    void AdjustXenTimeToUTC(FILETIME* time);
+    bool RegCheckIsUTC(const char* path);
+    void SetXenTime();
     void OnShutdown();
     void OnSuspend();
 
-- 
1.9.4.msysgit.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://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®.