u9fs
2008/02/18 追加
2016/02/17 補足
2017/06/13 改訂
u9fs とは
Plan9 端末から UNIX のファイルシステムを参照するには u9fs が一番使いやすい。rlogin と異なり、u9fs は UNIX のファイルシステムを Plan9 端末にマウントしてくれる。また Plan9 の ftpfs と異なり、ファイルに対してシーク(seek)命令が働くので tail などのコマンドでファイルの全てがコピーされることはない。
以下に簡単な使用例を挙げる。
nx
を UNIX システムとすると、
term% 9fs nx post ... # message term%
nx
のファイルシステムは /n/nx
の下に見える。term% ls /n/nx term% ls /n/nx ... /n/nx/bin /n/nx/dev /n/nx/etc /n/nx/home ... /n/nx/tmp /n/nx/usr term%
すなわち、cp や grep などのツールが使え、マウスベースのエディタで編集できる。
u9fs のインストール
方針
- /usr/local/sbin/u9fs # u9fs 本体
- /var/log/u9fs.log # log file
- /etc/u9fs.key # key による認証
u9fs は認証方式として次の3種類をサポートしている。
- rhosts による「認証」(rlogin の方式と同じ)
- キーによる認証
- 認証不要
また Linux や FreeBSD では (inetd ではなく) xinetd の下で動かす。Mac は全く方法が異なるので、独立して解説する。
u9fs のインストール
u9fs は/sys/src/cmd/unix/u9fs
に置かれている。これを UNIX 側にコピーして(ftpfs を使うがよい)、
unix$ make unix$ su root# cp u9fs /usr/local/sbin root# touch /var/log/u9fs.log
Mac にインストールするなら筆者のをダウンロードするのが良いだろう。
理由は
- 古いコードの修正が終わっていること、
- 悪名高い Mac の UTF8-MAC 対策がされていること
筆者のは
http:/netlib/u9fs/
に置かれている。
認証キーの設定
/etc/u9fs.key
に利用者のキーを設定する。(この場所は u9fs の -A
オプションで変更できる。
xxxxxxxx arisawa ddddddここに
xxxxxxxx
はパスワードで dddddd
は dom
の名称である。dom
の名称は適当に付けてよいが、パスワードが異なる他のシステムの名称と同じであってはならない。筆者の場合には u9fs をインストールしている Mac は家庭に設置されており、記憶力に乏しい筆者は mac
にしている。
/etc/service
さらに /etc/services
に
u9fs 564/tcp u9fs
/etc/xinetd.d/u9fs
の中でも可能になったようです)
xinetd による設定
2017/06/05 更新
まず
ps -axg|grep inetd
次に /etc/xinetd.d/
に以下の内容のファイル u9fs
を追加する
service u9fs { disable = no socket_type = stream protocol = tcp wait = no user = root server = /usr/local/sbin/u9fs server_args = -a p9any -l /var/log/u9fs.log groups = yes flags = REUSE }
xinetd の設定を変更した場合には root 権限で
-bash$ sudo /etc/init.d/xinetd restart
OSX Leopard の plist による設定
2008/02/18
OSX Leopard になって xinetd が無くなって launchd による plist に一本化された。設定例は次の通りである。
/Library/LaunchDaemons/com.bell-labs.plan9.u9fs.plist
の内容
plist のロード
/Library/LaunchDaemons/
の com.bell-labs.plan9.u9fs.plist
の設定を変更した後、それを Launchd に反映させるには
-bash$ sudo launchctl unload /Library/LaunchDaemons/ -bash$ sudo launchctl load /Library/LaunchDaemons/ -bash$を実行すればよい。
設定上の注意
/etc/services
で既に 9pfs
が定義されているので、"SockServiceName
" の値を 9pfs
にしたい所であるが、認識しない。次のエラーが出る。
sh-3.2# launchctl load /Library/LaunchDaemons/com.bell-labs.plan9.u9fs.plist getaddrinfo(): nodename nor servname provided, or not known
僕はこれまで plist を設定した事がなかった。このために今回は大変手間取った。
C プログラミングの世界に住んでいる者にとって、plist における、実行されるプログラムとその引数の指定の方法は "???" になりやすい。つまり "ProgramArguments
" を次のように書きやすいのである。
0 /usr/local/sbin/u9fs 1 u9fs 2 -l 3 /var/log/u9fs.log 4 -a 5 p9anyなぜ "
/usr/local/sbin/u9fs
" を "Program
" に指定しないで "ProgramArguments
" なんだ! と違和感を覚えつつ上記のように設定して、その為に 2 日程無駄な時間を費やした。僕は接続を検証するためにシンプルなプログラム "connect" を持っているが、それを使って 564 ポートにアクセスして、ようやくこの誤りに気付いた次第である。Plan 9 の "con" でも、あるいは OSX からtelnet loaclhost 564
initgroups (xinetd の groups) の値は YES でなくてはならない。Leopard でのデフォールトは YES であるが Tiger では NO なので、ここに上げた plist はそのまま Tiger では使えない。
参考になる文献
マニュアルによると plist の置き場所は次の 5 カ所である。
~/Library/LaunchAgents Per-user agents provided by the user. /Library/LaunchAgents Per-user agents provided by the administrator. /Library/LaunchDaemons System wide daemons provided by the administrator. /System/Library/LaunchAgents Mac OS X Per-user agents. /System/Library/LaunchDaemons Mac OS X System wide daemons.最後の 2 つには多数の plist が置かれており、設定サンプルとして役に立つ。
マニュアルは次の 3 つが基本的である。
- launchd(8)
- launchd.plist(5)
- launchctl(1)
- Getting Started with launchd
http://developer.apple.com/macosx/launchd.html
- plist
http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man5/launchd.plist.5.html
- launchctl(1)
http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html
- 第1回 initを置き換えるlaunchd【前編】
http://www.itmedia.co.jp/enterprise/articles/0704/26/news009.html
Launchd のデバッグ
僕は NeXT 時代にから NetInfo を使っているが、Launchd の plist にせよ、このような複雑なものは苦手だ。
Plan9 であれば netstat -n
によってサービスが行われているポートが直ちに分かる。これに相当する UNIX のコマンドは netstat -na
である1。次に示すのはその出力例で
-bash$ netstat -na Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 *.564 *.* LISTEN tcp6 0 0 *.564 *.* LISTEN tcp4 0 0 127.0.0.1.631 *.* LISTEN tcp6 0 0 ::1.631 *.* LISTEN564ポート(9pfs) が開いている事が分かる。ポート名を名前で表示させたい場合には
netstat -a
ラベル(例えば com.bell-labs.plan9.u9fs
)を指定して、launchd が実際に実行する plist の内容がダンプされるとありがたいのだが、launchctl にはその機能が見当たらない。
launchd のアクセスログは /var/log/system.log
に記録される。この内容はデバッグに役に立つ。
netstat -an64
ソースコード
コンパイル
なお u9fs のソースコードをコンパイルすると 2 つのファイルで warning が出る1。この warning は無視しても構わないが、いずれも include の追加で解決する。(以下の /* OSX,Linux */
の行)
oldfcall.c
:
#include <plan9.h> #include <stdlib.h> /* OSX,Linux */ #include <fcall.h> #include <oldfcall.h>
safecpy.c
:
#include <stdio.h> #include <string.h> /* OSX,Linux */
さらに次のエラーメッセージは(OSX の場合には) XCode がインストールされていない場合に発生する。
/usr/libexec/gcc/i686-apple-darwin8/4.0.1/ld: /usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libSystem.dylib unknown flags (type) of section 6 (__TEXT,__literal16) in load command 0 collect2: ld returned 1 exit status make: *** [u9fs] Error 1
u9fs の仕様の不十分な点
不思議な事に/etc/u9fs.key
は一人分のキーしかサポートしていない1。この点は改善されるべきで、好ましい仕様はキーはユーザの責任で管理することとし$HOME/keys/u9fs
$HOME/.*
に置いており、いっこうに改善されない。
注1: この問題は u9fs のプログラム構造と関係しているらしい。fork が使われていない。(thread さえも使われていない) それでいて複数のクライアントからの同時接続が可能である。しかし結局はせいぜい1人分である。大規模なクライアントをサポートするには認証システムの他に、プログラム構造にメスを入れる必要がある。しかし、難しいという程ではないだろう。若い子の手ごろな課題である。それに、unix の分散ファイルシステムを置き換えるポテンシャルを持っているのでやり甲斐があるだろう。(2016/02/17)
不可思議な unix の kill の仕様
今回気がついた事であるがユーザモードで-bash$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE 9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG 17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD 21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGINFO 30) SIGUSR1 31) SIGUSR2 -bash$スーパーバイザモードで
root# kill -l HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 root#そしてどちらのモードでも
-bash$ /bin/kill -l hup int quit ill trap abrt emt fpe kill bus segv sys pipe alrm term urg stop tstp cont chld ttin ttou io xcpu xfsz vtalrm prof winch info usr1 usr2 -bash$異なるプログラムが動いているのではないことは
which
コマンドで確認できる。筆者はこのように動作するプログラムを作る事はできるけれども、このような仕様を考えるプログラマーの気持ちが分からない。
ssh からの u9fs の起動
2005/05/102016/02/17 改定
UNIX ホストが ssh によるログインを許していれば1もっとエレガントな方法で Plan 9 から UNIX ホストのファイルをマウントできる。この方法の利点は、UNIX ホストの管理者権限を必要とせず、完全にユーザレベルの設定でやって行ける事、さらに UNIX 側の設定が要らない事にある。
以下に筆者の Mac OSX を例に解説する。なお以下において mac は筆者の Mac のホスト名はである。
1. Plan 9 端末から ssh でログインできる事を確認する。
ssh -r mac
term% ssh -r mac Last login: Tue May 10 13:06:26 2005 from 192.168.1.2 Welcome to Darwin! -bash$となれば OK である。
最初の1回目は暗号キーの確認を求められる。
2. u9fs へのパスが通っている事を確認する
Plan 9 端末から
ssh mac echo '$PATH'
u9fs へのパスが通っていない時には
$HOME/.bashrc
3. u9fs の実行
Plan 9 端末から
term% mntgen term% srvssh mac post...そして(この window はそのままにして)他のウィンドウから
term% mount /srv/mac /n/mac term% ls /n/mac /n/temp/.DS_Store /n/temp/.Trashes ...
srvssh はポート564(9fs ポート)を使わずに、ssh ポートを使った u9fs だと考えて良い。
この利点は、
- 認証系は ssh のを使える
- 独立して動くので、複数のユーザーが同時に使用しても問題が発生しない
ssh ポートの入出力は、古い(RS232C)時代の通信と相手が人間であると想定しており、そのために Byte 通過性が担保しずらい。通信路を Byte 透過にする方法は相手(unix)に依存する。旨く働くには多少の試行錯誤が要求されるかもしれない。その場合、やるべきことは
/rc/bin/srvssh
さて、「この window はそのままにして」と書いたが、srvssh の仕組みを考えると重要である。この window の中での I/O は srvssh でも使われており、干渉するリスクがある。
文字コード
u9fs は utf-8 に対応している。従って Mac OS X の日本語のフォルダはちゃんと表示される。もっとも OSX の日本語ファイル名/フォルダ名の扱いは少し変なのだ。OSX はファイル名やフォルダ名に UNICODE を使用している。不思議にも OSX は「ダ」や「パ」あるいは「だ」や「ぱ」などのように濁点や半濁点が名前に含まれる場合に、本来1文字として扱うべき文字を2文字として扱っているのである。まるで半角片仮名時代への逆行である!
さて、このような嫌らしい Mac のファイル名が Plan9 に流れ込むのは嫌なので、パッチを当てることにしていた。今回、文字コードの対応を日本語文字だけではなく、全てのラテン系の文字、およびギリシャ文字に拡張した(2017/06/23)。
http:/p9p/index.html