Categories Books | Hard | Hardware | Linux | MCU | Misc | Publish | Radio | Repository | Thoughts | Time | UNIX | Writing | プロフィール
今日は、余り知られていない binfmt_misc という Linux カーネルモジュールに関する TIPS を紹介しよう。ご存じの通り、UNIX は実行可能ファイルの先頭に位置する Magic number を識別することで、スクリプトファイルや ELF 実行ファイルの切り替えを行っている。Perl スクリプトファイルの先頭についている #!/usr/bin/perl という、アレである。この場合、#! が Magic number という訳だ。ちなみに file コマンドが識別のために利用しているのも、この Magic number である。
さて、Windows では拡張子に基づいたプログラム自動起動が行われる訳だが、UNIX では不可能なのだろうか?一々、Ruby スクリプトの先頭に #!/usr/bin/ruby という一行をエディターで挿入するよりは、test.rb というファイル名と実行属性を付けるだけで、ruby が起動する方が自然というものだ。
しかし、ご心配なく。Linux では先ほど紹介した binfmt_misc モジュールを使うことで、いとも簡単に実現することができる。まずは組み込み型式でも、モジュール型式でも良いから、CONFIG_BINFMT_MISC を有効化する。モジュールの場合は、insmod も忘れないように。
binfmt_misc の解説は Documentation/binfmt_misc.txt に記載されているが、実はここに大きなピットフォールが隠されている。Linux カーネルに含まれている、このドキュメントを読んだだけでは、binfmt_misc の機能は使えない。「なんでやねん?!」私も原因が分からずしばらく悩んだのだが、答えは binfmt_misc のホームページ に記されていた。
なんと、明示的にルートファイルシステムにマウントしなければならないのだ!こんな事はカーネルソース内の binfmt_misc.txt には一言も書かれていない。どうもカーネルメンテナの一人が、原作者の意志を無視して、ルートファイルシステムにマウントしなければ、register/status ファイルが可視化されないという仕様に変更してしまったようである。これに怒った Richard 氏は、binfmt_misc.txt の修正を行わず、そのまま放置。でも、ユーザーから質問が浴びせられるものだから、自分のホームページ上で弁明・・ということなのだろう。
全てとは言わないが、Linux カーネルというのは、一事が万事この調子だ。私はこれまでの苦い経験から、Documentation ディレクトリに置かれている文書群の内容は最初から疑ってかかるようにしている。信じることが出来るのは、ソースリストだけ。良い意味でも、悪い意味でも、このOSは「アマチュア」だと思う。プロとアマの違いは、コードではなくドキュメントに現れるからだ。
本題に戻ろう。以下に実例を示す(binfmt_misc.o モジュールは組み込み済み)。
23:16:21 root@mebius ~ # ls -al /proc/sys/fs/binfmt_misc/ total 0 dr-xr-xr-x 2 root root 0 Sep 19 23:16 . dr-xr-xr-x 3 root root 0 Sep 19 23:16 ..
ご覧の通り、カーネルに binfmt_misc モジュールを組み込んだだけでは、/proc/sys/fs/binfmt_misc/ ディレクトリは「空っぽ」である。ここで殆どの好奇心旺盛なユーザーは途方に暮れていることだろう。次に、アドバイス通り mount コマンドを実行する。
23:16:45 root@mebius ~ # mount -t binfmt_misc none /proc/sys/fs/binfmt_misc 23:17:26 root@mebius ~ # ls -al /proc/sys/fs/binfmt_misc/ total 0 drwxr-xr-x 1 root root 0 Sep 19 2003 . dr-xr-xr-x 3 root root 0 Sep 19 23:17 .. -r-------- 1 root root 0 Sep 19 2003 register -rw-r--r-- 1 root root 0 Sep 19 2003 status
確かに、register と status ファイルが出現した!(ずっと利用する場合は、/etc/fstab を変更しておこう)。それでは、早速 .rb ファイルを直接実行できるようにセットアップしてみる。
23:25:07 root@mebius ~ # echo ':Ruby:E::rb::/usr/bin/ruby:' > /proc/sys/fs/binfmt_misc/register
binfmt_misc の指定方法は、ホームページ上の解説を参照してほしい。上の例では、.rb 拡張子を持つ実行可能ファイルの場合は /usr/bin/ruby で起動するように指定している。
一見、何事も起こっていないようであるが、カーネルの中身は大変身しているのである。実験してみよう。
23:25:49 root@mebius ~ # cat hello.rb puts "Hello, world!" 23:26:07 root@mebius ~ # chmod +x hello.rb 23:26:13 root@mebius ~ # ./hello.rb Hello, world!
なんと、スクリプトファイルの先頭に #! /usr/bin/ruby がないにもかかわらず、実行属性をつけるだけで、ruby が起動した。素敵!この辺りは、Linux カーネルならではの楽しさと言えるだろう。
CQ 出版ホームページ曰く、「Design Wave Magazine 10月号は,お蔭様でご好評をいただき,弊社在庫分は売り切れました.お近くの書店にてお求めください」。発売前から、日本全国の FPGA 野郎達を興奮させた Cyclone FPGA 基盤付き Design Wave Magazine が完売の様子。私も2冊、買っておけば良かったかなぁ・・。
「技術の真髄を問う」のだそうである。内容は現物を見ていないので何とも言えないが、今の時期に年間契約 12000円 は、なかなか厳しいのではなかろうか?基盤もの第二弾である Design Wave Magazine 10月号が売れ切れる背景を、良く考えてみる必要があるだろう(第一弾が完売になったという話は聞いていない)。