2022 年 07 月 19 日 Yocto Project よもやま話
先月の予告とおり、今回は Linux の 2038 年問題について情報を提供していきます。
1969 年に誕生した Unix では、時刻の表現に 1970 年 1 月 1 日 0 時 0 分 0 秒 (GMT)からの経過秒数を採用しています。Unix 類似 OS として開発されてきた Linux も同様に 1970 年 1 月 1 日 0 時 0 分 0 秒 (GMT) を 0 としています。
C 言語の標準仕様である ISO/IEC 9899:1999 では、時刻表現に使用する型として time_t を用いるという定義がありますが、型名の定義であり範囲や精度は実装依存となっています。
伝統的な実装で、 time_t として符号付 32 ビット整数を採用するものが多かったのですが、最大値 231 - 1 (2,147,483,647) 秒を越えると、負として扱われてしまいます。つまり、1970 年 1 月 1 日午前 0 時 0 分から 2,147,483,647 秒経過した 2038 年 1 月 19 日午前 3 時 14 分 7 秒を過ぎると、時刻データの先頭ビットに 1 が立ち、1970 年 1 月 1 日から 2,147,483,647 秒前の 1901 年 12 月 13 日 20 時 45 分 52 秒となってしまいます。
time_t に 32 ビット整数型を使用する場合、2038 年 1 月 19 日以降は使用できない状況となっていました。
32bit アーキテクチャ向け Linux カーネルは、元々 time_t 型は符号付 32 ビット整数を採用していましたが、一部を除いて Kernel 5.6 から符号付 64 ビットで表現する変更が行われています。また、kernel 5.6 で行われた対応は、 5.5/5,4 へのバックポートが行われており、kernel 5.4 を使用する Yocto3.1 (LTS) dunfell 向けのカーネルも対応が行われています。
カーネルで time_t を 64 ビットに対応するとともに、ユーザーランド側も 64 ビットに対応しなと、システムとして正常に動作しません。具体的には、時間関係を扱る標準 C ライブラリも対応する必要があり、組込みも含めて多くのLinux カーネルと共に使用されている GNU プロジェクトが提供する glibc では 2021 年 9 月のリリース 2.34 にて対応が行われており、Yocto 3.4 のリリースに含まれています。
Yocto3.4 で提供される glibc 自体は、time_t 64bit に対応していますが、glibc とリンクを行うプログラムを構築する場合は、"-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" と 2 つのオプションを明示的に指定する必要があります。過去のシステムとの互換性を重視する考えから、明示的にオプションを設定しない場合 time_t は 32bit として扱う方針となっています。
glibc2.35 が提供されている Yocto4.0 上で qemuarm (32bit) 向けに core-image-base の構築を行ったところ、date コマンドなどを含む core-utils のレシピから生成されるパッケージは、configure 実行時に m4/year2038.m4 の処理を実行し、特に指定を行わなくても "-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" が有効となって構築が行われており、2038 年 1 月 19 日以降の日時を指定して日付の設定が行えることは確認できたのですが、全てのユーザーランドのプログラムがオプションをつけて構築されている状況ではないため、暫くすると動作が不安定になり、リブート不能・再起動不能といった不整合が発生します。
システム全体の構築時に、"-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64" を有効とした場合、glibc や zlib のレシピ構築時にエラーとなりますが、個別に対応することで動作する環境が確認できております
local.conf への追加 TARGET_CPPFLAGS:append = " -D_FILE_OFFSET_BITS=64" TARGET_CPPFLAGS:append = " -D_TIME_BITS=64 " glibic_%.bbappned 及び zlib_%.bbappend での記述 TARGET_CPPFLAGS:remove = "-D_FILE_OFFSET_BITS=64" TARGET_CPPFLAGS:remove = "-D_TIME_BITS=64"
Yocto Projectでは、使用する libcを TCLIBC 変数で指定可能となっています。 現在は、デフォルトで glibc が指定されていますが、"musl" や "newlib" 等も利用可能となっています。musl では 2020 年 2 月にリリースとなった v1.2.0 にて time_t の 64bit への対応がおこなわれています。
Yocto4.0.1 及び Yocto3.1.17 で、MACHINE に qemuarm を指定し、以下の記述を local.conf に追加して構築した core-image-full-cmdline において、2038 年 1 月 19 日以降の日時を設定して、動作確認が行えております。
local.conf への追記 TCLIBC = "musl"
musl を使う上での注意点ですが、Functional differences from glibc において説明されている相違点があります。
以下、気になった点を挙げておきます。
ファイルシステムでは、管理用の時刻データが 64 ビットになっていないと、2038 年を越えて利用することができません。
ext4 や、つい最近対応が行われた XFS は 2038 年以降も使用可能です。組込みで良く利用される jffs2 や squashfs は符号なし 32bit で時刻管理をしているため 2106 年まで使用可能ですが、現時点で以下のファイルシステムは 2038 年問題に対応できていません。
次回のテーマは「Yoctoへの道」 Yocto Project がどのように始まったのか、その前史もふくめて解説していきます。
2024 年 09 月 02 日 Vigiles サポート
2024 年 03 月 01 日 Vigiles サポート
2023 年 08 月 28 日 Vigiles サポート
2024 年 03 月 26 日 Yocto Project よもやま話
2023 年 07 月 25 日 Yocto Project よもやま話
2023 年 06 月 20 日 Yocto Project よもやま話
2024 年 01 月 10 日 Linux 技術ネタ
2023 年 12 月 12 日 Linux 技術ネタ
2023 年 03 月 31 日 Linux 技術ネタ
2024 年 07 月 26 日 イベントレポート
2024 年 07 月 09 日 イベントレポート
2024 年 06 月 03 日 イベントレポート
2023 年 05 月 30 日 リクルート
2022 年 12 月 27 日 リクルート
2022 年 09 月 27 日 リクルート
2024 年 09 月 25 日 信州リネオ便り
2024 年 08 月 20 日 信州リネオ便り
2024 年 08 月 07 日 信州リネオ便り
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 10 日 ソリューション統括部
2019 年 12 月 13 日 マーケティング統括部
2019 年 04 月 25 日 マーケティング統括部
2018 年 12 月 18 日 マーケティング統括部