KVM (čas)

Z DCEwiki
(přesměrováno z KVM (timing))
Skočit na navigaci Skočit na vyhledávání

Přesný čas je základním předpokladem pro fungování počítače. Problémy s časem ve virtualizovaném prostředí mohou vést ke zdánlivě záhadným kolapsům, proto je nutné vědět...

  1. jak fungují hodiny a korekce času jak ve fyzickém hostitelském stroji
  2. jakým způsobem je čas propagován do virtualizovaného prostředí
  3. a jak pak s časem pracuje virtuální stroj.
Poznámka I když bude primárně řeč o práci s časem v linuxovém prostředí, přijde na řadu i to jak funguje nastavení času v prostředí systémů MS Windows, aby bylo jasné, jak se dá změnit jejich zdroj času při ev. problémech s časem u virtualizovaného stroje s takovým OS.

Čas na hostiteli virtuálních strojů

V každém počítači se nachází několik potencionálních zdrojů času a v každém systému je k dispozici dvojí čas. Čas označovaný jako hardwarový měří obvykle nějaký hardwarový čip umístěný na základové desce a čas systémový si udržuje sám spuštěný systém.

Hardwarový čas

Hardwarový čas odměřují čipy, jejichž "srdcem" je kmitající křemíkový krystal. Oscilace krystalu generuje přerušení, které se počítá pomocí registru. Každé přerušení představuje jeden "tik". BIOS (případně operační systém) pak tyto tiky přepočítává na čas se kterým lze dále pracovat.

Problémem všech hodin postavených na kmitání křemíkového krystalu je, že i když "tikají" v pravidelných intervalech, nelze je použít pro měření času přímo, protože nelze vyrobit krystaly tak, aby kmitaly absolutně stejnou frekvencí. Některý krystal kmitá pomaleji, jiný rychleji. Protože však je rychlost zrychlení (příp. zpomalení) konstatní a pohybuje se spíše v řádech minut než hodin, lze pro každý čip vypočítat koeficient, kterým umožňuje zjistit jak velká je odchylka na určitý počet tiků.

Čip, který funguje jako hardwarové hodiny je jakožto součást CMOS napájen z malé baterie umístěné na základní desce. Díky tomu jeho čas běží i když je stroj vypnutý.

Zpočátku se tyto hardwarové hodiny používaly i k měření času přímo v operačním systému, jenže měřily čas s nízkou granularitou. Tj. nebylo možné s nimi změřit interval kratší než 1/20 sekundy[1]. Rostoucí frekvence procesorů a tím i celého systému však vyžadovala jemnější měření, proto se k měření systémového času začaly používat jiné zdroje času

Hardwarové hodiny však mají ještě jeden neduh a to, že načítání aktuálního času je z nich relativně pomalé. Proto se o udržení přesného času v linuxovém jádře stará vrstva clocksource, která zastřešuje různé zdroje času a provádí nejrůznější kejkle, aby byl systémový čas co nejpřesnější.

Ovšem díky stabilitě tiku a předvídatelné velikosti časové odchylky se hardwarové hodiny udržely jako zdroj "skutečného času" (RTC - Real Time Clock) při spuštění operačního systému

Systémový čas

Linuxové jádro měřilo původně čas podle tiku z PIT. Od verze 2.6.18[2] byl ale celý koncept časování přepracován tak, že byla přidána abstraktní vrstva clocksource, která jednak odstínila zdroj času od skutečného hardware, ze kterého trvalo načtení přesného času delší dobu, ale zároveň umožnila používat i jiné zdroje času.

Další významnou změnou pak byl přechod na beztikové jádro. Tj. jádro, které neměří svůj čas podle pravidelných tiků krystalu hardwarového čipu, ale podle plánovaných přerušení na časovačích.

CLOCK_MONOTONIC

Aktuální čas se v linuxovém jádře udržuje v několika proměnných, které se svou hodnotou liší. Z hlediska lokálního systému je nejpřesnější tzv. monotonický čas (CLOCK_MONOTONIC), který má bod nula v okamžiku spuštění stroje.

CLOCK_REALTIME

Zatím co monotonický času se měří od spuštění stroje, pro upíchnutí stroje v čase je důležitý skutečný čas (CLOCK_REALTIME), což je v podstatě zkorigovaná výchozí hodnota času načtená při startu z RTC, ke které se připočítá monotonický čas.

Skutečný čas má svůj počátek v pomyslném bodě nula, kterým je 00:00:00 UTC 1. ledna 1970[3]. A od monotonického času se liší i způsobem kterým lze změnit hodnotu kterou vrací.

Nastavení výchozí hodnoty CLOCK_REALTIME

Skutečný čas, který má nulu na počátku r. 1970 se nastavuje v Debianu při startu počítače spouštěcím skriptem /etc/init.d/hwclockfirst.sh, který zavolá utilitu hwclock. Ta, na aktuální časové razítko (timestamp) vytažené z hardwarových hodin (RTC) aplikuje koeficient zpoždění (či zrychlení), vypočtený a uložený v textovém souboru /etc/adjtime. A teprve výslednou hodnotu použije jako výchozí hodnotu pro CLOCK_REALTIME.

Od tohoto okamžiku již běží čas v CLOCK_REALTIME nezávisle na hardwarovém čase!

Obsah souboru můžete vidět níže

Poznámka
user@stroj:~$ cat /etc/adjtime
0.481047 1318428140 0.000000
1318428140
UTC
user@stroj:~$ date
St říj 12 23:23:40 CEST 2011
user@stroj:~$ date -d @1318428140
St říj 12 16:02:20 CEST 2011

Výpočet koeficientu obvykle provádí hwclock když je zavolán při korektním vypnutí systému spouštěcím skriptem /etc/init.d/hwclock.sh. Při výpočtu se vychází z premisy, že systémový čas v CLOCK_REALTIME, který je založen na monotonickém čase, je přesnější a navíc mohl být průběžně korigován přes NTP protokol vůči jiným zdrojům přesného času. Proto při výpočtu korekce nepočítá jak velký je posun hardwarového času vůči skutečnému času, ale jak se průběžně rozchází frekvence tiku hardwarových hodin od frekvence tiku hodin systémových.

Je-li čas, hardwarových hodin posunutý, zůstane posunutý i restartu počítače!

Posun hardwarových hodin lze zkorigovat jedině natažením aktuálního časového razítka systémového času pomocí hwclock do hardwarových hodin.

Poznámka
user@stroj:~# hwclock --systohc

Zdroje času

HPET

V dnešních čipsetech jsou již většinou integrovány čipy mnohem přesnější než původní PET, které se označují jako HPET. High Precision Event Timer je velmi přesný 64 bitový programovatelný hardwarový časovač, který však nemusí být k dispozici na všech strojích. Jeho použití, coby zdroje času také nemusí být vždy bezproblémové. HPET je totiž hardwarově integrován na úrovni chipsetu, nikoliv CMOS, jako PIT a tak se u některých chipsetů stává, že jej ACPI uspí spolu se zbytkem chipsetu.

Po probuzení ale HPET o této vynucené přestávce nic neví a pokud je hlavním zdrojem času, projeví se tento problém tak, že systémový čas je oproti HW času o interval který HPET prospal posunutý do minulosti[4].

ACPI_PM

Zdroj času, který nikdy nespí, je programovatelný časovač, který dělá v čipsetu budíka pro ACPI. To podle něj řídí správu napájení (Power Management). Je přesnější než PIT, protože jde o 24-bitový čítač s frekvencí 3.579545MHz (což odpovídá zhruba trojnásobku frekvence PIT). Nepoužívá žádný registr a jeho čas se po přetočení začíná počítat vždy znovu od nuly. Jeho výhodou oproti jiným zdrojům času však je, že zůstává v běhu i když jsou ostatní zdroje času uspané nebo zpomalené.

Nevýhodou ACPI_PM je zdlouhavý proces čtení aktuálního času, který trvá jednu až dvě mikrosekundy.

TSC

Naopak velmi rychlé je čtení aktuálního času z TSC. TSC není žádný speciální časovač, ale pouze hodnota časového razítka procesoru - rdtsc (Read Time-Stamp Counter). Toto časové razítko je závislé na frekvenci procesoru, proto není TSC spolehlivý zdroj času na strojích, kde systém mění frekvenci procesoru přes cpufreq, nebo tehdy, je-li virtuální stroj, který s hodnotou TSC pracuje, migrován mezi hostiteli s jinou frekvencí TSC!

Je-li hodnota TSC v procesoru stabilní lze zjistit podle toho, zda-li má uvedeno mezi svými flags constant_tsc. Pokud mezi nimi chybí, vypněte v BIOSu všechny věci, které nějak souvisí se správou napájení.

Aby linuxové jádro neměnilo frekvenci procesoru, lze také zabránit tak, že se mu předá hodnota

processor.max_cstate=1

a nebo tak, že se v konfiguračním souboru cpufreq /etc/sysconfig/cpuspeed nastaví hodnota jako pro MIN_SPEED, tak pro MAX_SPEED na maximum. Jakou maximální hodnotu uvést lze zjistit ze souboru /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies


Jak vypnout použití TSC u virtuálu

U hostitelů, které časovač TSC k dispozici nemají, nebo pokud nechcete aby jej virtuální stroj používal je nutné při startu 64 bitového kernelu virtuálního stroje předat parametr notsc. a 32 bitovému zase pro změnu implicitně přes clocksource říct, aby používal jako zdroj času acpi_pm

Systémové hodiny : Si nastaví svůj výchozí čas při spuštění podle zkorigovaného času z hardwarových hodin, ovšem pak již měří čas podle beztikových zdrojů, které nejsou založeny na pravidelném tepu nějakého oscilátoru, ale na událostech. Navíc mohou být průběžně korigovány z různých zdrojů.

Přímé dotazy na fyzické zařízení však jsou poměrně zdlouhavá záležitost, proto linuxové jádro používá hardwarové hodiny jako zdroj času pouze pro výchozí nastavení, a pak jižměří čas na jiném zdroji času, kterým je většinou nějaký časovač (timer).


Ovšem z hlediska komunikace mezi počítači je podstatný


Upozornění Příkaz date sice provede změnu času v systému, ale neudělá potřebnou korekci hardwarových hodin, Při ukončení se vypočítává koeficient zpoždění (či zrychlení) hardwarových hodin, a neřeší se o kolik jsou posunuty.


Časovače ( angl. timers) umožňují naplánovat spuštění události (angl. event) po uplynutí určitého intervalu.

který se vytáhne buď z hodnoty CLOCK_REALTIME, nebo . A


Systém používá vždy pouze jeden výchozí zdroj času, ale v případě, že tento zdroj přestane být spolehlivý (kontrolní odchylka přesáhne určitou mez), si - pokud má tu možnost - vybere zdroj jiný.

Jaký zdroj času používá zrovna váš linuxový systém můžete zjistit ze souborů v poadresáři /sys/devices/system/clocksource/clocksource0/current_clocksource

Poznámka
user@stroj:~$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
tsc hpet acpi_pm
user@stroj:~$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource
tsc

Z ukázkového výpisu je zřejmé, že stroj má k dispozici kromě aktuálně nastaveného tsc k dispozici ještě další dva.

Poznámka Ačkoliv název podadresáře clocksource0 evokuje myšlenku že by zde mohly existovat i jiné zdroje času, osobně jsem žádný jiný než tento adresář zatím neviděl

Časovače na fyzickém hardware

lapic

je programovatelný hardwarový časovač, který se nalézá v jádře procesoru (Local APIC Timer)

Zdroje času na fyzickém hardware, které zároveň fungují jako časovače

pit

Programmable Interval Timer je nejstarší programovatelný hardwarový časovač založený na chipu Intel 8253. Dnes se už v počítačích nevyskytuje, ale lze se s ním setkat u strojů na kterých je emulován (např. virtuály virtualizované v prostředí VMware).

acpi_pm

Programovatelný časovač, který se nalézá v chipsetu.

Zdroje času na fyzickém hardware

jiffies

jiffy je anglický výraz nejasného původu, který označuje blíže nespecifikovaný krátký časový interval, významově odpovídající českému výrazu "mžik" [5]. Z hlediska linuxového kernelu jde o časovač, který původně počítal jednotlivé "tiky" procesoru (tik == přerušení). To však dělalo problémy u beztikových jader. Obzvlášť pokud byl systém ve stavu idle ("uspaný"). Proto od kernelu verze 2.6.21 není jiffies již není navázaný na přerušení procesoru, ale na frekvenci úloh, která se nastavuje při kompilaci jádra[6]. Tím že jsou jiffies závislé na této frekvenci a navíc i na použité platformě[7] je dáno, že patří mezi nejméně spolehlivé zdroje času.

tsc

Čas na virtuálních strojích

Vzhledem k tomu, že hardware virtuálních strojů je většinou emulován hostitelem, může mít operační systém virtuálního stroje k dispozici stejné zdroje času jako kdyby šlo o stroje fyzické. Jenže s ohledem na skutečnost jsou pouze emulovány, je jejich přesnost a spolehlivost závislá na tom, jakým způsobem operační systém hostitele emulaci provádí. A v případě že se objeví nějaký problém na zdroji času hostitele o tom virtuální stroj vůbec nic nemusí vědět.

Principiálně by však tyto emulované zdroje času měly být přinejmenším stejně nespolehlivé  ;-) jako ty "skutečné". Je otázkou, co a jak je emulováno. Kupř. tik hardwarových hodin, emulovaný prostřednictvím časovače může být dokonce přesnější než skutečné hardwarové hodiny.

Krajně nespolehlivým zdrojem času ve virtualizovaném prostředí je TSC. Otázkou je, zda-li a jak je propagován do virtuálu HPET. Pro ten však musí existovat podpora i jádře virtualizovaného stroje. Poměrně spolehlivým zdrojem se zdá ACPI_PM, už jen s ohledem na to, že by na jeho tik nemělo mít z principu vliv ani emulované ACPI virtuálního stroje. jiffies je totálně k ničemu.

Použití NTP ve virtuálním prostředí KVM ztrácí smysl, protože pokud je vyřešen přesný čas v hostitelském systému, tak by malě být přesná o většina emulovaných zdrojů času. Naopak korekce systémového času přes NTP ve virtualizovaném prostředí může vyústit ve velmi podivné úkazy, pokud virtuální stroj se spuštěným NTP démonem ztratí konektivitu na stroje vůči kterým svůj čas synchronizuje.


Stroje virtualizované v prostředí VMware jsou nejčastěji navázané na použití emulovaného tsc (rtc)[8], ale virtuální prostředí jako KVM, nebo XEN propagují do virtuálního prostředí vlastní zdroje času.

rtc
Pokud virtuální stroj běží pod jiným uživatelem než root může být s přístupem k tomuto zdroji času. Řešením je buď přidat při spouštění virtuálu volbu -no-rtc, nebo upravit nastavení práv pro zařízení /dev/rtc0
xen
dyntick
je beztikové počítadlo, které může běžet i když je systém ve stavu idle (uspaný)
kvm-clock

Změna zdroje času v linuxovém kernelu

Defaultní zdroj času lze v linuxu změnit za běhu přepsáním hodnoty v souboru ..., nebo ho nastavit při bootu tak, že se jádru předá příslušná hodnota clocksource

clocksource=hpet


Zdroje času u MS Windows

Systémy MS Windows používají jako výchozí zdroj času rtc (Real-Time Clock), ale mohou používat i tsc (Time Stamp Counter), pokud se jim to implicitně nastaví při bootu. Pokud tedy není na hostiteli hardwarový čas stabilní, je lepší virtualizovanému stroji s MS Windows při startu říct aby používal tsc.

Od MS Windows Vista se to dělá přes aplikaci bcdedit.exe (Boot Configuration Data Editor)

Postup:

  1. V prostředí virtuálního stroje vyhledejte v menu Start, mezi položkami Příslušenství (Accessories) Příkazový řádek (Command Prompt). Klikněte nad touto položkou pravým tlačítkem myši a v kontextovém menu, které se objeví zvolte (Run as Administrator)
  2. Odklepněte případné upozornění
  3. A na spuštěné příkazové řádce spusťte následující příkaz..
Poznámka
C:\Windows\system32>bcdedit /set {default} USEPLATFORMCLOCK on

Hodnotou {default} je systémové UUID zaváděného systému. Změna se projeví až po restartu.

To však neplatí pro starší verze MS Windows (XP). U těch se nastavuje tsc jako zdroj času předáním parametru pmtimer v konfiguračním souboru zavaděče boot.ini.Viz příklad níže.

Poznámka
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /usepmtimer

  1. Interval mezi dvěma tiky trval cca 50 milisekund.
  2. U 64 bitové platformy až od verze 2.6.21
  3. K podání návrhu normy, která měla tento tento okamžik formálně zakotvit v ISO standardu, došlo v r.1971 ovšem k jejímu schálení (ISO 2014) došlo až r. 1976. Tato norma se pak stala základem aktuální normy ISO 8601, která určuje mj. i formu zápisu.
  4. Dělával to prý BIOS u IBM chipsetů, které měly HPET integrován v "severním můstku", při předání řízení chipsetu jádru.
  5. Což dokládá i příklad použití slova jiffy na anglické wikipedii - "I'll be back in a jiffy"
  6. Hodnota nastavená při kompilaci jádra v CONFIG_HZ
  7. Při hodnotě 1000HZ na 32 bitovém systému se začne čas rozcházet zhruba po 50 dnech, zatím co u 64 bitovém 1000HZ údajně až po 600 miliónech let.
  8. http://www.vmware.com/files/pdf/Timekeeping-In-VirtualMachines.pdf