Debianのntpdでのslewモード

■ntpdの日本語マニュアルについては、以下が詳しい。

 参考:ntpd
 http://www.asahi-net.or.jp/~aa4t-nngk/ntpd.html

■STEPモードとSLEWモードについては以下にも書いた。

 うるう秒のSTEPモードとSLEWモード
 http://labunix.hateblo.jp/entry/2012/03/04/194140

■Squeezeのntpのプロセスを見ると以下のようになる。

$ ps -ef | grep ntp | cut -c 40-
00:00:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 105:109
00:00:00 grep ntp

■「-g」オプションは以下のファイルから読まれる。
 ※1000秒を超える差異があった場合に一度だけexitを無視する。
  「-q -x」とすると、slewモードで時刻を合わせ次第終了することになる。

$ cat /etc/default/ntp
NTPD_OPTS='-g'

$ man ntpd | grep -A 5 "   \-g"
       -g     Normally, ntpd exits with a message to the  system  log  if  the
              offset  exceeds the panic threshold, which is 1000 s by default.
              This option allows the time to  be  set  to  any  value  without
              restriction; however, this can happen only once.  If the thresh‐
              old is exceeded after that, ntpd will exit with a message to the
              system log.  This option can be used with the -q and -x options.

■「-u」オプションはinitスクリプトから直接与えられる。
 ※デフォルトはsyslogにログを出力する。ログの出力先を変更する場合は「-l」オプションを使う。

$ grep "\-u" /etc/init.d/ntp
        NTPD_OPTS="$NTPD_OPTS -u $UGID"

$ man ntpd | grep -A 1 "   \-u"
       -u user[:group]
              Specify a user, and optionally a group, to switch to.

$ man ntpd | grep -A 3 "   \-l"
       -l logfile
              Specify  the  name and path of the log file.  The default is the
              system log file.  This is the same operation as the logfile log‐
              file configuration command.

■slewモードに変更する場合の注意点

 ※ntpデーモンの再起動が必要
  slewモードでうるう秒(1)のみの調整にかかる時間は3320秒である。
  ただし、30秒の調整にかかる時間が16時間40分、10分の調整にかかる時間が1321時間20分である点に注意。
  ちなみに1000秒の調整にかかる時間は233時間3320秒、
  stepモードとslewモードの切り替えが128ms以上ずれた状態が300秒以上続いた場合で、
  slewモードで128msの調整に416秒(つまりslewモードで調整可能な時間を越えた場合stepモードに切り替わる)
  であること、「-x」オプションを付与したことによる600秒以上ずれた状態が300秒以上続いた場合という設定上の矛盾を考えると、
  slewモードを恒久的な設定にするべきではないと思う。

  ※事実上600秒未満のずれが300秒未満続くという範囲内であればslewモードで動作し、時刻の調整に最大2週間かかる。
   これは逆進はしないが時刻はずれる可能性があるという意味で、最低2週間は安心出来ない状態が続くということでもある。
   600秒以上1000秒未満はstepモードの切り替わりの可能性、1000秒以上のずれが2回発生すると、ntpdのexitの可能性がある。

$ echo "1 0.0005" | awk '{print ($1/$2)}' | \
  awk '{print (($1-($1%86400))/86400)"日 "($1%86400)}' | \
  awk '{print $1" " (($2-($2%3600))/3600)"時間 " ($2%3600)}' | \
  awk '{print $1" " $2" " (($3-($3%60))/60)"分 " ($3%60)}' | \
  awk '{print $1 $2 $3 $4"秒"}'
00時間3320秒

$ echo "30 0.0005" | awk '{print ($1/$2)}' | \
  awk '{print (($1-($1%86400))/86400)"日 "($1%86400)}' | \
  awk '{print $1" " (($2-($2%3600))/3600)"時間 " ($2%3600)}' | \
  awk '{print $1" " $2" " (($3-($3%60))/60)"分 " ($3%60)}' | \
  awk '{print $1 $2 $3 $4"秒"}'
016時間400秒

$ echo "600 0.0005" | awk '{print ($1/$2)}' | \
  awk '{print (($1-($1%86400))/86400)"日 "($1%86400)}' | \
  awk '{print $1" " (($2-($2%3600))/3600)"時間 " ($2%3600)}' | \
  awk '{print $1" " $2" " (($3-($3%60))/60)"分 " ($3%60)}' | \
  awk '{print $1 $2 $3 $4"秒"}'
1321時間200秒

$ echo "1000 0.0005" | awk '{print ($1/$2)}' | \
  awk '{print (($1-($1%86400))/86400)"日 "($1%86400)}' | \
  awk '{print $1" " (($2-($2%3600))/3600)"時間 " ($2%3600)}' | \
  awk '{print $1" " $2" " (($3-($3%60))/60)"分 " ($3%60)}' | \
  awk '{print $1 $2 $3 $4"秒"}'
233時間3320秒

$ echo "0.128 0.0005" | awk '{print ($1/$2)}'
256

$ echo "0.128 0.0005" | awk '{print ($1/$2)}' | \
  awk '{print (($1-($1%86400))/86400)"日 "($1%86400)}' | \
  awk '{print $1" " (($2-($2%3600))/3600)"時間 " ($2%3600)}' | \
  awk '{print $1" " $2" " (($3-($3%60))/60)"分 " ($3%60)}' | \
  awk '{print $1 $2 $3 $4"秒"}'
00時間416秒

$ man ntpd | grep -A 9 "   \-x"
       -x     Normally, the time is slewed if the offset is less than the step
              threshold,  which is 128 ms by default, and stepped if above the
              threshold.  This option sets the threshold to 600  s,  which  is
              well  within  the  accuracy  window  to  set the clock manually.
              Note: Since the slew rate of typical Unix kernels is limited  to
              0.5  ms/s,  each  second  of adjustment requires an amortization
              interval of 2000 s.  Thus, an adjustment as much as 600  s  will
              take  almost  14 days to complete.  This option can be used with
              the -g and -q options.  Note: The kernel time discipline is dis‐
              abled with this option.

■上記を踏まえた上で設定変更するには、以下の手順で行う

 ※結局のところ、真剣にうるう秒対策を考えているのであれば、
  事前に(30-1)秒未満の範囲のずれであることを確認(1000秒では無い)し、
  うるう秒対策として、slewモードに変更、
  うるう秒調整以降に再度設定を元に戻し、
  ntpdあるいはシステムの再起動を行うのが手順ということになる。

  ※当然、作業は夜間等の影響の少ない時間帯になるだろう。

$ cat /etc/default/ntp
NTPD_OPTS='-g -x'
$ sudo /etc/init.d/ntp restart

$ ps -ef | grep ntp | cut -c 40-
00:00:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -x -u 105:109
00:00:00 grep ntp

■なお、ntpによる時刻同期を行っていない場合は、うるう秒によって単純に1秒ずれるだけである。
 ※「ntpdate -B」のslewモードで同期が出来る。

私個人としては、大規模システムで無い限り、ntpの設定を変更するのではなく、
うるう秒挿入後にntpデーモンの停止、「ntpdate -B」によるslewモード同期、ntpデーモンの起動で良いのではないかと思う。
手動で行うべき理由は、ネットワーク機器や、把握している範囲外の影響等、トラブルシュートを人の手で行う可能性を
考慮した結果である。
また、slewモードの設定の戻し忘れも、その後の時刻同期にかかる調整時間を考えると、後のトラブルとなる可能性が高い。
外部ネットワークに繋がっているのであればなおさらである。
設計上、完璧な対策は無いようなので、柔軟な対応が出来るよう心がけたい。