ntp で時計合わせをするのは、UNIX では普通のことで、当然 Mac OS X もその機能を持っている。「システム環境設定」の「日付と時刻」パネルには、そのものずばりの設定のためチェックボックスとドロップダウンリストがある。アップルがプリセットしているドロップダウンリストから適当な ntp サーバを選んで、「日付と時刻を自動的に設定」にチェックを入れれば、次の瞬間から時刻の同期が始まるようになっていて、非常に簡単。
さて、特に PowerBook や MacBook、MacBook Pro を頻繁に移動しながら使っていると、当然ネットワーク環境も場所ごとに異なってくる。IP アドレスや DNS、デフォルトルートなどは、普通 PPP の機能や DHCP によって適切に保たれることになっている。でも、ntpd は起動時に設定されていた IP アドレスをそのまま使おうとしてしまうので、ネットワーク環境が変化すると時刻の同期が行われなくなってしまう。ネットワーク環境自体は、アップルメニューから「自動」にしておけば、移動後にもなにもしなくても問題ないのだけれど、時刻同期を再開するためには「システム環境設定」を開いて「日付と時刻を自動的に設定」のチェックを外してまた入れ直すことになる。チェックのオン・オフについては、AppleScript と System Events.app を使えば(あるいは SystemStartar を使えば)自動化できるのだけれど、そもそもネットワーク環境の変化を検知してなんらかのアクションを起こす方法がなかなか見あたらなかった。
でも、ネットワーク環境やらなんやらに変化があったときに、Mac OS X はなにかしているようだし、方法がないはずないというわけで、調べてみたらなんとか見付けることができた。
どうやら configd を使えばなんとかなるみたい。
リンク先を読めば分かるけど、Bundle の中のファイルをいじったりするのであまりいい方法ではないのだろうけど、システムのアップデート時などに注意しておけばそれほど問題になることもないだろう。もちろん、将来に渡って同じ方法が通用する保証はないし、これによってなんらかの損害を被ったとしてもそれは自己責任ということになる。
では、具体的なやりかたを簡単に。
rok %pushd /System/Library/SystemConfiguration/Kicker.bundle/Contents/Resources/
rok % sudo vim Kicker.xml (*1)
rok % sudo cat <<EOF > /usr/local/bin/restart-ntpd
#!/bin/sh
(sleep 10; /sbin/SystemStarter restart 'Network Time') > /dev/null 2>&1
EOF
rok % sudo chmod +x /usr/local/bin/restart-ntpd
rok % sudo killall configd; sudo /usr/sbin/configd
(*1) では、ファイルの中身の構造に合わせて以下の断片を追加する。
<dict>
<key>execCommand</key>
<string>/usr/local/bin/restart-ntpd</string>
<key>execUID</key>
<integer>0</integer>
<key>keys</key>
<array>
<string>State:/Network/Global/IPv4</string>
</array>
<key>name</key>
<string>restart-ntpd</string>
</dict>
これで、IP アドレスが変わったときに自動で ntpd が再起動するようになるはず。この記事を見て試してみようという奇特な方は、あくまで自己責任であるとうことを了承してくださいますように。上の手順を見てわけが分からない人はやらない方がいい。
本当は自前で configd のための Bundle を用意するかconfigd の Kicker.bundle でポストするように設定されている com.apple.system.config.network_change なる Notification を受け取る daemon を書くのがいいんだろうけど、そこまでやる気力もプログラミング力もないなぁ。