2015-05-21

RHEL7: Set RTC to local time

ようやく RHEL7 を触り始めたので、その辺の話題を。

RHEL7 をインストールした日本人が最初に困るであろうことの一つが、OS 時刻がずれていること。これは RTC (要は BIOS 時刻)が UTC と扱われることが原因。RHEL6 まではインストール時に UTC にするかどうか選択できていたのに、RHEL7 では問答無用で UTC になる。

[rhel7]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.1 (Maipo)

[rhel7]# timedatectl status
      Local time: Fri 2015-05-22 02:04:00 JST
  Universal time: Thu 2015-05-21 17:04:00 UTC
        RTC time: Thu 2015-05-21 17:04:00
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

[rhel7]# cat /etc/adjtime
0.0 0 0.0
0
UTC

上記で RTC 時刻は日本時刻に合っているが、OS 時刻はそれより 9 時間進んでいる。

まあこれは FAQ なので、ググればすぐに「timedatectl set-local-rtc 1」すれば良いことは分かるし、公式ドキュメントにも記載がある。

[rhel7]# timedatectl set-local-rtc 1

[rhel7]# timedatectl status
      Local time: Fri 2015-05-22 02:04:49 JST
  Universal time: Thu 2015-05-21 17:04:49 UTC
        RTC time: Fri 2015-05-22 02:04:50
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: yes
      DST active: n/a

Warning: The RTC is configured to maintain time in the local timezone. This
         mode is not fully supported and will create various problems with time
         zone changes and daylight saving adjustments. If at all possible use
         RTC in UTC, by calling 'timedatectl set-local-rtc 0'.

[rhel7]# cat /etc/adjtime
0.0 0 0.0
0
LOCAL

これで確かに RTC は local time になる。しかし OS 時刻は進んだままだし、今度は RTC 時刻までもが進んでしまった。恐らくこれは皆が望む結果ではない。少なくとも私は望まない。これを(私が)望む結果にするには、set-local-rtc 時にオプション --adjust-system-clock を使う。(詳しくは、man timedatectl)

[rhel7]# timedatectl status
      Local time: Sat 2015-05-23 02:09:00 JST
  Universal time: Fri 2015-05-22 17:09:00 UTC
        RTC time: Fri 2015-05-22 17:09:00
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

[rhel7]# cat /etc/adjtime
0.0 0 0.0
0
UTC

[rhel7]# timedatectl set-local-rtc 1 --adjust-system-clock

[rhel7]# timedatectl status
      Local time: Fri 2015-05-22 17:11:04 JST
  Universal time: Fri 2015-05-22 08:11:04 UTC
        RTC time: Fri 2015-05-22 17:11:04
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: yes
      DST active: n/a

Warning: The RTC is configured to maintain time in the local timezone. This
         mode is not fully supported and will create various problems with time
         zone changes and daylight saving adjustments. If at all possible use
         RTC in UTC, by calling 'timedatectl set-local-rtc 0'.

[rhel7]# cat /etc/adjtime
0.0 0 0.0
0
LOCAL

これで(私が)望む結果になった。まあ普通の人は「set-local-rtc した後で時刻を合わせ直すので問題ない」で終了しそうだが。

ところで RTC を local time にすると、上記のようにいちいち Warning が出るようになる。言っていることは分かるが、UTC にすると BIOS 時刻がずれてしまうのが気持ち悪い。

例えばインターネットに繋がっている環境では自動的に時刻同期するので、何も意識せずに RHEL7 を使っている人も多いと思う。そういうシステムでは多分このようになっている。

[rhel7]# timedatectl status
      Local time: Thu 2015-05-21 17:17:31 JST
  Universal time: Thu 2015-05-21 08:17:31 UTC
        RTC time: Thu 2015-05-21 08:17:31
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

OS 時刻は日本時間に合っているが、RTC 時刻は(UTC なので) 9 時間遅れている。システム管理者とは別の SE がハードウェア保守をやっている場合、「毎回 BIOS 時刻を直しているのにまた狂った。このサーバーは変だ!」と騒ぎ出すかも知れない。それ以前、これらを知らなければ RHEL7 を使っている当人でさえ、BIOS の時刻を見る度に「?」ってなるだろう。

ちなみに RHEL5/6 では、UTC を local time にするのに次を使っていた。昔のことなのであまり覚えていないが、当時も私が望む結果にするため、色々と調べた記憶はある。

if grep '^UTC$' /etc/adjtime ; then
    hwclock --hctosys --local && hwclock --adjust --local
fi

これはそのまま RHEL7 でも動くが、「timedatectl status」の表示に反映させるには、systemd-timedated を再起動する必要がある。


2015-08-13(Thu) 追記

ということで、私としては自己解決したつもりだった。ところが!

RTC を local time にすると、OS 起動時にログのタイムスタンプがずれることに気が付いた。

次のように local time になっている状態で、OS を再起動してみる。

[rhel7]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.1 (Maipo)

[rhel7]# timedatectl
      Local time: Thu 2015-08-13 11:47:46 JST
  Universal time: Thu 2015-08-13 02:47:46 UTC
        RTC time: Thu 2015-08-13 11:47:46
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: yes
      DST active: n/a

Warning: The RTC is configured to maintain time in the local timezone. This
         mode is not fully supported and will create various problems with time
         zone changes and daylight saving adjustments. If at all possible use
         RTC in UTC, by calling 'timedatectl set-local-rtc 0'.

[rhel7]# reboot

その時の /var/log/messages の抜粋。

Aug 13 11:48:25 rhel7 systemd: Stopping user-0.slice.
Aug 13 11:48:25 rhel7 systemd: Removed slice user-0.slice.
Aug 13 11:48:25 rhel7 systemd: Stopping Dump dmesg to /var/log/dmesg...
Aug 13 11:48:25 rhel7 rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="486" x-info="http://www.rsyslog.com"] exiting on signal 15.
Aug 13 11:48:42 rhel7 rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="486" x-info="http://www.rsyslog.com"] start
Aug 13 20:48:34 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.1M, current limit 37.0M).
Aug 13 20:48:34 rhel7 kernel: Initializing cgroup subsys cpuset
Aug 13 20:48:34 rhel7 kernel: Initializing cgroup subsys cpu
Aug 13 20:48:34 rhel7 kernel: Initializing cgroup subsys cpuacct
Aug 13 20:48:34 rhel7 kernel: Linux version 3.10.0-229.el7.x86_64 (mockbuild@x86-035.build.eng.bos.redhat.com) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC) ) #1 SMP Thu Jan 29 18:37:38 EST 2015
Aug 13 20:48:34 rhel7 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-229.el7.x86_64 root=UUID=7aa3d286-206c-4938-82ce-cfbc6635c417 ro crashkernel=auto rhgb quiet LANG=ja_JP.UTF-8
<snip>
Aug 13 20:48:36 rhel7 systemd: Starting Switch Root.
Aug 13 20:48:36 rhel7 systemd: Reached target Switch Root.
Aug 13 20:48:36 rhel7 systemd: Started Plymouth switch root service.
Aug 13 20:48:36 rhel7 systemd: Starting Switch Root...
Aug 13 20:48:36 rhel7 systemd: Switching root.
Aug 13 20:48:36 rhel7 journal: Journal stopped
Aug 13 11:48:38 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.0M, current limit 37.0M).
Aug 13 11:48:38 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.0M, current limit 37.0M).
Aug 13 11:48:38 rhel7 systemd-journald[90]: Received SIGTERM
Aug 13 11:48:38 rhel7 kernel: type=1404 audit(1439466516.972:2): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295
Aug 13 11:48:38 rhel7 kernel: type=1403 audit(1439466517.276:3): policy loaded auid=4294967295 ses=4294967295
Aug 13 11:48:38 rhel7 systemd[1]: Successfully loaded SELinux policy in 322.882ms.
Aug 13 11:48:38 rhel7 systemd[1]: RTC configured in localtime, applying delta of 540 minutes to system time.
Aug 13 11:48:38 rhel7 systemd[1]: Relabelled /dev and /run in 39.287ms.
Aug 13 11:48:38 rhel7 journal: Journal started
Aug 13 11:48:38 rhel7 systemd: systemd 208 running in system mode. (+PAM +LIBWRAP +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ)

ある期間だけ、タイムスタンプがずれている。前後関係から、rsyslogd が落ちている間に journald が溜め込んだログのように見える。9 時間戻る(UTC 時刻になる)のならまだ分かるが、9 時間進むというのは頂けない。

一方、RTC が UTC の場合、

[rhel7]# timedatectl
      Local time: Thu 2015-08-13 11:51:56 JST
  Universal time: Thu 2015-08-13 02:51:56 UTC
        RTC time: Thu 2015-08-13 02:51:57
        Timezone: Asia/Tokyo (JST, +0900)
     NTP enabled: n/a
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

[rhel7]# reboot

今度はタイムスタンプはずれない。(正確には、ちょっとずれるけど大きくはずれない)

Aug 13 11:52:14 rhel7 systemd: Stopping user-0.slice.
Aug 13 11:52:14 rhel7 systemd: Removed slice user-0.slice.
Aug 13 11:52:14 rhel7 systemd: Stopping Dump dmesg to /var/log/dmesg...
Aug 13 11:52:14 rhel7 systemd: Stopped Dump dmesg to /var/log/dmesg.
Aug 13 11:52:14 rhel7 systemd: Stopping Multi-User System.
Aug 13 11:52:14 rhel7 systemd: Stopped target Multi-User System.
Aug 13 11:52:14 rhel7 systemd: Stopping Command Scheduler...
Aug 13 11:52:14 rhel7 rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="486" x-info="http://www.rsyslog.com"] exiting on signal 15.
Aug 13 11:52:30 rhel7 rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="487" x-info="http://www.rsyslog.com"] start
Aug 13 11:52:23 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.1M, current limit 37.0M).
Aug 13 11:52:23 rhel7 kernel: Initializing cgroup subsys cpuset
Aug 13 11:52:23 rhel7 kernel: Initializing cgroup subsys cpu
Aug 13 11:52:23 rhel7 kernel: Initializing cgroup subsys cpuacct
Aug 13 11:52:23 rhel7 kernel: Linux version 3.10.0-229.el7.x86_64 (mockbuild@x86-035.build.eng.bos.redhat.com) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC) ) #1 SMP Thu Jan 29 18:37:38 EST 2015
Aug 13 11:52:23 rhel7 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-229.el7.x86_64 root=UUID=7aa3d286-206c-4938-82ce-cfbc6635c417 ro crashkernel=auto rhgb quiet LANG=ja_JP.UTF-8
<snip>
Aug 13 11:52:25 rhel7 systemd: Starting Switch Root.
Aug 13 11:52:25 rhel7 systemd: Reached target Switch Root.
Aug 13 11:52:25 rhel7 systemd: Started Plymouth switch root service.
Aug 13 11:52:25 rhel7 systemd: Starting Switch Root...
Aug 13 11:52:25 rhel7 systemd: Switching root.
Aug 13 11:52:25 rhel7 journal: Journal stopped
Aug 13 11:52:27 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.0M, current limit 37.0M).
Aug 13 11:52:27 rhel7 journal: Runtime journal is using 4.6M (max 37.0M, leaving 55.6M of free 366.0M, current limit 37.0M).
Aug 13 11:52:27 rhel7 systemd-journald[90]: Received SIGTERM
Aug 13 11:52:27 rhel7 kernel: type=1404 audit(1439434345.778:2): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295
Aug 13 11:52:27 rhel7 kernel: type=1403 audit(1439434346.070:3): policy loaded auid=4294967295 ses=4294967295
Aug 13 11:52:27 rhel7 systemd[1]: Successfully loaded SELinux policy in 307.437ms.
Aug 13 11:52:27 rhel7 systemd[1]: Relabelled /dev and /run in 39.670ms.
Aug 13 11:52:27 rhel7 journal: Journal started
Aug 13 11:52:27 rhel7 systemd: systemd 208 running in system mode. (+PAM +LIBWRAP +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ)

OS 起動時だけとはいえ、ログのタイムスタンプがずれることが許容できない場合はあるだろう。そのような場合、RTC は UTC にしておく必要がある。

実際 RHEL7 を触っていると、今回のように RTC が UTC であることを前提としている印象を受けることがある。今までは私も「そうは言ってもねえ、」とそれに抗っていたが、今回の件でスッパリと諦めた。正直、他にどういう副作用があるか知れない。なので現時点での結論は、

RHEL7 で余計な面倒に遭いたくないなら、RTC は UTC にしとけ。

後は、BIOS 時刻(9 時間遅れている)を見た人が、時刻を直してくれないことを祈るのみ。