はじめての自作NFSサーバ

社長:「はじめての自作◎◎」って悪くないタイトルですよね。

開発:まあ、一般にあまり自作する事のないものだと違和感はあります。

経理:ベストセラーにはなりにくそうですね。

基盤:はじめての自作宇宙船とか。スペースXって結局、国鉄の民営化みたいのとは違うんですかね?

* * *

開発:ああそれで、NFSサーバが固まっちゃう問題は再現しました。

社長:なるほど、自分自身につなごうとしてタイムアウトを繰り返していると。

開発:unfsdを単一プロセスにしていたのでわかりやすかったです。要は、自身がマウントしているディレクトリの下に、自身のマウントポイントが見えているので、再帰しちゃってるんですね。

社長:多段のループだと検出は難しいですが、自分自身なら検出しても良いのにね。

開発:それはそうと、こうなった場合のmountテーブルのクリア方法がわかりません。umount は効かない。diskutil umount force も効かない。

社長:ひょっとして、unfsdを殺しちゃってるからじゃないですか?誰も応答しないから、後片付けができないとか。

開発:あ… そうかもです。unfsd を起動して、umount ... ああ、昨日見たこれがぽっと出ました。

開発:でもって Disconnect All。おー、mountがクリアされました。

社長:メデタシ。

開発:「昨日見たFUSEみたいの」なんて、失礼な事を書いちゃいました。とんだ濡れ衣でしたね。

社長:要は、私は eject しちゃいましたもうここにはいません、みたいなメッセージをクライアントに返してから死ねばよいのでしょうかね。

開発:まあ、原因もわかりましたし、方向性は見えましたのでおいおい。

開発:それで、ファイルをクリックで開く時に、それをどう扱うかは結局、拡張子で判断するのが趨勢なわけです。まあ、可変長文字列なのでまさに拡張性もありますしね。なので、

社長:ちょっと待った。ボウリングの試合に行ってきます。

* * *

社長:ただいま。

基盤:どうでした?

社長:130台で始まり、徐々に修正して、200台で終わりました。最初はフォームもタイミングも変でわけがわからなかったんですが、リリース時に右肩が突っ込んだりぶれてた事に気づいたんです。回転軸がぶれては、全てが台無しです。

社長:ああそれで、機能を持つファイルの名前ですが、最後は拡張子で終わる。ファイル名の先頭は本来の名前であるべき。だとすると、name++function.ext といった形になるのかなと思いました。

開発:「++function」の記法は悩ましいですね。?function でも良さそうには思いますが。

社長:「?」は伝統的にshellでファイル名の一文字マッチングに解釈されちゃうのが嫌なんですよね。まあ、おいおい考えましょう。

開発:ではとりあえず「++」がファイル名に入ってたら実行することにしてみます。

開発:またループすると嫌なので、$HOME/unifsv を $HOME/unifcl にマウントすることにします。まずこういうふうにexportsして、unfsdを起動。

開発:でこれをマウントする。

開発:ここにある4つのファイルは全部同じファイルです。ハードリンクしたものです。で、中身を読み出すと、NFSのクライアント側から見た ++ 付きのファイルだけが、実行された結果として見える。

開発:でこれをFinderで開いたりブラウザで開くとこうなります。

社長:ふーむ。機能的には出来てます。Finderやエクスプローラにファイルの名前以外でデータ型を、MIME Content-Type で伝えられると良いのですけどね。

開発:うーん。少なくとも最初のNFSが出来た時にはまだ MIME も無かったですしねw。

基盤:その後のNFSではどうなんでしょうね。

開発:grep -i mime *.h .c ... unfs3には無いみたいですね。NFSv4にはあるんですかね… あった。

開発:まあ、これをNFSクライアントが、つまりファインダーやエクスプローラが見てくれるかどうかですが…

社長:見てくれるなら、CGI使ってヘッダにContent-Typeを返す必要なくなりますね。

開発:ものによっては、HTTPサーバである必要もなくなりますね。単にNFSマウントしてfile URLで開けば良い。

開発:ですが、せっかくHTTPでURLにいろんな機能をもたせて普及したわけですから、それをそのままファイル名にも使いたいのも確かです。

社長:HTTP的に考えれば、クライアント側に見えない隠しファイル的に、いろんな属性を付加できればいいんじゃ無いかととは思います。

開発:そうですが… クライアント側から一律な変換機能を叩けるところが、NFSでやる面白さなんじゃないかとも思うわけです。

開発:どうもその、一度ディレクトリをキャッシュしてしまうと、その中に無いパスを追ってくれない的なクライアントの作りになっているように思われるんです。そうなると、無限の組み合わせのある隠し機能というかパラメータを指定することが出来ない。

社長:でも、巨大なディレクトリの中の一つのファイルを開くこともあるわけで。クライアントとしてそういう理不尽な実装をしますかね?

開発:ああでも、これも、ディレクトリの最終変更日付を変える手でしのげますかね。あるいは、このディレクトリ、このファイルはキャッシュするなという指示がNFS的にできるのかもです。明日また確認します。

-- 2020-0803 SatoxITS

世の中の全てをファイルとして見る

開発:明日、いやもう今日ですが、大谷くんが先発だそうです。5時10分試合開始予定。

社長:おおそうですか。ではテレビを見る練習をしておかないと… リモコンはどこに行きましたかね。NHKですよね?

開発:BS1です。なんたって女子ゴルフと違ってメジャーですからねw

社長:NEWSWEBもとんと見てなかったです。ええ!照ノ富士復活優勝!?

開発:稀勢の里とのボロボロ対決を思い出しますね。

基盤:相撲やってるのも気づかなかったです。

経理:ところでNHKの衛星契約は受信料が月2000円のようです。ケーブルテレビのほうでまとめて徴収されてると思いますが。

社長:おおっと、4LSU 相当ですかぁ。そう考えるとかなりの額ですね。以前はずっとNHKつけっぱなしでしたから、元が取れてたとは思いますが…

基盤:リモコン発見。電源ぽちっと。そもそもBS1になってますね。準備OK。

* * *

開発:それで、自前のNFSサーバを作りたいと言っていた件ですが、ようやく見つけました。これです。

https://unix.stackexchange.com/questions/45899/why-is-linux-nfs-server-implemented-in-the-kernel-as-opposed-to-userspace

社長:それだ。なんでなんですかね。

開発:nfsサーバをカーネルに取り込んだのは性能向上のためだったが、多くの問題を生んだ。今は反省している、みたいな流れですね。

社長:うちはギンギンにアクセスするために使うんではないので関係ないですね。NFSクライントから別サーバに中継するだけですし、基本、ユーザローカルに動かす個人用のNFSサーバだし。

開発:それでこの記事の中で言及されてるのがまずFUSE。めちゃ遅いという認識は同じですね。一方、ユーザ空間で動くnfsdとしては、unfs3とGaneshaというのが紹介されています。

開発:で両方ともダウンロードして眺めたのですが、これはもうひと目見てunfs3で決まりです。めっちゃ簡単。名前のとおりNFSv3ですが、まあクライアントがそれで許してくれるなら問題ないでしょう。

開発:ビルドはこれだけ。あっというまです。

開発:で、man ./unfsd.8 すると、ポート番号の指定は -m だそう。/etc/exports を変える時には -e。つまり、サーバの起動はこれで良いのではと。

開発:一方でmountはこんな感じ。じゃん!

基盤:通りましたね。

開発:でもって ls とかしてみる。

基盤:見えました。

開発:で書き込みの性能を見る。

基盤:2倍位遅いですかね。約280MB/s、2.28Gbpsです。

社長:うちの使い方には全く問題なさそうです。

開発:ランダムアクセスした時にどうかという話はありますが、主な用途が付加価値的なデータ処理や別プロトコルのサーバへの中継だと考えれば、そちらで律速されますから、問題ないかなと思います。

基盤:アンチウィルスフィルタとか噛ませたら、ファイルI/Oが10MB/sくらいに落ちることもありますからね。あれは本当に不愉快というか使い物にならない。

開発:あとは安定性ですかね。というか、nfs が反応しなくなると、I/O中のプロセスが固まって溜まりまくるという伝統芸的な問題を何とかしたい。

社長:特にdfで様子を見ようとすると固まるあれですね。mount コマンドとかで状態を検査する機能があるとよいかと思いますが。

* * *

基盤:大谷くん、またダメでしたね。

社長:でも今回は1回はもちました。

開発:実戦のブランクも長かったですしね。ピッチャーっていうのはそういうデリケートなポジションなんでしょう。

社長:それはそうと久しぶりにBS1を垂れ流しで見たんですが、悪くないですね。

基盤:ですがあれを常時専用のテレビモニタに映しておくのは電気の無駄ですね。カメラ入力としてキャプチャしてデスクトップに小さく表示しておくのがよいのではないかと。

開発:HDMIをディスクに記録しながら中継したりUSBに出すような製品がありますよね。確か1万円くらい。おそらく、大して電気も食わない。

基盤:ひょっとしてQNAPの上位機種にあるカメラ機能がそのまま使えるとか。

開発:上位版というと、うちのQちゃんより下位機種があるような響きですねw

経理:エアコン無しで、トイレと台所の照明は低消費電力LED化。次はテレビモニタのバックライトかと思います。あ、あとあのオーディオアンプ。

基盤:ケーブルテレビを継続するなら、10年くらい前に廃止キャンペーンしてたこのセットトップボックスも交換したほうが良いかと思います。これもめっちゃ熱くなってるんで。

基盤:ああそれで、iMac用の増設メモリですが、正規版?がクソ高いので、アマゾンで安いのを見つけて発注しました。価格的にはMac用メモリ専門店の1/4くらい。16GBで6,000円強。こないだレノボに入れた8GBのとほぼ同等というか割安です。こなれてはいませんが、日本語も比較的まともだし、質疑にも答えています。

社長:4倍という価格差。ハイリスク、ハイリターンな感じですねw

基盤:といいますか、iMacをカスタマイズする時のオプションによると、うちのiMacで16GBから16GB増やすと+40,000円です。

開発:誰が買うんでしょうね?

基盤:お金持ちの奥さんとか。

社長:運悪く不良品に当たるかどうかですね。

開発:まあ、届いたら徹底的に初期テストをしましょう。

* * *

基盤:といいますか、さっきからディスクがフリーズ気味なんですが。unfs3のせいでは。

開発:そういえば、なんか固まったんでサーバ自体はkillしたんですが、umount とか diskutil umount が効かなくなって…

社長:それは確か soft というマウントオプションを付けると良かったと思います。ファイルシステムとしてはちょっと嫌ですが、普通のアプリケーションプロトコルならタイムアウトで切れるとか普通だし、それに対応するようにプロトコルも実装も作られてますからね。

基盤:まあネットワークを意識したアプリじゃないと、ファイルI/Oが失敗した時の例外処理とか脱出なんて普通コーディングしないですからね。

社長:まー、カレントディレクトリがNFS上だったりするともう、どうにも回復もならなくなるわけです。zshあたりでそのへんなんとかしたいですね。

開発:うーん、だれかが掴んでてbusyのようで… Finderかな?プロセスをkill… あれー、すぐにまた生えてきちゃいますね。今朝も何度か強制unmountしてなんとかなったんですが。あの時はFUSEみたいなアイコンのがポップアップして答えたわけで… その後FUSEをコントロールパネルから抹消した程度なのですが… 呪い?

社長:もう小一時間がんばりました。再現性はあるでしょうから後で精査。リブートしましょう。

基盤:この、シャットダウンに抵抗するやつら、邪魔ですね。どうせ自動回復する機能があるんだから、おとなしく死ねば良いのに。OfficeとかFirefoxとか。ぷち。ぷち。ぷち。さあきれいにまりましたが… なんかくるくるしたままですね。

開発:電源リセットしましょう。

基盤:これやると、フィリップス君にレノボちゃんのDisplay Portのデスクトップがが顔を出すんですよねw で、再びHDMIを選んで MacMiniに戻す。

開発:きれいに立ち上がりました。というか、クラウド系のドライブのマウントがきれいさっぱりになりましたねw

社長:まあ、万が一MacMiniが立ち上がらなくなっても、もうiMacに環境があるし。最後の砦にレノボWin10も控えているわけです。BCPは完璧ですね。

経理:ベランダの打ち水は数分で蒸発してしまいます。

基盤:水道の蛇口がベランダにあると良いのですが… 設計ミスじゃないですかね。台所から引きましょうか。

社長:ていうか、うちのベランダってこんなに広かったんですね。野菜畑でもしましょうか。

* * *

開発:リブートしてからすごく快調で、diskutil なしの umount も普通に通るようになってしまいました。最初 / を export してマウントしたのが問題なのか、今はまだクラウドのドライブがほとんどマウントされてない関係なのか、よくわかりません。というか、unfsd 自体が出していると思っていた :/: の response が無いというようなエラーメッセージ、あーキャプチャし忘れました、MacOSのライブラリが出していたのかもしれません。strings unfsd しても出てこないんです。

開発:それはそうと、unfsd のバイナリはこんな感じ。

基盤:超コンパクト。

開発:ソースはこんな感じです。

開発:daemon.c はNFSプロトコルの出入り口で、実際の処理をやっているのがnfs.cです。

社長:つまり、うちが手をつっこむのは nfs.cだということですね。

開発:リードオンリーのファイルシステムなら、数個の関数しか関係しません。

開発:ちょっと getattr と lookup にprintfを突っ込んでみます。

基盤:簡単過ぎる…

社長:たとえばファイルのメタ情報を仮想的なファイルとして読み書きできると良いですね。何かの拡張子的なものを付けて… たとえばファイル名が name なら ._.name.attr とか。

開発:あれ?open に対応するものは無いですね。とりあえず read…

開発:1パケットに入らないのをread…

開発:ふむふむ。ソースコードはこう。

開発:なるほど、毎回openしてるんですね。ファイルディスクリプタがキャッシュに残っていたら再利用すると。

社長:要するにステートレスなんですね。このあたり、マルチプロセスでnfsdをするときにどう共有するのか。たぶん共有できないから、カーネルに入れたかったと。

開発:プロセス間でファイルディスクリプタを渡すシステムコールはありますよね。あれはWin32でしたっけ?

社長:なるほどー。かなり景色が開けてきました。メシに行きますか。

* * *

社長:外はまさに真夏でしたが、室内はまあ過ごせますね。

基盤:温度計は31.2度になってますけどね。

開発:まあ15年くらい前の時計のおまけのMEMSですけどね。

社長:でも、それで長年、室温を認識してきましたから、絶対値精度は別として比較の基準です。

社長:それで改善案を2つ。1つは、南向きベランダに噴水付き庭園を作る。2つ目は、北向きのベランダからサーキュレータで冷気を取り込む。

基盤:ではこの温度計を北の倉庫室に持ってって測ります。あ、ショックでUPSの電源が抜けました。

UPS:ぴぃー。… … … … … ぴぃー。… … … … …

開発:昔使ってたオムロンのはうつになるほど警告がうるさかったですけどね。

社長:でもMacMiniは平気で動いています。

基盤:では、電源を回復。ぶつ。

開発:けっこうバッテリを食いましたね。

基盤:可愛そうにQちゃんは、バックアップ無しの口に繋がれてました… 立ち上がりに数分かかるんですよね。

開発:なぜそのような迫害を。

基盤:最後に来た時に口が空いてなかったんですね。

QNAP:ぷうーーーーっ!

基盤:でも、元気に立ち上がりました。

社長:で、北の部屋の温度は?

基盤:30.0度でした。南より1度以上低いですね。

社長:風向きは?

経理:金鳥の煙は南から北へ向かって強く。

開発:うーん、とすると、北の部屋から南へ向けて強力なサーキュレータで送風する必要がありますね。

経理:単に北の部屋で仕事するという方法もあるかと思いますが。

社長:自然の風に任せるとすると、南のベランダに噴水付き庭園案は現実身が高まります。昔ガーデニングで使ってた道具は全部廃棄しちゃったから、また揃え直さなくっちゃ♪

開発:近場でガーデニング系を置いてたホームセンターは全部消えちゃいましたからね。品揃えがちゃんとしている店までだと車で20分かかるのが大変です。

基盤:あまくぼにちっちゃい花屋さんみたいのを見かけましたけど。

* * *

社長:さて、では読むと実行して結果を返すようなファイルを作りましょう。

開発:とりあえず popen するって感じですかね。何か拡張子なり属性なり…

社長:属性の拡張は難しいでしょうね。とりあえず、ファイル名に'?'が付いてたら、'?'より前を実行ファイル名にして、’?’から後を引数にするみたいな。

開発:CGIですね。じゃパス名をstrchrして… あれー、read_svc() に渡ってこないですね…。なんかNFSクライアント側でディレクトリのキャッシュしているとか、そんか感じのようにも?

社長:ではとりあえず、拡張子的な目印では。

開発:たとえば .shx ならsystem()で実行して結果を返すと。うーむ、popen()は厳しいですね。何か named pipe 的なものでないとだめかも。とりあえず実行結果をファイルに書いちゃってそれを読む。うーむ、read-only filesystem?では/tmpに書いてやりましょう。Go!

基盤:おお出来ましたね。

開発:いやしかし、2回目からは前と同じ結果が返ってきてしまいますよ。どこかでキャッシュしてますね。ああ、ファイルのタイムスタンプ属性を見てるようですね。じゃあこれを、いつも現在時刻にしてしまう。これでどうかな?

基盤:やった!

社長:うーん、one giant leap ですね。

開発:明るい未来が見えた気がした。unfs3に感謝感激。

* * *

社長:思えば、私が初めてNFSに触ったのは、たぶん 1987年頃の Sun ででした。あの頃、NFSでこういう感じの遊びができたら面白いのにと思ったものですが、当時は商用のSunOSでしたし、たぶん無理でしたね。それが今や、こんなふうにちょこちょこっと出来てしまう。まさに夢のような世界ですね。

基盤:LinuxのNFSは 1993年、unfs3は 2003年に出来てたみたいですけどね。

開発:なにしろ90年代は、Unixワークステーションの全盛期でしたからねえ。1台何百万円はする。Linux?なにそれそのおもちゃ、みたいな感じでしたよ。下手に予算にも恵まれていた。

社長:やはり経済的にもミニマルなところから新しいものは生まれるんですね。ああそうだ、車検が上がったそうなので、取りに行ってきます。

経理:この額、この会社ではとても負担できないですね。

社長:まあ、車は半分趣味だから、尺度が違います。いわゆる社長のポケットマネーです。あっはっは・・はは・・

基盤:いずれ社長機密費とかできると良いですね。

-- 2020-0803 SatoxITS