2001年秋、私は、小規模な上級オペレーティング・システム・コースを開講していました。学生数わずか6名でした。彼らは、皆、2001年春には、必修科目の私のオペレーティング・システム・コースを受講した学部学生でした。春学期の終了時に、私は、大学院形式のオペレーティング・システム・コースを受講してみませんかという電子メールを送りました。それは、研究論文を講読したり、実際のLinuxカーネル・プロジェクトに取り組んだりするというコースです。
秋になって授業が始まると、われわれのところにIBM Linuxスカラー・チャレンジの話が伝わってきました。私は、すでに実際のLinuxプロジェクトを進める計画でしたので、コンテストへの参加を学生たちの目標にすることは、まったく自然な成り行きのように思われました。結局、学生全員が参加することになりました。4名は各人で応募し、2名はグループで応募しました。このプロジェクトで素晴らしい仕事がなされてきたことは知っていましたし、われわれの中からも合格者が出ればいいなと思っていましたが、どんなことになるのかはまったく予想できませんでした。
われわれのクラスのメーリング・リストに良い知らせが届き始めたのは、12月の休みのころでした。最初に知らせてきたのはBryan Clarkでした。彼のメールには「やったー」と書いてありました。続いてPhil AllenとMatt Finlaysonが「Linuxチャレンジ合格者 - Bryanだけじゃないよ」というメールを送ってきました。彼らの大きな問題は、合格して得たラップトップをどうやって分割するかということでした。さらに最後に、Dwight Tuinstraが「僕も合格したよ」とメールを送ってきました。われわれは、全勝するかもしれないと思いました。SteveとMattは、祈りながら待っていましたが、最終的に、合格しなかったという公式な知らせがありました。それでも、大喜びでした。こんな6名だけの小さなクラスから、世界中で25組の合格者の中の3組を生みだしたわけですから。
日を追うにつれ、このニュースは、どんどん良い方向に進んでいるようでした。1600以上の応募があったことが知らされました。さらに、われわれ3組は、北米の合格者の半数だということも知りました。そして、最大のニュースが飛び込んできました。Clarksonが最も合格者数の多い学校であり、その結果、わが校は、われわれの希望するzSeriesサーバーすなわちノード数16のLinuxクラスターを手に入れたのです。今度は、このことが大きな勝利でした。
このことがあって以来、どうすればこんな小さなグループがコンテストでそんな成功を収めることができたのか、と多くの人々が質問してきました。その1名は、クラークソンの栄誉ある卒業生で、たまたまIBM developerWorksの編集者でもあるBarbara Wetmoreでした。本稿で、私は、その質問に答えたいと思っております。また、興味のある読者がLinux開発で同様の成功を収めるのに役に立つかもしれない話をさせてもらいたいと思っております。
私は、われわれの成功の種が、2001年春学期に私が教えた学部でのオペレーティング・システムのクラスにあったのではないかと見ています。私は、学生全員に実際のオペレーティング・システムのカーネルを実地で経験してもらいたいと考えました。そこで、クラークソン大学の学長Anthony Collinsに、ある考えを相談しました。
私は、その当時、マシンでいっぱいになっている研究室があることを知っていました。そのマシンは、ビジネス・スクールが新しい建物に引っ越した際に、そのスクールから持ち込まれたものでした。それらのマシンは組み立てられてもいませんでしたが、計画では、それらのマシンは、Windows 2000の管理 (administration) のクラスで使われることになっていました。このクラスの学生たちは、自分たち専用のマシンにアクセスする必要があったのです。というのも、彼らは、この学期を通してマシンをいろいろなやり方で構成してみることにしていたため、他の人々はそれらのマシンを自分の作業のためには使えなくなるからです。後ほど、私のオペレーティング・システムのクラスでも同じような問題が起こることになります。オペレーティング・システムのカーネルに変更を加える学生は、必ずや、他の人がそのマシンを使えないようにしてしまうからです。
私は、これら両方のクラスをVMWareの上で進めていくことを提案しました。VMWareというのは、複数のオペレーティング・システムがそれぞれの仮想マシン上で実行できるようにするための製品です。そうすれば、特別な構成にした場合の間違いや影響を他のユーザーに及ぼすことがなくなります。Collins学長は、学生たちの実地体験の機会が一層増し、研究室をより活用できるようになることに大喜びでした。学長は、マシンごとにVMWareのライセンスを購入するのに、何千ドルもの費用をかけることを快諾してくれました。Windows 2000管理のクラスの教官Bill MacKinnonも、研究室を共用したり、VMWareを試してみることに同意してくれました。
2001年の休暇はほとんど、Billやクラークソンのコンピューター・サポート・スタッフといっしょに、マシンを組み立てたり、VMWareのインストールやテストを行ったり、両方のクラスの授業の構想を練るといったことで、精力的に働き続けました。新しい学期が始まる頃には、研究室の構築作業は最終的段階に入り、それとともに、われわれの実験も始まりました。
オペレーティング・システムについての授業には、地元のLinuxユーザーズ・グループの会長をしていたMike Akersという素晴らしい補助教員も加わりました。彼は、LinuxカーネルをVMWareで使えるように構成するとともに、合計25名の3つのグループの学生たちに辛抱強く付き合い、学生たちが各自のカーネルをコンパイルする方法を教示してくれました。
実習のマニュアルには、Gary NuttのKernel Projects for Linux という本を使いました。また、学生たちにいろいろなオペレーティング・システムを体験してもらうために、同じくGary NuttのWindows NT実習マニュアルOperating Systems Projects Using Windows NT も使用しました。Nuttの本は、数多くの素晴らしい知識を紹介してくれてはいるのですが、学生たちは、本の構成や、細かい点が不完全であったり、間違っていたりする点に不満でした。(Gary Nuttは、こうした数多くの問題に対処するために訂正用のホームページを開いています。彼が第2版を執筆する際には、これらの問題も修正されることと思います。)
他にもLinuxカーネル・プロジェクトについてアイデアがないかと探し回っていたところ、いくつか有益な参考文献があることがわかりました。ワシントン大学のSteve Gribble教授は、2001年冬学期の学部学生向けのオペレーティング・システムのクラスに、4つの演習からなる素晴らしいシリーズ物の出版物を使用していました。Jason NiehとOzgur Leonardは、Dr. Dobbsの2000年8月号に "Examining VMWare" という記事を執筆しており、その中で、コロンビア大学の学部学生用のオペレーティング・システムにVMWareを使った事例を紹介しています (参照先のリンクは、参考文献に示してあります)。
結局、私は、Linuxカーネルにシステム・コールを追加するとか、仮想メモリー・サブシステムを設けて、指定されたプロセスのページ・フォールトの回数を報告させたり、ロード可能なカーネル・モジュールを実装するなど、学生たちにいろいろな実験を行わせました。次の節では、その中の代表的な実験について詳しく紹介したいと思います。
システム・コールを追加するというのは、カーネルのソースを思いどおりに扱えることを手早く簡単に実感できる方法です。
自分でこれを試すには、カーネルのソースをダウンロードし、構成し、自分のカーネル・イメージをコンパイルして、ブート・ローダーが想定する場所にそのイメージを配置することになります。新しいシステム・コールを付加した新しいカーネルを構築したくない場合は、単にコードをダウンロードしてきて、それらのファイルを眺める (あるいは、カーネルのソースのHTML版をオンラインで眺める) だけでもかまわないでしょう。
どういう形でソースを眺めるにしろ、カーネルのソースのメインのディレクトリー下にarchというディレクトリーが存在するはずです。このディレクトリーには、プラットフォームに固有なコードが収められています (Linuxをi386マシンで実行する場合とアルファ・マシンで実行する場合とで異なってくる部分のコード)。このディレクトリー下のコードの中には、指定されたアーキテクチャーに固有なアセンブリー・コードで記述されたものもあります。システム・コールを追加するときに、まず最初に行うことは、archディレクトリー下のファイルの1つ、具体的にはarch/PLATFORM/kernel/entry.S (PC上で直接あるいはVMWareで作業する場合にはarch/i386/kernel/entry.S) を編集することです。
特にこのファイルには、カーネル内のシステム・コールのエントリー・ポイントのリストが記述されています。リストは、ENTRY(sys_call_table) で始まり、それに続けて各システム・コールのエントリーが示されます。システム・コールの番号は、このリスト内でのその位置によって決まります。たとえば、呼び出し側プロセスの新しいコピーを作成するためのシステム・コールforkは、このリストでは3番目のエントリーになっていますので、このシステム・コール番号は2です。さらにリストを下っていくと、たぶんread、write、open、close、exitといったおなじみのコールの名前が確認できることと思います。オペレーティング・システムにサービスを要求するときには、みなさんも自分のコードの中でこうした名前を使用しますので、見慣れた名前のはずです。通常、Cでは、stdio.hのようなライブラリーに対して呼び出しを行います。しかし、これらのライブラリー関数も、結局は、オペレーティング・システムのエントリー・ポイントを直接呼び出すことで、オペレーティング・システムだけが直接操作することのできるファイルやプロセスなどのオブジェクトに対する処理を要求しています。
arch/i386/kernel/entry.S
.data ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_setup) /* 0 */
.long SYMBOL_NAME(sys_exit)
.long SYMBOL_NAME(sys_fork)
.long SYMBOL_NAME(sys_read)
.long SYMBOL_NAME(sys_write)
.long SYMBOL_NAME(sys_open) /* 5 */ ....
.long SYMBOL_NAME(sys_getdents64) /* 220 */
.long SYMBOL_NAME(sys_fcntl64)
.long SYMBOL_NAME(sys_printmyname)
.long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
.rept NR_syscalls-225
.long SYMBOL_NAME(sys_ni_syscall)
.endr
|
システム・コールを追加する場合、現在の順番を乱さないようにすることが大切で、それには、新しいシステム・コールはリストの最後に追加し、その番号を書き留めておくようにします。たとえば、222の位置にSYMBOL_NAME(sys_printmyname) というエントリーを追加するものとします。また、この場合、リストの最後にある.rept NR_syscalls-NUMBER の番号を変更しなければならない場合もあります。NUMBER が新しいシステム・コールをカバーするだけの大きな値になるようにしなければなりません。NUMBER が大きすぎるぶんにはかまいませんが、小さすぎるのはよくありません。
われわれが追加した行を見ると、名前は、システム・コールを実装する関数の名前になっています。新しいシステム・コールの名前は、Linuxカーネルの他のどの関数とも違うものにする必要があります。システム・コール・プロシージャーの名前は、約束ごととして、sys_で始めることになっています。sys_YOURNAMEのような名前なら、たぶん、まず問題ないでしょう。上の例で、sys_printmynameという名前にしたのは、このシステム・コールが実際に行うことを表してのことです。
同様の追加を、Linuxソースのルートにあるincludeディレクトリー下のファイルに対しても行う必要があります。include/asm-PLATFORM/unistd.h (ここでもPLATFORMは、PCの場合i386となる) には、各システム・コールのシステム・コール番号を指定する #defineのリストが記述されています。そのリストに、新しいシステム・コールのエントリーを追加します。ここでも、名前は一義的なものでなければなりません。
include/asm-i386/unistd.h
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
...
#define __NR_fcntl64 221
#define __NR_printmyname 222
|
さらに、当然ながら、新しいシステム・コールを実装する必要があります。entry.Sを変更したとき、われわれは、このシステム・コールを実装するプロシージャーの名前がsys_printmynameであるとしました。ところで、どこにこのプロシージャーを配置し、どんな引数と戻り値にすればよいのでしょうか。一番簡単な方法は、この関数をどこか既存のソース・コード・ファイルに入れてやることです。新しいファイルを追加することもできますが、少し面倒になります。論理的には、この関数を入れるファイルはkernel/sys.cです。このファイルに含まれている他のシステム・コール・プロシージャーを観察することでも、新しいシステム・コールをどんな形式にすべきかが把握できることと思います。以下が、sys_printmynameの実装内容です。
kernel/sys.cへの追加
asmlinkage void sys_printmyname(void) { printk("Jeanna was here\n"); }
|
このシステム・コールは、文字列 "Jeanna was here" をシステム・コンソールに出力する簡単なものです。kernel/sys.cに含まれている他のシステム・コールをいくつか調べてみると、戻り値をもたせたり、いろいろなパラメーターを渡せるようにするなど、もっと複雑なシステム・コールの設け方がわかるはずです。
当然ながら、自作のカーネルに新しいシステム・コールを設けても、それが使えなければ、面白くも何ともありません。そこで、新しいシステム・コールを使ってみるために、それを呼び出すCの簡単なプログラムを作成します。以下が、自作のシステム・コールprintmynameを呼び出すCのプログラムmy_testapp.cです。
my_testapp.c
//this gives us the syscall function:
#include <sys/syscall.h>
//this gives us access to our new system call number:
#include "PATH_TO_YOUR_LINUX_SOURCE/include/asm-i386/unistd.h"
//do this instead for system call numbers in the standard unistd.h
//#include <unistd.h>
int
main (int argc, char **argv) {
syscall( __NR_printmyname);
//we could avoid the include of our modified unistd.h altogether
//by calling syscall(222);
}
|
この学部学生向けのオペレーティング・システム・クラスでは、VMWare下でLinuxを実行することで、本物のオペレーティング・システムのカーネル・レベルのプロジェクトが可能になったという自信が得られました。オペレーティング・システムの基礎的な概念を教えることができたこと以外にも、このクラスの学生たちは、自分たちでLinuxのカーネルのソース・コードを読み、理解し、変更できるということを学んでいきました。われわれは、カーネル・ハッカー志望の者を怖気づかせるかもしれないいくつかの作業 (カーネルを構成し、問題なくコンパイルし、それをロードするといった作業) を彼らがこなせるように指導しました。VMWareによって、その他の大きな障害も克服できました。このシステムのおかげで、複数の開発者が、お互いの作業に支障をきたしたり、ベースとして安定しているオペレーティング・システムを混乱させたりすることなく、安心して作業を行うことができます。
この学期は、私に、そして学生たちの多くにも、もっと大がかりなプロジェクトに取り組んでみたいという願望を抱かせました。そこで私は、秋からの大学院レベルの高度なオペレーティング・システムのクラスにどの程度の興味があるか確かめてみようと思いました。また、私といっしょに約1年間研究を進めてきていた博士課程の学生Dwight Tuinstraに、大学院レベルのオペレーティング・システムの題材を扱ってほしいという思いもありました。私自身が博士論文で研究したログ構造形式のファイル・システム (log-structured file systems) についての考え方を拡張することが、彼といっしょに研究してきたプロジェクトに大いに役に立つのではないかと考えました。そのようなわけで、もっと高度なプロジェクトに興味のありそうな学生たちにメールを出したところ、数少ないながらも意欲の高い学生たちから積極的な反応がありました。夏の間、私は、この新しい高度なオペレーティング・システム・クラスについての計画を練りました。
この高度なオペレーティング・システムを題材とする小さなクラスは、2001年9月に始まりました。われわれは、週2回、1時間半ずつ集まりました。
夏の間、われわれは、Linux実装プロジェクトとなりそうな題材について (電子メールで) 議論することで、クラスの準備を進めていました。Bryan Clarkは、ユーザー・リソース追跡システムを提案してきました。これは、最終的に彼がコンテストで合格したエントリーの基礎となるものでした。ワシントン大学のSteve Gribble教授も、Linuxプロジェクトのいくつかを提供し、使用させてくれました。われわれがLinuxチャレンジのことを耳にしたとき、われわれ自身のプロジェクトの動機付けとして、このチャレンジを目標にすることは、当然の成り行きのように思われました。
Linuxプロジェクトの他に、われわれは、週に4、5本の研究論文を読み、授業時間には、それらの論文について議論しました。初期のオペレーティング・システムの論文 (Dykstraの1968年のTHE multiprogramming systemに関する論文やUNIXの前身であるMulticsをいろいろな角度から論じる論文など) から一番最近のオペレーティング・システムに関する出版物に到るまで何でも読みました。小さな規模のクラスでしたので、全員が意見を述べなくてはならないなど、真剣に取り組んでいました。
学生たちにとっては、この分野の歴史的な展開を学んでいくことはありがたいことでした。たとえば、Multicsを研究するときには、私は、その当時のメインフレーム・コンピューターであるIBM 360の写真を見せました (参照箇所は参考文献に示してあります)。われわれは、よく、この分野の歴史はまだ浅く、そうした短い期間に急速に技術が変化したことについて語りました。学生たちは、私の語ったことを理解したことと思います。この分野は、まだ若く、急速に変化しており、革新的なコンピューター科学者である学生にとっては、偉業をなすための余地がたくさん残されているということを。
学生たちは、また、オペレーティング・システムの文献にあたるだけの研究が絶対的なものではないということも学びました。われわれは、各授業で2つの論文について議論し、その論文も、似たような問題を非常に違った方法で扱っているものを意図的に選ぶようにしました。私は、コンピューター・サイエンスの数ある重要なテーマがさまざまな形で現れては消え、再び現れてきていることを強調しました。たとえば、大部分のアプリケーションを問題なく稼働させることのできる汎用のオペレーティング・システムを構築することと、アプリケーションがオペレーティング・システムに対して特別な最適化を行ってもらうように通知する方法を用意しておく (簡単な情報を流すか、ユーザー・レベルのサーバーを使うか、カーネルにコードをダウンロードしてかして) こととの対立がその例です。
各論文について、私は、授業を始める前に、論文の簡単な要約と論文に対する3つの批評をまとめた短いレポートを学生たちに提出させました。この学期の課程を進めるにつれ、学生たちは、論文の内容に限界があることを指摘したり、補足実験や論文の内容の拡張を提案したりすることが、ずいぶん多くなっていきました。春学期の学部学生向けのオペレーティング・システムのコースで、オペレーティング・システムのコードが「不可侵」であったり、手の届かないところにあるのではないということが明らかになったのと同様に、このクラスでも、オペレーティング・システムの研究が不可侵でもなければ、手の届かないところにあるわけでもないということが明らかになりつつありました。学生たちは、論文を読み、分析し、さらにはそれを実現したりテストできるようになりました。
さらに、この学期では、各学生に授業中の議論をリードさせるようにしました。そうすることで、学生たちは、雑多な細かいことを純化して、まず概要を示し、さらに比較対照される点を強調するという効果的なプレゼンテーションを生み出す経験を積みました。
われわれのクラスの議論は、活発で楽しいものでした。割り当てのスケジュールに30分以上を費やすこともしばしばでした。これには、夕方の時間帯を使うことが大切でした。ピザと映画に1日を予定したこともありました。Plan 9 from Outer Space です (Plan 9 from Bell Labsではありません。詳細は、参考文献のリンクでどうぞ)。
また、「課外活動」を提案したり、課外活動に単位を与えるといったことも行いました。学生たちは、ある仮説をテストするための小さなプログラムを作るといったことから、ネットワーク・カードの最大限のバンド幅をテストしたり、公開された性能値に挑戦するといったことまで、何でもやりました。私から提案するだけでなく、学生たちも、自らの活動について自由に提案してきました。また、これ以外にも、学生たちは、自分で興味をもったテーマについて研究し、それを授業の際に報告することで、単位を取得することができました。「他にも課外活動があります」という文句は、このクラスの議論で好んで使われるようになりました。
Linuxのコンテスト・エントリーに合格するのには、こうした課外活動が功を奏したのだと思います。実際、コンテストへのわれわれの応募の多くは、われわれが読んだ論文や授業の中で行った活動を直接発展させたものでした。Matthew Sabinsは、Savageの1997年の論文を読んだ後、マルチスレッド型プログラムのロック検出システムであるEraserの彼独自のバージョンを作成しました。Dwight Tuistraは、RosenblumとOusterhoutが書いた元のLFSの論文を読み、さらにLFSの性能を改善する方法についての私の1999年の論文を読んだ後、NetBSDからLFSクリーナーを再構成し、それをLinLogFSに移植するという案を提出して合格を得ました。Phil AllenとMatt Finlaysonが合格を得たスレッドプールの応募は、Steve Gribble教授の研究課題の1つと、われわれが授業の中で行ったスレッドプールのバックオフを基にしたものでした。(学生たち全員がスレッドプールの実装を行い、性能値を報告した後、授業の中で、それぞれのスレッドプールの分析を行いました。結局、それぞれのプログラムが、他にはない有用な機能を備えていることがわかりました。PhilとMattは、それらの優れた機能を1つに統合するというプロジェクトを題材に選びました。)Bryan ClarkとStephen Evanchikは、協力して、ユーザー・リソース追跡システムの構築にあたりました。これは、カーネルのソースにそのようなシステムが必要だというBryanの意見に基づくものでした。彼らは、このシステムを別々の角度からとらえた2つのエントリーを提出しました。その中、Bryanのエントリーが合格となりました。
われわれが、3つのエントリーで合格し、また全体の賞がクラークソンに授与されるという知らせを受けたのは、私が学部学生向けにオペレーティング・システムの研究室を設営し始めてからほぼ1年目のことでした。ちょうど、本物のオペレーティング・システムに直接触れることで、学生たちが教科書では決して得られないような形でオペレーティング・システムを理解するようになったのと同様に、オペレーティング・システム研究の一次資料に直接触れることで、学生たちは、研究というものを理解するようになりました。この2つのことが強力に連携することで、新しいアイデアを提案し、かつ、それを実現する力が学生たちの身についたのです。
こうした経験から、以下のような教訓が得られました。
- クラークソン大学では一貫して行っていることですが、チーム単位で実地学習することで、学生たちは、実社会でうまくやっていけるようになる。この点、小さなクラスであることには大きな効果がある。
- 本物の製品であるオペレーティング・システムのコードを扱う機会を与えることで、学生たちは現実の問題を解決しようという動機を抱くようになる。
- 研究の一次資料に直に触れることで、学生たちは、歴史や背景についての感覚を得ることができ、その結果、変化を提言する力を身につけるようになる。
- VMWareは、カーネルの開発を経験したり、1台のマシンで複数の学生が開発を効率よくかつ安全に行えるようにする上で素晴らしいプラットフォームである。
- オープン・ソースのソフトウェアは、大学の環境において、重要な教育の機会となっている。
私にとって、いっしょに研究を進めてきた学生たちが、プロと同等の開発を行い、大きな成功を収めるのを見てきて、非常に実りの多い年でした。学生たちと私は、学生たちの参加や達成を促し、かつ報いていただいたということに、Linuxスカラー・チャレンジに感謝しています。
-
われわれの連載記事で、クラークソンの他のエントリーについても紹介しています:Bryan Clark、Phil Allen and Matt Finlayson、Stephen Evanchik。
-
Linuxカーネルの情報。
-
Configuring the Linux Kernel. (Linuxカーネルの構成方法) が参考になります。
-
Plan 9 From Outer Space やPlan 9 From Bell Labs についての情報。
-
IBM 360 の写真。
-
クラークソン大学、Advanced Topics in Operating Systems クラスのホームページ、クラークソンInternet Teaching Laboratory。
- "Examining VMWare" (Dr. Dobb's Journal、2000年8月)。
- Gary Nutt著Kernel Projects For Linux。
-
ワシントン大学のSteve GribbleのOperating Systems コース。
- developerWorks のLinuxゾーンには、他にもLinux関係の記事が多数掲載されています。
- みなさんは、学生ですか、教官ですか。
IBM Faculty Portal には、みなさんのニーズに合わせた情報や提供品や提案が掲載されています。
Jeanna Matthewsは、カリフォルニア大学バークレー校でコンピューター・サイエンスの博士号を1999年12月に取得しました。学部学生としては、オハイオ州立大学で数学とコンピューター・サイエンスの2つを専攻しました。2000年1月から、クラークソン大学の数学科とコンピューター・サイエンス科で教鞭を執っています。研究の関心は、ファイル・システム、オペレーティング・システム、ネットワークおよび分散システムにあります。彼女と(この記事の執筆を手伝ってくれた) 夫のLennyは、ニューヨーク州Massenaにファミリー農園を所有しています。Dr.Matthewsのメール・アドレスは、jnm@clarkson.edu です。