[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |