試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

Debian/Ubuntuにおけるbinfmt_miscに関するメモ(Ubuntu 11.04時点・後半)

Debian/Ubuntuにおけるbinfmt_miscに関するメモ(Ubuntu 11.04時点・前半)」の続き。

判別ツール(detector)について

前半の「update-binfmts --display」の出力を見ると、同じ「MZ」という内容のマジックが

の2つから関連付けられていることが分かるが、実際にそれぞれの形式のファイルを直接実行してみると、MonoWineの内の適切なプログラムが選択されて問題なく実行できている(作業例は略)。
このような「マジックのみでは判別不可な2種類の形式」を区別する際に用いられるのが判別ツール(detector)で、Mono/.NETアセンブリの場合は

detector = /usr/lib/cli/binfmt-detector-cli

とあるように、/usr/lib/cli/binfmt-detector-cliというツールが用いられており、.exeファイルを直接実行したときにこれが自動的に実行されて形式の判別が行われた後、MonoWineのどちらを用いるかを決定しているようだ。
「detector」として使うプログラムは、引数に判別したいファイルの場所を指定して、その形式(ここではMono/.NETアセンブリ)に合っていれば0,合っていなければ0以外を戻り値として終了するような仕様となっている。

$ /usr/lib/cli/binfmt-detector-cli [Windowsの実行ファイルの場所] && echo "Mono/.NET Assembly" || echo "Windows executable"
Windows executable
$ /usr/lib/cli/binfmt-detector-cli [Mono/.NETアセンブリの場所] && echo "Mono/.NET Assembly" || echo "Windows executable"
Mono/.NET Assembly

以前「.exeファイル(Windows用とMono/.NET用)の識別と関連付けについて」でfileコマンドの出力で区別する方法を扱っているが、こちらのツールを用いたほうが扱いやすい。

binfmt-detector-cliについて

/usr/lib/cli/binfmt-detector-cliDebian/Ubuntuの「mono-runtime」パッケージに含まれるツールだが、Mono側のソースツリーには含まれず、Debian/Ubuntuの(ディストリの)パッケージにおいて独自に添付されているツールとなっている。
ソースは同パッケージのソースパッケージのdebian/detector/ディレクトリ内に存在する。プログラム名は「binfmt-pe」で、C言語で書かれており、GPLのバージョン2もしくはそれよりも後のバージョンでライセンスされている。

/proc/sys/fs/binfmt_misc/以下への登録処理について

/proc/sys/fs/binfmt_misc/以下への登録処理についてはupdate-binfmts--enableオプション付きの実行によって行われており、ディストリの起動処理の中でこれが自動的に実行されてカーネル(モジュール)側に設定が適用される。

/usr/lib/binfmt-support/run-detectorsの動作について

/var/lib/の中にはbinfmtsというディレクトリが存在し、update-binfmtsの設定が形式ごとにテキストファイルに保存されている。

(以下の出力についても、ディストリ内のパッケージのインストール状況によって内容が異なる)
$ ls /var/lib/binfmts
cli  jar  jarwrapper  python2.6  python2.7  python3.2  wine
$ cat /var/lib/binfmts/cli
mono-runtime
magic
0
MZ
(空の行)
/usr/bin/cli
/usr/lib/cli/binfmt-detector-cli
(空の行)
$ cat /var/lib/binfmts/wine
wine
magic
0
MZ
(空の行)
/usr/bin/wine
(空の行)
(空の行)

これらは/proc/sys/fs/binfmt_misc/以下の項目と対応しており、ファイル実行時の全体的な処理の流れとしては、前半の内容とあわせると

  1. /proc/sys/fs/binfmt_misc/以下の設定により「interpreter」項目のプログラムにファイルの場所を渡す(同一マジックで複数のファイル形式が存在しない形式の場合はここで終了)
  2. 同一マジックで複数のファイル形式が存在する場合は「interpreter」として/usr/lib/binfmt-support/run-detectorsへファイルの場所を渡す
  3. /usr/lib/binfmt-support/run-detectors/var/lib/binfmts/以下の項目を参照し、マジックが一致するものの「detector」(.exe形式であれば/usr/lib/cli/binfmt-detector-cli)を実行して形式を判別
  4. 形式が判別されたら/var/lib/binfmts/以下の内容から実行するプログラムを決定して実行

となる。

関連記事: