adjtimex(2)

NAZWA
adjtimex, clock_adjtime, ntp_adjtime - dopasowuje zegar w jądrze

BIBLIOTEKA
Standardowa biblioteka C (libc, -lc)

SKŁADNIA
#include <sys/timex.h>

int adjtimex(struct timex *buf);

int clock_adjtime(clockid_t clk_id, struct timex *buf);

int adjtimex(struct timex *buf);

OPIS
Linux używa algorytmu dopasowywania Davida L. Millsa (zob. w RFC 1305). Wywołanie systemowe adjtimex czyta i opcjonalnie ustawia parametry sterujące tego algorytmu. Pobiera wskaźnik do struktury timex, aktualizuje parametry w jądrze na podstawie (wybranych) wartości przekazanych w polach i zwraca tę samą strukturę z bieżącymi ustawieniami jądra. Struktura jest zadeklarowana następująco:

    struct timex {
        int  modes;      /* Wybór trybu */
        long offset;     /* Przesunięcie czasu; nanosekundy jeśli
                            ustawiono znacznik statusu STA_NANO, jeśli
                            nie - mikrosekundy */
        long freq;       /* Przesunięcie częstotliwości; zob. UWAGI
                            dotyczące jednostek */
        long maxerror;   /* Maksymalny błąd (mikrosekundy) */
        long esterror;   /* Szacowany błąd (mikrosekundy) */
        int  status;     /* Polecenie/status zegara */
        long constant;   /* Stała czasu PLL (phase-locked loop) */
        long precision;  /* Precyzja zegara
                            (mikrosekundy, tylko do odczytu) */
        long tolerance;  /* Tolerancja częstotliwości zegara (tylko do
                            odczytu); zob. UWAGI dotyczące jednostek */
        struct timeval time;
                         /* Bieżący czas (tylko do odczytu, za wyjątkiem
                            ADJ_SETOFFSET); przy powrocie time.tv_usec
                            zawiera nanosekundy jeśli ustawiono znacznik
                            statusu STA_NANO, jeśli nie - mikrosekundy */
        long tick;       /* Mikrosekundy pomiędzy impulsami zegara */
        long ppsfreq;    /* Częstotliwość PPS (pulse per second) (tylko
                            do odczytu); zob. UWAGI dot. jednostek */
        long jitter;     /* Fluktuacja PPS (tylko do odczytu); nanosek.
                            jeśli ustawiono znacznik statusu STA_NANO,
                            jeśli nie - mikrosekundy */
        int  shift;      /* Czas interwału PPS
                            (sekundy, tylko do odczytu) */
        long stabil;     /* Stabilność PPS (tylko do odczytu);
                            zob. UWAGI dotyczące jednostek */
        long jitcnt;     /* Liczba zdarzeń wykroczenia poza limit
                            fluktuacji PPS (tylko do odczytu) */
        long calcnt;     /* Liczba interwałów kalibracji PPS
                            (tylko do odczytu) */
        long errcnt;     /* Liczba interwałów błędów PPS
                            (tylko do odczytu) */
        long stbcnt;     /* Liczba zdarzeń wykroczenia poza limit
                            stabilności PPS (tylko do odczytu) */
        int tai;         /* Przesunięcie TAI, zgodnie z ustawieniem
                            poprzednią operacją ADJ_TAI (sekundy,
                            tylko do odczytu, od Linuksa 2.6.26) */
        /* Kolejne bajty wyrównania do przyszłych rozszerzeń */
    };

Pole modes określa, które parametry (jeśli w ogóle) ustawić (jak opisano później w niniejszym podręczniku, stałe używane w ntp_adjtime() są równoważne, lecz inaczej nazwane). Jest to maska bitowa zawierająca sumę bitową (OR) kombinacji zera lub więcej spośród następujących bitów:

ADJ_OFFSET
    Ustawia przesunięcie czasu z buf.offset. Od Linuksa 2.6.26, podana wartość jest ograniczana do przedziału (-0.5s, +0.5s). W starszych jądrach występował błąd EINVAL, gdy podało się wartość spoza zakresu.

ADJ_FREQUENCY
    Ustawia przesunięcie częstotliwości z buf.freq. Od Linuksa 2.6.26, podana wartość jest ograniczana do przedziału (-32768000, +32768000). W starszych jądrach występował błąd EINVAL, gdy podało się wartość spoza zakresu.

ADJ_MAXERROR
    Ustawia maksymalny błąd czasu z buf.maxerror.

ADJ_ESTERROR
    Ustawia szacowany błąd czasu z buf.esterror.

ADJ_STATUS
    Ustawia bity statusu zegara z buf.status. Niżej dostępny jest opis tych bitów.

ADJ_TIMECONST
    Ustawia stałą czasu PLL z buf.constant. Jeśli znacznik statusu STA_NANO (zob. niżej) jest wyczyszczony, jądro dodaje do tej wartości 4.

ADJ_SETOFFSET (od Linuksa 2.6.39)
    Dodaje buf.time do bieżącego czasu. Jeśli buf.status obejmuje znacznik ADJ_NANO, to buf.time.tv_usec jest interpretowane jako wartość w nanosekundach, w przeciwnym razie jest interpretowane jako mikrosekundy.

    Wartość buf.time jest sumą jego dwóch pól, lecz pole buf.time.tv_usec musi być zawsze nieujemne. Poniższy przykład ukazuje sposób normalizacji timeval z nanosekundową rozdzielczością.

        while (buf.time.tv_usec < 0) {
            buf.time.tv_sec  -= 1;
            buf.time.tv_usec += 1000000000;
        }

ADJ_MICRO (od Linuksa 2.6.26)
    Wybiera rozdzielczość mikrosekundową.

ADJ_NANO (od Linuksa 2.6.26)
    Wybiera rozdzielczość nanosekundową. Powinno się użyć tylko jednego ze znaczników ADJ_MICRO lub ADJ_NANO.

ADJ_TAI (od Linuksa 2.6.26)
    Ustawia przesunięcie międzynarodowego czasu atomowego — TAI (ang. Atomic International Time) z buf.constant.

    ADJ_TAI nie należy używać łącznie z ADJ_TIMECONST, ponieważ ten ostatni również używa pola buf.constant.

    Pełne wytłumaczenie TAI oraz różnic między TAI i UTC, opisano na stronie BIPM (http://www.bipm.org/en/bipm/tai/tai.html)

ADJ_TICK
    Ustawia wartość impulsu na buf.tick.

Alternatywnie, można podać modes jako jedną z następujących wartości (wielobitowej maski); wówczas w modes nie należy podawać innych bitów:

ADJ_OFFSET_SINGLESHOT
    Staromodne adjtime(3): (stopniowo) dostosowuje czas przy użyciu wartości podanej w buf.offset, określającej dostosowanie w mikrosekundach.

ADJ_OFFSET_SS_READ (działa od Linuksa 2.6.28)
    Zwraca (w buf.offset) czas pozostały do dostosowania po wcześniejszej operacji ADJ_OFFSET_SINGLESHOT. Funkcjonalność tę dodano w Linuksie 2.6.24, lecz nie działała poprawnie do Linuksa 2.6.28.

Zwykli użytkownicy są ograniczeni do wartości 0 lub ADJ_OFFSET_SS_READ dla modes. Jedynie superużytkownik może ustawiać jakiekolwiek parametry.

Pole buf.status jest maską bitową używaną do ustawiania/pobierania bitów statusu powiązanych z implementacją NTP. Niektóre bity w masce można odczytać i ustawić, inne są tylko do odczytu.

STA_PLL (tylko do odczytu)
    Włącza aktualizacje phase-locked loop (PLL) za pomocą ADJ_OFFSET.

STA_PPSFREQ (tylko do odczytu)
    Włącza dostosowanie częstotliwości (ang. frequency discipline) PPS (pulse-per-second) .

STA_PPSTIME (tylko do odczytu)
    Włącza dostosowanie czasu (ang. time discipline) PPS (pulse-per-second) .

STA_FLL (tylko do odczytu)
    Wybiera tryb frequency-locked loop (FLL).

STA_INS (tylko do odczytu)
    Umieszcza sekundę przestępną po ostatniej sekundzie dnia UTC, wydłużając zatem ostatnią minutę dnia o jedną sekundę. Sekunda przestępna będzie występowała każdego dnia, dopóki ten znacznik pozostanie ustawiony.

STA_DEL (tylko do odczytu)
    Odejmuje sekundę przestępną z ostatniej sekundy dnia UTC. Odjęcie sekundy przestępnej będzie występowało każdego dnia, dopóki ten znacznik pozostanie ustawiony.

STA_UNSYNC (tylko do odczytu)
    Zegar nie jest zsynchronizowany.

STA_FREQHOLD (tylko do odczytu)
    Utrzymuje częstotliwość. Zwykle, dostosowania częstotliwości uczynione za pomocą ADJ_OFFSET powodują również stopniowe korekcje częstotliwości. Tak więc jedno wywołanie poprawia bieżące przesunięcie, ale że przesunięcia w tym samym kierunku są czynione wielokrotnie, mniejsze dostosowania częstotliwości skumulują się poprawiając odchylenie występujące w dłuższym okresie.

    Ten znacznik zapobiega wykonywaniu mniejszych dostosowań częstotliwości, przy poprawianiu wartości ADJ_OFFSET.

STA_PPSSIGNAL (tylko do odczytu)
    Dostępny jest prawidłowy sygnał PPS (pulse-per-second).

STA_PPSJITTER (tylko do odczytu)
    Przekroczono fluktuację sygnału PSS.

STA_PPSWANDER (tylko do odczytu)
    Przekroczono dryft sygnału PSS.

STA_PPSERROR (tylko do odczytu)
    Błąd kalibracji sygnału PPS.

STA_CLOCKERR (tylko do odczytu)
    Usterka zegara sprzętowego.

STA_NANO (tylko do odczytu; od Linuksa 2.6.26)
    Rozdzielczość (0 = mikrosekundowa, 1 = nanosekundowa). Ustawiana poprzez ADJ_NANO, czyszczona poprzez ADJ_MICRO.

STA_MODE (od Linuksa 2.6.26)
    Tryb (0 = Phase Locked Loop, 1 = Frequency Locked Loop).

STA_CLK (tylko do odczytu; od Linuksa 2.6.26)
    Źródło zegara (0 = A, 1 = B); aktualnie nieużywane.

Próby ustawienia bitów statusu tylko do odczytu są po cichu ignorowane.

  clock_adjtime ()
Wywołanie systemowe clock_adjtime() (dodane w Linuksie 2.6.39) zachowuje się jak adjtimex(), lecz przyjmuje dodatkowy argument clk_id określający konkretny zegar, na którym ma działać.

  ntp_adjtime ()
Funkcja biblioteczna ntp_adjtime() (opisana w „Kernel Application Program API” — KAPI NTP) jest bardziej przenośnym interfejsem, wykonującym takie samo zadanie jak adjtimex(). Oprócz poniższych punktów, jest identyczne do adjtimex():

•   Stałe używane w modes mają przedrostki „MOD_” zamiast „ADJ_” i takie same przyrostki (co daje MOD_OFFSET, MOD_FREQUENCY, itd.), poza wyjątkami opisanymi poniżej.

•   MOD_CLKA jest synonimem ADJ_OFFSET_SINGLESHOT.

•   MOD_CLKB jest synonimem ADJ_TICK.

•   Brak jest synonimu dla ADJ_OFFSET_SS_READ, czego nie opisano w KAPI.

WARTOŚĆ ZWRACANA
W przypadku powodzenia, adjtimex() i ntp_adjtime() zwracają stan zegara; tj. jedną z poniższych wartości:

TIME_OK
    Zegar zsynchronizowany, brak oczekującego dostosowania sekundy przestępnej.

TIME_INS
    Wskazuje, że sekunda przestępna zostanie dodana pod koniec dnia UTC.

TIME_DEL
    Wskazuje, że sekunda przestępna zostanie odjęta pod koniec dnia UTC.

TIME_OOP
    Trwa umieszczenie sekundy przestępnej.

TIME_WAIT
    Zakończono umieszczenie lub odjęcie sekundy przestępnej. Ta wartość będzie zwracana do momentu wyczyszczenia znaczników STA_INS i STA_DEL, przez następną operację ADJ_STATUS.

TIME_ERROR
    Zegar systemowy nie został zsynchronizowany z wiarygodnym serwerem. Wartość jest zwracana, w przypadku spełnienia dowolnego z poniższych warunków:

    •   Ustawiono STA_UNSYNC albo STA_CLOCKERR.

    •   STA_PPSSIGNAL jest wyczyszczony i ustawiono STA_PPSFREQ albo STA_PPSTIME.

    •   Ustawiono STA_PPSTIME oraz STA_PPSJITTER.

    •   Ustawiono STA_PPSFREQ i ustawiono STA_PPSWANDER albo STA_PPSJITTER.

    Nazwa symboliczna TIME_BAD jest synonimem TIME_ERROR, w celu zachowania wstecznej kompatybilności.

Proszę zauważyć, że poczynając od Linuksa 3.4, wywołanie działa asynchronicznie i zwracana wartość zwykle nie oddaje zmiany stanu spowodowanej przez samo wywołanie.

W przypadku błędu, wywołania zwracają -1 i ustawiają errno wskazując błąd.

BŁĘDY

EFAULT
    buf nie wskazuje do zapisywalnej pamięci.

EINVAL (przed Linuksem 2.6.26)
    Próbowano ustawić wartość buf.freq spoza przedziału (-33554432, +33554432).

EINVAL (przed Linuksem 2.6.26)
    Próbowano ustawić wartość buf.offset spoza dozwolonego przedziału. Przed Linuksem 2.0, dozwolony przedział wynosił (-131072, +131072). Od Linuksa 2.0, dozwolony przedział wynosił (-512000, +512000).

EINVAL
    Próbowano ustawić buf.status na wartość inną niż opisaną powyżej.

EINVAL
    clk_id przekazane do clock_adjtime() jest nieprawidłowe z jednego z dwóch powodów: albo dodatnia wartość identyfikatora zegara zakodowana na stałe w stylu Systemu V jest poza zakresem, albo dynamiczne clk_id nie odnosi się do prawidłowego wystąpienia obiektu zegara. Opis dynamicznych zegarów znajduje się w podręczniku clock_gettime(2).

EINVAL
    Próbowano ustawić buf.tick na wartość spoza zakresu 900000/HZ do 1100000/HZ, gdzie HZ jest częstotliwością przerwania systemowego czasomierza.

ENODEV
    Urządzenie umożliwiające podłączenie „na gorąco” (np. USB) reprezentowane przez dynamiczny clk_id zniknęło po otwarciu jego urządzenia znakowego. Zob. podręcznik clock_gettime(2) aby dowiedzieć się więcej o zegarach dynamicznych.

EOPNOTSUPP
    Podany clk_id nie obsługuje dostosowywania.

EPERM
    buf.modes nie wynosi ani 0, ani ADJ_OFFSET_SS_READ i wywołujący nie jest wystarczająco uprzywilejowany. W Linuksie wymagany jest przywilej (ang. capability) CAP_SYS_TIME.

ATRYBUTY
Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).
Interfejs | Atrybut | Wartość
ntp_adjtime() | Bezpieczeństwo wątkowe | MT-bezpieczne

STANDARDY

adjtimex()
clock_adjtime()
    Linux.

Preferowanym API do demona NTP jest ntp_adjtime().

UWAGI
W strukturach timex, freq, ppsfreq i stabil występują ppm (części na milion) z 16-bitową częścią ułamkową, co oznacza, że wartość w tych polach wynosi tak naprawdę 2^-16 ppm, a 2^16=65536 jest równe 1 ppm. Jest to prawdziwe zarówno w przypadku wartości wejściowych (stosowane do freq) i wyjściowych.

Przetwarzanie sekundy przestępnej, wyzwolone przez STA_INS i STA_DEL jest dokonywane przez jądro w kontekście czasomierza. Z tego względu, zajmie to jeden impuls w sekundzie, zanim sekunda przestępna zostanie dodana lub usunięta.

ZOBACZ TAKŻE
clock_gettime(2), clock_settime(2), settimeofday(2), adjtime(3), ntp_gettime(3), capabilities(7), time(7), adjtimex(8), hwclock(8)

NTP „Kernel Application Program Interface” (http://www.slac.stanford.edu/comp/unix/package/rtems/src/ssrlApps/ntpNanoclock/api.htm)

TŁUMACZENIE
Tłumaczenie niniejszej strony podręcznika: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 (https://www.gnu.org/licenses/gpl-3.0.html) lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.