що робить `sshfs -oworkaround = перейменувати`?


17

Для класу операційних систем, який я беру, мені потрібно було запустити Freebsd5.4. Оскільки я не хотів боротися зі спробами побудувати git на версії bsd, випущеній до виходу git, я подумав, що це буде акуратно використовувати gitз Arch понад sshfs.

У будь-якому випадку я знайшов рішення, яке запропонувало дати sshfsможливість -o workaround=rename.

Здається, це робить gitщасливим, але я досить розгублений щодо того, що щойно сталося ...

Всі сторінки чоловіка говорять про обхід

fix renaming to existing file

але я зовсім збентежений, що це означає ...

Що саме робить цей варіант?


3
Вказівник для того, хто хоче вивчити, що саме це означає (і написати відповідь, і, сподіваємось, виправлення документації): sourceforge.net/p/fuse/sshfs/ci/master/tree/sshfs.c починаючи з лінії 2300.
дероберт

Відповіді:


10

sshfs використовує протокол передачі файлів SSH (SFTP). Ви увімкнули обхідне рішення, яке працює над семантикою операції rename () над цим протоколом, коли "нове" ім'я вже існує.

Поведінка POSIX для перейменування () у цьому випадку полягає у видаленні існуючого файлу та завершенні перейменування.

У протоколі SFTP ви можете перейменувати файл за допомогою операції SSH_FXP_RENAME; однак, його поведінка, коли цільове ім'я вже існує, схоже, залежить від версії протоколу, який ви використовуєте, та яких прапорів ви передаєте. Сторінка вікіпедії для протоколу SFTP містить посилання на різні проекти RFC для різних версій протоколу. У чернетці 00 поведінка вказана як:

Це помилка, якщо вже існує файл з ім'ям, вказаним newpath.

У проекті 13 поведінка вказана як

Якщо прапори не містять SSH_FXP_RENAME_OVERWRITE, а файл вже існує з ім'ям, вказаним newpath, сервер повинен відповідати SSH_FX_FILE_ALREADY_EXISTS.

Якщо прапори містять 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);
                    }
            }
    }

У цьому коді "від" - це існуюче ім'я файлу, який ми хочемо перейменувати, а "до" - це нове ім'я, яке ми хочемо. Відклавши деяку довжину шляху та бухгалтерський облік помилок, ця робота обійдеться

  • Перейменовує "в" на "totmp"
  • Перейменовує "з" в "до"
  • Скасовує (видаляє) "totmp"

Це дозволяє уникнути конфлікту "файл вже існує", але також змінює семантику операцій перейменування (), тому ви не хочете робити це за замовчуванням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.