labunix's blog

labunixのラボUnix

STEPモード(ntpd)の1秒のずれの調整にかかる時間の検証

■昨日の続き

 うるう秒の検証に使えそう ntptime
 http://d.hatena.ne.jp/labunix/20120306

■時刻を合わせ、任意の秒数をずらして、再度同期で時刻合わせが完了するまで
 秒数カウントを行う。仮想マシン環境でホストdebianを上位NTPサーバとして参照しているので、
 「sleep 0.8」をウエイトとし、これを秒と同一視する。
 (「sleep 0.9」でも問題無いし、「sleep 1」でも充分だと思う)

 ※私はこれ以上の正確さの必要性の認識が無いので、放っておいても答えが出る方針とした。

■必要なパッケージ「ntp、ntpd」
 ※同期の為の親NTPサーバは自身の管理環境下にある事が望ましい。

$ dpkg -s ntp | grep "Status\: install"
Status: install ok installed

$ dpkg -s ntpdate | grep "Status\: install"
Status: install ok installed

■1秒戻す場合は下記の箇所を変更
 ※「61」⇒「59」、この変更を「leapcheck2.sh」とでもしておく。

# NOW -1
env LANG=C date '+%H:%M:%S' | \
  awk -F\: '{printf "%02d:%02d:%02d", $1, $2, (($3+59)%60)}' | \
  date -s "`xargs`";

■以下のようなログが出る

 6 Mar 21:26:28 ntpdate[8991]: step time server 192.168.188.188 offset -7.021156 sec
Starting NTP server: ntpd.
ntp_gettime() returns code 0 (OK)
ntp_adjtime() returns code 0 (OK)
2012年  3月  6日 火曜日 21:26:31 JST
0000
0001
~省略~

■使い方
 ※IPやホスト名の間違いはそのまま「ntpdateコマンド」の失敗として返します。

 ・ログをファイルに落とす

$ sudo ./leapcheck.sh 192.168.188.188 > leapcheck.log

 ・上記+完了したらシステムメール

# ./leapcheck.sh 192.168.188.188 > leapcheck.log && \
   cat leapcheck.log | mail -s "1 seconds plus" root
 
■ログの見方

 ・定番

$ sudo tail -f leapcheck.log

 ・監視

$ sudo watch -d -n 'tail -1 leapcheck.log'

■時刻補正チェック用のbashスクリプト
 ※1秒進める

$ cat leapcheck.sh
#!/bin/bash

# Environment
set -e
echo $PATH | sed s/":"/"\n"/g | grep "^/usr/sbin\$" > /dev/null 2>&1 || \
  export PATH=/usr/sbin/${PATH}
echo $PATH | sed s/":"/"\n"/g | grep "^/sbin\$" > /dev/null 2>&1 || \
  export PATH=/sbin/${PATH}

# root check
if [ `id -u` -ne 0 ];then
  echo "Sorry,Not Permit User"
  exit 2
fi

# arg check
if [ "x$1" == "x" ];then
  echo "Usage $0 [Parent-NTP-Server-IP or hostname]"
  exit 2
else
  PNTP="$1"
fi

# at first,time sync or exit 
FLAG=0
/etc/init.d/ntp stop
ntpdate ${PNTP} || FLAG=1
/etc/init.d/ntp start

if [ "${FLAG}" == "1" ] ;then
  echo "ntpdate error"
  exit 2
fi

# sync check
ntptime | grep "returns code 0" || exit 1

# NOW + 1
env LANG=C date '+%H:%M:%S' | \
  awk -F\: '{printf "%02d:%02d:%02d", $1, $2, (($3+61)%60)}' | \
  date -s "`xargs`";

# main
cnt=0
while true;do
  echo ${cnt} | awk '{printf "%04d\n", $1}'
  let cnt=${cnt}+1
  ntptime | grep "returns code 0" && exit 0
  sleep 0.8;
done

■以下で1秒「進めた」、「戻した」後の調整ログが放置していても出ます。
 ※メールの到着時間との差異でより正確に終了時間の予測が可能です。

$ grep 60 leap*.sh
leapcheck.sh:  awk -F\: '{printf "%02d:%02d:%02d", $1, $2, (($3+61)%60)}' | \
leapcheck2.sh:  awk -F\: '{printf "%02d:%02d:%02d", $1, $2, (($3+59)%60)}' | \

$ su
# ./leapcheck.sh 192.168.188.188 > leapcheck.log && \
   cat leapcheck.log | mail -s "1 seconds plus" root; \
   ./leapcheck2.sh 192.168.188.188 > leapcheck2.log && \
   cat leapcheck2.log | mail -s "1 seconds minus" root

■結果は穴埋め方式で結果が出次第とします。
 ※私の個人環境ではSLEWモードは不要ですのでSTEPモードのみ
  同様にinitスクリプトをSLEWモード用に準備すれば、
  どちらも放置で出来ますが。。。

■STEPモードの場合、1秒進めた場合の時刻調整にかかった時間
 カウント数(=秒):993 = 00:16:33
 メール着時刻(22:23:52)-ntpdate強制同期時刻(22:08:38)=ntpd調整時間(00:15:14)

■STEPモードの場合、1秒遅れた場合の時刻調整にかかった時間
 カウント数(=秒):999 = 00:16:39
 メール着時刻(22:39:20)-ntpdate強制同期時刻(22:24:01)=ntpd調整時間(00:15:19)

※「ntpdate」、「ntpq -c rv」による目視ではほぼ同期しているが、
 1日以上経過しても「ntptime」が「returns code 5」のまま。

 3回づつ実行して、「1秒進めた」場合に一度だけ、
 以下のように約3時間で「returns code 0」となりました。

■SLEWモードの場合、1秒進めた場合の時刻調整にかかった時間
 カウント数(=秒):11374 = 03:09:34
 メール着時刻(00:07:38)-ntpdate強制同期時刻(21:13:11)=ntpd調整時間(02:54:27)

 ⇒私見では、とっても気持ち悪い結果なので、SLEWモードは使いたくありません。
  わたしの環境は、STEPモード(デフォルト)で運用することにします。

■仮想マシンなので、cronで1秒進めるスクリプトを毎日9時に実行して
 状況を確認するのもよさそうです。

 ※テスト中、散々変更して問題なかった現状を踏まえて、何かあるとも思えませんが。。。