Ssh

SSHFS/SFTP : Vim 在嘗試通過 sshfs 編輯文件時掛起,並且無法通過 sftp 上傳超過 MTU 大小的文件

  • October 17, 2019

我的大學提供了對學生大學帳戶的 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 編輯遠端 fs 上的文件時,編輯器都會在打開文件之前掛起 60 秒(非常準確,我猜這與連接超時參數有關)。當文件最終打開時,我得到錯誤說明並從 vimE297: Write error in swap file關閉。E72: Close error on swap file

但有時(特別是在我重新載入 dameon 並在更新 /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 文件時,問題似乎正在發生,但我不知道為什麼,因為我在遠端 fs 上手動創建或刪除文件或文件夾沒有問題。

我不了解 sshfs 並融合到足以自行解決此問題。

我也可以為 gcc 和 mv 提供 strace 日誌。問我是否需要精確度。

提前感謝您的回答。

**編輯:**我directory在 vimrc 中設置了選項,以便 vim 在我的本地 .vim 文件夾中創建其交換文件,這解決了我遇到的交換文件錯誤。

但是我在執行其他操作時仍然遇到了一些 I/O 錯誤,所以我相信 vim 發生的事情只是我將嘗試調查的更複雜問題的症狀。

正如@roaima 所說,這個問題似乎是由連接意外關閉引起的,這種情況發生在 vim 試圖在遠端 fs 中創建交換文件時。

我最近注意到無論如何我都無法複製一些文件,我現在不能肯定,但我認為它可能是文件大於一定大小,我需要做一些測試。

**Edit2:**今天做了一些測試後,我注意到當我嘗試通過 ssh 上傳超過 MTU 大小(1500)的文件(我嘗試通過 sshfs、scp 和 sftp 會話上傳文件)時,使用 sshServerAliveInterval選項集, 60 秒後連接斷開。

好的,因此降低 MTU 大小似乎已經解決了我在 SSHFS 上的所有 I/O 問題。正如@roaima 所指出的,問題可能是由於大學伺服器的防火牆過於急切地阻止 ICMP 數據包引起的。

感謝@roaima 指導我解決該問題。感謝@derobert 建議降低 MTU。

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本地執行會比僅登錄到遠端伺服器並在那裡執行要慢得多。老實說,我對“嘗試在遠端 fs 上編譯文件時 gcc 崩潰”並不感到驚訝。當然,它不應該,但然後想想在後台實際發生了什麼……

引用自:https://unix.stackexchange.com/questions/546110