systemdでboot_idの値をすばやく変更します。

systemdでboot_idの値をすばやく変更します。

別のコンピュータに保存されているいくつかのログファイルを表示している間、いくつかのログエントリの値が__BOOT_ID異なり、それらの間の時間間隔が非常に狭いことがわかりました。たとえば、ミリ秒で区切られたログエントリは異なる__BOOT_ID値を持ちます。これは短い間隔でシステムを再起動できないため、これは不可能です。

実行すると、journalctl -o verbose --directory <dir path> | grep -B 30 -A 30 -- "-- Reboot --"次の実際の例が参照されていることがわかります。ここでは、10ミリ秒間隔でログイベントに2つの異なる開始ID値があります。

Wed 2019-11-13 21:35:58.469925 ...
    _TRANSPORT=kernel
    PRIORITY=6
    SYSLOG_FACILITY=0
    SYSLOG_IDENTIFIER=kernel
    _BOOT_ID=fec227a60ef24474aacd023d6c02733f
...
...
...
    MESSAGE=spi1.0: ttyMAX1 at I/O 0x20 (irq = 30, base_baud = 3000000) is a MAX3109
-- Reboot --
Wed 2019-11-13 21:35:58.470352 ...
    _SOURCE_MONOTONIC_TIMESTAMP=0
    _TRANSPORT=kernel
    PRIORITY=6
    SYSLOG_FACILITY=0
    SYSLOG_IDENTIFIER=kernel
    MESSAGE=Booting Linux on physical CPU 0x0
    _BOOT_ID=21b95aabab034009a19d1b7deac80327
...
...
...

ブートIDが急速に変化する原因を見つけようとしましたが、成功しませんでした。バージョン(v243)のシステムソースを見ると、sd_id128_get_boot()これは開始IDを読み取るために使用される関数のようです。ファイルからカーネル生成値を読みます。


        if (sd_id128_is_null(saved_boot_id)) {
                r = id128_read("/proc/sys/kernel/random/boot_id", ID128_UUID, &saved_boot_id);
                if (r < 0)
                        return r;
        }

        *ret = saved_boot_id;
        return 0;

最終結果はログに表示されるリブートのリストですが、最終的にリブートされない可能性があります。興味深いことに、journalctl --list-bootsこれは再起動としてまったく表示されません(現在のget_boots()実装を理解しようとしています)。

以前にこのような振る舞いを見たことがある人がいたら、コメントやコメントをお寄せいただきありがとうございます。これが再起動リストを取得できる場所であることはわかっていますが、jounalctl --list-boots特定の再起動情報セットを含むログを分析したいと思います。これらの誤った肯定は、私が書こうとしたスクリプトの結果を汚染しました。

ベストアンサー1

実行IDが実際にそんなに早く変更されているようではありません。私の考えでは、複数の異なるブーツのログを同時に見ていて、互いに混ざっているようです。

システムにバッテリで動作するリアルタイムクロックがない場合、この現象が発生する可能性があります。

Journalctlはウォールクロック時間を使用して、さまざまな開始のログメッセージをソートします。起動するたびに壁時計がリセットされると、複数の起動でメッセージが同時に発生するように見え、Journalctlはメッセージを混乱させます。

バラよりlennart petlingでコメント存在するシステム機能要求#662(強調):

したがって、再起動するたびに、1970年の日付と新しいランダム起動IDで始まります。起動するたびに、このようにして複数のメッセージが生成されます。

表示中、Journalctlはこのデータを表示してインターリーブして理解しようとします。インターリーブ方式は、行を並べ替え、新しいデータの前に古いデータを配置する必要があることを意味します。これを行うには、まずシリアル番号を比較しようとします。シリアル番号はメモリに保存され、起動するたびにゼロにリセットされます。したがって、比較したい2行の実行IDが一致する場合にのみ比較できます。再起動時に起動IDが異なるため(明確かつ正確に)、このソートロジックは使用できません。次に、Journalctlは単調なタイムスタンプ(つまり開始から経過した時間)に基づいてアイテムをソートしようとします。このソートは同じ条件でのみ機能します。つまり、同じブートの行を単調な時間でのみソートできます。これは、壁時計の時間を通して2つの線を比較する最後のアプローチを取ることを意味します。しかし、これは常に1970年です。したがって、見てわかるように、インターレース、ラインがすべて一緒に混合される現象が発生します。

これを確認する1つの方法は、journalctl --list-boots日付範囲を実行して確認することです。重複している場合、Journalctlは偽のタイムスタンプを使用します。

おすすめ記事