что делает `sshfs -oworkaround = rename`?


17

Для класса операционных систем, который я использую, мне нужно было запустить Freebsd5.4. Так как я не хотел бороться с попыткой собрать git на версии bsd, выпущенной до выпуска git, я подумал, что будет полезно использовать gitArch из 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 для rename () в этом случае заключается в удалении существующего файла и завершении переименования.

В протоколе 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);
                    }
            }
    }

В этом коде «from» - это существующее имя файла, который мы хотим переименовать, а «to» - это новое имя, которое мы хотим. Оставляя в стороне некоторую длину пути и учет ошибок

  • Переименовывает в "to" в "Totmp"
  • Переименовывает "из" в "в"
  • Отменяет (удаляет) "Totmp"

Это позволяет избежать конфликта «файл уже существует», но также меняет семантику операций rename (), поэтому вы не захотите делать это по умолчанию.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.