Je to za námi, mezi posledním červnem a prvním červencem se světový čas zase jednou zastavil, tentokrát už po dvacáté šesté. Zdá se, že tentokrát se to obešlo bez katastrofálních následků, na rozdíl od posledního podobného vkládání přestupné sekundy v roce 2012. Drobné problémy se však přesto objevily. Společnost Dyn Research na Twitteru například dokumentuje skokový nárůst zpráv směrovacího protokolu BGP kolem půlnoci UTC. Některé routery tedy zřejmě přestupnou sekundu bez úhony nepřežily.
Time.is na jedničku
Ačkoli jsem měl původně v plánu druhou hodinu ranní věnovat obvyklému spánku, nakonec jsem si přeci jen nastavil budík a podíval se na vlastní oči. Takhle vypadala plocha mého počítače, kde jsem postupně otevřel stránky time.is, cas.nebezi.cz a time.gov, který měl tou dobou evidentní výkonnostní problémy – stránka se načítala asi 10 sekund.
Time.is samozřejmě nezklamal, jeho autor Even Scharning si na podobných vychytávkách zakládá. Time.gov se choval vcelku zvláštně, ale asi to souviselo s přetížením serveru. U mých vlastních hodin, které jsou součástí projektu Neběží.cz, jsem nepředpokládal, že 60. sekundu budou umět zobrazit – vždyť jsou napsané v JavaScriptu a pracují pouze s unixovým časem – překvapilo mě ale, že se nezastavily na 59., ale až na nulté sekundě nové hodiny. Vypadá to, jako by si stihly nového času všimnout ještě předtím, než jádro vrátilo čas zpátky na 59. sekundu předchozí minuty.
Fyzické hodiny bez šedesátky
Kromě sledování softwarových hodin jsem připravil i kameru pro záznam hodin, které pohání router Turris (tyto hodiny jsem představoval na konferenci IT14.2). Předpokládal jsem, že tady zasáhne algoritmus kompenzace předběhnutí hodin a ručičky se jednoduše na sekundu zastaví. Nestalo se ale tak.
Kromě ručičkových hodin jsou v záběru vidět také komerční hodiny řízené rádiovým signálem DCF77 a ručně vyráběný přijímač téhož časového signálu. Komerční hodiny, jak jsem předpokládal, přestupnou sekundu ignorovaly a rozdíl kompenzovaly až někdy v průběhu noci. Drtivá většina rádiem řízených hodin se totiž z důvodu šetření baterie synchronizuje jen několikrát denně a ve zbylém čase běží autonomně. Proto nejsou takové hodiny schopné ani hladkého přechodu na letní čas nebo zpět.
Překvapilo mě ale, že stejným způsobem se chovaly i hodiny řízené Turrisem. Problém bude asi způsoben NTP démonem v Turrisu, který pochází z projektu BusyBox. Moje vysvětlení, které nemám nijak podložené, spočívá v tom, že odlehčený NTP server z BusyBoxu zřejmě informace o přestupné sekundě ignoruje. Když pak někdy po vložení přestupné sekundy kontaktuje časové servery, detekuje odchylku místních hodin a hodiny přestaví. K seřízení hodin tedy zřejmě došlo někdy uprostřed noci, když už jsem měl záznam kamery vypnutý (taky kdo by se na tak dlouhý záznam chtěl dívat, že).
Systémové hodiny pod drobnohledem
Problém přestupné sekundy je především v tom, že pro unixový čas není definovaná a danému okamžiku tak nelze přiřadit žádnou časovou značku. U systému, který používá NTP, je jádru správným nastavením funkce adjtimex(2) nastaven příznak, upozorňující na nutnost vložení přestupné sekundy. Jádro si takového příznaku všimne a těsně po překlopení do půlnoci vrátí hodiny o sekundu zpět a zaloguje:
Jul 1 02:01:07 oskarpc kernel: Clock: inserting leap second 23:59:60 UTC
Zkusil jsem sledovat stav systémových hodin, včetně řídicích proměnných, které vypisuje utilita adjtimex
, pomocí jednoduché smyčky, spuštěné v inkriminovanou dobu:
$ while true; do /usr/sbin/adjtimex -p; LANG=C date; echo "===="; sleep 1; done mode: 0 offset: -1694770 frequency: 153174 maxerror: 8779 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708797s 741418171us = 1435708797.741418171 return value = 1 Wed Jul 1 01:59:57 CEST 2015 ==== mode: 0 offset: -1688150 frequency: 153174 maxerror: 9279 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708798s 744044144us = 1435708798.744044144 return value = 1 Wed Jul 1 01:59:58 CEST 2015 ==== mode: 0 offset: -1681556 frequency: 153174 maxerror: 9779 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708799s 745997271us = 1435708799.745997271 return value = 1 Wed Jul 1 01:59:59 CEST 2015 ==== mode: 0 offset: -1674987 frequency: 153174 maxerror: 10279 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708799s 748679340us = 1435708799.748679340 return value = 3 Wed Jul 1 01:59:59 CEST 2015 ==== mode: 0 offset: -1668444 frequency: 153174 maxerror: 10779 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708800s 754907380us = 1435708800.754907380 return value = 4 Wed Jul 1 02:00:00 CEST 2015 ==== mode: 0 offset: -1661927 frequency: 153174 maxerror: 11279 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708801s 757271381us = 1435708801.757271381 return value = 4 Wed Jul 1 02:00:01 CEST 2015 ==== mode: 0 offset: -1655435 frequency: 153174 maxerror: 11779 esterror: 1466 status: 8209 time_constant: 6 precision: 1 tolerance: 32768000 tick: 10000 raw time: 1435708802s 758942030us = 1435708802.758942030 return value = 4 Wed Jul 1 02:00:02 CEST 2015 ====
Zajímavé je zejména sledování řádku return value
, který se obvykle ve výpisu adjtimex -p
vůbec nevyskytuje, protože je návratová hodnota nulová. Jeho hodnotu rozklíčujeme nahlédnutím do manuálové stránky, resp. hlavičkového souboru:
On success, adjtimex() returns the clock state: #define TIME_OK 0 /* clock synchronized */ #define TIME_INS 1 /* insert leap second */ #define TIME_DEL 2 /* delete leap second */ #define TIME_OOP 3 /* leap second in progress */ #define TIME_WAIT 4 /* leap second has occurred */ #define TIME_BAD 5 /* clock not synchronized */
Vidíme tedy, že hodiny došly až do času 1435708799 s příznakem vkládání přestupné sekundy, po přechodu na další sekundu jádro vrátilo hodiny zpět na 1435708799 a změnilo příznak na „právě probíhá přestupná sekunda“. Po jejím uplynutí funkce ještě nějakou dobu vracela příznak, že k přestupné sekundě došlo. Až budu příště programovat hodiny, už vím, kde získat správný zdroj informace o přestupné sekundě.
Tenhle způsob řešení přestupné sekundy ale není jediný možný. Vývojáři Red Hatu před měsícem publikovali velmi podrobný blogpost, představující hned pět alternativ řešení problému s přestupnou sekundou. Tak například přidáním přepínače -x
pro ntpd
vyřadíte z činnosti kompenzaci přestupné sekundy v jádře a místo toho hodiny přejdou na nový čas pozvolným rozlaďováním rychlosti hodin. Při tomhle řešení však bude trvat dva dny, než se hodiny vrátí ke své obvyklé přesnosti.
Alternativní hodinový démon chronyd
, který je Red Hatem preferován, umožňuje hodiny po přestupné sekundě srovnat pozvolným zpomalením už během dvanácti sekund. Také je možné si pomocí chronyd
vyrobit, podobně jako Google, vlastní časový server, který přestupnou sekundu před svými klienty zatají a rozmaže ji do celého dne.
Přestupná sekunda ve vysílání Českého rozhlasu
Na samý závěr mě ještě napadlo podívat se do archivu, jak se s přestupnou sekundou vyrovnalo vysílání časového znamení Českého rozhlasu. Zdá se ale, že nijak zvlášť. Zde je záznam vysílání od 01:59:50 stanice Český rozhlas Dvojka:
Až později jsem si uvědomil, že jsem se měl také podívat na webové kamery, zda se přestupná sekunda korektně zobrazila alespoň na studiových hodinách Wharton, které byly předlohou pro čas.Neběží.cz. Musím si to zapsat na seznam, co mám zkontrolovat příště.
Chce to testovací platformu
Přestupná sekunda patří mezi několik málo věcí, které se dají jen velmi těžko otestovat. Přitom, jak se ukázalo před třemi lety, nemusí jít v počítačích vůbec o banalitu. Našel jsem pouze nabídku testování prostřednictvím GPS generátoru, což je jistě dobré řešení pro operátory primárních časových serverů, ale pro běžného programátora vcelku složitě dostupné.
Představoval bych si něco jako Keyroller, veřejný alternativní DNS kořen, který mění kořenový klíč každých 90 minut. Kdokoli si tak na něm může otestovat chování svého DNSSEC validátoru při výměně kořenového klíče.
Na stejném principu by mohl fungovat veřejný NTP server, který by vkládal přestupnou sekundu třeba každý den. Divím se, že jsem takovou službu ještě nenašel. Zvedne někdo hozenou rukavici?