K tomu bych měl dotaz, počítá si windows nějak "ticky času" že ví že běžel třeba x dní čistého času (po nějakých třeba minutových checkpointech) a pak se nastřádaný drift času při posunu systémového data v hypervizoru /biosu/nastavení času v guestovi nějak projeví?
Nerozumím otázce :-( Zkuste to pomaleji, pro mě pomalejšího...
Podrobnosti:
Zjistit uptime ve Windows lze, nejsnáz asi v Task Manageru = správci úloh (Ctrl+Shift+Esc), menu vlevo Výkon -> Procesor. V levém dolním rohu je číslo ve formátu dny:hodiny:minuty:sekundy od startu.
Datum a čas posledního startu se dá zjistit z příkazového řádku takto:
systeminfo | find "System Boot Time"
Windowsy při startu natáhnou momentální lidský čas z RTC, a při vypnutí aktuální čas do RTC uloží. RTC je maličký šváb nebo blok v čipsetu někde na motherboardu, zálohovaný knoflíkovou baterkou. Má krystal 32768 Hz, děličku 1/2^15 a pár registrů mapovaných do IO space hostitelského procesoru.
Mezi startem a vypnutím jede čas softwarově. HW RTC kdesi na motherboardu sice za běhu OS běží dál, ale nebere se na něj ohled. OS si jede "v softwaru" svoji vlastní runtime časovou základnu. Tato softwarová časová základna používá jeden z několika HW čítačů/časovačů architektury PC, kterým se nechá pravidelně budit pomocí IRQ. V DOSu tradičně byla perioda časovače asi 54.9 ms (18.2 Hz), pod Windows tradičně 15.6 ms. Relativně moderním trendem je, že se systémová časová základna naschvál budit nenechá, aby šetřila napájení - a vzbudí se jenom když je příležitost, a uběhlý čas počítá podle hardwarového TSC, což je primitivní 64b registr CPU, který počítá tiky "furt dopředu". Klíčová slova v linuxu jsou tickless / dynticks.
Softwarové časové základny se lze kdykoli zeptat "kolik je hodin", a ona odpoví s rozlišením buď na milisekundu, nebo tuším 100 ns (WinAPI funkce GetSystemTime() a GetSystemTimeAsFileTime()). V zásadě si interně drží údaj, kolik bylo hodin, když byl naposledy vyvolán její interrupt časomíry, a jaký byl tehdy stav TSC, takže kdykoli se nějaký ostatní software zeptá, časová základna si prostě dopočítá, kolik zrovna je. Dotaz na TSC je softwarově "levný", je na to instrukce CPU.
Systémovou časovou základnu lze také požádat "vzbuď mě za 11m:23s" nebo "vzbuď mě v 03:34:25". V tom případě si i tickless kernel "nastaví budíka v hardwaru" a v nastaveném čase obdrží interrupt - v rámci jeho obsluhy nastaví čekajícímu procesu "runnable" flag a pošťouchne scheduler k činnosti...
Systémová softwarová časová základna má ponětí, jaký časový úsek odpovídá jednomu tiku periodického timeru (postaru) resp. jednomu tiku TSC (ponovu/tickless). Pokud zavěsíte systémovou časovou základnu na upstream NTP, tak si tuto představu či koeficient průběžně aktualizuje, případně dokáže ovlivňovat frekvenci tikání periodického timeru (postaru). Vlastní systémová časová základna žije v kernelu (odehrává se částečně v kontextu IRQ). Závěs na NTP zajišťuje user-space prográmek (serviska) - tato sleduje odchylku lokální časové základny od upstream NTP, velkou odchylku doladí jednorázově skokem, následně malé odchylky dolaďuje jemnými změnami "rychlosti běhu lokální systémové časové základny". Pro toto dolaďování parametrů běhu poskytuje časová základna WinAPI funkci SetSystemTimeAdjustment() - obdoba linuxové adjtimex().
Systémová časová základna používá hodinový takt a HW čítače/časovače, které jsou živé při běhu počítače (ve vypnutém stavu nikoli). Lokální referencí těchto různých provozních taktů a čítačů je v konečné instanci jeden konkrétní krystal na motherboardu, od kterého jsou sychronními děličkami a PLL syntezátory odvozené hodiny pro všechny sběrnice / procesor / čipset. (Sem tam nějaká periferie má šutr svůj vlastní, třeba ethernetové čipy.) Tenhle krystal není nijak zvlášť přesný a stabilní - řekněme něco jako 10^-5 až 10^-6. Proto si softwarová časová základna může nastavit dělící poměr používaného HW čítače/časovače (pokud to lze), nebo spíš jeho mírnou odchylku post-kompenzuje softwarově při přepočtech na lidský čas.
Časová základna moderních operačních systémů, a také například NTP, běží interně v UTC. Což je stupnice, která občas vloží přestupnou sekundu (nebo teoreticky taky vypustí, což se ale nikdy nestalo). Existují příbuzené stupnice, které tikají stejně rychle, ale přestupné sekundy nevyužívají, a tedy mají oproti UTC pevný offset: zmínil bych GPS time a ještě třeba TAI (kterou znám z protokolu IEEE1588=PTP).
UTC nevyužívá přechody zimní/letní čas.
Lokální časové zóny a přechody zimní/letní čas jsou záležitostí "prezentace v uživatelském rozhraní". Operační systém nabízí připravené funkce ke konverzím časové značky mezi zónami, ale systémová časová základna toto v podstatě neřeší - tiká si prostě svoje UTC.
No a ve virtualizačním prostředí lze nastavit, aby emulovaný guest-side HW RTC tiše ignoroval nastavení času při vypnutí OS ve VM guestovi, a aby namísto toho při každém zapnutí guesta emulovaný RTC převzal čas z časové základny hostitelského hypervizoru. Hypervizor může být zavěšený na NTP apod. Díky tomu má VM guest po každém zapnutí přesný čas.
Věc má nuanci. Aneb čerstvá příhoda z natáčení, aktuální Proxmox vs. aktuální Windowsy:
UNIX a Linux tradičně ukládá čas do RTC v zóně UTC.
Naopak Windows Server dodnes by default předpokládá, že RTC jede v lokální časové zóně! Je to zjevně dědictví desktopových windows a DOSu a světa IBM PC, kdy se RTC provozoval tradičně v lokální časové zóně (protože dávný OS nevěděl, že je něco jiného než lokální čas.)
Což vede k různým legracím pokud střídání času proběhne ve chvíli, kdy počítač neběží. Nebo ho obnovíte ze zálohy, která byla pořízena v opačném stavu letního/zimního času. Nebo počítač startuje z disku v read-only režimu. Windows totiž provedou přechod na letní čas ve chvíli, kdy ho "zažijí v zapnutém stavu", nebo nastartují v období letního času, aniž by měly na disku záznam, že provedly poslední proběhlý přechod.
Takže Windows Server předpokládá a používá RTC v lokální časové zóně, včetně přechodů léto/zima.
Proxmox o tom ví, pročež je by default nastavený, aby emulovaný RTC startoval s časem v lokální časové zóně.
Problém nastane ve chvíli, kdy virtuál s instancí Windows Serveru spouštíte jenom občas, podle potřeby. Takže se stane, že během přechodu zimní/letní čas je virtuál vypnutý. Při dalším startu mu Proxmox podá RTC už po přechodu se správným lokálním časem... a Windowsy ve VM guestovi si přechod provedou *znovu* - takže běží s časem posunutým o hodinu vedle :-)
Jak tomuto jevu zabránit? Osobně bych navrhoval, držet se UNIXové konvence: RTC jede v UTC.
Kupodivu není úplně snadné, přemluvit aktuální Windows Server, aby si RTC provozoval v UTC! (Nešlo to kdysi během instalace jedním kliknutím?) Je potřeba sáhnout do powershellu:
reg add "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /t REG_DWORD /d 1 /fA v Proxmoxu ve vlastnostech VM je také třeba nastavit, že emulovaný RTC uvnitř guest VM jede v UTC.
Zvolte dotyčný guest VM -> Options -> Use local time for RTC: *No*