/* Top > Note > 132

Raspberry Pi(ラズベリーパイ)で秋月のリアルタイムクロックRTC-8564NBをバックアップ回路付きで使う

公開日:2017/07/30(日)
以下の内容は、Raspbian GNU/Linux 8 (jessie)をインストールしたRaspberry Pi 3 Model Bでの使用を前提にしています
Raspberry Piは普通のPCと違い、リアルタイムクロック(以下、RTCと言います)が 実装されていません。 ちなみに、リアルタイムクロック(RTC)とは、装置の電源を切ってもリセットされない ハードウェア内の時計です。現在日時を保持し続けるために、 通常は電池などのバッテリーや待機電力などによって電力が供給されています。 詳しくはwikipediaをご覧ください。 Raspberry Piにはこの仕組みがないため、電源を切ると日時情報を 保持することができません。 Raspberry Piがインターネットに接続できる環境であれば 起動時の処理でntpがntpサーバーから正確な日時を取得して 正しい日時を設定してくれるので特に問題はありません。 ですが、インターネットに接続できない環境(以下、オフライン環境と言います) で起動すると、ntpがntpサーバーから日時情報を取得できないので Raspberry Piは現在の日時がわかりません。 この対応として、Raspberry Piには fake-hwclock というパッケージが 最初からインストールされています。 fake-hwclock のパッケージ情報 [表示 / 非表示] fake-hwclock のマニュアル(英語) [表示 / 非表示] このパッケージは、1時間おきとシステムがシャットダウンされたときに ファイル /etc/fake-hwclock.data にその時の日時を書き出しており、 起動時のntpdによる時刻合わせに失敗したとき このファイルに書かれた日時を読み込んでRaspberry Piの システムクロックを設定するという働きをしています。 オフライン環境でRaspberry Piを起動すると、前回シャットダウンされた日時が 起動の日時として設定されているのはこのためです。 そんな働きをしているので fake-hwclock パッケージを削除したり無効にして オフライン環境でRaspberry Piを起動すると 日時が 1970年01月01日(木)09:00:00 JST に設定さます。 用途にもよると思いますが、自分は今のところRaspberry Piをオフライン環境で 使うことが多く、起動のたびに時計を見ながら毎回手動で時刻を合わせていました。 (システムクロックを手動で設定する例) ※ 2017年07月30日(日) 15時30分00秒 にセットする場合
$ sudo date -s '2017-07-30 15:30:00'
※ あらかじめコマンドをタイプしておき、時計を見ながらその時刻になった瞬間にエンター。 毎回これをやるのはめんどくさいですし、コマンドを手動入力すると 間違うリスクもあるのでなんとかしたいなーと思っていました。 そこでRTCに行き着いたわけでございます。 一言にRTCといってもけっこう種類がありまして "raspberry pi rtc" をGoogleで検索すると DS3231やDS1307を使った例が多く見つかります。 ただ、今回用意した(というか、だいぶ前に買った)RTCは秋月電子通商RTC-8564NBというもので Raspberry Piでの使用例が上の製品と比べると若干少ないものでした。 (なんでそんなの買ったの?とツッコミたくなるかもしれませんが 入手性と予算の都合と秋月で一番売れてるRTCだったのと 個人的に時計といえばセイコーエプソンというイメージが強かったからです) でも、この記事 によると、Raspberry Piでも動作することは確認できていたのでこれを実装することにしました。 ただ、それにはひとつ問題があって、このRTCにはバッテリーによる バックアップ機構がないので、単純に実装しても結局Raspberry Piの電源を切ると RTCへの電力も絶たれて日時情報を保持できないのです。 単純に接続した例 ラズベリーパイのGPIOと単純に接続したRTC-8564NBの画像 (これではRaspberry Piの電源が入っている間は日時情報を保持できるが Raspberry Piの電源が切れるとGPIOからRTCへの電流も止まるので日時情報が消えてしまう) なのでRaspberry Piの電源を切っても時刻情報を保持できるようにするための バックアップ機構を自分で用意しないとなりません。 バックアップ回路についてはさっきのマイナビの記事にもさらっとしか書いてありませんし ググれば何かしら出てくるだろうと思ったら Raspberry Piで、RTC-8564NBを使い、電池でバックアップ回路も実装している例は なかなか見つかりませんでした。 とはいえ、せっかく買ったものを使わないのはもったいないですし 必ず答えがあるはずなので、この辺を参考に作ってみました。 (別のマイコンでRTC-8564NBを使っている例ですが、充分参考になります)

部品の用意

RTC-8564NBは完成品なので半田付けは必要ありません。 (基板上に半田ジャンパが3つありますが、今回はどれも使いません) 1S4整流用ショットキーダイオードというものを2個使っていますが、 参考にした回路図がそうなっていただけで、他のダイオードでも代用はできるみたいです。

配線

こんな感じで配線しました。 ラズベリーパイとRTC-8564NBの配線図 Fritzingのパーツ RTC-8564NB:リアルタイムクロックモジュール(I2C) は 無料ダウンロード:Fritzing 部品一覧 のものを使わせていただきました。作成者様に感謝します。 実際の配線 ラズベリーパイのGPIOと実際に接続したRTC-8564NBの画像1 ミニブレッドボードに収めたのと、ケーブルを横一直線に並べたかったので 上の配線図とちょっと配線を変えていますが回路的には一緒です。 ジャンパーワイヤの一部が基盤に隠れてわかりにくくなっていますが 実際にはこんな風につながっています。 ラズベリーパイのGPIOと実際に接続したRTC-8564NBの画像2

回路図

配線図だとなんだかわかりにくいですが、回路図にすると とてもシンプルです。ただ、回路図書いたのは初めてなので間違ってたらすみません。 回路を作成するにあたり、助言をいただいた、さかじさんにこの場を借りてお礼申し上げます。 どうもありがとうございました。また何か聞きに行くと思いますのでよろしくお願いします。 ラズベリーパイとRTC-8564NBの回路図

Raspberry Piの設定1 (RTCに現在日時を設定)

このRTCも他のセンサーのときと同様I2Cインターフェースで接続するので Raspberry Piの設定からI2Cインターフェースを有効にします。 一度有効にすると無効にしない限りずっと有効なので、以前有効にした場合は確認だけでOKです。 Raspberry Pi の設定 インターフェイスのタブの画像 RTCはGPIOにつないだだけでは動作しません。 OSからI2Cで接続されたハードウェアクロックデバイスとして 認識されるための作業が必要です。 そもそも、RTCの初回起動時は日時情報が保存されていないので これもセットする必要があります。 【 RTCに現在の日時を書き込む手順 】
  1. i2cdetectコマンドでI2Cアドレスの0x51から応答があることを確認します。 (--と表示された場合は配線や接続ミスなどが考えられます。 場合によっては51の部分にUUと表示されることがありますがUUでも問題ありません。)
    $ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
    参考(i2cdetectコマンドのマニュアルより抜粋)
    "--". The address was probed but no chip answered.
    // アドレスを調査したがチップからの応答は無かった。
    "UU". Probing was skipped, because this address is currently in use by a driver. This strongly suggests that there is a chip at this address.
    // 調査はスキップされた。なぜなら、このアドレスは現在ドライバによって使用中である。 // これは、そのアドレスにチップがあることを強く示している。
    An address number in hexadecimal, e.g. "2d" or "4e". A chip was found at this address.
    // アドレスに16進数値、たとえば "2d" や "4e" などが表示されていると // そのアドレスにチップが見つかったことを表す。 // 緑色の行は自分が適当に訳した文章なので、あまり信用しないでください。
  2. RTCのドライバを探します。
    $ ls -l /lib/modules/$(uname -r)/kernel/drivers/rtc/ 合計 424 -rw-r--r-- 1 root root 16520 mm月 dd hh:ss rtc-abx80x.ko -rw-r--r-- 1 root root 8700 mm月 dd hh:ss rtc-bq32k.ko -rw-r--r-- 1 root root 8400 mm月 dd hh:ss rtc-ds1302.ko -rw-r--r-- 1 root root 13208 mm月 dd hh:ss rtc-ds1305.ko -rw-r--r-- 1 root root 25108 mm月 dd hh:ss rtc-ds1307.ko -rw-r--r-- 1 root root 11584 mm月 dd hh:ss rtc-ds1374.ko -rw-r--r-- 1 root root 8288 mm月 dd hh:ss rtc-ds1390.ko -rw-r--r-- 1 root root 8180 mm月 dd hh:ss rtc-ds1672.ko -rw-r--r-- 1 root root 12780 mm月 dd hh:ss rtc-ds3232.ko -rw-r--r-- 1 root root 7580 mm月 dd hh:ss rtc-em3027.ko -rw-r--r-- 1 root root 9932 mm月 dd hh:ss rtc-fm3130.ko -rw-r--r-- 1 root root 9204 mm月 dd hh:ss rtc-isl12022.ko -rw-r--r-- 1 root root 16548 mm月 dd hh:ss rtc-isl1208.ko -rw-r--r-- 1 root root 14680 mm月 dd hh:ss rtc-m41t80.ko -rw-r--r-- 1 root root 8628 mm月 dd hh:ss rtc-m41t93.ko -rw-r--r-- 1 root root 7844 mm月 dd hh:ss rtc-m41t94.ko -rw-r--r-- 1 root root 7644 mm月 dd hh:ss rtc-max6900.ko -rw-r--r-- 1 root root 6920 mm月 dd hh:ss rtc-max6902.ko -rw-r--r-- 1 root root 10772 mm月 dd hh:ss rtc-pcf2123.ko -rw-r--r-- 1 root root 12988 mm月 dd hh:ss rtc-pcf2127.ko -rw-r--r-- 1 root root 8592 mm月 dd hh:ss rtc-pcf8523.ko -rw-r--r-- 1 root root 13984 mm月 dd hh:ss rtc-pcf8563.ko -rw-r--r-- 1 root root 7912 mm月 dd hh:ss rtc-pcf8583.ko -rw-r--r-- 1 root root 7960 mm月 dd hh:ss rtc-r9701.ko -rw-r--r-- 1 root root 8228 mm月 dd hh:ss rtc-rs5c348.ko -rw-r--r-- 1 root root 12840 mm月 dd hh:ss rtc-rs5c372.ko -rw-r--r-- 1 root root 17380 mm月 dd hh:ss rtc-rv3029c2.ko -rw-r--r-- 1 root root 8432 mm月 dd hh:ss rtc-rx4581.ko -rw-r--r-- 1 root root 12076 mm月 dd hh:ss rtc-rx8025.ko -rw-r--r-- 1 root root 9236 mm月 dd hh:ss rtc-rx8581.ko -rw-r--r-- 1 root root 10092 mm月 dd hh:ss rtc-s35390a.ko -rw-r--r-- 1 root root 13784 mm月 dd hh:ss rtc-x1205.ko
    このなかに"rtc-8563nb.ko"というのがあれば それをそのまま使えば良いのですが、残念ながらありません。
  3. しかし、"rtc-pcf8563.ko"を使えばRTC-8564NBも動かせることが さっきのマイナビの記事でわかっているので"rtc-pcf8563.ko"をロードします。
    $ sudo su # modprobe rtc-pcf8563
    エラーが表示されなければOKです。
  4. ドライバがロードされたことを確認します。
    # lsmod | grep rtc rtc_pcf8563 7056 0
    rtc_pcf8563の行が表示されればOKです。
  5. RTCをI2Cのデバイスとして追加します。
    # echo pcf8563 0x51 > /sys/class/i2c-adapter/i2c-1/new_device
    エラーが表示されなければOKです。
  6. RTCがOSからデバイスファイル /dev/rtc0 として認識されていることを確認します。
    # ls -l /dev/rtc* lrwxrwxrwx 1 root root 4 mm月 dd hh:mm /dev/rtc -> rtc0 crw------- 1 root root 253, 0 mm月 dd hh:mm /dev/rtc0
    /dev/rtc0が表示されればOKです。
  7. Raspberry Piの現在の日時(システムクロック)が正確であることを確認します。
    # date yyyy年 mm月 dd日 *曜日 hh:mm:ss JST
    日時が正しければOKです。 日時が正確でない場合は手動で合わせるか、ネットに接続してNTPに補正されるまで待ちます。
  8. RTCにRaspberry Piの現在の日時(システムクロック)を書き込みます。
    # hwclock --systohc hwclock: ioctl(RTC_RD_TIME) to /dev/rtc to read the time failed: 無効な引数です
    こんなメッセージが出て失敗したかのように見えることがありますが 実はちゃんとRTCに日時が書き込まれています。 ntpdを無効化するとこのメッセージは出なくなります。 ちなみに、hwclock --systohc は hwclock -w と同じ意味です。 (1文字だとタイプミスしたときの影響が大きいので、あえて長い方を使っています)
  9. RTCの日時を確認します。
    # hwclock --show yyyy年mm月dd日 hh時mm分ss秒 -n.nnnnnn seconds
    dataコマンドと比較して日時がズレていなければOKです。 (1〜3秒くらいの誤差が出ることがありますが、ハードウェアクロックは 元々そんなに正確なものじゃないのであまり気にしない方が良いです。)
  10. rootからexitします。
    # exit $
    これでRTCへ日時を書き込む手順は終わりです。

Raspberry Piの設定2 (デーモンの無効化とntpdateのインストール)

あとは電池が切れたり配線が外したりしない限りRTCに現在の日時情報が保持されています。 という動きにしたいので、スクリプトを作って起動時に実行されるようにします。 ntpdateを実行して成功すればRTCの日時も更新する、 失敗すればRTCの日時でシステムクロックを更新する、 という方法が一番シンプルかな、と思ったのですが、 ntpdateはデフォルトではインストールされていないので 追加でインストールが必要です。 パッケージの追加や削除はできるだけ避けたい、 と最初は考えていましたが、いろいろ試した結果 既存の状態では難しいことがわかりました。 なぜなら、シャットダウンしてしばらくしてから起動してみると、 システムクロックもRTCもシャットダウンした時刻に戻ってしまうのです。 調べてみると、別のRTCの例ですが Raspberry PiにRTCを実装したら fake-hwclock を(場合によってはntpdも)無効にしないと 悪さをする(RTCの方が正しい日時だとしてもシステムクロックで上書きしてしまう)ようです。 fake-hwclock を無効にしてみました。
$ sudo update-rc.d fake-hwclock disable insserv: warning: current start runlevel(s) (empty) of script `fake-hwclock' overrides LSB defaults (S). insserv: warning: current stop runlevel(s) (0 1 6 S) of script `fake-hwclock' overrides LSB defaults (0 1 6).
参考 : update-rc.d のマニュアル(英語) [表示 / 非表示] そしてさっきの手順で再度RTCに現在の日時を書き込みました。 それから再起動してみると、 fake-hwclock が動作していないので システムクロックは 1970年01月01日(木)09:00:00 JST にタイムスリップします。 システムクロックは1970年でもRTCは現在の日時のはず、と思ったら RTCの日時も 1970年01月01日(木)09:00:00 JST になってました…。 もう犯人は ntpd しか思い付かないので ntpd も無効にしました。
$ sudo update-rc.d ntp disable insserv: warning: current start runlevel(s) (empty) of script `ntp' overrides LSB defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (2 3 4 5) of script `ntp' overrides LSB defaults (empty).
そしてまたさっきの手順で再度RTCに現在の日時を書き込みました。 再起動してみると、 fake-hwclock が動作していないので システムクロックは 1970年01月01日(木)09:00:00 JST になるのは同じです。 でもRTCは現在の日時のはず、と祈るように確認したら 願いが通じたのかRTCは現在の日時を刻んでいました。 どうもntpdが動いているとRTCの日時より システムクロックの方が優先されるようです。 そしてシステムクロックの日時でRTCの日時が更新されるという動き。 これで邪魔者がいなくなったので あとはスクリプトにして起動時に自動実行されるようにするだけです。 ただ、RTCはそれほど正確ではなく、電池で動いているので 電池がなくなれば日時情報も消えてしまいます。 ntpdは無効にしましたが、ネットに接続できるときはやっぱりNTPで 正確な日時を設定したいものです。そのときついでにRTCの日時もNTPで取得した日時に 更新してやればRTCの時間のズレもそれほど大きくなりません。 というわけで、さっき上の方で「パッケージの追加や削除はできるだけ避けたい」 とか書いておきながら、あっさり方針転換して ntpdate をインストールします。
$ sudo apt-get install ntpdate パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下の追加パッケージがインストールされます: lockfile-progs 以下のパッケージが新たにインストールされます: lockfile-progs ntpdate # 以下省略 #
ntpdate のパッケージ情報 [表示 / 非表示] ntpdate のマニュアル(英語) [表示 / 非表示]

スクリプトの用意

当初の予定(?)どおり というスクリプトを作りました。 こんな感じです。setsysclock.sh [表示 / 非表示] NTPサーバーは NICT 国立研究開発法人 情報通信研究機構 のものを使わせていただきました。 (stratum1ですが個人で利用してもOKらしいです) 本人じゃないと、何してるのかわからない感満載の 酷いコードですが、やってること最初に書いたようにわりと単純です。
  1. ntpdateを実行、失敗したら3秒待って再度ntpdateを実行を最大5回繰り返す。
  2. ntpdateが成功したらシステムクロックが正しい時間に更新されるので それをRTCにも書き込む。
  3. ntpdateが一度も成功しなかったらRTCの日時でシステムクロックを更新する。
残りの部分はRTCを使うための各種確認やデバイスの追加/削除、 カーネルモジュールをロード/アンロードをしたりしてるだけです。 手動でやるとしたらこんな感じになります。
$ sudo su # ntpdate -bv ntp.nict.jp # この結果を覚えておく # modprobe rtc-pcf8563 # echo pcf8563 0x51 > /sys/class/i2c-adapter/i2c-1/new_device # ntpdateが成功したら # hwclock --systohc # システムクロックの日時でRTCを更新する # ntpdateが失敗したら # hwclock --hctosys # RTCの日時でシステムクロックを更新する # echo 0x51 > /sys/class/i2c-adapter/i2c-1/delete_device # I2C-RTCデバイスの削除(やらなくても問題なし) # modprobe -r rtc_pcf8563 # カーネルモジュールのアンロード(やらなくても問題なし) # exit $
あとは作ったスクリプトファイルのパーミッションを実行可にして
$ chmod 774 ./setsysclock.sh
オーナーを root に変更して
$ sudo chown root:root ./setsysclock.sh
/usr/local/bin に配置して (他の場所でも問題ないとは思いますが)
$ sudo cp -ip ./setsysclock.sh /usr/local/bin
/etc/rc.local を一応バックアップして
$ sudo cp -ip /etc/rc.local /etc/rc.local-bkup`date '+%Y%m%d'` $ ls -l /etc/rc.local* -rwxr-xr-x 1 root root 420 mm月 dd yyyy /etc/rc.local -rwxr-xr-x 1 root root 420 mm月 dd yyyy /etc/rc.local-bkupyyyymmdd
/etc/rc.local を編集して
$ sudo nano /etc/rc.local #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi
# set system-clock script /usr/local/bin/setsysclock.sh &
exit 0
青字の部分を追加して保存します。 一応、差分を見て変な所を編集してないか確認します。
$ diff /etc/rc.local /etc/rc.local-bkupyyyymmdd nn,nndnn < # set system-clock < /usr/local/bin/setsysclock.sh &
これで次回起動時から ntpdate が使えるときは ntpdate で 使えないときはRTCの日時でシステムクロックの設定が自動で行われます。 オフライン環境で電源入れてもOSには正しい日時が設定されます。

失敗事例集

実は私、電子工作の素人です。小学生の頃に電子工作キットを8個くらい 作ったことがあるので、半田ごてを使うことには全く抵抗ないのですが、 回路の設計とか実装の知識はさっぱりです。 当然、今回も最初からうまくいった訳ではなく、数々の失敗がありました。 そのなかでもこれをやったらヤバイというものがあったので ダメな例としてご紹介したいと思います。

回路編

まず、最初からRaspberry Piの電源(+3.3V)と電池を単純に RTCへつなぎっぱなしにすればいいじゃん、というド素人の発想です。 注意!! これは絶対マネしないでください。故障しても知りませんよ。 ラズベリーパイとRTC-8564NBのダメな配線図1 Raspberry Piの電源が入っていない(コンセントにもつないでいない)状態で この配線をすると、電池からRTCの他にRaspberry PiのGPIO側に電流が流れ なんと、Raspberry Piの電源が入りOSが起動し始めました。(電池1個で) うちのRaspberry Piは普段テレビに接続しているので、 テレビのHDMI連動機能でテレビの電源も入り、さらにテレビと連動して 録画用のHDDの電源まで入るという驚きの展開に!! すぐに電池を外して電源を切りましたけど Raspberry Pi的にかなりのイレギュラーな事態なので止めておいた方がいいです。 ちなみに、一瞬だけだったからかもしれませんが、 こんな使い方をしてもRaspberry Piは壊れませんでした。 元は教育目的で作られたものなので、子供が変な使い方をしても 簡単には壊れないよう頑丈に設計されているのかもしれません。 ファミコンだかゲームボーイでもそんなエピソードありましたよね。 ともかく、これによりダイオードの重要性に気付いたわけです。 次に、Raspberry Piの電源(+3.3V)を使わずに電池だけRTCに つなげればいいじゃん、というド素人の発想その2です。 ラズベリーパイとRTC-8564NBのダメな配線図2
$ i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
i2cdetectコマンドでデバイスが検出されなかったのでボツ。

Raspberry Piの設定編

RTCがRaspberry Piに追加され、正しい日時情報を持っていたとしても fake-hwclock と ntpd が動いていると、どんなにRTCの日時が正しかろうと 何もしなくても5分くらいで勝手にシステムクロックでRTCが上書きされてしまいます。 最初はRTCの日時が勝手に変更されてしまう現象の原因が分からず、頭を抱えました。 原因は上に書いたとおり fake-hwclock と ntpd です。 setsysclock.sh スクリプトも、hwclock --hctosys または --systohc が 終わった後すぐに /dev/rtc0 を削除してカーネルモジュールも アンロードしているのはシステム側からRTCに変なことをされないよう守るためです。

スクリプト編

piユーザーでログインしてから setsysclock.sh スクリプトを実行すると 期待通りの動きをするのですが /etc/rc.local からこのスクリプトを実行しても ntpdate がどうしても失敗してしまいます。 /var/log/boot.log の一部
1 Jan 09:00:07 ntpdate[625]: ntpdate 4.2.6p5@1.2349-o Mon Jul 25 22:35:35 UTC 2016 (1) Error resolving ntp.nict.jp: Name or service not known (-2) 1 Jan 09:00:07 ntpdate[625]: Can't find host ntp.nict.jp: Name or service not known (-2) 1 Jan 09:00:07 ntpdate[625]: no servers can be used, exiting
ネットに接続されたオンライン状態にもかかわらず ntpdate が失敗しています。なのでRTCの日時がシステムクロックにセットされています。 なんだか名前解決ができてないような感じのメッセージだったので piユーザーでログインしてからNTPサーバーのドメイン名で ping を打ってみました。
$ ping -c 4 ntp.nict.jp PING ntp.nict.jp (133.243.238.163) 56(84) bytes of data. 64 bytes from ntp.nict.jp (133.243.238.163): icmp_seq=1 ttl=44 time=19.3 ms 64 bytes from ntp.nict.jp (133.243.238.163): icmp_seq=2 ttl=44 time=18.3 ms 64 bytes from ntp.nict.jp (133.243.238.163): icmp_seq=3 ttl=44 time=18.6 ms 64 bytes from ntp.nict.jp (133.243.238.163): icmp_seq=4 ttl=44 time=18.7 ms --- ntp.nict.jp ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 18.304/18.767/19.335/0.405 ms
普通に応答が返ってくるのでログイン後は名前解決も疎通もできています。 スクリプトのNTPサーバーをドメイン名ではなく直接IPアドレスを指定してみました。
$ sudo nano /usr/local/bin/setsysclock.sh $ diff ./setsysclock.sh /usr/local/bin/setsysclock.sh 7c7 < NTP_SOURCE_SERVER='ntp.nict.jp' # NTP source server --- > NTP_SOURCE_SERVER='133.243.238.163' # NTP source server
で、もう一回再起動してみた結果がこれ。 /var/log/boot.log の一部
1 Jan 09:00:07 ntpdate[666]: ntpdate 4.2.6p5@1.2349-o Mon Jul 25 22:35:35 UTC 2016 (1) 1 Jan 09:00:07 ntpdate[666]: no servers can be used, exiting
やっぱりダメでした。 syslog や dmesg を見る限り、通信の準備ができる前に /etc/rc.local が動いているようで、その結果 ntpdate が失敗したように見えます。 試しに、 setsysclock.sh スクリプトの初めに sleep 15 と入れて スクリプトが動いてから15秒後に ntpdate が実行さるようにすると 普通に ntpdate は成功しました。ようは実行タイミングの問題だったようです。 スクリプトの中で ntpdate を3秒間隔で最大5回ループさせているのは そのためです。ネットに接続された状態なら、最初の1回目は失敗しても 3秒待ってまた実行を最大5回も繰り返せばほぼ間違いなく成功します。
< Return */