ADJTIMEX - Linux手册页
Linux程序员手册 第2部分
更新日期: 2020-06-09
名称
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; /* Mode selector */ long offset; /* Time offset; nanoseconds, if STA_NANO status flag is set, otherwise microseconds */ long freq; /* Frequency offset; see NOTES for units */ long maxerror; /* Maximum error (microseconds) */ long esterror; /* Estimated error (microseconds) */ int status; /* Clock command/status */ long constant; /* PLL (phase-locked loop) time constant */ long precision; /* Clock precision (microseconds, read-only) */ long tolerance; /* Clock frequency tolerance (read-only); see NOTES for units */ struct timeval time; /* Current time (read-only, except for ADJ_SETOFFSET); upon return, time.tv_usec contains nanoseconds, if STA_NANO status flag is set, otherwise microseconds */ long tick; /* Microseconds between clock ticks */ long ppsfreq; /* PPS (pulse per second) frequency (read-only); see NOTES for units */ long jitter; /* PPS jitter (read-only); nanoseconds, if STA_NANO status flag is set, otherwise microseconds */ int shift; /* PPS interval duration (seconds, read-only) */ long stabil; /* PPS stability (read-only); see NOTES for units */ long jitcnt; /* PPS count of jitter limit exceeded events (read-only) */ long calcnt; /* PPS count of calibration intervals (read-only) */ long errcnt; /* PPS count of calibration errors (read-only) */ long stbcnt; /* PPS count of stability limit exceeded events (read-only) */ int tai; /* TAI offset, as set by previous ADJ_TAI operation (seconds, read-only, since Linux 2.6.26) */ /* Further padding bytes to allow for future expansion */ };
模式字段确定要设置的参数(如果有)。 (如本页稍后所述,用于ntp_adjtime()的常量是等效的,但名称有所不同。)它是一个位掩码,其中包含以下任一或多个零位或多个位的组合:
- ADJ_OFFSET
- 设置与buf.offset的时间偏移。从Linux 2.6.26开始,提供的值被限制在范围内(-0.5s,+ 0.5s)。在较早的内核中,如果提供的值超出范围,则会发生EINVAL错误。
- ADJ_FREQUENCY
- 设置buf.freq的频率偏移。从Linux 2.6.26开始,提供的值被限制在范围内(-32768000,+32768000)。在较早的内核中,如果提供的值超出范围,则会发生EINVAL错误。
- ADJ_MAXERROR
- 从buf.maxerror设置最大时间错误。
- ADJ_ESTERROR
- 从buf.esterror设置估计的时间错误。
- ADJ_STATUS
- 从buf.status设置时钟状态位。这些位的描述在下面提供。
- ADJ_TIMECONST
- 从buf.constant设置PLL时间常数。如果STA_NANO状态标志(请参见下文)被清除,则内核在该值上加4。
- ADJ_SETOFFSET(since Linux 2.6.39)
- 将buf.time添加到当前时间。如果buf.status包含ADJ_NANO标志,则buf.time.tv_usec解释为纳秒级值;否则,将其解释为微秒。
- buf.time的值是其两个字段的总和,但是字段buf.time.tv_usec必须始终为非负数。以下示例显示了如何以纳秒分辨率对时间间隔进行标准化。
while (buf.time.tv_usec < 0) { buf.time.tv_sec -= 1; buf.time.tv_usec += 1000000000; }
- ADJ_MICRO(since Linux 2.6.26)
- 选择微秒分辨率。
- ADJ_NANO(since Linux 2.6.26)
- 选择纳秒分辨率。仅应指定ADJ_MICRO和ADJ_NANO之一。
- ADJ_TAI(since Linux 2.6.26)
- 设置buf.constant的TAI(原子国际时间)偏移量。
- ADJ_TAI不应与ADJ_TIMECONST结合使用,因为后者的模式也使用buf.constant字段。
- 有关TAI的完整说明以及TAI和UTC之间的区别,请参阅BIPM。
- ADJ_TICK
- 从buf.tick设置刻度值。
或者,可以将模式指定为以下(多位掩码)值之一,在这种情况下,不应在模式中指定其他位:
- ADJ_OFFSET_SINGLESHOT
- 老式的adjtime(3):(逐渐地)通过buf.offset中指定的值来调整时间,该值指定以微秒为单位的调整。
- ADJ_OFFSET_SS_READ(functional since Linux 2.6.28)
- 返回(以buf.offset为单位)在较早的ADJ_OFFSET_SINGLESHOT操作之后要调整的剩余时间量。此功能已在Linux 2.6.24中添加,但是直到Linux 2.6.28才可以正常使用。
普通用户的模式限制为0或ADJ_OFFSET_SS_READ。只有超级用户可以设置任何参数。
buf.status字段是位掩码,用于设置和/或检索与NTP实现相关的状态位。掩码中的某些位既可读又可设置,而其他则为只读。
- STA_PLL(read-write)
- 通过ADJ_OFFSET启用锁相环(PLL)更新。
- STA_PPSFREQ(read-write)
- 启用PPS(每秒脉冲)频率规则。
- STA_PPSTIME(read-write)
- 启用PPS时间纪律。
- STA_FLL(read-write)
- 选择锁频环(FLL)模式。
- STA_INS(read-write)
- 在UTC日期的最后一秒之后插入一个leap秒,从而将日期的最后一分钟延长一秒。只要此标志保持置位状态,每天都会插入ap秒。
- STA_DEL(read-write)
- 在UTC的最后一秒删除a秒。只要此标志保持设置,每天都会发生秒删除。
- STA_UNSYNC(read-write)
- 时钟不同步。
- STA_FREQHOLD(read-write)
- 保持频率。通常,通过ADJ_OFFSET进行的调整也会导致衰减的频率调整。因此,一次调用就可以校正当前偏移,但是随着在同一方向上重复进行偏移,将累积少量的频率调整以固定长期偏斜。
- 该标志防止在校正ADJ_OFFSET值时进行小的频率调整。
- STA_PPSSIGNAL(read-only)
- 存在有效的PPS(每秒脉冲)信号。
- STA_PPSJITTER(read-only)
- 超出了PPS信号抖动。
- STA_PPSWANDER(read-only)
- PPS信号漂移超出范围。
- STA_PPSERROR(read-only)
- PPS信号校准错误。
- STA_CLOCKERR(read-only)
- 时钟硬件故障。
- STA_NANO(read-only; since Linux 2.6.26)
- 分辨率(0 =微秒,1 =纳秒)。通过ADJ_NANO设置,通过ADJ_MICRO清除。
- STA_MODE(since Linux 2.6.26)
- 模式(0 =锁相环,1 =频率锁相环)。
- STA_CLK(read-only; since Linux 2.6.26)
- 时钟源(0 = A,1 = B);当前未使用。
设置只读状态位的尝试将被静默忽略。
clock_adjtime ()
clock_adjtime()系统调用(在Linux 2.6.39中添加了)的行为类似于adjtimex(),但需要一个额外的clk_id参数来指定要对其操作的特定时钟。
ntp_adjtime ()
ntp_adjtime()库函数(在NTP"内核应用程序API",KAPI中进行了描述)是一种可移植的接口,用于执行与adjtimex()相同的任务。除了以下几点,它与adjtimex()相同:
- *
- 模式中使用的常量以" MOD_"而不是" ADJ_"为前缀,并且具有以下相同的后缀(因此,MOD_OFFSET,MOD_FREQUENCY等),但以下几点除外。
- *
- MOD_CLKA是ADJ_OFFSET_SINGLESHOT的同义词。
- *
- MOD_CLKB是ADJ_TICK的同义词。
- *
- 不是ADJ_OFFSET_SS_READ的同义词,KAPI中没有对此进行描述。
返回值
成功时,adjtimex()和ntp_adjtime()返回时钟状态;即,以下值之一:
- TIME_OK
- 时钟已同步,没有leap秒调整待定。
- TIME_INS
- 表示将在UTC日结束时添加a秒。
- TIME_DEL
- 表示a秒将在UTC日结束时删除。
- TIME_OOP
- 正在插入a秒。
- TIME_WAIT
- leap秒的插入或删除操作已完成。该值将一直返回,直到下一个ADJ_STATUS操作清除STA_INS和STA_DEL标志为止。
- TIME_ERROR
- The system clock is not synchronized to a reliable server.
This value is returned when any of the following holds true:
- *
- 设置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(kernels before Linux 2.6.26)
- 试图将buf.freq设置为超出范围(-33554432,+33554432)的值。
- EINVAL(kernels before Linux 2.6.26)
- 试图将buf.offset设置为允许范围之外的值。在Linux 2.0之前的内核中,允许的范围是(-131072,+131072)。从Linux 2.0开始,允许的范围是(-512000,+512000)。
- EINVAL
- 试图将buf.status设置为上述值以外的值。
- EINVAL
- 出于以下两个原因之一,赋予clock_adjtime()的clk_id无效。 System-V样式硬编码的正时钟ID值超出范围,或者动态clk_id没有引用时钟对象的有效实例。有关动态时钟的讨论,请参见clock_gettime(2)。
- EINVAL
- 尝试将buf.tick设置为900000 / HZ到1100000 / HZ之外的值,其中HZ是系统计时器中断频率。
- ENODEV
- 由动态clk_id表示的可热插拔设备(例如USB)在其字符设备打开后已消失。有关动态时钟的讨论,请参见clock_gettime(2)。
- EOPNOTSUPP
- 给定的clk_id不支持调整。
- EPERM
- buf.modes既不是0也不是ADJ_OFFSET_SS_READ,并且调用者没有足够的特权。在Linux下,需要CAP_SYS_TIME功能。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
ntp_adjtime() | Thread safety | MT-Safe |
遵循规范
POSIX.1中没有描述这些接口。
adjtimex()和clock_adjtime()是特定于Linux的,不应在打算移植的程序中使用。
NTP守护程序的首选API是ntp_adjtime()。
备注
在struct timex中,freq,ppsfreq和stabil是ppm(百万分之一),具有16位小数部分,这意味着这些字段之一中的值1实际上表示2 ^ -16 ppm,而2 ^ 16 = 65536是1 ppm。输入值(对于频率)和输出值均属于这种情况。
STA_INS和STA_DEL触发的leap秒处理由内核在计时器上下文中完成。因此,插入或删除the秒需要一秒。
另外参见
clock_gettime(2),clock_settime(2),settimeofday(2),adjtime(3),ntp_gettime(3),capabilities(7),time(7),adjtimex(8),hwclock(8)
NTP"内核应用程序接口"
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。