Linuxカーネルが難しい?Rustで実装できそう!
「ついに、RustでLinuxカーネルを実装できる!」
待ち望んだ感を出してみましたが、2年前に記事を書いてから、すっかり忘れていました。LinuxカーネルのRustサポートについての意見を求められたら、「技術的には面白いけど、実用レベルではないね。」と、上から目線の回答でエンジニアレベルの高さをアピールするつもりでしたが、2年間の間、誰にも聞かれませんでした。
近々、LinuxカーネルにRustサポートが取り込まれそう、ということで、デバイスドライバを実装してみました。
Rust対応カーネルのコンパイル
まずは、Rust対応を有効にしたLinuxカーネルをコンパイルする必要があります。「カーネルってコンパイルするものなの?」という読者は、ネットの長老たちに叡智を求めましょう。「インストール直後に、メモリ削減のために不要な機能を無効にして、カーネルコンパイルしたんじゃ。」というような、太古の物語を聞きながら、やり方を教わってください。
「Rustのカーネルコンフィグオプション!!」と興奮を抑えられない読者は下図をどうぞ。
Rust用API
Rust版デバイスドライバは、バインディングと抽象化という、2種類のAPIを利用することができます。
前者のバインディングAPIは、カーネルのC言語のAPIを呼び出すもので、自動的にRustのコードが生成されます(RustのFFI機能です)。例えば、排他制御のため、カーネルのMutex機能を使うRustのデバイスドライバのコードは以下のようになります。
bindings::mutex_lock(mutex_object);
// fiddle around with shared data
bindings::mutex_unlock(mutex_object);
Rustの利点が全くないので、Cで実装したほうがよさそうですね!
アプリケーションで用いられるRustライブラリのMutexは、Mutexオブジェクトが保護対象のデータをラップし、ロックを保持せずに、データにアクセスすることが不可能です。また、Mutexのロックは適切に解放されます。
後者の抽象化APIは、バインディングAPIを内部で利用して、Rustライブラリとほぼ同様のインターフェイスを実現しています。Mutexの抽象化APIを使ったデバイスドライバのコードは以下のようになります。
{
let mut shared_data = mutex.lock();
// fiddle around with shared data
}
// the mutex is released here
これなら、RustライブラリのMutex同様、C言語で実装する排他制御で発生しやすいバグを防ぐことができそうですね。
ドキュメントには、通常のデバイスドライバは抽象化APIのみを使え、サブシステム(ネットワーク、ファイルシステム、SCSIなど)がバインディングAPIを使って抽象化APIを実装しろ、と書かれています。
デバイスドライバを実装
前回の記事で、「Rustのデバイスドライバは意味のある機能を実装できない」と書いたので、今回は、意味のある機能を実装したいですよね。問題は、筆者が意味のある仕事をしてないので、何も実装するものがないことです。
今回は、デバイスファイルに書き込まれたデータを保存し、読み込み時にそのデータを返すキャラクタ型デバイスドライバを実装してみました。メモ機能を実現するデバイスドライバです!
デバイスドライバのコードは抽象化APIを使い、キャラクタデバイスの登録、read/writeデバイスファイルオペレーションの実装、Mutexによるバッファの管理などを実装しています。
非同期プログラミングとカーネル
Rustサポートは、Rustの非同期処理モデル、async/awaitもLinuxカーネルに持ち込もうとしています。例えば、1つのカーネルスレッドが複数のネットワークソケットをブロックすることなく処理する機能を、async/awaitでおしゃれに実装できるということです。
この機能は、まだ、Linuxカーネルに含めるように提案されておらず、今後どうなるか分かりませんが、NFSサーバ機能をRustで再実装するとか、カーネル内で動作するgRPCサーバとか、色々と妄想が膨らみますね。
まとめ
LinuxカーネルがRustをサポートする時期は分かりませんが、既存のC言語のデバイスドライバのRustでの書き換えも進められるなど、実際に役立つデバイスドライバを実装できる状態になっています。
まだ、全てのC言語のAPIに対してRust用抽象化APIが実装されていないので、どんなデバイスドライバでも実装できるというわけではありませんが、LinuxカーネルのRustサポートが普及するにつれて、抽象化APIの実装も進むと予想されます。将来的には、デバイスドライバ以外のコンポーネントもRustで実装される可能性もありそうです。
NTTでは、Rustでの低レイヤの開発に興味がある仲間を募集中です。連絡お待ちしています。