
systemdの開発版に、C言語に加えてRustで新しいプログラムを書ける仕組みが追加されました。対象は既存コードと連携する末端のプログラムで、systemdの中核部分をRustへ移す変更ではありません。Rust対応は任意で、ビルド時に有効化できます。
Rust対応は新しい末端プログラムが対象
今回マージされた変更は、Rustでsystemdのプログラムを開発するための基盤です。既存のCコードをRustへ移植する計画はなく、他のコンポーネントが依存する中核コードもRustでは書かない方針です。
RustコードはCとの連携に使うC ABIで接続し、既存のlibsystemd-sharedは動的リンクで利用します。Rust側のクレートは利用するプログラムへ静的リンクされ、Rust標準ライブラリーはプログラムにもlibsystemd-sharedにも入りません。
この仕組みはsystemd 263に向けた変更としてマージされました。Rust対応はMesonの-Drust=オプションで切り替えられ、既定値のautoでは利用可能な環境に応じて有効になります。
Cargoを使わずMesonとbindgenでビルド
RustコードのビルドにはMesonを使い、Cargoは使いません。依存するRustクレートも追加せず、利用範囲はcoreに限定されています。コードはno_stdで、Rust標準のメモリー確保用クレートallocも使いません。
CヘッダーからRustのバインディングを作る処理にはbindgenを使います。ビルド時にsystemdのヘッダーを基に生成し、その上にsystemd_sharedクレートを置いて、ログ出力やエラー処理、コマンドライン解析など、既存のCプログラムに沿った機能を提供します。
ビルドにはrustc 1.85以上、bindgen 0.71.1以上、Meson 1.4.0以上が必要です。Mesonが古い環境では-Drust=autoによりRust対応が無効になり、ディストリビューションのビルドではRust対応を明示的に有効化できます。
既存プログラムに合わせた実行時の仕組み
Rustプログラムは、Cプログラムと同じヘルプ表示やオプション解析の仕組みを使います。--introspect-cliへの応答もC版に合わせ、テストでは両者の出力をバイト単位で比較します。
動的に読み込むライブラリーへの依存関係は、Rustプログラム側で.note.dlopenに宣言します。これは既存のdlopen()による読み込み機構に合わせた扱いで、Rust対応のために共有ライブラリーの仕組みを置き換えるものではありません。
秘密情報を扱う型として、消去処理を伴うVec<u8, Erasing>も用意されます。メモリー確保には独自のBoxやVecを使い、確保に失敗した場合はエラーを返す仕組みです。
新しい鍵管理ツールとサイズ差
Rust対応の最初の利用先として、systemd-keyring-setupが開発されています。このユーティリティーは起動時にカーネルのdm-verity、fs-verity、BPF用キーリングを準備し、X.509証明書を登録する用途です。
ただし、Rust対応基盤のマージと、このユーティリティー自体のマージは別の変更です。systemd-keyring-setupは、必要なCヘルパーやlibsystemd-sharedのラッパーを含む変更とともに準備されています。
最適化を行ったRust版のテスト用実行ファイルは32KB、対応するC版は20KBでした。実際の各プログラムで生じるバイナリーサイズの差は、個別の構成によって異なります。











