u9fsはPlan 9に付属している(のに)Unix向けのソフトウェアである。これはUnixのファイルシステムをPlan 9の通信プロトコル9Pでサーブし、Plan 9でマウントすることを目的としている。私は初め使い方が全く分からなかったので、私と同じ人のためにメモを残す。
若者のinetd離れ
u9fsのソースコードにはソケットを操作する部分が見当たらなかったため、初めて読んだとき(こいつはどうやって通信するんだ)と悩んだ。 答えをいうとこのソフトウェアはinetdを使って通信するのだ。 私は"若い" Unixユーザーなので最近あまり使われていないinetdを知らなかったのである。 inetdはsuffixのdが示すとおり、デーモンである。 使い方はWikipediaのページを参照してほしい。
要するにinetdは接続がacceptされた際に登録されたプログラムを起動し、そのプログラムの標準出入力をソケットにフックするのだ。 つまりinetdを使って通信するu9fsは標準出入力を通して9Pをサーブしているのである。 これがわかればinetdを使わなくても通信できる。
u9fsの使い方を示した日本語の記事を紹介しよう。
inetdを使わずにちょっと使ってみる
この記事の本題である。ちゃんと使うにはinetdを設定する必要があるが、面倒である。 ちょっと使うだけなら次の方法できるだろう。
netcat
一番簡単なのはnetcat (nc)を使う方法である。
fifo=/tmp/tmpfifo.$$ mkfifo $fifo ./u9fs -a none -l /dev/null -n -u $(id -un) < $fifo | nc -l localhost 5640 > $fifo
あまり用いられないnamed pipeの格好の利用例でもある(ちなみにmktemp(1)に似た一時的なnamed pipeを作るコマンドmktempfifoがある)。
設定は接続時の認証は無し(-a none
)、ログファイルは残さず(-l /dev/null
)、u9fsを通して作ったファイルのオーナーは自分(-u $(id -un)
)としている。
オプションについて詳しくはmanページを参照してほしい。
そして別のターミナルから接続してみよう(9pはplan9portにあるコマンドで、9Pのクライアントである)。
$ 9p -a 'tcp!localhost!5640' ls -l d-rwxr-xr-x M 0 root root 106496 Jul 23 12:45 bin d-rwxr-xr-x M 0 root root 4096 Jul 23 12:36 boot d-rwxrwxr-x M 0 root root 4096 Mar 2 2020 cdrom d-rwxr-xr-x M 0 root root 5120 Jul 23 15:13 dev d-rwxr-xr-x M 0 root root 12288 Jul 23 12:45 etc ...
この方法は一度しか接続できないという問題点がある。
listen
これは私が作成した簡易版inetdである。とても単純なプログラムだ(Plan 9のユーザープログラムにこれに似たlisten1がある)。
$ listen -a 'localhost:5640' ./u9fs -a none -l /dev/null -n -u $(id -un)
と起動する。これは接続ごとにu9fsをexecするので同時に何度も接続することが可能である。