Phi*_*ing 9 linux ntpd ntp clock systemd-timesyncd
我正在研究一些Beagle Bone Black (BBB)板上的一个非常奇怪的效果。我们看到系统时钟偶尔会出现几个月的跳跃,这总是与systemd-timesyncd更新系统时钟相关。我们每周会在不同地点的 2000 台设备中看到其中的 2 到 3 个。
我们花了很多时间检查 SNTP,但这似乎表现正常。
我们终于提出了板载实时时钟的硬件问题,由于电子噪声,该问题可能导致其随机跳跃 131072 秒(36 小时)。这并不立即正确,报告的时间跳跃非常具体并且比我们观察到的要少得多,但是对该问题的深入阅读表明跳跃可能更加随机,甚至可能倒退。
我的问题是... linux 如何使用实时时钟来维护系统时钟?
我想知道实时时钟的错误是否只会在时间同步代理(ntpd 或 systemd-timesyncd)更新时出现在系统时钟中。系统时钟和 RTC 之间是否有任何直接联系,还是仅由代理使用?
注意:在第一段中我提到我们在系统时钟中看到几个月的跳跃,这总是与systemd-timesyncd更新系统时钟相关。我的意思是,时间跳转后的第一个系统日志消息是一条Time has been changed系统日志消息:
grep 'Time has been changed' /var/log/syslog
Oct 2 23:53:33 hostname systemd[1]: Time has been changed
Nov 21 00:07:05 hostname systemd[1]: Time has been changed
Nov 21 00:05:17 hostname systemd[1]: Time has been changed
Nov 21 00:03:29 hostname systemd[1]: Time has been changed
Nov 21 00:01:43 hostname systemd[1]: Time has been changed
Oct 3 02:07:20 hostname systemd[1]: Time has been changed
Oct 3 06:37:04 hostname systemd[1]: Time has been changed
Run Code Online (Sandbox Code Playgroud)
据我所知,唯一发出这些消息的是 systemd-timesycnd(请参阅源代码)。显然,如果其他人知道systemd与这些匹配的其他常规系统日志消息消息,我愿意接受建议。
我可以回应其中的一些观点,包括标题。
[...] 这总是与
systemd-timesyncd更新系统时钟相关。我的意思是,时间跳转后的第一个系统日志消息是一条Time has been changed系统日志消息:Run Code Online (Sandbox Code Playgroud)grep 'Time has been changed' /var/log/syslog Oct 2 23:53:33 hostname systemd[1]: Time has been changed
实际上,此消息并没有告诉您是什么程序导致了时间跳跃。这只是时间跳跃的一种症状。
它发生在内核告诉systemd时钟已更改时。[*]systemd通过将此消息写入系统日志来响应,然后重新计算何时.timer需要触发任何单元。
该消息由程序打印systemd,而不是由systemd-timesyncd.
更具体地说,消息前缀“systemd[1]:”表示它来自进程 ID 1。PID 1 是特殊的“init”进程。systemd 项目也称其为“系统管理器”,以区别于systemd管理用户服务的实例。
systemd系统完成启动后,调用的程序不会更改时钟。
在您链接到的当前 systemd 源代码树中,唯一可以读取 RTC/硬件时钟/hwclock 的程序是timedated,并且仅当您使用timedatectl.
我记得,旧版本的systemd程序在启动时读取一次 hwclock,然后再运行任何其他程序,并相应地设置系统时钟。在最新版本中,systemd没有这样做。只有一些技巧可以告诉内核哪个时区用于硬件时钟。(并避免触发称为“时间扭曲”的非常具体的东西)。
换句话说, currentsystemd似乎隐含地假设其他东西初始化了系统时钟。在大多数情况下,这将是内核。
查找内核构建选项“在启动和恢复时从 RTC 设置系统时间” - CONFIG_RTC_HCTOSYS。
为了全面理解,请注意还有一个选项“基于 NTP 同步设置 RTC 时间” - CONFIG_RTC_SYSTOHC。
[*] 使用 Linux 特定功能检测系统时钟更改。见TFD_TIMER_CANCEL_ON_SET。
非常感谢 sourcejedi 的回答。这真的让我找到了正确的答案。
Linux 如何使用实时时钟来维护系统时钟?
它只执行一次,在启动期间。在下次重新启动之前,它不会再次查询 RTC。这是可配置的,但默认情况下会在大多数内核构建中进行。
我想知道实时时钟的错误是否只会在时间同步代理(ntpd 或 systemd-timesyncd)更新时出现在系统时钟中。
除非系统重新启动,否则 RTC 中的时间根本不可能进入系统时钟。有些代理ntpd可以配置为使用 RTC 作为时间源,但默认情况下通常不启用。除非您知道 RTC 是一个非常好的时间源,否则不建议启用它。
系统时钟之间有直接联系吗?
看来时间是以另一种方式复制的。RTC 会根据系统时间定期更新。根据 sourcejedi 的回答,如果设置了CONFIG_RTC_HCTOSYS,这将由内核完成。
这可以测试:
设置 RTC
# hwclock --set --date='18:28'
Run Code Online (Sandbox Code Playgroud)然后每隔几分钟检查一次 RTC 时间:
# hwclock
Run Code Online (Sandbox Code Playgroud)这样做的结果将是系统时间根本不会改变,RTC 最终会恢复到系统时间。
正如 sourcejedi 指出的那样,消息不是由systemd-timesyncd. 他们是由 触发的connman。证据是(应该)中的虚假日志消息/var/log/syslog:
Oct 3 00:10:37 hostname connmand[1040]: ntp: adjust (jump): -27302612.028018 sec
...
Nov 21 00:07:05 hostname systemd[1]: Time has been changed
Run Code Online (Sandbox Code Playgroud)
在 1.37 版之前, connman 被硬编码为混杂轮询当时的默认网关。它不需要配置 DHCP 来执行此操作,如果启用了 connman 的 NTP 客户端(默认情况下),那么无论任何其他配置如何,它都会执行此操作。
在我们的例子中,一些家庭路由器实际上正在响应这些 NTP 请求,但结果非常不可靠。尤其是在路由器重启的地方,它在不知道正确时间的情况下继续分发时间。
例如,我们知道至少有一个BT Home Hub 5版本在重新启动时默认为 2018 年 11 月 21 日,并通过 NTP 给出此日期。然后它自己的 NTP 客户端将纠正问题,但有一个窗口,它会在 2018 年 11 月 21 日分发。
也就是说,这个问题最终是由于我们的客户重新启动了他们的路由器,而 connman 只是接受了这次。
我会在这里表达我的沮丧,似乎有些人的好战让 connman 中的这个“功能”已经太久了。 早在 2015 年就被报告为一个问题。这是一个非常隐藏的“功能”。没有配置时间服务器,也没有日志消息来解释 connman 正在做什么或关于原因的文档。如果您的测试设备在默认网关上没有 NTP 服务器,您将永远不会在测试中看到这一点。
我们正在研究两个似乎都有效的选项:
完全删除 connman。没有它,网络似乎也能正常工作;我们还没有找到它首先存在的原因。
apt-get remove connman
Run Code Online (Sandbox Code Playgroud)通过编辑在 connman 中禁用 NTP,/var/lib/connman包括:
[global]
TimeUpdates=manual
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1736 次 |
| 最近记录: |