Přestupná sekunda?

Michal Dobes dobes na tes.eu
Neděle Prosinec 28 21:57:04 CET 2008


Pavel Kankovsky napsal(a):
>> 	tak nějak jsem nucen přemýšlet nad tím, jak vlastně probíhá
>> v linuxu proces přestupné sekundy, jak nám bude na konci tohoto roku
>> nadělena (přesněji až 1. ledna v 00:59:60 SEČ v ČR) po několika letech 
> 
> Ono to žádným dobrým způsobem nejde udělat, protože POSIXová časová řada
> prostě na jednu stranu s existencí přestupných sekund nepočítá a každý den
> je podle ní dlouhý přesně 86400 s, na druhou stranu se mají od ní odvozené
> časové údaje shodovat s těmi podle UTC.

Nicméně i linux jde nastavit, že se nemá chovat POSIXově, ale ISOvě
a přestupné sekundy podporovat korektně a počítat s nimi. Stačí si
nastavit vhodné timezone soubory z podadresáře right, které obsahují
definice přestupných sekund a pak se s tím dá normálně pracovat
a knihovní funkce to také zvládají (pro hraní si stačí třeba definovat
TZ=right/MET). Ale trochu to rozhodí pár programů, které počítají
natvrdo s tím minuta=60 s, den=86400 s.

> Což znamená, že během přestupné sekundy přicházejí do úvahy jen asi tři 
> možnosti:
> 
> 1. hodiny stojí,
> 2. hodiny jdou nějakou delší dobu pomaleji,
> 3. hodiny se vrátí o sekundu zpět.
> 
> Každá možnost má nějaké přednosti a nějaké nedostatky.
> 
>> Čili je tam skok v čase zpět, což některým věcem může kapánek vadit.
> 
> Kapánek ano. Ale na druhou stranu: vzhledem k tomu, jak přesné a stabilní
> hodiny jsou v běžných počítačích, bych řekl, že se potřeba opravit hodiny
> skokem zpět vyskytuje v posledních pár letech výrazně častěji než
> přestupná sekunda.

Toto jsem nepozoroval, pokud je při startu systému poprvé korigováno 
skokově, tak než se pak ntp démon chytne a synchronizuje se mi nestalo, 
že by čas systému ujel o víc než těch defualt 128 ms, takže to 
regulovalo plynulou změnou. Samozřejmě to znamená, že mám trvale při
startu vždy nějaký nadřízený syncnutý ntp démon k dispozici a funkční
spojení (na fyzickém počítači bez prznění virtualizací).

>> [...] čili pokud vlákno používá pro buzení nějakou formu časovače třeba
>> po 200 ms, tak bude v době přestupné sekundy vzbuzeno o sekundu později
>> místo těch 200 ms?
> 
> Jádro jede interně podle jiffies a ty jsou zásadně monotónní (tedy
> obvykle, viz níže).

Ano, kernel jede takto interně, já to bral externě z pohledu user space
a tam dle pokusů opravdu cvičení s časem o sekundu zpět (pomocí
adjtimex() a příkazu k vložení přestupné sekundy) rozhodí časování
u starších knihoven a kernelů, kde nic jiného, než CLOCK_REALTIME není
k dispozici. A občas to vypadá zajímavě. Mám vlákno, které se má budit
po 20 ms, časování dělám pomocí pthread_cond_timedwait() na ETIMEOUT
a v okamžiku vložení přestupné sekundy vzbuzení vypadá takto (čas
z gettimeofday()):
1230076799.882841
1230076799.902841
1230076799.922840
1230076799.942840
1230076799.962839
1230076799.982844
1230076799.002849  <- těsně před tímto kernel cuknul zpět časem
1230076800.002918

Byla tam opravdu sekunda pauza (ověřováno čtením čítače v PCI kartě,
která o čase v systému nic neví).

U nových kernelů/libc tento problém není, tam je k dispozici časovač
CLOCK_MONOTONIC a i NPTL ho standardně používá.

>> 	Sice ve zdrojácích kernelu je moudrá poznámka, že když je
>> v činnosti ntp nebo něco podobného, tak je jeho starostí, aby v dané
>> době čas plynul  monotonně, ale nějak nemám představu, jak to zařídí.
> 
> Obávám se, že to nijak nezařídí, protože by to musel udělat výše uvedeným 
> postupem č. 2, který by ale vedl k tomu, že by měl v určitém okamžiku 
> odchylku hodin nejméně 0,5 s. Ovšem ntpd obvykle toleruje pouze odchylku 
> do 128 ms, a pokud je větší, tak hodiny přenastaví skokem.

On to tak ntpd možná dneska dělá. Jednak se dá ntp démonu říci, že má
plynule doregulovávat i víc, než 128 ms (viz zmíněná volba -x) a jednak
dle dohadování v mailing listu ntpd to řeší ntpd třemi způsoby:
a) systém nemá podporu pro přestupnou sekundu a ani potřebnou regulaci
času, pak ntpd v okolí přestupné sekundy trhne sám časem zpět,
b) systém má podporu přestupné sekundy, pak ntpd jen oznámí vložit
nebo vypustit přestupnou sekundu a nechá to na systému,
c) systém má podporu pro potřebnou PLL změnu plynutí času, pak ntp na
danou chvíli změní plynutí tak, aby to dohnal, takže je otázka, kolik
dovolí linux maximálně zrychlit/zpomalit.

A vypadá to, že to, zda dojde na případ b) nebo c) také záleží
distribuce kus od kusu, někdo to má po různě oháčkováno.
Nicméně asi výchozí chování je, že ntp oznámí tu přestupnou sekundu
a kernel si tím trhne zpět sám.

>> 	Je pravda, že pokud se posílá během přestupné sekundy dotazy na
>> ntpd démon jaký má čas, tak po dobu přestupné sekundy mu čas má stát
>> a hlásit pořád stejný [viz 2].
> 
> To bych řekl, že není úplně správná interpretace. Z okolního textu
> vyplývá, že časová řada NTP tvoří epochy ohraničené přestupnými sekundami.
> Čili tam uvedenou tabulku je IMHO třeba chápat tak, že sekunda s číslem
> 3124137560 běží dvakrát: jednou jako koncová přestupná sekunda patřící do 
> epochy s offsetem 31 s vůči TAI, podruhé už jako počáteční sekunda epochy 
> s offsetem 32.

Ano, ta jedna sekunda běží ve skutečnosti 2 sekundy, ale NTP nechá
v první sekundě plynout čas a v druhé stojí těsně před překlopením
do už normální.

>> PS: A to optimisticky přehlížím tu hromadu reportů z poslední přestupné
>> sekundy, kdy kernel do logu hodil "Clock: inserting leap second 23:59:60
>> UTC" a za tím už jen následovalo kernel panic.... :-)
> 
> Uh! To jsem tedy v životě neviděl. Viděl jsem kernel panic, když jádru
> přetekly kolem dokola jiffies, ale že by padlo na ústa kvůli posunu hodin
> zpět, to tedy opravdu ještě nikdy.

Aspoň případy, co jsem četl důkladněji, tak došlo ke zhroucení něčeho
v IP stacku. Čili vlastní systém po ohlášeném panicu jel, akorát 
kompletně odpadla síť.

M.




Další informace o konferenci Linux