*注意:如果您的服务器由于内核混淆而仍然存在问题,并且无法重新启动,那么在您的系统上安装gnu date的最简单解决scheme是:date -s now。 这将重置内核的内部“time_was_set”variables,并修复java和其他用户空间工具中的CPU hogging futex循环。 我已经在我自己的系统上确定了这个命令,
死后
Anticlimax:唯一死的是我的VPN(openvpn)链接到集群,所以重新build立时有一个激动人心的几秒钟。 其他的一切都很好,在闰秒过后,启动ntp就干干净净了。
我写了一天的全部经验在http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/
如果你看看Marco的博客http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-秒 – 他有一个解决scheme使用ntpd -x在24小时内逐步改变时间,避免1秒跳过。 这是运行自己的ntp基础架构的另一种涂抹方法。
就在今天,2012年6月30日星期六 – 格林尼治标准时间开始后不久即将开始。 我们在不同的数据中心有几台服务器,由不同的团队pipe理,所有的服务器都是黑屏的 – 没有响应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
不幸的是,所有刀片都configuration了kdump,但是他们死得很厉害,kdump没有触发 – 而且他们开启了控制台消隐function。 我现在已经禁用了控制台消隐function,所以在下一次崩溃之后,我会有更多的信息。
只是想知道这是一个共同的线索还是“只有我们”。 他们在不同的时间购买不同的数据中心的不同单位,并且由不同的pipe理员运行(我运行FastMail.FM),而现在甚至是不同的供应商硬件,真的很奇怪。 大多数坠毁的机器已经运行了几个星期/月,运行的是3.1或3.2系列的内核。
最近的一次碰撞是一台只运行了大约6小时3.2.21的机器。
解决方法
好的人,这是我如何解决它。
/etc/init.d/ntp stop
fixtime.pl
没有一个参数,看到有一个飞跃第二集 fixtime.pl
来删除闰秒 注意:取决于adjtimex
。 我已经在http://linux.brong.fastmail.fm/2012-06-30/adjtimex上放置了一个squeeze adjtimex
二进制文件的副本 – 它将在没有依赖于64位系统的情况下运行。 如果你把它放在与fixtime.pl
相同的目录中,那么如果系统不存在,它将被使用。 显然,如果你没有挤64位…find你自己的。
我明天要开始ntp
。
正如匿名用户所build议的 – 运行adjtimex
的另一种方法就是自己设置时间,这也可能会清除跳跃计数器。
当ntpd调用adjtimex(2)告诉内核插入一个闰秒时,这是由一个活锁造成的。 查看lkml发帖http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
红帽也应该更新他们的KB文章。 https://access.redhat.com/knowledge/articles/15145
更新:红帽有这个问题的第二个知识库文章在这里: https : //access.redhat.com/knowledge/solutions/154713 – 上一篇文章是为了一个较早的,不相关的问题
解决方法是closuresntpd。 如果ntpd已经发出了adjtimex(2)调用,则可能需要禁用ntpd并重启以保证100%的安全。
这会影响RHEL 6和运行较新内核的其他发行版(比2.6.26更新),但不会影响RHEL 5。
在闰秒实际上计划发生之前发生的原因是ntpd让内核在午夜处理闰秒,但是需要提醒内核在午夜之前插入闰秒。 ntpd因此在闰秒的某一天的某个时候调用adjtimex(2),此时触发该错误。
如果安装了adjtimex(8),则可以使用此脚本来确定是否设置了标志16。 旗16是“插闰秒”:
adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'
更新:
红帽已经更新了他们的知识库文章,注意到:“RHEL 6客户可能会受到一个已知问题的影响,导致NMI看门狗在接收到NTP突发公告时检测到挂起,这个问题正在及时解决。没有经历过这个问题,那么他们就不再受影响了。“
更新:上述语言已从红帽文章中删除; 并添加了第二个KB解决scheme,详细介绍了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
如果这次我正在读这篇文章,那么当闰秒被应用时,我错误地认为会出现另一个僵局。 这似乎也是红帽的意见,根据他们的KB条目。 但是,如果您禁用了ntpd,请将其禁用另外10分钟,以便在ntpd调用adjtimex(2)时不会造成死锁。
我们会发现是否还有更多的错误:)
POST-LEAP SECOND UPDATE:
我花了几个小时阅读ntpd和pre-patch(buggy)的内核代码,虽然我可能在这里错了,但我会试着解释一下我的想法:
首先,ntpd始终调用adjtimex(2)。 它作为其在“ntp_loopfilter.c”中local_clock中定义的“时钟循环filter”的一部分。 你可以看到这里的代码: http : //www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (从ntp版本4.2.6)。
时钟循环filter经常运行 – 每当ntpd轮询其上游服务器时运行,默认情况下是每17分钟或更多。 时钟环路滤波器的相关位是:
if (sys_leap == LEAP_ADDSECOND) ntv.status |= STA_INS;
接着:
ntp_adjtime(&ntv)
换句话说,在第二个闰秒的时候,ntpd设置“STA_INS”标志并且调用adjtimex(2)(通过它的可移植性包装)。
该系统调用进入内核。 以下是相关的内核代码: https : //github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
内核代码path大致是这样的:
这里有一些有趣的事情。
首先,每当调用adjtimex(2)时,第691行取消现有的定时器。 然后,554重新创build该计时器。 这意味着每次ntpd运行其时钟循环filter,都会调用错误的代码。
所以我相信红帽说错了,一旦ntpd设置了闰秒标志,系统就不会崩溃。 我相信每个运行ntpd的系统都有可能在闰秒前的24小时内每隔17分钟(或更多)活跃一次。 我相信这也可以解释为什么这么多的系统崩溃了; 与一小时三次机会相比,一次碰撞的可能性要小得多。
更新:红帽的KB解决schemehttps://access.redhat.com/knowledge/solutions/154713 ,红帽工程师也得出了同样的结论(运行ntpd将不断碰到错误的代码)。 事实上,他们在我做了几个小时之前就这样做了。 这个解决scheme没有链接到https://access.redhat.com/knowledge/articles/15145上的主要文章,所以直到现在我才注意到它。
其次,这解释了为什么加载的系统更容易崩溃。 加载的系统将会处理更多的中断,导致“do_tick”内核函数被更频繁地调用,给这个代码更多的机会运行,并在定时器创build时获取ntp_lock。
第三,闰秒实际发生时系统是否有崩溃的机会? 我不知道,但可能是的,因为启动的计时器并实际执行闰秒调整(ntp_leap_second,在第388行)也抓住ntp_lock螺旋锁,并调用hrtimer_add_expires_ns。 我不知道这个电话是否也能够导致活锁,但这似乎不可能。
最后,在闰秒运行之后,导致闰秒标志被禁用的原因是什么? 有ntpd的答案停止设置闰秒标志在午夜后的某个时刻,当它调用adjtimex(2)。 由于该标志未被设置,因此第554行的检查将不成立,并且不会创build定时器,并且第598行将把time_state全局variables重置为TIME_OK。 这就解释了为什么如果你在闰秒后用adjtimex(8)检查标志,你仍然会看到闰秒标志设置。
总之,今天最好的build议似乎是我给的第一个:禁用ntpd,并禁用闰秒标志。
还有一些最后的想法:
06/02 John Stultz的更新:
https://lkml.org/lkml/2012/7/1/203
这篇文章包含了闰秒为什么会导致futex定时器过早和持续失效的一步一步的介绍,消除了CPU负载。
这打击我们很难。 在重启我们的许多主机之后,没有主机重新启动,结果是令人尴尬的简单和完全有效:
/etc/init.d/ntp stop ntpdate 0.us.pool.ntp.org /etc/init.d/ntp start
所有需要的是重置系统时钟。 啧。 我六个小时前已经知道了。
一个简单的C程序,清除内核时间状态字段中的闰秒:
#include <sys/timex.h> #include <string.h> #include <stdio.h> int main(int argc, char **argv) { struct timex txc; int ret; (void) argc; (void) argv; bzero(&txc, sizeof(txc)); txc.modes = 0; /* fetch */ ret = adjtimex(&txc); if (ret < 0) { perror("adjtimex (get)"); return 1; } txc.modes = ADJ_STATUS; txc.status &= ~16; ret = adjtimex(&txc); if (ret < 0) { perror("adjtimex (set)"); return 1; } return 0; }
保存为lsec.c
,用gcc -Wall -Wextra -o lsec lsec.c
并以root用户gcc -Wall -Wextra -o lsec lsec.c
运行。
在运行之前,您可能需要停止ntpd,并在闰秒后重新启动ntpd。
看来似乎./lsec没有效果。
我们所看到的是大量的进程在吃CPU(通常对于java进程是线性的)
通过ntp应用闰秒修复POSTMORTEM的工作如下:
似乎只要发布就足够了:
export LANG="en_EN"; date -s "`date`"
这应该减less没有ntpd重新启动或重新启动的负载。 或者,您可以发出:
apt-get install ntpdate /etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start
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中崩溃。“