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 */

相關內容