25周年を記念するつもりで始めた「Linuxの成長過程をふりかえる」シリーズは前回までで一段落したものの、少し積み残した話題があったので、今回はそれを紹介してみようと思います。
Linuxの特徴を示す言葉のひとつに、Eric Reymond氏が「伽藍とバザール」の中で指摘した「早めの公開、しばしば公開(release early, release often)」があります。
Linux以前にも、X Window SystemやGNUプロジェクトの「フリーソフトウェア」のように、ソースコードを公開してユーザーからのフィードバックを受けつけるソフトウェアはあったものの、それらのバージョンアップは多くても年に数回程度でした。
それに対しLinuxでは、利用者からのフィードバックを積極的にソースコードに反映し、最初期のころから頻繁なバージョンアップを繰り返していました。その結果、雪ダルマ式に利用者や開発者が増えていき、前代未聞の成長が実現することになった、というのが彼の指摘です。
さて、それでは実際にどれくらいの頻度と規模でLinuxはバージョンアップしてきたのでしょう? 前回までに紹介したlinux-1.1シリーズから2.5シリーズの公開日とファイルサイズを元に調べてみました。
バージョンアップに要した日数
linux-1.0が公開された1994年3月13日を起源とすると、linux-1.1.13が公開された1994年5月23日はその71日後、2.3.0が公開された1999年5月11日は1885日後となります。
このように公開日を1.0からの経過日数に換算して、バージョンが一つ上がるまでに要した日数を数えてみたところ、バージョンアップが95回行われたlinux-1.1シリーズでは、最短が「1日」(1.1.63と64の間、1.1.79と80、80と81の間等、計5回)、最長が「8日」(1.1.73と74の間、1.1.94と95の間の計2回)、平均が「3.4日」という結果になりました。
同様の分析を114回バージョンアップしたlinux-1.3シリーズで行ったところ、バージョンアップに要した最短日数は、その日のうちに次のバージョンが出た「0日」が3回(linux-1.3.65と66、linux-pre2.0.1と2.0.2、pre2.0.13と2.0.14)、最長日数は「15日」(linux-1.3.59と60)、平均は「3.2日」となりました。
同様に140回のバージョンアップが行われたlinux-2.1シリーズでは、最短日数は「1日」で10回、最長日数は「21日」で2回(2.1.43と44、2.1.36と37)、平均は「6.0日」でした。
以下同様に、59回バージョンアップが行われたlinux-2.3シリーズでは、最短は「0日」で2回(2.3.27と28、2.3.32と33)、最長は「24日」(2.3.18と19)で平均は「6.2日」、75回バージョンアップが行われたlinux-2.5シリーズでは、最短は「1日」で3回(2.5.23と24、2.5.55と56、2.5.57と58)、最長は「29日」(2.5.1と2)、平均は「6.0日」という結果になりました。
以上の結果を表にまとめると下表のようになります。
| バージョンアップ回数 | バージョン間の最短日数 | 最長日数 | 平均日数 |
linux-1.1.x | 95 | 1 | 8 | 3.4 |
linux-1.3.x | 114 | 0 | 15 | 3.2 |
linux-2.1.x | 140 | 1 | 21 | 6.0 |
linux-2.3.x | 59 | 0 | 24 | 6.2 |
linux-2.5.x | 75 | 1 | 29 | 6.0 |
1.x世代のlinuxでは週に二度、より規模が大きくなった2.x世代でも週に一度ずつのバージョンアップが、各シリーズごとに100回近く繰り返される、これがEric Reymond氏が指摘した「早めの公開、しばしば公開」の具体的な中身と言えそうです。
バージョンアップごとのサイズ変遷
前節同様の分析を公開されたtar.xzのファイルサイズに対して行い、バージョンアップごとにどれくらいファイルサイズが増加するかも整理してみました。
linux-1.1シリーズではバージョン間の差分の最大値は1.1.75と76の間の33760バイト、2番目に大きいのは1.1.81と82の間の31176バイト、逆に一番小さいのは1.1.89と90の間の904バイト、その次は1.1.86と87の間の1360バイト、平均は9900バイトという結果になりました。
同様の分析をlinux-1.3シリーズで行うと、最大は1.3.93と94の間の459988バイト、次は1.3.68と69の間の108868バイト、最小はpre2.0.10と11の間の-2924バイト、次は1.3.11と12の間の-1916バイト、平均は19344バイト、となりました。
以下同様に、2.1シリーズでは、最大は2.1.131と132の間の255320バイト、次点は2.1.26と27の間の140400バイト、最小は2.1.114と115の間の-16860バイト、次点は2.1.20と21の間の-7756バイト、平均は31997バイト、2.3シリーズでは最大358100バイト(2.3.14と15)、最小-33160バイト(2.3.41と42)、平均は75114バイト、2.5シリーズでは最大1071676バイト(2.5.4と5)、最小は-119788バイト(2.5.72と73)、平均は94939バイトとなりました。
これらの結果も表に整理してみましょう。
バージョン間の差分の |
| 最大値 | 最小値 | 平均値 |
linux-1.1.x | 33760 | 904 | 9900 |
linux-1.3.x | 459988 | -2924 | 19344 |
linux-2.1.x | 255320 | -16860 | 31997 |
linux-2.3.x | 358100 | -3316 | 75114 |
linux-2.5.x | 1071676 | -119788 | 94939 |
この結果を見ると、カーネルが成長していくにつれて、バージョンアップごとに追加されるコードの量が増えていることがうかがえます。特にlinux-2.3シリーズでは、1世代前の2.1シリーズと比較して、1つのバージョンアップで追加されるコードの規模が倍以上に増加しているのが目に付きます。
この結果を見たとき、最初は「2.1シリーズと2.3シリーズではバージョンアップの間隔が異なってるのかな?」と思ったものの、前節で見たようにバージョンアップの間隔が異なるのは1.3シリーズと2.1シリーズの間で、2.1シリーズと2.3シリーズでは大きな違いは見られません。そこでバージョン間のサイズ差をより詳しく見てみることにしました。
1日あたりのファイルサイズの増分の変化
前節までに見てきた、「バージョンアップごとのファイルサイズの変化量」を「かかった日数」で割ると、その間の「ソースコードの1日あたりの増加量」が計算できます。たとえばlinux-1.1.81と82の間の増分は31176バイト、この間に3日かかっているので1日あたりの増分は10392バイトとなります。
各バージョンアップごとに計算してみると、linux-1.1シリーズでは1日あたりの増分の最大は1.1.87と88の間の18332バイト、最小は1.1.89と90の間の301バイト、平均は4350バイトとなりました。
以下同様に、linux-1.3シリーズでは1日あたりの増分の最大値は489988バイト(1.3.93と94)、最小値は-1462バイト(pre2.0.10と11)、平均は9381バイト、2.1シリーズでは最大66124バイト(2.1.52と53)、最小-5620バイト(2.1.114と115)、平均7460バイト、2.3シリーズでは最大190688バイト(2.3.99-pre7とpre8)、最小-8240バイト(2.3.41と42)、平均16614バイト、2.5シリーズでは最大243938バイト(2.5.35と36)、最小-31692バイト(2.5.13と14)、平均17361バイト、という結果になりました。この結果も表に整理してみましょう。
1日あたりの増分 |
| 最大値 | 最小値 | 平均値 |
linux-1.1.x | 18332 | 301 | 4350 |
linux-1.3.x | 489988 | -1462 | 9381 |
linux-2.1.x | 661240 | -5620 | 7460 |
linux-2.3.x | 1906880 | -8240 | 16614 |
linux-2.5.x | 2439386 | 31692 | 17361 |
このように整理してみると、1日あたりのファイルサイズの増分は、1.1シリーズと1.3シリーズの間で倍程度増加するものの、2.1シリーズではやや減少し、2.3シリーズでは改めて倍以上に増加、そのペースは2.5シリーズでも維持されていることが分かります。
1日あたりのファイルサイズの増分はカーネルの開発速度と見なせます。さて、それでは何がこのような開発速度の向上をもたらしたのでしょうか?
開発速度から見た開発スタイルの変化
Linuxは最初のバージョンこそLinusさんが一人で書きあげたものの、それ以降は利用者から寄せられるコードを積極的に取り込み、いわば「インターネット上の共同プロジェクト」として開発されました。
当初は、世界中のユーザーから送られてくるソースコードへの修正差分(パッチ)をLinusさんが一人でチェックしていたものの、Linuxのユーザーが増えるにつれ送られてくるパッチも急増していき、ネットワーク回りはAlan Cox、SCSI回りはEric Youngdale、イーサネットカードはDonald Becker、ファイルシステム(ext/ext2)はRemy Card、等々、サブシステムごとに担当者を決めて、各領域の担当者が承認したパッチをLinusさんがとりまとめる、というスタイルが生まれてきました。パッチはkernel-ML等のメーリングリストでやりとりされるので、担当者だけでなく全ての参加者がコードをレビューできるオープンな仕組みです。
linux-1.xのころはこのような体制で何とか対応できたものの、Linuxが普及するにつれ開発に参加する人々が増え、ML上を流れるパッチの量も膨大になり、必要なパッチが見落されることも増えてきました。SMPやマルチアーキテクチャに対応するように全面的に書き直されたlinux-2.0がリリースされたころには、カーネルの開発体制はどうあるべきかがずいぶん議論になっていた記憶があります。
すでに存在していたRCS(Revision Control System)やCVS(Concurrent Versions System)、Subversionといったソースコード管理システム(SCM:Source Code Management system)を利用すべき、という意見もあったものの、Linusさんの目から見ると、これら既存のSCMはカーネルのような大規模ソフトウェアを管理するには力不足でした。
パッチファイルをMLでやりとりする方式での開発はlinux-2.1シリーズでも続くものの、2.1シリーズの開発速度が1.3シリーズに比べてやや低下しているのは、開発者が増えすぎた結果、このスタイルでの開発が限界に逹したことを示しているようです。
この限界を打破するためにLinusさんたちが選んだのがBitKeeperと呼ばれるSCMでした。BitKeeperはカーネル開発にも参加していたLarry McVoy氏がCEOを務めるBitMover社が開発したSCMで、BitMover社が管理する中央リポジトリとそれぞれの開発者が手元に置くローカルなリポジトリ間で、整合性を保ちつつ高速にソースコードのやりとりができる分散型のSCMとして設計されていました。
「Linuxの開発にBitKeeperを採用する」とLinusさんが宣言したのが2002年のことでした。当時のBitKeeperはカーネル開発者たちには無償で提供されていたものの、BitMover社が管理する商用ソフトウェアだったため、GNUプロジェクト総帥のRichard Stallman氏が危惧を表明するなど、物議をかもしました。
各バージョンの開発期間を眺めるとlinux-2.1シリーズが1996年から98年、2.3シリーズは1999年から2000年、2.5シリーズが2001年から2003年なので、BitKeeperの採用表明はlinux-2.5シリーズのころになります。
一方、BitKeeperはβバージョンを1999年に、最初の公式版を2000年に公開しています。今回の分析結果から見ると、恐らくLinusさんたちはBitKeeperの初期バージョンをlinux-2.3シリーズの開発に試用し、開発速度が倍以上に向上するという好結果を得たのでしょう。そういう具体的な結果が出ていたから、周囲の危惧にも関わらず、カーネル開発にBitKeeperを採用する、という判断を下した、このあたり、徹底した実用主義者であるLinusさんの特徴がよく表われているように感じます。
BitKeeperというツールを得て、カーネルのソースコードをより効率よく管理できるようになった結果、開発版と安定版を1つのバージョン内で運用するlinux-2.6シリーズの新しい開発スタイルが生まれた、とも言えそうです。
その後、2005年になってBitMover社はlinuxの開発者たちへのBitKeeperの無償提供を中止することになり、Linusさんは新しくGit(ギット)と呼ばれるSCMを開発することになりますが、そのあたりはまた別の機会に考えてみることにします。