私の大学では、学生の大学アカウントへのsshアクセスを提供しており、リモートアカウントのいくつかのフォルダにアクセスするようにsshfsを設定するだけです。
ローカルマシンでpop_osを実行していて、systemd automountを次のオプションで使用しています:noauto,x-systemd.automount,_netdev,user,idmap=user,follow_symlinks,workaround=rename,IdentityFile=/home/me/.ssh/identityfile,allow_other,default_permissions,uid=1000,gid=1000,ServerAliveInterval=15
自動マウントは正常に機能し、リモートフォルダーを参照できますが、ファイルを置き換えたり、フォルダーをリモートに再帰的にコピーしたりする際に問題があります。
しかし、vimを使用してリモートfs上のファイルを編集しようとするたびに、エディターはファイルを開く前に60秒間ハングします(正確には、接続タイムアウトパラメーターと関係があると思います)。ファイルが最終的に開くと、E297: Write error in swap file
および終了時E72: Close error on swap file
vimから。
しかし、時々(特に私がdameonをリロードして/ etc/fstabのオプションを更新した後にautomountサービスを再起動した後、ファイルはエラーなしで即座に開きます。
Sshfsでファイルを開くときにstraceを実行しました。問題が発生していると思われるログのサンプルを以下に示します。
0.000032 openat(AT_FDCWD, ".../myremotefile.c", O_RDONLY) = 3
0.041890 readlink(".../myremotefile.c", 0x7ffd99b19540, 4095) = -1 EINVAL (Invalid argument)
0.000302 openat(AT_FDCWD, ".../.myremotefile.c.swp", O_RDONLY) = -1 ENOENT (No such file or directory)
0.029883 openat(AT_FDCWD, ".../.myremotefile.c.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
0.103207 openat(AT_FDCWD, ".../.myremotefile.c.swx", O_RDONLY) = -1 ENOENT (No such file or directory)
0.074409 openat(AT_FDCWD, ".../.myremotefile.c.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 5
0.116541 fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
0.000419 fstat(5, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
0.000318 close(5) = 0
0.000268 unlink(".../.myremotefile.c.swx") = 0
0.075053 close(4) = 0
0.000448 unlink(".../.myremotefile.c.swp") = 0
0.061916 stat(".../.myremotefile.c.swp", 0x7ffd99b1a4d0) = -1 ENOENT (No such file or directory)
0.077126 lstat(".../.myremotefile.c.swp", 0x7ffd99b1a660) = -1 ENOENT (No such file or directory)
0.041249 openat(AT_FDCWD, ".", O_RDONLY) = 4
0.000218 fchdir(4) = 0
0.000197 chdir(".../myremotefolder") = 0
0.000086 getcwd("/home/myhomefolder/.../myremotefolder", 4096) = 34
0.000029 fchdir(4) = 0
0.000025 close(4) = 0
0.000027 lstat(".../.myremotefile.c.swp", 0x7ffd99b1a9e0) = -1 ENOENT (No such file or directory)
0.043704 openat(AT_FDCWD, ".../.myremotefile.c.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 4
0.127965 fcntl(4, F_GETFD) = 0
0.000331 fcntl(4, F_SETFD, FD_CLOEXEC) = 0
0.000347 openat(AT_FDCWD, ".", O_RDONLY) = 5
0.000221 fchdir(5) = 0
0.000145 chdir(".../myremotefolder") = 0
0.046751 getcwd("/home/myhomefolder/.../myremotefolder", 4096) = 34
0.000375 fchdir(5) = 0
0.000351 close(5) = 0
0.000262 lseek(4, 0, SEEK_SET) = 0
0.000082 write(4, "b0VIM 8.1\0\0\0\0\20\0\0\217\266\235]>\0\0\0\335\16\0\0balo"..., 4096) = 4096
0.000645 select(1, [0], [], [0], {tv_sec=0, tv_usec=0}) = 0 (Timeout)
0.000176 chmod("..../.myremotefile.c.swp", 0644) = -1 EIO (Input/output error)
60.064610 close(3) = -1 ENOTCONN (Transport endpoint is not connected)
プロセスを閉じると60秒間ハングすることがわかります。
Vimが.swpファイルを作成しようとしたときに問題が発生しているようですが、リモートfsでファイルまたはフォルダーを手動で作成または削除するのに問題がないため、理由がわかりません。
私は自分でこれを修正するのに十分なsshfsとFuseを理解していません。
Gccとmvのstraceログも提供できます。精度が必要かどうか私に尋ねてください。
回答ありがとうございます。
編集: vimrcでdirectory
オプションを設定して、vimがスワップファイルをローカルの.vimフォルダーに作成するようにしました。
しかし、他の操作を実行しているときにまだいくつかのI/Oエラーが発生したため、vimで起こっていたのは、調査しようとするより複雑な問題の症状にすぎないと思います。
@roaimaが述べたように、この問題はvimがリモートfsにスワップファイルを作成しようとしたときに発生した、予期せず接続が閉じたことが原因であると思われます。
最近、何にせよ一部のファイルをコピーできないことに気づきました。確かに言うことはできませんが、特定のサイズより大きいファイルである可能性があると思うので、いくつかのテストを行う必要があります。
Edit2:今日いくつかのテストを行った後、sshを介してMTUサイズ(1500)を超えるファイルをアップロードしようとすると(sshfs、scp、およびsftpセッションでファイルをアップロードしようとしました)、 ssh ServerAliveInterval
オプションを設定してこれを行うと、60秒後に接続がドロップします。
さて、MTUサイズを下げることで、SSHFSを介したすべてのI/O問題が解決したようです。 @roaimaによって指摘されたように、問題はおそらく大学サーバーのファイアウォールがICMPパケットを非常に熱心にブロックしていることが原因でした。
その問題の解決に向けて私を導いてくれた@roaimaに感謝します。 MTUを下げることを提案してくれた@derobertに感謝します。
sshfs
Fuseファイルシステムは、ファイルシステムをファイル転送プロトコルsftp
の上に提示することによって実装されます。その結果、vi[m]
を使用した編集などのファイルアクセスでは、まずファイルをローカルファイルシステムのキャッシュにコピーするためにsshfs
サブシステムが必要です。ファイルが特に大きい場合、またはクライアントとサーバー間のネットワークが特に遅い場合、ローカルでアクセスできるようになるまでに、ファイルの転送にかなりの時間がかかります。
次のものと(非常に)ほぼ同じです(ただし、sftp
ではなくscp
を使用します)。
# Copy the remote file to a temporary local cache
scp -p remote:/path/to/file /tmp/file.tmp
checksum=$(cksum /tmp/file.tmp)
# Action on remote file is implemented by performing the action locally
vi /tmp/file.tmp
# Simplified; we would also need to handle local rm/mv -> remote rm/mv, etc.
[[ "$(cksum /tmp/file.tmp)" != "$checksum" ]] && scp -p /tmp/file.tmp remote:/path/to/file
その結果、gcc
をローカルで実行しようとすると、リモートサーバーにログインしてそこで実行するよりも、かなり遅いことがわかります。正直言って、「リモートfsでファイルをコンパイルしようとするとgccがクラッシュする」と言っても、それほど驚くことはありません。もちろん、そうすべきではありませんが、実際にバックグラウンドで何が起こっているのかを考えてください...