新しい Linux カーネルをテストしなければならない理由 |
|
|
|
Michael D. Crawford
GoingWare Inc.
Copyright (C) 2001 Michael D. Crawford.
Free Software Foundation によって発行された GNU Free Documentation License バージョン 1.1 またはそれ以降のバージョンの条件に基づき、本ドキュメントをコピー、配布、および/または変更する許可が与えられています。条件は、セクションが変更されていないこと、表紙のテキストがないこと、裏表紙のテキストがないことです。断り書きとして次のことを記載します。「This contains material from the Linux Quality Database at http://linuxquality.sunsite.dk(本ドキュメントには、http://linuxquality.sunsite.dk にある Linux Quality Database からの資料が含まれています」。ライセンスのコピーが「GNU Free Documentation License」というタイトルのドキュメントに含まれています。
注 - 本ドキュメントは、元々、 Linux 2.4.0 のリリース直前に、「新しい Linux カーネルをテストしなければならない理由」というタイトルで Advogato に投稿したものです。しかし、投稿した後に、数人の人々からコメントを頂き、間違いの指摘や役に立つ追加を提案してくれました。しかし、いったん記事として Advogato に投稿しているので、編集ができず、コメントに答えるだけしかできませんでした。そこで、必要な修正を加え、この Linux Quality Database に記事の改訂版を投稿することにしました。「はじめに」の章の 2.4.0-prerelease の言及で残した記事の元々の意図を維持するためには、カーネルの現在のバージョンを反映して改訂すべきかどうか迷いました。しかし、これを書いた時点で、現在の安定版カーネルは 2.4.4 で、Alan Cox 氏によるテストパッチは 2.4.4-ac11 です。
はじめに
皆さん、フリーソフトウェアの歴史において、私たちは重要な地点に近付きつつあります - そうです、Linux カーネルの大規模な改訂版のリリースが間近に迫って来たのです。自分の作業のために大多数の人たちが依存しているシステムの基盤として、カーネルの正確さは、Advogato 上で開発するプログラムが正常に機能するために非常に重要なことです。最寄りの Kernal.org ミラーサイトから最新版の 2.4.0-prerelease のソースを入手して、機器上でのテストと、使用しているプログラムのテストを徹底して行ってください。
現在の製品版カーネルは 2.2.18 で、長い間、開発版カーネルは 2.3 シリーズでした。2.4.0-test1 カーネルは、今年の初めに登場しましたが、多くの新機能を Linux システムに提供するだけでなく、カーネルを大きく再構築するものでもあります。
私は、今年の大半を 2.4.0-test と 2.4.0-prerelease カーネルに取り組むことに費やしていますが、その結果、概して、これらがおおむね良好に動作することがわかりました。プログラマや自分の Linux システムを管理できる人が使う限りは申し分ないと言うことができると思います。このことは、カーネルがもうトラブルを起こさないと言うのではなく、この記事を読むような人であれば十分に使用する価値があるということです。
(注 - この時点では製品開発用コンピュータと netatalk/samba ファイルサーバ上で 2.4.3 と 2.4.4 を使用していますが、何もトラブルはありません。)
問題(ならびに、ここに投稿した理由)は、2.4.0 がリリースされると、多数のエンドユーザシステム上で製品の使用が急増する可能性があり、そうしたシステムの多くは設定が十分にテストされていない状態であるということです。さらに広範囲にわたるテストが行われて、このような問題の発生が防止されることを望んでいます。
これは、一部には、必要とする機能や修正があるため、ユーザがソースをダウンロードしてカーネルを自分で構築するからでもありますが、他方で、ディストリビューションの多くが、他のディストリビューションやフリーでないオペレーティングシステムに「負けない」と思われるように、2.4.0 を一斉に採用しようとするからです。
しかし、2.4.0 カーネルに最も積極的に取り組んでいるのは、カーネル開発者自身か、あるいは私のようなにただテストする目的だけで取り組んでいる僅かの人です。テストに苦労している人たちがたくさんいるとは思いません。また、カーネルにほとんどの時間を費やしている人たち(カーネル開発者)でさえ、さまざまな設定を試みようとすると、リソースが制限されている場合が多々あります(prerelease 版のカーネルを搭載したシステムを、まだ完全でない状態で出荷したディストリビューションの話を聞いたことがありますが、無責任なことだと思います)。
Linux の最初の経験は、「調べてみるだけ」の目的で 29 ドルの CD ディストリビューションを購入してからの場合が多くなるでしょう。これらの人々にとっては、真新しい 2.4.0 カーネルを手に入れることになるため、このカーネルに対して肯定的な経験をすることが非常に重要になります。「Linux Quality」の読者によって発見されるあらゆるバグは、もはや戻っては来なくなるかもしれない数千人の Linux 初心者によっては発見されないバグなのです。
広範囲にわたるコンフィギュレーションで、多数のさまざまなアプリケーションの負荷をかけてテストすることが非常に重要なのです。
実業界で経験したことと比較してみましょう。私はかつてアップル社に勤務していました。ある時は QA エンジニアとして、そしてある時はシステムのデバッグを行う OS エンジニアとして。アップル社の以前の TCP/IP スタックである MacTCP をテストし、そのためにラボ内で およそ 3 ダースのコンピュータを使用し、そこで約 1 年間、 テスト、テストプランの作成、テストツールの作成 のみにフルタイムで従事しました。すべて QA にかかわることでしたが、当時(1990 年)は、システムの中で重要でないコンポーネントと会社のほとんどの人にみなされました。
1990 年代半ばに OS エンジニアだった当時、アップル社に何人の QA スタッフがいたかわかりませんが、推測すると 500 人ないしはそれ以上は在籍していました。全員フルタイムで働き、一年中、Linux カーネルがサポートを予定しているよりもはるかに少ないハードウェア・コンフィギュレーションを持ったシステムをテストしていました。そして、インターネット機器から昔の 386 ボックスやメインフレームまで Linux の実行が予定されているハードウェアに対して、アップル社が非常に厳しくコントロールしていることに着目してください。
カーネルは、以下のいくつかの理由により、広範囲にわたる人々によるテストを特に必要とします。
- さまざまなコンフィギュレーションが可能なソースコードとして配布されているため、バグを発生させる組合せを発見しようとするには、多くの異なったオプションを試してみる必要があります。
- 数多くの異なった命令セットを使用しているアーキテクチャ、特定のアーキテクチャで使用されるさまざまな CPU のグレード、およびメインフレームのプロセッサ(S/390)さえもサポートしています。しかも、誰もこれらのさまざまなコンピュータをすべて所有しているわけではありません。
- 機能を確認するには実際にインストールする必要がある、膨大な数のハードウェア機器をサポートしています。広範囲にわたるテストを行わないと見つからないような競合が、さまざまなデバイス間に存在する場合があります。
- カーネルは、ユーザアプリケーションとハードウェア間のインターフェースであるので、システムコールの多数の組合せと、システムへのその他の負荷をテストするために、さまざまなユーザモード・プログラムを実行してテストする必要があります。そのため、新しいカーネル上で使用しているアプリケーションをテストする必要があるのです。
- 製品版のシステムでカーネルに障害が発生すると、通常はユーザモード・プログラムの障害よりも悪影響を及ぼします。
カーネルが不安定ならば、コンピュータがクラッシュし、ファイルシステムが破損して、ユーザがデータを喪失し、リブートするか問題を解決するまでコンピュータが使えなくなることは明らかです。さらに悪いことには、バグの多いカーネルの場合、クラッシュしなくても、他の環境では信頼性のあるプログラムの異常な動作を引き起こしてしまいます。この種のバグは潜在的で、突き止めるのが極めて困難な場合があります。
テスト版カーネルに取り組むには
新しいカーネルに取り組む場合に知っておくべきことがいくつかあります。
バグを発見すると、通常は にメールを送り、linux-kernel メーリングリストに報告します。新しいメールサーバに注意してください。vger.rutgers.edu は、徐々に使用できなくなります。
メール量が多いため、linux-kernel メーリングリストには実際には加入したくはないでしょう。リストを読み終えたら、アーカイブから削除することをお薦めします。私は、このアーカイブが気に入っています。。
もちろん、linux-kernel メーリングリストの FAQ を読んでみるのもいいでしょう。
アーカイブのあるサーバに接続すれば、目的のファイルは pub/linux/kernel/v2.4 にあります。
カーネル・アーカイブのミラーサーバ一覧は、http://www.kernel.org/mirrors/ にあります。
ミラーサーバの一部にある、現在のカーネルとユーティリティのダウンロードディレクトリへのリンクは以下の通りです。
現在のカーネルバージョンのダウンロード用リンク
国名 |
安定版 |
テスト版 |
AC テストパッチ |
modutils
|
util-linux |
米国 |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
カナダ |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
英国 |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
ドイツ |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
フランス |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
日本 |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
中国 |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
韓国 |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
インド |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
サウジアラビア |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
ロシア |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
南アフリカ |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
ブラジル |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
メキシコ |
安定版 |
テスト版 |
AC |
modutils |
util-linux |
全体のカーネルソースは一度だけダウンロードすればよく、次からははるかにサイズの小さいパッチが出された時点でダウンロードして当てることができます(すべてのパッチを当てて行く必要はなく、必要なペースで当てます)。
(さらに小さい).bz2 ファイルをダウンロードする場合、使用している tar のバージョンが bzip2 フォーマットをサポートしている場合、tar xvfpy filename.bz2 を使用して展開するか、bunzip2 を使用して伸張し、次に tar -xvfp で展開します。.tar.gz ファイルをダウンロードする場合、tar -xvfzp を使用して一度に展開して伸張します。
ソースを展開する場合、「linux」と呼ばれるディレクトリが生成されます。私は、カーネルを設定して構築する方法には踏み込むつもりはありません。これらについては、カーネル Newbies Webサイトに最適な情報が掲載されています。
ソースを /usr/src 内で展開しないようにすることを推奨します。伸張する場合、必ず既存の /usr/src/linux の名前を変更しないと混乱することになります。/usr/src/linux が、シンボリックリンクであるかもしれません。その場合、ソースを /usr/src 内に置くことを実際に望むのならば、そのリンクを削除してから、ソースを展開し、linux ディレクトリの名前を linux-バージョンへ変更して、新たなシンボリックリンクを作成します。しかし、多数のカーネルのバージョンをテストすると、ディスクスペースが大量に使用されることがすぐにわかるでしょう。そして、予備のスペースを /usr 内に多くは確保できなくなる可能性があります。私は、/home/admin というディレクトリを作成し、私のカーネルのほとんどはそのディレクトリに置いています。私の /usr/src/linux ディレクトリは、自分のディストリビューションに含まれていたカーネル用か、またはしばらく使い続けることにした新しいバージョン用のいずれかです。
これまでに明らかになった大きな収穫は、使用している 2.2 カーネルから 2.4 カーネルに変更するために、カーネルのモジュールの管理プログラムである modutils の新しいバージョンを必要としたことです。それらがないと、多数の未定義記号を使用しているモジュール内に入れることになり、モジュールが正しくロードしなくなります(その新しい modutils は、以前のカーネルとも問題なく動作するようです)。新しい modutils は、ローカル・ミラーサーバ上の pub/linux/utils/kernel/modutils/v2.4 にあります。
完全に互換性を確保するためには、linux/Documentation/ のファイルにあるさまざまなパッケージの必要なバージョン番号を確認する必要があります。私と同じように、最初は、ディストリビューションに含まれていた古いバージョンのプログラムと問題なく動作していたのに、しばらくすると、上手く動作しなくなるかもしれません。バグを報告する前に、関連するアップデートがインストールされていることを確認してください。以下は、カーネル 2.4.4 と共に使用するプログラムに必要とされるソフトウェアバージョンです。
何かをアップデートすることが必要な場合、確認することになる Changes ファイルを、新しい各カーネルとともに必ずチェックします。もちろん、あるソフトウェアを全く使用しない場合、そのアップデート版を備える必要はありません。例えば、ほとんどのデスクトップコンピュータは pcmcia-cs を必要とせず、ジャーナリング機能のある ReiserFS ファイルシステムを使用している場合、reiserfsprogs だけしか必要としません。
万全を期したい場合、公開されたパッチをダウンロードして当てるようにします。特定の問題を抱えていて、そのパッチを誰かがメーリングリストに投げていれば、パッチを電子メールから入手して当てるか、あるいは Linus 氏や Alan Cox 氏によって配布されるコンパイルを入手できます。これには、彼らが承認した送信パッチのすべてが含まれています。何かを修正するパッチをダウンロードする場合、必ずしも新しいコンパイルが含まれているわけではないので、その場合はカーネル開発者に問題が残っているということを丁重に知らせ、おそらくパッチを再送信してもらう必要があります。
patch-2.4-prerelease-ac5 というパッチを入手した場合、cd コマンドによって linux ディレクトリ(カーネルソースのトップレベル)への移動を実行して、そのパッチを 2.4.0-prereleaseカーネルソースにあてます。
patch -p1 < patch-2.4-prerelease-ac5
パッチは、コマンドラインパラメータとしてではなく、入力を標準入力から取るため、< でリダイレクトすることを忘れないようにしてください。
Linus 氏のコンパイル済みパッチは、pub/linux/kernel/testing にあり、Alan Cox 氏のパッチは、pub/linux/kernel/people/alan/2.4/ にあります。一般に、Linus 氏の方は、より公式で安定しており、Alan 氏のパッチは何かの最初の試みやフィックスの実験であることがよくあります。
若干の役に立つヒント
カーネルを設定すると、.config という名のファイルが linux ディレクトリ内に生成されます。このファイルに、選択された設定オプションがすべて保存されています。ディレクトリを 1 つどこかに作成し、.config のコピーにカーネルのバージョンと、そのビルド内に設定した最も重要なオプションを反映する名前を付けて保存すると役立ちます。そして、後日、テストのため以前のカーネルを復元する際に、後日、保存したファイルを使うことができます。また、カーネル開発者がそれを必要とする場合、報告したバグがあるカーネルの .config ファイルを送付することができます。
.config ファイルはメーリングリストに直接投稿しないようにするのがいいでしょう。と言うのも、そのファイルは大きく、多くの人々がメーリングリストに加入しているので、リストのトラフィックが多くなるからです。依頼した人に必要な .config を、個人的にメールで送るか、または Web ページ上に掲示(私が、使用しているラップトップに問題があったときに、ここで掲示したように)して、URL をバグのレポートに含めることをお薦めします。
(.config、 XF86Config、ならびに lilo.conf(カーネルパラメータを使用している場合)を含む設定ファイルの成功例を Web ページに掲示して、同じようなハードウェア(特に、正しく設定するのが難しいハードウェアを持っている場合)を使用しているユーザを手助けするのも欲に立ちます。私は、使用しているコンパック Presario 1800T ラップトップの設定ファイルを共有するために、そのようなページを作っています。)
使用しているカーネルソースにパッチを当てる場合、以前の .config ファイルを使用して、「make oldconfig 」コマンドで、設定を最も早く行うことができます。以前のファイルでは挙げられていない新しい項目の入力を促されます。しかし、最初に 2.4 カーネルを作成する際には、新しいものが多数あるので、全体の設定を手作業で実行するのがおそらく最善の策です。
XWindows をコンピュータ上で動作させている場合は、カーネルを設定する最も快適なやり方は、(必要とされる「make oldconfig 」の後に、)「make xconfig 」のコマンドを使用することです(この対応は、おそらく、私を真のハッカーではないとみなされないようにすることでしょう...)。これも、あちこちで 2、3 のオプションを変更したり、config オプションのヘルプをブラウズするだけであれば、最も迅速なやり方です(GUI コンフィギュレーションツール)。他のやり方として、「make config 」(数多くのオプションを一つ一つたどって行きます。非常に面倒な作業になります)、「make menuconfig 」(ターミナルでのコマンドベースの編集のため)、または手作業で .config ファイル (オプション間の依存関係のため、一般的には推奨されません)を編集する方法があります。
最後に、インテル・アーキテクチャのコンピュータ上で作業し、新しいカーネルをたびたび試している場合、GNU Grub をインストールすると非常に便利です。GNU Grub は、LILO よりも機能がはるかに揃ったブートローダです。主な利点としては、ファイルシステムの多様なフォーマットをネィティブで認識するということです。そのため、新しいカーネルバイナリを配置するごとに再インストールする必要がある LILO とは異なり、Grub は一度インストールすると、ブートメニューにブートしたい全く新しいカーネル名を追加したければ、Grub の menu.lst ファイルを編集するだけで済みます。この作業を忘れた場合、カーネルを名前によって grub のコマンドラインからブートできます。
Grub は物理ディスクセクタではなく名前でカーネルをブートするため、以前のカーネルを、同じパス名の新しいカーネルに置き換える必要は全く必要ありません。LILO はセクタリストを使用するので、同じパスの新しいカーネルはディスク上の別の物理的な位置に記憶される場合があり、新しいカーネルを配置する時は再インストールする必要があります。
Grub は、「チェーンローディング」と呼ばれるプロセスによって、フォーマットを認識しオペレーティングシステムをブートします。これは LILO から DOS や Windows をブートするのと同じです。
Grub はまだ 1.0 でないことに注意してください。Grub の機能は私の場合は非常に上手く機能しているのですが、ブートセクタにインストールする前に、grub のフロッピーを作成してテストすることから始めることをお薦めします。
User Mode Linux - カーネルをプロセスとして実行
Jeff Dike 氏の User Mode Linux を使用して、他のネィティブな Linux システムのもとで Linux カーネルをユーザプロセスとして実行できます。
これは、少し前までは Slashdot の特徴でした。
私はまだ試していませんが、これは素晴らしいことです。新しいカーネルの安全なテスト(ハードウェアへのアクセスをコントロールした状態で、単一のレギュラーファイルから作成したファイルシステムにディストリビューションをインストールする)に加え、User Mode Linux を使用して、潜在的に危険な新しいソフトウェアをテストできます(ネットからダウンロードしたソフトウェアを、root(/)としては決して実行しないでください)。さらに、もしかすると実際のハードウェアでは実行が困難なあらゆるやり方で、カーネルを実装できるかもしれません。また、新しいカーネルをインストールして、使用しているコンピュータをリブートしなくてもそれをテストすることができます。そして、システムを自動的に起動してコマンドを実行し、それをリブートするスクリプトがあります。
他に付け加えることとしては、特に大事なデータを保存している実際のコンピュータ上でテストを予定している場合です。まずバックアップを取り、作業内容を頻繁に保存し、バックアップを定期的に取ります。しかし、ユーザモードで Linux を使用している場合には心配する必要はありません。
その他の考え
以下は、元の記事が Advogato に投稿されてから、読者よりメールで頂いたフィードバックに対する回答として書いたものです。
2.4.x カーネルは現在どれほど良好ですか? 安心してテスト出来るでしょうか?
新しいカーネルは「非常に良好に」、ないしは少なくとも「良好に」動作すると言うべきであると勧めるメールを知人より受け取りました。「かなりに良好に」動作するという私の表現が、じっくりテストしようと思っていた多くの人々のやる気をそぐものだと感じたようです。
私自身の経験では、新しいカーネルにはほとんど問題はありませんでした。皆さんもおそらく大丈夫でしょう。しかし、それが問題なく動作し、大丈夫そうであっても、どれほど良好に動作するかについて本質的なことを言うのにはためらいがありますが、最新の機能とパフォーマンスの強化という追加された恩恵を享受することになるでしょう。
しかし、linux-kernel メーリングリストでやり取りを見ていると、人によっては深刻なトラブルを経験しています。ユーザがテストを試みると、遊ぶにはもってこいの新しいおもちゃを得た感じになりますが、ある程度のリスクは覚悟しなければなりません。また、そのリスクは、使用しているコンピュータが全く起動しなかったり、あるいはファイルシステムを壊したり、ユーザがプログラムで作成したデータを喪失するといった類いのものかもしれません。したがって、テストを実行する人は、故障したコンピュータを直したり、喪失したデータを復元しなければならない可能性を受け入れる用意が出来ている人々に限るべきです。
ReiserFS は、バージョン 2.4.1 で主要なカーネルディストリビューションに受け入れられました。しかし、製品ファイルの保管用にはまだ使用しないことをお薦めします。これは、推奨している多くの人々とは反対の意見になります。多数の人々は、ReiserFS を問題なく使用しています。
しかし、複数の最新カーネルリリースの changelogs から、いくつかの重要なバグが ReiserFS でフィックスされていることに気づきました。そして、それらの一部はファイルシステムの破損を招く恐れがあることがわかりました。自分のコンピュータで使用したいとは思いますが、ReiserFS に関するバグ・フィックスのないカーネルが少なくとも 1 つはリリースされない限り、そうするつもりはありません。出来れば、その機能を放棄したというよりは、安定していると示されることを願います!
ただ、ReiserFS を試してみることはお勧めしたい。簡単な方法としては、ext2 上の、ループバックマウントされた通常のファイルにある ReiserFS ファイルシステムをマウントするか、あるいは予備のハードドライブを用意します。
しかし、これをベータテストの時の Windows 2000 の条件と対比してみましょう。私は、コンサルティングの仕事のために、NT 上で実行する Java を書く必要がありました。クライアントは、私が Windows 2000 のベータ版を使用するのを面白がっていました。私の経験は、惨憺たるものでした。果てしないトラブルに襲われ、私の仕事に大損害を与えました。たとえば、PPP を介してイーサネットと DNS を同時に使用するということは出来ず(Windows 2000 サーバを稼働していましたが)、自分のメールをチェックするには、その前にイーサネットを使用不可にしてリブートしなければなりませんでした。
Windows 2000 の問題は、多数のバグを伴って出荷され、サービスパックが 2、3 リリースされるまではインストールすべきではないという意見が、業界のマスコミと IT マネージャの間に広がりました。しかし、いずれにしてもマイクロソフトは Windows 2000 を出荷しました(公正を期すために申し上げると、これらのバグすべてはシステム全体でカウントされたのであり、カーネルだけではありませんでした。また、著者が最初の記事中で引用した明らかになっているバグが 64,000 個という数字は、正確ではないことがわかりました)。
test1 がリリースされて以来、著者は日常の仕事に使用しているコンピュータ上で 2.4.0-test カーネルを実行しています。仕事の遂行を妨げるような問題は、今のところ経験していません。私の発見した深刻なバグは、使用している Adaptec APA1480 Cardbus SCSI ホスト・バス・アダプタがなかなか機能しなかったことです。この問題は、メーリングリストで相談して非常に速やかに解決されました。そのため、現在ではるラップトップから CD を SCSI CD バーナーで焼くことが出来ます。現在抱えている唯一の問題は、コンピュータをシャットダウンした時に、自動的に電源が切られないことです。
と言うわけで、ご自身で判断してください。
特定のディストリビューションを使用するユーザは、新カーネルを実行するために、カーネルの設定の他に、どんな手順を踏めばいいのでしょうか?
既存のディストリビューションによって、必ず必要と思われるのは、先に説明した新しい modutils パッケージをインストールすることのみです。modutils とは、カーネルモジュールを管理するユーザプログラムを言いますが、通常は、実行時にカーネルにロードされたり、カーネルから取り出されるデバイスドライバのことを指します。そのモジュールフォーマットは 2.4 では変更されているので、新しいバージョンをインストールする必要があります。
現在使用しているシステムは、以前の modutils を使用して起動してもおそらくまだ大丈夫でしょうが、depmod を実行したときに未解決の記号に関する多数のメッセージを受け取ることになります。insmod または modprobe を使用しようとしても、役に立ちそうもないエラーメッセージが表示される結果となります。
モジュールは最初の起動ではロード出来ないので、システムは依然として起動すると言うことは出来ます。したがって、起動する必要があるドライバとスタティックにリンクさせなければなりませんが、多数の重要な機能が動作しない場合があります。例えば、PPP はモジュールとしてロードするのが一般的なので、インターネットにはダイヤルイン出来ないでしょう。
ユーザが使用している既存のユーザモード・プログラム、アプリケーションならびにライブラリはすべて、それぞれのソースをアップデートしたり、再コンパイルする必要なく継続的に動作するはずです。以前のカーネルバージョン上で動作したユーザプログラムとのバイナリ互換性がシステムの基本要件だからです。
ある種の既存のアプリケーションが、新しいカーネルのもとで実行されるとクラッシュするというレポートを見たことがあります。これは、ユーザ側のエラーではなく、通常はカーネル内のバグであり、メーリングリストに報告すべきです。
ユーザプログラムが利用しなければならない新しいカーネルの機能がいくつかあります。しかし、新しいカーネルを以前のシステム上で実行する場合は、その新機能は必要ではありません。私はその新機能をすべてを把握しているわけではありませんが、カーネルの config ヘルプに記載されています。構成オプションを調べる際にそのヘルプを選択すると、ユーザが必要とするソフトウェアについて他のドキュメントや Web サイトを参照するように、そのヘルプが指示していることがあります。
このようなユーザモードのプログラムの一例が reiserfsprogs です。カーネルだけが、既存の ReiserFS ファイルシステムのマウント、アンマウント、読み出し、書き込みをサポートしています。新しいファイルシステムをパーティション上に作成したり、損傷したファイルシステムを修復するには、ある種のユーザプログラムを必要とします。
既存のディストリビューションをインストールしていじくりまわしたい大部分の未熟なユーザにとって、おそらく根本的すぎる機能があります。それが DevFS ファイルシステムです。DevFS では、/dev ディレクトリは最初は空(から)で、ドライバがロードされると、専用ファイルが作成されますが(ブートの時点か、またはドライバのモジュールがロードされた時)、ドライバのモジュールがアンロードされるとなくなります。
これはアーキテクチャ上の非常な改善点ですが、おそらくユーザは、/dev ファイルが同じところに止まることを前提にしている既存のディストリビューションに、その専用ファイルを乱暴に入れるのは好まないと思われます。また、処理される必要があるこれらのファイルを管理する上での問題が生じます(これらのダイナミックファイルのいずれかに、デフォルトのパーミッションを設定する方法など)。最初から Linux を使用している人以外は、おそらくその専用ファイルを一体化されたものとしてサポートするディストリビューションを待ち望むことになります。
仮想マシンのぶちこわし
カーネルは、Linux だけでなくどんなオペレーティングシステムにとっても高品質でなければならないということが、なぜ重要であるかについて、2、3 付け加えたいと思います。ライブラリ内のエラーは、それを使用するプログラムに影響することがあるので、システムライブラリにエラーがないことも同様に重要であるという主張もありえますが、カーネルとなると格別です。
これは、仮想マシンを故障させるという、局所的でない影響を及ぼすからです。
安定して機能するコンピュータプログラムは、カーネルもユーザモードのプログラムも、仮想マシンであり、一部は、その上で動作するデータ構造やアルゴリズムです。スタック、キュー、リスト、サブルーチン、割り込み(信号などのカーネルでのハードウェア割り込みや使用プログラムでのソフトウェア割り込みの両方)、スレッド、ロックなどがあります。
プログラミング言語、ライブラリ、およびカーネルは、非常に広範なコンピュータ部分を提供し、私たちはこれらを組み合わせて非常に精巧なコンピュータを作ります。物理的な仕組みが与えられ、プログラムが正しく作成されている限り、最高に素晴らしいスポーツカーを凌ぐものに仕上がります。
問題なのは、大量の破損、バッファのオーバーフロー、競合条件、重要な領域を保護しないことなどのバグが、作成したプログラムに存在する場合、素晴らしさにブレーキがかかります。それはあたかも、軍隊が曲射砲をあなたの素晴らしいスポーツカーのところまで引っ張ってきて、砲弾をエンジンに打ち込むようなものです。しかし、それでも、車は走り続けます。プログラムは、損傷したときでも爆発はしません。スポーツカーは幸いなことに走り続け、各命令を逐次実行しますが、プログラムはユーザが欲していることは何も実行していない可能性があります。
セグメント違反の状態になったら幸運だと思うことです。ディスク内で結局破損することになるファイルに作業内容を保存した 1 時間後に気づいたのではなく、少なくとも、その時、何かがおかしいということにすぐに気が付いたのですから。。
このことを、私は、「Algorithms have unclear boundaries」というタイトルを付けたレターで論じました。このレターは最初、特許事務所に出したもので、「Forum on Risks to the Public in Computers and Related Systems」にも提出しました(コンピュータのユーザはだれでも「Risks」を読むことをお薦めします。「Risks Forum」を数年間手本にしたせいで、私はソフトウェアの品質に対してことさら敏感になりました)。
私はかつて、『Usenet News』上で行われたプログラミングの表明に関する議論に関心を持ちました。表明とはテスト群のことで、真でなければならないある条件が実際に真であるかどうかをテストするプログラムのデバッグビルドに含まれています。その条件が偽であることがわかるとプログラムは直ちに停止されるので、プログラマは間違っている内容を調べることができます。表明は、間違いを早期に発見し、プログラムを実行する度に一部のテストを自動的に実行することによって、ソフトウェア開発を早めます。
一般的なやり方は、不可能な条件は真ではないことをテストすることです。例えば、変数が 3 つの値のうちのいずれかを保持することを許可されている場合、その変数は 4 つの値のいずれかは含まないことを表明します。しかし、そのディスカッションの参加者の一人が熱心に主張しました。記述されているプログラムコードの論理的なフローによって、不可能な条件は決して生じることは出来ないと自分が証明することが出来たら、不可能かどうかがテストされる表明を含めることは時間の浪費だという論理です。
しかし、彼は間違っていると私は思いました。彼は、表明をもっと多く使用いれば節約出来るような多大な時間をプログラムの不必要なデバッグに費やすことになるでしょう。彼の主張は、仮想マシンが無傷な限りにおいて有効です。仮想マシンが故障すると、不可能な条件がたちどころに生じ始めて、コードの中に散りばめられている表明が、障害が発生したことを直ちに警告します。テストする不可能な条件の内容を前もって知るのは不可能なので、実際には都合がいい場合にいつでもテストします。
さて、この長い理論上の議論は、カーネルとどのように関連するのでしょうか?
Linux のような最近のオペレーティングシステム上で動作する通常のユーザモードのプログラムは、保護メモリを使用して実行されます。保護メモリ内で、プログラムはコンピュータ全体の全メモリスペースを所有するという認知を得ますが、他のプログラムに影響を与えるメモリアクセスを 1 つのプログラムが使用するのは不可能です。保護メモリは、カーネルによって管理され、最近のマイクロプロセッサのコンポーネントであるメモリ管理装置によって実施されます。
ユーザモードプログラムの仮想マシンが故障すると、不安定に動作するか、システムによって終了させられますが、他のプログラムを損なうことは起こりそうもありません。
保護メモリは、ユーザにとってはシステムの信頼性を維持しユーザデータを保護してくれますが、プログラムにエラーがあると、最悪でもそのアプリケーションを終了してくれるので、プログラマにとっても仕事も楽にしてくれます。これで、不具合があることはすぐにわかります。デバッガを使用している場合は、問題の内容について役に立つ情報を得ることが出来ます。また、プログラムはコンピュータをクラッシュしないので、作業を継続するためにリブートを待つ必要がありません。
保護メモリを当然のことと思わないでください。依然としてそれを備えていないシステムも多数存在します。標準的な Mac OS には備わっていません。私は、これまで取るに足りないいくつかのポインタバグのせいで、Mac が再起動するのを待つのに多大な時間を費やして来ました。現在ベータテストをしている BSD/Mach ベースの Mac OS X は、アップルが公けに最初にリリースする、広範囲にわたり保護メモリを使用した OS になります(A/UX という Mac Unix が以前にもありましたが、この OS は広く使用されることを目的としたものではありませんでした)。
Linux 上で動作するユーザモードプログラムは、相互に影響し合うことがありますが、 これらのプログラムは、カーネルによって支配され慎重に管理された通信チャンネルを介して相互作用しています。最も馴染みのあるものは、TCP/IP ネットワーキングとハードドライブ上のファイルですが、同様に Unix ドメインソケット、パイプ、信号などがあります。プログラムは、mmap システムコールなどのような方法で、共有メモリを使用してそれぞれのメモリの中身を他のプログラムに直接アクセスさせることがあります。しかし、このようなことは必要な時にのみ行われ、通常、重要なデータは他のプログラムではアクセスできないようにされます。
これらの例は、すべて十分に定義された通信経路です。これらの経路のいずれかを介して、あるプログラムが別のプログラムをクラッシュすることはあり得ますが(たとえば、破損ファイルを、別のプログラムで使用されているディスクに書き込むなど)、このようなことは一般的に非常に起こりにくいことで、またその場合も問題は局所化されます。
しかし、カーネルの場合は特別です。本来、カーネルは特に複雑な仮想マシンです(カーネル自体の動作内でも、ユーザプログラムに提供するシステムコールと専用のデバイスファイル・インターフェースにおいても)。カーネルは、外部仮想マシンとしてハードウェアをユーザプログラムに提供します。カーネルは、あらゆるものの中心に位置しています。例えば、各ユーザプログラムとハードウェアの間、ハードウェアバスと DMA を経由して相互にやり取りするさまざまなハードウェアの間、同じコンピュータ上あるいはネットワークプロトコルを介して通信している異なったコンピュータ上で同時に実行されているユーザプログラムの間などです。
カーネルは、root 特権をユーザのコンピュータに効果的に働かせます。プログラムの特権が減少する場合、それはカーネルがそのポリシーを実施しているからです。しかし、実際には、カーネルは条件を与えられると、必要とする機能は何でも実行できます。
カーネルは、すべて 1 つの大きな仮想マシン内で動作します。カーネルはそれ自体には保護メモリを備えていません。状況が複雑なのは、カーネルの一部はユーザプログラムの仮想メモリスペース内で動作し、カーネルはメモリスペース自体を管理し、同様に物理メモリへの直接アクセスを行うからです。そのため、動作しているカーネルのメモリアーキテクチャも複雑になっています。しかし、実際には、別の部分を混乱させる特定のカーネル部分に対するプロテクションはありません。
そして、カーネルの仮想マシンが故障した場合、それもちょっとした理由で、使用しているコンピュータがクラッシュダウンするほどではない場合には、パソロジカル通信経路をカーネル内に作成することが出来ます。
極端なケース(私は、実際に起こったのを見たことはありませんが)は、ドライバに ReiserFS などのジャーナル・ファイルシステムによって使用された重要なメモリデータ構造の一部に上書きさせたデバイスドライバのポインタバグの例かもしれません。ジャーナル・ファイルシステムは、ファイルシステムのメタデータを最小の単位で書き込むように配列するので、多くの人々はジャーナル・ファイルシステムを完全に信頼できると思っています。まず、メタデータはジャーナルに格納され、それが終了した時のみ、ファイルシステム自体にコピーされます。そして、プロセスがいつ中断されても(電源障害による場合など)、ファイルシステムの完全性が維持されるように実行されます。
しかし、バグの多いドライバが、あるでたらめなデータを、ディスクに書き込む直前に、ジャーナル・ファイルシステムによって使用されているメモリに書き散らしたらどうなるでしょう? ハードウェアの一風変わった部分のために、使用しているコンピュータに次回このドライバをインストールするようなことがあったら、このことを考えてください。
私が米国カリフォルニア州キュパティーノにあるあのビッグフルーツカンパニー(アップル社)の「デバッグマイスター」であった時に、何度も起こるのを目にしたのは、オペレーティングシステム(この場合は Mac OS システム)内の 1 つのエラーが、あるシステムコール中に、そのシステムの他の部分で使用されたデータ構造を壊すことでした。後でユーザアプリケーションがそのシステムコールを行うと、『Inside Macintosh』に記載されていることとは別の事象が発生します。システムが異常に振る舞うか、でたらめな結果を返すのです。
このテストを行う最も簡単で系統的な方法は、さまざまなシステムコールすべてを厳密に検査し、許容される範囲を超えるシステムコールのパラメータを変更し、返される結果が文書化された範囲内に収まるようにするテストツールを作成することです。適切なエラーコードが返されるようにするために、無効なパラメータを指定してシステムコールを行ってみるのも一つの方法です。
これはとても役立ちますが、ツールを作成する作業は退屈で、またシステムを全く動かなくすることもしばしばです。ツールがフリーソフトウェアのコミュニティにたくさんあるのを見てはいないのですが、いくつか作成すると役立つと思います(このことは、私がアップルの QA エンジニアだった時に行ったことです)。
Linux 用のテストツールがいくつかあります。「テストスイートを使用してLinux カーネルの有効性を確認」を参照してください。カーネルを直接テストするツールもいくつかあり、そのうちの 1 つはユーザレベルのパッケージ用のテストスイートを使用してカーネルを実行することが出来ます。
これも非常に役に立つのですが、他のカーネルでは高い信頼性で動作すると思われるさまざまなアプリケーションを使用して、カーネルを試してみるのです。と言うのも、これらのアプリケーションは、以前のカーネルでは安定的に動作しているからです。何らかの実用的な目的のために作成されたプログラムは、テストツールよりもはるかに多いので、これらのアプリケーションを使用して、テストツールが通常カバーする範囲よりもはるかに広範囲にわたりテストすることが出来ます。それに、通常、アプリケーションであれば何日費やしても興味が持てるものです。
プログラムで異常な通信経路を生成するハードウェア依存コードの問題のために、多数のさまざまなハードウェア設定でこれらのアプリケーションを試してみることをお薦めします。実際、商用アプリケーションが、システムの新しいバージョンを搭載した Macintosh のあるモデルでは安定して動作するのに他のモデルでは安定しないことことがあり、このことをテスタがレポートするのはアップル社ではごく普通のことでした。そして、これはビデオゲームやスプレッドシートの間違った動作として発生するハードウェアドライバ内のバグが原因であることがよくありました。
この点で、皆さんがテストしようとしていた範囲を超えてしまい、驚かしてしまったでしょう。しかし、状況は、想像するほど厳しいものではありません。カーネルは初めに信頼性が高くなければ、その後でも順調には動作しないものです。そして、他のオペレーティングシステムのカーネルの場合よりもはるかに強固にするものが、カーネルと開発手法にあります。
Linux の信頼性を高める 1 つの要素は、Linux はクロスプラットフォームであるということです。S/390 メインフレームプロセッサのほか、多数のさまざまなマイクロプロセッサをサポートしています。Linux は、非常に同質でない環境で使用されます。
別の要素としては、Linux は設定が可能なソースコードとして配布されていることです。カーネルが動作するいくつかの形態向けにいろいろなオプションが広く揃えられているので、ある特定のプロセッサに最適化するために、特定のアーキテクチャ用の一連の機能を選択することさえできます。
こうしたことは、潜んでいるバグを明らかにするのに役立つので、朗報なのです。バグによっては、トラブルをたまにしか引き起こさないものもあれば、システムの大幅な変更後になるまでは姿を現さないものもあります。しかし、カーネルはソースコードとして配布され、多数のさまざまなシステム向けに構築されるため、1 つのシステムのさまざまな条件(メモリは実際には別々に展開されている場合が多かったり、コードが別のオプションで構築されていたりします)が、少なくとも設定に関しては、繰り返しバグを刺激する可能性があるので、バグを早期に発見して修正することができます。
これを、例えば Windows 2000 のカーネルと比べてみましょう。これは、すべて、マイクロソフトのリリースエンジニアによってシステムの単一のビルドからコピーされたコードを実行するインテル・アーキテクチャのマイクロプロセッサ上のみで動作します。これは非常に同質な環境で、いろいろなパラメータを変えるということによって Linux にもたらされるようなメリットはありません。また、Be, Inc. が BeOS を PowerPC からインテル・アーキテクチャに移植した際、PowerPC BeOS よりも Pentium BeOS に対する方が市場の関心が格段に高いということを同社が理解していたにもかかわらず、コードの品質保証に役立つという理由から、依然として PowerPC バージョンもサポートしています。マイクロソフト、少なくともマイクロソフトのエンジニアは、PowerPC と Alpha を放棄したことを、この理由のために最後には後悔することになると思うのです。
(ところで、これはユーザアプリケーションのクロスプラットフォーム開発を行うメリットの 1 つです。皆さんは、さまざまなプロセッサを使用しているユーザに、自分が作成したコードと連動させ、そして可能であれば gcc 以外のコンパイラと連動させ、またさまざまなオペレーティングシステム上で完全に動作させたいと思っていることでしょう。これらは、皆さんが作成したコードを非常に強固にします)。
また、カーネル開発者の多くは、自分のコンピュータ上で長期間、開発版カーネルを使用し、それらをたびたび重いストレステスト負荷にかけています。開発の際に、カーネルのバグを発見して修正する時間はたっぷりあります。
したがって、皆さんが実際に致命的な操作をするようなおそれは全くありません。
私が、カーネルバグにこのように関心があるのは、カーネルのバグはよくあることだと思うからではなく、もし発生したら、発生したカーネルのバグを調べるのが困難だと思うからです。間違っていないプログラムにバグがあるように見えても、そのプログラムの開発者が同じカーネルバグはおそらく経験しないことを考えると、プログラムの開発者はそのカーネルバグを見つけ出すことは出来ないと思われます。
このような問題が、製品のコンピュータでなくテスト中に見つかった場合、または熟練したユーザでない人が所有がするコンピュータ上で見つかった場合であれば、不幸中の幸いなのですが。
|