Is moving file from
tmpfs
toext4
atomic?
Não. Renomeadas, como tal, funcionam apenas dentro de um sistema de arquivos. A página de manual para rename(2)
menciona explicitamente o erro retornado ao tentar renomear os pontos de montagem:
EXDEV
oldpath and newpath are not on the same mounted filesystem.
As transferências entre os sistemas de arquivos precisam ser feitas como uma combinação de uma cópia e uma exclusão. mv
fará isso para você se o rename()
não funcionar, mas não será atômico nesse caso.
A maneira simples de contornar isso seria, de fato, primeiro copiar o arquivo para um local temporário no mesmo sistema de arquivos. Em geral, é mais simples colocar o arquivo temporário no mesmo diretório que o destino final, já que esse é o único lugar que tem garantia de estar no mesmo sistema de arquivos. Claro que isso requer que qualquer processo que trabalhe nos arquivos tenha alguma lógica para ignorar o temporário baseado em seu nome.
Aproximadamente, algo assim deve funcionar para um arquivo:
cp /src/filename /dst/filename.tmp &&
mv /dst/filename.tmp /dst/filename &&
rm /src/filename
Note que o processo que você descreve para um diretório é essencialmente isto:
cp -r /src/dir /dst/dir.tmp &&
mv /dst/dir /dst/dir.bak &&
mv /dst/dir.tmp /dst/dir &&
rm -r /dst/dir.bak
O que não é ruim, mas não é mv
(ou chamadas para rename()
), quando /dst/dir
não existe. Isso poderia ser resolvido acessando o diretório por meio de um link simbólico, já que o link pode ser substituído atomicamente por uma renomeação.