c - 使用 adjtimex 进行小的时间调整

标签 c linux time kernel

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

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

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

感谢任何帮助。

最佳答案

(请参阅 Linux 手册页的 Linux man-pages project。它们很可能是最新的。注释表明实现的逻辑应遵循 RFC 1305。)

有关实现细节,只需浏览 Linux 内核源代码即可。 adjtimex() 系统调用在 kernel/time.c 中定义;寻找 SYSCALL_DEFINE.*(adjtimex,

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

关于您的具体问题:

  1. 如果您使用 ADJ_OFFSET_SINGLESHOTadjtimex() 的行为与 adjtime() 相同,您只能使用 .offset 字段。根据调整的大小和符号,NTP 时钟会在短时间内加快或减慢,直到达到所需的偏移量;然后 NTP 时钟速率恢复到原来的状态。您不能将任何其他模式标志与它一起使用。

    ADJ_SETOFFSET 添加.time到当前时间;立即将时钟拨快。

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

    根据 Grodriguez 的评论进行编辑:

    ADJ_OFFSET 只有在偏移被认为是好的情况下才会起作用,即时钟状态是锁相的,STA_PLL。通常,如果采样间隔很长,或者 NTP 守护进程的样本不好,NTP 守护进程会将状态更改为频率锁定 (STA_FLL)。

    要使用ADJ_OFFSET,您的程序可能应该使用模式mode ADJ_OFFSET|ADJ_STATUS,并设置.status=STA_PLL。这会导致当前时间被设置为引用时间,以便相对于当前系统时间计算偏移量,并启用时钟偏移量调整。

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

    在 2.6.26 之前的 Linux 内核中,限制更小 (±131071µs)。在 May 2008 中添加了新限制.

    (限制的更改已传达给 Linux 手册页维护者 Michael Kerrisk,in June 2009 但显然 adjtimex(2) 手册页从未更新以反射(reflect)此更改。我不认为建议的措辞是不过,足够清楚了。)

关于c - 使用 adjtimex 进行小的时间调整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21732321/

相关文章:

复制到 C 中的 Null 位置并传递无效数据时崩溃

Golang 相当于 strtotime ("this Sunday, 23:59:59")

c - 禁用 DSUSP - 终端控制

无法将数据包接收到原始套接字

linux - 有没有Linux命令行环境的网站,可以练习命令?

linux - unqlite.h :651:15: error: changes meaning of ‘pgno’ from ‘typedef sxu64 pgno’ [-fpermissive]

linux - 从 ssh 登录中删除公钥

python - python 的快速/交互式开发环境

java - 如何使用公历在Java中通过出发时间减去到达时间来获得持续时间?

c - 为什么(带符号的)强制转换有时只需要表示最小整数(32 位系统)?