*注意:如果您的服务器仍然由于内核混乱而出现问题,并且您无法重新启动 - 建议在您的系统上安装 gnu date 的最简单解决方案是:date -s now。这将重置内核的内部“time_was_set”变量并修复 Java 和其他用户空间工具中占用 CPU 的 futex 循环。我已经在我自己的系统上跟踪了这个命令,并确认它正在做它在罐头上所说的 *
尸检
虎头蛇尾:唯一死掉的是我的 VPN (openvpn) 链接到集群,所以在它重新建立时有几秒钟令人兴奋。其他一切都很好,在闰秒过去后启动 ntp 顺利进行。
我在http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/上写下了当天的全部经历
如果您在http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second查看 Marco 的博客- 他有一个解决方案使用 ntpd -x 在 24 小时内分阶段更改时间以避免跳过 1 秒。这是运行您自己的 ntp 基础设施的替代涂抹方法。
就在今天,2012 年 6 月 30 日星期六 - 格林威治标准时间当天开始后不久开始。我们在由不同团队管理的不同数据中心中有几台服务器都变暗了——不响应 ping,屏幕空白。
他们都在运行 Debian Squeeze——从库存内核到自定义 3.2.21 构建的一切。大多数是戴尔 M610 刀片,但我也刚刚丢失了一台戴尔 R510,其他部门也丢失了其他供应商的机器。还有一个旧的 IBM x3550 崩溃了,我认为它可能无关,但现在我想知道。
我确实从中得到屏幕转储的一次崩溃说:
[3161000.864001] BUG: spinlock lockup on CPU#1, ntpd/3358
[3161000.864001] lock: ffff88083fc0d740, .magic: dead4ead, .owner: imapd/24737, .owner_cpu: 0
不幸的是,所有刀片服务器都应该配置了 kdump,但它们死得太厉害以至于 kdump 没有触发 - 而且它们打开了控制台消隐。我现在已经禁用了控制台消隐,所以祈祷下次崩溃后我会得到更多信息。
只是想知道这是一个共同话题还是“只有我们”。真的很奇怪,它们是在不同时间购买的不同数据中心的不同单元,由不同的管理员运行(我运行 FastMail.FM 的)......现在甚至是不同的供应商硬件。大多数崩溃的机器已经运行了数周/数月,并且运行的是 3.1 或 3.2 系列内核。
最近的一次崩溃是一台运行 3.2.21 的机器只运行了大约 6 个小时。
解决方法
好吧,这就是我解决它的方法。
- 禁用的 ntp:
/etc/init.d/ntp stop
- 创建了http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl(从 Marco 窃取的代码,请参阅评论中的博客文章)
- 没有争论地跑去
fixtime.pl
看看有闰秒设置 - 运行
fixtime.pl
参数以删除闰秒
注意:取决于adjtimex
. 我在http://linux.brong.fastmail.fm/2012-06-30/adjtimexadjtimex
上放了一个 squeeze二进制文件的副本——它将运行而不依赖于 squeeze 64 位系统。如果将它放在与 相同的目录中,则在系统不存在时将使用它。显然,如果您没有 squeeze 64 位……找到您自己的。fixtime.pl
我ntp
明天要重新开始。
正如一位匿名用户所建议的那样——跑步的另一种选择adjtimex
是自己设置时间,这可能也会清除闰秒计数器。
这是由 ntpd 调用 adjtimex(2) 告诉内核插入闰秒时的活锁引起的。请参阅 lkml 发布http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Red Hat 也应该更新他们的知识库文章。https://access.redhat.com/knowledge/articles/15145
更新:Red Hat 在此处针对此问题发布了第二篇知识库文章:https ://access.redhat.com/knowledge/solutions/154713 - 上一篇文章针对的是较早的不相关问题
解决方法是关闭 ntpd。如果 ntpd 已经发出 adjtimex(2) 调用,您可能需要禁用 ntpd 并重新启动才能 100% 安全。
这会影响 RHEL 6 和其他运行较新内核(比大约 2.6.26 更新)的发行版,但不会影响 RHEL 5。
在闰秒实际计划出现之前发生这种情况的原因是 ntpd 让内核在午夜处理闰秒,但需要提醒内核在午夜之前插入闰秒。因此,ntpd 在闰秒当天的某个时间调用 adjtimex(2),此时会触发此错误。
如果您安装了 adjtimex(8),您可以使用这个脚本来确定是否设置了标志 16。标志 16 是“插入闰秒”:
更新:
Red Hat 更新了他们的知识库文章以注意:“RHEL 6 客户可能会受到一个已知问题的影响,该问题会导致 NMI Watchdog 在收到 NTP 闰秒公告时检测到挂起。这个问题正在及时解决。如果您的系统收到闰秒公告并没有遇到这个问题,那么他们就不再受到影响。”
更新:上述语言已从 Red Hat 文章中删除;并添加了第二个知识库解决方案,详细说明了 adjtimex(2) 崩溃问题:https ://access.redhat.com/knowledge/solutions/154713
但是,IBM 工程师 John Stultz 在 LKML 帖子中的代码更改指出,实际应用闰秒时也可能会出现死锁,因此您可能希望通过重新启动或在禁用 ntpd 后使用 adjtimex(8) 来禁用闰秒。
最后更新:
好吧,我不是内核开发人员,但我在这里再次查看了 John Stultz 的补丁:https ://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h =6b43ae8a619d17c4935c3320d2ef9e92bdeed05d
如果这次我没看错的话,我错了,应用闰秒时会出现另一个死锁。根据他们的知识库条目,这似乎也是 Red Hat 的意见。但是,如果您禁用了 ntpd,请将其再禁用 10 分钟,这样您就不会在 ntpd 调用 adjtimex(2) 时遇到死锁。
我们会尽快查明是否还有更多错误 :)
飞跃后第二次更新:
我花了最后几个小时阅读了 ntpd 和预补丁(错误)内核代码,虽然我在这里可能是非常错误的,但我将尝试解释我的想法:
首先,ntpd 一直调用 adjtimex(2)。它作为其“时钟循环过滤器”的一部分执行此操作,该过滤器在 ntp_loopfilter.c 的 local_clock 中定义。您可以在此处查看该代码:http ://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (来自 ntp 版本 4.2.6)。
时钟循环过滤器运行得相当频繁——它在每次 ntpd 轮询其上游服务器时运行,默认情况下每 17 分钟或更长时间运行一次。时钟环路滤波器的相关位是:
接着:
换句话说,在有闰秒的日子里,ntpd 设置“STA_INS”标志并调用 adjtimex(2)(通过其可移植性包装器)。
该系统调用进入内核。这是相关的内核代码:https ://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
内核代码路径大致是这样的:
这里有一些有趣的事情。
首先,每次调用 adjtimex(2) 时,第 691 行都会取消现有计时器。然后,554 重新创建该计时器。这意味着每次 ntpd 运行其时钟循环过滤器时,都会调用错误代码。
因此我相信 Red Hat 说一旦 ntpd 设置了闰秒标志,系统就不会崩溃是错误的。我相信每个运行 ntpd 的系统都有可能在闰秒之前的 24 小时内每 17 分钟(或更长时间)活锁一次。我相信这也可以解释为什么这么多系统崩溃;与每小时 3 次碰撞相比,一次碰撞的可能性要小得多。
更新:在https://access.redhat.com/knowledge/solutions/154713的 Red Hat 知识库解决方案中,Red Hat 工程师确实得出了相同的结论(运行 ntpd 会不断地遇到错误代码)。事实上,他们比我早几个小时就这样做了。这个解决方案没有链接到https://access.redhat.com/knowledge/articles/15145上的主要文章,所以我直到现在才注意到它。
其次,这解释了为什么加载的系统更容易崩溃。加载的系统将处理更多的中断,导致“do_tick”内核函数被更频繁地调用,从而为该代码提供更多机会运行并在创建计时器时获取 ntp_lock。
第三,真正出现闰秒时,系统是否有可能崩溃?我不确定,但可能是,因为触发并实际执行闰秒调整的计时器(ntp_leap_second,第 388 行)也获取 ntp_lock 自旋锁,并调用 hrtimer_add_expires_ns。我不知道那个调用是否也可能导致活锁,但这似乎并非不可能。
最后,是什么导致闰秒标志在闰秒运行后被禁用?ntpd 的答案是在午夜过后调用 adjtimex(2) 时停止设置闰秒标志。由于未设置标志,第 554 行的检查不会为真,并且不会创建计时器,并且第 598 行会将 time_state 全局变量重置为 TIME_OK。这解释了为什么如果您在闰秒之后使用 adjtimex(8) 检查标志,您仍然会看到闰秒标志设置。
简而言之,今天最好的建议似乎是我给出的第一个建议:禁用 ntpd,并禁用闰秒标志。
最后的一些想法:
06/02 John Stultz 更新:
https://lkml.org/lkml/2012/7/1/203
该帖子包含了一步一步的演练,说明了为什么闰秒会导致 futex 计时器过早和持续地过期,从而增加 CPU 负载。
这对我们打击很大。在重新启动我们的许多主机后,事实证明以下内容非常简单且完全有效,无需重新启动主机:
所需要的只是重置系统时钟。嘘。我付出了什么才能在六个小时前就知道这一点。
一个简单的 C 程序,用于清除内核时间状态字段中的闰秒位:
另存为
lsec.c
,编译gcc -Wall -Wextra -o lsec lsec.c
并以 root 身份运行。您可能希望在运行 ntpd 之前停止它,并在闰秒之后重新启动 ntpd。
事后看来 ./lsec 没有效果。
我们看到的是大量 softirqd 进程占用 CPU(通常与 java 进程的负载呈线性关系)
使用 ntp 已应用的闰秒来修复 POSTMORTEM 的工作如下:
仅发布以下内容似乎就足够了:
这应该可以在没有 ntpd restart 或 reboot 的情况下减少负载。或者你可以发出:
http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back似乎表明 Debian 压缩内核不会处理闰秒。
comp.protocols.tim.ntp 上的这个线程也很有趣:https ://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE
也就是说,闰秒尚未发生:23:59:60 UTC
最后,https://access.redhat.com/knowledge/articles/15145有如下说法:“当出现闰秒时,内核会向系统日志打印一条消息。打印这条消息有可能可能导致内核在 Red Hat Enterprise Linux 中崩溃。”