apa yang dilakukan `sshfs -oworkaround = rename`?

17

Untuk kelas sistem operasi yang saya ikuti, saya harus menjalankan Freebsd5.4. Karena saya tidak ingin bergulat dengan mencoba membangun git pada versi bsd yang dirilis sebelum git dirilis, saya pikir akan lebih rapi untuk digunakan gitdari Arch over sshfs.

Bagaimanapun saya menemukan solusi yang menyarankan saya memberikan sshfspilihan -o workaround=rename.

Tampaknya membuat gitsenang, tapi aku agak bingung dengan apa yang baru saja terjadi ...

Semua halaman manual mengatakan tentang solusinya adalah

fix renaming to existing file

tapi saya benar-benar bingung apa artinya ...

Apa sebenarnya yang dilakukan opsi itu?

math4tots
sumber
3
Pointer untuk seseorang yang ingin melihat dengan tepat apa artinya (dan menulis jawaban, dan semoga tambalan dokumentasi): sourceforge.net/p/fuse/sshfs/ci/master/tree/sshfs.c mulai dari baris 2300.
derobert

Jawaban:

10

sshfs menggunakan SSH File Transfer Protocol (SFTP). Solusi yang telah Anda aktifkan adalah bekerja di sekitar semantik operasi rename () atas protokol itu ketika nama "baru" sudah ada.

Perilaku POSIX untuk mengganti nama () dalam hal ini adalah menghapus file yang ada dan menyelesaikan mengganti nama.

Dalam protokol SFTP, Anda dapat mengganti nama file dengan operasi SSH_FXP_RENAME; Namun, perilakunya ketika nama target sudah ada tampaknya tergantung pada versi protokol yang Anda gunakan dan tanda apa yang Anda lewati. The halaman wikipedia untuk protokol SFTP memiliki link ke berbagai rancangan RFC untuk berbagai versi dari protokol. Dalam Draf 00 perilaku ini terdaftar sebagai:

Ini adalah kesalahan jika sudah ada file dengan nama yang ditentukan oleh newpath.

Dalam Konsep 13 , perilaku ini terdaftar sebagai

Jika bendera tidak menyertakan SSH_FXP_RENAME_OVERWRITE, dan sudah ada file dengan nama yang ditentukan oleh jalur baru, server HARUS merespons dengan SSH_FX_FILE_AL_AD__EXISTS.

Jika flag menyertakan SSH_FXP_RENAME_ATOMIC, dan file tujuan sudah ada, itu diganti dengan cara atom. Yaitu, tidak ada waktu instan yang dapat diamati di mana nama tersebut tidak merujuk ke file lama atau baru. SSH_FXP_RENAME_ATOMIC menyiratkan SSH_FXP_RENAME_OVERWRITE.

Untuk menangani kemungkinan kegagalan operasi penggantian nama () ketika nama target ada, sshfs memberikan solusi berikut (jika diaktifkan) :

   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);
                    }
            }
    }

Dalam kode ini "from" adalah nama file yang ada yang ingin kita rename dan "to" adalah nama baru yang kita inginkan. Mengesampingkan beberapa panjang jalur dan kesalahan pembukuan, ini berhasil

  • Ganti nama "menjadi" menjadi "totmp"
  • Mengganti nama "dari" menjadi "menjadi"
  • Putuskan tautan (hapus) "totmp"

Ini menghindari konflik "file yang sudah ada", tetapi juga mengubah semantik operasi rename (), itulah sebabnya Anda tidak ingin melakukannya secara default.

Steven D
sumber