Temos um arquivo que contém dados que precisam sempre ser consistentes. Quando precisa ser modificado, Process 1
cria um novo arquivo, grava o novo arquivo com as modificações e usa mv
para renomear o novo arquivo com o nome de arquivo antigo.
Se tivermos outro processo, Process 2
, que precisa ler este arquivo, como podemos garantir que ele sempre lerá um arquivo consistente, ou seja, um mv
by Process 1
durante a leitura não pode corromper os dados?
Responder1
Você garante isso criando o novo arquivo no mesmo sistema de arquivos do arquivo antigo e usando a rename(2)
função [1], que é garantidamente atômica.
Em sistemas de arquivos Unix, a rename(2)
atua apenas nas entradas do diretório, não afetará nenhum processo que tenha um identificador aberto para o inode apontado pela entrada do diretório original; esse processo continuará lendo ou gravando no arquivo antigo.
Normalmente, o mv(1)
utilitário apenas invocará rename(2)
, mas poderá recorrer a remover + copiar ou outras operações não atômicas duvidosas no caso de rename(2)
falha.
Observe que dois arquivos no mesmo sistema de arquivos podem não garantir o rename(2)
sucesso - existem sistemas de arquivos como 9pfs
os que não suportam uma operação de renomeação, portanto, ela deve ser fabricada, de uma forma ou de outra.
[1] ou melhor ainda, renameat(2)
o que evita que os caminhos principais para os arquivos sejam alterados sub-repticiamente de outro processo, ou seja, "ataques de links simbólicos".