| ADJTIMEX(2) | Руководство программиста Linux | ADJTIMEX(2) | 
adjtimex, ntp_adjtime - тонкая настройка часов в ядре
#include <sys/timex.h>
int adjtimex(struct timex *buf);
int ntp_adjtime(struct timex *buf);
В Linux для подстройки часов используется алгоритм Дэвида Л. Миллса (David L. Mills) (смотрите RFC 5905). Системный вызов adjtimex() читает и (необязательно) устанавливает параметры подстройки для этого алгоритма. Он берёт указатель на структуру timex, изменяет параметры ядра согласно значениям (некоторых) её полей и возвращает эту уже обновлённую структуру с текущими значениями параметров ядра. Данная структура объявлена так:
struct timex {
    int  modes;      /* выбор режима */
    long offset;     /* смещение по времени; в наносекундах, если
                        установлен флаг состояния STA_NANO, иначе
                        в микросекундах */
    long freq;       /* смещение частоты; единицы измерения */
                        описаны в ЗАМЕЧАНИЯХ */    long maxerror;   /* максимальная ошибка (микросекунды) */
    long esterror;   /* ожидаемая ошибка (микросекунды) */
    int  status;     /* команда/состояние для часов */
    long constant;   /* константа времени PLL (phase-locked loop) */
    long precision;  /* точность часов
                        (микросекунды, только чтение) */
    long tolerance;  /* допуск тактовой частоты (только чтение);
                        единицы измерения описаны в ЗАМЕЧАНИЯХ */
    struct timeval time;
                     /* текущее время (только чтение, кроме
                        ADJ_SETOFFSET); при возврате в time.tv_usec
                        содержатся наносекунды, если установлен флаг
                        STA_NANO, иначе микросекунды */
    long tick;       /* микросекунд между тиками часов */
    long ppsfreq;    /* частота PPS (импульсов в секунду)
                        (только чтение); единицы измерения описаны в
                        ЗАМЕЧАНИЯХ */
    long jitter;     /* искажение PPS (только чтение); в наносекундах,
                        если установлен флаг состояния STA_NANO,
                        иначе в микросекундах
    int  shift;      /* длительность интервала PPS
                        (секунды, только чтение) */
    long stabil;     /* устойчивость PPS (только чтение);
                        единицы измерения описаны в ЗАМЕЧАНИЯХ */
    long jitcnt;     /* счётчик превышений ограничения искажения
                        PPS (только чтение) */
    long calcnt;     /* счётчик интервалов калибровки PPS
                        (только чтение) */
    long errcnt;     /* счётчик ошибок калибровки PPS
                        (только чтение) */
    long stbcnt;     /* счётчик событий превышения ограничения
                        устойчивости PPS (только чтение) */
    int tai;         /* смещение TAI offset, установленное предыдущей
                        операцией ADJ_TAI (секунды, только чтение,
                        начиная с Linux 2.6.26) */
    /* далее идут байты заполнения, для расширения структуры в будущем */
};
Полем modes определяется какие параметры, если это необходимо, устанавливаются (как описывалось выше, константы, используемые в ntp_adjtime(), те же самые, но названные по-другому). Является битовой маской, содержащей побитовую (или) комбинацию нуля или более следующих бит:
Также в modes можно указывать любое из следующих значений (многобитовая маска), биты которых нельзя указать в modes:
Обычные пользователи могут задавать в modes значение ноль или ADJ_OFFSET_SS_READ. Только суперпользователь может задавать любые параметры.
Поле buf.status представляет собой битовую маску, используется для установки/получения битов состояния, связанных с реализацией NTP. Одни биты в маске можно и читать, и изменять, другие — только читать.
Попытки установить биты status, помеченные только для чтения, просто игнорируются.
Библиотечная функция ntp_adjtime() (описана в NTP "Kernel Application Program API", KAPI) является более переносимым интерфейсом для выполнения той же задачи, что и adjtimex(). Она идентична adjtime() кроме следующего:
При успешном выполнении adjtimex() и ntp_adjtime() возвращают состояние часов, а именно одно из следующих значений:
Заметим, что начиная с Linux 3.4 вызов выполняется асинхронно и возвращаемое значение, обычно, не отражает состояние, изменённое самим вызовом.
При ошибке эти вызовы возвращают -1 и изменяют errno.
Описание терминов данного раздела смотрите в attributes(7).
| Интерфейс | Атрибут | Значение | 
| ntp_adjtime() | Безвредность в нитях | MT-Safe | 
Эти интерфейсы не описаны в POSIX.1
Вызов adjtimex() есть только в Linux и не должен использоваться в переносимых программах.
Предпочтительным программным интерфейсом для службы NTP является ntp_adjtime().
В структуре timex, freq, ppsfreq и stabil ppm (частей на миллион) имеет 16-битную дробную часть, что означает, что значение 1 в одном из этих полей в действительности равно 2^-16 ppm, и 2^16=65536 равно 1 ppm. Это действительно как для входных (в случае freq) так и для выходных значений.
Обработка високосной секунды, возникающая при установке STA_INS и STA_DEL, выполняется ядром в контексте таймера. Следовательно, для установки или удаления високосной секунды потребуется один тик для перехода.
settimeofday(2), adjtime(3), ntp_gettime(3), capabilities(7), time(7), adjtimex(8), hwclock(8)
| 2019-03-06 | Linux |