RelayFS

2.6.11-rc1-mm1のアナウンスの最初に、次のようなAndrew Mortonのコメントをみつけることができる。「Linux Trace Toolkitと、それに従ってrelayfsを加えた。あなたと同様、LTTには今まではそれほど注目していなかったというのが主な理由で。それはたいしたものでないが、少しだけkernel <-> user周りの仕事を必要とする。」

今回は、前回登場した 「組み込みLINUXシステム構築」の著者、Karim YaghmourのRelayFSのアナウンスと関連する話題を取り上げる。

Status Of RelayFS

2.6.11-rc1-mm1は今年1月13日にリリースされたが、その後の20日に、Karim Yaghmourは「relayfs redux for 2.6.10: lean and mean」と題したパッチをLKMLにポストして言った。

私はrelayfsパッチを広範囲に再加工した。APIと内部コードは極端に削除した。パッチは実際のところ半分近くになった。オリジナルのサイズから90KBを除いたため、大きさは200KBから110KBまでになった。変更の要約を以下に示す。

  • ロックがない構成を落とした(Christoph, Arjan, Ingo, Andrewらからの、従来のロック上のcmpxchngの効率に関する議論と指摘に基づいた)
  • サイズ変更する機能(Andi, Christoph, ほか)を落とした
  • ユーザスペースの読み取り/書込み機能(Andi, Christoph, Roman, Timほか)をすべて落とした。基本的にこれは、relayfsに「ユーザスペースに高いデータ容量をできるだけ効率的に移す」という1つのことをさせそれに役立たせるに関している
  • アドホック・モードを実装した。このモードは古いロックを使うマネージド・モードと対照をなす。それは単に1つのリング・バッファを管理し、外部との同期に無関係の基本的なバッファを行う方法である。(この問題については、Romanと議論が進行中である。)
  • klogクライアントを落とした(Greg)
  • IDの代わりにポインタを使用ようにAPIを修正した(Roman)
  • その他のクリーンアップ(Domen)
  • その他の再構成(私)

私はハックされたlttパッチでこれをテストした。また私は、マネージド・モードを使用して問題なくデータ収拾をすることができている。データを読むことは別の話ではある。もしもrelayfsの行く先がわかれば、私はLTTパッチを更新する。注意点としては、Andrewのツリーでこのrelayfsを使用しようとしないこと。それは全く異質のの物だからである。

以下にコードを置く。私は、Documentation/filesystems/relayfs.txtファイルを取り合えず削除した。作業が完了する前に、恐らくそれは書き直す必要がある。

http://www.opersys.com/ftp/pub/relayfs/patch-relayfs-redux-2.6.10-050120-real.bz2

Greg KHおよびPekka Enbergはパッチとこの提案を読んで試した。その後Gregは、さらにコードを500行をカットして「fs」部分を除くことを提案した。さらにすでにあるdebugfsと、デバッグや開発時にだけ使用することと、ファイルシステムにして通常の利用環境と分離するというコンセプトが似ていることを指摘した。

Karimが答えた。

しかしそれは、relayfsのユーザは通常のシステム操作中にそれ(デバッグ用のファイルシステムを利用する事)を望まないという想定でのことである。これは、LTT(Linux Trace Toolkit=relayfsを有効に活用するトレースツールキット)が対象としているシステム管理者、アプリケーション開発者、およびシステムをトレースする必要があるパワーユーザが、ほとんどいないという場合でのことになる。
そのような場合は、私は別のファイルシステムの上に載せてもいいと思う。しかしrelayfsはdebugfsとは異なり、一般的に使用でき、そこにあるすべてのファイルが同じタイプになることを意図している。それは、ユーザスペースへの巨大な量のデータをダンプするためのチャンネルを中継(Relay)するものである。このような手法のための、特別の「ファイル」を使用してユーザに混乱させずに、強制させる別のやり方があれば教えて欲しい。言いかえればこれが一般的に使用される時、例えば/procのように、あるディレクトリに特定の「奇妙な」ファイルを持っていることで、マウントされたファイルシステムの中のファイルがすべて一定の方法で作用する場合には、ユーザは理解し易いだろう。

Gregが尋ねた。

relayfsが終始マウントされることを提案しているのだが、どこにマウントするつもりか?私は、人々に満足してもらうため、debugfsのための「標準的な」場所を用意しなければならない。

Karimは答えた。

我々は、/relayfsを使うことを望んでいる。しかしこれが問題になる場合、私はやはり/mnt/relayfsで良いのではないかと思う。いずれにしても、私は、このようなものを導入するための正確な形式上の規則に詳しくは無い。
もちろん、私はFHS(Filesystem Hierarchy Standard=Linuxのファイルとディレクトリに関する規格)とLSB(Linux Standard Base=Linuxのディストリビューションに関する標準規定)について知っているが、これから進むべき最良の方法を知らせて欲しい。

この後のやりとりは、メーリング・リストでは継続しなかった。しかし、2.6.11-rc1-mm1から2.6.11-rc2-mm2までの間含まれていたrelayfs(圧縮前の旧バージョン)/lttパッチは、2.6.11-rc3-mm1以降では、再構成のために一旦落とされている。

RelayFSとは

relayfsは、ユーザ・スペースで大量のデータを交換させるためのカーネル・コード用の共通のフレームワークを用意する試みである。Karim Yaghmourとともに開発している、Tom Zanussiが2003年3月に、「New relayFS High-Speed Data Relay Filesystemと」題したアナウンスをLKMLにポストして以来、LWNをはじめ一般に広まっている。

もう一つの使い道として、他のユーザスペース・アプリケーションでの同様なシステムの利用が考えられる。

Relayfsは、カーネルによってインプリメントされたもう一つ別の仮想ファイルシステムである。それを利用可能にするためには、明示的にユーザ・スペースでマウントしなければならない。そして、カーネル・コードは、relay_open()を備えたリレーを作成することができる。それはrelayfsの下のファイルとして現われることになる。

その後、ユーザスペースはリレーを開始し、カーネルでデータを交換するために(mmap()とpoll()を含む)通常のファイル操作をすべて使用することができる。アプリケーションには、relayfsファイル・ディスクリプタは、もう一つのエンドが別のプロセスではなく、1個のカーネル・コードである以外はあたかもUnixドメイン・ソケットのように見える。

カーネル側のインタフェースは少しだけ複雑である。期待されるべきrelay_read()およびrelay_write()ファンクションは存在し、ユーザ・スペース間でデータを移動させるために使用することができる。しかしrelayfsは、やはりそれを知るために必要な内部構造のほとんどをカーネル・コードに露呈している。そのため、例えば特殊目的コードでは、relayfsバッファへポインタを得て、そこにデータを直接コピーすることができる。relayfsのイベントを知りたいカーネルコードのためのコールバックのセットと、バッファ・サイズ、ロックやその他の使用効率を最適化する操作するためのユーティリティのセットがある。

RelayFSの実際

筆者の環境で、パッチ削減前のrelayfs/TTLのカーネル・モジュールが入っている2.6.11-rc2-mm2とツールキットであるLTT 0.9.6pre4をインストールして、試してみた。2.6.11-rc2-mm2自体はテスト版のため、動作環境によっては不安定であるが、relayfs/TTLの機能は問題なく動作しているようである。

opersysの文書は古いため、そのままでは利用できない。特にマニュアル中の/dev/traceは、最新版では関係無いので注意が必要だ。make installまでのインストール終了後は、

# mount -t relayfs nodev /mnt/relay

でマウントし

# /usr/sbin/trace 10 test

などのサンプルスクリプトを実行すると、カレントディレクトリにrelayfs経由で取得したトレース結果が、test.proc, test000.traceといった実行結果ファイルとして作られる。LTTに関しては別の機会にもっと詳しく取り上げたい。