chatty9p〜9Pプロトコルをのぞき見る
昨日はファイルサーバの雛形について書いたが,9Pプロトコルをハンドリングするライブラリlib9pを使ったので,実際にどんなメッセージがやり取りされているかわからなかった.そこで,今日はメッセージのやり取りについて具体的に見ていこうと思う.
lib9pは,やり取りされるメッセージを端末に出力するか制御するグローバル変数chatty9pを提供している.デフォルトは0だが,これを非0にすると,メッセージの内容が人間が読める形式で出力してくれるので,9Pプロトコルの勉強や,デバッグに便利である.
ramfsにならう形でmysrvに-Dオプションを追加しよう.Plan9では,コマンドラインオプションの解析用にARGBEGIN,ARGEND,ARGFといったマクロが用意されている.そこで,次のコードをmain関数の先頭に追加すればよい.
ARGBEGIN { case 'D': chatty9p++; break; } ARGEND;
-Dオプションを付けて,mysrvを実行してみよう.postfdはpostmountsrvから呼ばれ,/srv/mysrvをcreateし,srvfdをpostしていることを示している.
% mysrv -D postfd /srv/mysrv postfd successful
9Pプロトコルの処理は,mountから始まる.mountでは,version,auth,attachというメッセージがやり取りされている.メッセージの先頭のTはクライアントからファイルサーバ(mysrv)へ,Rはファイルサーバからクライアントへメッセージが送られていることを示している.矢印の間の数字はファイル記述子infd,outfdである.メッセージの向きに着目すると,常にクライアントからのリクエストに対して,ファイルサーバがリプライを返していることがわかる.これは,すべてのメッセージに共通する決まりごとである.
version,authで9Pコネクションが確立する.attachはクライアントが指定したfidとファイルサーバのファイルツリーのルートを対応付けることを意味する.fidはクライアントが保持するファイル識別子で,readやwriteはfidに対してリクエストする.
% mount /srv/mysrv /n/mysrv <-5- Tversion tag 65535 msize 8216 version '9P2000' -5-> Rversion tag 65535 msize 8216 version '9P2000' <-5- Tauth tag 5 afid 267 uname oraccha aname -5-> Rerror tag 5 ename mysrv: authentication not required <-5- Tattach tag 5 fid 267 afid -1 uname oraccha aname -5-> Rattach tag 5 qid (0000000000000000 0 d)
catしてみる.walkとclunkが耳慣れないと思うが,walkはパス名の検索,clunkはfidの解放(closeに近い)を意味する.mysrvはTreadメッセージを受け取ると,myread関数を実行し,Rreadメッセージで結果を返している.
% cat /n/mysrv/data <-5- Twalk tag 5 fid 267 newfid 268 nwname 1 0:data -5-> Rwalk tag 5 nwqid 1 0:(0000000000000001 0 ) <-5- Topen tag 5 fid 268 mode 0 fid mode is 0x0 -5-> Ropen tag 5 qid (0000000000000001 0 ) iounit 0 <-5- Tread tag 5 fid 268 offset 0 count 8192 -5-> Rread tag 5 count 18 'home=/usr/oraccha ' home=/usr/oraccha <-5- Tread tag 5 fid 268 offset 18 count 8192 -5-> Rread tag 5 count 0 '' <-5- Tclunk tag 5 fid 268 -5-> Rclunk tag 5
最後にunmount.
% unmount /n/mysrv <-5- Tclunk tag 5 fid 267 -5-> Rclunk tag 5 % rm /srv/mysrv
NFSを知っている人なら,あぁ,やっていることはNFSのRPCと同じだなとわかるだろう.もちろん違う点もある.NFSはステートレスなプロトコルであるが,9Pはステートフルである.クライアントは状態を持っている.この状態はFid構造体として保持され,その識別子が前述のfidである.