*注:カーネルの混乱が原因でサーバーにまだ問題があり、再起動できない場合-システムに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のブログを見ると、 =-彼は、1秒のスキップを回避するためにntpd -xを使用して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時間しか稼働していないマシンでした。
回避策
人よ、これが私がそれを回避した方法です。
/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ビットをスクイーズしていない場合は、自分で見つけてください。
明日はntp
を再開します。
匿名ユーザーが提案したように、adjtimex
を実行する代わりに、時刻を自分で設定することもできます。これにより、おそらくうるう秒カウンタもクリアされます。
これは、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/15471 -前の記事は、以前の無関係な問題に関するものです
回避策は、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"'
UPDATE:
Red HatはKB記事を次のように更新しました:「RHEL 6のお客様は、NMI WatchdogがNTP =うるう秒のアナウンス。この問題はタイムリーに対処されています。システムがうるう秒のアナウンスを受信し、この問題が発生していなければ、影響はありません。」
更新:上記の言語はRed Hatの記事から削除されました。そして、adjtimex(2)のクラッシュの問題を詳述する2番目のKBソリューションが追加されました: https://access.redhat.com/knowledge/solutions/15471
ただし、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と事前パッチ(バグの多い)カーネルコードを読むのに費やしましたが、ここでは非常に間違っているかもしれませんが、私が何が起こっていたのかを説明しようとします。
まず、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
カーネルのコードパスは大体これです:
ここにはいくつか興味深い点があります。
まず、行691はadjtimex(2)が呼び出されるたびに既存のタイマーをキャンセルします。次に、554はそのタイマーを再作成します。これは、ntpdがクロックループフィルターを実行するたびに、バグのあるコードが呼び出されたことを意味します。
したがって、ntpdがうるう秒フラグを設定するとシステムはクラッシュしないと彼らが言ったとき、私はRed Hatが間違っていたと思います。 ntpdを実行している各システムには、うるう秒の前の24時間、17分(またはそれ以上)ごとにライブロックする可能性があったと思います。これは、多くのシステムがクラッシュした理由も説明していると思います。 1回のクラッシュのチャンスは、1時間に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を取得する機会が増えます。
3番目に、うるう秒が実際に発生したときにシステムがクラッシュする可能性はありますか?はっきりとはわかりませんが、おそらく可能性があります。うるう秒の調整を起動して実際に実行するタイマー(ntp_leap_second、行388)もntp_lockスピンロックを取得し、hrtimer_add_expires_nsを呼び出しているためです。その呼び出しでライブロックが発生する可能性があるかどうかはわかりませんが、不可能ではないようです。
最後に、うるう秒の実行後にうるう秒フラグが無効になる原因は何ですか? ntpdがadjtimex(2)を呼び出す真夜中の後のある時点でうるう秒フラグの設定を停止するという答えがあります。フラグが設定されていないため、行554のチェックはtrueにならず、タイマーは作成されず、行598はtime_stateグローバル変数をTIME_OKにリセットします。これは、うるう秒の直後にadjtimex(8)でフラグをチェックした場合でも、うるう秒フラグが設定されているのがわかる理由を説明しています。
要するに、今日の最良のアドバイスは、結局最初に私が与えた最初のようです:ntpdを無効にし、うるう秒フラグを無効にします。
そしていくつかの最終的な考え:
06/02 John Stultzからの更新:
https://lkml.org/lkml/2012/7/1/2
投稿には、うるう秒によってfutexタイマーが時期尚早かつ継続的に期限切れになり、CPU負荷が急上昇した理由の段階的なウォークスルーが含まれていました。
これは私たちに大きな打撃を与えました。多くのホストを再起動した後、ホストの再起動を行わなくても、以下は非常にシンプルで完全に効果的であることがわかりました。
/etc/init.d/ntp stop
ntpdate 0.us.pool.ntp.org
/etc/init.d/ntp start
必要なのは、システムクロックをリセットすることだけです。シーッシュ。 6時間前に私がこれを知っているために私が与えたもの。
カーネルの時間ステータスフィールドのうるう秒ビットをクリアする単純な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
でコンパイルして、ルートとして実行します。
Ntpdを実行する前に停止し、うるう秒の後でntpdを再起動する必要があるでしょう。
死後は./lsecは効果がないようです。
多くのsoftirqdプロセスがCPUを消費しています(通常、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
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でカーネルがクラッシュする可能性があります。」