Sshfs

sshfs -oworkaround=rename 有什麼作用?

  • April 5, 2014

對於我正在學習的作業系統課程,我需要執行 Freebsd5.4。由於我不想嘗試在 git 發布之前發布的 bsd 版本上建構 git,所以我認為git從 Arch over使用它會很整潔sshfs

無論如何,我找到了一種解決方法,建議我提供sshfs選項-o workaround=rename

看起來git很開心,但我對剛剛發生的事情感到很困惑……

手冊頁中有關解決方法的所有內容都是

fix renaming to existing file

但我完全不知道這意味著什麼……

該選項到底有什麼作用?

sshfs 使用 SSH 文件傳輸協議 (SFTP)。當“新”名稱已經存在時,您啟用的解決方法是圍繞該協議上的 rename() 操作的語義。

在這種情況下 rename() 的 POSIX 行為是刪除現有文件並完成重命名。

在 SFTP 協議中,可以通過 SSH_FXP_RENAME 操作重命名文件;但是,當目標名稱已經存在時,它的行為似乎取決於您使用的協議版本以及您傳遞的標誌。SFTP 協議的wikipedia 頁面有各種版本的協議的各種草案 RFC 的連結。在Draft 00中,行為被列為:

如果已經存在名稱由 newpath 指定的文件,則會出錯。

草案 13中,該行為被列為

如果 flags 不包括 SSH_FXP_RENAME_OVERWRITE,並且已經存在具有 newpath 指定名稱的文件,則伺服器必須以 SSH_FX_FILE_ALREADY_EXISTS 響應。

如果 flags 包含 SSH_FXP_RENAME_ATOMIC,並且目標文件已經存在,則會以原子方式替換它。即,不存在名稱既不指舊文件也不指新文件的可觀察時刻。SSH_FXP_RENAME_ATOMIC 意味著 SSH_FXP_RENAME_OVERWRITE。

當目標名稱存在時,為了處理可能的 rename() 操作失敗,sshfs 提供了以下解決方法(如果啟用)

  if (err == -EPERM && sshfs.rename_workaround) {
           size_t tolen = strlen(to);
           if (tolen + RENAME_TEMP_CHARS < PATH_MAX) {
                   int tmperr;
                   char totmp[PATH_MAX];
                   strcpy(totmp, to);
                   random_string(totmp + tolen, RENAME_TEMP_CHARS);
                   tmperr = sshfs_do_rename(to, totmp);
                   if (!tmperr) {
                           err = sshfs_do_rename(from, to);
                           if (!err)
                                   err = sshfs_unlink(totmp);
                           else
                                   sshfs_do_rename(totmp, to);
                   }
           }
   }

在這段程式碼中,“from”是我們要重命名的文件的現有名稱,“to”是我們想要的新名稱。把一些路徑長度和錯誤簿記放在一邊,這個解決方法

  • 將“to”重命名為“totmp”
  • 將“從”重命名為“到”
  • 取消連結(刪除)“totmp”

這避免了“文件已存在”的衝突,但也改變了 rename() 操作的語義,這就是為什麼你不想預設這樣做的原因。

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