wake-up-neo.com

在a日第二天,是否有人遇到Linux服务器崩溃率很​​高的情况?

*注意:如果您的服务器由于内核混乱而仍然存在问题,并且您无法重新启动-建议在系统上安装gnu date的最简单解决方案是:date -s now。这将重置内核的内部“ time_was_set”变量,并修复Java和其他用户空间工具)中占用大量CPU的futex循环。锡*

[〜#〜]验尸[〜#〜]

Anticlimax:唯一导致死亡的是我到群集的VPN(openvpn)链接,因此重新建立群集的过程令人兴奋。其他一切都很好,the秒过去后,启动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-second =-他有一个解决方案,可以使用ntpd -x逐步调整24小时内的时间变化,以避免跳过1秒。这是运行自己的ntp基础结构的另一种拖尾方法。


就在今天,2012年6月30日,星期六-GMT一天开始后不久开始。我们在不同数据中心中有少数服务器,由不同团队管理的服务器全都变黑了-无法响应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个小时。

解决方法

好的,这是我的解决方法。

  1. 禁用的ntp:_/etc/init.d/ntp stop
  2. 已创建 http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (从Marco窃取的代码,请参阅评论中的博客文章)
  3. 在没有参数的情况下运行fixtime.pl以查看是否存在a秒
  4. 用一个参数运行fixtime.pl以删除to秒

注意:取决于adjtimex。我将压缩adjtimex二进制文件的副本放在 http://linux.brong.fastmail.fm/2012-06-30/adjtimex 上-它将在没有依赖的情况下运行压缩的64位系统。如果将它与fixtime.pl放在同一目录中,则在不存在系统目录的情况下将使用该目录。显然,如果您没有压缩64位的话,那就找到自己的吧。

我明天再开始ntp

正如一个匿名用户建议的那样-运行adjtimex的一种替代方法是自己设置时间,这大概还会清除the秒计数器。

363
Bron Gondwana

这是由ntpd调用adjtimex(2)告诉内核插入a秒时的活锁引起的。请参阅lkml发布 http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

红帽还应该更新其知识库文章。 https://access.redhat.com/knowledge/articles/15145

更新:Red Hat在这里有第二个KB文章专门针对此问题: https://access.redhat.com/knowledge/solutions/15471 -上一篇文章是针对一个较早的,不相关的问题的

解决方法是仅关闭ntpd。如果ntpd已经发出了adjtimex(2)调用,则可能需要禁用ntpd并重新启动以确保100%安全。

这会影响运行较新内核(大约大于2.6.26的内核)的RHEL 6和其他发行版,但不会影响RHEL 5。

之所以发生之前实际计划的leap秒发生是因为ntpd让内核在午夜处理handle秒,但需要提醒内核插入the秒午夜之前。因此,ntpd在the秒期间的某个时间调用adjtimex(2),此时将触发此错误。

如果安装了adjtimex(8),则可以使用此脚本来确定是否设置了标志16。标志16是“插入leap秒”:

adjtimex -p | Perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'

更新:

红帽更新了其知识库文章,以指出:“ RHEL 6客户可能受到已知问题的影响,该问题导致NMI看门狗在收到NTP =秒级公告。此问题正在得到及时解决。如果您的系统收到了秒级公告并且没有遇到此问题,那么它们将不再受到影响。”

更新:以上语言已从Red Hat文章中删除;并且添加了第二个KB解决方案,详细说明了adjtimex(2)崩溃问题: https://access.redhat.com/knowledge/solutions/15471

但是,IBM工程师John Stultz在LKML帖子中的代码更改指出,在实际应用the秒时也可能会出现死锁,因此您可能要在禁用ntpd后重新引导或使用adjtimex(8)来禁用the秒。

最终更新:

好吧,我不是内核开发人员,但是我在这里再次查看了John Stultz的补丁: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a = commit; h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

如果我这次没看错,那我错了,就是在应用the秒时还有另一个死锁。基于其KB条目,这似乎也是Red Hat的意见。但是,如果您已禁用ntpd,请再禁用10分钟,以免在ntpd调用adjtimex(2)时遇到死锁。

我们很快就会发现是否还有其他错误:)

跳跃后第二次更新:

我花了最后几个小时来阅读ntpd和预修补程序(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)

换句话说,在a秒的日子里,ntpd设置“ STA_INS”标志并调用adjtimex(2)(通过其可移植性包装程序)。

该系统调用进入内核。这是相关的内核代码: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

内核代码路径大致如下:

  • 第663行-do_adjtimex例程的开始。
  • 第691行-取消所有现有的leap秒计时器。
  • 第709行-抓取ntp_lock自旋锁(此锁与可能发生的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(另一个内核函数)以启动the秒计时器。在创建计时器的过程中,此代码捕获了xtime_lock。如果在另一个CPU已经抢占了xtime_lockntp_lock的情况下发生这种情况,则内核将处于活动状态。这就是John Stultz编写补丁以避免使用hrtimers的原因。这就是今天引起所有人麻烦的原因。
  • 第598行-如果ntp_start_leap_timer实际未启动跳转计时器,请将time_state设置为TIME_OK
  • 第751行-假设内核没有活动锁,则取消堆栈堆栈并释放ntp_lock自旋锁。

这里有一些有趣的事情。

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

因此,当他们说ntpd设置了the秒标志时,我相信Red Hat是错误的,该系统不会崩溃。我相信每个运行ntpd的系统都有潜力在the秒之前的24小时内每隔17分钟(或更长时间)进行一次活动锁定。我相信这也可以解释为什么这么多系统崩溃了。一次撞车的机会比每小时3次的机会要小得多。

更新:在 https://access.redhat.com/knowledge/solutions/15471 的Red Hat的KB解决方案中,Red Hat工程师确实得出了相同的结论(运行ntpd会不断遇到错误代码) )。实际上,他们比我早做了几个小时。该解决方案未链接到 https://access.redhat.com/knowledge/articles/15145 上的主要文章,因此直到现在我都没有注意到它。

其次,这解释了为什么加载的系统更容易崩溃。加载的系统将处理更多的中断,从而导致更频繁地调用“ do_tick”内核函数,从而在创建计时器时使此代码更有机会运行并抓住ntp_lock。

第三,在实际发生actually秒时,系统是否有崩溃的可能?我不确定,但可能是肯定的,因为触发并实际执行leap秒调整的计时器(第388行的ntp_leap_second)也抓取了ntp_lock自旋锁,并调用了hrtimer_add_expires_ns。我不知道该呼叫是否也可能导致活动锁定,但这似乎并非不可能。

最后,什么原因导致the秒运行后禁用disabled秒标志? ntpd的答案是在午夜之后某个时刻停止设置when秒标志,这时它将调用adjtimex(2)。由于未设置该标志,因此第554行的检查将不成立,也不会创建任何计时器,第598行将把time_state全局变量重置为TIME_OK。这解释了为什么如果在the秒之后用adjtimex(8)检查了标志,仍然会看到设置了set秒标志。

简而言之,今天最好的建议似乎是我给出的第一个建议:禁用ntpd,并禁用the秒标志。

还有一些最后的想法:

  • 没有一个Linux供应商注意到John Stultz的补丁并将其应用于他们的内核:(
  • john Stultz为什么不提醒某些供应商这是必需的?可能发生活锁的可能性似乎很低,因此没有必要发出噪音。
  • 我听过有关Java)在应用leap秒时进程锁定或旋转的报告。也许我们应该遵循Google的思路,重新考虑如何将how秒应用于系统: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

John Stultz 06/02更新:

https://lkml.org/lkml/2012/7/1/2

该帖子分步介绍了为什么the秒导致futex计时器过早连续地超时,从而增加了CPU负载。

318
Daniel S. Sterling

这给我们带来了沉重的打击。重新启动我们的许多主机后,以下结果非常简单且完全有效,而无需重新启动主机:

/etc/init.d/ntp stop
ntpdate 0.us.pool.ntp.org
/etc/init.d/ntp start

所需要做的只是重置系统时钟。嘘。我六个小时前所知道的。

33
HikeOnPast

一个简单的C程序,清除内核时间状态字段中的the秒位:

#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身份运行。

您可能需要在运行之前停止ntpd,然后在leap秒之后重新启动ntpd。

24
jon

验尸./lsec似乎没有效果。

我们看到的是许多softirqd进程占用了CPU(通常与Java进程)的负载成线性关系

使用ntp已应用的leap秒来修复POSTMORTEM的方法如下:

发出以下命令似乎就足够了:

export LANG="en_EN"; date -s "`date`"

这样可以减少负载,而无需重新启动或重新启动ntpd。或者,您可以发出:

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start
18
Gregor

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back 似乎表明Debian压缩内核无法处理the秒。

Comp.protocols.tim.ntp上的该线程也很有趣,它也是: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

也就是说,the秒尚未发生:UTC 23:59:60

最后, https://access.redhat.com/knowledge/articles/15145 表示:“发生the秒时,内核将一条消息打印到系统日志中。此消息的打印可能会导致内核在Red Hat Enterprise Linux中崩溃。”

16
Luca Filipozzi