【问题描述】
记录一个有意思的问题,问题的分析定位废了九牛二虎之力,但问题最终的处理方案比较乌龙;
工控机安装U14系统,当设备异常断电关机再次上电启动后,系统时间会向前漂移整整8小时,现象稳定可复现。
【原因分析】
拿到这个问题,上来基本假设,这一问题的诱因应该是和硬件时钟以及系统时区的东八区有关。
先离线验证,正常不断电重启开关机,确实没有此问题;断电重启复现此问题,确实稳定存在,且时差会堆积。
可能有点上头,上来对系统和固件的时间进行规律性的摸查,最终得出8小时时差的诱发逻辑:
①、发现,系统开机后,hwc和sys都会首先从rtc读取时间,sys会将rtc直接作为东八区的时间,hwc则会自动加8小时,然后系统触发同步机制
系统同步机制,文件:/etc/init/hwclock.conf
②、如此,虚拟硬件时间被变更和系统当前时间一致,rtc时间则被变更为向前漂移8小时,一致持续下去。
③、此时,如若断电,系统重新从rtc读取时间直接作为东八区时间,则系统时间向前漂移8小时,且启动后触发②,rtc再次向前漂移8小时。
至此,基本剖析到根本原因,非断电重启则不会发生时间漂移(猜测应该是正常系统直接向hwc读取时间而非RTC);
设备上电不进到系统再断电也不会发生漂移,因为导致时间漂移的是因为系统内的时间同步机制导致的;
经过多次测试,此同步机制生效大概是系统开机后5秒左右触发,rtc就会被向前漂移。
【解决方案】
①、直接,给出初步解决方案:让rtc时间同步和系统时间一致,则不管怎么断电都不会发生漂移。
timedatectl set-local-rtc 1 【修改RTC时间和系统时间一致】
echo "@reboot (sleep 6 ; /sbin/hwclock --rtc=/dev/rtc0 --systohc --localtime)" >>/var/spool/cron/crontabs/root
【添加系统开机后自动触发时间同步,效果雷同“hwclock -w”】
/sbin/hwclock --rtc=/dev/rtc0 --systohc --localtime 【直接生效,不需要重启】
配置前:timedatectl
配置后:timedatectl
②、到此,是不是问题就已经结束了,非也,方案上线验证,发现系统每10分左右就会触发一次系统同步到硬件时间机制,RTC的时间会被再次修改向前漂移8小时,所以此方案宣告失败。
再次经过反复验证,未找到为什么导致此机制的发生,但证实了确实RTC时钟会每10分钟被触发同步更新,猜测应该是底层固件的同步机制,非系统内机制。
所以,回头重新审视此问题,问题的根本原因应该是:
RTC的时间默认被认为是UTC时间(虽然RTC时钟是没有时区的),系统时区是东八区,但是系统从RTC读取时间时会认为此就是东八区时间;
当系统启动后,触发同步机制(/etc/init/hwclock.conf),应该时rtc先同步到hwc,再同步到rtc;hwc是东八区,同步rtc也认为rtc应该是utc,所以前移8小时;
③、最终,两次上头后,冷静思考,得出最新解决方案:告诉系统,rtc是utc的时间不是东八区的,你要用自己加8小时;
机制文件:/etc/default/rcS
sed -i '/UTC=no/c\UTC=yes' /etc/default/rcS 【仅此一条命令即可,取消之前的指令】
配置后,断电重启,系统刚开机时间是不对的,但5秒后会自动校时,效果如下: