- bullseye-backports 4.18.1-1~bpo11+1
- testing 4.18.1-1
- unstable 4.18.1-1
ADJTIMEX(2) | Руководство программиста Linux | ADJTIMEX(2) |
ИМЯ¶
adjtimex, clock_adjtime, ntp_adjtime - тонкая настройка часов в ядре
СИНТАКСИС¶
#include <sys/timex.h>
int adjtimex(struct timex *buf);
int clock_adjtime(clockid_t clk_id, 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(), те же самые, но названные по-другому). Является битовой маской, содержащей побитовую (или) комбинацию нуля или более следующих бит:
- ADJ_OFFSET
- Установить смещение по времени из buf.offset. Начиная с Linux 2.6.26, переданное значение ограничивается диапазоном (-0.5s, +0.5s). В старых ядрах, если значение выходит из диапазона, то возвращается ошибка EINVAL.
- ADJ_FREQUENCY
- Установить смещение по частоте из buf.offset. Начиная с Linux 2.6.26, переданное значение ограничивается диапазоном (-32768000, +32768000) В старых ядрах, если значение выходит из диапазона, то возвращается ошибка EINVAL.
- ADJ_MAXERROR
- Установить максимальную ошибку времени из buf.maxerror.
- ADJ_ESTERROR
- Установить ожидаемую ошибку времени из buf.esterror.
- ADJ_STATUS
- Установить биты состояния часов из buf.status. Описание бит представлено ниже.
- ADJ_TIMECONST
- Установить константу времени PLL из buf.constant. Если не задан флаг состояния STA_NANO (смотрите ниже), то ядро добавляет к этому значению 4.
- ADJ_SETOFFSET (начиная с Linux 2.6.39)
- Добавить buf.time к текущему времени. Если в buf.status указан флаг ADJ_NANO, то значение buf.time.tv_usec считается заданным в наносекундах; в противном случае это микросекунды.
- The value of buf.time is the sum of its two fields, but the field buf.time.tv_usec must always be nonnegative. The following example shows how to normalize a timeval with nanosecond resolution.
-
while (buf.time.tv_usec < 0) {
buf.time.tv_sec -= 1;
buf.time.tv_usec += 1000000000; }
- ADJ_MICRO (начиная с Linux 2.6.26)
- Выбрать микросекундной разрешение.
- ADJ_NANO (начиная с Linux 2.6.26)
- Выбрать наносекундной разрешение. Должно быть указано что-то одно: ADJ_MICRO или ADJ_NANO.
- ADJ_TAI (начиная с Linux 2.6.26)
- Установить смещение TAI (атомное международное время) из buf.constant.
- ADJ_TAI не должно использоваться вместе с ADJ_TIMECONST, так как последний режим также использует поле buf.constant.
- Подробное описание TAI и различия между TAI и UTC смотрите в BIPM
- ADJ_TICK
- Установить значение тика из buf.tick.
Также в modes можно указывать любое из следующих значений (многобитовая маска), биты которых нельзя указать в modes:
- ADJ_OFFSET_SINGLESHOT
- Старый вариант adjtime(3): (постепенно) корректировать время значением, указанным в buf.offset, которое задаётся в микросекундах.
- ADJ_OFFSET_SS_READ (работает, начиная с Linux 2.6.28)
- Получить (в buf.offset) остаток необходимого откорректированного времени после выполнения операции ADJ_OFFSET_SINGLESHOT. Это возможность была добавлена в Linux 2.6.24, но работала неправильно до Linux 2.6.28.
Обычные пользователи могут задавать в modes значение ноль или ADJ_OFFSET_SS_READ. Только суперпользователь может задавать любые параметры.
Поле buf.status представляет собой битовую маску, используется для установки/получения битов состояния, связанных с реализацией NTP. Одни биты в маске можно и читать, и изменять, другие — только читать.
- STA_PLL (чтение-запись)
- Включить обновление фазовой подстройки частоты (PLL) через ADJ_OFFSET.
- STA_PPSFREQ (чтение-запись)
- Включить частотную дисциплину обслуживания PPS (импульсов в секунду).
- STA_PPSTIME (чтение-запись)
- Включить временную дисциплину обслуживания PPS.
- STA_FLL (чтение-запись)
- Выбрать режим частотной подстройки частоты (FLL).
- STA_INS (чтение-запись)
- Вставить високосную секунду за последней секундой дня UTC, то есть удлинить последнюю минуту дня на одну секунду. Вставка високосной секунды будет происходить каждый день пока установлен этот флаг.
- STA_DEL (чтение-запись)
- Удалить високосную секунду из последней секунды дня UTC. Удаление високосной секунды будет происходить каждый день пока установлен этот флаг.
- STA_UNSYNC (чтение-запись)
- Часы не синхронизированы.
- STA_FREQHOLD (чтение-запись)
- Зафиксировать частоту. Обычно корректировки, внесённые через результат ADJ_OFFSET, приводят к ослаблению также проводимых настроек по частоте. Таким образом, единичный вызов исправляет текущее смещение, но поскольку смещения в том же направлении делаются неоднократно, маленькие изменения по частоте будут накапливаться, чтобы исправить длинный сдвиг.
- Данный флаг отключает маленькие исправления по частоте при корректировке значения ADJ_OFFSET.
- STA_PPSSIGNAL (только чтение)
- Присутствует сигнал PPS (импульсов в секунду).
- STA_PPSJITTER (только чтение)
- Превышено искажение сигнала PPS.
- STA_PPSWANDER (только чтение)
- Превышено отклонение сигнала PPS.
- STA_PPSERROR (только чтение)
- Ошибка калибровки сигнала PPS.
- STA_CLOCKERR (только чтение)
- Проблема с аппаратурой часов.
- STA_NANO (только чтение; начиная с Linux 2.6.26)
- Единица данных (0 = микросекунды, 1 = наносекунды). Устанавливается с помощью ADJ_NANO, очищается с помощью ADJ_MICRO.
- STA_MODE (начиная с Linux 2.6.26)
- Режим (0 = фазовая подстройка частоты, 1 = частотная подстройка частоты).
- STA_CLK (только чтение; начиная c Linux 2.6.26)
- Источник часов (0 = A, 1 = B); не используется.
Попытки установить биты status, помеченные только для чтения, просто игнорируются.
clock_adjtime ()¶
The clock_adjtime() system call (added in Linux 2.6.39) behaves like adjtimex() but takes an additional clk_id argument to specify the particular clock on which to act.
ntp_adjtime ()¶
Библиотечная функция ntp_adjtime() (описана в NTP "Kernel Application Program API", KAPI) является более переносимым интерфейсом для выполнения той же задачи, что и adjtimex(). Она идентична adjtimex() кроме следующего:
- Константы, используемые в modes, начинаются с «MOD_», а не с «ADJ_», и содержат одинаковые суффиксы (MOD_OFFSET, MOD_FREQUENCY, and so on), кроме:
- MOD_CLKA — синоним ADJ_OFFSET_SINGLESHOT.
- MOD_CLKB — синоним ADJ_TICK.
- Синонима для ADJ_OFFSET_SS_READ в KAPI нет.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении adjtimex() и ntp_adjtime() возвращают состояние часов, а именно одно из следующих значений:
- TIME_OK
- Часы синхронизированы, подстройки високосной секундой не ожидается.
- TIME_INS
- Показывает, что в конце дня по UTC будет добавлена високосная секунда.
- TIME_DEL
- Показывает, что в конце дня по UTC будет удалена високосная секунда.
- TIME_OOP
- Выполняется вставка високосной секунды.
- TIME_WAIT
- Выполнена вставка или удаление високосной секунды. Это значение возвращается при следующей операции ADJ_STATUS по очистке флагов STA_INS и STA_DEL.
- TIME_ERROR
- Системное время не синхронизировано с авторитетным сервером. Это значение возвращается при любом утвердительном значении следующего:
- Установлен STA_UNSYNC или STA_CLOCKERR.
- Флаг STA_PPSSIGNAL сброшен и установлен STA_PPSFREQ или STA_PPSTIME.
- Установлены флаги STA_PPSTIME и STA_PPSJITTER.
- Установлен флаг STA_PPSFREQ и STA_PPSWANDER или STA_PPSJITTER.
- Символическое имя TIME_BAD — синоним TIME_ERROR, предоставляется для обратной совместимости.
Заметим, что начиная с Linux 3.4 вызов выполняется асинхронно и возвращаемое значение, обычно, не отражает состояние, изменённое самим вызовом.
При ошибке эти вызовы возвращают -1 и изменяют errno.
ОШИБКИ¶
- EFAULT
- buf не является указателем на доступную для записи область памяти.
- EINVAL (до Linux 2.6.26)
- Попытка установить buf.freq в значение вне диапазона (-33554432, +33554432).
- EINVAL (до Linux 2.6.26)
- Попытка установить buf.offset в значение вне разрешённого диапазона. В ядрах до Linux 2.0 допустимым диапазоном был (-131072, +131072). Начиная с Linux 2.0 и новее допустимым диапазоном является (-512000, +512000).
- EINVAL
- Попытка установить buf.status в значение, отличное от перечисленных выше.
- EINVAL
- The clk_id given to clock_adjtime() is invalid for one of two reasons. Either the System-V style hard-coded positive clock ID value is out of range, or the dynamic clk_id does not refer to a valid instance of a clock object. See clock_gettime(2) for a discussion of dynamic clocks.
- EINVAL
- Предпринята попытка установить buf.tick в значение вне диапазона от 900000/HZ до 1100000/HZ, где HZ — частота прерываний системного таймера.
- ENODEV
- The hot-pluggable device (like USB for example) represented by a dynamic clk_id has disappeared after its character device was opened. See clock_gettime(2) for a discussion of dynamic clocks.
- EOPNOTSUPP
- The given clk_id does not support adjustment.
- EPERM
- Значение buf.modes не равно 0 или ADJ_OFFSET_SS_READ и вызывающий не имеет необходимых прав. В Linux для этого требуется мандат CAP_SYS_TIME.
АТРИБУТЫ¶
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
ntp_adjtime() | Безвредность в нитях | MT-Safe |
СООТВЕТСТВИЕ СТАНДАРТАМ¶
Эти интерфейсы не описаны в POSIX.1
adjtimex() and clock_adjtime() are Linux-specific and should not be used in programs intended to be portable.
Предпочтительным программным интерфейсом для службы NTP является ntp_adjtime().
ЗАМЕЧАНИЯ¶
В структуре timex, freq, ppsfreq и stabil ppm (частей на миллион) имеет 16-битную дробную часть, что означает, что значение 1 в одном из этих полей в действительности равно 2^-16 ppm, и 2^16=65536 равно 1 ppm. Это действительно как для входных (в случае freq) так и для выходных значений.
Обработка високосной секунды, возникающая при установке STA_INS и STA_DEL, выполняется ядром в контексте таймера. Следовательно, для установки или удаления високосной секунды потребуется один тик для перехода.
СМ. ТАКЖЕ¶
clock_gettime(2), clock_settime(2), settimeofday(2), adjtime(3), ntp_gettime(3), capabilities(7), time(7), adjtimex(8), hwclock(8)
ЗАМЕЧАНИЯ¶
Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан Dmitry Bolkhovskikh <d20052005@yandex.ru> и Yuri Kozlov <yuray@komyakino.ru>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
9 июня 2020 г. | Linux |