NTP 系统时间与硬件时间不同

NTP 系统时间与硬件时间不同

在 centos 6.5 服务器上我刚刚执行了 ntp:

service ntpd start

系统时间已修复,但硬件时间仍然错误。这正常吗?我该如何修复?

ntpstat 报告:

unsynchronized
polling server every 64s

答案1

首先:Linux 系统上的硬件时间以 UTC 格式存储,因此与时区相关的偏移是可以预料的。是的,这在双启动时确实会带来问题。

除此之外,Linux 系统不会总是立即将 NTP 时间传播到 RTC(“硬件时钟”),但它至少应该在关机时这样做。

答案2

NTP 可能确实在校正时间,但速度很慢。它通常这样做是为了避免程序因为在几分之一秒内过了 N 秒而感到烦恼。许多程序使用该时间来在内部安排其工作。

因此时钟会稍微增加或减少秒数,比如每秒增加 0.1 秒(甚至更少)。两个时钟同步可能需要一些时间。

检查时间差,看看它是否随着时间的推移而减少。

如果在“正常”断电(即关机,而不是硬件断电)后差异仍然存在,则应检查系统是否编程正确。在我的系统中,这是在关机时运行的命令文件中完成的:

/etc/rc.d/rc.0 包含:

# Save the system time to the hardware clock using hwclock --systohc.
if [ -x /sbin/hwclock ]; then
  # Check for a broken motherboard RTC clock (where ioports for rtc are
  # unknown) to prevent hwclock causing a hang:
  if ! grep -q -w rtc /proc/ioports ; then
    CLOCK_OPT="--directisa"
  fi
  if grep -q "^UTC" /etc/hardwareclock 2> /dev/null ; then
    echo "Saving system time to the hardware clock (UTC)."
    /sbin/hwclock $CLOCK_OPT --utc --systohc
  else
    echo "Saving system time to the hardware clock (localtime)."
    /sbin/hwclock  $CLOCK_OPT --localtime --systohc
  fi
fi

您可以手动尝试该命令:sudo hwclock --systohc。如果不起作用,则可能是硬件问题。

同步两个时钟的重要性?取决于您运行的软件。硬件时钟用于在启动时设置系统时钟。在 NTP 启动之前,您的机器使用该时间。在此期间使用的任何文件都会被标记为错误的时间。这对某些人来说可能很重要...

答案3

由于现有的答案忽略了最重要的事实,我告诉你:NTP 调整系统时钟(软件时钟)。然而,在 Linux 中调整系统时钟才不是调整硬件时钟(实际上我大约 20 年前就写过一个补丁来修复该问题,但从未被接受)。

当前系统通常会在以下情况下根据系统时间更新硬件时钟:干净的关闭或处于定期工作状态。

更新硬件时钟的问题在于内核不知道硬件时钟是设置为本地时间还是 UTC,因此在更新硬件时钟时必须应用一些未知的偏移量。另一个问题是 Linux 有一些损坏的代码(我没有检查过去 20 年的情况)用于在系统时钟标记为“同步”的情况下更新硬件时钟的分钟和秒。

古老的密码曾经是:

     * If we have an externally synchronized Linux clock, then update
     * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
     * called as close as possible to 500 ms before the new second starts.
     */
    if ((time_status & STA_UNSYNC) == 0 &&
        xtime.tv_sec > last_rtc_update + 660 &&
        xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
        xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
        if (set_rtc_mmss(xtime.tv_sec) == 0)
            last_rtc_update = xtime.tv_sec;
        else
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */

相关内容