3.3.4 NTP - Network Time Protocol

 

Spis treści


Wstęp

W rozdziale czas opisałem rzeczy, które działają w oparciu o przerwania zegarowe, które są jedynym wiarygodnym wewnętrznym źródłem informującym komputer o upływającym czasie. Wiemy jednak, że komputerowe zegary bywają zawodne - spóźniają się lub spieszą, wyczerpuje się lub psuje akumulatorek, itp. Trzeba też pamiętać o takich szczegółach jak zmiana czasu z zimowego na letni i odwrotnie (wprawdzie tylko dwa razy w roku, ale jednak kłopot). Jedynym więc ratunkiem dla czasu komputerowego wydaje się być jego okresowy nadzór przez operatora systemu.

Nie jest aż tak źle - dla komputerów wolnostojących (nie podłączonych do sieci) wypada tylko zaufać dokładności wbudowanego zegara, ale gdy mamy podłączenie do internetu, jest znacznie lepiej. Problem ten badał już od dłuższego czasu, a radę na problemy z zegarem dał w 1994 roku prof. David L. Mills z Uniwersytetu w Delaware (USA). Opracował on mianowicie protokół rozgłaszania bardzo dokładnego czasu przez sieć - stąd nazwa NTP. David Mills jest także autorem jednego z plików Linuxa: include/linux/timex.h. Linuxa do współpracy z NTP przystosował Ulrich Windl.

W NTP rozróżniamy cztery warstwy (ang. stratum, l.mn. strata). Komputery warstwy 1 to te, do których jest bezpośrednio podłączony zegar atomowy, bądź odbiornik zegarowego sygnału radiowego lub satelitarnego (obecnie na świecie jest ok. 50 publicznych takich serwerów). Warstwa 2 (ok. 100 publicznych serwerów na świecie; liczba prywatnych nie jest znana) składa się z komputerów połączonych z tymi z 1. warstwy, itd., przy czym 3. warstwa jest przeznaczona raczej dla serwerów wydziałowych, które (po jednym na wydziale) rozgłaszają dokładny czas innym komputerom z tego samego wydziału (nie jest to zbyt absorbujące), zaś na 4. warstwie (samodzielne komputery) NTP się kończy. Zauważmy, że nawet przy małej ilości komputerów 1. warstwy takie rozwarstwienie nie obciąża łącz internetu. Wewnątrz sieci lokalnych dokładność ustawienia czasu względem lokalnego serwera jest rzędu milisekund.

Warto zauważyć, że komputery pracują w różnych strefach czasowych. Wobec tego obowiązującym czasem rozgłaszanym przez serwery jest skoordynowany czas uniwersalny (UTC - Universal Coordinated Time) i w zasadzie jako taki powinien być ustawiany na komputerach z Linuxem, które już sobie same uwzględnią swoje położenie w strefie czasowej (timezone) - ustawia się ją podczas instalacji Linuxa, można to też zrobić później.

Komputer, którego zegar wewnętrzny nie jest zbyt popsuty, prawidłowo korzystając z NTP powinien chodzić z dokładnością +/-2 ms w zależności od temperatury pomieszczenia, w którym pracuje.

Oto adresy niektórych publicznych serwerów 1. warstwy NTP: clock.isc.org (Kalifornia), ntp0.ja.net (Uniwersytet w Cambridge - W. Brytania), poza tym co najmniej jeden publiczny serwer 2. warstwy NTP znajduje się w Polsce: info.cyf-kr.edu.pl.

Możliwe jest też korzystanie z NTP do regulacji czasu w wewnętrznej sieci bez korzystania z internetu, nawet bez dostępu do zegara atomowego, czy sygnału satelitarnego lub radiowego. Ważne jest wówczas odpowiednie rozmieszczenie serwerów kolejnych warstw - tak, aby nie przeciążać łącz.


Algorytmy

Obecne wersje NTP są już zaimplementowane w jądrze Linuxa od jakiegoś czasu. Opierają się one na opracowaniu A Kernel Model for Precision Timekeeping autorstwa Davida L. Millsa (najnowsza wersja, która znalazłem, pochodzi ze stycznia 1996).

Model NTP został pierwotnie zaimplementowany na systemach, które wywołują przerwanie zegarowe co pewną wielokrotność mikrosekundy, np. Linux - 100 Hz. Później jednakże opracowano specjalne wersje dla Ultrixa (256 Hz) i OSF/1 (1024 Hz).

Ogólnie rzecz biorąc, na komputerze, na którym działa demon NTP (np. xntpd) manipuluje czasem systemowym w ten sposób, żeby przede wszystkim czas był zawsze monotoniczny, oraz jego wahania nie przekraczały dopuszczalnych w systemie, które zresztą czasem się zdarzają bez większej szkody - rzędu kilku procent. Takie manipulacje umożliwa komenda adjtimex - posługując się nią można np. zmienić szybkość zegara systemowego o +/-10%. Wytyczne demon pobiera poprzez port szeregowy (RS232) z odpowiedniego źródła (najczęściej innego komputera), które wysyła co sekundę sygnał PPS (pulse per second).

Przy uruchomieniu demona NTP sprawdzamy zgodność czasów. Jeśli różnią się o więcej niż 1024 s, to trzeba po prostu ustawić czas przez settimeofday(). Jest to możliwe, gdyż sygnały PPS przesyłane są do portu szeregowego w postaci ASCII zawierającej dokładną bieżącą godzinę.

Następnie porównując czasy, jakie upływają między sekundą "komputerową", a sekundą "atomową" przysyłaną z zewnątrz, możemy ustalić, o jaki współczynnik należy przeregulować szybkość zegara systemowego. No więc robimy to przez adjtimex()

Gdy odchylenie zegara systemowego zostanie ustabiliowane w granicach +/-128ms, pozostaje tylko co jakiś czas wołać procedurę ntp_adjtime(), która dokona w razie potrzeby niewielkich korekt. Będzie się to odbywało nie częściej niż co 16 s (chyba, że coś nagle zacznie się psuć), ale nie rzadziej niż co 1024 s. Ta procedura regulacji czasu nalepiej działa jednak dla odstępu między wywołaniami wynoszącego 64 s.

Błąd niezgodności może się teoretycznie wahać w granicach +/-512 ms, ale w praktyce na tym etapie odchylenia większe niż +/-128ms zdarzają się rzadko.

W niektórych systemach występuje jednak trudny do usunięcia problem - przerwanie portu szeregowego musi mieć tam wyższy priorytet, niż przerwanie zegarowe. Wówczas sygnał synchronizacji przyjdzie o jedno tyknięcie spóźniony.

Do komputera można sobie też podłączyć własny dokładny zegar, np. HIGHBALL.
 

Opis zmiennych odnoszących się do NTP

Zmienne te występują w second_overflow() i update_wall_time_one_tick(), zadeklarowane są w kernel/sched.c.

int time_state = TIME_ERROR;
 
TIME_OK wszystko w porządku, zegary zsynchronizowane w granicach 128 ms
TIME_INS planowane wstawienie dodatkowej sekundy 23:59:60
TIME_DEL planowane skasowanie ostatniej sekundy dnia - po 23:59:58 nastąpi od razu północ
TIME_OOP trwa wstawianie dodatkowej sekundy
TIME_WAIT przed chwilą skończona operacja związana z dodatkową/nadmiarową sekundą
TIME_ERROR (== TIME_BAD) brak sygnału PPS lub zegary niedostatecznie zsynchronizowane

Na komputerze nie poprawiającym swojego zegara przez NTP wartość ta zawsze będzie TIME_ERROR.
Na powyższą zmienną (poza TIME_ERROR i TIME_OK inne wartości może jej nadać tylko funkcja second_overflow()) ma wpływ kolejna, ustawiana już za pomocą adjtimex() przez procedury NTP:

int time_status = STA_UNSYNC;

Zmienna ta zawiera różne flagi (bity), które wymienię od najmłodszego bitu do coraz starszych
 
STA_PLL (==1) działa aktualizacja PLL
STA_PPSFREQ częstotliwość dobrze uregulowana (+/- 0,01%)
STA_PPSTIME czas dobrze uregulowany (+/- 512 ms)
STA_FLL wybierz tryb FLL
STA_INS zażądaj wstawienia dodatkowej sekundy
STA_DEL zażądaj usunięcia nadmiarowej sekundy
STA_UNSYNC brak synchronizacji
STA_FREQHOLD
STA_PPSSIGNAL obecny sygnał PPS
STA_PPSJITTER (? - signal jitter exceeded)
STA_PPSWANDER (? - signal wander exceeded)
STA_PPSERROR błąd kalibracji sygnału (signal calibration error)
STA_CLOCKERR błąd sprzętowy zegara (clock hardware fault)

int time_constant = 2;

określa maksymalny odstęp pomiędzy kolejnymi regulacjami - wartość 2, optymalna dla zwykłych komputerów oznacza 64 s, zaś maksymalna wartość 6 oznacza 1024 s.
 
 


Oprogramowanie

Do korzystania z NTP przeznaczone specjalne programy freeware nie wymagające rekompilacji jądra (nawet dla 1. warstwy!): Stąd można ściągnąć wersję oprogramowania NTP (wersja 5.92 ze stycznia 1998): kliknij.


Wyjaśnienie ważniejszych pojęć (FAQ)

Co to jest dodatkowa/nadmiarowa sekunda (leap second)?

Przyczyna istnienia dodatkowej sekundy jest dość głęboka. Zacznijmy od tego, czym jest sekunda - będzie trochę astronomii. Do roku 1960 sekunda była zdefiniowana jako "1/86400 śedniego Dnia Słonecznego" (nie chodzi tu o dobrą pogodę ;-), tylko o odstęp czasu między kolejnymi górowaniami Słońca - południami, gdy Słońce znajduje się w najwyższym punkcie firnamentu danego dnia). W 1960 wprowadzono nową definicję - sekundę efemryczną - jako pewien ułamek roku gwiezdnego 1900.

Jest to dość kłopotliwe w codziennym użytku, więc używa się też określenia sekundy atomowej jako okresu w którym następuje pewna ilość (ok. 9162770000) drgań radioaktywnego atomu cezu - jest to zadowalająco zgodne z sekundą efemryczną.

Należy jednak wziąć pod uwagę, że Ziemia obraca ze zmienną prędkością (na dłuższą metę coraz wolniej) - zmiany są praktycznie niezauważalne, ale jednak są. Wobec tego wprowadzono pojęcie dodatkowej/nadmiarowej sekundy - o północy czasu uniwersalnego 30 czerwca lub 31 grudnia zegar światowy (naprawdę postanawiają o tym astronomowie) może wysłać sygnał powiadamiający o potrzebie dodania/odjęcia nowej sekundy. Jeśli nasz system korzysta z NTP, musi to uwzględnić i stąd się biorą pewne dziwne czynności wykonywane przez second_overflow().


Bibliografia