Unengineered Weblog

PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND

Unixのファイルシステムを9Pでサーブするu9fsを「ちょっと」使う

github.com

u9fsはPlan 9に付属している(のに)Unix向けのソフトウェアである。これはUnixファイルシステムPlan 9通信プロトコル9Pでサーブし、Plan 9でマウントすることを目的としている。私は初め使い方が全く分からなかったので、私と同じ人のためにメモを残す。

若者のinetd離れ

u9fsのソースコードにはソケットを操作する部分が見当たらなかったため、初めて読んだとき(こいつはどうやって通信するんだ)と悩んだ。 答えをいうとこのソフトウェアはinetdを使って通信するのだ。 私は"若い" Unixユーザーなので最近あまり使われていないinetdを知らなかったのである。 inetdはsuffixのdが示すとおり、デーモンである。 使い方はWikipediaのページを参照してほしい。

ja.wikipedia.org

要するにinetdは接続がacceptされた際に登録されたプログラムを起動し、そのプログラムの標準出入力をソケットにフックするのだ。 つまりinetdを使って通信するu9fsは標準出入力を通して9Pをサーブしているのである。 これがわかればinetdを使わなくても通信できる。

u9fsの使い方を示した日本語の記事を紹介しよう。

p9.nyx.link

oraccha.hatenadiary.org

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

github.com

これは私が作成した簡易版inetdである。とても単純なプログラムだ(Plan 9のユーザープログラムにこれに似たlisten1がある)。

$ listen -a 'localhost:5640' ./u9fs -a none -l /dev/null -n -u $(id -un)

と起動する。これは接続ごとにu9fsをexecするので同時に何度も接続することが可能である。