o que `sshfs -oworkaround = rename` faz?

17

Para uma classe de sistemas operacionais que estou cursando, eu precisava executar o Freebsd5.4. Como eu não queria lutar com o build do git em uma versão do bsd lançada antes do lançamento do git, pensei que seria interessante usar o gitArch over sshfs.

De qualquer forma, encontrei uma solução alternativa que sugeria que eu desse sshfsa opção -o workaround=rename.

Parece fazer gitfeliz, mas estou um pouco confuso com o que aconteceu ...

Tudo o que a página do manual diz sobre a solução alternativa é

fix renaming to existing file

mas estou completamente confuso quanto ao que isso significa ...

O que exatamente essa opção faz?

math4tots
fonte
3
Ponteiro para alguém que deseja analisar exatamente o que isso significa (e escrever uma resposta e, espero, um patch de documentação): sourceforge.net/p/fuse/sshfs/ci/master/tree/sshfs.c a partir da linha 2300.
derobert

Respostas:

10

O sshfs usa o protocolo SFTP (SSH File Transfer Protocol). A solução alternativa que você ativou está contornando a semântica de uma operação rename () sobre esse protocolo quando o nome "novo" já existir.

O comportamento do POSIX para renomear () neste caso é remover o arquivo existente e concluir a renomeação.

No protocolo SFTP, você pode renomear um arquivo com a operação SSH_FXP_RENAME; no entanto, seu comportamento quando o nome do destino já existe parece depender da versão do protocolo que você está usando e dos sinalizadores que você passa. A página da wikipedia para o protocolo SFTP possui links para vários rascunhos de RFCs para várias versões do protocolo. No rascunho 00, o comportamento é listado como:

É um erro se já existir um arquivo com o nome especificado por newpath.

No rascunho 13 , o comportamento é listado como

Se os sinalizadores não incluem SSH_FXP_RENAME_OVERWRITE, e já existe um arquivo com o nome especificado por newpath, o servidor DEVE responder com SSH_FX_FILE_ALREADY_EXISTS.

Se os sinalizadores incluírem SSH_FXP_RENAME_ATOMIC e o arquivo de destino já existir, ele será substituído de maneira atômica. Ou seja, não há um instante observável no tempo em que o nome não se refira ao arquivo antigo ou ao novo. SSH_FXP_RENAME_ATOMIC implica SSH_FXP_RENAME_OVERWRITE.

Para lidar com a possível falha de uma operação rename () quando o nome do destino existe, o sshfs fornece a seguinte solução alternativa (se ativada) :

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

Nesse código "from" é o nome existente do arquivo que queremos renomear e "to" é o novo nome que queremos. Deixando de lado algum comprimento do caminho e a contabilização de erros, esta solução

  • Renomeia "para" para "totmp"
  • Renomeia "de" para "para"
  • Desvincula (exclui) "totmp"

Isso evita o conflito "o arquivo já existe", mas também altera a semântica das operações rename (), e é por isso que você não deseja fazê-lo por padrão.

Steven D
fonte