PTP を使ったLinux時刻同期の設定方法
概要
PTP(Precision Time Protocol)は、サーバー時刻をとても正確に合わせるための仕組みです。
これはNTP(chrony)というよく使われている仕組みよりもさらに高い精度で時間を合わせることができます。
PTPを使うと、100ナノ秒(1秒の1億分の1)以内の誤差で時間を合わせることが期待できます。
PTPはNTPほど多く使われていませんが、同じネットワーク内でとても正確な時間合わせが必要なときには、とても便利な仕組みです。
ハードウェアの確認
NIC のハードウェアサポートを確認する方法
PTP でハードウェアタイムスタンプが使えるか確認するには、ethtool
コマンドを使います。
ethtool -T eth1
Time stamping parameters for eth1:
Capabilities:
hardware-transmit (SOF_TIMESTAMPING_TX_HARDWARE)
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
hardware-receive (SOF_TIMESTAMPING_RX_HARDWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
hardware-raw-clock (SOF_TIMESTAMPING_RAW_HARDWARE)
PTP Hardware Clock: 0
出力結果で、以下のパラメータが表示されていることを確認します。
ハードウェアタイムスタンプを使う場合
- hardware-raw-clock
SOF_TIMESTAMPING_RAW_HARDWARE
- hardware-transmit
SOF_TIMESTAMPING_TX_HARDWARE
- hardware-receive
SOF_TIMESTAMPING_RX_HARDWARE
ソフトウェアタイムスタンプを使う場合
- software-system-clock
SOF_TIMESTAMPING_SOFTWARE
- software-transmit
SOF_TIMESTAMPING_TX_SOFTWARE
- software-receive
SOF_TIMESTAMPING_RX_SOFTWARE
PTP の通信について
PTPはUDPの319ポート ptp-event
と、320ポート ptp-general
を使用します。
グランドマスターからは1秒ごとにマルチキャストパケットが送信され、スレーブからも1秒ごとにパケットが送信されます。
ファイアウォールでこれらのポートを許可する必要があります。
ファイアウォールを開ける
次のコマンドでUDPの319と320ポートを開けます。
firewall-cmd --add-port=319/udp --permanent
firewall-cmd --add-port=320/udp --permanent
firewall-cmd --reload
PTP のインストール
まず、PTP をインストールします。
dnf install linuxptp -y
これで ptp4l と phc2sys という 2 つのツールがインストールされます。
PTP の設定
ptp4l の設定
/etc/sysconfig/ptp4l
ファイルを編集して NIC の名前を設定します。
vi /etc/sysconfig/ptp4l
次のようにオプションを指定します(eth1でPTPを受ける場合)
OPTIONS="-f /etc/ptp4l.conf -i eth1"
/etc/ptp4l.conf ファイルの作成
以下は ptp4l
の設定ファイル例です。
下記はPTP ProfileをSMPTE ST2059にした場合の例です。
同期先のグランドマスター装置の設定に合わせて調整してください。
[global]
# ドメイン番号(SMPTE ST 2059では127を指定)
domainNumber 127
# ネットワークトランスポートの設定(UDP over IPv4)
network_transport UDPv4
# アナウンス間隔(ログ秒):2^-2 = 0.25秒(250ミリ秒)
logAnnounceInterval -2
# 同期間隔(ログ秒):2^-3 = 0.125秒(125ミリ秒)
logSyncInterval -3
# 遅延要求間隔(ログ秒):2^-3 = 0.125秒(125ミリ秒)
logMinDelayReqInterval -3
# アナウンスタイムアウト(アナウンスメッセージのタイムアウト回数)
announceReceiptTimeout 3
# 優先度1(デフォルトは128)
priority1 255
# 優先度2(デフォルトは128)
priority2 255
# 遅延メカニズム(デフォルトはE2E)
delay_mechanism E2E
# P2P遅延要求間隔(ログ秒):2^0 = 1秒
# E2Eモードでは使用されませんが、互換性のために設定
logMinPdelayReqInterval 0
# クロッククラス(デフォルトは248)
clockClass 248
# クロック精度(デフォルトは0xFE)
clockAccuracy 0xFE
# オフセットスケールログのばらつき(デフォルトは0xFFFF)
offsetScaledLogVariance 0xFFFF
# 時間源(デフォルトは0xA0)
timeSource 0xA0
# スレーブ専用モードを有効にする
slaveOnly 1
# ハードウェアタイムスタンプの有効化(デフォルトは0)
use_syslog 1
# マスター専用モード(デフォルトは0)
masterOnly 0
# `transportSpecific` フィールドを無視する
ignore_transport_specific 1
# ログの有効化
verbose 1
ptp4l の起動
次のコマンドで ptp4l
を起動します
ptp4l -i eth1 -m -s
次のコマンドで phc2sys
を起動します
phc2sys -a -r -m
同期確認
PTP の同期状態を確認するには、以下のコマンドを実行します。
pmc -u -b0 'GET CURRENT_DATA_SET' -d 127
sending: GET CURRENT_DATA_SET
844709.fffe.0e3b53-0 seq 0 RESPONSE MANAGEMENT CURRENT_DATA_SET
stepsRemoved 1
offsetFromMaster -36.0
meanPathDelay 3261.0
- stepsRemoved: 最上位クロックまでのホップ数
- offsetFromMaster: マスタークロックとの時刻差(ナノ秒単位)
- meanPathDelay: マスタークロックからの同期メッセージの遅延予測値(ナノ秒単位)
pmc -u -b0 'GET TIME_STATUS_NP' -d 127
sending: GET TIME_STATUS_NP
844709.fffe.0e3b53-0 seq 0 RESPONSE MANAGEMENT TIME_STATUS_NP
master_offset -5
ingress_time 1719292412888503147
cumulativeScaledRateOffset +0.000000000
scaledLastGmPhaseChange 0
gmTimeBaseIndicator 0
lastGmPhaseChange 0x0000'0000000000000000.0000
gmPresent true
gmIdentity 001747.fffe.d959bd
-
gmPresent:
true
であれば、マスタークロックと正常に同期しています。
サービスとして自動起動する設定
ptp4l
と phc2sys
をサービスとして設定し、システム起動時に自動的に起動するようにします。
ptp4l のサービス化
サービスファイルを作成します。
vi /etc/systemd/system/ptp4l.service
内容は以下の通りです。
[Unit]
Description=Precision Time Protocol (PTP) service
After=network-online.target
[Service]
ExecStart=/usr/sbin/ptp4l -f /etc/ptp4l.conf -i eth1 -m
Restart=on-failure
[Install]
WantedBy=multi-user.target
サービスを有効化して起動します。
systemctl enable ptp4l
systemctl start ptp4l
phc2sys のサービス化
同様に、サービスファイルを作成します。
vi /etc/systemd/system/phc2sys.service
内容は以下の通りです。
[Unit]
Description=PHC to System Clock Synchronization Service
After=ptp4l.service
[Service]
ExecStart=/usr/sbin/phc2sys -s /dev/ptp1 -c CLOCK_REALTIME -O 0 -m
RestartSec=5
Restart=always
[Install]
WantedBy=multi-user.target
サービスを有効化して起動します。
systemctl enable phc2sys
systemctl start phc2sys
これで、システム起動時に自動的に ptp4l
と phc2sys
が起動し、PTP の時刻同期が行われるようになります。
Discussion