web-dev-qa-db-ja.com

Linuxはリアルタイムクロックをどのように使用しますか?

一部の Beagle Bone Black(BBB) ボードに対する非常に奇妙な影響を調査しています。システムクロックで数か月の不定期のジャンプが見られます。これは、常に_systemd-timesyncd_システムクロックの更新と相関しています。さまざまな場所にある2000台のデバイスのフリート全体で、週に2〜3回見られます。

SNTPの確認に多くの時間を費やしてきましたが、それは正常に動作しているようです。

電子ノイズによりランダムに131072秒(36時間)ジャンプする可能性があるオンボードリアルタイムクロックのハードウェアの問題がついに判明しました。これはすぐに正しく表示されません。報告された時間ジャンプは非常に具体的であり、観察したものよりもはるかに少ないですが、 問題をより深く読むと、ジャンプがよりランダムになる可能性があることを示唆しています で、逆に進むことさえあります。

私の質問は... Linuxはシステムクロックを維持するためにリアルタイムクロックをどのように使用しますか?

リアルタイムクロックのエラーが、timesyncエージェント(ntpdまたはsystemd-timesyncd)の更新時にシステムクロックにのみ表示されるかどうかを知りたい。システムクロックとRTC=の間に直接リンクがありますか、それともエージェントだけが使用していますか?


注:最初の段落で、システムクロックの更新と常に相関する_systemd-timesyncd_と常に相関するシステムクロックで数か月のジャンプが見られることを述べました。これは、タイムジャンプ後の最初のsyslogメッセージが_Time has been changed_ syslogメッセージであることを意味します。

_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 syslogメッセージメッセージを知っている場合は、提案を受け付けています。

8
Philip Couling

この答え についてsourcejediに感謝します。これは本当に私に正しい答えを見つけることを導きました。

質問に答える

Linuxはシステムクロックを維持するためにどのようにリアルタイムクロックを使用していますか?

これは、ブート時に1回だけ行われます。次の再起動まで、RTCを再度照会しません。これは構成可能ですが、ほとんどのカーネルビルドでは、デフォルトで照会を行います。


リアルタイムクロックのエラーが、timesyncエージェント(ntpdまたはsystemd-timesyncd)の更新時にシステムクロックにのみ現れるかどうかを知りたいです。

システムが再起動されない限り、RTCの時間はシステムクロックに入る可能性がほとんどありません。ntpdのような一部のエージェントは RTCタイムソースとして しかし、これは通常デフォルトでは有効になっていません。RTCが非常に良い時間であることがわかっている場合を除き、有効にすることはお勧めできません。ソース。


システムクロック間に直接リンクはありますか?

時間が逆にコピーされているようです。 RTCはシステム時間で定期的に更新されます。sourcejediの回答によると、これは CONFIG_RTC_HCTOSYS が設定されている場合、カーネルによって実行されます。

これはテストできます:

  • RTCを設定する

    # 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=要求に実際に応答していましたが、結果は非常に信頼できませんでした。特にルーターが再起動された場合、実際に正しい時間を知らない時間

たとえば、少なくとも1つのバージョンの BT Home Hub 5 を再起動すると、デフォルトで2018年11月21日になり、この日付がNTPで提供されることがわかっています。それはそれ自身のものですNTPクライアントは問題を修正しますが、2018年11月21日に配布するウィンドウがあります。

つまり、この問題の最終的な原因は、お客様がルーターを再起動し、connmanがこの時間をそのまま受け入れたことです。

私はここで私の欲求不満を表現します、それは何人かの好意があまりにも長い間connmanにこの「特徴」を残したようです。 2015年に問題として報告されました 。そして、それは本当によく隠された「機能」です。タイムサーバーが構成されておらず、connmanが何をしているかを説明するログメッセージも、その理由に関するドキュメントもありません。テストリグにNTPサーバーがない場合、テストでこれが表示されることはありません。


直し方

どちらも機能しているように見える2つのオプションを検討しています。

  1. Connmanを完全に削除します。ネットワークがなくてもネットワークは正常に機能しているようです。そもそもその理由がまだわかりません。

    apt-get remove connman
    
  2. 以下を含めるように/var/lib/connmanを編集して、connmanでNTPを無効にします。

    [global]
    TimeUpdates=manual
    
4
Philip Couling

タイトルを含め、これらの点のいくつかに対応できます。

[...]これは常に_systemd-timesyncd_システムクロックの更新と相関します。これは、タイムジャンプ後の最初のsyslogメッセージが_Time has been changed_ syslogメッセージであることを意味します。

_grep 'Time has been changed' /var/log/syslog
Oct  2 23:53:33 hostname systemd[1]: Time has been changed
_

実際、このメッセージは、どのプログラムがタイムジャンプを引き起こしたかを通知するものではありません。タイムジャンプの兆候です。

これは、カーネルがsystemdにクロックが変更されたことを通知したときに発生します。[*] systemdは、このメッセージをシステムログに書き込み、_.timer_ユニットをトリガーする必要がある場合に再計算して応答します。

メッセージは、_systemd-timesyncd_ではなく、プログラムsystemdによって出力されます。

より具体的には、メッセージプレフィックス「systemd [1]:」は、プロセスID 1からのものであることを意味します。PID1は特別な「init」プロセスです。 systemdプロジェクトはこれを「システムマネージャ」とも呼び、ユーザーサービスを管理するsystemdのインスタンスと区別します。


systemdと呼ばれるプログラムは、システムの起動が完了した後でクロックを変更しません。

リンクしている現在のsystemdソースツリーで、RTC/hardware clock/hwclockを読み取ることさえできる唯一のプログラムはtimedatedであり、timedatectlを使用してクエリする場合のみです。

私が覚えているように、古いバージョンのsystemdプログラムは、他のプログラムを実行する前に、ブート時に一度hwclockを読み取り、それに応じてシステムクロックを設定しました。最新バージョンでは、systemdはこれを行いません。ハードウェアクロックにどのタイムゾーンが使用されているかをカーネルに伝える方法は、一部のハッカーだけです。 (そして、「タイムワープ」と呼ばれる非常に具体的なもののトリガーを回避します)。

つまり、現在のsystemdは、何かがシステムクロックを初期化すると暗黙的に想定しているように見えます。ほとんどの場合、これがカーネルになります。

カーネルビルドオプション「システム時間をRTC起動および再開時に設定する」-_CONFIG_RTC_HCTOSYS_を検索します。

丸みを帯びた理解のために、オプション「RTC時間に基づいてNTP同期に基づく)-_CONFIG_RTC_SYSTOHC_」を設定することに注意してください。


[*]システムクロックの変更は、Linux固有の機能を使用して検出されます。 _TFD_TIMER_CANCEL_ON_SET_ を参照してください。

7
sourcejedi