1. カーネル開発プロセスへの手引き

本書は、開発者(およびその上司)が開発コミュニティと一緒に作業する際のフラストレーションを最小限にすることを目的としています。ここでは、Linux カーネル(または一般のフリーソフトウェア)の開発に特に深い知識を持たない人でも理解できる形で、このコミュニティの仕組みを文書化しようとしています。一部には技術的な内容もありますが、本書の多くはプロセス志向の議論であり、その内容を理解する上でカーネルのプログラミングに関する深い知識は不要です。

1.1: エグゼクティブサマリー

本セクションは、カーネル開発プロセス全般の話題と、開発者やその上司の方が遭遇しがちなフラストレーションについて述べています。カーネル・コードを公式の(メインライン)カーネルにマージすることが必要な理由は非常に多く、たとえばユーザーにとって自動的に利用可能になること、様々な形でのコミュニティのサポートが得られること、カーネル開発の方向付けに影響を及ぼすことが可能になることなどの理由があります。なおLinux カーネル用に提供されるコードは、GPL互換の使用許諾で利用可能なものでなければなりません。

セクション2では、開発プロセス、カーネルのリリース・サイクル、およびマージ・ウィンドウの仕組みについて紹介し、パッチの開発、レビュー、マージ・サイクルの各フェーズについて説明します。また、一部にはツールやメーリングリストに関する説明も含まれます。カーネル開発に参入しようと志す開発者の最初の課題としては、バグの追跡と修正から始めるがお勧めです。

セクション3は、早い段階のプロジェクト計画について述べており、できるだけ早めに開発コミュニティを巻き込むことの重要性を強調しています。

セクション4はコーディング・プロセスについて、他の開発者が遭遇したことのあるいくつかの落とし穴について説明しています。パッチに対するいくつかの要件について述べ、またカーネル・パッチに間違いがないことの確認に役立つ一部のツールについて紹介しています。

セクション5では、パッチをレビューしてもらうために公開するプロセスについて説明します。開発コミュニティにまともに見てもらうためには、パッチは正しいフォーマットで、適切な説明を付けて、適切な場所に送付しなければなりません。このセクションに示されたアドバイスに従うことにより、その成果物が最適な形で受け入れられるようになります。

セクション6はパッチを公開した後に何が起きるかについて説明しています。この時点で、作業は完了までにまだまだ程遠い状態です。レビューアとの連携作業は開発プロセスの中で特に重要な部分ですが、ここでは、この重要な段階での問題発生を避けるための多くのヒントを提供しています。開発者は、パッチがメインラインにマージされたことで自分の仕事が終わったと考えてしまわないよう、注意が必要です。

セクション7では、gitによるパッチ管理や、他人が公開したパッチのレビューなど、より上級の話題をいくつか紹介します。

セクション8、および、9では全体の結論をまとめ、またカーネル開発の詳しい情報が得られるソースへのリンクを示します。

1.2: 本書のねらい

Linuxカーネルは、1000人を大きく超えるコントリビュータ(貢献者)の協力による、現時点で世界最大クラスの最もアクティブなフリーソフトウェア・プロジェクトの一つであり、そのプログラムの規模は600万行を超えています。1991年にわずかな規模で開始されたこのカーネルは、今では最も優れたオペレーティングシステムへと進化し、ポケットサイズのデジタル音楽プレーヤからデスクトップPC、さらには現存する世界最大級のスーパーコンピュータに至るまでの、またこれらシステムの中間に位置するあらゆるシステムで使われています。Linuxは、ほとんどあらゆる場面に対応可能な、堅牢で効率のよい拡張性に優れたソリューションです。

Linuxの成長に伴い、その開発への参加を希望する開発者(および企業)の数も増加しています。ハードウェア・ベンダーは、Linuxユーザーにとって自社の製品が魅力的なものとなるよう、Linuxが彼らの製品をサポートすることを望んでいます。Linuxを製品の一部として使う組み込みシステムのベンダーは、Linuxが彼らの製品の機能を十分に引き出すことを望んでいます。Linuxをベースとする製品の販売業者やその他のソフトウェア・ベンダーは、Linuxカーネルの能力、性能、および信頼性に対して関心を持っています。また、エンドユーザーの場合も、そのニーズに沿わせるための変更を望むことも多いでしょう。

Linuxが人々を魅了する素晴らしい特長のひとつは、これら開発者がLinuxにアクセスできることです。すなわち、要求されるスキルを持つ人なら誰でもLinuxを改良することや、その開発の方向に影響を与えることができます。プロプラエタリーな(独自に開発された)製品の場合には、フリーソフトウェアのプロセスに特有なこの種のオープンさは得られません。とりわけ、このカーネルは他のフリーソフトウェア・プロジェクトよりも更にオープンなものです。平均すると3ヵ月のカーネル開発サイクルには100社以上、さらには企業以外からも含め、合計で1000人を超える開発者が関与しています。

カーネル開発コミュニティとの共同作業は特に難しいものではありません。しかし、そうは言うものの、多くの新規参加者がカーネルに関する作業を行おうとしたとき、その困難さを経験しています。カーネル・コミュニティは、毎日数千行ものコードが変更されていくという環境の中で、その運営が円滑に行えるよう(また高品質な製品が実現できるよう)、独特な運営方法を進化させてきました。このようなことから、Linuxカーネルの開発プロセスがプロプラエタリな製品の開発方法とは大きく異なるということは特に驚くべきことではありません。

Linuxカーネルの開発プロセスは新規参入の開発者にとっては奇妙で威嚇的なものに見えるかもしれませんが、その背景にはそれ相当の理由があり、また多くの経験に基づいています。カーネル・コミュニティのやり方を理解しようとしない開発者(更に悪いのはその方法を無視したり、迂回したりする開発者)には挫折感を伴うような困難が待ち構えています。開発コミュニティは、学習しようとする人を手助けしますが、他人に耳を傾けない人や開発プロセスに無関心な人のために費やす時間はありません。

この文書は、これを読んだ開発者がそのようなフラストレーションを避けられることを望んで作成されています。本書には実質的な内容が多く含まれており、これをよく読むことにより、短時間ですぐに元がとれます。開発コミュニティはカーネルの改良に協力できる開発者を常に必要としています。以下はそのような人や、またはあなたの部下に役立つはずです。是非、このコミュニティに参加してください。

1.3: コードを「メインライン」にマージすることの重要性

なぜカーネル・コミュニティとの共同作業の方法やコードのメインライン・カーネルへのマージの方法を学ぶ必要があるのかについて、疑問に思う企業や開発者が存在します(「メインライン」とは、Linus Torvaldsが管理している、各Linuxディストリビュータがベースとして使うカーネルのことです)。短期的に見れば、コードの提供(コントリビューション)に費用をかける必要はないと思えるかもしれません。すなわち、自分のコードは別途管理し、ユーザーを直接サポートする方が簡単に思えます。しかし実際は、コードを別途(「ツリー外で」)管理することは不経済なのです。

ツリーから外れたコードのコストを示す方法として、ここではカーネル開発プロセスに関係するいくつかの側面を示します。またこれらのほとんどは本書の中でも詳しく検討します。以下を十分に考えてみて下さい。

  • メインライン・カーネルにマージされたコードはすべてのLinuxユーザーが利用できます。すなわち、それを含んだ意すべてのディストリビューションに自動的に含まれることになります。ドライバ・ディスクやダウンロード等も不要になり、また複数のディストリビューション、複数のバージョンに対応する煩雑さもなくなります。これは開発者にとっても、またエンドユーザーにとっても同様です。メインラインにマージすることで、配布とサポート上の多数の問題が解決します。
  • カーネルの開発者はユーザー空間における安定的なインタフェースを維持するように努めていますが、反面、カーネルの内部APIは常に流動的です。安定的なカーネル内部インタフェースを定めないことは、実は意図的な設計方針であり、これはいつでも基本的な改良を行って高品質のプログラムを実現できるようにするためなのです。しかし、この方針の一つの結果として、ツリーから外れたプログラムは新しいカーネルを使うための維持管理が常に必要となります。ツリーから外れたコードを維持するには、そのコードを単に動作させるためだけでも相当な作業が必要になります。

これに対しメインラインに含まれたコードの場合、API変更のために使えなくなったコードはその開発者が修正するという単純なルールがあるため、このような作業は不要となります。そのため、メインラインにマージされたコードの場合、その維持費用は非常に小さくなります。

  • それだけでなく、カーネル内のコードは他の開発者によって頻繁に改良されます。ユーザー・コミュニティや顧客に自社の製品を改良する権限を与えることにより、すばらしい結果が得られます。
  • カーネルのコードはメインラインへのマージの前後にレビューの対象となります。開発者のスキルがどんなに高くても、このレビュー・プロセスでは常にそのコードを改良する方法が見つかります。またレビューによって重大なバグやセキュリティ問題が発見される場合も多くあります。これは閉じられた環境で開発されたコード(たとえば内部の開発者だけでのみ開発、レビューを行った)の場合に特に顕著であり、そのようなコードは外部の開発者によるレビューで多くの利益が得られます。ツリーから外れたコードは低品質です。
  • 開発プロセスに参加することで、カーネル開発の方向に影響を与えることができます。横から苦情を言うユーザーの意見も重要ですが、アクティブな開発者の意見はより強く、また必要性に合わせてカーネルを改良するための変更を行うことも可能です。
  • コードを別に管理する場合、そのコードと同様な機能を実現する別のコードが他の開発者によりLinuxカーネルにマージされるという可能性が常にあります。そのような場合、自分のコードをマージしてもらうことは(不可能と言えるくらい)極めて困難になります。そうなると、(1) ツリーから外れた非標準の機能を永久に維持するか、(2) 自分のコードを捨て、ユーザーにツリー内のバージョンへと移行してもらうか、という不本意な選択肢に直面することになります。
  • コードをコミュニティに提供することは、全体プロセスを機能させるための基本的な行為です。自分のコードを提供することにより、カーネルに新たな機能を追加することができ、同時に他のカーネル開発者が利用できる機能や用例も提供することができます。あなたがLinux用のコードを開発したのであれば(または開発を検討中であれば)、このプラットフォームが継続して成功することに明らかな関心があるはずですが、コードの提供はその成功を確実にするための最も適切な方法の一つです。

上に示した理由は、全て、プロプラエタリなバイナリ形式で提供されるものも含め、ツリーから外れたカーネル・コードのすべてに当てはまります。しかし、バイナリのみのカーネル・コードの配布を検討する時に考慮すべき別の要素があります。これには以下の内容が含まれます。

  • プロプラエタリなカーネル・モジュールの配布には法的な問題がつきまとい、少なくとも灰色の問題として存在します。すなわち多くのカーネル著作権保持者は、バイナリ・モジュールをカーネルから派生したプロダクトと考えており、従ってその配布はGNUの一般公有使用許諾に違反するものと考えます(これについては以下に補足します)。なお、本文書の筆者は法律家ではないため、ここに示す内容は決して法律上の助言として考えられては困りますが、ソースが公開されていないモジュールの法的地位は法廷でのみ判断されます。しかし、いずれにしても、これらモジュールには常に不確実性がつきまといます。
  • バイナリ・モジュールは、カーネルの問題のデバッグを非常に難しくするため、ほとんどのカーネル開発者はデバッグそのものを行おうともしません。そのため、バイナリ・モジュールのみの配布をする場合、ユーザーはコミュニティからのサポートを得ることが困難になります。
  • また、対象とするすべてのカーネル・バージョンやディストリビューションについて対応するモジュールを提供しなければならないため、バイナリ・モジュールの配布者にとってもサポートが困難になります。妥当と考えられる範囲に対応するだけでも、1個のモジュールについて数10ものビルドが必要となる場合もあり、また、ユーザーはカーネルのアップグレードを行う都度、そのモジュールのアップグレードも別途必要になります。
  • コード・レビューに関して既に述べた内容は、ソースが非公開のコードの場合は2倍に意味をもちます。このコードは全く公開されないため、コミュニティによるレビューも行われず、疑いの余地もなく、将来にわたり重大な問題を抱えこみます。

特に組み込みシステムのメーカーの場合、自己完結型の製品が出荷されること、固定されたカーネル・バージョンが使われ、リリース後の開発は不要なことから、これまでに述べた内容を無視したいという誘惑に駆られる場合があります。この考え方は広範囲にわたるコード・レビューの価値を見逃しており、またユーザーに製品への機能追加を許可することの価値も見逃しています。しかし、これら製品もその商品寿命は限られており、その後は新バージョンのリリースが必要です。その場合、メインラインにあり、うまく維持されてきたコードを持つベンダーは、新製品を短時間で市場に投入することができるという点で特に有利な立場となります。

1.4: 使用許諾

Linuxカーネルへのコード提供は複数の使用許諾契約に基づいて行われますが、コードはすべてカーネル全体の配布をカバーするGNU一般公衆使用許諾契約バージョン2 (GPLv2)と互換性を持つことが必要です。このことは、実際には提供されるすべてのコードがGPLv2(オプションとして、GPLの将来バージョンによる配布の許可を含めることもできる)、または、3箇条のBSD使用許諾に対応している必要があることを意味しています。カーネルへのコード提供は、適合する使用許諾契約が結ばれていない場合は受け付けられません。

カーネル用に提供されたコードに関する著作権の譲渡は不要です(要求もされません)。メインライン・カーネルにマージされたコードはすべて、その当初の所有権が保持されます。その結果、現在Linuxカーネルには数千人の所有者が存在します。

この所有権構成は、カーネルの使用許諾契約を変更しようとする試みはほぼ確実に失敗するということを意味しています。すべての著作権者の合意を得る(またはそのコードをカーネルから削除する)ことができる現実的なシナリオはほとんどありません。そのため、予測可能な将来においてバージョン3のGPL(GPLv3)へと移行する見込みもありません。

カーネル用に提供されるコードは合法的なフリーソフトウェアであることが必須です。この理由から、匿名(または変名)のコントリビュータのコードは受け付けられません。すべてのコントリビュータに対し、そのコードがGPLによりLinuxカーネルと共に配布可能な旨を述べた「サインオフ(承諾)」を行うことが求められます。その所有者からフリーソフトウェアとしての使用許諾が行われていないコード、またはカーネルの著作権に関係する問題が発生するおそれのあるコード(適切な予防措置を講じることなくリバース・エンジニアリングにより得られたコードなど)については、貢献を行うことができません。

著作権に関係する問題についての質問はLinux開発のメーリングリストでもよくある質問です。通常、そのような質問に対する回答は多く寄せられますが、これらの質問に答えている人々は法律家ではなく、したがって、その助言は法律上の助言ではないということに留意しておくことが必要です。Linuxのソースコードに関する法律的な質問がある場合、この分野に造詣の深い法律家に相談する以外の選択はありません。技術的なメーリングリストで得られた回答を信頼することは危険です。