つれづれ日記 2015年10月

予定

毎日


2015年10月21日 (水曜日)

18:58:12 # Life FUSEのファイルシステムでioctlを実装してみた。 POSIX系のデバイスファイルでは通常ioctlというインタフェースで操作ができるようになっていて、read/writeだけでは表現しきれないことができるようになってます。 別にこれはデバイスファイルじゃないと実装しちゃダメってことはないので、FUSEでファイルシステムを実装するととりあえず任意のFUSEファイルシステム上のファイルに対してのioctlを実装することが可能です。 gitlstreefsでファイルにioctlしたらGitハッシュがわかるようにしたいなとおもったので調査してみた。ioctl(fd, ioctl番号, &arg)という感じでクライアント側は使うのだけど、ioctlの番号にデータのサイズとかがエンコードされていて、その番号を生成するマクロがsys/ioctl.hに定義されている。例えば _IOR / _IOW マクロはioctlの番号とパラメータのサイズを指定する。 FUSEでの複雑な点はioctlを呼び出したアプリケーションの仮想メモリ空間とFUSEサーバ側の仮想メモリ空間は別なので通常のカーネルドライバと違いarg の指す先を参照することができないこと。そのため、FUSEではioctlのコマンドにエンコードされたデータのサイズを活用してそれをメモリコピーしてくれるような実装になっています (ioctlのハンドラーには2種類あって、iov で任意の領域を指定してカーネルにコピーしてもらうというモードもあるのだけどここでは割愛)。 _IORで定義したら読み込み用なのでFUSEのハンドラで書き込んだデータをクライアント側にコピーしてくれて、_IOWで定義したら書き込み用なのでクライアント側から書き込んだデータをFUSEのハンドラにコピーしてくれる。一個はまったのは fuseのioctl のインタフェースにはargとdataというパラメータがあるのだけど、argがクライアント側のプロセスのメモリ空間の中でのアドレスで data がFUSEサーバ側のプロセスのメモリ空間にコピーしてくれた側でのアドレスで、argはほぼなにの役にも立たずdata側を利用しないといけないこと。 FUSEのdoxygenドキュメントが全く意味不明で in /out area がどうのという別のモードの説明しかかいてなくてしばらく悩みました。 ドキュメントが意味の通る感じだったら、ソースをちゃんと最初から読んでいたら、もうちょっとはやくわかったかな。

static int fs_ioctl(const char *path, int cmd, void *arg,
	  struct fuse_file_info *fi, unsigned int flags, void *data);

	

2015年10月16日 (金曜日)

06:47:33 # Life SSH 経由で git リポジトリをマウントする。 毎回ちょっとテストするためにgit clone するの不便だなぁと思っていたので gitlstreefsにそういう機能を追加してみた。これでなんか便利になるかな。

2015年10月2日 (金曜日)

06:58:19 # Life FUSE と Git と遊んでみた。 10年前を振り返ってみるとGitとかFUSEとかに熱中していたのだけどあまりがりがりとGitもFuseもコード書いていないなぁと思ったので両方をガリガリといじるC++のプログラムをいくつか書いてみました。 Githubのgitlstreefs においてあります。 Gitリポジトリの特定リビジョンをマウントするツール gitlstreefs、とそれの libgit2を使って再実装してみたけど遅くなってしまったバージョン。 ninja のターゲットをファイルとして見せてくれ、必要になったらビルドしてくれるninjafs。 実用的じゃない感じのものですが宴会受けは良かったかも。


Junichi Uekawa