伙计们!
我有一台单板计算机(HardKernel Odroid C2),它没有内置 RTC,每次系统启动时都需要外部时间源。虽然我有一个本地 NTP 服务器,但我还需要 RTC,以防罕见的电源故障,这将迫使 NTP 服务器重新启动并丢失时间。由于时间对于系统运行至关重要,我使用 PCF8563 I2C RTC 构建了 RTC。问题是它需要特殊的内核模块才能使系统可用 RTC,我必须在启动过程中加载这些模块。因此系统以错误的时间启动,加载所需的模块,然后在 /etc/rc.local 的帮助下从 RTC 设置系统时间:
#Set system datetime from RTC
logger "Starting system clock synchronization with RTC"
if [ -e /dev/rtc ]; then
/sbin/hwclock --hctosys
fi
logger "System clock synchronized to RTC"
问题是 systemd 似乎将早期启动过程和时钟设置之间的时间段视为不写入日志的“错误”时间段。系统关闭和系统时钟设置后,我根本看不到任何日志:
Jan 5 23:20:39 tank systemd-journald[206]: Journal stopped
Jan 5 23:20:55 tank root[394]: System clock synchronized to RTC <- this is the second logger message
Jan 5 23:20:55 tank systemd[1]: Started /etc/rc.local Compatibility.
...
Jan 5 23:21:07 tank chronyd[384]: Forward time jump detected!
HardKernel 建议通过从 /etc/rc.local 运行 hwhlock --hctosys 来从 RTC 同步系统时钟。但这似乎完全错误,因为系统在运行 rc.local 之前显然会工作一段时间,时间是预先定义的。那么,有没有办法从 RTC 提前设置系统时钟?
答案1
我花了 2 天时间,终于找到了确切的解决方案。问题是rc.local
在系统启动后执行得太晚了。这会导致几个问题:1) 部分(包括有价值的内核和早期系统启动)或所有日志都因时间跳跃而丢失,这使得日志丢弃新日期之前的所有日志 2) 如果由于某种原因系统时钟将在系统记录器(在我的情况下是 syslogd 或 syslog-ng)启动后更新,则上次关闭后将没有任何日志。虽然系统仍可运行,但这是一个重大故障,因为无法调查正在运行的系统上的任何内容。经过一些没有日志的精疲力尽的实验后,我找到了将系统时钟设置为最接近一年的时间的组合(实际上非常明显):
/lib/systemd/system/hwrtc.service
[Unit]
Description=Synchronise System clock to hardware RTC
DefaultDependencies=no
After=systemd-modules-load.service
Before=systemd-journald.service time-sync.target sysinit.target shutdown.target
Conflicts=shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/hwclock --hctosys --utc --noadjfile
RestrictRealtime=yes
[Install]
WantedBy=sysinit.target
并启用该服务。这将使系统在强制模块加载之后、日志启动之前立即启动 hwclock,因此所有日志都将标记从 RTC 恢复的实际时间,并保存所有消息,包括第一个内核消息。