玩式草子─ソフトウェアとたわむれる日々

第82回Linuxの成長過程をふりかえる[その1]

つい先日、linux-4.6がリリースされました。このカーネルは4.6というバージョンが示すように、昨年4月にメジャー・バージョンが更新されたlinux-4.xシリーズの6度めのマイナー・バージョンアップになります。

最近の動向を見ると、linux-4.0が2015年4月、4.1が同年6月、4.2が8月、4.3が11月、4.4が2016年1月、4.5が同年3月、4.6が5月にそれぞれリリースされており、linux-4.xシリーズのマイナー・バージョンアップはほぼ2、3ヵ月に一度のペースです。

一方、4.0や4.1といった各バージョンごとにバグフィックスを主目的としたメンテナンス・バージョンもリリースされています。メンテナンス・バージョンは4.0.1や4.1.3といった3ケタ目の数字で区別され、通常、マイナー・バージョンが2つ更新する程度の期間(4~6ヵ月)に、10回前後リリースされます。

Linuxの最初のバージョンである0.01が公開されたのが1991年のことでした。それから25年、いったいどれだけの数のLinuxが公開されてきたのでしょう? www.kernel.orgに保存されている過去のバージョンを調べてみました。

リリースされたLinux

現在、開発が進んでいるlinux-4.xでは、本稿執筆時点で4.0から4.6まで7つの開発版がリリースされ、4.0では4.0.1から4.0.9まで9つのメンテナンス・リリースがありました。長期サポート対象になっている4.1では25回のメンテナンス・リリースが行なわれ、現在もサポートが続いています。以下、4.2では8回、4.3では6回、4.4では11回、4.5では5回のメンテナンス・リリースがあり、71のバージョンが存在しています。

同様に、linux-3.xでは3.0から3.19まで20の開発版がリリースされ、メンテナンス・リリースは3.0では101回、3.1では10回、3.2では80回、3.3では8回、3.4は112回、3.5は7回、3.6は11回、3.7は10回、3.8は13回、3.9は11回、3.10は101回、3.11は10回、3.12は60回、3.13は11回、3.14は70回、3.15は10回、3.16は35回、3.17は8回、3.18は34回、3.19は8回、それぞれ行なわれていました。これらを合わせるとlinux-3.xには730のバージョンが存在することになります。

以下同様に過去のシリーズを調べ、開発期間と共にまとめてみると以下の表のようになりました。開発期間欄の「LTSあり」は、そのシリーズの開発は終了しているものの、特定バージョンのサポートが現在も続いていることを示します。

カーネルシリーズリリース数開発期間
linux-4.x712015/04 -
linux-3.x7302011/07 - 2015/03(LTSあり)
linux-2.6.x3042003/12 - 2011/05(LTSあり)
linux-2.5.x752001/11 - 2003/07
linux-2.4.x 762001/01 - 2013/05
linux-2.3.x 601999/03 - 2000/12
linux-2.2.x 261999/01 - 2004/02
linux-2.1.x 1411996/09 - 1999/01
linux-2.0.x 401996/01 - 2004/02
linux-1.3.x 1141995/01 - 1996/01
linux-1.2.x 141995/03 - 1995/08
linux-1.1.x 961994/04 - 1995/03
linux-1.0.x 101994/03 - 1994/04
1.0以前31(?)1991/09 - 1994/02

1.0以前のバージョンはwww.kernel.orgにもまばらにしか残っていないため正確ではないものの、集計すると過去25年間に1800近い回数のリリースが行なわれていたことになります。さて、それではこれだけのバージョン・アップでLinuxはどのように成長してきたのでしょう?

1991年に公開されたlinux-0.01のソースコードを調べると、ファイル数は88、総行数は10239行でした。一方、最新版のlinux-4.6ではファイル数が53637、総行数は2120万行を超えています。すなわち、ソースコードのファイル数では600倍強、行数では2000倍強にまで増加していることになります。

Linuxの最初のバージョンと最新のバージョンを比較するとこれほど大きな違いになるものの、ではその途中経過はどうなのか、もう少し詳しく調べてみることにしました。

カーネルサイズの経時的変化

ソフトウェアの規模を比較するには行数(=ステップ数)を比べるのが一番よさそうなものの、行数をカウントするにはソースコード一式を展開しておく必要があります。しかし、Linuxは上述のように1800近いバージョンがリリースされており、それら全てを展開しておくのは現実的ではありません。

そこで簡便な方法としてtar.xzで圧縮した状態のサイズを使って比較することにしました。tar.xzで圧縮した状態のファイルならば、ncftp等のFTPクライアントでwww.kernel.orgに接続し、ls -lするだけでリストを入手できます。

ncftp /pub/linux/kernel/v2.6 > ls -l linux*tar.xz
ls -l linux*tar.xz
-rw-rw-r--    1 ftp      ftp     26531084   12月 18  2003   linux-2.6.0.tar.xz
-rw-rw-r--    1 ftp      ftp     26569168    1月  9  2004   linux-2.6.1.tar.xz
-rw-rw-r--    1 ftp      ftp     29251456   12月 24  2004   linux-2.6.10.tar.xz
-rw-r--r--    1 ftp      ftp     29668184    3月  9  2005   linux-2.6.11.1.tar.xz
-rw-r--r--    1 ftp      ftp     29605396    5月 16  2005   linux-2.6.11.10.tar.xz
-rw-rw-r--    1 ftp      ftp     29603048    5月 27  2005   linux-2.6.11.11.tar.xz
-rw-rw-r--    1 ftp      ftp     29594552    6月 12  2005   linux-2.6.11.12.tar.xz
-rw-r--r--    1 ftp      ftp     29674844    3月  9  2005   linux-2.6.11.2.tar.xz
…

このリストには、そのバージョンがリリースされた日付も含まれているので、日付けの起点を決めればそこからの経過日数ファイルサイズをグラフにプロットできそうです。

日付の起点は最初のバージョンであるlinux-0.01が公開された日がいいかと思ったものの、本来は1991年9月に公開されたはずのlinux-0.01の日付が、www.kernel.orgのアーカイブでは1993年10月になっています。加えて、1.0以前のバージョンはHistoricディレクトリに集められ、圧縮形式もgzipのみ(1.0以降のバージョンはgzip、bzip2、xzの3形式から選べるようになっている⁠⁠、ソースコードも一式ではなくパッチファイルのみで保管されているバージョンが多いなど、1.0以降のバージョンと直接比較するのは困難なようです。

そのため、今回の分析では最初の公式版であるlinux-1.0以降を対象とすることにし、linux-1.0が公開された1994年3月13日を日付の起点にして、そこからの経過日数を計算することにしました。この手の処理にはPythonのtimeモジュールが便利そうなので、こんなスクリプトを組んでls -lで得られたデータをパースしました。

 1  #!/usr/bin/python
 2  # -*- coding: utf-8 -*-;
 3  
 4  import sys, os, time
 5  
 6  # Linux v1.0 release date = epoch
 7  epoch_str = "{}/{}/{} 12:00:00".format("1994", "03", "13")
 8  epoch_time = time.strptime(epoch_str, "%Y/%m/%d %H:%M:%S")
 9  epoch = time.mktime(epoch_time)
10  
11  datafile = sys.argv[1]
12  with open(datafile, 'r') as file:
13      whole_str = file.readlines()
14  
15  for line in whole_str:
16      (perm, tmp, owner, group, size, t_month, day, year, filename) = line.rstrip().split()
17      month = t_month.replace('月','')
18      time_str = "{}/{}/{} 12:00:00".format(year,month,day)
19      struct_time = time.strptime(time_str, "%Y/%m/%d %H:%M:%S")
20      interval = time.mktime(struct_time) - epoch
21      interval_days = interval/(24*60*60)
22      print("{} {} {}".format(interval_days, size, filename))

このスクリプトでは、7行目から9行目でlinux-1.0の公開日である1994年3月13日の12時をUNIXタイムに変換してepochとし、15行目からのループでwww.kernel.orgから入手したそれぞれのカーネルの公開日を読みこんでUNIXタイムに変換してepochからの差分を求めて日数に変換する、という処理をしています。

このスクリプトをformat.pyncftpでwww.kernel.orgから得たファイルサイズや日付のデータを2.6.datとすると、出力はこういう形になります。

$ python format.py 2.6.dat 
3567.0 26531084 linux-2.6.0.tar.xz
3589.0 26569168 linux-2.6.1.tar.xz
3615.0 27107192 linux-2.6.2.tar.xz
3629.0 27248004 linux-2.6.3.tar.xz
3651.0 27393444 linux-2.6.4.tar.xz
3675.0 27527616 linux-2.6.5.tar.xz
3711.0 27908596 linux-2.6.6.tar.xz
…

この出力は、linux-2.6.0がリリースされたのは1.0公開後3567日目、tar.xzのサイズは26.5MB、linux-2.6.1は3589日目で26.6MB、2.6.2は3615日目で27.1MBであることを示します。

この結果をカーネルの各シリーズごとにまとめ、縦軸をtar.xz形式で固めた場合のファイルサイズ横軸をlinux-1.0公開日からの経過日数としてグラフに描くと図1のような結果になりました。

図1 Linuxのサイズの変遷
図1 Linuxのサイズの変遷

図1ではそれぞれの黒点がリリースされたカーネルのサイズと1.0からの経過日数を示し、急速に上昇していく線が1.1.xや1.3.x, 2.5.xといった開発版カーネル、サイズがあまり変らず横に伸びていく線が1.2.xや2.0.xといった安定版カーネルを示しています。開発版カーネルの線の上にはおおよそのシリーズ名を、長期に渡ってメンテナンスされた(=横に長く伸びた)安定版カーネルではその最終バージョンも記載しました。

また、3.x以降のカーネルでは3.2.xや3.4.xなど長期間サポート(LTS)の対象になっているバージョンがいくつかあり、それらについては枠外から矢印で示してみました。なお、グラフが煩雑になるのを防ぐため、サイズがあまり変化しない安定版カーネルは適宜間引いてプロットしています。

ソースコードをtar.xzで固めたサイズで見ると、

  • 1994年3月のlinux-1.0では0.94MB、
  • 1996年7月のlinux-2.0では3.9MB、
  • 2001年1月のlinux-2.4.0で15.7MB、
  • 2003年12月のlinux-2.6.0で26.5MB、
  • 2011年7月のlinux-3.0で63.7MB、
  • 2015年4月のlinux-4.0で82.3MB、

最新(2016年5月)のlinux-4.6で89.5MBに達しています。

「linux-1.0と比べるとlinux-4.6は100倍近く増大している」と言葉で言うのは簡単ですが、その過程をグラフに描いてみると、その100倍という重みを改めて感じます。Linusさんを中心としたカーネル開発者たちは、20年以上の間、1バージョン1バージョンごとに改良を積み重ねLinuxを成長させてきました。図1を見ると彼らの不断の努力に改めて頭が下がる思いがします。

図1は、いわばLinuxの成長過程全体の見取り図で、大きく見れば右肩あがりの単調増加なものの、細かく見ると増加速度が大きい部分とそれほどでもない部分があるようです。次回はそのあたりをもう少し細かく見てみることにします。

おすすめ記事

記事・ニュース一覧