ホームページ  >  記事  >  運用・保守  >  Linux ABI について 10 分で学ぶ

Linux ABI について 10 分で学ぶ

WBOY
WBOY転載
2023-08-03 16:33:04987ブラウズ

十分钟让你了解 Linux ABI

LCTT 翻訳注: 昨日、AlmaLinux は、RHEL との 1:1 互換性を放棄しますが、RHEL との ABI 互換性は維持すると発表しました。 RHEL 上で実行されるソフトウェアは、AlmaLinux 上でシームレスに実行できます。 ABI の概念についてよく理解していない学生もいるかもしれないので、誰でも理解できるようにこの記事を翻訳しました。

多くの Linux 愛好家は、Linus Torvalds の有名な警告「私たちはユーザー空間を破壊しません」をよく知っていますが、おそらくこの文を聞いた人全員がその意味を認識しているわけではありません。

この「最初のルール」は、アプリケーションとカーネル間の通信と構成に使用されるアプリケーション バイナリ インターフェイス (ABI) の安定性について開発者に思い出させます。以下の内容は、読者に ABI の概念を理解してもらい、ABI の安定性が重要である理由を説明し、Linux の安定した ABI に含まれるものについて説明することを目的としています。 Linux の継続的な成長と進化には ABI への変更が必要であり、その一部は物議を醸しています。

ABI とは何ですか?

ABI は、アプリケーション バイナリ インターフェイスの略です。 ABI の概念を理解する 1 つの方法は、ABI が他の概念とどのように異なるかを考慮することです。多くの開発者にとって、アプリケーション プログラミング インターフェイス (API) の方が馴染みがあります。通常、ライブラリのヘッダー ファイルとドキュメントは、

HTML5

などの標準ドキュメントとともに API とみなされます。ライブラリを呼び出したり、文字列形式でデータを交換したりするプログラムは、API で説明されている規則に従う必要があります。そうしないと、予期しない結果が生じる可能性があります。

ABI は、コマンドの解釈方法とバイナリ データの交換方法を指定するという点で API に似ています。 C プログラムの場合、ABI には通常、関数の戻り型と引数リスト、構造体のレイアウト、列挙型の意味、順序、および範囲が含まれます。 2022 年の時点で、Linux カーネルは依然としてほぼ完全に C プログラムであるため、これらの仕様に準拠する必要があります。

カーネル システム コール インターフェイス

」の説明は、「

Linux マニュアル セクション 2」にあり、ミドルウェア アプリケーションから呼び出すことができる同様の関数が含まれています。 . C バージョンの mountsync の関数。これらの関数のバイナリ レイアウトは、Linux ABI の最初の重要な部分です。 「Linux 用の安定した ABI には何が含まれていますか?」という質問に対して、多くのユーザーや開発者は「sysfs (/sys) と procfs (/proc) の内容」と答えます。実際、公式 Linux ABI ドキュメントは主にこれらの 仮想ファイル システムに焦点を当てています。 前のセクションでは、Linux ABI がプログラムでどのように使用されるかに焦点を当てましたが、同様に重要な人的要因については説明していませんでした。以下の図に示すように、ABI の機能には、カーネル コミュニティ、C コンパイラ (GCC

clang など)、およびユーザー空間 C ライブラリの作成が必要です。 (通常は glibc )、および Executable and Linkable Format (ELF) でレイアウトされたバイナリ アプリケーション。

開発コミュニティ内でのコラボレーション

十分钟让你了解 Linux ABI

なぜ ABI を気にするのでしょうか?

Torvalds 氏自身による Linux ABI の安定性保証により、Linux ディストリビューションと個々のユーザーはオペレーティング システムの影響を受けることなくカーネルを独立して更新できます。

Linux 用の安定した ABI がなければ、セキュリティ問題に対処するためにカーネルにパッチを適用する必要があるたびに、オペレーティング システムのほとんどまたはすべてを再インストールする必要があります。バイナリ インターフェイスの安定性が、Linux の使いやすさと広く普及する上で重要な要素の 1 つであることは明らかです。

十分钟让你了解 Linux ABIターミナル出力

上の図に示すように、カーネル (linux-libc-dev 内) と Glibc ( libc6-dev ) はすべて、ファイルのアクセス許可を定義するビット マスクを提供します。明らかに、これら 2 つの定義セットは一致する必要があります。 apt パッケージ マネージャーは、パッケージによって提供される各ファイルを識別します。 Glibc ABI の潜在的に不安定な部分は、bits/ ディレクトリにあります。

Linux ABI の安定性保証は、ほとんどの場合に適切に機能します。 コンウェイの法則コンウェイの法則によると、開発プロセス中に発生する厄介な技術的問題は、多くの場合、さまざまなソフトウェア開発コミュニティ間の誤解や意見の相違が原因であり、これらのコミュニティはすべて Linux に貢献しています。上の図に示すように、さまざまなコミュニティ間のインターフェイスは、Linux パッケージ マネージャーのメタデータを通じて容易に想像できます。

Y2038: ABI 破損の例

Linux ABI は、現在進行中で ゆっくりと発生している「2038 年」の ABI 破損の例を考慮すると、よりよく理解できます。 2038 年 1 月には、古い車両の走行距離計と同じように、32 ビットのタイム カウンタがすべて 0 に戻ります。 2038 年 1 月というとまだ遠いように聞こえるかもしれませんが、現在販売されている IoT デバイスの多くはまだ稼働していると考えて間違いありません。今年設置された スマート メータースマート パーキング システム などの一般的な製品は、32 ビット プロセッサ アーキテクチャを使用している可能性があり、ソフトウェア アップデートをサポートしていない可能性があります。

Linux カーネルは、後の時点を表すために 64 ビット time_t 不透明データ型の使用に内部的に切り替えられました。これは、time() のようなシステム コールの関数シグネチャが 64 ビット システムで変更されたことを意味します。これらの努力の範囲は、データ構造の新しいバージョンと _old バージョンが配置されているカーネル ヘッダー ファイル (time_types.h など) で明らかにわかります。

十分钟让你了解 Linux ABI走行距離計ロールオーバー

Glibc プロジェクトは 64 ビット時間もサポートしているので、準備は完了ですよね?残念ながら、Debian メーリング リスト での議論によれば、これは事実ではありません。ディストリビューションは、32 ビット システム用のすべてのバイナリ パッケージの 2 つのバージョンを提供するか、インストール メディア用の 2 つのバージョンを提供するかの難しい選択に直面しています。後者の場合、32 ビット時間のユーザーはアプリケーションを再コンパイルして再インストールする必要があります。いつものように、独自のアプリケーションは本当に頭の痛い問題です。

Linux 安定版 ABI には正確に何が含まれていますか?

安定した ABI を理解するのは少し難しいです。考慮すべき点は、sysfs の大部分は安定した ABI ですが、デバッグ インターフェイスはカーネルの内部をユーザー空間に公開するため、明らかに不安定であるということです。 Linus Torvalds はかつて「ユーザー空間を壊すな」と言ったことがありますが、通常彼が意味したのは、カーネルのドキュメントやソース コードを読んで確認できるべきシステム プログラマやカーネル エンジニアではなく、「ただ機能したいだけ」の一般ユーザーを保護することです。バージョン間で何が変わったのか。下の図はこの違いを示しています。

十分钟让你了解 Linux ABI安定性の保証

平均的なユーザーが Linux ABI の不安定な部分を操作する可能性はほとんどありませんが、システム プログラマは意図せず操作してしまう可能性があります。 sysfs (/sys) および procfs (/proc) のすべての部分は、/sys/kernel/debug を除いて安定しています。

ユーザー空間に表示される他のバイナリ インターフェイス (/dev のデバイス ファイル、カーネル ログ ファイル (dmesg コマンドで読み取ることができる) など) についてはどうでしょうか。ファイル システムのメタデータ、またはカーネルの「コマンド ライン」で提供される「ブート パラメータ」(GRUB や u-boot などのブート ローダーで表示されます)?もちろん、「状況によります」。

古いファイル システムのマウント

Linux システムが起動中にハングするという事実のほかに、ファイル システムをマウントできないことが最も残念です。ファイル システムが有料顧客の SSD 上にある場合、問題は非常に深刻です。古いカーネル バージョンでマウント可能だった Linux ファイルシステムは、カーネルがアップグレードされてもマウント可能であるはずですよね。実際のところ、それは「場合による」のです。

2020 年、負傷した Linux 開発者 がカーネル メーリング リストで苦情を申し立てました :

カーネルは、これをエラーやエラーもなく有効なマウント可能なファイル システム形式として受け入れました。あらゆる種類の警告が表示され、何年もこのように確実に動作しています...私は一般に、既存のルート ファイルシステムのマウントはカーネル<->ユーザー空間またはカーネル<->定義された既存のシステム境界の範囲に属すると常々考えてきました。カーネルによって受け入れられ、既存のユーザー空間で正常に使用されるものによって決まります。カーネルのアップグレードは、既存のユーザー空間およびシステムと互換性がある必要があります。

しかし、問題があります。これらのマウントできないファイル システムは、カーネルによって定義されているが使用されていないフラグに依存する独自のツールを使用して作成されています。このフラグは Linux の API ヘッダー ファイルや procfs/sysfs には表示されませんが、実装の詳細です。したがって、ユーザー空間コードでこのフラグを解釈することは、「未定義の動作」というほぼすべてのソフトウェア開発者を震え上がらせるフレーズに依存することを意味します。カーネル コミュニティが内部テストを改善し、新しい整合性チェックに取り組み始めたとき、「man 2 mount」システム コールが突然、独自形式のファイル システムを拒否し始めました。この形式の作成者は明らかにソフトウェア開発者であったため、カーネル ファイルシステムの保守者から共感を得ることができませんでした。

十分钟让你了解 Linux ABI工事標識には、作業員が木の上で作業していると書かれています

スレッドカーネルの Dmesg ログ

/dev ディレクトリ内のファイル形式は安定していることが保証されていますか?または不安定ですか? dmesg コマンドは、ファイル /dev/kmsg からコンテンツを読み取ります。 2018 年、開発者は dmesg 出力のスレッド を実装し、カーネルが「同時実行による中断や干渉を受けることなく、一連の printk() メッセージをコンソールに出力できるようにしました」他のスレッドの printk()"。いいですね!スレッド化は、/dev/kmsg 出力の各行にスレッド ID を追加することで実現されます。注意を払っている読者であれば、この変更により /dev/kmsg の ABI が変更されることがわかります。つまり、このファイルを解析するアプリケーションもそれに応じて変更する必要があります。多くのディストリビューションは新機能を有効にしてカーネルをコンパイルしないため、/bin/dmesg のほとんどのユーザーはこれに気付かないかもしれませんが、この変更により GDB デバッガ を読み取る機能が壊れます。カーネルログ。

確かに、賢明な読者は、デバッガは開発者ツールであるため、GDB のユーザーは運が悪いと考えるでしょう。新しい

/dev/kmsg 形式をサポートするために更新する必要があるコードは、カーネル独自の Git ソース コード リポジトリの「ツリー内」部分にあるため、これは実際には当てはまりません。通常のプロジェクトの場合、単一のコードベース内のプログラムが連携できないことは明らかなバグであるため、GDB がスレッド化された /dev/kmsg で動作できるようにする パッチがマージされました。

BPF プログラムについてはどうですか?

BPF は、実行中のカーネルでリアルタイムに監視し、構成することもできる強力なツールです。 BPF は元々、システム管理者がコマンド ラインからその場でパケット フィルターを変更できるようにすることで、リアルタイムのネットワーク構成をサポートするように設計されました。 Alexei Starovoitov らは、任意のカーネル関数のトレースを可能にするために BPF を大幅に拡張しました。トレースは明らかに開発者の領域であり、一般ユーザーの領域ではないため、明らかに ABI 保証の対象ではありません (ただし、bpf() システム コール には他のシステム コールと同じ安定性が保証されています)。一方、新しい機能を作成する BPF プログラムは、カーネルを拡張する事実上の標準手段としてカーネル モジュールを置き換える可能性を提供します。カーネル モジュールは、デバイス、ファイル システム、暗号化、ネットワーキングなどを適切に動作させるものであり、「動作させたいだけ」という平均的なユーザーが依存する機能であることは明らかです。問題は、ほとんどのオープンソース カーネル モジュールとは異なり、BPF プログラムは伝統的にカーネル ソース コードに含まれていないことです。 2022 年の春、幅広いヒューマン インターフェイス デバイス (マウスやキーボードなど) にデバイス ドライバー パッチの代わりにミニ BPF プログラムを使用するという

提案

が注目されました。サポート。 白熱した議論が続きましたが、問題は明らかに

オープンソース サミットでの Torvalds のコメントで解決されました

:

彼は、「通常の (カーネル開発者ではない) ユーザーが使用する実際のユーザー空間ツール」を壊す場合は、eBPF が使用されているかどうかに関係なく、それを修正する必要があると指摘しています。

カーネル更新後も BPF プログラムが動作することを望む開発者は、カーネル ソース コード リポジトリ内のまだ指定されていない場所にプログラムをコミットする必要があるというコンセンサスが得られつつあるようです。 。 BPF と ABI の安定性に関してカーネル コミュニティがどのようなポリシーを採用するかに注目してください。

結論

カーネルの ABI 安定性保証は、procfs、sysfs、およびシステム コール インターフェイスに適用されますが、重要な例外があります。カーネルの変更により「ツリー内」コードまたはユーザー空間アプリケーションが破損すると、多くの場合、問題のあるパッチはすぐにロールバックされます。カーネル実装の詳細に依存する独自のコードの場合、これらの詳細はユーザー空間からアクセスできますが、保護されておらず、問題が発生した場合の同情は限られています。 2038 年問題のような問題により ABI の破綻が避けられない場合、可能な限り計画的かつ体系的な方法で移行が行われます。また、BPF プログラムのような新機能は、ABI の安定性の境界について未解決の疑問を引き起こします。

謝辞

以前のサポートについて、

Akkana PeckSarah R. NewmanLuke S. Crawford に感謝します。マテリアルのバージョン。コメント。

以上がLinux ABI について 10 分で学ぶの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
前の記事:Nginx - 最小構成次の記事:Nginx - 最小構成