Linux 如何使用實時時鐘?
我正在研究一些Beagle Bone Black (BBB)板上的一種非常奇怪的效果。我們看到系統時鐘偶爾會出現幾個月的跳躍,這總是與
systemd-timesyncd
更新系統時鐘相關。我們每週會在不同地點的 2000 台設備中看到其中的 2 到 3 台。我們花了很多時間檢查 SNTP,但它似乎表現正常。
我們終於想出了一個板載實時時鐘的硬體問題,它可能會由於電子雜訊而導致它隨機跳躍 131072 秒(36 小時)。這並不立即正確,報告的時間跳躍非常具體,比我們觀察到的要少得多,但是對這個問題的深入閱讀表明跳躍可能更加隨機,甚至可能倒退。
我的問題是…… linux如何使用實時時鐘來維護系統時鐘?
我想知道實時時鐘的錯誤是否只會在時間同步代理(ntpd 或 systemd-timesyncd)更新時出現在系統時鐘中。系統時鐘和 RTC 之間是否有任何直接聯繫,還是僅由代理使用?
*注意:*在第一段中,我提到我們看到系統時鐘出現幾個月的跳躍,這總是與
systemd-timesyncd
更新系統時鐘相關。我的意思是時間跳轉後的第一條系統日誌消息是Time has been changed
系統日誌消息:grep 'Time has been changed' /var/log/syslog Oct 2 23:53:33 hostname systemd[1]: Time has been changed Nov 21 00:07:05 hostname systemd[1]: Time has been changed Nov 21 00:05:17 hostname systemd[1]: Time has been changed Nov 21 00:03:29 hostname systemd[1]: Time has been changed Nov 21 00:01:43 hostname systemd[1]: Time has been changed Oct 3 02:07:20 hostname systemd[1]: Time has been changed Oct 3 06:37:04 hostname systemd[1]: Time has been changed
據我所知,唯一發出這些消息的是 systemd-timesycnd (參見原始碼)。顯然,如果其他人知道
systemd
與這些匹配的其他正常系統日誌消息,我願意接受建議。
非常感謝 sourcejedi 的回答。這真的讓我找到了正確的答案。
回答問題
Linux如何使用實時時鐘來維護系統時鐘?
它只這樣做一次,在引導期間。在下次重新啟動之前,它不會再次查詢 RTC。這是可配置的,但預設情況下會在大多數核心建構中這樣做。
我想知道實時時鐘的錯誤是否只會在時間同步代理(ntpd 或 systemd-timesyncd)更新時出現在系統時鐘中。
除非系統重新啟動,否則 RTC 中的時間根本不可能進入系統時鐘。一些代理
ntpd
可以配置為使用 RTC 作為時間源,但預設情況下通常不啟用。除非您知道 RTC 是一個非常好的時間源,否則不建議啟用它。系統時鐘之間是否有直接聯繫?
看來時間是以另一種方式複制的。RTC 會定期更新系統時間。根據 sourcejedi 的回答,如果設置了CONFIG_RTC_HCTOSYS ,則這是由核心完成的。
這可以測試:
- 設置實時時鐘
# hwclock --set --date='18:28'
- 然後每隔幾分鐘檢查一次 RTC 時間:
# hwclock
這樣做的結果將是系統時間根本不會改變,而 RTC 最終將恢復為系統時間。
時間的原因在BBB上跳躍
正如 sourcejedi 指出的那樣,消息不是由
systemd-timesyncd
. 他們被觸發了connman
。證據是*(應該是)*虛假的日誌消息/var/log/syslog
:Oct 3 00:10:37 hostname connmand[1040]: ntp: adjust (jump): -27302612.028018 sec ... Nov 21 00:07:05 hostname systemd[1]: Time has been changed
在 1.37 版本之前,connman 被硬編碼以隨機輪詢預設網關。它不需要配置 DHCP 來執行此操作,如果 connman 的 NTP 客戶端已啟用*(預設情況下)*,那麼無論任何其他配置如何,它都會執行此操作。
在我們的案例中,一些家庭路由器實際上正在響應這些 NTP 請求,但結果非常不可靠。尤其是在路由器重啟的地方,它在實際上不知道正確時間的情況下繼續分配時間。
例如,我們知道至少有一個版本的BT Home Hub 5在重新啟動時會預設為 2018 年 11 月 21 日,並通過 NTP 給出這個日期。然後它自己的 NTP 客戶端將糾正問題,但有一個視窗在 2018 年 11 月 21 日發布。
也就是說,這個問題最終是由於我們的客戶重新啟動了他們的路由器而 connman 只是接受了這次。
我將在這裡表達我的挫敗感,似乎某些人的好戰已經在 connman 中留下了這個“功能”太久了。 早在 2015 年就被報告為一個問題。這是一個非常隱藏的“功能”。沒有配置時間伺服器,也沒有日誌消息來解釋 connman 正在做什麼或文件說明原因。如果您的測試設備在預設網關上沒有 NTP 伺服器,您將永遠不會在測試中看到這一點。
怎麼修
我們正在研究兩個似乎都有效的選項:
- 完全刪除 connman。沒有它,網路似乎工作得很好;我們還沒有找到它存在的原因。
apt-get remove connman
- 在 connman 中通過編輯禁用 NTP
/var/lib/connman
以包括:[global] TimeUpdates=manual
我可以回應其中的一些觀點,包括標題。
$$ … $$這總是與
systemd-timesyncd
更新系統時鐘相關。我的意思是時間跳轉後的第一條系統日誌消息是Time has been changed
系統日誌消息:grep 'Time has been changed' /var/log/syslog Oct 2 23:53:33 hostname systemd[1]: Time has been changed
實際上,這條消息並沒有告訴你是什麼程序導致了時間跳躍。這只是時間跳躍的一個症狀。
當核心告訴
systemd
時鐘已更改時,就會發生這種情況。$$ * $$
systemd
通過將此消息寫入系統日誌進行響應,然後重新計算何時.timer
需要觸發任何單元。 該消息由程序列印systemd
,而不是由systemd-timesyncd
.更具體地說,消息前綴“systemd
$$ 1 $$:" 表示它來自程序 ID 1。PID 1 是特殊的“init”程序。systemd 項目也將其稱為“系統管理器”,以區別於
systemd
管理使用者服務的實例。系統啟動完成後,呼叫的程序
systemd
不會更改時鐘。在您連結到的目前 systemd 原始碼樹中,唯一甚至讀取 RTC/硬體時鐘/hwclock 的程序是
timedated
,並且只有當您使用timedatectl
.我記得,舊版本的
systemd
程序在啟動時讀取 hwclock 一次,然後再執行任何其他程序,並相應地設置系統時鐘。在最新版本中,systemd
不這樣做。告訴核心哪個時區用於硬體時鐘只有一些技巧。(並避免觸發非常具體的稱為“時間扭曲”的東西)。換句話說, current
systemd
似乎隱含地假設其他東西初始化了系統時鐘。在大多數情況下,這將是核心。查找核心建構選項“在啟動和恢復時從 RTC 設置系統時間” -
CONFIG_RTC_HCTOSYS
。為了全面了解,請注意還有一個選項“根據 NTP 同步設置 RTC 時間” -
CONFIG_RTC_SYSTOHC
。$$ * $$使用 Linux 特定功能檢測系統時鐘變化。見
TFD_TIMER_CANCEL_ON_SET
。