Linux Man на русском

  User    Syst    Libr    Device    Files    Other    Admin  



   adjtimex - тонкая настройка часов в ядре

adjtimex(2) тонкая настройка часов в ядре


ОБЗОР

#define _BSD_SOURCE /* Смотрите feature_test_macros(7) */
#include <sys/timex.h>
int adjtimex(struct timex *buf);


ОПИСАНИЕ

В Linux для подстройки часов используется алгоритм Дэвида Л. Миллса (David L. Mills) (см. RFC 5905). Системный вызов adjtimex() читает и (необязательно) устанавливает параметры подстройки для этого алгоритма. В качестве аргумента используется указатель на структуру timex, по значениям в полях которой осуществляется обновление параметров ядра и в этой же структуре происходит возврат текущих значений параметров ядра. Данная структура объявлена так:

struct timex {
    int  modes;      /* выбор режима */
    long offset;     /* смещение по времени; в наносекундах, если
                        флаг установлен состояния STA_NANO, иначе
                        в микросекундах */
    long freq;       /* частота смещения, в единицах 2^-16 ppm
                        (частей на миллион, смотрите 
ЗАМЕЧАНИЯ далее) */ long maxerror; /* максимальная ошибка (микросекунды) */ long esterror; /* ожидаемая ошибка (микросекунды) */ int status; /* команда/состояние для часов */ long constant; /* временная константа PLL (phase-locked loop) */ long precision; /* точность часов (микросекунды, только чтение) */ long tolerance; /* допуск тактовой частоты (ppm, только чтение) */ struct timeval time; /* текущее время (только чтение, кроме ADJ_SETOFFSET); при возврате в time.tv_usec содержатся наносекунды, если установлен флаг состояния STA_NANO, иначе микросекунды */ long tick; /* микросекунд между тиками часов */ long ppsfreq; /* частота PPS (импульсов в секунду) (в единицах 2^-16 ppm, смотрите
ЗАМЕЧАНИЯ далее, только чтение) */ long jitter; /* искажение PPS (только чтение); в наносекундах, если установлен флаг состояния STA_NANO, иначе микросекунды */ int shift; /* длительность интервала PPS (секунды, только чтение) */ long stabil; /* устойчивость PPS (2^-16 ppm; смотрите
ЗАМЕЧАНИЯ, только чтение) */ long jitcnt; /* превышение ограничения искажения PPS (только чтение) */ long calcnt; /* интервалы калибровки PPS (только чтение) */ long errcnt; /* ошибки калибровки PPS (только чтение) */ long stbcnt; /* превышение ограничения устойчивости PPS (только чтение) */ int tai; /* смещение TAI, задаваемое предыдущей операцией ADJ_TAI (секунды, только чтение, начиная с Linux 2.6.26) */ /* далее идут байты заполнения, для расширения структуры в будущем */ };

Поле modes определяет какие параметры, если это необходимо, устанавливаются. Является битовой маской, содержащей комбинации (or) нуля или более следующих бит:

ADJ_OFFSET Установить смещение по времени из buf.offset.

ADJ_FREQUENCY Установить смещение частоты из buf.freq.

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.29) Добавить buf.time к текущему времени. Если в buf.status указан флаг ADJ_NANO, то значение buf.time.tv_usec считается заданным в наносекундах; в противном случае это микросекунды.

ADJ_MICRO (начиная с Linux 2.6.36) Выбрать микросекундной разрешение.

ADJ_NANO (начиная с Linux 2.6.36) Выбрать наносекундной разрешение. Должно быть указано что-то одно: ADJ_MICRO или ADJ_NANO.

ADJ_TAI (начиная с Linux 2.6.26) Установить смещение TAI (атомное международное время) из buf->константы.

ADJ_TAI не должно использоваться вместе с ADJ_TIMECONST, так как последний режим также использует поле buf->константа.

Подробное описание TAI и различия между TAI и UTC смотрите в BIPM

ADJ_TICK Установить значение тика из buf.tick.

Также в modes можно указывать любое из следующих значений (многобитовая маска), биты которых нельзя указать в modes:

ADJ_OFFSET_SINGLESHOT Старый вариант adjtime(): (постепенно) корректировать время значением, указанным в 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 Вставить високосную секунду (чтение/запись).

STA_DEL Удалить високосную секунду (чтение/запись).

STA_UNSYNC Часы не синхронизированы (чтение/запись).

STA_FREQHOLD Зафиксировать частоту (чтение/запись).

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 (начиная с Linux 2.6.26) Источник часов (0 = A, 1 = B; только чтение).

Попытки установить биты status, помеченные только для чтения, просто игнорируются.


ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении adjtimex() возвращает состояние часов; то есть одно из следующих значений:

TIME_OK Часы синхронизированы.

TIME_INS Вставлена високосная секунда.

TIME_DEL Удалена високосная секунда.

TIME_OOP Происходит учёт високосной секунды.

TIME_WAIT Прошла високосная секунда.

TIME_ERROR Часы не синхронизированы. Символическое имя TIME_BAD — синоним TIME_ERROR, предоставляется для обратной совместимости.

При ошибке adjtimex() возвращается -1 и изменяется errno.


ОШИБКИ

EFAULT buf не является указателем на доступную для записи область памяти.

EINVAL Предпринята попытка установить buf.offset в значение, выходящее за диапазон от -131071 до +131071, или установить buf.status в значение отличное от перечисленных выше, или установить buf.tick в значение за пределами диапазона от 900000/HZ до 1100000/HZ, где HZ — частота прерываний системного таймера.

EPERM Значение buf.modes не равно 0 или ADJ_OFFSET_SS_READ и вызывающий не имеет необходимых прав. В Linux для этого требуется мандат CAP_SYS_TIME.


ЗАМЕЧАНИЯ

В структуре timex, freq, ppsfreq и stabil ppm (частей на миллион) имеет 16-битную дробную часть, что означает, что значение 1 в одном из этих полей в действительности равно 2^-16 ppm, и 2^16=65536 равно 1 ppm. Это действительно как для входных (в случае freq) так и для выходных значений.


СООТВЕТСТВИЕ СТАНДАРТАМ

adjtimex() --- это специфичный для Linux системный вызов и он не должен использоваться в программах, которые должны быть переносимыми. Существует похожий, более переносимый, более гибкий метод настройки системных часов adjtime(3).