技术解析

systemd 的时区是怎么确定下来的?
0
2021-06-11 21:36:58
idczone
在系统启动时,记录的时间是比中国时区更快 8 个小时的。然后 systemd 意识到时区不对,把后续内容改回正确的了。但我还是想请教一下这里面的细节,意识到时区不对之前到底发生了什么?
感觉这种错误只有在( localtime 指向中国时区&&RTC 为 UTC 时区)的条件下才能产生。但正式 rootfs 里的情况是:localtime 指向中国时区、RTC 为 LOCAL ; initramfs 里俩设置均不存在,应该按 UTC 处理。

/var/log/messages 日志:

Mar 14 02:15:40 systemd: Stopped dracut initqueue hook.
Mar 14 02:15:40 systemd: Stopped udev Coldplug all Devices.
Mar 14 02:15:40 systemd: Stopped target Paths.
Mar 14 02:15:40 systemd: Stopped target Slices.
Mar 14 02:15:40 systemd: Starting Plymouth switch root service...
Mar 14 02:15:40 systemd: Stopped target Local File Systems.
Mar 14 02:15:40 systemd: Started Cleaning Up and Shutting Down Daemons.
Mar 14 02:15:40 systemd: Stopped udev Kernel Device Manager.
Mar 14 02:15:40 systemd: Stopped dracut pre-udev hook.
Mar 14 02:15:40 systemd: Stopped dracut cmdline hook.
Mar 14 02:15:40 systemd: Stopped Create Static Device Nodes in /dev.
Mar 14 02:15:40 systemd: Stopped Create list of required static device nodes for the current kernel.
Mar 14 02:15:40 systemd: Closed udev Control Socket.
Mar 14 02:15:40 systemd: Closed udev Kernel Socket.
Mar 14 02:15:40 systemd: Starting Cleanup udevd DB...
Mar 14 02:15:40 systemd: Started Cleanup udevd DB.
Mar 14 02:15:40 systemd: Reached target Switch Root.
Mar 14 02:15:40 systemd: Started Plymouth switch root service.
Mar 14 02:15:40 systemd: Starting Switch Root...
Mar 14 02:15:40 systemd: Switching root.
Mar 14 02:15:40 journal: Journal stopped
Mar 13 18:15:41 journal: Runtime journal is using 8.0M (max allowed 256.0M, trying to leave 4.0G free of 125.3G available → current limit 256.0M).
Mar 13 18:15:41 systemd-journald[776]: Received SIGTERM from PID 1 (systemd).
Mar 13 18:15:41 systemd[1]: RTC configured in localtime, applying delta of 480 minutes to system time.
Mar 13 18:15:41 systemd[1]: Inserted module 'autofs4'
Mar 13 18:15:41 kernel: ip_tables: (C) 2000-2006 Netfilter Core Team
Mar 13 18:15:41 systemd[1]: Inserted module 'ip_tables'
Mar 13 18:15:41 journal: Journal started
Mar 13 18:15:41 systemd: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +X
Z +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Mar 13 18:15:41 systemd: Detected architecture x86-64.
/etc/localtime 指向 Asia/Shanghai
/etc/adjtime 内容:

0.0 0 0.0
0
LOCAL
timedatectl 命令:

Local time: Sat 2021-03-13 22:44:30 CST
Universal time: Sat 2021-03-13 14:44:30 UTC
RTC time: Sat 2021-03-13 22:49:29
Time zone: Asia/Shanghai (CST, +0800)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: yes
DST active: n/a

Warning: The system is configured to read the RTC time in the local time zone.
This mode can not be fully supported. It will create various problems
with time zone changes and daylight saving time adjustments. The RTC
time is never updated, it relies on external facilities to maintain it.
If at all possible, use RTC in UTC by calling
'timedatectl set-local-rtc 0'.
hwclock --show --debug 命令:

hwclock from util-linux 2.23.2
Using /dev interface to clock.
Last 大带宽服务器drift adjustment done at 0 seconds after 1969
Last calibration done at 0 seconds after 1969
Hardware clock is on local time
Assuming hardware clock is kept in local time.
Waiting for clock tick...
...got clock tick
Time read from Hardware Clock: 2021/03/13 22:49:43
Hw clock time : 2021/03/13 22:49:43 = 1615646983 seconds since 1969
Sat 13 Mar 2021 10:49:43 PM CST -0.203822 seconds
把 initramfs 展开之后,发现没有 /etc/adjtime 文件、/etc/localtime 文件、/usr/share/zoneinfo/ 整个目录
initramfs 只负责启动,启动过程中由 systemd 挂载真正的 rootfs(log 里也有 switching root)
/etc /usr 之类的目录都是由 systemd-mount 挂载完毕后才指向实际硬盘里的内容

默认情况下,Linux 的硬件时间用的是 UTC 时间,应该是读取到了配置文件才改成对应的时区的时间
感觉其实没有多大的影响,因为很多嵌入式设备连 RTC 都没有,还是可以正常使用,启动的某个过程中会改变时间,如果没有联网的话似乎是上次关机的时间。不过没有留意过这个过程
initramfs 切换到真正的 rootfs 的过程中,很多东西都会改变,应该就是这个原因吧

systemd 的时区是 timedatectl 设置的,而时间从 /dev/rtc0 读取的 rtc 时间;而 /etc/localtime 是 glibc 的配置文件。
正如 所说,Unix 系统一般把 RTC 时间设置为 UTC 时间,这也许是一个标准或者是一个事实标准。macos 和 linux 就是这样默认的。
你不应该将 RTC 时间设置为本地时间( utc+8 ), timedatectl 也警告过你。
另外,/var/log/messages 是有 syslogd 输出的,而 systemd ( journald )的日志位于 /var/log/journal/下。

谢谢各位
我把 rtc 改成 utc 时区试试

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服