ntpd ばたばた日記

REPORT

ntpd がよく落ちる…。

ということで daemontools で ntpd を維持しようとしたところ、なかなかうまく行かずに格闘してしまいました。


ntpd が停止する

Linux で時刻を調整および提供する ntpd ですが、なんだか気が付くと落ちているなんてことが何度かありました。

時刻を自動的に同期させているつもりだったのに、肝心の ntpd が落ちているのでは話になりません。

ということで、落ちないようにと試行してみたところ、ちょっとばかりトラブル発生でした。

 

daemontools を使ってみる

落ちないといえば、D. J. Bernstein さんの daemontools

常駐する svscan というプログラムのおかげで、もし停止してしまってもまたプロセスをあげてくれるのでなにかと安心です。

いったん daemontools をインストールしてしまえば、あとは run スクリプトを用意して、/service/ ディレクトリに run スクリプトのあるディレクトリへのシンボリックリンクを張るだけ。

 

ということで、とりあえず次のような run スクリプトを、/etc/ntpd/ ディレクトリに作成しました。あまり daemontools のことを詳しく知らないので、もしかしたらここが間違っていたのかもしれません。

#!/bin/sh

exec /usr/local/bin/ntpd

svscan のための run スクリプトは、exec 命令を使ってプロセスを生成する必要がある、ということなので、単純に exec 命令をつかって ntpd を起動させるスクリプトを書いてみました。

そしてさっそく、次のようにして ntpd を起動してみます。

ln -s /etc/ntpd /service/ntpd

 

するとしばらくして、正常に ls 命令やら cat 命令やら su 命令やら、いろんなコマンドを実行するたびに、「これ以上ファイルが開けません」 というようなメッセージが表示されてしまい、どうすることもできなくなってしまいました。

exit はできますが login はできません…。

 

これは推測ですけど、ntpd を立ち上げてもなんらかの影響で ntpd のプロセスを svscan が把握することができなくなっているのではないでしょうか。

そのため、svscan は ntpd が落ちているものと思って、ふたたび ntpd を立ち上げようとする…。なんだかその繰り返しで、ntpd がたくさん開いてしまったのが原因のように思います。

 

復旧させる

ntpd を停止させる

さて、再起動したところですぐに svscan が ntpd を起動してくれますので、復旧するには何とかして /service/ntpd というシンボリックリンクを削除しなくてはなりません。

ということで、素直に rm で削除したいところなのですけど、ファイルを開けないということでだめでした。ほかにも echo を使ってリダイレクトしてみたりもしましたが、やっぱりだめでした。

 

こうなると、Slackware のインストール CD をつかって、インストール用の Slackware を起動して、そこで直すしかなさそうです。

ということで、CD-ROM ドライブに Slackware 8 のインストール CD を入れて、いざ reboot 命令にて再起動しようと、コンソールからログインしようとしたところ、シェルの起動に失敗してしまい、ログインすることができませんでした。

 

幸い、Slackware の場合、ディフォルトで Ctrl+Alt+Del によって再起動プロセスを呼び出すことができるので、それを試してみることにしました。

Ctrl+Alt+Del を押すと Slackware は再起動プロセスに入ります。が、それもすぐにうまく行かないことが判明です。なんだか、プロセスの停止にうまく答えられないアプリケーションがあるようです。

仕方がないので、電源を落としてしまうことにしました。

 

daemontools から ntpd を起動しないようにする

まず、Slackware 8 のインストール CD を使って、インストール用の Slackware を起動します。

そして、先ほどまで動いていた Linux の root ドライブである /dev/hda2 を、次のようにしてとりあえず /cdrom ディレクトリへマウントさせました。

mount /dev/hda2 /cdrom

 

そうしたら後は簡単です。

/cdrom/ ディレクトリを一番上とみたてて、肝心の /service/ ディレクトリにある ntpd というシンボリックリンクを削除するだけです。

rm /cdrom/service/ntpd

これで、実際は /service/ ディレクトリにある ntpd というシンボリックリンクが削除されたわけですから、あとは通常通りに Linux を起動しても、ntpd が svscan によって起動されることはなくなりました。

これで、とりあえず復旧完了です。

 

ntpd が落ちるわけ

なぜ ntpd がよく落ちるのか…。幸い (?) 起動させてもすぐに落ちてしまう環境があったので調べてみることにしました。

ntpd -l /var/log/ntp.log みたいにして、ログを /var/log/ntp.log に出力してみると、すぐに理由がわかりました。エラーの最後の方には次のような部分がありました。

 

26 May 13:07:39 ntpd[921]: logging to file /etc/ntpd/ntp.log

26 May 13:07:39 ntpd[921]: ntpd 4.0.99k Tue Feb 6 19:49:33 JST 2001 (1)

26 May 13:07:39 ntpd[921]: signal_no_reset: signal 13 had flags 4000000

26 May 13:07:39 ntpd[921]: set_process_priority: priority_done is <2>

26 May 13:07:39 ntpd[921]: precision = 10 usec

26 May 13:07:39 ntpd[921]: kern_enable is 1

26 May 13:07:39 ntpd[921]: using kernel phase-lock loop 0041

26 May 13:07:39 ntpd[921]: frequency initialized 0.000 from /etc/ntpd/ntp.drift

26 May 13:07:39 ntpd[921]: using kernel phase-lock loop 0041

26 May 13:11:10 ntpd[921]: time error 444615 over 1000 seconds; set clock manually

どうやらこれから察するに、ntpd は、自身の時刻が 1000 秒以上の開きがあると、ntpd はその役割を終えてしまうようです。しばらくしてから落ちるのは、タイムサーバへ時刻の問い合わせをしているせいなのでしょう…。

たしかに、あまりにも時刻がずれてしまっていると、そのタイムサーバを信頼していいものか不安にもなります。…、単純に、自分のコンピュータの時刻がずれすぎているだけなのですけどね。

 

時刻を合わせるソフトウェアに時刻が合っていないためにとめられてしまうというのはなんとも盲点でした。

最初に ntpdate コマンドを使って時刻を合わせてから、ntpd を走らせて見たところ、今度はどうやらちゃんと安定して動いてくれているようでした。

 

ntpd を daemontools で走らせる

いろいろと調べてみるうちに、daemontools で動かすためには、そのデーモンがフォアグラウンドで起動している必要があるそうです。

そして、ntpd も 4.0.99k23 なら -d オプションをつけることでフォアグラウンドで動くとのことです。さっそく ntpd -d として ntpd を起動してみると、なにやら文字列がいっぱい表示され、そして ntpd はフォアグラウンドでの起動を維持していることがわかります。

 

さっそく、/etc/ntpd/ ディレクトリを用意して、次のような起動スクリプトを書いてみます。

#!/bin/sh

exec /usr/local/bin/ntpd -d

これを /etc/ntpd/run として保存します。

ついでにログをとるために log/ ディレクトリを作成して、また、/etc/ntpd/ ディレクトリ自身も chmod +t しておきます。

mkdir /etc/ntpd/log

chmod +t /etc/ntpd

そしてこの log/ ディレクトリにも、次のような run スクリプトを用意します。

#!/bin/sh

exec multilog -t ./main

あとは chmod +x をつかって /etc/ntpd/run と /etc/ntpd/log/run の両方に実行権限をつければ準備完了です。そうしたら /service/ ディレクトリへ /etc/ntpd へのシンボリックリンクを張って、ntpd を起動させます。

chmod +x /etc/ntpd/run /etc/ntpd/log/run

ln -s /etc/ntpd /service/

 

これで daemontools を使って ntpd を起動させることができました。ただ、ntpd の落ちる原因がわかった以上、そこまで daemontools にこだわる必要はなさそうですね。

 

1000 秒以上の開きがあっても ntpd を停止させないようにするには

それからだいぶたったある日のこと、ntp 4.2.0 をインストールしていたら、オプションに "-g" というものがあることに気づきました。

なんでもこの "-g" オプションをつけて ntpd を起動すると、1000 秒以上の開きがあってもプロセスを終了するようなことはしないのだとか…。さっそく数時間以上狂っているサーバで試しに "-g" オプションをつけて ntpd を起動してみたところ、同期が行われて正常に時刻が調整されました。

これなら、わざわざ 1000 秒の遅れで停止させることもないでしょうし、"-g" をつけて起動しておくと良さそうです。