在闰秒的第二天,任何遇到高服务器的Linux服务器崩溃?

*注意:如果您的服务器由于内核混乱而仍然存在问题,并且无法重新启动 – 那么在您的系统上安装gnu date最简单的解决方案是:date -s now。这将重置内核的内部“time_was_set”变量并修复java和其他用户空间工具中的CPU hogging futex循环。我已经在我自己的系统上确定了这个命令,

死后

Anticlimax:唯一死的是我的VPN(openvpn)链接到集群,所以重新建立时有一个激动人心的几秒钟。其他一切都很好,在闰秒过后,启动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-秒 – 他有一个解决方案使用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小时,运行时间仅为6小时。

解决方法

好的人,这是我如何解决它。

  1. 禁用ntp: /etc/init.d/ntp stop
  2. 创建了http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl(代码从Marco中窃取,请参阅评论中的博客文章)
  3. fixtime.pl不带参数看,有一个闰秒集
  4. fixtime.pl用的参数,以除去闰秒

注意:取决于adjtimex。我adjtimexhttp://linux.brong.fastmail.fm/2012-06-30/adjtimex上放了一个squeeze 二进制文件的副本- 它将在不依赖于64位系统的情况下运行。如果你把它放在同一个目录下fixtime.pl,如果系统不存在,它将被使用。显然,如果你没有挤64位…找到你自己的。

ntp明天要重新开始。

正如一位匿名用户所建议的那样 – 运行的另一种方法adjtimex就是自己设定时间,这可能也会清除跳跃计数器。


这是由ntpd调用adjtimex(2)告诉内核插入闰秒的livelock导致的。请参阅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 – 上一篇文章是针对早期的,不相关的问题

解决方法是关闭ntpd。如果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解决方案,详细介绍了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

如果我现在正在阅读的话,那么当闰秒被应用时,我错误地认为会出现另一个僵局。基于他们的知识库文章,这似乎也是红帽的看法。但是,如果您禁用了ntpd,请将其禁用另外10分钟,以便在ntpd调用adjtimex(2)时不会造成死锁。

我们会发现是否会有更多的错误:)

POST-LEAP SECOND UPDATE:

我花了最后几个小时阅读了ntpd和pre-patch(buggy)的内核代码,虽然我可能在这里错了,但我会试着解释我的想法:

首先,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分钟或更长时间。时钟环路滤波器的相关位是:

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

内核代码路径大致是这样的:

  • 663行 – do_adjtimex例程的开始。
  • 691行 – 取消任何现有的闰秒计时器。
  • 第709行 – 抓住ntp_lock spinlock(这个锁涉及可能的livelock崩溃)
  • 第724行 – 调用process_adjtimex_modes。
  • 第616行 – 调用process_adj_status。
  • 第590行 – 根据在adjtimex(2)调用中设置的标志设置time_status全局变量
  • 第592行 – 检查time_state全局变量。在大多数情况下,请调用ntp_start_leap_timer。
  • 第554行 – 检查time_status全局变量。STA_INS将被设置,因此将time_state设置为TIME_INS并调用hrtimer_start(另一个内核函数)来启动闰秒定时器。在创建计时器的过程中,此代码抓取xtime_lock。如果在另一个CPU已经抓取xtime_lock  ntp_lock的情况下发生这种情况,则内核处于活锁状态。这就是John Stultz为了避免使用角质体而写了补丁的原因。这是今天造成每个人的麻烦。
  • 第598行 – 如果ntp_start_leap_timer实际上没有启动闰秒计时器,请将time_state设置为TIME_OK
  • 751行 – 假设内核不活锁,堆栈被解除,ntp_lock spinlock被释放。

这里有一些有趣的事情。

首先,691行在每次调用adjtimex(2)时取消现有的定时器。然后,554重新创建该计时器。这意味着每当ntpd运行其时钟循环过滤器时,都会调用该错误代码。

因此,我相信红帽当他们说ntpd设置了闰秒标志时系统不会崩溃是错误的。我相信运行ntpd的每个系统都有可能在闰秒前的24小时内每17分钟(或更多)活锁一次。我相信这也可以解释为什么这么多系统崩溃了; 与一小时三次机会相比,一次碰撞的机会将不太可能达到。

更新:在Red Hat的KB解决方案中,https://access.redhat.com/knowledge/solutions/154713,红帽工程师也得出了同样的结论(即运行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,并禁用闰秒标志。

还有一些最后的想法:

  • 没有一家Linux供应商注意到John Stultz的补丁,并将其应用到他们的内核:(
  • 为什么没有John Stultz警告某些供应商这是需要的?也许活锁的机会似乎足够低,使得噪音无法保证。
  • 我听说有关Java过程在闰秒应用时锁定或旋转的报道。也许我们应该遵循Google的主导思想,并重新思考我们如何将闰秒应用于我们的系统:http//googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

添加评论

友情链接:蝴蝶教程