tabimoba.net

とあるエンジニアの雑記帳

Linuxで時刻設定後、ハードウェア再起動後や電源投入後に日時ずれが生じる場合の対応

はじめに

Linuxで日時設定を行う場合、dateコマンドで以下のように行うと思います。

# date --set "2015/11/25 9:14:58"

しかし、サーバ(あるいは端末)をの電源断・再投入や、再起動を行うと、日付が数時間ずれる、1日あるいはそれ以上ずれる等、予期しない結果が生じる場合があります。

原因

Linuxでは、日時情報として「Local time」「Universal time」「RTC time」の3種類が管理されています。これはtimedatectlコマンドで確認することが出来ます。

# timedatectl
      Local time: 水 2015-11-25 09:23:38 JST
  Universal time: 水 2015-11-25 00:23:38 UTC
        RTC time: 木 2015-11-26 00:29:58
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

「Local time」は現地時刻、「Universal time」は世界標準時で、これらはシステムクロックと云われます。「RTC time」は、ハードウェアが持つ日時情報で、これはリアルタイムクロックと云われます。BIOS/UEFIで設定可能な日時情報と「RTC time」は同じものです。

うち、dateコマンドで反映されるのは「Local time」と「Universal time」の2つです。(正しくは、設定値が反映されるのは「Local time」で、「Universal time」は「Local time」の時差に合わせて結果が出力されるものです)

「RTC time」はdateコマンドで日時設定を行っても、その設定値が反映されません。また、NTPによる日時補正についても同様(「Local time」しか補正されない)となります。

対応

最もシンプルな方法は、BIOS/UEFIで日時を設定することです。しかし、既にLinuxが起動していて、再起動が難しい場合は、hwclockコマンドで「RTC time」を設定することができます。

dateコマンドで日時を設定した後に、hwclock --systohcを実行すると、「Local time」と「RTC time」が同期されます。

# date --set "2015/11/25 9:28:20"
# hwclock --systohc

上記実行後、timedatectlコマンドを実行すると、「Localtime」と「RTC time」が同期されていることがわかります。

# timedatectl
      Local time: 水 2015-11-25 09:28:26 JST
  Universal time: 水 2015-11-25 00:28:26 UTC
        RTC time: 水 2015-11-25 00:28:26
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

なお、NTPによる日時補正は、前述の通り「Local time」しか反映されませんので、「RTC time」の日時ずれが生じた際は、上記コマンドを実行する必要があります。1週間〜1ヶ月に1回程度cronで上記コマンドを定期的に実行するのが良いでしょう。