SSHFS/SFTP :尝试通过 sshfs 编辑文件时 Vim 挂起,并且无法通过 sftp 上传超过 MTU 大小的文件

SSHFS/SFTP :尝试通过 sshfs 编辑文件时 Vim 挂起,并且无法通过 sftp 上传超过 MTU 大小的文件

我的大学提供对学生大学帐户的 ssh 访问,我只是设置了一个 sshfs 来访问我的远程帐户上的一些文件夹。

我在本地计算机上运行 pop_os 并使用带有以下选项的 systemd 自动挂载: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 编辑远程文件系统上的文件时,编辑器都会在打开文件之前挂起 60 秒(非常准确,我猜这与连接超时参数有关)。当文件最终打开时,我收到错误提示,并从 vimE297: Write error in swap file关闭。E72: Close error on swap file

但有时(特别是在更新 /etc/fstab 中的选项后重新加载守护进程并重新启动自动挂载服务后,文件会立即打开,没有错误。

我尝试过的

我在 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 文件时似乎会发生此问题,但我无法弄清楚为什么,因为我在手动创建或删除远程文件系统上的文件或文件夹时没有遇到任何问题。

我不太了解 sshfs 和 fusion,无法自行解决此问题。

我也可以提供 gcc 和 mv 的 strace 日志。问我是否需要精确度。

预先感谢您的回答。

编辑 :directory在 vimrc 中设置了该选项,以便 vim 在我的本地 .vim 文件夹中创建其交换文件,这解决了我遇到的交换文件错误。

但我在执行其他操作时仍然遇到一些 I/O 错误,因此我相信 vim 发生的情况只是我将尝试调查的更复杂问题的症状。

正如 @roaima 所说,该问题似乎是由连接意外关闭引起的,这种情况发生在 vim 尝试在远程文件系统中创建交换文件时。

我最近注意到我无论如何都无法复制某些文件,我现在不能确定,但​​我认为可能是文件大于特定大小,我需要做一些测试。

编辑2:今天做了一些测试后,我注意到当我尝试通过 ssh 上传超过 MTU 大小 (1500) 的文件时(我尝试通过 sshfs、scp 和在 sftp 会话中上传文件),在ServerAliveInterval设置 ssh 选项时,连接60秒后下降。

答案1

FUSE 文件系统是通过在文件传输协议sshfs之上提供一个文件系统来实现的。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在本地运行会比登录到远程服务器并在那里运行要慢得多。说实话,我并不太惊讶“尝试编译远程文件系统上的文件时 gcc 崩溃“。当然不应该,但是想想背景中实际发生的事情......

答案2

好吧,降低 MTU 大小似乎解决了我通过 SSHFS 遇到的所有 I/O 问题。正如 @roaima 所指出的,问题可能是由于大学服务器的防火墙过于急切地阻止 ICMP 数据包引起的。

感谢@roaima 指导我解决该问题。感谢 @derobert 建议降低 MTU。

相关内容