うるう2日目にLinuxサーバーのクラッシュが頻繁に発生する人はいますか?


365

*注意:混乱したカーネルが原因でサーバーにまだ問題があり、再起動できない場合-システムにインストールされているgnu dateで提案される最も簡単な解決策はdate -s nowです。これにより、カーネルの内部「time_was_set」変数がリセットされ、Javaおよびその他のユーザースペースツールでCPUが占有するfutexループが修正されます。私は自分のシステムでこのコマンドを実行し、スズで言うことを実行していることを確認しました*

死後

Anticlimax:死んだのはクラスターへの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を使用して1時間のスキップを回避するために、24時間にわたって時間の変更を段階的に行います。これは、独自のntpインフラストラクチャを実行するための代替の塗り付け方法です。


ちょうど今日、2012年6月30日(土)-GMTの開始後すぐに開始。さまざまなチームによって管理されているように、さまざまなデータセンターに少数のサーバーがあります-pingに応答せず、画面が空白になります。

それらはすべてDebian Squeezeを実行しています-ストックカーネルからカスタム3.2.21ビルドまでのすべてを備えています。ほとんどがDell M610ブレードですが、私はDell R510を失い、他の部門も他のベンダーのマシンを失いました。また、クラッシュし、無関係であると思われた古いIBM x3550もありましたが、今は疑問に思っています。

私が言ったからスクリーンダンプを取得した1つのクラッシュ:

[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うるう秒セットがあることを確認するために引数なしで実行しました
  4. fixtime.plうるう秒を削除する引数を指定して実行しました

注:に依存しadjtimexます。squeeze adjtimexバイナリのコピーをhttp://linux.brong.fastmail.fm/2012-06-30/adjtimexに置きました。squeeze64ビットシステムに依存せずに実行されます。のディレクトリと同じディレクトリfixtime.plに配置すると、システムのディレクトリが存在しない場合に使用されます。明らかに、64ビットsqueezeがない場合は、自分で見つけてください。

ntp明日また始めます。

匿名ユーザーが提案したように-実行する代わりにadjtimex、自分で時間を設定するだけで、おそらくうるう秒カウンターもクリアされます。


58
今日は30秒のうるう秒があります。私はそれがあなたの問題であることをほのめかしますが、私のDebianマシンを注意深く見ています。
jscott

2
朝から、ストックスクイーズ2.6.32カーネルを実行しているさまざまなベンダーから少なくとも9種類のdebianスクイーズボックスを失いました。コンソールのブランキングも原因でクラッシュダンプを取得することができませんでした
...-kargig


2
これを報告していただきありがとうございます!私は今、非常に密接に自分のサーバーを見つめています。
ジャンヌピッカライネン

5
LKMLスレッドはそれがdate -s "`date`"役立つことを示しました-それは確かに私を助けました。
とがった

回答:


321

これは、ntpdがadjtimex(2)を呼び出して、うるう秒を挿入するようカーネルに指示するときのライブロックが原因です。lkmlの投稿http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.htmlを参照してください

Red HatもKB記事を更新する必要があります。https://access.redhat.com/knowledge/articles/15145

更新:Red Hatには、この問題に関する2番目のKB記事があります: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"'

更新:

Red HatはKB記事を更新して、「RHEL 6のお客様は、NTPうるう秒のアナウンスを受信するとNMI Watchdogがハングを検出するという既知の問題の影響を受ける可能性があります。この問題はタイムリーに対処されています。うるう秒の発表であり、この問題は発生していなかったため、影響を受けなくなりました。」

更新:上記の言語はRed Hatの記事から削除されました。また、adjtimex(2)クラッシュの問題の詳細を示す2番目のKBソリューションが追加されました: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エントリに基づくと、これもRed Hatの意見のようです。ただし、ntpdを無効にしている場合は、ntpdがadjtimex(2)を呼び出したときにデッドロックが発生しないように、さらに10分間無効のままにします。

もうすぐバグがあるかどうかを確認します:)

ポストラップ2回目の更新:

私はここ数時間、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スピンロックを取得します(このロックは、可能性のあるライブロッククラッシュに関与しています)
  • 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がhrtimersの使用を避けるためにパッチを作成した理由です。これが今日、誰もがトラブルを引き起こした原因です。
  • 598行目-ntp_start_leap_timerが実際にリープタイマーを開始しなかった場合、time_stateをTIME_OKに設定します
  • 751行目-カーネルがライブロックしないと仮定すると、スタックは巻き戻され、ntp_lockスピンロックが解放されます。

ここにはいくつか面白いことがあります。

まず、行691は、adjtimex(2)が呼び出されるたびに既存のタイマーをキャンセルします。次に、554はそのタイマーを再作成します。これは、ntpdがクロックループフィルターを実行するたびに、バグのあるコードが呼び出されたことを意味します。

したがって、ntpdがうるう秒フラグを設定するとシステムがクラッシュしないと言ったとき、Red Hatは間違っていたと思います。ntpdを実行している各システムは、うるう秒の前の24時間の間、17分(またはそれ以上)ごとにライブロックする可能性があると思います。これにより、多くのシステムがクラッシュした理由も説明できると思います。1回のクラッシュの可能性は、1時間に3回の可能性と比較して、ヒットする可能性がはるかに低くなります。

更新:https ://access.redhat.com/knowledge/solutions/154713のRed HatのKBソリューションでは、Red Hatのエンジニアは同じ結論に達しました(ntpdを実行するとバグのあるコードが継続的にヒットする)。そして実際、彼らは私がそうする数時間前にそうしました。このソリューションは、https://access.redhat.com/knowledge/articles/15145のメイン記事にリンクされていなかったため、今まで気づいていませんでした。

第二に、これはロードされたシステムがクラッシュする可能性が高い理由を説明します。ロードされたシステムはより多くの割り込みを処理するため、「do_tick」カーネル関数がより頻繁に呼び出され、タイマーの作成中にこのコードを実行してntp_lockを取得する機会が増えます。

第三に、実際にうるう秒が発生したときにシステムがクラッシュする可能性はありますか?確かにわかりませんが、恐らくはい、うるう秒調整を実行して実際に実行するタイマー(388行目のntp_leap_second)もntp_lockスピンロックを取得し、hrtimer_add_expires_nsを呼び出します。その呼び出しがライブロックを引き起こす可能性があるかどうかはわかりませんが、不可能ではないようです。

最後に、うるう秒の実行後にうるう秒フラグが無効になる原因は何ですか?ntpdの答えは、adjtimex(2)を呼び出す深夜0時以降のある時点でうるう秒フラグの設定を停止します。フラグが設定されていないため、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

06/02 John Stultzからの更新:

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

この投稿には、うるう秒が原因でfutexタイマーが時期尚早に継続的に期限切れになり、CPU負荷が急上昇する理由が段階的に説明されています。


7
すばらしい回答をありがとう。そのため、残りのサーバーはクラッシュするのを待っています。素敵。ここからローリングが再開します!
ブロンゴンドワナ

3
adjtimexが発行されたかどうかを知る方法はありますか、カーネルはdmesgで何かを出力しますか?ntpdをオフにする前にクラッシュしなかったシステムがクラッシュする可能性はありますか?
ヒューバートカリオ

3
ヒューバート: "adjtimex"(通常は個別にパッケージ化されています)を実行し、うるう秒が保留中であることを示すフラグ16を探します。
ドミニククリール

22
担当者キャップは嫌いです。
ウェズリー

26
@WesleyDavid:心配ありません。UTCの深夜に担当者キャップがリセットされます。多分。
mmyers

33

これは私たちに大きな打撃を与えました。ホストの多くを再起動した後、ホストを再起動しなくても、以下は非常に単純で完全に効果的であることがわかりました。

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

必要なのは、システムクロックをリセットすることだけです。シーシュ。これを6時間前に知ったことに私が与えたもの。


8
date -s "`date`"私のために働いた。
とがった

@DeanB:午前3時に、時計をリセットするとうまくいくと投稿しましたが、残念ながら、モデレートに時間がかかりました。サーバーの再起動も開始しました
Gregor

24

カーネルの時間ステータスフィールドのうるう秒をクリアする単純な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.cgcc -Wall -Wextra -o lsec lsec.croot でコンパイルして実行します。

ntpdを実行する前に停止し、うるう秒後にntpdを再起動することをお勧めします。


何を(void) argc;達成しますか?未使用の変数の警告を消しますか?使用int main()しても同じことはできませんか?物beいになろうとしていない、私は本当に興味があります。
12

18

./lsecには効果がないようです。

私たちが見ているのは、CPUを消費する多くのsoftirqdプロセスです(通常、Javaプロセスの負荷に対して線形です)

ntpによって既に適用されているうるう秒で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

なぜsntp -sありませんかntpdate
-errordeveloper

ntpdateはここでのsntpの単なるラッパーです。ntpdateを使用してもかまいません。
グレゴール

ああ、実際にはバイナリであるsqueeze用のntpdateパッケージがありませんでした。これを含めるように投稿を編集しました。
グレゴール

この問題を修正する同様の報告も聞いています(を使用するなどdate -s)。修正では、システム時間を変更するのではなく、システム時間を設定するだけでよいようです(オフセットが小さい場合のデフォルトのntpdの動作)。時間を設定すると、カーネルの内部時間管理メカニズムが自動的にリセットされると思います。
パトリック

4
私のJavaアプリのCPU使用率も急上昇し(softirqdで大量のCPU時間を費やした)、これが修正されました。
ヒューバートカリオ

16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-backは、Debian squeezeカーネルがうるう秒を処理しないことを示しているようです。

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でカーネルがクラッシュする可能性があります。」


しかし、3.2.21カーネルは、おそらく-クラッシュしたマシンの少なくとも1つが実行していたはずです
ブロンゴンドワナ

ブロンが示したこれらのマシンのいくつかでは、今後のうるう秒を正しく処理する修正を実際に展開しました。
コジモ

他の人がアイデアをレビュー/提案/試行できるように、修正をどこかに投稿できますか?
カーギグ

修正方法はありません...情報を収集しています。おそらく、元の質問に対するコメントとしてこれを置くべきでした。
ルカフィリポッチ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.