Linux Mintのファイルマネージャ(nemo)で快適にネットワーク上のファイルを閲覧する方法について考えました。
ネットワーク上というのはGoogle Driveやssh(sftp)などで、これらは適切なツールを使うとファイルシステムのように扱うことができるようになります。
そのツールの代表例がrcloneで、これはvfsという技術を使っていて大半のクラウドストレージやネットワークプロトコルを同じようなやり方でマウントしたり同期を取ったりということができます。
ただこのrcloneのマウント(rclone mountコマンド)には問題があって(といっても実際にはrclone自体が悪いわけではないのですが)、nemoで普通に閲覧するとフォルダを開くたびにロード中のような表示で何秒か待たされたりして非常に遅いです。ネットワーク上だからローカルのような性能が出ないのはもちろんですが、lsコマンドだとそんなに遅くないので何かがおかしいです。なので解決策を考えます。
nemoと書いていますがcajaとnautilusも同系統のソフトウェアなので多分同じ方法が使えます。全く無関係のファイルマネージャでも役立つ可能性はあります。
gvfs(gio)のWebdavを使う
結論からいうとgvfsのdavバックエンドを使って閲覧するとかなり改善します。
どうするかというと、まずrclone mountで直接マウントするかわりにrclone serve webdavコマンドを使って該当のクラウドストレージをWebDAVサーバーとして見えるようにします。たとえばここではlocalhost:8080にWebDAVサーバーを立てたとしましょう。
この状態でnemoのアドレスバーのところにdav://localhost:8080と打ってEnterを押すと、rclone mountしたときと同じような感じで中身が見れます。(こういうdav://みたいなアドレスを使えるのがgvfsの仕組みです)
で、ここからいろいろなフォルダに移動してみるとさっきよりめちゃくちゃフォルダの表示が速いです。これでひとまず解決です。
なんでmountだと遅いの?
同じクラウドストレージを見ているのにrclone mountとgvfs経由で明らかに速度に違いがあるのはなんででしょうか?
一つ明らかなのは、dav://はネットワーク上のリソースなのでnemoが各種の処理をサボっているということです。たとえばrclone mountしたものをnemo見る場合は画像ファイルのサムネイルが表示されますがgvfsの場合はされません。同様に、各サブフォルダに含まれるアイテム数もrclone mountのときしか表示されません。あと、プレーンテキストの中身を読まなきゃわからない情報(シェルスクリプトかどうか、とか)もrclone mountのときしか出ません。
ただし、実際にはサムネイル自体は一覧表示のレスポンスとは関係ありません。ファイルの一覧表示はサムネイルの読み込みを待たずに(並行して)行われるからです。実際、nemoには特定フォルダ以下でサムネイルを無効にするオプションがありますが、この場合でも一覧表示は遅いです。同様に、gvfsのバックエンドでlocaltestというのがあって、localtest:///みたいなアドレスをnemoに打つと普通に/以下が見られるというテスト用の機能で、これもサムネイルは表示されないのですが、これでrclone mountの内容を見るとやっぱり遅いです。
まあとにかく、dav://以下で見るのだけがうまくいくということです。今後nemo側に「指定したフォルダではdav://と同等に各種の処理をサボる」みたいな機能が実装される可能性はあるかもしれませんが。
ちなみに、dav://というのは内部的には/run以下の特殊なフォルダを閲覧していることになっているのでローカル側からシンボリックリンクも張れるのですが、このシンボリックリンクを経由して閲覧するとやっぱり遅いです。
rcloneのキャッシュ
一覧表示とはあんまり関係ないですが、頻繁にアクセスするファイルがある場合は--vfs-cache-mode fullとかを指定すると読み込みで開いたときもキャッシュするようになるので速いです。~/.cache/rcloneがキャッシュフォルダなので、これをtmpfsとかにするとさらに速いです。
このキャッシュを効率よく使うためにもやはりdav://を使って無駄な読み込みを避けたほうがいいですね。
WebDAVに認証をつけたい
これは筆者が必要以上に気にしすぎ説もあるんですが、localhost:8080とかに普通にWebDAVサーバーを立てると当然他のユーザーから見えるようになります。別に他の人に自分のPCを使わせる予定はないんですがなんとなく気になります。
気になる人は、WebDAVにはBasic認証もあるのでそれを使うのもいいと思うんですが、筆者がやっているのは、rclone serve webdavに--baseurl /passwordというオプションをつけてpasswordというフォルダ以下にファイルを配置することです。これだとpasswordの文字列がわからない限りはポートにアクセスしても何も返ってこないので一応安全ということになります。もちろんファイルパスは一般的には暗号化が必要なものとは思われていないのでお気軽に危険な場所(ディスクとか?)に記録されてしまうかもしれないという問題もあります(getリクエストでパスワードを送るのと似てる)。でもそのかわり認証がないから暗号化の処理がなくて軽いはず。
ファイルが更新されるまでにラグがあるんだけど?
これも余談です。
rcloneのデフォルトだと--dir-cache-timeが5分に設定されているので別のところで新規ファイルを作ったりするとそれが最大5分間こっちに反映されません。なので--dir-cache-time 10sとかにしておくとキャッシュ効率を犠牲にして応答速度を改善できます。あまりにも短くすると一覧表示の処理中に二回アクセスが走ったりしそうなので最低5sくらいはあると良さそう。
複数のクラウドストレージを使いたい
rcloneするものが一個でよければ楽ですが複数アカウントのGoogle Driveとあとはsshサーバーもいくつか…とたくさんある場合もあります。この場合解決策は2通りあります。
まずはrcloneのcombineを使う方法で、基本的にはこれがまともな方法です。combineというのはrcloneに登録した複数のストレージをまとめられるやつで、例えば「driveっていうフォルダ以下にGoogle Driveの内容、sshっていうフォルダ以下にsshサーバーの内容が入ってる」ようなやつを作れます。
もう一つはrclone mountと組み合わせる方法です。一番外側がdav://経由でさえあれば内側がrclone mountでも問題ないので、たとえば~/.mnt/networkみたいなフォルダを作っといてそこをdav://経由で見られるようにして(ローカルのファイルシステムをwebdavにするのはrcloneでもできるしwsgidavとかでもよい)、あとは各クラウドストレージを~/.mnt/network/driveみたいなフォルダにマウントしていけばいいということです。ただ、combineに比べると--dir-cache-timeとかをいちいち指定するのがダルいかも。
マウントするストレージが固定で変更頻度が少ないならcombineがおすすめです。
(余談)ssh上のフォルダから直接ssh上のVS Codeを開きたい
完全にoff topicですがせっかく自分の記事があるので宣伝しておきます。
gvfsで直接Google Driveとかを閲覧する
rcloneほど対応クラウドストレージは多くないのですがgvfs自体にもGoogle Driveやssh(sftp)などの一部クラウドストレージを扱う機能があります。ただGoogle Driveだとショートカットがうまく表示されなかったりパス名が長ったらしいIDになっていたりしてあんまりきれいではないので普通にrcloneでもいいと思います。
他にはGoogle Drive限定ですがgoogle-drive-ocamlfuseというものすごく説明的な名前のツールとかもありますね。
まとめ
マジで体感かなり速いのでrclone mountを使っててやっぱりクラウドは遅すぎる!ってなってた人は一度試してみてください。