Esta rename()função é equivalente para arquivos regulares àquela definida pelo padrão ISO C. Sua inclusão aqui expande essa definição para incluir ações em diretórios e especifica o comportamento quando o novo parâmetro nomeia um arquivo que já existe. Essa especificação requer que a ação da função seja atômica.
#include <stdio.h>
int rename(const char *old, const char *new);
Descrição
A renamefunção faz com que o arquivo cujo nome é a string apontada por oldseja doravante conhecido pelo nome fornecido pela string apontada por new. O arquivo nomeado oldnão está mais acessível por esse nome. Se um arquivo nomeado pela string apontada por newexistir antes da chamada para a renamefunção, o comportamento será definido pela implementação.
Devoluções
A renamefunção retornará zero se a operação for bem-sucedida, diferente de zero se falhar; nesse caso, se o arquivo existia anteriormente, ainda é conhecido por seu nome original.
Surpreendentemente, observe que não há requisitos explícitos para atomicidade. Pode ser necessário em outro lugar do último padrão C disponível publicamente, mas não consegui encontrá-lo. Se alguém puder encontrar esse requisito, edições e comentários serão bem-vindos.
Se newpathjá existir, ele será substituído atomicamente, de modo que não há nenhum ponto em que outro processo que tente acessar
newpatho encontre ausente. No entanto, provavelmente haverá uma janela na qual ambos oldpathe se newpathreferem ao arquivo que está sendo renomeado.
A página de manual do Linux afirma que a substituição do arquivo será atômica.
Testar e verificar se a atomicidade pode ser muito difícil, se é assim que você precisa ir. Você não está claro quanto ao significado de "Como posso verificar se mv é atômico". Deseja requisitos / especificação / documentação atômica ou precisa realmente testá- lo?
Observe também que o acima pressupõe que os dois nomes de arquivos de operando estejam no mesmo sistema de arquivos. Não consigo encontrar nenhuma restrição padrão no mvutilitário para impor isso.
Eu tenho que garantir que o movimento seja atômico. O teste é suficiente para aceitar isso? Não sei dizer. Sim, estou trabalhando no mesmo fs (ext4 a ext4).
Tizianoreica 9/11/16
1
O POSIX também não garante atomicidade, mas o Linux, como a maioria das variantes unix, garante sistemas de arquivos "nativos", como o ext4.
Gilles 'SO- stop be evil'
1
Dado que a ISO C define apenas o comportamento de um programa e não de um sistema inteiro, seria estranho dizer algo sobre renameatomicidade.
Gilles 'SO- stop be evil'
3
Eu li "essa especificação" como referindo-se à frase anterior ("Sua inclusão aqui ... especifica o comportamento quando o novo parâmetro nomeia um arquivo que já existe"), que se refere a partes anteriores do documento POSIX ("um link chamado new will permaneça visível para outros threads em todo ... e consulte o arquivo referido por novo ou antigo ... "). Em outras palavras, o POSIX promete implementar o padrão ISO C e oferece garantias adicionais além do que o ISO C fornece. Essa interpretação ajuda?
Simonj
1
@Tizianoreica Eu sei que este é um post antigo, mas acabei de ver seu comentário e pensei em esclarecer: O sistema de arquivos real precisa ser o mesmo para que a renomeação seja atômica. Não é apenas o mesmo tipo de sistema de arquivos. por exemplo, se você possui /um ext4 fs e /tmpum ext4 fs diferente, não é possível mv atomicamente de um para o outro.
Wodin
0
mvé baseado na renamechamada do sistema e rename()é atômico. Você pode olhar para a página de manual rename(2).
Além de verificar as chamadas do sistema e sua atomicidade, talvez inotify-toolspossa servir como teste, embora não tenha certeza se é uma prova garantida de atomicidade.
Abra 2 conchas. Assista ao diretório de destino da movimentação em um deles:
inotifywait -m target/
Mova um arquivo para o diretório no outro:
mv foobar target/
O inotifywaitdeve mostrar apenas uma linha:
target/ MOVED_TO foobar
Parece atômica em comparação com a resposta a ls target/e touch target/a, que produzem mensagens de várias linhas como:
# the response to ls target/
target/ OPEN,ISDIR
target/ ACCESS,ISDIR
target/ CLOSE_NOWRITE,CLOSE,ISDIR
PS
Eu acho que, pelo menos, mostra que a cooperação multiprocesso assíncrona em arquivos é segura com inotify(praticamente atômica): em qualquer caso, você responderia apenas depois de inotifydar o sinal final após a operação. Por exemplo, uma configuração produtor-consumidor pode ser implementada com facilidade e segurança inotify.
strace
?unlink
ourename
portável e atomicamente irálink
falhar?Respostas:
Curiosamente, parece que a resposta pode ser: "Depende".
Para ficar claro,
mv
é especificado paraA especificação da função renomear indica:
Mas a mais recente especificação ISO C para
rename()
estados:Surpreendentemente, observe que não há requisitos explícitos para atomicidade. Pode ser necessário em outro lugar do último padrão C disponível publicamente, mas não consegui encontrá-lo. Se alguém puder encontrar esse requisito, edições e comentários serão bem-vindos.
Consulte também É renomeado () atômico?
De acordo com a página de manual do Linux :
A página de manual do Linux afirma que a substituição do arquivo será atômica.
Testar e verificar se a atomicidade pode ser muito difícil, se é assim que você precisa ir. Você não está claro quanto ao significado de "Como posso verificar se mv é atômico". Deseja requisitos / especificação / documentação atômica ou precisa realmente testá- lo?
Observe também que o acima pressupõe que os dois nomes de arquivos de operando estejam no mesmo sistema de arquivos. Não consigo encontrar nenhuma restrição padrão no
mv
utilitário para impor isso.fonte
rename
atomicidade./
um ext4 fs e/tmp
um ext4 fs diferente, não é possível mv atomicamente de um para o outro.mv
é baseado narename
chamada do sistema erename()
é atômico. Você pode olhar para a página de manualrename(2)
.Você pode encontrar resposta em É renomear () atômico? no stackoverflow.
Que tipo de fs você usou?
fonte
Além de verificar as chamadas do sistema e sua atomicidade, talvez
inotify-tools
possa servir como teste, embora não tenha certeza se é uma prova garantida de atomicidade.Abra 2 conchas. Assista ao diretório de destino da movimentação em um deles:
Mova um arquivo para o diretório no outro:
O
inotifywait
deve mostrar apenas uma linha:Parece atômica em comparação com a resposta a
ls target/
etouch target/a
, que produzem mensagens de várias linhas como:PS
Eu acho que, pelo menos, mostra que a cooperação multiprocesso assíncrona em arquivos é segura com
inotify
(praticamente atômica): em qualquer caso, você responderia apenas depois deinotify
dar o sinal final após a operação. Por exemplo, uma configuração produtor-consumidor pode ser implementada com facilidade e segurançainotify
.fonte