使用adjtimex进行小时间调整

Gro*_*uez 2 c linux time kernel

我有一个Linux系统,我需要对系统时间进行小周期性调整以跟踪外部时间源,但我想避免日期/时间跳转.

我想过使用adjtimex()内核函数(参见:adjtimex(2),adjtimex(8)),但我有些疑惑:

  1. 偏移和单一拍摄模式之间的区别是什么?
  2. 什么是可接受的参数范围?我问的是因为:
    • adjtimex(8)提到参数--offset必须在-512000 ... 512000范围内(所以它只能纠正+/- 0.5s),并且没有提到任何值--singleshot
    • adjtimex(2)提到范围-131071 .. + 131071,这显然适用于两种模式
    • 在我的测试中(使用adjtimex命令行实用程序),这些限制似乎都不适用

任何帮助表示赞赏.

Nom*_*mal 6

(有关Linux手册页,请参阅Linux man-pages项目.它们更可能是最新的.注释表明实现的逻辑应遵循RFC 1305.)

有关实现的详细信息,请浏览Linux内核源代码.在adjtimex()系统调用中定义内核/ time.c ; 寻找SYSCALL_DEFINE.*(adjtimex,.

adjtimex()本身调用do_adjtimex()kernel/time/timekeeping.c中定义.基本范围检查ntp_validate_timex()kernel/time/ntp.c中定义.

至于你的具体问题:

  1. 如果您使用ADJ_OFFSET_SINGLESHOT,则adjtimex()表现为adjtime(),并且您只能使用该.offset字段.根据调整的大小和符号,NTP时钟会加速或减速一段时间,直到达到所需的偏移; 然后NTP时钟速率恢复原状.您不能使用任何其他模式标志.

    ADJ_SETOFFSET增加.time当前时间; 立即向前移动时钟.

    ADJ_OFFSET还调整NTP时钟速率以在合理的时间内实现所需的偏移,因此效果应与单次模式相同.但是,您也可以ADJ_在同一个调用中使用其他模式标志.

    Grodriguez发表评论后编辑:

    ADJ_OFFSET只有当偏移被认为是好的时,才有效,即时钟状态是锁相的STA_PLL.通常,STA_FLL如果采样间隔很长,或者NTP守护程序的样本不正确,NTP守护程序会将状态更改为频率锁定().

    要使用ADJ_OFFSET,您的程序应该使用模式模式ADJ_OFFSET|ADJ_STATUS,然后设置.status=STA_PLL.这使得当前时间被设置为参考时间,从而相对于当前系统时间计数偏移,并且还启用时钟偏移调整.

  2. 在内核源代码中,MAXPHASE常量(在include/linux/timex.h中)定义了偏移量限制.目前,它是以纳秒为单位,并指定半秒; 较大的值(大小)静静地限制在半秒,没有任何错误.

    在2.6.26之前的Linux内核中,限制较小(±131071μs).新的限制是在20085月增加的.

    (限制的更改已于2009年6月传达给Linux手册维护人员Michael Kerrisk,但显然adjtimex(2)手册页从未更新以反映此更改.我认为建议的措辞不够明确,虽然.)