Plan9 を除く普通のOSではファイルシステムのコードはカーネルの中に存在し、そのことが新しいファイルシステムをOSに組み込むことを困難(開発が困難なばかりか、OSの配布者以外は事実上配布不可能)にしていた。Plan9 ではファイルシステムのコードをカーネルの外に置き、カーネルにはファイルシステムとのインターフェースに関するコードを置く。この考え方はFUSE(Filesystem in Userspace)として他のOSでも採用されつつある1。
FUSE(Filesystem in Userspace) を使うと、ユーザースペースのプログラムによってファイルシステムを構成できる。このメリットは計り知れない。例えば
現在までに FUSE を基にした多様なファイルシステムが作成されているが、僕とっては sshfs が役に立っている。
また僕が作った FUSE のサンプルが Maxim があり、MacOS, Linux, FreeBSD で動作が確認されている。
FUSE の面白さが分かるサンプルにしたつもりである。
http://ar.nyx.link/fuse/index.html
From: rsc@plan9.bell-labs.com Subject: [9fans] user-level file systems for Linux Date: 2004年2月19日 10:57:42:JST To: 9fans@cse.psu.edu Reply-To: 9fans@cse.psu.eduThere is a user-level file system driver for Linux called FUSE that has just released a new stable version:
http://sourceforge.net/forum/forum.php?forum_id=350517
They have user-level servers to mount various archives and various network protocols (http, ftp, smb).
The protocol itself looks fairly similar to the old 9P:
http://tinyurl.com/28f2y
There is another similar project called LUFS
http://lufs.sourceforge.net/lufs/
though it seems more complicated than necessary and makes at least one (imo) critical mistake: no fids.
Actually there have been a handful of projects doing similar things over the past few years, and they've all died out. I'm optimistic about FUSE because it's almost an exact translation of the VFS layer, meaning that it's simple and as expressive as possible.
Russ
MacFUSE は OS X 10.4 以降で使える。発行元の Google のページには次のように書かれている。
Examples of file systems that work and have been tested (to varying degrees) include sshfs, ntfs-3g (read/write NTFS), ftpfs (read/write FTP), wdfs (WebDAV), cryptofs, encfs, bindfs, unionfs, beaglefs (yes, including the entire Beagle paraphernalia), and so on.SpotlightFS と sshfs しか Google のページには見つからないが、これらのプロジェクトに関しては
(http://code.google.com/p/macfuse/
)
http://fuse.sourceforge.net/wiki/index.php/FileSystems
https://osxfuse.github.io/
https://osxfuse.github.io/
からダウンロードすれば良いと思う。"FUSE for macOS" のパッケージが置かれており、最新版は2017年5月時点で 3.5.8 である。パッケージのファイルは osxfuse-3.5.8.dmg である。
このバージョンのネーミングは非常に誤解を招く。FUSE を使ったアプリケーションにとって重要なのはライブラリである。
ライブラリのバージョン選択に関しては以下の点に注意する必要がある。
注意すべきは osxfuse-3.5.8.dmg
のインストールで生成されるライブラリは FUSE2 である事である。
インストールすると /dev/osxfuse0, /dev/osxfuse1,...,
が作成される。
Plan9port の 9PFUSE は FUSE の API(ライブラリ) は使っていないが、FUSE の提供するカーネル拡張とマウンタを使っている。従って FUSE バージョンの影響を受ける。
さらに重要なことは、9PFUSE は現時点では osxfuse.3.x.x
の下では動かない。 → 動く様にしました(2017/05/27)
Mac は OS のバージョンアップが激しく、その度にアプケーションは大きな影響を受ける。
(以下の記事は古くなっている可能性がある)
動作確認には SpotlightFS を使うのが簡便であろう。
Gogle のページには次の例が載ってはいるが...
$ mkdir /Volumes/SpotlightFS/Hasselhoff $ ls -lrt /Volumes/SpotlightFS/Hasselhoff [... output omitted to avoid embarrassment ...]
mkdir
が効かない!
-bash$ mkdir /Volumes/SpotlightFS/Google mkdir: /Volumes/SpotlightFS/Google: Permission denied -bash$ ls -ld /Volumes/SpotlightFS dr-x------ 2 arisawa arisawa 0 Aug 20 11:58 /Volumes/SpotlightFS -bash$ ls -l /Volumes/SpotlightFS total 0 dr-x------ 2 arisawa arisawa 0 Aug 20 11:58 SmarterFolder -bash$
chmod
も効かない!
-bash$ chmod 700 /Volumes/SpotlightFS -bash$ ls -ld /Volumes/SpotlightFS dr-x------ 2 arisawa arisawa 0 Aug 20 12:08 /Volumes/SpotlightFS -bash$これは使い方の説明が悪いのだ。ネット上の次の記事を見つけて解決:
http://www.mail-archive.com/macfuse-devel@googlegroups.com/msg00202.html
(以下の記事は古くなっている可能性がある)
まず SpotlightFS を立ち上げておいて
Finder ⇒ ファイル ⇒ 新規スマートフォルダ
/Volumes/SpotlightFS/
macwiki http://macwiki.sourceforge.jp/wiki/index.php/MacFUSE
の説明
SporlightFS を起動すると、「SpotlightFS」というボリュームがマウントされます。このボリューム内にディレクトリを作成すると、作成したディレクトリ名を使って Spotlight の検索がおこなわれ、その結果がディレクトリ中にファイルとして表示されるようになります。が悪い! 次のように書き換えるべきであろう。
SporlightFS を起動すると、「SpotlightFS」というボリュームがマウントされます。ファインダーから新規スマートフォルダを実行し Spotlight の検索を行い、その結果を「保存済みの検索条件」に名前を付けて保存すると、その名前が「SpotlightFS」に生成されます。
http://journal.mycom.co.jp/column/osx/235/index.html
http://journal.mycom.co.jp/column/osx/213/index.html
http://code.google.com/p/macfuse/
http://fuse.sourceforge.net/
http://macwiki.sourceforge.jp/wiki/index.php/MacFUSE
http://code.google.com/p/macfuse/wiki/MACFUSE_FS_SPOTLIGHTFS
http://code.google.com/p/macfuse/downloads/list
Mac の FUSE を使って Plan 9 のファイルシステムをマウントするには MacFUSE(OSXFUSE) の他に Plan9port が必要である。
Plan9port は PowerPC Mac、intel Mac 共にサポートしている。
Plan9port のコードは以下のサイトに置かれている。(いた)
http://swtch.com/plan9port/
https://code.google.com/archive/p/plan9port/downloads
https://github.com/9fans/plan9port
GITHUB 版の Plan9port のインストールに関すしては別ページに解説する。→ http:/p9p/index.html
Plan9port には Plan9 の使いやすいライブラリやコマンドが多数含まれており、特に rc は、unix 系の分かり難くて継ぎ接ぎの貧弱なシェルに比べると天地の違いであり、きっと好きになると思う。なお rc はスクリプト言語に特化しているので、コマンド環境として使うには rlwrap との組み合わせが良いと思う(コマンド履歴が使えるようになる)。
rc については以下の筆者の記事が参考になる。
ネットの記事を見ていると FUSE の能力を示すデモとして sshfs が注目されているようだ。確かに sshfs は UNIX ユーザにとっては驚きであろう。しかし僕としてはこのようなまがい物ではなく、リモートファイルシステムとの本物のリンクが欲しい。Plan 9 の 9P2000 は本物だ。
筆者の実験では
Russ の Plan9port にはバグが含まれ、そのために chmod
コマンドが働かない、また大きなファイルの書き込みで(Linux は問題はないが) Mac ではエラーが発生する。
現在のところ僕が見つけた問題箇所は3つで、修正の理由もコメントとして加えている。
このバグは FUSE カーネルのバージョンに依存している可能性が高いので、最新版では修正されているかも知れない。→ GITHUB の最新版でも同じ
必要な修正に関しては、先の http:/p9p/index.html
に解説されている。(9pfuse
の修正されたプログラムも含まれている)
Mac に関しては、この修正を行ってもまだ問題が残っていて、Finder でファイルを生成するような操作でエラーになる。sshfs に関してはそのような問題は発生していないので、sshfs を研究すれば問題の回避法が分かると思えるが、残念ながら sshfs の Mac 版のソースコドをコンパイルできない。
コマンドでの操作に関しては以上の修正で(現在のところ) Mac、Linux、FreeBSD で実用になっている。
hebe
がファイルサーバー、認証サーバー、HTTP サーバーを兼ねている。僕が文房具代わりに使っているのは MacBook Pro であり、Plan9port はこれにインストールされている。以下、$PLAN9
をインストールディレクトリとする。
$PLAN9/ndb/local
の設定:
# ndb - only used for authdial right now # database - would add extra file= lines here # probably need some kind of syntax to avoid hard-coding paths. database file=root-servers # authentication domains authdom=outside.plan9.bell-labs.com auth=sources.cs.bell-labs.com authdom=hebe.local dom=local # we need this entry for non Plan9 client # the ns value is the name server for dom=local ns=hebe.local # for speed up auth=hebe # # --- WARNING --- # ipv4 must be first, then ipv6 # otherwise ndb/ipquery does not work! # # plan9port does not support il protocol # look $plan9/src/lib9/_p9dialparse.c # ipnet=local ip=192.168.0.0 ipmask=255.255.255.0 ipgw=192.168.0.1 proto=tcp auth=hebe fs=hebe dns=io # these values are advertised by DHCP or BOOTP. (look dhcpd(8)) # we assume that dhcpd is running on the same ip. look /cfg/common/cpurc # search domains are given by dnsdomain # if query is ar, then ar.local and then ar.aichi-u.ac.jp is looked # they are not advertised by DHCP server # therefore DHCP client should add (if unix): # search local # search aichi-u.ac.jp # are used only for ndb/dnsquery dnsdomain=local sys=router dom=router.local # the IPs below are LAN sid # ether=1066820ced19 # WAN # ether=1066820ced18 # LAN ip=192.168.0.1 sys=hebe dom=hebe.local ip=192.168.0.6 # proto=il # il is not supported in p9p
Bell-Labs 純正の Plan9 は(チームが Google に移ったために)現在はメンテされていない。ここから派生した OS が2つある。9tom と 9front である。筆者は 9front を推奨する。推奨する理由は、
(a) Cinap の存在である。Cinap の能力は素晴らしく、僕のような凡人100人以上の力を発揮する。多分天才なのだろう。(それでいて謙虚であると言うか、優しくて親切なんだね)
(b) 9front を推奨する他の理由はファイルシステムに Ken Thompson の CWFS が採用されていることにある。こんなことを言うと Fossil のコードを書いた Russ には悪いが、Plan9 の Fossil は回避した方が良い。理由は(Venti との組み合わせで使うために)仕組みが複雑すぎる点にある。Ventiの設定が難しく性能が出にくい。僕が CWFS に移った時点では Fossil にはバグが残っていた。そのバグはまだ残っているかも知れない。Fossil を使う場合には Venti スコアの管理が重要である。このデータを失うと全てを失うことになる。僕が Fossil を使っていた時には、過去10回分のスコアを安全な場所に保管しており、それによって全滅を免れた経験がある。
(c) 9front が採用しているブートプロセスが素晴らしい。これは Cinap がいたから出来たのであろう。Plan9 のブートプロセスが抱えている問題点は、Bell-Labs にチームが存在すした時代から問題視されていたが、これが 9front で見事に解決されたわけである。Cinap は Rob Pike, Russ Cox に並ぶ天才である。
CWFS(Cached WORM FS) は WORM(Write Once Read Many) と、その Cache の組み合わせで動く。この FS(File System) は Ken Thompson の設計とコーディングである。Ken Thompson のものは FS 専用に1つのコンピュータが要求されたが、Geoff によってユーザーランドのファイルシステムとして再設計された。
Plan9 のファイルシステムの最大の特徴は WORM をベースにしていることだろう。どの OS でもファイルは断片に分けて管理されるが、Unix などで採用されている普通のファイルシステムは(メデイアの価格が高価だった時代に設計されたこともあり)断片を再利用する。そのために断片の繋がりを示す情報を失うと致命的な問題を引き起こす。WORM では断片を再利用しない。1度作られた断片は消されないで残す。それによって過去のファイルシステムの履歴を残せるようになった。 また断片はデバイスのパーティション上に積み上げ方式で作られていく。ファイルは1日の内で何度も修正されたり、作られたり、消されたりする。そうした1日の中で発生する全ての変化を WORM が直接扱う訳ではない。それらは WORM Cache が処理する。 WORM Cache は普通のファイルシステムであり Cache の中のファイルは必要に応じて1日単位で WORM にダンプ(バックアップ)されると言う仕組みである。
CWFS は僕が全面的に信頼している唯一のファイルシステムである。僕は Plan9 を使うようになってから無停電源装置を入れたことがない。突然の電源OFFの場合に発生するダメッジは高々 Cache にしか及ばない。Cache が潰れても前日の状態には回復可能である。(業務用はともかく、個人用にはそれで十分である) WORM への書き込みは数分で終わるが、その間に電源 OFF になったらどうか? WORM には正常にダンプされたことを示すマークが積み上げのトップに書き込まれる。ダンプ失敗なら(多分)もう一度ダンプすれば良いだけであろう。推測でしか言えないのは、経験が無いからである。Ken Thompson のことだ、そこまで考えていると思う。
ハードディスクのような機械装置はやがては壊れる。従って結局は WORM のバックアップが欠かせないであろう。実際に僕もバックアップを取っていた。しかし最近はそれも止めた。理由は大容量 SSD が安価に手に入るようになったからである。SSD では可能な上書き回数はハードディスクに比べて少ないので unix などではサーバーには使われないのであるが WORM では上書きが発生しない。コストの面を別にすれば SSD は WORM に最適である。(安くなったから僕は WORM のために1TBの SSD を使っている。多分使い切れないであろう) もちろん Cache には小容量の SSD を別に割り当てている。
僕は記憶力が悪く(母によれば僕の子供の頃の病気が原因なのだそうだ) CWFS のコンソールへのアクセス方法が分からなくなるので覚えやすいコマンドを持っている。
fscons
:
#!/bin/rc if(test -e /srv/fscons) exec con /srv/fscons if(test -e /srv/cwfs.cmd) exec con -C /srv/cwfs.cmd echo 'no fscons' ls /srv
ここで fscons
を取り上げるのは、認証問題に関係しているからである。
CWFS は次のオプションを持っている。
noauth
、nonone
で制御できる。僕にとって理解し難いのは、こうしたセキュリティセンシティブなコマンドがトグルになっていることだ。打ってみて初めてどうなったかが理解できる。(この問題は簡単なパッチで解決は可能である)
noauth
nonone
Plan9 をやっていて感じる難しさは認証に絡む問題である。認証プロセスを外すオプションは、認証以外の部分が正しく働いていることを確認する上で役に立つ。このオプションを使う場合には、もちろん、ルーターなどによって外部からのアクセスを遮断しておく必要がある。
9front では新しい認証プロトコルが追加された。dp9ik
である。これは p9sk1
の代替えである。p9sk1
は現在では古く、インターネットレベルで使用するには危険である。 Plan9port を使って Plan9 ホストに接続するには以下の点に注意を払う必要がある。
tcp
と il
毎に固定である。il566
及び tcp567
il
をサポートしない。従って Russ の Plan9port も、また drawterm も$PLAN9/ndb/local
で設定するdrawterm
は dp9ik
をサポートしないが、Cinap の drawterm
は dp9ik
をサポートしている。
つまりインターネット環境から家庭などの Plan9 ホストに cpu コマンドなどによるアクセスを許し、かつ p9sk1
を許したく無い場合にはそれ用に認証サーバが必要になると言うことである。僕はそのためにもう一つの認証サーバーとして Raspi を使っている。
9front の標準設定では /rc/bin/service.auth/tcp567
は p9sk1
を禁止している。僕は Unix 環境からのアクセスを必要としているので家庭内ネットワーク用の認証サーバ(ファイルサーバーと兼用)で次のように古いプロトコルも(p9sk1
)を許している。
#!/bin/rc1 #exec /bin/auth/authsrv -N $3 # -N disables old des key exec /bin/auth/authsrv $3
ファイルサーバーの factotum キー:
key proto=p9sk1 dom=local user=arisawa !password=XXXXXX key proto=dp9ik dom=local user=arisawa !password=XXXXXX ...
マウントに絡む問題はコードの修正が必要とされるものが多い。必要な修正は p9p_patch
( http:/p9p/p9p_patch.tgz
) に含まれている。
以下、これが使用されていると仮定する。
mbook
とする)mbook
からアクセスする Plan9 サーバーは hebe
である。hebe
はインターネットからは様々な名前で呼ばれる。例えば ar.nyx.link
とか p9.nyx.link
である。家庭内のパソコンのブラウザからもアクセスしたいので、そのために ar.local
とか p9.local
のような名前でも呼ばれる。かなり複雑なのであるが、以下では複雑な部分を省いて、関係していることだけを説明する。もちろん Plan9port がインストールされている必要がある。
mbook
から hebe
をマウントするために、以下のディレクトリが mbook
に追加されている。
/n
/srv
/mnt
$HOME
以下に置くべきであって、そうした教義を信じる人から言えばクレームがつくであろうが、mbook
は完全に個人使用であるので便利さを優先して構わない。/n
はホストのマウントポイントである。
hebe
のマウントポイントを作ると仮定して、ユーザー(例えば arisawa
)から
sudo mkdir /n /srv /mnt sudo chown arisawa /n /srv /mnt chmod 700 /n /srv /mnt mkdir /mnt/factotum mkdir /n/hebeを実行しておく。(one time action)
/n
の下に置くホストに関しては、後からいくつでも追加できる。筆者は sshfs でマウントする他の unix ホストの名前もここに登録している。その方が楽。
環境変数 NAMESPACE の設定が必要である。
NAMESPACE=/srv ; export NAMESPACE
$HOME/.profile
にでも設定しておけばよい。
Plan9port のインストール時に $HOME/.profile
に
PLAN9=/usr/local/plan9 export PLAN9 PATH=$PATH:$PLAN9/bin export PATH追加されたと思うが、ついでに確認しておく。$PLAN9は、Plan9port の置き場所で、ここでコンパイルしなくてはならない。(他の場所でコンパイルしてもよいが SYMLINK が必要になる)
/srv
には Plan9 ホストとの接続が成功すれば、自動的に /srv/hebe
などが生成される。
/mnt
は認証エージェント factotum が使う。
初めてトライする人は CWFS を認証なしの設定にし、接続の確認をする。9p
コマンドが役に立つ。
9p -a hebe ls
hebe
側の FS root が見えれば接続成功。もちろんパスワードは聞かれない。
成功したら以下のコマンドを順に実行してみよう。
-bash$ srv hebe -bash$ ls /srv hebe -bash$ 9 mount /srv/hebe /n/hebe -bash$ ls /n/hebe
/n/hebe
へのマウントに成功しているはずである。
認証ありにすると難しくなる。
-bash$ ls /n/hebe # not mounted yet -bash$ factotum -a hebe # wait a few seconds -bash$ ls /srv # you should see "factotum" factotum -bash$ 9 mount /srv/factotum /mnt/factotum -bash$ ls /mnt/factotum # you should see "ctl" ... confirm conv ctl log needkey proto rpc -bash$ srv -a -k 'dom=local' hebe !adding key: role=client proto=p9sk1 dom=local user[arisawa]: password: XXXXX ! -bash$ ls /srv # you should see "factotum" and "hebe" factotum hebe -bash$ cat /mnt/factotum/ctl key dom=local proto=p9sk1 role=client user=arisawa !password? -bash$ 9 mount /srv/hebe /n/hebe -bash$ ls /n/hebe 386 68020 adm amd64 cfg fd lib ... -bash$
図1: mount までの流れ
認証には少し時間がかかるかも知れない(5秒程度)。
なお、
9 mount /srv/hebe /n/hebe
mount
コマンドはシェルスクリプトで、内部では結局 9pfuse
コマンドが実行されている。つまり9pfuse /srv/hebe /n/hebe
図1には現れないかせ、9p
コマンドはデバッグにおいて非常に役に立つ。このコマンドの機能は ftp の 9p プロトコル版だと思ってよい。通信状態の基礎が分かるのである。特に認証が正しく働いているか否かの判断が可能である。 9p
コマンドは FUSE には関係していない。 Russ の mount のコードは FUSE に強く依存しており、FUSE が抱えている問題点がそのまま Russ の mount に反映される。Russ が FUSE のコードに問題を感じていてもままならない面があるのである。その点で、9p
は 100% Russ であり、信頼性は高い。
クリーンな状態から出発すれば上記の通りになるはずだか、しばしは途中からになる。例えば factotum が認証データを得るのは one time action に近い。
他方、1日の内に何回でも サーバーへの mount や unmount が発生する。そうした場合には発生しがちなエラーを整理する。
Address already in use:
-bash$ srv -a -k 'dom=local' hebe 9pserve: announce unix!/srv/hebe: Address already in use srv: post9p: 9pserve failed -bash$ rm /srv/hebe # and retry
Address already in use:
-bash$ factotum -a hebe 9pserve: announce unix!/srv/factotum: Address already in use factotum: post9pservice factotum: 9pserve failed -bash$このケースでは認証ずみの場合である。
mount point /n/hebe is itself ...:
-bash$ 9 mount /srv/hebe /n/hebe mount_osxfusefs: mount point /n/hebe is itself on a OSXFUSE volume -bash$ unmount /n/hebe # and retryなお unmount は Plan9port のコマンドである。
Connection refused:
-bash$ 9 mount /srv/hebe /n/hebe 9pfuse: dial /srv/hebe: connect /srv/hebe: Connection refused認証されないとか...
認証からマウントまでのプロセスをもっと簡便にやりたければ、9fs
コマンドがあるので、使ってみるとよい。
ただし Plan9port 付属の 9fs
は認証不要なホストにマウントするのは良いのだけど、認証が必要な場合にはもう少し丁寧にやった方が良い。
僕の場合は次のように変更している。(2017/05/28 コードを追加)
#!/usr/local/plan9/bin/rc if(! ~ $#* 1){ echo 'usage: 9fs sysname' exit usage } fn srv1 { flag=() while(~ $1 -*){ switch($1){ case -a -n flag=($flag $1) shift case -k flag=($flag $1 $2) shift 2 } } if(! 9p stat $1 >/dev/null >[2=1]){ rm -f $ns/$1 srv $flag $2 $1 } } ns=`{namespace} switch($1){ case sources srv1 -n sources sources.cs.bell-labs.com case * if(test -e /n/$1/usr){ echo already mounted exit } if(! test -e /srv/factotum) factotum -a $1 if(! test -e /mnt/factotum/ctl) 9 mount /srv/factotum /mnt/factotum srv1 -a -k 'dom=local' $1 $1 if(! test -e /srv/$1){ echo 'srv failed' exit srv } if(u mount | 9 grep -s /n/$1) unmount /n/$1 9 mount /srv/$1 /n/$1 }
譜1: customized 9fs (2017-06-07 update)
認証が必要な場合には '-a
' も 'dom=
' も指定した方が良い。dom
の値は環境に依存する。
この値はファイルサーバ上で cat /mnt/factotum/ctl
を実行しなければ分からない。
シェルスクリプトなるものは、利用者の環境と好みに合わせて書けば良いのであって、実際には僕の場合には 9fs
の中で sshfs ホストもマウントしている。(unix と Plan9 の混在環境のもとでは、その方が扱いやすい)
僕が現在使用している 9fs が p9p_patch ( http:/p9p/p9p_patch.tgz
) に含まれている。
クリーンアップしてやり直ししたいこともあろう。 one time action の部分は残すことにすれば、次のようになろう。
#!/usr/local/plan9/bin/rc # usage: un9fs # un9p cleans up all 9fs related processes # rfork e path=(/usr/local/plan9/bin $path) if(! ~ $#* 0){ echo 'usage: un9fs' exit usage } pid=`{/bin/ps axg|awk '$5 ~ /factotum|9pserve|srv|9pfs!sshfs/{print $1}'} if(~ $#pid 0) echo 'no 9p related processes' if not /bin/kill -KILL $pid for(f in `{ls /n}) unmount /n/$f unmount /mnt/factotum rm /srv/*
un9fs (クリーンアップ用のコード)
このコードは p9p_patch ( http:/p9p/p9p_patch.tgz
) に含まれている。
ネットを検索していると、9pfs
と言うのに出会った[1]。これは Russ の 9pfuse
の置き換えを狙っているらしい。こののサイトによると、9pfuse
に比べて相当に速いらしい。(キャッシュのお陰だと思う)
Russ は FUSE のライブラリを使用せずに、FUSE のカーネルだけを直接的に利用してコードを書いている。他人の書いたコードに依存したくないのであろう。Russ ほどの力量があればこそ可能な事である。実際に Russ のコードはシンプルで良くわかる。他方 FUSE のライブラリのコードを見ていると、何で... と思う部分が多い。
9pfs
の方は FUSE のライブラリを利用している。少々手を加えればコンパイルは成功する。
typedef uint32_t u32int; typedef int32_t s32int; typedef unsigned char uchar; +typedef unsigned long ulong; typedef unsigned long long uvlong; typedef long long vlong;
size = CACHECTLSIZE; if(off >= size) return 0; - memcpy(buf, "cleared\n" + off, size - off); + memcpy(buf, &("cleared\n"[off]), size - off); clearcache(path); return size;
つまらない GNU 拡張が使われているために数10行の修正が必要になっている。
問題の部分は
char *calls2str[] = { [Tversion] "Tversion", [Tauth] "Tauth", [Tattach] "Tattach", ...
これは clang で蹴られる。この部分は
char *calls2str[] = { [Tversion] = "Tversion", [Tauth] = "Tauth", [Tattach] = "Tattach", ...で書き換えれば解決する。
それにしても GNU は、こんなに詰まらない(酷い)拡張をするのだね~~~
拡張というのは、常に副作用を伴う。従って、拡張が許されるのは相当な理由(合理性)が無くてはならない。例えば、論理的、必然的にあるべき姿が実現していない場合は許されるだろう。しかし、この場合には、文法エラーになって当然の書き方を、1文字の入力の節約のために許してしまおうとする拡張であって、コンパイラのバグと見なして良いものだ。
コードを修正してパッケージにしたものを次に置く。
http:9pfs.tgz
Makefile_osx
、Makefile_bsd
、Makefile_linux
を新たに含めた。
MacOS、FreeBSD、Linux でコンパイルできる事が確認されている。
FreeBSD ではマウントが NG である。
MacOS、Linux ではマウントは OK。しかし、僕はまだ使い込んでいない。
使い込めば、修正が必要な箇所が発見されるかも知れない。
factotum
のマウントは Plan9port の mount
を使うFACTOTUM
が必要 (factotum
の位置を指定する)$PLAN9/ndb/local
での認証サーバの設定
マウントは 9pfs
で統一したいと思っても、factotum
とミスマッチがあるらしい。
筆者の環境では
-bash$ factotum -a hebe -bash$ 9 mount /srv/factotum /mnt/factotum -bash$ export FACTOTUM=/mnt/factotum -bash$ 9pfs -a hebe /n/hebe !adding key: role=client proto=p9sk1 dom=local user[arisawa]: password:
ここに
hebe
は筆者のサーバー名/n/hebe
は hebe
のマウントポイント
あるいは、譜1の最後の 9 mount
に代わって
9pfs -U /srv/$1 /n/$1
FACTOTUM
のみである。しかし factotum
が $PLAN9/ndb/local
を参照している。.fscache
が生成されたように見えるが、これは見かけ上で、実際にはホスト上には作成されていない。ローカル側に作成される。
FUSE では setattr
が使えると思っていたが、fuse-2.9.7
のコードを見ている限り、使えるのは FUSE kernel との low level interface みのであって、普通のプログラマが使う API レベルではサポートされていない。
9pfs
では API レベルを使っているので setattr
がサポートされていない。そのために local のファイルをホスト側にコピーしたときに、元のファイルが持っていた時刻情報(atime
やmatime
など)まで含めてコピーできない。この事が問題なら 9pfs
は使えない事となる。
Russ が 9pfuse で FUSE API を使わなかった理由の1つかも知れない。
その内に解決される可能性は高いのだが...
Russ の 9pfuse は unix ホストの u9fs をマウントできないが1、9pfs だとマウントできる。
もっとも unix から unix ホストのマウントは、現在では sshfs で間に合うだろう。
ところで「9pfs」と言うのはいろいろあるらしい。
記事[1]のコードは Mischief のもの。(コードを見る限り、Mischief は几帳面だね...)
記事[2]から推測すると py9p
プロジェクトの副産物としての 9pfs
。これは、Saveliev と Mirtchovski による開発である。
前者では
Usage: 9pfs [-anU] [-A aname] [-p port] [-u user] service mtpt
後者では
Usage: 9pfs [-dDw] [-c mode] [-p port] [-r root] [-a address] [user [domain]]
また記事[3]によると、「9pfs」は 9P プロトコルの別名としても使われているらしい。
なお記事[4]には、9P の実装が多数紹介されている。(いつの間にか、こんなに...)
[1] 9pfs
https://github.com/mischief/9pfs
[2] 9pfs man page
https://www.mankier.com/1/9pfs
[3] Xen transport for 9pfs version 1
https://xenbits.xen.org/docs/unstable/misc/9pfs.html
[4] 9P Implementations
http://9p.cat-v.org/implementations
クライアントは Mac のノートブック。僕は Mac のノートブックを2つ持っている。PowerBook と MacBook である。いずれも OSX 10.4 環境下で動いている。以下それらを各々 pbook と mbook と呼ぶ。どちらで行っても動作に違いはない。そこで、ここでは pbook での実験のみを示す。
マウントするリモートホストは 3 つを試した。
逆にデメリットは、
実験した日には研究室にある認証サーバ hera は停電のためにダウンしていた。しかし pc は認証サーバーと関係なく動いているので問題はない。
pc に接続するためには、pc の factotum には次の内容が必要である。
key dom=pc proto=p9sk1 user=arisawa !password=xxxxxxxxxxxxxxxx はパスワードである。
以下にマウントに至るまでの pbook で実行するコマンド手順を示す。
-bash$ mkdir /srv # needs only once -bash$ mkdir -p /n/pc # needs only once -bash$ mkdir -p /mnt/factotum # needs only once -bash$ NAMESPACE=/srv -bash$ export NAMESPACE -bash$ factotum # it may be required to execute here (added 2016) # -bash$ 9 mount /srv/factotum /mnt/factotum -bash$ 9fs pc !adding key: role=client proto=p9sk1 dom=pc user[arisawa]: password: ! -bash$ 9 mount /srv/pc /n/pc kextload: /System/Library/Filesystems/fusefs.fs/Support/fusefs.kext loaded successfully -bash$ ls /n/pc 386 NOTICE cfg lp rc 68000 acme cron mail sparc 68020 adm dist mips sys LICENSE alpha env mnt tmp LICENSE.afpl amd64 fd n update LICENSE.gpl arm lib power usr -bash$
ディレクトリ /srv
と /n/pc
はあらかじめ作成しておく。また NAMESPACE
の設定と export
は .profile
で行うのが良いであろう。
9
コマンドは Plan9port のコマンド名が UNIX のコマンド名と衝突する場合に Plan9port のコマンドを実行してくれる。
factotum
を実行すると /srv/factotum
が生成される。"9fs pc
" を実行すると /srv/pc
が生成される。/srv
に生成されたものはソケットである。
Plan 9 の 9fs
はマウントまでやってくれるが、Plan9port の 9fs
はやらない。9fs
は rc スクリプトで内部で srv
を実行している。また、Plan9port の mount
も rc スクリプトで、ソースを見るに BSD 系の OS に対しては 9pfuse
を実行している。
以下にマウントされた時の Mac の Finder を示す。
Finder に反映された MacFUSE
-bash$ mkdir -p /mnt/factotum # needs only onece -bash$ 9 mount /srv/factotum /mnt/factotum -bash$ ls /mnt/factotum confirm conv ctl log needkey proto rpc -bash$ cat /mnt/factotum/ctl key dom=pc proto=p9sk1 role=client user=arisawa !password? -bash$
factotum にデータを追加するには
echo key 'dom=aichi-u.ac.jp proto=p9sk1 role=client user=arisawa !password=xxxxxxxx' >> /mnt/factotum/ctlのように "
>>
" を使う必要がある。(Plan 9 の factotum の場合には ">
" で構わない。)
削除するときにも同様である。
ls -l
を実行してみると UNIX の限界がよく分かる。
-bash$ ls -l /n/pc total 85 drwxrwxr-x 1 arisawa arisawa 0 Jun 27 17:24 386 drwxrwxr-x 1 arisawa arisawa 0 Jan 31 2007 68000 drwxrwxr-x 1 arisawa arisawa 0 Jan 31 2007 68020 -r--r--r-- 1 arisawa arisawa 13006 Jul 13 2005 LICENSE -rw-rw-r-- 1 arisawa arisawa 14333 Jun 29 2003 LICENSE.afpl -rw-rw-r-- 1 arisawa arisawa 15081 Jun 26 2003 LICENSE.gpl -r--r--r-- 1 arisawa arisawa 63 Apr 15 2002 NOTICE drwxrwxr-x 1 arisawa arisawa 0 Jan 31 2007 acme ...オーナーやグループはどれも
arisawa
になっているが、本来は sys
である。UNIX ではファイルシステム毎にファイルのユーザとグループを決める事ができないので、リモートファイルをマウントした時にローカルファイルシステムのユーザとグループで適当にマッピングする他ない。ここでは全て arisawa
にマッピングされているのだ。その場合にはファイルに対する arisawa
の本来のアクセス権を知る事ができない。
コマンドでファイルにアクセスする限り、実際にアクセスして拒否されれば知らせてくれる。しかし Mac の Finder を通じてマウスでクリックしていると状況が異なる。Finder は余計な親切をしているのだ。それがあだになって読み取れるはずのファイルが読み取れない事もある。(Finder は正しいメッセージを出していない!)
このような問題は UNIX と Plan 9 と言う異質な OS を結んだから発生したのではない。 UNIX 相互でも管理者ドメインが異なれば同じ問題が発生する。UNIX がネットワーク環境に適合しないと言われる根拠の一つになっている。
参考のために Plan 9 端末から u9fs を使って UNIX (Mac OSX) をマウントした場合の ls -l
を示す
--rwxrwxrwx M 29 arisawa staff 6148 Apr 24 22:05 .DS_Store d-rw------- M 29 root ??? 272 Aug 29 06:34 .Spotlight-V100 d--wx-wx-wx M 29 root admin 170 Feb 23 2006 .Trashes [中略] d-rwxr-xr-x M 29 arisawa staff 1360 Jan 26 2003 システムフォルダ d-rwxrwxr-x M 29 root admin 340 Sep 13 2002 書類 d-rwxr-xr-x M 29 arisawa admin 68 Jan 26 2003 起動時に消去する項目グループ名の欄の "
???
" は元は数字であった。この変更以外は本来のユーザ名とグループ名が正しく表示される。Plan 9 の場合にはマッピングの必要はないのである。
/lib/ndb/local
で、ar の認証サーバーとして hera が指定されている。また ar の factotum はkey dom=aichi-u.ac.jp proto=p9sk1 user=arisawa !password=xxxxxxxxである。(xxxxxxxx はパスワード)
ar の認証ドメインは aichi-u.ac.jp
であるが、factotum には認証サーバーに関する情報が含まれていない。従って pbook から ar をマウントするには ar の認証サーバーが何であるかを知らせる必要がある。この事は $PLAN9/ndb/local
で行える。僕のケースでは
authdom=aichi-u.ac.jp auth=hera.aichi-u.ac.jpを追加した。これを追加すれば、マウントまでの手順は pc と同じである。
hera.aichi-u.ac.jp
は NetInfo に登録しておかなくてはならない。
これは unix (like) から unix (like) へのマウントである。
pmac は自宅の PowerMac G4 で、ここでは u9fs が動いている。pmac は Plan 9 端末からはマウントできる。しかし不思議な事に pbook からは(pmac からも)マウントできない。
この問題は現在においても解決できない。9fans ではマウントできるとの情報もある。(2016/02/17)
-bash$ 9fs pmac authdial: Connection refused原因不明
9 mount /srv/ar /n/ar
unmount
9 unmount /n/ar
9fs ar
-bash$ ps PID TT STAT TIME COMMAND 24157 p1 S 0:00.46 -bash 24276 p1 S 0:00.51 factotum 24278 p1 S 0:02.51 9pserve -u unix!/srv/factotum 24289 p1 S 0:40.18 9pserve -u -M 8192 -A 0 unix!/srv/ar 24306 p1 S 0:11.60 9pserve -u -M 8192 -A 0 unix!/srv/pc 24198 p2 S+ 0:00.07 -bash -bash$ kill 24289 -bash$ ls /srv ar factotum pc -bash$ rm /srv/ar -bash$Plan 9 の場合には
/srv/ar
だけを消せば良かったが、Plan9port ではプロセスも落とさなくてはならない。
factotum
を取り消すには-bash$ ps PID TT STAT TIME COMMAND 24157 p1 S 0:00.53 -bash 24751 p1 S 0:00.01 factotum 24753 p1 S 0:00.01 9pserve -u unix!/srv/factotum 24198 p2 S+ 0:00.07 -bash -bash$ kill 24751 -bash$ rm /srv/factotum -bash$
この後に
unmount /mnt/factotum
"9pserve -u unix!/srv/factotum
" は factotum
によって生成されたプロセスで factotum
を落とせば自動的に落ちるが、/srv/factotum
は削除しなくてはならない。
pc
とか ar
は実験当時に筆者が使用していたホスト名である。pmac
は実験当時に僕が(Plan9port をインストールして)使っていた PowerBook の名称である。
実験では 9fs
は Plan9port 付属のものをそのまま使用していた。譜1を使えは、もっとスムーズに行く可能性がある。
bash$ 9fs pc !adding key: role=client proto=p9sk1 dom=home user[arisawa]: password: ! authdial: unknown host home bash$原因: pc 側の factotum の誤設定
dom=home
となっていた。$PLAN9/ndb/local の設定と一致していることを確認する。
-bash$ factotum -bash$ 9fs ar srv: authproxy: auth_proxy rpc: p9any client ask for keys: unable to find common key -bash$この問題は
$PLAN9/ndb/local
の設定を行う事で解決したはずである。
-bash$ echo key 'dom=aichi-u.ac.jp proto=p9sk1 user=arisawa !password=xxxxxxxx'>/mnt/factotum/ctl -bash: /mnt/factotum/ctl: Result too largeこの問題は "
>>
" を使う事によって解決する。
-bash$ 9 mount /srv/pc /n/pc can't mount on Darwin -bash$これは pmac から pc をマウントするときに出た。原因は pmac の Plan9port が古い事による。最新の版をダウンロードしてインストールすれば解決する。
このメッセージはマウントするときに発生する。例えば
-bash$ 9 mount /srv/hebe /n/hebe 9pfuse: dial /srv/hebe: connect /srv/hebe: Connection refused
原因は認証されないままマウントを試みたからだろうと思われる。
参考のために、実行すべきコマンドと、その結果として生成されるファイル("→" で示してある)を以下に示しておく。
"*
" はそこに名前が存在することを意味する。また"#
" より右はコメントである。
認証は
9fs
で行われているので、/mnt/factotum/ctl
が存在すれば、(このケースでは)
9fs hebe
なお譜1だと "9fs HOST
" でマウントまで進むはずである。
認証を求めようとして 9fs
で次のメッセージに出会うことがある。
-bash$ 9fs nix authdial: Connection refused
相手ホストは Linux で、こちらは Mac である。
今のところ筆者は unix 相互のマウントに成功したことがない。
Connection refused
の発生要因として多いのは、閉じている port へのアクセス。(2017/06/13)
-bash$ 9pfuse /srv/mmac /n/mmac 9pfuse: fsmount: fid unknown or out of range -bash$
これは macbook から mac mini へのマウントで発生する。もっと一般的に言えば unix (like) から u9fs へのマウントで発生する。原因は認証が正しく行われていないからだろうと思えるが、「Connection refused」との違いが今のところ分からない。
既にマウントされている XXX
にさらにマウントしようとした。
unmount XXX
9PFUSE はコマンドレベルで使う限り、現在のところ問題はない。
しかし Finder との関係では問題がある。見えることは見えるのだが、書き込みが発生する操作(複製とか Drag&Drop とか)はエラーになる。これが何から発生しているか今のところ分からない。Macの拡張属性の処理ではないかとは推測しているが証拠を持っていない。
sshfs は上手くやっているので研究したいと思う。
Mac 付属のテキストエディタ TextEdit.app や Xcode.app では、(拡張属性が邪魔をして)編集した結果を保存できない1。
Plan9port の acme は OK である。
ところで最近の TextEdit.app は(僕にとっては非常に使いにくくなっている)
なお僕は edit コマンドを作って持っており、TextEdit.app で読み取る前に xattr を削除することとした。
関係するコードは次の通りである。(rc で書かれている)
xa=`{xattr $e} # extended attribute if(~ $xa ?*) xattr -d $xa $e open -a $EDITOR $e || echo $usageここに、$e は編集の対象となっているファイルである。
TextEdit.app
はファイルの保存時に必ず拡張属性も合わせて保存する。不思議なことに、9pfuse でも 9pfs でも拡張属性の上書きができない。その場合には、TextEdit.app
はファイルの上書き(つまり保存)を拒否するようだ。 従って 9pfuse や 9pfs を使って Plan9 ホストをマウントした場合には、エディタは acme 択一になろうか? (2017/06/13)
http://swtch.com/plan9port/
http://swtch.com/plan9port/man/man3/9pclient.html
http://swtch.com/plan9port/man/man4/intro.html
http://swtch.com/plan9port/man/man4/9pfuse.html
http://swtch.com/plan9port/man/man4/factotum.html